# HG changeset patch # User Michael Van De Vanter # Date 1442705372 25200 # Node ID a0fa69e3e60e39fbb94058cd435688a77bbeea70 # Parent 776dc0a09749f55a8deff7d4bb9e138baf95b6cc Truffle/Instrumentation: remove static Instrument factory methods, now supported by Instrumenter diff -r 776dc0a09749 -r a0fa69e3e60e truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/AdvancedInstrumentTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/AdvancedInstrumentTest.java Sat Sep 19 13:56:42 2015 -0700 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/AdvancedInstrumentTest.java Sat Sep 19 16:29:32 2015 -0700 @@ -33,7 +33,6 @@ import com.oracle.truffle.api.instrument.AdvancedInstrumentRoot; import com.oracle.truffle.api.instrument.AdvancedInstrumentRootFactory; -import com.oracle.truffle.api.instrument.Instrument; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.Probe; import com.oracle.truffle.api.instrument.ProbeListener; @@ -82,26 +81,27 @@ assertEquals(vm.eval(source).get(), 13); assertNotNull("Add node should be probed", addNodeProbe[0]); - // Attach a null factory; it never actually attaches a node. - final Instrument instrument = Instrument.create(null, new AdvancedInstrumentRootFactory() { + // Attach a factory that never actually attaches a node. + final AdvancedInstrumentRootFactory rootFactory1 = new AdvancedInstrumentRootFactory() { public AdvancedInstrumentRoot createInstrumentRoot(Probe p, Node n) { return null; } - }, null, "test AdvancedInstrument"); - addNodeProbe[0].attach(instrument); + }; + instrumenter.attach(addNodeProbe[0], null, rootFactory1, null, "test AdvancedInstrument"); assertEquals(vm.eval(source).get(), 13); + // Attach a factory that splices an execution counter into the AST. final TestAdvancedInstrumentCounterRoot counter = new TestAdvancedInstrumentCounterRoot(); - - // Attach a factory that splices an execution counter into the AST. - addNodeProbe[0].attach(Instrument.create(null, new AdvancedInstrumentRootFactory() { + final AdvancedInstrumentRootFactory rootFactory2 = new AdvancedInstrumentRootFactory() { public AdvancedInstrumentRoot createInstrumentRoot(Probe p, Node n) { return counter; } - }, null, "test AdvancedInstrument")); + }; + instrumenter.attach(addNodeProbe[0], null, rootFactory2, null, "test AdvancedInstrument"); + assertEquals(0, counter.getCount()); assertEquals(vm.eval(source).get(), 13); assertEquals(1, counter.getCount()); diff -r 776dc0a09749 -r a0fa69e3e60e truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java Sat Sep 19 13:56:42 2015 -0700 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/instrument/InstrumentationTest.java Sat Sep 19 16:29:32 2015 -0700 @@ -116,10 +116,10 @@ assertNotNull("Value nodes should be probed", probes[2]); // Check instrumentation with the simplest kind of counters. // They should all be removed when the check is finished. - checkCounters(probes[0], vm, source, new TestSimpleInstrumentCounter(), new TestSimpleInstrumentCounter(), new TestSimpleInstrumentCounter()); + checkCounters(probes[0], vm, source, new TestSimpleInstrumentCounter(instrumenter), new TestSimpleInstrumentCounter(instrumenter), new TestSimpleInstrumentCounter(instrumenter)); // Now try with the more complex flavor of listener - checkCounters(probes[0], vm, source, new TestStandardInstrumentCounter(), new TestStandardInstrumentCounter(), new TestStandardInstrumentCounter()); + checkCounters(probes[0], vm, source, new TestStandardInstrumentCounter(instrumenter), new TestStandardInstrumentCounter(instrumenter), new TestStandardInstrumentCounter(instrumenter)); } @@ -230,28 +230,11 @@ public int enterCount = 0; public int leaveCount = 0; - public final Instrument instrument; - - public TestSimpleInstrumentCounter() { - this.instrument = Instrument.create(new SimpleInstrumentListener() { - - public void enter(Probe probe) { - enterCount++; - } + public Instrumenter instrumenter; + private Instrument instrument; - public void returnVoid(Probe probe) { - leaveCount++; - } - - public void returnValue(Probe probe, Object result) { - leaveCount++; - } - - public void returnExceptional(Probe probe, Exception exception) { - leaveCount++; - } - - }, "Instrumentation Test Counter"); + public TestSimpleInstrumentCounter(Instrumenter instrumenter) { + this.instrumenter = instrumenter; } @Override @@ -266,7 +249,25 @@ @Override public void attach(Probe probe) { - probe.attach(instrument); + instrument = instrumenter.attach(probe, new SimpleInstrumentListener() { + + public void enter(Probe p) { + enterCount++; + } + + public void returnVoid(Probe p) { + leaveCount++; + } + + public void returnValue(Probe p, Object result) { + leaveCount++; + } + + public void returnExceptional(Probe p, Exception exception) { + leaveCount++; + } + + }, "Instrumentation Test Counter"); } @Override @@ -282,28 +283,11 @@ public int enterCount = 0; public int leaveCount = 0; - public final Instrument instrument; - - public TestStandardInstrumentCounter() { - this.instrument = Instrument.create(new StandardInstrumentListener() { - - public void enter(Probe probe, Node node, VirtualFrame vFrame) { - enterCount++; - } + public final Instrumenter instrumenter; + public Instrument instrument; - public void returnVoid(Probe probe, Node node, VirtualFrame vFrame) { - leaveCount++; - } - - public void returnValue(Probe probe, Node node, VirtualFrame vFrame, Object result) { - leaveCount++; - } - - public void returnExceptional(Probe probe, Node node, VirtualFrame vFrame, Exception exception) { - leaveCount++; - } - - }, "Instrumentation Test Counter"); + public TestStandardInstrumentCounter(Instrumenter instrumenter) { + this.instrumenter = instrumenter; } @Override @@ -318,7 +302,25 @@ @Override public void attach(Probe probe) { - probe.attach(instrument); + instrument = instrumenter.attach(probe, new StandardInstrumentListener() { + + public void enter(Probe p, Node node, VirtualFrame vFrame) { + enterCount++; + } + + public void returnVoid(Probe p, Node node, VirtualFrame vFrame) { + leaveCount++; + } + + public void returnValue(Probe p, Node node, VirtualFrame vFrame, Object result) { + leaveCount++; + } + + public void returnExceptional(Probe p, Node node, VirtualFrame vFrame, Exception exception) { + leaveCount++; + } + + }, "Instrumentation Test Counter"); } @Override diff -r 776dc0a09749 -r a0fa69e3e60e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/LineBreakpointFactory.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/LineBreakpointFactory.java Sat Sep 19 13:56:42 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/LineBreakpointFactory.java Sat Sep 19 16:29:32 2015 -0700 @@ -382,12 +382,12 @@ throw new IllegalStateException("Attempt to attach a disposed " + BREAKPOINT_NAME); } Instrument newInstrument = null; + final Instrumenter instrumenter = debugger.getInstrumenter(); if (conditionExpr == null) { - newInstrument = Instrument.create(new UnconditionalLineBreakInstrumentListener(), BREAKPOINT_NAME); + newInstrument = instrumenter.attach(newProbe, new UnconditionalLineBreakInstrumentListener(), BREAKPOINT_NAME); } else { - newInstrument = Instrument.create(this, debugger.createAdvancedInstrumentRootFactory(newProbe, conditionExpr, this), Boolean.class, BREAKPOINT_NAME); + newInstrument = instrumenter.attach(newProbe, this, debugger.createAdvancedInstrumentRootFactory(newProbe, conditionExpr, this), Boolean.class, BREAKPOINT_NAME); } - newProbe.attach(newInstrument); instruments.add(newInstrument); changeState(isEnabled ? ENABLED : DISABLED); } diff -r 776dc0a09749 -r a0fa69e3e60e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/TagBreakpointFactory.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/TagBreakpointFactory.java Sat Sep 19 13:56:42 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/TagBreakpointFactory.java Sat Sep 19 16:29:32 2015 -0700 @@ -342,12 +342,12 @@ throw new IllegalStateException("Attempt to attach a disposed " + BREAKPOINT_NAME); } Instrument newInstrument = null; + final Instrumenter instrumenter = debugger.getInstrumenter(); if (conditionExpr == null) { - newInstrument = Instrument.create(new UnconditionalTagBreakInstrumentListener(), BREAKPOINT_NAME); + newInstrument = instrumenter.attach(newProbe, new UnconditionalTagBreakInstrumentListener(), BREAKPOINT_NAME); } else { - newInstrument = Instrument.create(this, debugger.createAdvancedInstrumentRootFactory(newProbe, conditionExpr, this), Boolean.class, BREAKPOINT_NAME); + instrumenter.attach(newProbe, this, debugger.createAdvancedInstrumentRootFactory(newProbe, conditionExpr, this), Boolean.class, BREAKPOINT_NAME); } - newProbe.attach(newInstrument); instruments.add(newInstrument); changeState(isEnabled ? ENABLED : DISABLED); } diff -r 776dc0a09749 -r a0fa69e3e60e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Sat Sep 19 13:56:42 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Sat Sep 19 16:29:32 2015 -0700 @@ -33,9 +33,6 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.source.SourceSection; -// TODO (mlvdv) these statics should not be global. Move them to some kind of context. -// TODO (mlvdv) migrate factory (together with Probe)? break out nested classes? - /** * A binding between: *
    @@ -47,73 +44,13 @@ * Client-oriented documentation for the use of Instruments is available online at https:// * wiki.openjdk.java.net/display/Graal/Listening+for+Execution+Events - *

    - * The implementation of Instruments is complicated by the requirement that Truffle be able to clone - * ASTs at any time. In particular, any instrumentation-supporting Nodes that have been attached to - * an AST must be cloned along with the AST: AST clones are not permitted to share Nodes. - *

    - * AST cloning is intended to be as transparent as possible to clients. This is encouraged - * by providing the {@link SimpleInstrumentListener} for clients that need know nothing more than - * the properties associated with a Probe: it's {@link SourceSection} and any associated instances - * of {@link SyntaxTag}. - *

    - * AST cloning is not transparent to clients that use the - * {@link StandardInstrumentListener}, since those event methods identify the concrete Node instance - * (and thus the AST instance) where the event takes place. - *

    - *

    Implementation Notes: the Life Cycle of an {@link Instrument} at a {@link Probe}

    - *

    - *

    * * @see Probe * @see TruffleEvents */ public abstract class Instrument { - /** - * Creates a Simple Instrument: this Instrument routes execution events to a - * client-provided listener. - * - * @param listener a listener for execution events - * @param instrumentInfo optional description of the instrument's role, intended for debugging. - * @return a new instrument, ready for attachment at a probe - */ + @Deprecated public static Instrument create(SimpleInstrumentListener listener, String instrumentInfo) { return new SimpleInstrument(listener, instrumentInfo); } @@ -126,6 +63,7 @@ * @param instrumentInfo optional description of the instrument's role, intended for debugging. * @return a new instrument, ready for attachment at a probe */ + @Deprecated public static Instrument create(StandardInstrumentListener standardListener, String instrumentInfo) { return new StandardInstrument(standardListener, instrumentInfo); } @@ -145,18 +83,11 @@ * @param instrumentInfo optional description of the instrument's role, intended for debugging. * @return a new instrument, ready for attachment at a probe */ + @Deprecated public static Instrument create(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, Class requiredResultType, String instrumentInfo) { return new AdvancedInstrument(resultListener, rootFactory, requiredResultType, instrumentInfo); } - // TODO (mlvdv) experimental - /** - * For implementation testing. - */ - public static Instrument create(TruffleOptListener listener) { - return new TruffleOptInstrument(listener, null); - } - /** * Has this instrument been disposed? stays true once set. */ @@ -169,6 +100,61 @@ */ private final String instrumentInfo; + /** + *

    Implementation Notes

    + *

    + * The implementation of Instruments is complicated by the requirement that Truffle be able to + * clone ASTs at any time. In particular, any instrumentation-supporting Nodes that have been + * attached to an AST must be cloned along with the AST: AST clones are not permitted to share + * Nodes. + *

    + * AST cloning is intended to be as transparent as possible to clients. This is + * encouraged by providing the {@link SimpleInstrumentListener} for clients that need know + * nothing more than the properties associated with a Probe: its {@link SourceSection} and any + * associated instances of {@link SyntaxTag}. + *

    + * AST cloning is not transparent to clients that use the + * {@link StandardInstrumentListener}, since those event methods identify the concrete Node + * instance (and thus the AST instance) where the event takes place. + *

    + *

    Implementation Notes: the Life Cycle of an {@link Instrument} at a {@link Probe}

    + *

    + *

    + */ private Instrument(String instrumentInfo) { this.instrumentInfo = instrumentInfo; } @@ -223,14 +209,14 @@ /** * An instrument that propagates events to an instance of {@link SimpleInstrumentListener}. */ - private static final class SimpleInstrument extends Instrument { + static final class SimpleInstrument extends Instrument { /** * Tool-supplied listener for events. */ private final SimpleInstrumentListener simpleListener; - private SimpleInstrument(SimpleInstrumentListener simpleListener, String instrumentInfo) { + SimpleInstrument(SimpleInstrumentListener simpleListener, String instrumentInfo) { super(instrumentInfo); this.simpleListener = simpleListener; } @@ -305,14 +291,14 @@ /** * An instrument that propagates events to an instance of {@link StandardInstrumentListener}. */ - private static final class StandardInstrument extends Instrument { + static final class StandardInstrument extends Instrument { /** * Tool-supplied listener for AST events. */ private final StandardInstrumentListener standardListener; - private StandardInstrument(StandardInstrumentListener standardListener, String instrumentInfo) { + StandardInstrument(StandardInstrumentListener standardListener, String instrumentInfo) { super(instrumentInfo); this.standardListener = standardListener; } @@ -389,13 +375,13 @@ * within a Probe's instrumentation chain, and thus directly in the executing Truffle * AST with potential for full optimization. */ - private static final class AdvancedInstrument extends Instrument { + static final class AdvancedInstrument extends Instrument { private final AdvancedInstrumentResultListener resultListener; private final AdvancedInstrumentRootFactory rootFactory; private final Class requiredResultType; - private AdvancedInstrument(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, Class requiredResultType, String instrumentInfo) { + AdvancedInstrument(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, Class requiredResultType, String instrumentInfo) { super(instrumentInfo); this.resultListener = resultListener; this.rootFactory = rootFactory; @@ -516,10 +502,12 @@ } } + // TODO (mlvdv) experimental public interface TruffleOptListener { void notifyIsCompiled(boolean isCompiled); } + @SuppressWarnings("unused") private static final class TruffleOptInstrument extends Instrument { private final TruffleOptListener toolOptListener; diff -r 776dc0a09749 -r a0fa69e3e60e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumenter.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumenter.java Sat Sep 19 13:56:42 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumenter.java Sat Sep 19 16:29:32 2015 -0700 @@ -36,6 +36,7 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.impl.Accessor; +import com.oracle.truffle.api.instrument.InstrumentationNode.TruffleEvents; import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeVisitor; @@ -309,6 +310,72 @@ astProbers.remove(prober); } + /** + * Attaches a {@link SimpleInstrumentListener listener} to a {@link Probe}, creating a + * binding called an {@link Instrument}. Until the Instrument is + * {@linkplain Instrument#dispose() disposed}, it routes notification of + * {@linkplain TruffleEvents execution events} taking place at the Probe's AST location to the + * listener. + * + * @param probe source of execution events + * @param listener receiver of execution events + * @param instrumentInfo optional documentation about the Instrument + * @return a handle for access to the binding + */ + @SuppressWarnings("static-method") + public Instrument attach(Probe probe, SimpleInstrumentListener listener, String instrumentInfo) { + final Instrument instrument = new Instrument.SimpleInstrument(listener, instrumentInfo); + probe.attach(instrument); + return instrument; + } + + /** + * Attaches a {@link StandardInstrumentListener listener} to a {@link Probe}, creating + * a binding called an {@link Instrument}. Until the Instrument is + * {@linkplain Instrument#dispose() disposed}, it routes notification of + * {@linkplain TruffleEvents execution events} taking place at the Probe's AST location to the + * listener. + * + * @param probe source of execution events + * @param listener receiver of execution events + * @param instrumentInfo optional documentation about the Instrument + * @return a handle for access to the binding + */ + @SuppressWarnings("static-method") + public Instrument attach(Probe probe, StandardInstrumentListener listener, String instrumentInfo) { + final Instrument instrument = new Instrument.StandardInstrument(listener, instrumentInfo); + probe.attach(instrument); + return instrument; + } + + /** + * Attaches a {@link AdvancedInstrumentResultListener listener} to a {@link Probe}, + * creating a binding called an {@link Instrument}. Until the Instrument is + * {@linkplain Instrument#dispose() disposed}, it routes notification of + * {@linkplain TruffleEvents execution events} taking place at the Probe's AST location to the + * listener. + *

    + * This Instrument executes efficiently, subject to full Truffle optimization, a client-provided + * AST fragment every time the Probed node is entered. + *

    + * Any {@link RuntimeException} thrown by execution of the fragment is caught by the framework + * and reported to the listener; there is no other notification. + * + * @param probe probe source of execution events + * @param listener optional client callback for results/failure notification + * @param rootFactory provider of AST fragments on behalf of the client + * @param requiredResultType optional requirement, any non-assignable result is reported to the + * the listener, if any, as a failure + * @param instrumentInfo instrumentInfo optional documentation about the Instrument + * @return a handle for access to the binding + */ + @SuppressWarnings("static-method") + public Instrument attach(Probe probe, AdvancedInstrumentResultListener listener, AdvancedInstrumentRootFactory rootFactory, Class requiredResultType, String instrumentInfo) { + final Instrument instrument = new Instrument.AdvancedInstrument(listener, rootFactory, requiredResultType, instrumentInfo); + probe.attach(instrument); + return instrument; + } + @SuppressWarnings("unused") void executionStarted(Source s) { } diff -r 776dc0a09749 -r a0fa69e3e60e truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Sat Sep 19 13:56:42 2015 -0700 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Sat Sep 19 16:29:32 2015 -0700 @@ -208,7 +208,7 @@ * @param instrument an instrument not yet attached to a probe * @throws IllegalStateException if the instrument has ever been attached before */ - public void attach(Instrument instrument) throws IllegalStateException { + void attach(Instrument instrument) throws IllegalStateException { if (instrument.isDisposed()) { throw new IllegalStateException("Attempt to attach disposed instrument"); } diff -r 776dc0a09749 -r a0fa69e3e60e truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java --- a/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java Sat Sep 19 13:56:42 2015 -0700 +++ b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java Sat Sep 19 16:29:32 2015 -0700 @@ -70,7 +70,6 @@ import org.junit.runners.model.InitializationError; import com.oracle.truffle.api.instrument.ASTProber; -import com.oracle.truffle.api.instrument.Instrument; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.Probe; import com.oracle.truffle.api.instrument.StandardSyntaxTag; @@ -255,7 +254,7 @@ // Attach an instrument to every probe tagged as an assignment for (Probe probe : instrumenter.findProbesTaggedAs(StandardSyntaxTag.ASSIGNMENT)) { SLPrintAssigmentValueListener slPrintAssigmentValueListener = new SLPrintAssigmentValueListener(printer); - probe.attach(Instrument.create(slPrintAssigmentValueListener, "SL print assignment value")); + instrumenter.attach(probe, slPrintAssigmentValueListener, "SL print assignment value"); } TruffleVM.Symbol main = vm.findGlobalSymbol("main"); diff -r 776dc0a09749 -r a0fa69e3e60e truffle/com.oracle.truffle.tools/src/com/oracle/truffle/tools/CoverageTracker.java --- a/truffle/com.oracle.truffle.tools/src/com/oracle/truffle/tools/CoverageTracker.java Sat Sep 19 13:56:42 2015 -0700 +++ b/truffle/com.oracle.truffle.tools/src/com/oracle/truffle/tools/CoverageTracker.java Sat Sep 19 16:29:32 2015 -0700 @@ -304,12 +304,10 @@ } } - final CoverageRecord coverage = new CoverageRecord(srcSection); - final Instrument instrument = Instrument.create(coverage, CoverageTracker.class.getSimpleName()); - coverage.instrument = instrument; + final CoverageRecord coverageRecord = new CoverageRecord(srcSection); + final Instrument instrument = getInstrumenter().attach(probe, coverageRecord, CoverageTracker.class.getSimpleName()); + coverageRecord.instrument = instrument; instruments.add(instrument); - probe.attach(instrument); - coverageMap.put(lineLocation, coverage); + coverageMap.put(lineLocation, coverageRecord); } - } diff -r 776dc0a09749 -r a0fa69e3e60e truffle/com.oracle.truffle.tools/src/com/oracle/truffle/tools/NodeExecCounter.java --- a/truffle/com.oracle.truffle.tools/src/com/oracle/truffle/tools/NodeExecCounter.java Sat Sep 19 13:56:42 2015 -0700 +++ b/truffle/com.oracle.truffle.tools/src/com/oracle/truffle/tools/NodeExecCounter.java Sat Sep 19 16:29:32 2015 -0700 @@ -120,7 +120,7 @@ /* * Everything up to here is inlined by Truffle compilation. Delegate the next part * to a method behind an inlining boundary. - * + * * Note that it is not permitted to pass a {@link VirtualFrame} across an inlining * boundary; they are truly virtual in inlined code. */ @@ -301,9 +301,10 @@ if (instrumenter.isInstrumentable(node)) { try { - final Instrument instrument = Instrument.create(instrumentListener, "NodeExecCounter"); + + final Probe probe = instrumenter.probe(node); + final Instrument instrument = instrumenter.attach(probe, instrumentListener, "NodeExecCounter"); instruments.add(instrument); - instrumenter.probe(node).attach(instrument); } catch (ProbeException ex) { failures.add(ex.getFailure()); } @@ -324,9 +325,8 @@ @Override public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { if (countingTag == tag) { - final Instrument instrument = Instrument.create(instrumentListener, NodeExecCounter.class.getSimpleName()); + final Instrument instrument = getInstrumenter().attach(probe, instrumentListener, NodeExecCounter.class.getSimpleName()); instruments.add(instrument); - probe.attach(instrument); } } }