hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(Universe::heap()->is_gc_active(), "called outside gc");
{- -------------------------------------------
(1) PSPromotionManager::gc_thread_promotion_manager() で,
これを実行している GCTaskThread 用の PSPromotionManager オブジェクトを取得する.
---------------------------------------- -}
PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
PSScavengeRootsClosure roots_closure(pm);
{- -------------------------------------------
(1) ScavengeRootsTask は, コンストラクタで指定された _root_type に応じて処理対象を変える.
以下, _root_type に応じて処理を分岐.
といっても, どの場合も _root_type に対応するオブジェクトの oops_do() メソッドを呼び出すだけ.
(CodeCache だけは CodeCache::scavenge_root_nmethods_do() というメソッド名だが...)
その際に, PSScavengeRootsClosure オブジェクト (上の roots_closure) を引数として呼び出す.
これにより, そのオブジェクト内のポインタを PSPromotionManager オブジェクトのタスクキューに追加していく.
なお現状では, 以下の case threads: のケースは使われていない模様.
(Thread 内の処理は ThreadRootsTask クラスで処理するので,
ScavengeRootsTask オブジェクトが threads を指定されて生成されることはない.)
---------------------------------------- -}
switch (_root_type) {
case universe:
Universe::oops_do(&roots_closure);
ReferenceProcessor::oops_do(&roots_closure);
break;
case jni_handles:
JNIHandles::oops_do(&roots_closure);
break;
case threads:
{
ResourceMark rm;
Threads::oops_do(&roots_closure, NULL);
}
break;
case object_synchronizer:
ObjectSynchronizer::oops_do(&roots_closure);
break;
case flat_profiler:
FlatProfiler::oops_do(&roots_closure);
break;
case system_dictionary:
SystemDictionary::oops_do(&roots_closure);
break;
case management:
Management::oops_do(&roots_closure);
break;
case jvmti:
JvmtiExport::oops_do(&roots_closure);
break;
case code_cache:
{
CodeBlobToOopClosure each_scavengable_code_blob(&roots_closure, /*do_marking=*/ true);
CodeCache::scavenge_root_nmethods_do(&each_scavengable_code_blob);
}
break;
default:
fatal("Unknown root type");
}
{- -------------------------------------------
(1) PSPromotionManager::drain_stacks() で,
タスクキューに追加したポインタに対して, 再帰的な Scavenge 処理を行う.
---------------------------------------- -}
// Do the real work
pm->drain_stacks(false);
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.