Top


定義場所(file name)

hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp

名前(function name)

void CMTask::drain_local_queue(bool partially) {

本体部(body)

  {- -------------------------------------------
  (1) 何らかの理由でこの CMTask が中断されていたら, ここでリターン
      ---------------------------------------- -}

      if (has_aborted())
        return;

  {- -------------------------------------------
  (1) (変数宣言など)
      (target_size は, 今回の処理で _task_queue 内の要素をどこまで減らすかを表す.
      partially 引数が true なら 現在の3分の1の数 もしくは GCDrainStackTargetSize の小さい方まで削減する.
      partially 引数が false なら, すべて処理し終える.)
      ---------------------------------------- -}

      // Decide what the target size is, depending whether we're going to
      // drain it partially (so that other tasks can steal if they run out
      // of things to do) or totally (at the very end).
      size_t target_size;
      if (partially)
        target_size = MIN2((size_t)_task_queue->max_elems()/3, GCDrainStackTargetSize);
      else
        target_size = 0;

  {- -------------------------------------------
  (1) (以降の処理で,
      _task_queue 内の要素数が目標数(target_size)以下になるまで処理を続ける)
      ---------------------------------------- -}

      if (_task_queue->size() > target_size) {

    {- -------------------------------------------
  (1.1) (トレース出力)
        ---------------------------------------- -}

        if (_cm->verbose_high())
          gclog_or_tty->print_cr("[%d] draining local queue, target size = %d",
                                 _task_id, target_size);

    {- -------------------------------------------
  (1.1) (変数宣言など)
        ---------------------------------------- -}

        oop obj;

    {- -------------------------------------------
  (1.1) (以下の while ループで, 終了条件を満たすまで, 
        「pop_local() で次の要素を取得しては CMTask::scan_object() で処理する」という流れを繰り返す)
        ---------------------------------------- -}

        bool ret = _task_queue->pop_local(obj);
        while (ret) {
          statsOnly( ++_local_pops );

      {- -------------------------------------------
  (1.1.1) (トレース出力)
          ---------------------------------------- -}

          if (_cm->verbose_high())
            gclog_or_tty->print_cr("[%d] popped "PTR_FORMAT, _task_id,
                                   (void*) obj);

      {- -------------------------------------------
  (1.1.1) (assert)
          ---------------------------------------- -}

          assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" );
          assert(!_g1h->is_on_master_free_list(
                      _g1h->heap_region_containing((HeapWord*) obj)), "invariant");

      {- -------------------------------------------
  (1.1.1) CMTask::scan_object() を呼んで, 処理対象のオブジェクトを処理する
          ---------------------------------------- -}

          scan_object(obj);

      {- -------------------------------------------
  (1.1.1) 終了条件を満たしていれば, ret を false にする
          (= ループを抜けてこの関数の処理を終える).
          そうでなければ, 次の要素を取り出してループの次の周回へ進む.
          ---------------------------------------- -}

          if (_task_queue->size() <= target_size || has_aborted())
            ret = false;
          else
            ret = _task_queue->pop_local(obj);
        }

    {- -------------------------------------------
  (1.1) (トレース出力)
        ---------------------------------------- -}

        if (_cm->verbose_high())
          gclog_or_tty->print_cr("[%d] drained local queue, size = %d",
                                 _task_id, _task_queue->size());
      }
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.