32
32
// tail _Z32object_reference_write_slow_callPvS_m
33
33
void MMTkObjectBarrierSetAssembler::object_reference_write_post (MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {
34
34
// tmp1 and tmp2 is from MacroAssembler::access_store_at
35
- // See tmplateTable_riscv , we don't actually get any temporary register.
35
+ // For do_oop_store , we have three tmps, x28/t3, x29/t4, x13/a3
36
36
// printf("object_reference_write_post\n");
37
37
if (can_remove_barrier (decorators, val, /* skip_const_null */ true )) return ;
38
- #if MMTK_ENABLE_BARRIER_FASTPATH
39
- Label done;
40
-
41
38
Register obj = dst.base ();
42
39
assert (obj->is_valid (), " dst must be an offset from a base register" );
43
- assert_different_registers (obj, t0, t1);
44
- assert_different_registers (val, t0, t1);
45
-
46
- // t0 = load-byte (SIDE_METADATA_BASE_ADDRESS + (obj >> 6));
47
- __ mv (t0, obj);
48
- __ srli (t0, t0, 6 ); // t0 = obj >> 6;
49
- __ li (t1, SIDE_METADATA_BASE_ADDRESS);
50
- __ add (t0, t0, t1); // t0 = SIDE_METADATA_BASE_ADDRESS + (obj >> 6);
51
- __ lbu (t0, Address (t0, 0 ));
52
- // t1 = (obj >> 3) & 7
53
- __ mv (t1, obj);
54
- __ srli (t1, t1, 3 );
55
- __ andi (t1, t1, 7 );
56
- // t0 = t0 >> t1
57
- __ sraw (t0, t0, t1);
58
- // if ((t0 & 1) == 1) fall through to slowpath;
59
- __ andi (t0, t0, 1 );
60
- __ bnez (t0, done); // (t0 & 1) == 1 is equivalent to (t0 & 1) != 0
40
+ RegSet saved = RegSet::of (obj); // see void G1BarrierSetAssembler::g1_write_barrier_post
41
+ __ push_reg (saved, sp);
42
+ #if MMTK_ENABLE_BARRIER_FASTPATH
43
+ Label done;
44
+ assert_different_registers (obj, tmp1, tmp2);
45
+ assert_different_registers (val, tmp1, tmp2);
46
+ assert (tmp1->is_valid (), " need temp reg" );
47
+ assert (tmp2->is_valid (), " need temp reg" );
48
+ // tmp1 = load-byte (SIDE_METADATA_BASE_ADDRESS + (obj >> 6));
49
+ __ mv (tmp1, obj);
50
+ __ srli (tmp1, tmp1, 6 ); // tmp1 = obj >> 6;
51
+ __ li (tmp2, SIDE_METADATA_BASE_ADDRESS);
52
+ __ add (tmp1, tmp1, tmp2); // tmp1 = SIDE_METADATA_BASE_ADDRESS + (obj >> 6);
53
+ __ lbu (tmp1, Address (tmp1, 0 ));
54
+ // tmp2 = (obj >> 3) & 7
55
+ __ mv (tmp2, obj);
56
+ __ srli (tmp2, tmp2, 3 );
57
+ __ andi (tmp2, tmp2, 7 );
58
+ // tmp1 = tmp1 >> tmp2
59
+ __ sraw (tmp1, tmp1, tmp2);
60
+ // if ((tmp1 & 1) == 1) fall through to slowpath;
61
+ __ andi (tmp1, tmp1, 1 );
62
+ __ bnez (tmp1, done); // (tmp1 & 1) == 1 is equivalent to (tmp1 & 1) != 0
61
63
// setup calling convention
62
64
__ mv (c_rarg0, obj);
63
65
__ la (c_rarg1, dst);
@@ -71,6 +73,7 @@ void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler*
71
73
__ mv (c_rarg2, val == noreg ? zr : val);
72
74
__ call_VM_leaf_base (FN_ADDR (MMTkBarrierSetRuntime::object_reference_write_post_call), 3 );
73
75
#endif
76
+ __ pop_reg (saved, sp);
74
77
}
75
78
76
79
void MMTkObjectBarrierSetAssembler::arraycopy_epilogue (MacroAssembler* masm, DecoratorSet decorators, bool is_oop,
0 commit comments