Skip to content

Fix invalid register values in arraycopy_epilogue barrier #216

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions openjdk/barriers/mmtkObjectBarrier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,41 @@ void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler*
#endif
}

void MMTkObjectBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) {
// `count` or `dst` register values may get overwritten after the array copy, and `arraycopy_epilogue` can receive invalid addresses.
// Save the register values here and restore them in `arraycopy_epilogue`.
// See https://github.com/openjdk/jdk/blob/jdk-11%2B19/src/hotspot/cpu/x86/gc/shared/modRefBarrierSetAssembler_x86.cpp#L37-L50
bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
if (type == T_OBJECT || type == T_ARRAY) {
if (!checkcast) {
if (!obj_int) {
// Save count for barrier
__ movptr(r11, count);
} else if (disjoint) {
// Save dst in r11 in the disjoint case
__ movq(r11, dst);
}
}
}
}

void MMTkObjectBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) {
bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
const bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
if ((type == T_OBJECT || type == T_ARRAY) && !dest_uninitialized) {
if (!checkcast) {
if (!obj_int) {
// Save count for barrier
count = r11;
} else if (disjoint) {
// Use the saved dst in the disjoint case
dst = r11;
}
}
__ pusha();
__ movptr(c_rarg0, src);
__ movptr(c_rarg1, dst);
Expand Down
1 change: 1 addition & 0 deletions openjdk/barriers/mmtkObjectBarrier.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class MMTkObjectBarrierSetAssembler: public MMTkBarrierSetAssembler {
protected:
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const override;
public:
virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) override;
virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) override;
};

Expand Down