changeset 16941:4e3b63e7a9f6

Fixing relock on interpreter when entering synchronized methods.
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Mon, 25 Aug 2014 11:32:04 -0700
parents c01648e41410
children ae0f235469db
files src/cpu/sparc/vm/sharedRuntime_sparc.cpp src/cpu/sparc/vm/templateInterpreter_sparc.cpp src/share/vm/graal/graalCodeInstaller.cpp
diffstat 3 files changed, 62 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon Aug 25 10:41:56 2014 -0700
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon Aug 25 11:32:04 2014 -0700
@@ -3433,6 +3433,9 @@
   if (UseStackBanging) {
     pad += StackShadowPages*16 + 32;
   }
+#ifdef GRAAL
+  pad += 32; // Increase the buffer size when compiling for GRAAL
+#endif
 #ifdef _LP64
   CodeBuffer buffer("deopt_blob", 2100+pad, 512);
 #else
@@ -3567,6 +3570,33 @@
   // Restore G2_thread
   __ get_thread();
 
+#ifdef GRAAL
+  // load throwing pc from JavaThread and patch it as the return address
+  // of the current frame. Then clear the field in JavaThread
+  __ block_comment("load throwing pc and patch return");
+  Address exception_pc(G2_thread, JavaThread::exception_pc_offset());
+  Label has_no_pc;
+  // TODO: Remove this weird check if we should patch the return pc
+  // This is because when graal decides to deoptimize and the ExceptionHandlerStub.java
+  // jumps back to this code and the I7 register contains the pc pointing to the begin
+  // of this code. If this is the case (PC within a certain range) then we need to patch
+  // the return pc.
+  // THIS NEEDS REWORK! (sa)
+  __ rdpc(L0);
+  __ sub(L0, I7, L0);
+  __ cmp(L0, 0xFFF);
+  __ br(Assembler::greater, false, Assembler::pt, has_no_pc);
+  __ delayed() -> nop();
+  __ cmp(L0, -0xFFF);
+  __ br(Assembler::less, false, Assembler::pt, has_no_pc);
+  __ delayed() -> nop();
+  __ ld_ptr(exception_pc, I7);
+  __ sub(I7, 8, I7);
+  __ st_ptr(G0, exception_pc);
+  __ bind(has_no_pc);
+  __ block_comment("/load throwing pc and patch return");
+#endif // GAAL
+
 #ifdef ASSERT
   {
     // verify that there is really an exception oop in exception_oop
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Mon Aug 25 10:41:56 2014 -0700
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Mon Aug 25 11:32:04 2014 -0700
@@ -199,6 +199,22 @@
 address InterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
   address entry = __ pc();
   __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache
+#ifdef GRAAL
+  // Check if we need to take lock at entry of synchronized method.
+  {
+    Label L;
+
+    //__ cmp(, 0);
+    Address pending_monitor_enter_addr(G2_thread, Thread::pending_monitorenter_offset());
+    __ ldbool(pending_monitor_enter_addr, Gtemp);  // Load if pending monitor enter
+    __ cmp_and_br_short(Gtemp, G0, Assembler::equal, Assembler::pn, L);
+    // Clear flag.
+    __ stbool(G0, pending_monitor_enter_addr);
+    // Take lock.
+    lock_method();
+    __ bind(L);
+  }
+#endif
   { Label L;
     Address exception_addr(G2_thread, Thread::pending_exception_offset());
     __ ld_ptr(exception_addr, Gtemp);  // Load pending exception.
@@ -1689,8 +1705,13 @@
         // make sure I5_savedSP and the entry frames notion of saved SP
         // agree.  This assertion duplicate a check in entry frame code
         // but catches the failure earlier.
-        assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP),
+        /*
+         * Sanzinger: This does not make sense to me, since when we call stub_call -> i2c, the i2c may change the
+         * sp, which then is not in sync with Lscratch anymore.
+         */
+        /**assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP),
                "would change callers SP");
+               */
       }
       if (caller->is_entry_frame()) {
         tty->print("entry ");
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Aug 25 10:41:56 2014 -0700
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Aug 25 11:32:04 2014 -0700
@@ -231,6 +231,8 @@
       Location::Type locationType;
       if (type == T_INT) {
         locationType = reference ? Location::narrowoop : Location::int_in_long;
+      } else if(type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) {
+        locationType = Location::int_in_long;
       } else if (type == T_FLOAT) {
         locationType = Location::int_in_long;
       } else if (type == T_LONG) {
@@ -264,7 +266,7 @@
 #ifdef TARGET_ARCH_sparc
       ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_FloatRegister(encoding)->as_VMReg()));
       if (type == T_DOUBLE) {
-        second = new ConstantIntValue(0);
+        second = value;
       }
       return value;
 #else
@@ -278,6 +280,8 @@
       locationType = reference ? Location::oop : Location::lng;
     } else if (type == T_INT) {
       locationType = reference ? Location::narrowoop : Location::normal;
+    } else if(type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) {
+      locationType = Location::normal;
     } else if (type == T_FLOAT) {
       assert(!reference, "unexpected type in stack slot");
       locationType = Location::normal;
@@ -289,6 +293,11 @@
       locationType = Location::oop;
     }
     jint offset = StackSlot::offset(value);
+#ifdef TARGET_ARCH_sparc
+    if(offset >= 0) {
+      offset += 128;
+    }
+#endif
     if (StackSlot::addFrameSize(value)) {
       offset += total_frame_size;
     }