changeset 21354:575032310b2c

Truffle/Instrumentation: runtime failures executing an AdvancedInstrument root are now reported automatically via a new mehtod onAdvancedInstrumentResultListener.
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Tue, 12 May 2015 14:48:33 -0700
parents 876e710523c5
children 442b57a7f208
files graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/InstrumentationPartialEvaluationTest.java graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/AdvancedInstrumentTest.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentResultListener.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRootFactory.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java
diffstat 5 files changed, 47 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/InstrumentationPartialEvaluationTest.java	Tue May 12 12:57:47 2015 -0700
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/InstrumentationPartialEvaluationTest.java	Tue May 12 14:48:33 2015 -0700
@@ -212,8 +212,9 @@
         root.adoptChildren();
         Probe testProbe = result.probe();
         // A factory that could insert a AdvancedInstrumentRoot into the AST, but which never does.
-        Instrument instrument = Instrument.create(new AdvancedInstrumentRootFactory() {
+        Instrument instrument = Instrument.create(new AdvancedInstrumentRootFactory(null) {
 
+            @Override
             public AdvancedInstrumentRoot createInstrumentRoot(Probe probe, Node node) {
                 return null;
             }
@@ -232,11 +233,13 @@
         rootTestNode.adoptChildren();
         Probe testProbe = resultTestNode.probe();
         // Factory inserts a AdvancedInstrumentRoot with empty methods into instrumentation .
-        Instrument instrument = Instrument.create(new AdvancedInstrumentRootFactory() {
+        Instrument instrument = Instrument.create(new AdvancedInstrumentRootFactory(null) {
 
+            @Override
             public AdvancedInstrumentRoot createInstrumentRoot(Probe probe, Node node) {
                 return new AdvancedInstrumentRoot() {
 
+                    @Override
                     public String instrumentationInfo() {
                         return null;
                     }
@@ -351,6 +354,7 @@
             final boolean[] isCurrentlyCompiled = {false};
             final Instrument optInstrument = Instrument.create(new Instrument.TruffleOptListener() {
 
+                @Override
                 public void notifyIsCompiled(boolean isCompiled) {
                     isCurrentlyCompiled[0] = isCompiled;
                 }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/AdvancedInstrumentTest.java	Tue May 12 12:57:47 2015 -0700
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/AdvancedInstrumentTest.java	Tue May 12 14:48:33 2015 -0700
@@ -58,9 +58,10 @@
 
         assertEquals(13, callTarget1.call());
 
-        // Attach a null listener; it never actually attaches a node.
-        final Instrument instrument = Instrument.create(new AdvancedInstrumentRootFactory() {
+        // Attach a null factory; it never actually attaches a node.
+        final Instrument instrument = Instrument.create(new AdvancedInstrumentRootFactory(null) {
 
+            @Override
             public AdvancedInstrumentRoot createInstrumentRoot(Probe p, Node n) {
                 return null;
             }
@@ -71,9 +72,10 @@
 
         final TestAdvancedInstrumentCounterRoot counter = new TestAdvancedInstrumentCounterRoot();
 
-        // Attach a listener that splices an execution counter into the AST.
-        probe.attach(Instrument.create(new AdvancedInstrumentRootFactory() {
+        // Attach a factory that splices an execution counter into the AST.
+        probe.attach(Instrument.create(new AdvancedInstrumentRootFactory(null) {
 
+            @Override
             public AdvancedInstrumentRoot createInstrumentRoot(Probe p, Node n) {
                 return counter;
             }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentResultListener.java	Tue May 12 12:57:47 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentResultListener.java	Tue May 12 14:48:33 2015 -0700
@@ -24,6 +24,7 @@
  */
 package com.oracle.truffle.api.instrument;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 
@@ -42,7 +43,10 @@
      * Notifies listener that a client-provided {@linkplain AdvancedInstrumentRoot AST fragment} has
      * been executed by an {@linkplain Instrument#create(AdvancedInstrumentRootFactory, String)
      * Advanced Instrument} with the specified result, possibly {@code null}.
-     *
+     * <p>
+     * <strong>Note: </strong> Truffle will attempt to optimize implementations through partial
+     * evaluation; annotate with {@link TruffleBoundary} if this should not be permitted.
+     * 
      * @param node the guest-language AST node to which the host Instrument's {@link Probe} is
      *            attached
      * @param vFrame execution frame at the guest-language AST node
@@ -54,6 +58,9 @@
      * Notifies listener that execution of client-provided {@linkplain AdvancedInstrumentRoot AST
      * fragment} filed during execution by a @linkplain
      * Instrument#create(AdvancedInstrumentRootFactory, String) Advanced Instrument}.
+     * <p>
+     * <strong>Note: </strong> Truffle will attempt to optimize implementations through partial
+     * evaluation; annotate with {@link TruffleBoundary} if this should not be permitted.
      *
      * @param node the guest-language AST node to which the host Instrument's {@link Probe} is
      *            attached
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRootFactory.java	Tue May 12 12:57:47 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/AdvancedInstrumentRootFactory.java	Tue May 12 14:48:33 2015 -0700
@@ -34,7 +34,9 @@
  * @see Instrument
  * @see AdvancedInstrumentRoot
  */
-public interface AdvancedInstrumentRootFactory {
+public abstract class AdvancedInstrumentRootFactory {
+
+    private final AdvancedInstrumentResultListener resultListener;
 
     /**
      * Provider of {@linkplain AdvancedInstrumentRoot AST fragment} instances for efficient
@@ -47,5 +49,17 @@
      * @return a newly created AST fragment suitable for execution, via instrumentation, in the
      *         execution context of the specified guest-language AST site.
      */
-    AdvancedInstrumentRoot createInstrumentRoot(Probe probe, Node node);
+    public abstract AdvancedInstrumentRoot createInstrumentRoot(Probe probe, Node node);
+
+    /**
+     * Gets the listener, if one was specified, to notify with the result of executing every
+     * {@link AdvancedInstrumentRoot} created by this factory.
+     */
+    public final AdvancedInstrumentResultListener resultListener() {
+        return resultListener;
+    }
+
+    protected AdvancedInstrumentRootFactory(AdvancedInstrumentResultListener resultListener) {
+        this.resultListener = resultListener;
+    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java	Tue May 12 12:57:47 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java	Tue May 12 14:48:33 2015 -0700
@@ -436,8 +436,17 @@
                     }
                 }
                 if (instrumentRoot != null) {
-                    // TODO (mlvdv) should report exception ; non-trivial architectural change
-                    instrumentRoot.executeRoot(node, vFrame);
+                    final AdvancedInstrumentResultListener resultListener = AdvancedInstrument.this.rootFactory.resultListener();
+                    try {
+                        final Object result = instrumentRoot.executeRoot(node, vFrame);
+                        if (resultListener != null) {
+                            resultListener.notifyResult(node, vFrame, result);
+                        }
+                    } catch (RuntimeException ex) {
+                        if (resultListener != null) {
+                            resultListener.notifyFailure(node, vFrame, ex);
+                        }
+                    }
                 }
                 if (nextInstrumentNode != null) {
                     nextInstrumentNode.enter(node, vFrame);