hotspot/src/share/vm/memory/referenceProcessor.cpp
// Traverse the list and process the referents, by either
// clearing them or keeping them (and their reachable
// closure) alive.
void
ReferenceProcessor::process_phase3(DiscoveredList& refs_list,
bool clear_referent,
BoolObjectClosure* is_alive,
OopClosure* keep_alive,
VoidClosure* complete_gc) {
{- -------------------------------------------
(1) (以下の while 文の中で, (DiscoveredListIterator を使って)
引数で渡された DiscoveredList を最初から最後まで辿って処理を行う)
---------------------------------------- -}
ResourceMark rm;
DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
while (iter.has_next()) {
{- -------------------------------------------
(1.1) DiscoveredListIterator::update_discovered() で, 参照オブジェクト自体を live にしておく
---------------------------------------- -}
iter.update_discovered();
{- -------------------------------------------
(1.1) 参照オブジェクトの差し先については, 引数に応じて live にするかどうかを決める.
* 引数で消去するよう指定されていた場合 (= clear_referent が true の場合):
live にはしない.
代わりに DiscoveredListIterator::clear_referent() で
参照オブジェクト内の差し先を示すフィールドを null にしておく.
* そうでない場合:
DiscoveredListIterator::make_referent_alive() で mark を付けて live 状態にする.
---------------------------------------- -}
iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
if (clear_referent) {
// NULL out referent pointer
iter.clear_referent();
} else {
// keep the referent around
iter.make_referent_alive();
}
{- -------------------------------------------
(1.1) (トレース出力)
---------------------------------------- -}
if (TraceReferenceGC) {
gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
clear_referent ? "cleared " : "",
iter.obj(), iter.obj()->blueprint()->internal_name());
}
{- -------------------------------------------
(1.1) (assert)
---------------------------------------- -}
assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
{- -------------------------------------------
(1.1) 次の要素へ
---------------------------------------- -}
iter.next();
}
{- -------------------------------------------
(1) 最後に, リストの終端にある番兵を指しているポインタも処理しておく.
---------------------------------------- -}
// Remember to keep sentinel pointer around
iter.update_discovered();
{- -------------------------------------------
(1) 引数で渡されていた VoidClosure (以下の complete_gc) を用いて,
以上の処理で mark を付けられたオブジェクトから再帰的に辿れる範囲全てにも mark を付ける
(= 再帰的な到達範囲全てを live にする).
---------------------------------------- -}
// Close the reachable set
complete_gc->do_void();
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.