# HG changeset patch # User iveresov # Date 1291804596 28800 # Node ID ec8c74742417f37e59c9d7c258a9754b0d6b77ae # Parent 5fe0781a8560ad3a177cc5aa48177dd40f9ca503 7005241: C1: SEGV in java.util.concurrent.LinkedTransferQueue.xfer() with compressed oops Summary: 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 diff -r 5fe0781a8560 -r ec8c74742417 src/cpu/x86/vm/c1_LIRAssembler_x86.cpp --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Tue Dec 07 11:00:02 2010 -0800 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Dec 08 02:36:36 2010 -0800 @@ -1993,15 +1993,14 @@ if ( op->code() == lir_cas_obj) { #ifdef _LP64 if (UseCompressedOops) { - __ mov(rscratch1, cmpval); __ encode_heap_oop(cmpval); - __ mov(rscratch2, newval); - __ encode_heap_oop(rscratch2); + __ mov(rscratch1, newval); + __ encode_heap_oop(rscratch1); if (os::is_MP()) { __ lock(); } - __ cmpxchgl(rscratch2, Address(addr, 0)); - __ mov(cmpval, rscratch1); + // cmpval (rax) is implicitly used by this instruction + __ cmpxchgl(rscratch1, Address(addr, 0)); } else #endif {