7005241: C1: SEGV in java.util.concurrent.LinkedTransferQueue.xfer() with compressed oops

Implementation of the CAS primitive for x64 compressed oops was incorrect. It kills rscratch2 register (r11), which is allocatable in C1. Also, we don't need to restore cmpval as it's never used after that, so we need only one temporary register, which can be scratch1.

Reviewed-by: kvn, never
This commit is contained in:
Igor Veresov 2010-12-08 02:36:36 -08:00
parent 797fb02b41
commit eafb22164b

View File

@ -1993,15 +1993,14 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {
if ( op->code() == lir_cas_obj) { if ( op->code() == lir_cas_obj) {
#ifdef _LP64 #ifdef _LP64
if (UseCompressedOops) { if (UseCompressedOops) {
__ mov(rscratch1, cmpval);
__ encode_heap_oop(cmpval); __ encode_heap_oop(cmpval);
__ mov(rscratch2, newval); __ mov(rscratch1, newval);
__ encode_heap_oop(rscratch2); __ encode_heap_oop(rscratch1);
if (os::is_MP()) { if (os::is_MP()) {
__ lock(); __ lock();
} }
__ cmpxchgl(rscratch2, Address(addr, 0)); // cmpval (rax) is implicitly used by this instruction
__ mov(cmpval, rscratch1); __ cmpxchgl(rscratch1, Address(addr, 0));
} else } else
#endif #endif
{ {