comparison src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @ 2013:ec8c74742417

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 5ddfcf4b079e
children 037c727f35fb
comparison
equal deleted inserted replaced
2012:5fe0781a8560 2013:ec8c74742417
1991 assert(newval != addr, "new value and addr must be in different registers"); 1991 assert(newval != addr, "new value and addr must be in different registers");
1992 1992
1993 if ( op->code() == lir_cas_obj) { 1993 if ( op->code() == lir_cas_obj) {
1994 #ifdef _LP64 1994 #ifdef _LP64
1995 if (UseCompressedOops) { 1995 if (UseCompressedOops) {
1996 __ mov(rscratch1, cmpval);
1997 __ encode_heap_oop(cmpval); 1996 __ encode_heap_oop(cmpval);
1998 __ mov(rscratch2, newval); 1997 __ mov(rscratch1, newval);
1999 __ encode_heap_oop(rscratch2); 1998 __ encode_heap_oop(rscratch1);
2000 if (os::is_MP()) { 1999 if (os::is_MP()) {
2001 __ lock(); 2000 __ lock();
2002 } 2001 }
2003 __ cmpxchgl(rscratch2, Address(addr, 0)); 2002 // cmpval (rax) is implicitly used by this instruction
2004 __ mov(cmpval, rscratch1); 2003 __ cmpxchgl(rscratch1, Address(addr, 0));
2005 } else 2004 } else
2006 #endif 2005 #endif
2007 { 2006 {
2008 if (os::is_MP()) { 2007 if (os::is_MP()) {
2009 __ lock(); 2008 __ lock();