# HG changeset patch # User Michael Van De Vanter # Date 1429660926 25200 # Node ID d6d9631eb05707f06e6cf5068edf527463554d78 # Parent 7d21cdb15e54604f08a47fb1ce4aef387dbc21a1 TruffleInstrumentation: rename Probe.setTagTrap() to Probe.setBeforeTagTrap() and add Probe.setAfterTagTrap() diff -r 7d21cdb15e54 -r d6d9631eb057 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Tue Apr 21 15:56:48 2015 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Tue Apr 21 17:02:06 2015 -0700 @@ -109,7 +109,17 @@ */ private static final List> 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 { @@ -199,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 "before tag trap"; there can be no more than one in effect. * * - * @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 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 "after tag trap"; there can be no more than one in effect. + *
    + *
  • The after-trap triggers a callback just after execution leaves + * any {@link Probe} (either existing or subsequently created) with + * the specified {@link SyntaxTag}.
  • + *
  • Setting the after-trap to {@code null} clears an existing after-trap.
  • + *
  • Setting a non{@code -null} after-trap when one is already set clears the previously set + * after-trap.
  • + *
+ * + * @param newAfterTagTrap The new "after" {@link SyntaxTagTrap} to set. + */ + public static void setAfterTagTrap(SyntaxTagTrap newAfterTagTrap) { + afterTagTrap = newAfterTagTrap; + for (WeakReference ref : probes) { + final Probe probe = ref.get(); + if (probe != null) { + probe.notifyTrapsChanged(); } } } @@ -237,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}. @@ -279,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(); } } @@ -349,11 +398,25 @@ } /** - * Gets the currently active {@linkplain SyntaxTagTrap tagTrap}; {@code null} if not set. + * Gets the currently active before {@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 after {@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; } /** @@ -374,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(); } diff -r 7d21cdb15e54 -r d6d9631eb057 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java Tue Apr 21 15:56:48 2015 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java Tue Apr 21 17:02:06 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() { diff -r 7d21cdb15e54 -r d6d9631eb057 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java Tue Apr 21 15:56:48 2015 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SyntaxTagTrap.java Tue Apr 21 17:02:06 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); }