hotspot/src/share/vm/memory/sharedHeap.cpp
void SharedHeap::process_strong_roots(bool activate_scope,
bool collecting_perm_gen,
ScanningOption so,
OopClosure* roots,
CodeBlobClosure* code_roots,
OopsInGenClosure* perm_blk) {
{- -------------------------------------------
(1) #TODO
(See: StrongRootsScope)
---------------------------------------- -}
StrongRootsScope srs(this, activate_scope);
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
// General strong roots.
assert(_strong_roots_parity != 0, "must have called prologue code");
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が Universe の処理を行ったかどうかを確認する.
まだであれば Universe や ReferenceProcessor の処理を行う.
---------------------------------------- -}
if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
Universe::oops_do(roots);
ReferenceProcessor::oops_do(roots);
// Consider perm-gen discovered lists to be strong.
perm_gen()->ref_processor()->weak_oops_do(roots);
}
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が JNIHandle の処理を行ったかどうかを確認する.
まだであれば JNIHandle の処理を行う.
---------------------------------------- -}
// Global (strong) JNI handles
if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
JNIHandles::oops_do(roots);
{- -------------------------------------------
(1) ?? #TODO
---------------------------------------- -}
// All threads execute this; the individual threads are task groups.
if (ParallelGCThreads > 0) {
Threads::possibly_parallel_oops_do(roots, code_roots);
} else {
Threads::oops_do(roots, code_roots);
}
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が ObjectSynchronizer の処理を行ったかどうかを確認する.
まだであれば ObjectSynchronizer の処理を行う.
---------------------------------------- -}
if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
ObjectSynchronizer::oops_do(roots);
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が FlatProfiler の処理を行ったかどうかを確認する.
まだであれば FlatProfiler の処理を行う.
---------------------------------------- -}
if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do))
FlatProfiler::oops_do(roots);
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が Management の処理を行ったかどうかを確認する.
まだであれば Management の処理を行う.
---------------------------------------- -}
if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do))
Management::oops_do(roots);
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が JvmtiExport の処理を行ったかどうかを確認する.
まだであれば JvmtiExport の処理を行う.
---------------------------------------- -}
if (!_process_strong_tasks->is_task_claimed(SH_PS_jvmti_oops_do))
JvmtiExport::oops_do(roots);
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が SystemDictionary の処理を行ったかどうかを確認する.
まだ処理されておらず, かつ引数の処理対象種別(以下の so)で SO_AllClasses または SO_SystemClasses が指定されている場合には処理を行う.
(SO_AllClasses の場合には, SystemDictionary::oops_do() を呼び出す.
SO_SystemClasses の場合には, SystemDictionary::always_strong_oops_do() を呼び出す.)
---------------------------------------- -}
if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) {
if (so & SO_AllClasses) {
SystemDictionary::oops_do(roots);
} else if (so & SO_SystemClasses) {
SystemDictionary::always_strong_oops_do(roots);
}
}
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が StringTable の処理を行ったかどうかを確認する.
まだ処理されておらず, かつ以下の条件のどちらかがなりたった場合には, 処理を行う.
* 引数の処理対象種別(以下の so)で SO_Strings が指定されている場合
* 引数で Perm 領域は処理対象としないよう指定されており(!collecting_perm_gen), かつ JavaObjectsInPerm オプションも指定されていない場合 (<= これはどういう条件?? #TODO)
(なお, 非 product 版でかつ JavaObjectsInPerm オプションが指定されている場合, ここで verify 処理も行われている)
---------------------------------------- -}
if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
if (so & SO_Strings || (!collecting_perm_gen && !JavaObjectsInPerm)) {
StringTable::oops_do(roots);
}
if (JavaObjectsInPerm) {
// Verify the string table contents are in the perm gen
NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
}
}
{- -------------------------------------------
(1) SubTasksDone::is_task_claimed() で, 他の WorkGang が CodeCache の処理を行ったかどうかを確認する.
まだ処理されておらず, かつ引数の処理対象種別(以下の so)で SO_CodeCache または SO_SystemClasses または SO_AllClasses が指定されている場合には処理を行う.
(SO_CodeCache の場合には, CodeCache::blobs_do を呼び出す.
SO_SystemClasses または SO_AllClasses の場合には, CodeCache::scavenge_root_nmethods_do() を呼び出す (が, 引数の collecting_perm_gen が false の場合には何も処理しない. コメントに何か書いてあるが... #TODO))
---------------------------------------- -}
if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
if (so & SO_CodeCache) {
// (Currently, CMSCollector uses this to do intermediate-strength collections.)
assert(collecting_perm_gen, "scanning all of code cache");
assert(code_roots != NULL, "must supply closure for code cache");
if (code_roots != NULL) {
CodeCache::blobs_do(code_roots);
}
} else if (so & (SO_SystemClasses|SO_AllClasses)) {
if (!collecting_perm_gen) {
// If we are collecting from class statics, but we are not going to
// visit all of the CodeCache, collect from the non-perm roots if any.
// This makes the code cache function temporarily as a source of strong
// roots for oops, until the next major collection.
//
// If collecting_perm_gen is true, we require that this phase will call
// CodeCache::do_unloading. This will kill off nmethods with expired
// weak references, such as stale invokedynamic targets.
CodeCache::scavenge_root_nmethods_do(code_roots);
}
}
{- -------------------------------------------
(1) (verify)
---------------------------------------- -}
// Verify that the code cache contents are not subject to
// movement by a scavenging collection.
DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, /*do_marking=*/ false));
DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable));
}
{- -------------------------------------------
(1) もし引数で Perm 領域は処理対象としないよう指定されていれば(!collecting_perm_gen),
代わりに Perm 領域のオブジェクトは全て live と扱うことにして,
Perm 内のポインタで Perm 外を指しているもの全てに対して perm_blk を適用する.
(この関数の先頭にあるコメントも参照).
(処理自体は CardTableRS::younger_refs_iterate() を使って実現している).
---------------------------------------- -}
if (!collecting_perm_gen) {
// All threads perform this; coordination is handled internally.
rem_set()->younger_refs_iterate(perm_gen(), perm_blk);
}
{- -------------------------------------------
(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.