Mercurial > hg > graal-compiler
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(); |