hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
{- -------------------------------------------
(1) CAS で, コピー元のオブジェクトの mark フィールドに, そのオブジェクト自身へのポインタを埋め込む.
(CAS で比較する値としては, 自分がそのオブジェクトの処理を開始した時点での mark 値とする.
CAS が成功してしまったら, 他のスレッドは誰もそのオブジェクトの処理をしていないということになる.)
---------------------------------------- -}
// Attempt to CAS in the header.
// This tests if the header is still the same as when
// this started. If it is the same (i.e., no forwarding
// pointer has been installed), then this thread owns
// it.
if (obj->cas_forward_to(obj, obj_mark)) {
{- -------------------------------------------
(1) CAS が成功した場合は, oopDesc::push_contents() で
オブジェクト内のポインタを PSPromotionManager 内のタスクキューに追加する.
その後, PSScavenge::oop_promotion_failed() で
(必要であれば) 元の mark 値を PSScavenge::_preserved_mark_stack に保存しておく.
(forwarding pointer を埋めてしまったので, そのままだと元の mark 情報が失われるため)
また, 確保が失敗したことが後から認識できるよう, _promotion_failed フィールドも変更しておく.
---------------------------------------- -}
// We won any races, we "own" this object.
assert(obj == obj->forwardee(), "Sanity");
obj->push_contents(this);
// Save the mark if needed
PSScavenge::oop_promotion_failed(obj, obj_mark);
{- -------------------------------------------
(1) CAS が失敗した場合は, 他の誰かがコピーしたということなので,
単にそのコピー先を取得するだけ.
---------------------------------------- -}
} else {
// We lost, someone else "owns" this object
guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed.");
// No unallocation to worry about.
obj = obj->forwardee();
}
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
#ifdef DEBUG
if (TraceScavenge) {
gclog_or_tty->print_cr("{%s %s 0x%x (%d)}",
"promotion-failure",
obj->blueprint()->internal_name(),
obj, obj->size());
}
#endif
{- -------------------------------------------
(1) 結果をリターン
---------------------------------------- -}
return obj;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.