hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
// Do an oop store like *(base + index + offset) = val
// index can be noreg,
static void do_oop_store(InterpreterMacroAssembler* _masm,
Register base,
Register index,
int offset,
Register val,
Register tmp,
BarrierSet::Name barrier,
bool precise) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(tmp != val && tmp != base && tmp != index, "register collision");
assert(index == noreg || offset == 0, "only one offset");
{- -------------------------------------------
(1) (この関数の処理は, barrier set の種別 (= GC アルゴリズムの種別) に応じて2通りのパスが存在
* G1GC の場合 (BarrierSet::G1SATBCT または BarrierSet::G1SATBCTLogging の場合)
* G1GC 以外の場合 (BarrierSet::CardTableModRef または BarrierSet::CardTableExtension の場合))
(なお, 正確には上記以外の場合 (BarrierSet::ModRef, BarrierSet::Other, またはそれ以外) というパスも書かれているが,
Should_Not_Reach_Here() になるだけ)
---------------------------------------- -}
switch (barrier) {
{- -------------------------------------------
(1) (以下は G1GC の場合のパス)
---------------------------------------- -}
#ifndef SERIALGC
case BarrierSet::G1SATBCT:
case BarrierSet::G1SATBCTLogging:
{
{- -------------------------------------------
(1.1) コード生成:
「MacroAssembler::g1_write_barrier_pre() が生成するコードにより,
SATB 用の Write Barrier 処理を (その必要があれば) 実行する.」
---------------------------------------- -}
// Load and record the previous value.
__ g1_write_barrier_pre(base, index, offset,
noreg /* pre_val */,
tmp, true /*preserve_o_regs*/);
{- -------------------------------------------
(1.1) コード生成:
「MacroAssembler::store_heap_oop() が生成するコードにより,
対象のポインタ値の書き換えを行う」
---------------------------------------- -}
if (index == noreg ) {
assert(Assembler::is_simm13(offset), "fix this code");
__ store_heap_oop(val, base, offset);
} else {
__ store_heap_oop(val, base, index);
}
{- -------------------------------------------
(1.1) コード生成: (ただし, 書き込み元が G0 レジスタ(= 0) の場合は生成しない)
「MacroAssembler::g1_write_barrier_pre() が生成するコードにより,
書き換え箇所に対応する Barrier Set 中の値を dirty にする.」
(G0 レジスタの場合に生成しないのは, コード生成時点で NULL (= 記録の必要が無い) と保証できるため)
(なお, precise 引数が true の場合には,
base で指定された値に offset/index 分も足し込んだ正確なアドレスを記録する.
そうでない場合には base の値だけを記録する)
---------------------------------------- -}
// No need for post barrier if storing NULL
if (val != G0) {
if (precise) {
if (index == noreg) {
__ add(base, offset, base);
} else {
__ add(base, index, base);
}
}
__ g1_write_barrier_post(base, val, tmp);
}
}
break;
#endif // SERIALGC
{- -------------------------------------------
(1) (以下は G1GC 以外の場合のパス)
---------------------------------------- -}
case BarrierSet::CardTableModRef:
case BarrierSet::CardTableExtension:
{
{- -------------------------------------------
(1.1) コード生成:
「MacroAssembler::store_heap_oop() が生成するコードにより,
対象のポインタ値の書き換えを行う」
---------------------------------------- -}
if (index == noreg ) {
assert(Assembler::is_simm13(offset), "fix this code");
__ store_heap_oop(val, base, offset);
} else {
__ store_heap_oop(val, base, index);
}
{- -------------------------------------------
(1.1) コード生成: (ただし, 書き込み元が G0 レジスタ(= 0) の場合は生成しない)
「MacroAssembler::card_write_barrier_post() が生成するコードにより,
書き換え箇所に対応する Barrier Set 中の値を dirty にする.」
(G0 レジスタの場合に生成しないのは, コード生成時点で NULL (= 記録の必要が無い) と保証できるため)
(なお, precise 引数が true の場合には,
base で指定された値に offset/index 分も足し込んだ正確なアドレスを記録する.
そうでない場合には base の値だけを記録する)
---------------------------------------- -}
// No need for post barrier if storing NULL
if (val != G0) {
if (precise) {
if (index == noreg) {
__ add(base, offset, base);
} else {
__ add(base, index, base);
}
}
__ card_write_barrier_post(base, val, tmp);
}
}
break;
{- -------------------------------------------
(1) (以下のパスに来ることはあり得ない)
(もし来てしまったら HotSpot 内のバグ)
---------------------------------------- -}
case BarrierSet::ModRef:
case BarrierSet::Other:
ShouldNotReachHere();
break;
default :
ShouldNotReachHere();
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.