changeset 16535:ada0a7729b6f

Truffle: introduce debug option to print the stack trace when transferring to the interpreter
author Andreas Woess <andreas.woess@jku.at>
date Wed, 16 Jul 2014 15:18:48 +0200
parents 4aaa97f42b92
children 82ec79372221
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DeoptimizationReason.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java src/share/vm/graal/vmStructs_graal.hpp src/share/vm/runtime/deoptimization.cpp src/share/vm/runtime/deoptimization.hpp src/share/vm/utilities/exceptions.hpp
diffstat 13 files changed, 64 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DeoptimizationReason.java	Tue Jul 15 11:52:45 2014 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DeoptimizationReason.java	Wed Jul 16 15:18:48 2014 +0200
@@ -41,4 +41,5 @@
     RuntimeConstraint,
     LoopLimitCheck,
     Aliasing,
+    TransferToInterpreter,
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Jul 15 11:52:45 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Jul 16 15:18:48 2014 +0200
@@ -1014,6 +1014,7 @@
     @HotSpotVMField(name = "ThreadShadow::_pending_exception", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingExceptionOffset;
     @HotSpotVMField(name = "ThreadShadow::_pending_deoptimization", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingDeoptimizationOffset;
     @HotSpotVMField(name = "ThreadShadow::_pending_failed_speculation", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingFailedSpeculationOffset;
+    @HotSpotVMField(name = "ThreadShadow::_pending_transfer_to_interpreter", type = "bool", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingTransferToInterpreterOffset;
 
     @HotSpotVMFlag(name = "UseHSAILDeoptimization") @Stable public boolean useHSAILDeoptimization;
     @HotSpotVMFlag(name = "UseHSAILSafepoints") @Stable public boolean useHSAILSafepoints;
@@ -1460,6 +1461,7 @@
     @HotSpotVMConstant(name = "Deoptimization::Reason_constraint") @Stable public int deoptReasonConstraint;
     @HotSpotVMConstant(name = "Deoptimization::Reason_loop_limit_check") @Stable public int deoptReasonLoopLimitCheck;
     @HotSpotVMConstant(name = "Deoptimization::Reason_aliasing") @Stable public int deoptReasonAliasing;
+    @HotSpotVMConstant(name = "Deoptimization::Reason_transfer_to_interpreter") @Stable public int deoptReasonTransferToInterpreter;
     @HotSpotVMConstant(name = "Deoptimization::Reason_LIMIT") @Stable public int deoptReasonOSROffset;
 
     @HotSpotVMConstant(name = "Deoptimization::Action_none") @Stable public int deoptActionNone;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Tue Jul 15 11:52:45 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Wed Jul 16 15:18:48 2014 +0200
@@ -230,6 +230,8 @@
                 return config.deoptReasonLoopLimitCheck;
             case Aliasing:
                 return config.deoptReasonAliasing;
+            case TransferToInterpreter:
+                return config.deoptReasonTransferToInterpreter;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
@@ -282,6 +284,9 @@
         if (reason == config.deoptReasonAliasing) {
             return DeoptimizationReason.Aliasing;
         }
+        if (reason == config.deoptReasonTransferToInterpreter) {
+            return DeoptimizationReason.TransferToInterpreter;
+        }
         throw GraalInternalError.shouldNotReachHere(Integer.toHexString(reason));
     }
 
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Tue Jul 15 11:52:45 2014 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Wed Jul 16 15:18:48 2014 +0200
@@ -29,6 +29,7 @@
 
 import java.util.*;
 import java.util.concurrent.*;
+import java.util.stream.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
@@ -41,6 +42,7 @@
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
@@ -52,6 +54,7 @@
 import com.oracle.graal.printer.*;
 import com.oracle.graal.runtime.*;
 import com.oracle.graal.truffle.*;
+import com.oracle.graal.word.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.SlowPath;
 import com.oracle.truffle.api.frame.*;
@@ -342,4 +345,25 @@
     public void reinstallStubs() {
         installOptimizedCallTargetCallMethod();
     }
+
+    public void notifyTransferToInterpreter() {
+        CompilerAsserts.neverPartOfCompilation();
+        if (TraceTruffleTransferToInterpreter.getValue()) {
+            Word thread = CurrentJavaThreadNode.get(HotSpotGraalRuntime.runtime().getTarget().wordKind);
+            boolean deoptimized = thread.readByte(HotSpotGraalRuntime.runtime().getConfig().pendingTransferToInterpreterOffset) != 0;
+            if (deoptimized) {
+                thread.writeByte(HotSpotGraalRuntime.runtime().getConfig().pendingTransferToInterpreterOffset, (byte) 0);
+
+                logTransferToInterpreter();
+            }
+        }
+    }
+
+    private static void logTransferToInterpreter() {
+        final int skip = 2;
+        final int limit = 20;
+        StackTraceElement[] stackTrace = new Throwable().getStackTrace();
+        String suffix = stackTrace.length > skip + limit ? "\n  ..." : "";
+        TTY.out().out().println(Arrays.stream(stackTrace).skip(skip).limit(limit).map(StackTraceElement::toString).collect(Collectors.joining("\n  ", "", suffix)));
+    }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Tue Jul 15 11:52:45 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Jul 16 15:18:48 2014 +0200
@@ -119,6 +119,8 @@
     public static final OptionValue<Boolean> TraceTruffleInlining = new OptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleSplitting = new OptionValue<>(false);
+    @Option(help = "Print stack trace on transfer to interpreter")
+    public static final OptionValue<Boolean> TraceTruffleTransferToInterpreter = new StableOptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Boolean> TruffleCallTargetProfiling = new StableOptionValue<>(false);
     // @formatter:on
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Tue Jul 15 11:52:45 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Wed Jul 16 15:18:48 2014 +0200
@@ -41,12 +41,12 @@
 
     @MethodSubstitution
     public static void transferToInterpreter() {
-        DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.UnreachedCode);
+        DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter);
     }
 
     @MethodSubstitution
     public static void transferToInterpreterAndInvalidate() {
-        DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode);
+        DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter);
     }
 
     @MethodSubstitution
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Tue Jul 15 11:52:45 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Wed Jul 16 15:18:48 2014 +0200
@@ -65,6 +65,9 @@
      * insert a transfer to the interpreter.
      */
     public static void transferToInterpreter() {
+        if (inInterpreter()) {
+            Truffle.getRuntime().notifyTransferToInterpreter();
+        }
     }
 
     /**
@@ -72,6 +75,9 @@
      * insert a transfer to the interpreter, invalidating the currently executing machine code.
      */
     public static void transferToInterpreterAndInvalidate() {
+        if (inInterpreter()) {
+            Truffle.getRuntime().notifyTransferToInterpreter();
+        }
     }
 
     /**
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java	Tue Jul 15 11:52:45 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java	Wed Jul 16 15:18:48 2014 +0200
@@ -131,4 +131,8 @@
      */
     FrameInstance getCurrentFrame();
 
+    /**
+     * Internal API method. Do not use.
+     */
+    void notifyTransferToInterpreter();
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java	Tue Jul 15 11:52:45 2014 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java	Wed Jul 16 15:18:48 2014 +0200
@@ -135,4 +135,7 @@
     public FrameInstance getCurrentFrame() {
         return currentFrames.get();
     }
+
+    public void notifyTransferToInterpreter() {
+    }
 }
--- a/src/share/vm/graal/vmStructs_graal.hpp	Tue Jul 15 11:52:45 2014 +0200
+++ b/src/share/vm/graal/vmStructs_graal.hpp	Wed Jul 16 15:18:48 2014 +0200
@@ -34,12 +34,14 @@
   nonstatic_field(InstanceKlass, _graal_node_class, oop)                      \
   nonstatic_field(ThreadShadow,  _pending_deoptimization, int)                \
   nonstatic_field(ThreadShadow,  _pending_failed_speculation, oop)            \
+  nonstatic_field(ThreadShadow,  _pending_transfer_to_interpreter, bool)      \
   nonstatic_field(MethodData,    _graal_node_count, int)                      \
 
 #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type)                   \
 
 #define VM_INT_CONSTANTS_GRAAL(declare_constant, declare_preprocessor_constant)                   \
   declare_constant(Deoptimization::Reason_aliasing)                                               \
+  declare_constant(Deoptimization::Reason_transfer_to_interpreter)                                \
   declare_constant(GraalEnv::ok)                                                                  \
   declare_constant(GraalEnv::dependencies_failed)                                                 \
   declare_constant(GraalEnv::cache_full)                                                          \
--- a/src/share/vm/runtime/deoptimization.cpp	Tue Jul 15 11:52:45 2014 +0200
+++ b/src/share/vm/runtime/deoptimization.cpp	Wed Jul 16 15:18:48 2014 +0200
@@ -1393,7 +1393,12 @@
       trap_bci = 0;
       Thread::current()->set_pending_monitorenter(true);
     }
+
+    if (reason == Deoptimization::Reason_transfer_to_interpreter) {
+      thread->set_pending_transfer_to_interpreter(true);
+    }
 #endif
+
     Bytecodes::Code trap_bc     = trap_method->java_code_at(trap_bci);
 
     if (trap_scope->rethrow_exception()) {
@@ -1996,7 +2001,10 @@
   "age" GRAAL_ONLY("_or_jsr_mismatch"),
   "predicate",
   "loop_limit_check",
-  GRAAL_ONLY("aliasing")
+#ifdef GRAAL
+  "aliasing",
+  "transfer_to_interpreter",
+#endif
 };
 const char* Deoptimization::_trap_action_name[Action_LIMIT] = {
   // Note:  Keep this in sync. with enum DeoptAction.
--- a/src/share/vm/runtime/deoptimization.hpp	Tue Jul 15 11:52:45 2014 +0200
+++ b/src/share/vm/runtime/deoptimization.hpp	Wed Jul 16 15:18:48 2014 +0200
@@ -74,6 +74,7 @@
     Reason_loop_limit_check,      // compiler generated loop limits check failed
 #ifdef GRAAL
     Reason_aliasing,              // optimistic assumption about aliasing failed
+    Reason_transfer_to_interpreter, // explicit transferToInterpreter()
 #endif
     Reason_LIMIT,
 
--- a/src/share/vm/utilities/exceptions.hpp	Tue Jul 15 11:52:45 2014 +0200
+++ b/src/share/vm/utilities/exceptions.hpp	Wed Jul 16 15:18:48 2014 +0200
@@ -65,6 +65,7 @@
   int _pending_deoptimization;
   oop _pending_failed_speculation;
   bool _pending_monitorenter;
+  bool _pending_transfer_to_interpreter;
 #endif
   oop  _pending_exception;                       // Thread has gc actions.
   const char* _exception_file;                   // file information for exception (debugging only)
@@ -100,6 +101,7 @@
   void set_pending_monitorenter(bool b)          { _pending_monitorenter = b; }
   void set_pending_deoptimization(int reason)    { _pending_deoptimization = reason; }
   void set_pending_failed_speculation(oop failed_speculation)    { _pending_failed_speculation = failed_speculation; }
+  void set_pending_transfer_to_interpreter(bool b) { _pending_transfer_to_interpreter = b; }
 #endif
 
   // use THROW whenever possible!
@@ -111,7 +113,7 @@
   ThreadShadow() : _pending_exception(NULL),
                    _exception_file(NULL), _exception_line(0)
 #ifdef GRAAL
-                   , _pending_monitorenter(false), _pending_deoptimization(-1), _pending_failed_speculation(NULL)
+                   , _pending_monitorenter(false), _pending_deoptimization(-1), _pending_failed_speculation(NULL), _pending_transfer_to_interpreter(false)
 #endif
   {}
 };