changeset 2607:008adfd6d850

Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction. This is necessary to ensure correct continuation in the interpreter when the stateBefore is used as a deoptimization point.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Fri, 06 May 2011 17:47:17 +0200
parents f21f430a6ef2
children b1b58f908044
files graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java src/cpu/x86/vm/c1_Runtime1_x86.cpp src/share/vm/c1/c1_Runtime1.cpp src/share/vm/c1/c1_Runtime1.hpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/sharedRuntime.cpp src/share/vm/runtime/sharedRuntime.hpp src/share/vm/runtime/vframeArray.cpp
diffstat 8 files changed, 38 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Fri May 06 16:21:10 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Fri May 06 17:47:17 2011 +0200
@@ -787,26 +787,29 @@
             genResolveClass(RiType.Representation.StaticFields, holder, isInitialized, cpi);
         }
 
+        FrameState stateBefore = curState.immutableCopy(bci());
         Value[] args = curState.popArguments(target.signature().argumentSlots(false));
-        appendInvoke(INVOKESTATIC, target, args, cpi, constantPool);
+        appendInvoke(INVOKESTATIC, target, args, cpi, constantPool, stateBefore);
     }
 
     void genInvokeInterface(RiMethod target, int cpi, RiConstantPool constantPool) {
+        FrameState stateBefore = curState.immutableCopy(bci());
         Value[] args = curState.popArguments(target.signature().argumentSlots(true));
-
-        genInvokeIndirect(INVOKEINTERFACE, target, args, cpi, constantPool);
+        genInvokeIndirect(INVOKEINTERFACE, target, args, cpi, constantPool, stateBefore);
 
     }
 
     void genInvokeVirtual(RiMethod target, int cpi, RiConstantPool constantPool) {
+        FrameState stateBefore = curState.immutableCopy(bci());
         Value[] args = curState.popArguments(target.signature().argumentSlots(true));
-        genInvokeIndirect(INVOKEVIRTUAL, target, args, cpi, constantPool);
+        genInvokeIndirect(INVOKEVIRTUAL, target, args, cpi, constantPool, stateBefore);
 
     }
 
     void genInvokeSpecial(RiMethod target, RiType knownHolder, int cpi, RiConstantPool constantPool) {
+        FrameState stateBefore = curState.immutableCopy(bci());
         Value[] args = curState.popArguments(target.signature().argumentSlots(true));
-        invokeDirect(target, args, knownHolder, cpi, constantPool);
+        invokeDirect(target, args, knownHolder, cpi, constantPool, stateBefore);
 
     }
 
@@ -842,7 +845,7 @@
         return target;
     }
 
-    private void genInvokeIndirect(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) {
+    private void genInvokeIndirect(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool, FrameState stateBefore) {
         Value receiver = args[0];
         // attempt to devirtualize the call
         if (target.isResolved()) {
@@ -851,14 +854,14 @@
             // 0. check for trivial cases
             if (target.canBeStaticallyBound() && !isAbstract(target.accessFlags())) {
                 // check for trivial cases (e.g. final methods, nonvirtual methods)
-                invokeDirect(target, args, target.holder(), cpi, constantPool);
+                invokeDirect(target, args, target.holder(), cpi, constantPool, stateBefore);
                 return;
             }
             // 1. check if the exact type of the receiver can be determined
             RiType exact = getExactType(klass, receiver);
             if (exact != null && exact.isResolved()) {
                 // either the holder class is exact, or the receiver object has an exact type
-                invokeDirect(exact.resolveMethodImpl(target), args, exact, cpi, constantPool);
+                invokeDirect(exact.resolveMethodImpl(target), args, exact, cpi, constantPool, stateBefore);
                 return;
             }
             // 2. check if an assumed leaf method can be found
@@ -867,7 +870,7 @@
                 if (C1XOptions.PrintAssumptions) {
                     TTY.println("Optimistic invoke direct because of leaf method to " + leaf);
                 }
-                invokeDirect(leaf, args, null, cpi, constantPool);
+                invokeDirect(leaf, args, null, cpi, constantPool, stateBefore);
                 return;
             } else if (C1XOptions.PrintAssumptions) {
                 TTY.println("Could not make leaf method assumption for target=" + target + " leaf=" + leaf + " receiver.declaredType=" + receiver.declaredType());
@@ -880,27 +883,27 @@
                     TTY.println("Optimistic invoke direct because of leaf type to " + targetMethod);
                 }
                 // either the holder class is exact, or the receiver object has an exact type
-                invokeDirect(targetMethod, args, exact, cpi, constantPool);
+                invokeDirect(targetMethod, args, exact, cpi, constantPool, stateBefore);
                 return;
             } else if (C1XOptions.PrintAssumptions) {
                 TTY.println("Could not make leaf type assumption for type " + klass);
             }
         }
         // devirtualization failed, produce an actual invokevirtual
-        appendInvoke(opcode, target, args, cpi, constantPool);
+        appendInvoke(opcode, target, args, cpi, constantPool, stateBefore);
     }
 
     private CiKind returnKind(RiMethod target) {
         return target.signature().returnKind();
     }
 
-    private void invokeDirect(RiMethod target, Value[] args, RiType knownHolder, int cpi, RiConstantPool constantPool) {
-        appendInvoke(INVOKESPECIAL, target, args, cpi, constantPool);
+    private void invokeDirect(RiMethod target, Value[] args, RiType knownHolder, int cpi, RiConstantPool constantPool, FrameState stateBefore) {
+        appendInvoke(INVOKESPECIAL, target, args, cpi, constantPool, stateBefore);
     }
 
-    private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) {
+    private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool, FrameState stateBefore) {
         CiKind resultType = returnKind(target);
-        Value result = append(new Invoke(opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), null, graph));
+        Value result = append(new Invoke(opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), stateBefore, graph));
         pushReturn(resultType, result);
     }
 
@@ -1040,7 +1043,9 @@
             lockAddress = new MonitorAddress(lockNumber, graph);
             append(lockAddress);
         }
-        MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, null, graph);
+        curState.push(CiKind.Object, x);
+        MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, curState.immutableCopy(bci()), graph);
+        curState.apop();
         appendWithoutOptimization(monitorEnter, bci);
         curState.lock(ir, x, lockNumber + 1);
         monitorEnter.setStateAfter(curState.immutableCopy(bci));
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri May 06 16:21:10 2011 +0200
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri May 06 17:47:17 2011 +0200
@@ -1924,21 +1924,6 @@
       break;
     }
 
-    case c1x_global_implicit_null_id: {
-      __ push(rax);
-      __ push(rax);
-      // move saved fp to make space for the inserted return address
-      __ get_thread(rax);
-      __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset()));
-      __ movptr(Address(rsp, HeapWordSize), rax);
-      __ pop(rax);
-
-      { StubFrame f(sasm, "c1x_global_implicit_null_id", dont_gc_arguments);
-        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
-      }
-      break;
-    }
-
     case c1x_throw_div0_exception_id: {
       __ push(rax);
       __ push(rax);
--- a/src/share/vm/c1/c1_Runtime1.cpp	Fri May 06 16:21:10 2011 +0200
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Fri May 06 17:47:17 2011 +0200
@@ -216,6 +216,7 @@
 
     // All other stubs should have oopmaps
     default:
+      tty->print_cr("No oopmap found for %d", id);
       assert(oop_maps != NULL, "must have an oopmap");
   }
 #endif
--- a/src/share/vm/c1/c1_Runtime1.hpp	Fri May 06 16:21:10 2011 +0200
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Fri May 06 17:47:17 2011 +0200
@@ -72,7 +72,6 @@
   stub(counter_overflow)             \
   stub(c1x_unwind_exception_call)    \
   stub(c1x_handle_exception)         \
-  stub(c1x_global_implicit_null)     \
   stub(c1x_throw_div0_exception)     \
   stub(c1x_slow_subtype_check)       \
   stub(c1x_arithmetic_frem)          \
--- a/src/share/vm/runtime/globals.hpp	Fri May 06 16:21:10 2011 +0200
+++ b/src/share/vm/runtime/globals.hpp	Fri May 06 17:47:17 2011 +0200
@@ -2878,7 +2878,7 @@
           "Prefetch instruction to prefetch ahead")                         \
                                                                             \
   /* deoptimization */                                                      \
-  develop(bool, TraceDeoptimization, false,                                 \
+  product(bool, TraceDeoptimization, false,                                 \
           "Trace deoptimization")                                           \
                                                                             \
   develop(bool, DebugDeoptimization, false,                                 \
--- a/src/share/vm/runtime/sharedRuntime.cpp	Fri May 06 16:21:10 2011 +0200
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Fri May 06 17:47:17 2011 +0200
@@ -692,6 +692,15 @@
   throw_and_post_jvmti_exception(thread, exception);
 JRT_END
 
+address SharedRuntime::deoptimization_continuation(JavaThread* thread, address pc, nmethod* nm)
+{
+  if (TraceSignals) {
+    tty->print_cr(err_msg("Deoptimizing on implicit exception at relative pc=%d in method %s", pc - nm->entry_point(), nm->method()->name()->as_C_string()));
+  }
+  thread->_ScratchA = (intptr_t)pc;
+  return (SharedRuntime::deopt_blob()->jmp_uncommon_trap());
+}
+
 address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
                                                            address pc,
                                                            SharedRuntime::ImplicitExceptionKind exception_kind)
@@ -777,11 +786,7 @@
           _implicit_null_throws++;
 #endif
           if (UseC1X) {
-            if (TraceSignals) {
-              tty->print_cr(err_msg("calling implicit call stub relative pc=%d method name = %s", pc - nm->entry_point(), nm->method()->name()->as_C_string()));
-            }
-            thread->_ScratchA = (intptr_t)pc;
-            target_pc = (SharedRuntime::deopt_blob()->jmp_uncommon_trap());//Runtime1::entry_for(Runtime1::c1x_global_implicit_null_id);
+            target_pc = deoptimization_continuation(thread, pc, nm);
           } else {
             target_pc = nm->continuation_for_implicit_exception(pc);
           }
--- a/src/share/vm/runtime/sharedRuntime.hpp	Fri May 06 16:21:10 2011 +0200
+++ b/src/share/vm/runtime/sharedRuntime.hpp	Fri May 06 17:47:17 2011 +0200
@@ -178,6 +178,7 @@
   static void    throw_NullPointerException(JavaThread* thread);
   static void    throw_NullPointerException_at_call(JavaThread* thread);
   static void    throw_StackOverflowError(JavaThread* thread);
+  static address deoptimization_continuation(JavaThread* thread, address pc, nmethod* nm);
   static address continuation_for_implicit_exception(JavaThread* thread,
                                                      address faulting_pc,
                                                      ImplicitExceptionKind exception_kind);
--- a/src/share/vm/runtime/vframeArray.cpp	Fri May 06 16:21:10 2011 +0200
+++ b/src/share/vm/runtime/vframeArray.cpp	Fri May 06 17:47:17 2011 +0200
@@ -304,6 +304,10 @@
       iframe()->interpreter_frame_set_mdp(mdp);
     }
   }
+  
+  if (TraceDeoptimization) {
+    tty->print_cr("Expressions size: %d", expressions()->size());
+  }
 
   // Unpack expression stack
   // If this is an intermediate frame (i.e. not top frame) then this