6889740: G1: OpenDS fails with "unhandled exception in compiled code"
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
This commit is contained in:
parent
cd43e74d4e
commit
bf0f699b33
@ -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.
|
// Algorithm must match oop.inline.hpp encode_heap_oop.
|
||||||
void MacroAssembler::encode_heap_oop(Register r) {
|
void MacroAssembler::encode_heap_oop(Register r) {
|
||||||
assert (UseCompressedOops, "should be compressed");
|
assert (UseCompressedOops, "should be compressed");
|
||||||
|
@ -1682,6 +1682,17 @@ class MacroAssembler: public Assembler {
|
|||||||
|
|
||||||
void load_heap_oop(Register dst, Address src);
|
void load_heap_oop(Register dst, Address src);
|
||||||
void store_heap_oop(Address dst, Register 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 encode_heap_oop(Register r);
|
||||||
void decode_heap_oop(Register r);
|
void decode_heap_oop(Register r);
|
||||||
void encode_heap_oop_not_null(Register r);
|
void encode_heap_oop_not_null(Register r);
|
||||||
|
@ -139,7 +139,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
|
|||||||
}
|
}
|
||||||
__ g1_write_barrier_pre(rdx, r8, rbx, val != noreg);
|
__ g1_write_barrier_pre(rdx, r8, rbx, val != noreg);
|
||||||
if (val == noreg) {
|
if (val == noreg) {
|
||||||
__ store_heap_oop(Address(rdx, 0), NULL_WORD);
|
__ store_heap_oop_null(Address(rdx, 0));
|
||||||
} else {
|
} else {
|
||||||
__ store_heap_oop(Address(rdx, 0), val);
|
__ store_heap_oop(Address(rdx, 0), val);
|
||||||
__ g1_write_barrier_post(rdx, val, r8, rbx);
|
__ g1_write_barrier_post(rdx, val, r8, rbx);
|
||||||
@ -152,7 +152,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
|
|||||||
case BarrierSet::CardTableExtension:
|
case BarrierSet::CardTableExtension:
|
||||||
{
|
{
|
||||||
if (val == noreg) {
|
if (val == noreg) {
|
||||||
__ store_heap_oop(obj, NULL_WORD);
|
__ store_heap_oop_null(obj);
|
||||||
} else {
|
} else {
|
||||||
__ store_heap_oop(obj, val);
|
__ store_heap_oop(obj, val);
|
||||||
// flatten object address if needed
|
// flatten object address if needed
|
||||||
@ -168,7 +168,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
|
|||||||
case BarrierSet::ModRef:
|
case BarrierSet::ModRef:
|
||||||
case BarrierSet::Other:
|
case BarrierSet::Other:
|
||||||
if (val == noreg) {
|
if (val == noreg) {
|
||||||
__ store_heap_oop(obj, NULL_WORD);
|
__ store_heap_oop_null(obj);
|
||||||
} else {
|
} else {
|
||||||
__ store_heap_oop(obj, val);
|
__ store_heap_oop(obj, val);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user