[aarch64-port-dev ] Fix code that jumps from interpreter to OSR method.

Andrew Haley aph at redhat.com
Thu Jan 23 08:47:39 PST 2014


We've been getting occasional bus errors when compiling.

The problem is that the OSR code does not correctly pop the
interpreter frame.  Two things are wrong: firstly, the stack pointer
isn't aligned when it returns, which is the cause of the bus error.
Secondly, the nmethod is saved in rmethod (AKA r12) around the call to
SharedRuntime::OSR_migration_begin, but r12 is a call-clobbered
register.

Andrew.


# HG changeset patch
# User aph
# Date 1390495433 18000
#      Thu Jan 23 11:43:53 2014 -0500
# Node ID 1e2c91a63fc3019b4958ae443ba66d6862e8e19f
# Parent  813458fe14eeb9da65e68a12abb85ae1343b2b2d
Fix code that jumps from interpreter to OSR method.

diff -r 813458fe14ee -r 1e2c91a63fc3 src/cpu/aarch64/vm/templateTable_aarch64.cpp
--- a/src/cpu/aarch64/vm/templateTable_aarch64.cpp      Wed Jan 22 16:29:43 2014 +0000
+++ b/src/cpu/aarch64/vm/templateTable_aarch64.cpp      Thu Jan 23 11:43:53 2014 -0500
@@ -1759,26 +1759,24 @@
       // We need to prepare to execute the OSR method. First we must
       // migrate the locals and monitors off of the stack.

-      __ mov(rmethod, r0);                             // save the nmethod
+      __ mov(r19, r0);                             // save the nmethod

       call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin));

       // r0 is OSR buffer, move it to expected parameter location
       __ mov(j_rarg0, r0);

-      // We use j_rarg definitions here so that registers don't conflict as parameter
-      // registers change across platforms as we are in the midst of a calling
-      // sequence to the OSR nmethod and we don't want collision. These are NOT parameters.
-
-      // const Register retaddr = j_rarg2;
-      const Register sender_sp = j_rarg1;
-
-      // pop the interpreter frame
-      __ ldr(sender_sp, Address(rfp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp
-      __ leave(); // remove frame anchor (leaves return address in lr)
-      __ mov(sp, sender_sp);                   // set sp to sender sp
+      // remove activation
+      // get sender esp
+      __ ldr(esp,
+         Address(rfp, frame::interpreter_frame_sender_sp_offset * wordSize));
+      // remove frame anchor
+      __ leave();
+      // Ensure compiled code always sees stack at proper alignment
+      __ andr(sp, esp, -16);
+
       // and begin the OSR nmethod
-      __ ldr(rscratch1, Address(rmethod, nmethod::osr_entry_point_offset()));
+      __ ldr(rscratch1, Address(r19, nmethod::osr_entry_point_offset()));
       __ br(rscratch1);
     }
   }



More information about the aarch64-port-dev mailing list