From 195fc83d541ad8144834f8ad603f83fe960e4b09 Mon Sep 17 00:00:00 2001 From: johnc Date: Thu, 29 Oct 2009 09:42:26 -0700 Subject: [PATCH] 6889740: G1: OpenDS fails with "unhandled exception in compiled code" Summary: Incorrect code was being generated for the store operation in the null case of the aastore bytecode template. The bad code was generated by the store_heap_oop routine which takes a Register as its second argument. Passing NULL_WORD (0) as the second argument causes the value to be converted to Register(0), which is rax. Thus the generated store was "mov (dst), $rax" instead of "mov (dst), $0x0". Changed calls to store_heap_oop that pass NULL_WORD as the second argument to a new routine store_heap_oop_null. Reviewed-by: kvn, twisti --- src/cpu/x86/vm/assembler_x86.cpp | 9 +++++++++ src/cpu/x86/vm/assembler_x86.hpp | 11 +++++++++++ src/cpu/x86/vm/templateTable_x86_64.cpp | 6 +++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/cpu/x86/vm/assembler_x86.cpp b/src/cpu/x86/vm/assembler_x86.cpp index 075094930..aa93bc8f2 100644 --- a/src/cpu/x86/vm/assembler_x86.cpp +++ b/src/cpu/x86/vm/assembler_x86.cpp @@ -8214,6 +8214,15 @@ void MacroAssembler::store_heap_oop(Address dst, Register src) { } } +// Used for storing NULLs. +void MacroAssembler::store_heap_oop_null(Address dst) { + if (UseCompressedOops) { + movl(dst, (int32_t)NULL_WORD); + } else { + movslq(dst, (int32_t)NULL_WORD); + } +} + // Algorithm must match oop.inline.hpp encode_heap_oop. void MacroAssembler::encode_heap_oop(Register r) { assert (UseCompressedOops, "should be compressed"); diff --git a/src/cpu/x86/vm/assembler_x86.hpp b/src/cpu/x86/vm/assembler_x86.hpp index 2d61a3cf0..7aa0d0877 100644 --- a/src/cpu/x86/vm/assembler_x86.hpp +++ b/src/cpu/x86/vm/assembler_x86.hpp @@ -1682,6 +1682,17 @@ class MacroAssembler: public Assembler { void load_heap_oop(Register dst, Address src); void store_heap_oop(Address dst, Register src); + + // This dummy is to prevent a call to store_heap_oop from + // converting a zero (like NULL) into a Register by giving + // the compiler two choices it can't resolve + + void store_heap_oop(Address dst, void* dummy); + + // Used for storing NULL. All other oop constants should be + // stored using routines that take a jobject. + void store_heap_oop_null(Address dst); + void encode_heap_oop(Register r); void decode_heap_oop(Register r); void encode_heap_oop_not_null(Register r); diff --git a/src/cpu/x86/vm/templateTable_x86_64.cpp b/src/cpu/x86/vm/templateTable_x86_64.cpp index 48285f46d..1180227b5 100644 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp @@ -139,7 +139,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm, } __ g1_write_barrier_pre(rdx, r8, rbx, val != noreg); if (val == noreg) { - __ store_heap_oop(Address(rdx, 0), NULL_WORD); + __ store_heap_oop_null(Address(rdx, 0)); } else { __ store_heap_oop(Address(rdx, 0), val); __ g1_write_barrier_post(rdx, val, r8, rbx); @@ -152,7 +152,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm, case BarrierSet::CardTableExtension: { if (val == noreg) { - __ store_heap_oop(obj, NULL_WORD); + __ store_heap_oop_null(obj); } else { __ store_heap_oop(obj, val); // flatten object address if needed @@ -168,7 +168,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm, case BarrierSet::ModRef: case BarrierSet::Other: if (val == noreg) { - __ store_heap_oop(obj, NULL_WORD); + __ store_heap_oop_null(obj); } else { __ store_heap_oop(obj, val); } -- GitLab