hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
void CMTask::drain_local_queue(bool partially) {
{- -------------------------------------------
(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.