Skip to content

Commit b448168

Browse files
authored
Skip val register in ObjectBarrier impl (#294)
`MMTkBarrierSetAssembler::store_at` calls `object_reference_write_post` after calling `BarrierSetAssembler::store_at`. However, `BarrierSetAssembler::store_at` modifies the `val` register to compress its value in place. Consequently, `object_reference_write_post` will see a compressed pointer in the `val` register. This PR makes two changes. Firstly, in `MMTkObjectBarrierSetAssembler::object_reference_write_post`, we simply set both `c_rarg1` and `c_rarg2` to 0 before calling the write barrier slow path. We exploit the semantics of the `ObjectBarrier` that it simply logs the object without looking at the slot or the target. This will fix the [assertion error](#291) because 0 will be interpreted as a `None` of type `Option<ObjectReference>`. Secondly, we add a `bool compensate_val_reg` parameter to `MMTkBarrierSetAssembler::object_reference_write_post` so that if we call it after `BarrierSetAssembler::store_at`, we can give `object_reference_write_post` a chance to decompress the compressed oop in the `val`. This is intended for implementing *other barriers introduced in the future* that may use the `val` register, and keep the developers informed that the `val` register is mutated in `BarrierSetAssembler::store_at`. Fixes: #291 Related PR: #293
1 parent 1fcc9f1 commit b448168

File tree

4 files changed

+23
-10
lines changed

4 files changed

+23
-10
lines changed

.github/scripts/ci-test-minimal.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ MMTK_PLAN=MarkSweep runbms_dacapo2006_with_heap_multiplier fop 8
2727
MMTK_PLAN=NoGC runbms_dacapo2006_with_heap_size fop 1000 1000
2828
# Test heap resizing
2929
MMTK_PLAN=GenImmix runbms_dacapo2006_with_heap_size fop 20 100
30+
# Test compressed oops with heap range > 4GB
31+
MMTK_PLAN=GenImmix runbms_dacapo2006_with_heap_size fop 20 5000
3032
# Test no compressed oop
3133
MMTK_PLAN=GenImmix runbms_dacapo2006_with_heap_multiplier fop 4 -XX:-UseCompressedOops -XX:-UseCompressedClassPointers
3234

openjdk/barriers/mmtkObjectBarrier.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,11 @@ void MMTkObjectBarrierSetRuntime::object_reference_write_post(oop src, oop* slot
3838

3939
#define __ masm->
4040

41-
void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {
41+
void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2, bool compensate_val_reg) const {
4242
if (can_remove_barrier(decorators, val, /* skip_const_null */ true)) return;
43+
44+
bool is_not_null = (decorators & IS_NOT_NULL) != 0;
45+
4346
Register obj = dst.base();
4447
#if MMTK_ENABLE_BARRIER_FASTPATH
4548
Label done;
@@ -67,17 +70,22 @@ void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler*
6770
__ andptr(tmp2, 1);
6871
__ cmpptr(tmp2, 1);
6972
__ jcc(Assembler::notEqual, done);
73+
#endif
7074

7175
__ movptr(c_rarg0, obj);
72-
__ lea(c_rarg1, dst);
73-
__ movptr(c_rarg2, val == noreg ? (int32_t) NULL_WORD : val);
74-
__ call_VM_leaf_base(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_slow_call), 3);
76+
__ xorptr(c_rarg1, c_rarg1);
77+
// Note: If `compensate_val_reg == true && UseCompressedOops === true`, the `val` register will be
78+
// holding a compressed pointer to the target object. If the write barrier needs to know the
79+
// target, we will need to decompress it before passing it to the barrier slow path. However,
80+
// since we know the semantics of `mmtk::plan::barriers::ObjectBarrier`, i.e. it logs the object
81+
// without looking at the `slot` or the `target` parameter at all, we simply pass nullptr to both
82+
// parameters.
83+
__ xorptr(c_rarg2, c_rarg2);
7584

85+
#if MMTK_ENABLE_BARRIER_FASTPATH
86+
__ call_VM_leaf_base(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_slow_call), 3);
7687
__ bind(done);
7788
#else
78-
__ movptr(c_rarg0, obj);
79-
__ lea(c_rarg1, dst);
80-
__ movptr(c_rarg2, val == noreg ? (int32_t) NULL_WORD : val);
8189
__ call_VM_leaf_base(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_post_call), 3);
8290
#endif
8391
}

openjdk/barriers/mmtkObjectBarrier.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class MMTkObjectBarrierSetRuntime: public MMTkBarrierSetRuntime {
3030

3131
class MMTkObjectBarrierSetAssembler: public MMTkBarrierSetAssembler {
3232
protected:
33-
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const override;
33+
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2, bool compensate_val_reg) const override;
3434
public:
3535
virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) override;
3636
virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) override;

openjdk/mmtkBarrierSetAssembler_x86.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ class MMTkBarrierSetAssembler: public BarrierSetAssembler {
1616
/// Full pre-barrier
1717
virtual void object_reference_write_pre(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {}
1818
/// Full post-barrier
19-
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {}
19+
/// `compensate_val_reg` is true if this function is called after `BarrierSetAssembler::store_at` which compresses the pointer in the `val` register in place.
20+
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2, bool compensate_val_reg) const {}
2021

2122
/// Barrier elision test
2223
virtual bool can_remove_barrier(DecoratorSet decorators, Register val, bool skip_const_null) const {
@@ -34,7 +35,9 @@ class MMTkBarrierSetAssembler: public BarrierSetAssembler {
3435
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Address dst, Register val, Register tmp1, Register tmp2) override {
3536
if (type == T_OBJECT || type == T_ARRAY) object_reference_write_pre(masm, decorators, dst, val, tmp1, tmp2);
3637
BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2);
37-
if (type == T_OBJECT || type == T_ARRAY) object_reference_write_post(masm, decorators, dst, val, tmp1, tmp2);
38+
// BarrierSetAssembler::store_at modifies val and make it compressed if UseCompressedOops is true.
39+
// We need to compensate for this change and decode it in object_reference_write_post.
40+
if (type == T_OBJECT || type == T_ARRAY) object_reference_write_post(masm, decorators, dst, val, tmp1, tmp2, true);
3841
}
3942

4043
/// Generate C1 write barrier slow-call stub

0 commit comments

Comments
 (0)