changeset 21132:fc6fd02ecf95

Merge with f6f3f44a183051ae5ee581be7c8c6c8cbbc0d5fe
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Sun, 26 Apr 2015 20:50:30 -0700
parents d6d9631eb057 (diff) f6f3f44a1830 (current diff)
children bbc6a4347faf
files graal/com.oracle.graal.compiler/src/META-INF/services/javax.annotation.processing.Processor graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java graal/com.oracle.graal.hotspotvmconfig/src/META-INF/services/javax.annotation.processing.Processor graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMConfigProcessor.java graal/com.oracle.graal.options/src/META-INF/services/javax.annotation.processing.Processor graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CachingPEGraphDecoder.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PEGraphDecoder.java
diffstat 4 files changed, 110 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java	Sat Apr 25 19:47:45 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java	Sun Apr 26 20:50:30 2015 -0700
@@ -39,7 +39,8 @@
 /**
  * A <em>binding</em> between:
  * <ol>
- * <li>A program location in an executing Truffle AST (defined by a {@link SourceSection}), and</li>
+ * <li>A program location in an executing Truffle AST (corresponding to a {@link SourceSection}),
+ * and</li>
  * <li>A dynamically managed collection of "attached" {@linkplain Instrument Instruments} that
  * receive event notifications on behalf of external clients.</li>
  * </ol>
@@ -97,7 +98,7 @@
  * @see ProbeListener
  * @see SyntaxTag
  */
-public final class Probe implements SyntaxTagged {
+public final class Probe {
 
     private static final List<ASTProber> astProbers = new ArrayList<>();
 
@@ -108,7 +109,17 @@
      */
     private static final List<WeakReference<Probe>> probes = new ArrayList<>();
 
-    @CompilationFinal private static SyntaxTagTrap tagTrap = null;
+    /**
+     * A global trap that triggers notification just before executing any Node that is Probed with a
+     * matching tag.
+     */
+    @CompilationFinal private static SyntaxTagTrap beforeTagTrap = null;
+
+    /**
+     * A global trap that triggers notification just after executing any Node that is Probed with a
+     * matching tag.
+     */
+    @CompilationFinal private static SyntaxTagTrap afterTagTrap = null;
 
     private static final class FindSourceVisitor implements NodeVisitor {
 
@@ -198,24 +209,50 @@
         return taggedProbes;
     }
 
-    // TODO (mlvdv) can this be generalized to permit multiple traps without a performance hit?
+    // TODO (mlvdv) generalize to permit multiple "before traps" without a performance hit?
     /**
-     * Sets the current "tag trap"; there can be no more than one set at a time.
+     * Sets the current "<em>before</em> tag trap"; there can be no more than one in effect.
      * <ul>
-     * <li>A non-null trap sets a callback to be triggered whenever execution reaches a
-     * {@link Probe} (either existing or subsequently created) with the specified tag.</li>
-     * <li>Setting the trap to null clears the existing trap.</li>
-     * <li>Setting a non-null trap when one is already set will clear the previously set trap.</li>
+     * <li>The before-trap triggers a callback just <strong><em>before</em></strong> execution
+     * reaches <strong><em>any</em></strong> {@link Probe} (either existing or subsequently created)
+     * with the specified {@link SyntaxTag}.</li>
+     * <li>Setting the before-trap to {@code null} clears an existing before-trap.</li>
+     * <li>Setting a non{@code -null} before-trap when one is already set clears the previously set
+     * before-trap.</li>
      * </ul>
      *
-     * @param newTagTrap The {@link SyntaxTagTrap} to set.
+     * @param newBeforeTagTrap The new "before" {@link SyntaxTagTrap} to set.
      */
-    public static void setTagTrap(SyntaxTagTrap newTagTrap) {
-        tagTrap = newTagTrap;
+    public static void setBeforeTagTrap(SyntaxTagTrap newBeforeTagTrap) {
+        beforeTagTrap = newBeforeTagTrap;
         for (WeakReference<Probe> ref : probes) {
             final Probe probe = ref.get();
             if (probe != null) {
-                probe.notifyTrapSet();
+                probe.notifyTrapsChanged();
+            }
+        }
+    }
+
+    // TODO (mlvdv) generalize to permit multiple "after traps" without a performance hit?
+    /**
+     * Sets the current "<em>after</em> tag trap"; there can be no more than one in effect.
+     * <ul>
+     * <li>The after-trap triggers a callback just <strong><em>after</em></strong> execution leaves
+     * <strong><em>any</em></strong> {@link Probe} (either existing or subsequently created) with
+     * the specified {@link SyntaxTag}.</li>
+     * <li>Setting the after-trap to {@code null} clears an existing after-trap.</li>
+     * <li>Setting a non{@code -null} after-trap when one is already set clears the previously set
+     * after-trap.</li>
+     * </ul>
+     *
+     * @param newAfterTagTrap The new "after" {@link SyntaxTagTrap} to set.
+     */
+    public static void setAfterTagTrap(SyntaxTagTrap newAfterTagTrap) {
+        afterTagTrap = newAfterTagTrap;
+        for (WeakReference<Probe> ref : probes) {
+            final Probe probe = ref.get();
+            if (probe != null) {
+                probe.notifyTrapsChanged();
             }
         }
     }
@@ -236,8 +273,11 @@
      */
     @CompilationFinal private Assumption probeStateUnchangedAssumption = probeStateUnchangedCyclic.getAssumption();
 
-    // Must invalidate whenever this changes.
-    @CompilationFinal private boolean isTrapActive = false;
+    // Must invalidate whenever changed
+    @CompilationFinal private boolean isBeforeTrapActive = false;
+
+    // Must invalidate whenever changed
+    @CompilationFinal private boolean isAfterTrapActive = false;
 
     /**
      * Intended for use only by {@link ProbeNode}.
@@ -251,11 +291,18 @@
         }
     }
 
+    /**
+     * Is this node tagged as belonging to a particular human-sensible category of language
+     * constructs?
+     */
     public boolean isTaggedAs(SyntaxTag tag) {
         assert tag != null;
         return tags.contains(tag);
     }
 
+    /**
+     * In which user-sensible categories has this node been tagged (<em>empty set</em> if none).
+     */
     public Collection<SyntaxTag> getSyntaxTags() {
         return Collections.unmodifiableCollection(tags);
     }
@@ -271,8 +318,18 @@
             for (ProbeListener listener : probeListeners) {
                 listener.probeTaggedAs(this, tag, tagValue);
             }
-            if (tagTrap != null && tag == tagTrap.getTag()) {
-                this.isTrapActive = true;
+
+            // Update the status of this Probe with respect to global tag traps
+            boolean tagTrapsChanged = false;
+            if (beforeTagTrap != null && tag == beforeTagTrap.getTag()) {
+                this.isBeforeTrapActive = true;
+                tagTrapsChanged = true;
+            }
+            if (afterTagTrap != null && tag == afterTagTrap.getTag()) {
+                this.isAfterTrapActive = true;
+                tagTrapsChanged = true;
+            }
+            if (tagTrapsChanged) {
                 invalidateProbeUnchanged();
             }
         }
@@ -341,11 +398,25 @@
     }
 
     /**
-     * Gets the currently active {@linkplain SyntaxTagTrap tagTrap}; {@code null} if not set.
+     * Gets the currently active <strong><em>before</em></strong> {@linkplain SyntaxTagTrap Tag
+     * Trap} at this Probe. Non{@code -null} if the global
+     * {@linkplain Probe#setBeforeTagTrap(SyntaxTagTrap) Before Tag Trap} is set and if this Probe
+     * holds the {@link SyntaxTag} specified in the trap.
      */
-    SyntaxTagTrap getTrap() {
+    SyntaxTagTrap getBeforeTrap() {
         checkProbeUnchanged();
-        return isTrapActive ? tagTrap : null;
+        return isBeforeTrapActive ? beforeTagTrap : null;
+    }
+
+    /**
+     * Gets the currently active <strong><em>after</em></strong> {@linkplain SyntaxTagTrap Tag Trap}
+     * at this Probe. Non{@code -null} if the global
+     * {@linkplain Probe#setAfterTagTrap(SyntaxTagTrap) After Tag Trap} is set and if this Probe
+     * holds the {@link SyntaxTag} specified in the trap.
+     */
+    SyntaxTagTrap getAfterTrap() {
+        checkProbeUnchanged();
+        return isAfterTrapActive ? afterTagTrap : null;
     }
 
     /**
@@ -366,8 +437,9 @@
         probeStateUnchangedCyclic.invalidate();
     }
 
-    private void notifyTrapSet() {
-        this.isTrapActive = tagTrap != null && this.isTaggedAs(tagTrap.getTag());
+    private void notifyTrapsChanged() {
+        this.isBeforeTrapActive = beforeTagTrap != null && this.isTaggedAs(beforeTagTrap.getTag());
+        this.isAfterTrapActive = afterTagTrap != null && this.isTaggedAs(afterTagTrap.getTag());
         invalidateProbeUnchanged();
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java	Sat Apr 25 19:47:45 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java	Sun Apr 26 20:50:30 2015 -0700
@@ -153,9 +153,9 @@
 
     public void enter(Node node, VirtualFrame vFrame) {
         this.probe.checkProbeUnchanged();
-        final SyntaxTagTrap trap = probe.getTrap();
-        if (trap != null) {
-            trap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        final SyntaxTagTrap beforeTagTrap = probe.getBeforeTrap();
+        if (beforeTagTrap != null) {
+            beforeTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
         }
         if (firstInstrumentNode != null) {
             firstInstrumentNode.enter(node, vFrame);
@@ -167,6 +167,10 @@
         if (firstInstrumentNode != null) {
             firstInstrumentNode.returnVoid(node, vFrame);
         }
+        final SyntaxTagTrap afterTagTrap = probe.getAfterTrap();
+        if (afterTagTrap != null) {
+            afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        }
     }
 
     public void returnValue(Node node, VirtualFrame vFrame, Object result) {
@@ -174,6 +178,10 @@
         if (firstInstrumentNode != null) {
             firstInstrumentNode.returnValue(node, vFrame, result);
         }
+        final SyntaxTagTrap afterTagTrap = probe.getAfterTrap();
+        if (afterTagTrap != null) {
+            afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        }
     }
 
     public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) {
@@ -181,6 +189,10 @@
         if (firstInstrumentNode != null) {
             firstInstrumentNode.returnExceptional(node, vFrame, exception);
         }
+        final SyntaxTagTrap afterTagTrap = probe.getAfterTrap();
+        if (afterTagTrap != null) {
+            afterTagTrap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize());
+        }
     }
 
     public String instrumentationInfo() {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java	Sat Apr 25 19:47:45 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java	Sun Apr 26 20:50:30 2015 -0700
@@ -45,7 +45,7 @@
     }
 
     /**
-     * Callback that will be received whenever execution enters a node with the specified tag.
+     * Notifies that execution is halted at a node with the specified tag.
      */
     public abstract void tagTrappedAt(Node node, MaterializedFrame frame);
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagged.java	Sat Apr 25 19:47:45 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.instrument;
-
-import java.util.*;
-
-/**
- * Information about a guest language program element in a Truffle AST that can be marked as
- * belonging to 0 or more {@linkplain SyntaxTag tags}.
- */
-public interface SyntaxTagged {
-
-    /**
-     * Is this node tagged as belonging to a particular human-sensible category of language
-     * constructs?
-     */
-    boolean isTaggedAs(SyntaxTag tag);
-
-    /**
-     * In which user-sensible categories has this node been tagged (<em>empty set</em> if none).
-     */
-    Collection<SyntaxTag> getSyntaxTags();
-
-}