hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
void
G1CollectedHeap::
g1_process_strong_roots(bool collecting_perm_gen,
SharedHeap::ScanningOption so,
OopClosure* scan_non_heap_roots,
OopsInHeapRegionClosure* scan_rs,
OopsInGenClosure* scan_perm,
int worker_i) {
{- -------------------------------------------
(1) 処理開始時の時間を記録しておく
---------------------------------------- -}
// First scan the strong roots, including the perm gen.
double ext_roots_start = os::elapsedTime();
{- -------------------------------------------
(1) ?? (以下の変数は使用箇所が無いような...)
---------------------------------------- -}
double closure_app_time_sec = 0.0;
{- -------------------------------------------
(1) (変数宣言など) (?? #TODO)
---------------------------------------- -}
BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
BufferingOopsInGenClosure buf_scan_perm(scan_perm);
buf_scan_perm.set_generation(perm_gen());
// Walk the code cache w/o buffering, because StarTask cannot handle
// unaligned oop locations.
CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, /*do_marking=*/ true);
{- -------------------------------------------
(1) SharedHeap::process_strong_roots() を呼んで,
strong root から辿れる範囲に G1ParCopyClosure を適用する.
(ただし, ポインタ配列については G1ParScanPartialArrayClosure を適用する)
---------------------------------------- -}
process_strong_roots(false, // no scoping; this is parallel code
collecting_perm_gen, so,
&buf_scan_non_heap_roots,
&eager_scan_code_roots,
&buf_scan_perm);
{- -------------------------------------------
(1) 最後に, BufferingOopClosure や BufferingOopsInGenClosure のバッファ内に残っているものがあれば処理している?? #TODO
---------------------------------------- -}
// Finish up any enqueued closure apps.
buf_scan_non_heap_roots.done();
buf_scan_perm.done();
{- -------------------------------------------
(1) 処理に掛かった時間を G1CollectorPolicy オブジェクトに記録.
---------------------------------------- -}
double ext_roots_end = os::elapsedTime();
g1_policy()->reset_obj_copy_time(worker_i);
double obj_copy_time_sec =
buf_scan_non_heap_roots.closure_app_seconds() +
buf_scan_perm.closure_app_seconds();
g1_policy()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
double ext_root_time_ms =
((ext_roots_end - ext_roots_start) - obj_copy_time_sec) * 1000.0;
g1_policy()->record_ext_root_scan_time(worker_i, ext_root_time_ms);
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が mark stack の処理を行ったかどうかを確認する.
まだであれば ConcurrentMark::oops_do() で mark stack の処理を行う.
---------------------------------------- -}
// Scan strong roots in mark stack.
if (!_process_strong_tasks->is_task_claimed(G1H_PS_mark_stack_oops_do)) {
concurrent_mark()->oops_do(scan_non_heap_roots);
}
{- -------------------------------------------
(1) mark stack の処理に掛かった時間を G1CollectorPolicy オブジェクトに記録.
---------------------------------------- -}
double mark_stack_scan_ms = (os::elapsedTime() - ext_roots_end) * 1000.0;
g1_policy()->record_mark_stack_scan_time(worker_i, mark_stack_scan_ms);
// XXX What should this be doing in the parallel case?
g1_policy()->record_collection_pause_end_CH_strong_roots();
{- -------------------------------------------
(1) G1RemSet::oops_into_collection_set_do() を呼び出して,
回収対象の region の remembered set に入っているポインタ (= 回収対象ではない region から回収対象の region を指しているポインタ) について処理を行う.
(引数の scan_rs が NULL だった場合には処理しないようだが, 今のところそんな処理パスは無いような... #TODO)
---------------------------------------- -}
// Now scan the complement of the collection set.
if (scan_rs != NULL) {
g1_rem_set()->oops_into_collection_set_do(scan_rs, worker_i);
}
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が refProcessor の処理を行ったかどうかを確認する.
まだであれば ReferenceProcessor::weak_oops_do() と ReferenceProcessor::oops_do() で refProcessor の処理を行う.
(なお, ref_processor() に格納されているのは ReferenceProcessor オブジェクト.
G1CollectedHeap::ref_processing_init() 参照)
---------------------------------------- -}
// Finish with the ref_processor roots.
if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) {
// We need to treat the discovered reference lists as roots and
// keep entries (which are added by the marking threads) on them
// live until they can be processed at the end of marking.
ref_processor()->weak_oops_do(scan_non_heap_roots);
ref_processor()->oops_do(scan_non_heap_roots);
}
{- -------------------------------------------
(1) 処理に掛かった時間を G1CollectorPolicy オブジェクトに記録.
---------------------------------------- -}
g1_policy()->record_collection_pause_end_G1_strong_roots();
{- -------------------------------------------
(1) SubTasksDone::all_tasks_completed() を呼びだしておく.
(これにより, 全部の WorkGang の処理が終わった時点で
次の処理に備えて, SubTasksDone オブジェクトが最初の状態に戻される.)
---------------------------------------- -}
_process_strong_tasks->all_tasks_completed();
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.