# HG changeset patch # User Michael Van De Vanter # Date 1399951045 25200 # Node ID bb9473723904ff828b24cb20cdc15328c7494c77 # Parent 8f09b84f325f7d48e0d216ece87378533de65f78 Truffle/Instrumentation: - Merge instrumentation support into the general execution context; remove separate Instrumentation interface and implementation - Generalize the ?tagging? mechanism for extensibility: the enum PhylumTag is now an interface, and the standard tags moved to the new enum StandardTag - A new ?trap? mechanism interrupts program execution at any probed node holding a specified PhylumTag; this replaces some other special-purpose code. - Refine several interface by factoring out callback methods and simplifying collaboration among key implementation classes. diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java Fri May 02 16:12:07 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java Mon May 12 20:17:25 2014 -0700 @@ -24,6 +24,8 @@ */ package com.oracle.truffle.api; +import java.util.*; + import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.source.*; @@ -47,20 +49,62 @@ SourceManager getSourceManager(); /** - * Gets access to AST instrumentation services. + * Registers a tool interested in being notified of events related to the loading of sources. + */ + void addSourceListener(SourceListener listener); + + /** + * Add instrumentation to subsequently constructed Truffle ASTs for the guest language; every + * one added will have the opportunity to add instrumentation. + * + * @throws IllegalStateException if AST instrumentation not enabled + * @throws IllegalArgumentException if prober not usable for the guest language implementation. + */ + void addNodeProber(ASTNodeProber nodeProber) throws IllegalStateException, IllegalArgumentException; + + /** + * Registers a tool interested in being notified about the insertion of a newly created + * {@link Probe} into a Truffle AST. + */ + void addProbeListener(ProbeListener listener); + + /** + * Return the (possibly newly created) {@link Probe} uniquely associated with a particular + * source code location. A newly created probe carries no tags. + * + * @return a probe uniquely associated with an extent of guest language source code. */ - Instrumentation getInstrumentation(); + Probe getProbe(SourceSection sourceSection); + + /** + * Returns all existing probes with specific tag, or all probes if {@code tag = null}; empty + * collection if no probes found. + */ + Collection findProbesTaggedAs(PhylumTag tag); + + /** + * Returns all existing probes with first character on a specified line; empty collection if no + * probes found. + */ + Collection findProbesByLine(SourceLineLocation lineLocation); + + /** + * Sets a trap that will make a callback at any AST location where a existing probe holds a + * specified tag; only one trap may be set at a time. + * + * @throws IllegalStateException if a trap is already set + */ + void setTrap(PhylumTrap trap) throws IllegalStateException; + + /** + * Clears a trap that will halt execution; only one trap may be set at a time. + * + * @throws IllegalStateException if no trap is set. + */ + void clearTrap() throws IllegalStateException; /** * Access to information visualization services for the specific language. */ Visualizer getVisualizer(); - - /** - * Add instrumentation to subsequently constructed Truffle ASTs for the guest language; every - * one added will have the opportunity to add instrumentation. - * - * @throws IllegalArgumentException if prober not usable for the guest language. - */ - void addNodeProber(ASTNodeProber nodeProber); } diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractExecutionContext.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractExecutionContext.java Fri May 02 16:12:07 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractExecutionContext.java Mon May 12 20:17:25 2014 -0700 @@ -24,41 +24,175 @@ */ package com.oracle.truffle.api.impl; +import java.util.*; + import com.oracle.truffle.api.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.instrument.impl.*; +import com.oracle.truffle.api.instrument.impl.InstrumentationNode.ProbeCallback; +import com.oracle.truffle.api.instrument.impl.InstrumentationNode.ProbeImpl; import com.oracle.truffle.api.source.*; public abstract class AbstractExecutionContext implements ExecutionContext { + // TODO (mlvdv) use weak references. + /** + * Map: SourceSection ==> probe associated with that source section in an AST. + */ + private final Map srcToProbe = new HashMap<>(); + + // TODO (mlvdv) use weak references. + /** + * Map: Source line ==> probes associated with source sections starting on the line. + */ + private final Map> lineToProbes = new HashMap<>(); + private final SourceManager sourceManager = new SourceManager(); - private final Instrumentation instrumentation; + private final List sourceListeners = new ArrayList<>(); + private final List probeListeners = new ArrayList<>(); + + private final SourceCallback sourceCallback = new SourceCallback() { + + public void startLoading(Source source) { + for (SourceListener listener : sourceListeners) { + listener.loadStarting(source); + } + } + + public void endLoading(Source source) { + for (SourceListener listener : sourceListeners) { + listener.loadEnding(source); + } + } + }; + + private final ProbeCallback probeCallback = new ProbeCallback() { + /** + * Receives (from the {@link Probe} implementation) and distributes notification that a + * {@link Probe} has acquired a new {@linkplain PhylumTag tag}. + */ + public void newTagAdded(ProbeImpl probe, PhylumTag tag) { + for (ProbeListener listener : probeListeners) { + listener.probeTaggedAs(probe, tag); + } + if (trap != null && tag == trap.getTag()) { + probe.setTrap(trap); + } + } + }; + private Visualizer visualizer = new DefaultVisualizer(); - protected ASTProber astProber = null; + + /** + * When non-null, "enter" events with matching tags will trigger a callback. + */ + private PhylumTrap trap = null; protected AbstractExecutionContext() { - this.instrumentation = InstrumentationFactory.create(this); + } + + public void initialize() { + setSourceCallback(sourceCallback); } public final SourceManager getSourceManager() { return sourceManager; } - public final Instrumentation getInstrumentation() { - return instrumentation; + public void addSourceListener(SourceListener listener) { + assert listener != null; + sourceListeners.add(listener); + } + + public void addProbeListener(ProbeListener listener) { + assert listener != null; + probeListeners.add(listener); + } + + public Probe getProbe(SourceSection sourceSection) { + assert sourceSection != null; + + ProbeImpl probe = srcToProbe.get(sourceSection); + + if (probe != null) { + return probe; + } + probe = InstrumentationNode.createProbe(sourceSection, probeCallback); + + // Register new probe by unique SourceSection + srcToProbe.put(sourceSection, probe); + + // Register new probe by source line, there may be more than one + // Create line location for map key + final SourceLineLocation lineLocation = new SourceLineLocation(sourceSection.getSource(), sourceSection.getStartLine()); + + Collection probes = lineToProbes.get(lineLocation); + if (probes == null) { + probes = new ArrayList<>(2); + lineToProbes.put(lineLocation, probes); + } + probes.add(probe); + + for (ProbeListener listener : probeListeners) { + listener.newProbeInserted(sourceSection, probe); + } + + return probe; + } + + /** + * Returns all existing probes with specific tag, or all probes if {@code tag = null}; empty + * collection if no probes found. + */ + public Collection findProbesTaggedAs(PhylumTag tag) { + final List probes = new ArrayList<>(); + for (Probe probe : srcToProbe.values()) { + if (tag == null || probe.isTaggedAs(tag)) { + probes.add(probe); + } + } + return probes; + } + + public Collection findProbesByLine(SourceLineLocation lineLocation) { + final Collection probes = lineToProbes.get(lineLocation); + if (probes == null) { + return Collections.emptyList(); + } + return new ArrayList<>(probes); + } + + // TODO (mlvdv) consider allowing multiple traps (without inhibiting Truffle inlining) + public void setTrap(PhylumTrap trap) { + assert trap != null; + if (this.trap != null) { + throw new IllegalStateException("trap already set"); + } + this.trap = trap; + + for (ProbeImpl probe : srcToProbe.values()) { + if (probe.isTaggedAs(trap.getTag())) { + probe.setTrap(trap); + } + } + } + + public void clearTrap() { + if (this.trap == null) { + throw new IllegalStateException("no trap set"); + } + for (ProbeImpl probe : srcToProbe.values()) { + if (probe.isTaggedAs(trap.getTag())) { + probe.setTrap(null); + } + } + trap = null; } public Visualizer getVisualizer() { return visualizer; } - public void addNodeProber(ASTNodeProber nodeProber) { - if (astProber == null) { - throw new IllegalStateException("No ASTProber installed in context"); - } - astProber.addNodeProber(nodeProber); - } - /** * Assign guest language-specific visualization support for tools. This must be assigned outside * the implementation context to avoid build circularities. @@ -73,19 +207,11 @@ * implementation context to avoid build circularities. It must also be set before any * instrumentation probe implementations are assigned. */ - public void setASTProber(ASTProber astProber) { - this.astProber = astProber; - } + public abstract void setASTProber(ASTProber astProber); /** - * Gets a guest language-specific {@link ASTNodeProber} that will apply all that have been - * added; {@code null} if no instrumentation in AST. + * Establishes source event reporting */ - public ASTNodeProber getCombinedNodeProber() { - return astProber == null ? null : astProber.getCombinedNodeProber(); - } + protected abstract void setSourceCallback(SourceCallback sourceCallback); - public abstract void setInstrumentEventListener(InstrumentEventListener listener); - - public abstract InstrumentEventListener getInstrumentEventListener(); } diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTProber.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTProber.java Fri May 02 16:12:07 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTProber.java Mon May 12 20:17:25 2014 -0700 @@ -24,10 +24,24 @@ */ package com.oracle.truffle.api.instrument; +import com.oracle.truffle.api.nodes.*; + /** * Implementation of a policy for instrumenting Truffle ASTs with {@link Probe}s at * particular nodes by inserting node {@link Wrapper}s. *

+ * Multiple "node probers" can be added, typically by different tools; the "combined prober" will + * apply all of them. + *

+ * The current implementation is provisional and does not completely encapsulate everything that + * needs to be implemented for a particular use-case or set of use-cases. In particular, the AST + * building code for each language implementation must have hand-coded applications of node probing + * methods at the desired locations. For the duration of this approach, this must be done for any + * node that any client tool wishes to probe. + *

+ * A better approach will be to implement such policies as a Truffle {@link NodeVisitor}, but that + * is not possible at this time. + *

* Disclaimer: experimental interface under development. */ public interface ASTProber { @@ -35,10 +49,18 @@ // TODO (mlvdv) This is a provisional interface, more of a marker really // TODO (mlvdv) AST probing should eventually be done with visitors. - void addNodeProber(ASTNodeProber nodeProber); + /** + * Adds a specification for adding probes at particular kinds of nodes. + * + * @param nodeProber + * @throws IllegalArgumentException if the prober is not applicable to the guest language + * implementation. + */ + void addNodeProber(ASTNodeProber nodeProber) throws IllegalArgumentException; /** - * Gets a prober that applies all added {@link ASTNodeProber}s. + * Gets a (possibly guest language-specific) {@link ASTNodeProber} that will apply all that have + * been added; {@code null} if no instrumentation in AST. */ ASTNodeProber getCombinedNodeProber(); } diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Fri May 02 16:12:07 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Mon May 12 20:17:25 2014 -0700 @@ -69,9 +69,7 @@ *

* Disclaimer: experimental; under development. * - * @see Instrumentation * @see Probe - * @see Instrument * @see ASTNodeProber */ public class Instrument extends InstrumentationNode { diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentEventListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentEventListener.java Fri May 02 16:12:07 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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 com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * A client of the instrumentation framework that requests event notifications from the language - * engine. - */ -public interface InstrumentEventListener { - - /** - * The guest language runtime is starting to load a source. Care should be taken to ensure that - * under any circumstance there is always a following call to {@link #loadEnding(Source)} with - * the same argument. - */ - void loadStarting(Source source); - - /** - * The guest language runtime has finished loading a source. Care should be taken to ensure that - * under any circumstance there is always a prior call to {@link #loadStarting(Source)} with the - * same argument. - */ - void loadEnding(Source source); - - /** - * A guest language call is about to be executed. - */ - void callEntering(Node astNode, String name); - - /** - * A guest language call has just completed. - */ - void callReturned(Node astNode, String name); - - /** - * An opportunity for instrumentation to interact with Truffle AST execution halted at some - * node. - */ - void haltedAt(Node astNode, MaterializedFrame frame); - -} diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentation.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentation.java Fri May 02 16:12:07 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2014, 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.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.source.*; - -public interface Instrumentation { - - /** - * Adds a new specification for how to instrument ASTs. - */ - void addNodeProber(ASTNodeProber nodeProber); - - /** - * Registers a tool interested in being notified about the insertion of a newly created - * {@link Probe} into a Truffle AST. - */ - void addProbeListener(ProbeListener listener); - - /** - * Return the (possibly newly created) {@link Probe} uniquely associated with a particular - * source code location. A newly created probe carries no tags. - * - * @param eventListener an optional listener for certain instrumentation-related events - * @return a probe uniquely associated with an extent of guest language source code. - */ - Probe getProbe(SourceSection sourceSection, InstrumentEventListener eventListener); - - /** - * Returns all existing probes with specific tag, or all probes if {@code tag = null}; empty - * collection if no probes found. - */ - Collection findProbesTaggedAs(PhylumTag tag); - - /** - * Returns all existing probes with first character on a specified line; empty collection if no - * probes found. - */ - Collection findProbesByLine(SourceLineLocation lineLocation); - -} diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationFactory.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationFactory.java Fri May 02 16:12:07 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2014, 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 com.oracle.truffle.api.*; -import com.oracle.truffle.api.instrument.impl.*; - -public class InstrumentationFactory { - - public static Instrumentation create(ExecutionContext context) { - return new InstrumentationImpl(context); - } - -} diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTag.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTag.java Fri May 02 16:12:07 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTag.java Mon May 12 20:17:25 2014 -0700 @@ -25,46 +25,32 @@ package com.oracle.truffle.api.instrument; /** - * Program element "tags" that define user-visible behavior for debugging and other simple tools. - * These categories (phyla) should correspond to program structures that are meaningful to - * a guest language programmer. + * Program element "tags", presumed to be singletons (best implemented as enums) that define + * user-visible behavior for debugging and other simple tools. These categories (phyla) + * should correspond to program structures that are meaningful to a guest language programmer. *

* An untagged Truffle node should be understood as an artifact of the guest language implementation * and should not be visible to the user of a guest language programming tool. Nodes may also have * more than one tag, for example a variable assignment that is also a statement. Finally, the * assignment of tags to nodes could depending on the use-case of whatever tool is using them. *

- * This is a somewhat language-agnostic set of phyla, suitable for conventional imperative - * languages, and is being developed incrementally. - *

- * The need for alternative sets of tags is likely to arise, perhaps for other families of languages - * (for example for mostly expression-oriented languages) or even for specific languages. - *

- * These are listed alphabetically so that listing from some collection classes will come out in - * that order. - *

* Disclaimer: experimental interface under development. + * + * @see Probe + * @see Wrapper + * @see StandardTag */ -public enum PhylumTag { +public interface PhylumTag { /** - * Marker for a variable assignment. + * Human-friendly name of guest language program elements belonging to the category, e.g. + * "statement". */ - ASSIGNMENT, - - /** - * Marker for a call site. - */ - CALL, + String name(); /** - * Marker for a location where a guest language exception is about to be thrown. + * Criteria and example uses for the tag. */ - THROW, - - /** - * Marker for a location where ordinary "stepping" should halt. - */ - STATEMENT; + String getDescription(); } diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTagged.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTagged.java Fri May 02 16:12:07 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTagged.java Mon May 12 20:17:25 2014 -0700 @@ -24,13 +24,14 @@ */ package com.oracle.truffle.api.instrument; -import java.util.*; - /** - * Information about a guest language program element that can be marked as belonging to 0 or more - * {@linkplain PhylumTag tags}. + * Information about a guest language program element in a Truffle that can be marked as belonging + * to 0 or more {@linkplain PhylumTag tags}. *

* Disclaimer: experimental interface under development. + * + * @see Probe + * @see Wrapper */ public interface PhylumTagged { @@ -42,6 +43,6 @@ /** * In which categories has this node been tagged (empty set if none). */ - Set getPhylumTags(); + Iterable getPhylumTags(); } diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTrap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTrap.java Mon May 12 20:17:25 2014 -0700 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, 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 com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * A trap that can be set to interrupt execution at probed nodes carrying a specific tag. + */ +public abstract class PhylumTrap { + + private final PhylumTag tag; + + protected PhylumTrap(PhylumTag tag) { + this.tag = tag; + } + + public final PhylumTag getTag() { + return tag; + } + + /** + * Callback that will be received whenever execution enters a node with the specified tag. + */ + public abstract void phylumTrappedAt(Node node, MaterializedFrame frame); +} diff -r 8f09b84f325f -r bb9473723904 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 Fri May 02 16:12:07 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Mon May 12 20:17:25 2014 -0700 @@ -48,7 +48,11 @@ * removed, but some instruments may change their internal state in such a way that the assumption * should also be invalidated. *

- * Disclaimer: experimental interface under development. + * Disclaimer: experimental interface under development. In particular, the + * notify methods must be migrated to another interface. + * + * @see Instrument + * @see Wrapper */ public interface Probe extends PhylumTagged { @@ -73,17 +77,7 @@ */ void removeInstrument(Instrument oldInstrument); - /** - * Change stepping mode, which is used in association with nodes tagged as - * {@linkplain PhylumTag#STATEMENT statements}. - */ - void setStepping(boolean stepping); - - /** - * Value of stepping mode, which is used in association with nodes tagged as - * {@linkplain PhylumTag#STATEMENT statements}. - */ - boolean isStepping(); + // TODO (mlvdv) migrate the remaining methods to another interface. /** * @see ExecutionEvents#enter(Node, VirtualFrame) diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SourceListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SourceListener.java Mon May 12 20:17:25 2014 -0700 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, 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 com.oracle.truffle.api.*; + +/** + * A client of the instrumentation framework that requests event notifications from the language + * engine when sources are loaded. + *

+ * Disclaimer: experimental interface under development. + */ +public interface SourceListener { + + /** + * The guest language runtime is starting to load a source. Care should be taken to ensure that + * under any circumstance there is always a following call to {@link #loadEnding(Source)} with + * the same argument. + */ + void loadStarting(Source source); + + /** + * The guest language runtime has finished loading a source. Care should be taken to ensure that + * under any circumstance there is always a prior call to {@link #loadStarting(Source)} with the + * same argument. + */ + void loadEnding(Source source); + +} diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/StandardTag.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/StandardTag.java Mon May 12 20:17:25 2014 -0700 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, 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; + +/** + * A somewhat language-agnostic set of phylum categories, suitable for conventional imperative + * languages, and is being developed incrementally. + *

+ * The need for alternative sets of tags is likely to arise, perhaps for other families of languages + * (for example for mostly expression-oriented languages) or even for specific languages. + *

+ * Disclaimer: experimental interface under development. + * + * @see Probe + * @see Wrapper + */ +public enum StandardTag implements PhylumTag { + + /** + * Marker for a variable assignment. + */ + ASSIGNMENT("assignment", "a variable assignment"), + + /** + * Marker for a call site. + */ + CALL("call", "a method/procedure call site"), + + /** + * Marker for a location where a guest language exception is about to be thrown. + */ + THROW("throw", "creator of an exception"), + + /** + * Marker for a location where ordinary "stepping" should halt. + */ + STATEMENT("statement", "basic unit of the language, suitable for \"stepping\" in a debugger"); + + private final String name; + private final String description; + + private StandardTag(String name, String description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + +} diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java Fri May 02 16:12:07 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java Mon May 12 20:17:25 2014 -0700 @@ -29,13 +29,11 @@ import com.oracle.truffle.api.nodes.*; /** - * Visualization services for the benefit of {@link Instrumentation}-based tools, possibly - * specialized for each guest language and possibly specialized for relevant information from the - * underlying Truffle implementation. + * Visualization services for the benefit of instrumentation-based tools, possibly specialized for + * each guest language and possibly specialized for relevant information from the underlying Truffle + * implementation. *

* Disclaimer: experimental interface under development. - * - * @See Instrumentation */ public interface Visualizer { diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Wrapper.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Wrapper.java Fri May 02 16:12:07 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Wrapper.java Mon May 12 20:17:25 2014 -0700 @@ -33,14 +33,34 @@ * A wrapper decorates an AST node (its child) by acting as a transparent * proxy for the child with respect to Truffle execution semantics. *

- * A wrapper is also expected to notify its associated {@link Probe} when certain - * {@link ExecutionEvents} occur at the wrapper during program execution. + * A wrapper is also expected to notify its associated {@link Probe} when {@link ExecutionEvents} + * occur at the wrapper during program execution. *

* The wrapper's {@link Probe} is shared by every copy of the wrapper made when the AST is copied. *

- * Wrappers methods must be amenable to Truffle/Graal inlining. + * Wrapper implementation guidelines: + *

    + *
  1. Every guest language implementation should include a Wrapper implementation; usually only one + * is needed.
  2. + *
  3. The Wrapper type should descend from the language-specific node class of the guest + * language.
  4. + *
  5. The Wrapper must have a single {@code @Child private Node child} field.
  6. + *
  7. The Wrapper must act as a proxy for its child, which means implementing every + * possible execute- method that gets called on guest language AST node types by their + * parents, and passing along each call to its child.
  8. + *
  9. The Wrapper must have a single {@code private final Probe probe} to which an optional probe + * can be attached during node construction.
  10. + *
  11. Wrapper methods must also notify its attached {@link Probe}, if any, in terms of standard + * {@link ExecutionEvents}.
  12. + *
  13. Most importantly, Wrappers must be implemented so that Truffle optimization will reduce their + * runtime overhead to zero when there is no probe attached or when a probe has no attached + * {@link Instrument}s.
  14. + *
*

* Disclaimer: experimental interface under development. + * + * @see Probe + * @see ExecutionEvents */ public interface Wrapper extends PhylumTagged { diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationImpl.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationImpl.java Fri May 02 16:12:07 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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.impl; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.source.*; - -public final class InstrumentationImpl implements Instrumentation { - - private final ExecutionContext context; - - // TODO (mlvdv) maps should really use weak references. - - /** - * Map: SourceSection ==> probe associated with that source section in an AST. - */ - private final Map srcToProbe = new HashMap<>(); - - /** - * Map: Source line ==> probes associated with source sections starting on the line. - */ - private final Map> lineToProbes = new HashMap<>(); - - private final List probeListeners = new ArrayList<>(); - - public InstrumentationImpl(ExecutionContext context) { - this.context = context; - } - - public void addNodeProber(ASTNodeProber nodeProber) { - context.addNodeProber(nodeProber); - } - - public void addProbeListener(ProbeListener listener) { - assert listener != null; - probeListeners.add(listener); - } - - /** - * Return the (possibly newly created) {@link Probe} uniquely associated with a particular - * source code location. A newly created probe carries no tags. - * - * @param eventListener an optional listener for certain instrumentation-related events - * @return a probe uniquely associated with an extent of guest language source code. - */ - public Probe getProbe(SourceSection sourceSection, InstrumentEventListener eventListener) { - assert sourceSection != null; - - Probe probe = srcToProbe.get(sourceSection); - - if (probe != null) { - return probe; - } - probe = InstrumentationNode.createProbe(this, sourceSection, eventListener); - - // Register new probe by unique SourceSection - srcToProbe.put(sourceSection, probe); - - // Register new probe by source line, there may be more than one - // Create line location for map key - final SourceLineLocation lineLocation = new SourceLineLocation(sourceSection.getSource(), sourceSection.getStartLine()); - - Collection probes = lineToProbes.get(lineLocation); - if (probes == null) { - probes = new ArrayList<>(2); - lineToProbes.put(lineLocation, probes); - } - probes.add(probe); - - for (ProbeListener listener : probeListeners) { - listener.newProbeInserted(sourceSection, probe); - } - - return probe; - } - - /** - * Returns all existing probes with specific tag, or all probes if {@code tag = null}; empty - * collection if no probes found. - */ - public Collection findProbesTaggedAs(PhylumTag tag) { - if (tag == null) { - return new ArrayList<>(srcToProbe.values()); - } - final List probes = new ArrayList<>(); - for (Probe probe : srcToProbe.values()) { - if (probe.isTaggedAs(tag)) { - probes.add(probe); - } - } - return probes; - } - - /** - * Returns all existing probes with first character on a specified line; empty collection if no - * probes found. - */ - public Collection findProbesByLine(SourceLineLocation lineLocation) { - final Collection probes = lineToProbes.get(lineLocation); - if (probes == null) { - return Collections.emptyList(); - } - return new ArrayList<>(probes); - } - - /** - * Receives (from the {@link Probe} implementation) and distributes notification that a - * {@link Probe} has acquired a new {@linkplain PhylumTag tag}. - */ - void newTagAdded(Probe probe, PhylumTag tag) { - for (ProbeListener listener : probeListeners) { - listener.probeTaggedAs(probe, tag); - } - } - -} diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationNode.java Fri May 02 16:12:07 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationNode.java Mon May 12 20:17:25 2014 -0700 @@ -27,6 +27,7 @@ import java.util.*; import com.oracle.truffle.api.*; +import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.nodes.*; @@ -38,17 +39,18 @@ */ public abstract class InstrumentationNode extends Node implements ExecutionEvents { - // TODO (mlvdv) This is a pretty awkward design; it is a priority to revise it. + public interface ProbeCallback { + void newTagAdded(ProbeImpl probe, PhylumTag tag); + } /** * Creates a new {@link Probe}, presumed to be unique to a particular {@linkplain SourceSection} * extent of guest language source code. * - * @param eventListener an optional listener for certain instrumentation-related events. * @return a new probe */ - static Probe createProbe(InstrumentationImpl instrumentation, SourceSection sourceSection, InstrumentEventListener eventListener) { - return new ProbeImpl(instrumentation, sourceSection, eventListener); + public static ProbeImpl createProbe(SourceSection sourceSection, ProbeCallback probeCallback) { + return new ProbeImpl(sourceSection, probeCallback); } /** @@ -103,84 +105,84 @@ probe.notifyProbeChanged(instrument); } - private void internalEnter(Node astNode, VirtualFrame frame) { + protected void internalEnter(Node astNode, VirtualFrame frame) { enter(astNode, frame); if (next != null) { next.internalEnter(astNode, frame); } } - private void internalLeave(Node astNode, VirtualFrame frame) { + protected void internalLeave(Node astNode, VirtualFrame frame) { leave(astNode, frame); if (next != null) { next.internalLeave(astNode, frame); } } - private void internalLeave(Node astNode, VirtualFrame frame, boolean result) { + protected void internalLeave(Node astNode, VirtualFrame frame, boolean result) { leave(astNode, frame, result); if (next != null) { next.internalLeave(astNode, frame, result); } } - private void internalLeave(Node astNode, VirtualFrame frame, byte result) { + protected void internalLeave(Node astNode, VirtualFrame frame, byte result) { leave(astNode, frame, result); if (next != null) { next.internalLeave(astNode, frame, result); } } - private void internalLeave(Node astNode, VirtualFrame frame, short result) { + protected void internalLeave(Node astNode, VirtualFrame frame, short result) { leave(astNode, frame, result); if (next != null) { next.internalLeave(astNode, frame, result); } } - private void internalLeave(Node astNode, VirtualFrame frame, int result) { + protected void internalLeave(Node astNode, VirtualFrame frame, int result) { leave(astNode, frame, result); if (next != null) { next.internalLeave(astNode, frame, result); } } - private void internalLeave(Node astNode, VirtualFrame frame, long result) { + protected void internalLeave(Node astNode, VirtualFrame frame, long result) { leave(astNode, frame, result); if (next != null) { next.internalLeave(astNode, frame, result); } } - private void internalLeave(Node astNode, VirtualFrame frame, char result) { + protected void internalLeave(Node astNode, VirtualFrame frame, char result) { leave(astNode, frame, result); if (next != null) { next.internalLeave(astNode, frame, result); } } - private void internalLeave(Node astNode, VirtualFrame frame, float result) { + protected void internalLeave(Node astNode, VirtualFrame frame, float result) { leave(astNode, frame, result); if (next != null) { next.internalLeave(astNode, frame, result); } } - private void internalLeave(Node astNode, VirtualFrame frame, double result) { + protected void internalLeave(Node astNode, VirtualFrame frame, double result) { leave(astNode, frame, result); if (next != null) { next.internalLeave(astNode, frame, result); } } - private void internalLeave(Node astNode, VirtualFrame frame, Object result) { + protected void internalLeave(Node astNode, VirtualFrame frame, Object result) { leave(astNode, frame, result); if (next != null) { next.internalLeave(astNode, frame, result); } } - private void internalLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { + protected void internalLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { leaveExceptional(astNode, frame, null); if (next != null) { next.internalLeaveExceptional(astNode, frame, e); @@ -197,100 +199,92 @@ * May be categorized by one or more {@linkplain PhylumTag tags}, signifying information useful * for instrumentation about its AST location(s). */ - private static final class ProbeImpl extends InstrumentationNode implements Probe { - - final InstrumentationImpl instrumentation; + public static final class ProbeImpl extends InstrumentationNode implements Probe { - final InstrumentEventListener eventListener; - - @CompilerDirectives.CompilationFinal private Assumption probeUnchanged; + private final ProbeCallback probeCallback; /** - * When in stepping mode, ordinary line breakpoints are ignored, but every entry at a line - * will cause a halt. - */ - @CompilerDirectives.CompilationFinal private boolean stepping; - - /** - * Source information about the AST node to which this instrumentation is attached. + * Source information about the AST node (and its clones) to which this probe is attached. */ private final SourceSection probedSourceSection; - private final Set tags = EnumSet.noneOf(PhylumTag.class); + // TODO (mlvdv) assumption model broken + @CompilerDirectives.CompilationFinal private Assumption probeUnchanged; + + @CompilerDirectives.CompilationFinal private PhylumTrap trap = null; - private ProbeImpl(InstrumentationImpl instrumentation, SourceSection sourceSection, InstrumentEventListener eventListener) { - this.instrumentation = instrumentation; + private final ArrayList tags = new ArrayList<>(); + + private ProbeImpl(SourceSection sourceSection, ProbeCallback probeCallback) { + this.probeCallback = probeCallback; this.probedSourceSection = sourceSection; - this.eventListener = eventListener == null ? NullInstrumentEventListener.INSTANCE : eventListener; this.probeUnchanged = Truffle.getRuntime().createAssumption(); this.next = null; } + public SourceSection getSourceLocation() { + return probedSourceSection; + } + + @SlowPath + public void tagAs(PhylumTag tag) { + assert tag != null; + if (!tags.contains(tag)) { + tags.add(tag); + probeCallback.newTagAdded(this, tag); + } + } + + public boolean isTaggedAs(PhylumTag tag) { + assert tag != null; + return tags.contains(tag); + } + + public Iterable getPhylumTags() { + return tags; + } + + @SlowPath + public void addInstrument(Instrument instrument) { + probeUnchanged.invalidate(); + super.internalAddInstrument(instrument); + probeUnchanged = Truffle.getRuntime().createAssumption(); + } + + @SlowPath + public void removeInstrument(Instrument instrument) { + probeUnchanged.invalidate(); + super.internalRemoveInstrument(instrument); + probeUnchanged = Truffle.getRuntime().createAssumption(); + } + @Override public Probe getProbe() { return this; } @Override + @SlowPath protected void notifyProbeChanged(Instrument instrument) { probeUnchanged.invalidate(); probeUnchanged = Truffle.getRuntime().createAssumption(); } - public SourceSection getSourceLocation() { - return probedSourceSection; - } - - public void tagAs(PhylumTag tag) { - assert tag != null; - if (!tags.contains(tag)) { - tags.add(tag); - instrumentation.newTagAdded(this, tag); - } - } - - public boolean isTaggedAs(PhylumTag tag) { - assert tag != null; - return tags.contains(tag); - } - - public Set getPhylumTags() { - return tags; - } - - public void setStepping(boolean stepping) { - if (this.stepping != stepping) { - this.stepping = stepping; - probeUnchanged.invalidate(); - probeUnchanged = Truffle.getRuntime().createAssumption(); - } - } - - public boolean isStepping() { - return stepping; - } - - @CompilerDirectives.SlowPath - public void addInstrument(Instrument instrument) { + @SlowPath + public void setTrap(PhylumTrap trap) { + assert trap == null || isTaggedAs(trap.getTag()); probeUnchanged.invalidate(); - super.internalAddInstrument(instrument); - probeUnchanged = Truffle.getRuntime().createAssumption(); - } - - @CompilerDirectives.SlowPath - public void removeInstrument(Instrument instrument) { - probeUnchanged.invalidate(); - super.internalRemoveInstrument(instrument); + this.trap = trap; probeUnchanged = Truffle.getRuntime().createAssumption(); } public void notifyEnter(Node astNode, VirtualFrame frame) { - if (stepping || next != null) { + if (trap != null || next != null) { if (!probeUnchanged.isValid()) { CompilerDirectives.transferToInterpreter(); } - if (stepping) { - eventListener.haltedAt(astNode, frame.materialize()); + if (trap != null) { + trap.phylumTrappedAt(astNode, frame.materialize()); } if (next != null) { next.internalEnter(astNode, frame); diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/NullInstrumentEventListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/NullInstrumentEventListener.java Fri May 02 16:12:07 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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.impl; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Minimal, mostly no-op implementation of instrumentation services. - */ -public final class NullInstrumentEventListener implements InstrumentEventListener { - - public static final InstrumentEventListener INSTANCE = new NullInstrumentEventListener(); - - private NullInstrumentEventListener() { - } - - public void callEntering(Node astNode, String name) { - } - - public void callReturned(Node astNode, String name) { - } - - public void haltedAt(Node astNode, MaterializedFrame frame) { - } - - public void loadStarting(Source source) { - } - - public void loadEnding(Source source) { - } - -} diff -r 8f09b84f325f -r bb9473723904 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/SourceCallback.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/SourceCallback.java Mon May 12 20:17:25 2014 -0700 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, 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.impl; + +import com.oracle.truffle.api.*; + +/** + * Instrumentation callback for guest language source-related events. + */ +public interface SourceCallback { + + public void startLoading(Source source); + + public void endLoading(Source source); +}