hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
(コメントによると, 単純化のため single threaded 用のコードは削除したい, とのこと)
// SATB Queue has several assumptions on whether to call the par or
// non-par versions of the methods. this is why some of the code is
// replicated. We should really get rid of the single-threaded version
// of the code to simplify things.
void CMTask::drain_satb_buffers() {
{- -------------------------------------------
(1) 何らかの理由でこの CMTask が中断されていたら, ここでリターン
---------------------------------------- -}
if (has_aborted())
return;
{- -------------------------------------------
(1) (ここからが _draining_satb_buffers が true の範囲)
---------------------------------------- -}
// We set this so that the regular clock knows that we're in the
// middle of draining buffers and doesn't set the abort flag when it
// notices that SATB buffers are available for draining. It'd be
// very counter productive if it did that. :-)
_draining_satb_buffers = true;
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
CMObjectClosure oc(this);
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
{- -------------------------------------------
(1) set_par_closure() もしくは set_closure を呼び出して,
JavaThread::satb_mark_queue_set() に
CMObjectClosure オブジェクトをセットしておく.
(この closure が, この後の SATBMarkQueueSet::*_apply_closure_to_completed_buffer() の処理で使用される.)
---------------------------------------- -}
if (G1CollectedHeap::use_parallel_gc_threads())
satb_mq_set.set_par_closure(_task_id, &oc);
else
satb_mq_set.set_closure(&oc);
{- -------------------------------------------
(1) 以下のどちらかを呼び出し続けて, SATB バッファの処理を行う.
(また, 一回呼び出すごとに CMTask::regular_clock_call() も呼び出して, 必要に応じて has_aborted() を true にする)
この処理は, 呼び出した関数が false を返すか, または has_aborted() が true を返すようになるまで繰り返す.
* SATBMarkQueueSet::par_apply_closure_to_completed_buffer()
multi-thread 用
* SATBMarkQueueSet::apply_closure_to_completed_buffer()
single thread 用
---------------------------------------- -}
// This keeps claiming and applying the closure to completed buffers
// until we run out of buffers or we need to abort.
if (G1CollectedHeap::use_parallel_gc_threads()) {
while (!has_aborted() &&
satb_mq_set.par_apply_closure_to_completed_buffer(_task_id)) {
if (_cm->verbose_medium())
gclog_or_tty->print_cr("[%d] processed an SATB buffer", _task_id);
statsOnly( ++_satb_buffers_processed );
regular_clock_call();
}
} else {
while (!has_aborted() &&
satb_mq_set.apply_closure_to_completed_buffer()) {
if (_cm->verbose_medium())
gclog_or_tty->print_cr("[%d] processed an SATB buffer", _task_id);
statsOnly( ++_satb_buffers_processed );
regular_clock_call();
}
}
{- -------------------------------------------
(1) もし, この処理が Final Mark 用のものであれば(??)
(そして, まだこの CMTask が中断されていなければ)
以下のどちらかを呼び出して, ... #TODO
* SATBMarkQueueSet::par_iterate_closure_all_threads()
multi-thread 用
* SATBMarkQueueSet::iterate_closure_all_threads()
single thread 用
---------------------------------------- -}
if (!concurrent() && !has_aborted()) {
// We should only do this during remark.
if (G1CollectedHeap::use_parallel_gc_threads())
satb_mq_set.par_iterate_closure_all_threads(_task_id);
else
satb_mq_set.iterate_closure_all_threads();
}
{- -------------------------------------------
(1) (ここまでが _draining_satb_buffers が true の範囲)
---------------------------------------- -}
_draining_satb_buffers = false;
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(has_aborted() ||
concurrent() ||
satb_mq_set.completed_buffers_num() == 0, "invariant");
{- -------------------------------------------
(1) ?? (#TODO) (satb_mq_set (つまり JavaThread::satb_mark_queue_set()) をリセットしている??)
---------------------------------------- -}
if (G1CollectedHeap::use_parallel_gc_threads())
satb_mq_set.set_par_closure(_task_id, NULL);
else
satb_mq_set.set_closure(NULL);
{- -------------------------------------------
(1)
---------------------------------------- -}
// again, this was a potentially expensive operation, decrease the
// limits to get the regular clock call early
decrease_limits();
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.