changeset 7438:6e2a9ad88dba

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
author iveresov
date Wed, 08 Dec 2010 02:36:36 -0800
parents 270cb0bf17af
children 572e3f624901
files hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
diffstat 1 files changed, 4 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Dec 07 11:00:02 2010 -0800
+++ b/hotspot/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
       {