hotspot/src/share/vm/runtime/biasedLocking.cpp
void BiasedLocking::preserve_marks() {
{- -------------------------------------------
(1) UseBiasedLocking オプションが指定されていない場合は, 何もすることはないので, ここでリターン.
---------------------------------------- -}
if (!UseBiasedLocking)
return;
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint");
assert(_preserved_oop_stack == NULL, "double initialization");
assert(_preserved_mark_stack == NULL, "double initialization");
{- -------------------------------------------
(1) (GC 時に待避する mark 量を減らすため, bias されている mark についても,
普通は GC 時にそのまま初期状態に戻すだけにしている.
ただし, 現在ロックされているものについてだけは保存しておかないとまずいので,
この関数で待避を行っている.
なお, 待避しないといけない mark の数はヒープ内のオブジェクト全体に比べればずいぶん小さいはず, とのこと.)
---------------------------------------- -}
// In order to reduce the number of mark words preserved during GC
// due to the presence of biased locking, we reinitialize most mark
// words to the class's prototype during GC -- even those which have
// a currently valid bias owner. One important situation where we
// must not clobber a bias is when a biased object is currently
// locked. To handle this case we iterate over the currently-locked
// monitors in a prepass and, if they are biased, preserve their
// mark words here. This should be a relatively small set of objects
// especially compared to the number of objects in the heap.
{- -------------------------------------------
(1) mark を保存しておくための領域を確保する (以下の _preserved_mark_stack と _preserved_oop_stack).
---------------------------------------- -}
_preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(10, true);
_preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<Handle>(10, true);
{- -------------------------------------------
(1) 全ての JavaThread に対して, スタックフレーム内の全ての MonitorInfo を調査する.
もし, ロックを取得されているオブジェクトで mark フィールドが bias pattern のものがあれば,
その情報を _preserved_mark_stack と _preserved_oop_stack に記録していく.
---------------------------------------- -}
ResourceMark rm;
Thread* cur = Thread::current();
for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
if (thread->has_last_Java_frame()) {
RegisterMap rm(thread);
for (javaVFrame* vf = thread->last_java_vframe(&rm); vf != NULL; vf = vf->java_sender()) {
GrowableArray<MonitorInfo*> *monitors = vf->monitors();
if (monitors != NULL) {
int len = monitors->length();
// Walk monitors youngest to oldest
for (int i = len - 1; i >= 0; i--) {
MonitorInfo* mon_info = monitors->at(i);
if (mon_info->owner_is_scalar_replaced()) continue;
oop owner = mon_info->owner();
if (owner != NULL) {
markOop mark = owner->mark();
if (mark->has_bias_pattern()) {
_preserved_oop_stack->push(Handle(cur, owner));
_preserved_mark_stack->push(mark);
}
}
}
}
}
}
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.