diff mbox

Patch to fix SEGV/SIGBUS in client with +CompressedOops

Message ID 1390408832.4665.8.camel@localhost.localdomain
State New
Headers show

Commit Message

Edward Nevill Jan. 22, 2014, 4:40 p.m. UTC
Hi,

The following patch fixes a problem in the client compiler whereby the cmpval in emit_compare_and_swap was being encoded as a compressed oop while still live.

This variously resulted in a SIGBUS or SIGSEGV depending on whether the resultant compressed oop was aligned or not.

The patch uses a temp to encode the oop.

I have also incorporation a fix to the problem spotted by Andrew Dinn whereby casw did a cbnz rather than a cbnzw on a compressed oop.

There is also a minor tweak to use the two arg version of encode_heap_oop(dest, src) instead of the single arg version which removes two redundant moves.

OK to push?

Ed.

--- CUT HERE ---
exporting patch:
# HG changeset patch
# User Edward Nevill edward.nevill@linaro.org
# Date 1390408183 0
#      Wed Jan 22 16:29:43 2014 +0000
# Node ID 813458fe14eeb9da65e68a12abb85ae1343b2b2d
# Parent  895bbf967b692fecdc4919deeb8a30907b5bd2cb
- Add fix spotted by Andrew Dinn to do cbnzw instead of cbnz in casw
- Use temp reg in emit_compare_and_swap to avoid corrupting cmpval
- Minor tweak to use 2 arg vsn of encode_heap_oop
diff mbox

Patch

diff -r 895bbf967b69 -r 813458fe14ee src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp    Fri Jan 17 13:39:19 2014 -0500
+++ b/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp    Wed Jan 22 16:29:43 2014 +0000
@@ -1584,7 +1584,7 @@ 
   __ stlxrw(rscratch1, newval, addr);
   // retry so we only ever return after a load fails to compare
   // ensures we don't return a stale value after a failed write.
-  __ cbnz(rscratch1, retry_load);
+  __ cbnzw(rscratch1, retry_load);
   __ bind(nope);
 }

@@ -1615,10 +1615,12 @@ 

   if (op->code() == lir_cas_obj) {
     if (UseCompressedOops) {
-      __ encode_heap_oop(cmpval);
-      __ mov(rscratch2, newval);
+      Register t1 = op->tmp1()->as_register();
+      assert(op->tmp1()->is_valid(), "must be");
+      __ encode_heap_oop(t1, cmpval);
+      cmpval = t1;
+      __ encode_heap_oop(rscratch2, newval);
       newval = rscratch2;
-      __ encode_heap_oop(newval);
       casw(addr, newval, cmpval);
     } else {
       casl(addr, newval, cmpval);
--- CUT HERE ---