Skip to content

Commit 47a85ed

Browse files
authored
Fix invalid register values in arraycopy_epilogue barrier (#216)
1 parent 94f50cd commit 47a85ed

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

openjdk/barriers/mmtkObjectBarrier.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,41 @@ void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler*
8282
#endif
8383
}
8484

85+
void MMTkObjectBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) {
86+
// `count` or `dst` register values may get overwritten after the array copy, and `arraycopy_epilogue` can receive invalid addresses.
87+
// Save the register values here and restore them in `arraycopy_epilogue`.
88+
// See https://github.com/openjdk/jdk/blob/jdk-11%2B19/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp#L37-L50
89+
bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
90+
bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
91+
bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
92+
if (type == T_OBJECT || type == T_ARRAY) {
93+
if (!checkcast) {
94+
if (!obj_int) {
95+
// Save count for barrier
96+
__ movptr(r11, count);
97+
} else if (disjoint) {
98+
// Save dst in r11 in the disjoint case
99+
__ movq(r11, dst);
100+
}
101+
}
102+
}
103+
}
104+
85105
void MMTkObjectBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) {
106+
bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
107+
bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
108+
bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
86109
const bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
87110
if ((type == T_OBJECT || type == T_ARRAY) && !dest_uninitialized) {
111+
if (!checkcast) {
112+
if (!obj_int) {
113+
// Save count for barrier
114+
count = r11;
115+
} else if (disjoint) {
116+
// Use the saved dst in the disjoint case
117+
dst = r11;
118+
}
119+
}
88120
__ pusha();
89121
__ movptr(c_rarg0, src);
90122
__ movptr(c_rarg1, dst);

openjdk/barriers/mmtkObjectBarrier.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class MMTkObjectBarrierSetAssembler: public MMTkBarrierSetAssembler {
3232
protected:
3333
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const override;
3434
public:
35+
virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) override;
3536
virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) override;
3637
};
3738

0 commit comments

Comments
 (0)