From 1c384fd86ffe843afac779e85a98f6550a355923 Mon Sep 17 00:00:00 2001 From: Wenyu Zhao Date: Wed, 19 Apr 2023 10:45:43 -0700 Subject: [PATCH] Fix invalid register values in `arraycopy_epilogue` barrier --- openjdk/barriers/mmtkObjectBarrier.cpp | 32 ++++++++++++++++++++++++++ openjdk/barriers/mmtkObjectBarrier.hpp | 1 + 2 files changed, 33 insertions(+) diff --git a/openjdk/barriers/mmtkObjectBarrier.cpp b/openjdk/barriers/mmtkObjectBarrier.cpp index 8aea1c00..d95944bc 100644 --- a/openjdk/barriers/mmtkObjectBarrier.cpp +++ b/openjdk/barriers/mmtkObjectBarrier.cpp @@ -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); diff --git a/openjdk/barriers/mmtkObjectBarrier.hpp b/openjdk/barriers/mmtkObjectBarrier.hpp index e8124785..c6087dad 100644 --- a/openjdk/barriers/mmtkObjectBarrier.hpp +++ b/openjdk/barriers/mmtkObjectBarrier.hpp @@ -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; };