# HG changeset patch # User Michael Van De Vanter # Date 1398051447 25200 # Node ID 0c6d8a08e31b7b7eaba787be1779160370aea2f3 # Parent 0e713dba33bbaeccf7c2ebfeabfac0f1a8f80cb2 Truffle: Major cleanup and extension of the Truffle Instrumentation framework in com.oracle.truffle.api diff -r 0e713dba33bb -r 0c6d8a08e31b 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 Thu Mar 27 16:38:39 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java Sun Apr 20 20:37:27 2014 -0700 @@ -24,11 +24,12 @@ */ package com.oracle.truffle.api; -import com.oracle.truffle.api.debug.*; +import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.source.*; /** - * Information about the runtime context of a Truffle program. + * Access to information and basic services in the runtime context for a Truffle-implemented guest + * language. *

* Disclaimer: this interface is under development and will change. */ @@ -46,8 +47,20 @@ SourceManager getSourceManager(); /** - * Gets access to debugging services. Returns an inert instance if no services installed. + * Gets access to AST instrumentation services. + */ + Instrumentation instrumentation(); + + /** + * Access to information visualization services for the specific language. */ - DebugContext getDebugContext(); + Visualizer visualizer(); + /** + * 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 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/ASTPrinter.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/ASTPrinter.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +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.debug; - -import java.io.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * Language-agnostic access to AST-based debugging support. - *

- * WARNING: this interface is under development and will change substantially. - */ -public interface ASTPrinter { - - /** - * Prints a textual AST display, one line per node, with nesting. - * - * @param p - * @param node the root node of the display. - * @param maxDepth the maximum number of levels to print below the root - * @param markNode a node to mark with a textual arrow prefix, if present. - */ - void printTree(PrintWriter p, Node node, int maxDepth, Node markNode); - - /** - * Creates a textual AST display, one line per node, with nesting. - * - * @param node the root node of the display. - * @param maxDepth the maximum number of levels to print below the root - * @param markNode a node to mark with a textual arrow prefix, if present. - */ - String printTreeToString(Node node, int maxDepth, Node markNode); - - /** - * Creates a textual AST display, one line per node, with nesting. - * - * @param node the root node of the display. - * @param maxDepth the maximum number of levels to print below the root - */ - String printTreeToString(Node node, int maxDepth); - -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugContext.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugContext.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +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.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.instrument.*; - -/** - * Access to the suite of facilities available when debugging is enabled. - */ -public interface DebugContext { - - /** - * Access to the Truffle execution context being debugged. - */ - ExecutionContext getContext(); - - /** - * Access to the appropriate implementation of AST node instrumentation. - */ - NodeInstrumenter getNodeInstrumenter(); - - /** - * Access to the management of breakpoints, notifications, etc. - */ - DebugManager getDebugManager(); - - /** - * Gets a printer for Truffle ASTs helpful for debugging guest language implementations. - */ - ASTPrinter getASTPrinter(); - - /** - * Converts a value in the guest language to a display string. - */ - String displayValue(Object value); - - /** - * Converts a slot identifier in the guest language to a display string. - */ - String displayIdentifier(FrameSlot slot); - - /** - * Invokes appropriate debugging action when Truffle execution halts. - */ - void executionHalted(Node node, VirtualFrame frame); - -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugManager.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugManager.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +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.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.instrument.*; -import com.oracle.truffle.api.nodes.instrument.InstrumentationProbeNode.ProbeChain; - -/** - * Language-agnostic access to AST-based debugging support. - *

- * Disclaimer: this interface is under development and will change. - */ -public interface DebugManager { - - /** - * Informs the {@link DebugManager} that 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 #notifyFinishedLoading(Source)} with the same argument. - */ - void notifyStartLoading(Source source); - - /** - * Informs the {@link DebugManager} that 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 #notifyStartLoading(Source)} with the same argument. - */ - void notifyFinishedLoading(Source source); - - /** - * Return a reference to the (canonical) instrumentation site associated with a particular - * source code location; this site will have effect on any Truffle/AST implementation - * corresponding to the source location, even if the AST is copied multiple times. - */ - ProbeChain getProbeChain(SourceSection sourceSection); - - /** - * Informs the {@link DebugManager} that Truffle execution has halted; execution will resume - * when this method returns. - * - * @param astNode a guest language AST node that represents the current execution site, assumed - * not to be any kind of {@link InstrumentationNode}, - * @param frame execution frame at the site where execution suspended - */ - void haltedAt(Node astNode, VirtualFrame frame); - -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DefaultDebugManager.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DefaultDebugManager.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +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.debug; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.instrument.InstrumentationProbeNode.ProbeChain; -import com.oracle.truffle.api.source.*; - -/** - * A minimal, language-agnostic implementation that tracks loaded sources, and keeps maps describing - * what locations in the source have instrumentation available. This implementation will do nothing - * unless there are calls to it during AST construction, notably {@link #notifyStartLoading(Source)} - * and {@link #notifyFinishedLoading(Source)} and there are at least some AST nodes being - * instrumented. - */ -public class DefaultDebugManager implements DebugManager { - - private final Set loadedSources = new HashSet<>(); - - private Source beingLoaded = null; - - /** - * Map: SourceSection ==> probe chain associated with that source section in an AST. - */ - private final Map srcToProbeChain = new HashMap<>(); - - /** - * Map: Source lines ==> probe chains associated with source sections starting on the line. - */ - private final Map> lineToProbeChains = new HashMap<>(); - - private final ExecutionContext context; - - public DefaultDebugManager(ExecutionContext context) { - this.context = context; - } - - /** - * Gets the {@linkplain ProbeChain probe} associated with a particular {@link SourceSection - * source location}, creating a new one if needed. There should only be one probe associated - * with each {@linkplain SourceSection source location}. - */ - public ProbeChain getProbeChain(SourceSection sourceSection) { - assert sourceSection != null; - assert sourceSection.getSource().equals(beingLoaded); - - ProbeChain probeChain = srcToProbeChain.get(sourceSection); - - if (probeChain != null) { - return probeChain; - } - probeChain = new ProbeChain(context, sourceSection, null); - - // Register new ProbeChain by unique SourceSection - srcToProbeChain.put(sourceSection, probeChain); - - // Register new ProbeChain by source line, there may be more than one - // Create line location for map key - final SourceLineLocation lineLocation = new SourceLineLocation(sourceSection.getSource(), sourceSection.getStartLine()); - - Set probeChains = lineToProbeChains.get(lineLocation); - if (probeChains == null) { - probeChains = new HashSet<>(); - lineToProbeChains.put(lineLocation, probeChains); - } - probeChains.add(probeChain); - - return probeChain; - } - - public void notifyStartLoading(Source source) { - assert beingLoaded == null; - beingLoaded = source; - } - - public void notifyFinishedLoading(Source source) { - assert source == beingLoaded; - loadedSources.add(source); - beingLoaded = null; - } - - public void haltedAt(Node astNode, VirtualFrame frame) { - } - -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/KillException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/KillException.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +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.debug; - -import com.oracle.truffle.api.nodes.*; - -/** - * Controls breaking out of an execution context, such as a shell or eval. - */ -public final class KillException extends ControlFlowException { - - private static final long serialVersionUID = 3163641880088766957L; -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/QuitException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/QuitException.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +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.debug; - -import com.oracle.truffle.api.nodes.*; - -/** - * Controls breaking out of all executions and ending Truffle execution. - */ -public final class QuitException extends ControlFlowException { - - private static final long serialVersionUID = -4301115629772778413L; -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractExecutionContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractExecutionContext.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,91 @@ +/* + * 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.impl; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.instrument.impl.*; +import com.oracle.truffle.api.source.*; + +public abstract class AbstractExecutionContext implements ExecutionContext { + + private final SourceManager sourceManager = new SourceManager(); + private final Instrumentation instrumentation; + private Visualizer visualizer = new DefaultVisualizer(); + protected ASTProber astProber = null; + + protected AbstractExecutionContext() { + this.instrumentation = InstrumentationFactory.create(this); + } + + public final SourceManager getSourceManager() { + return sourceManager; + } + + public final Instrumentation instrumentation() { + return instrumentation; + } + + public Visualizer visualizer() { + 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. + */ + public void setVisualizer(Visualizer visualizer) { + this.visualizer = visualizer; + } + + /** + * Assigns a guest language-specific manager for using {@link ASTNodeProber}s added by tools to + * instrument ASTs with {@link Probe}s at specified nodes. This must be assigned outside the + * 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; + } + + /** + * Gets a guest language-specific {@link ASTNodeProber} that will apply all that have been + * added; {@code null} if no instrumentation in AST. + */ + public ASTNodeProber getCombinedNodeProber() { + return astProber == null ? null : astProber.getCombinedNodeProber(); + } + + public abstract void setInstrumentEventListener(InstrumentEventListener listener); + + public abstract InstrumentEventListener getInstrumentEventListener(); +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTNodeProber.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTNodeProber.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,63 @@ +/* + * 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.nodes.*; + +/** + * Implementation of a policy for instrumenting inserting a {@link Probe} at a Truffle AST + * node. + *

+ * Note that this interface is guest language agnostic, but current extensions are + * language-specific. This will be revisited. + *

+ * Disclaimer: experimental interface under development. Really! + */ +public interface ASTNodeProber { + + /** + * Optionally applies instrumentation at a Truffle AST node, depending on guest + * language characteristics and use-case policy. + *

+ * + * @param astNode an AST node to which instrumentation might be applied + * @param tag an optional category directing how the node, if instrumented, should be perceived + * by tool users + * @param args additional arguments for instrumentation specific to a particular guest language + * @return if no instrumentation should be applied or if the node is a {@link Wrapper} then the + * unmodified node; otherwise a newly created {@link Wrapper} (whose child + * {@code astNode}) with an associated {@link Probe} . + */ + + Node probeAs(Node astNode, PhylumTag tag, Object... args); +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTPrinter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTPrinter.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,65 @@ +/* + * 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 java.io.*; + +import com.oracle.truffle.api.nodes.*; + +/** + * Language-agnostic access to AST-based debugging support. + *

+ * WARNING: this interface is under development and will change substantially. + */ +public interface ASTPrinter { + + /** + * Prints a textual AST display, one line per node, with nesting. + * + * @param p + * @param node the root node of the display. + * @param maxDepth the maximum number of levels to print below the root + * @param markNode a node to mark with a textual arrow prefix, if present. + */ + void printTree(PrintWriter p, Node node, int maxDepth, Node markNode); + + /** + * Creates a textual AST display, one line per node, with nesting. + * + * @param node the root node of the display. + * @param maxDepth the maximum number of levels to print below the root + * @param markNode a node to mark with a textual arrow prefix, if present. + */ + String printTreeToString(Node node, int maxDepth, Node markNode); + + /** + * Creates a textual AST display, one line per node, with nesting. + * + * @param node the root node of the display. + * @param maxDepth the maximum number of levels to print below the root + */ + String printTreeToString(Node node, int maxDepth); + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTProber.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ASTProber.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,44 @@ +/* + * 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; + +/** + * Implementation of a policy for instrumenting Truffle ASTs with {@link Probe}s at + * particular nodes by inserting node {@link Wrapper}s. + *

+ * Disclaimer: experimental interface under development. + */ +public interface ASTProber { + + // 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); + + /** + * Gets a prober that applies all added {@link ASTNodeProber}s. + */ + ASTNodeProber getCombinedNodeProber(); +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ExecutionEvents.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ExecutionEvents.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,179 @@ +/* + * 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.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Normal events during program execution at Truffle AST nodes that are reported via a {@link Probe} + * associated with the node, and made available to the probe's attached {@link Instrument}s. + *

+ * Disclaimer: experimental interface under development. + */ +public interface ExecutionEvents { + + /** + * Notifies that an AST node's execute method has just been entered. Callers should assure that + * a matching call to {@link #leave(Node, VirtualFrame, Object)} always follows. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame being passed to the execute method + */ + void enter(Node astNode, VirtualFrame frame); + + /** + * Notifies that an AST Node's void-valued execute method is about to exit. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + */ + void leave(Node astNode, VirtualFrame frame); + + /** + * Notifies that an AST Node's boolean-valued execute method is about to exit. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, boolean result); + + /** + * Notifies that an AST Node's byte-valued execute method is about to exit. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, byte result); + + /** + * Notifies that an AST Node's short-valued execute method is about to exit. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, short result); + + /** + * Notifies that an AST Node's integer-valued execute method is about to exit. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, int result); + + /** + * Notifies that an AST Node's long-valued execute method is about to exit. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, long result); + + /** + * Notifies that an AST Node's float-valued execute method is about to exit. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, float result); + + /** + * Notifies that an AST Node's double-valued execute method is about to exit. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, double result); + + /** + * Notifies that an AST Node's char-valued execute method is about to exit. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, char result); + + /** + * Notifies that an AST Node's object-valued execute method is about to exit. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param result The result of the call to the execute method. + */ + void leave(Node astNode, VirtualFrame frame, Object result); + + /** + * Notifies that an AST Node's execute method is about to leave under exceptional conditions, + * returning no value. + *

+ * Callers should assure (via {@code try/finally}) that a matching call to this method always + * follows a call to {@link #enter(Node, VirtualFrame)}. + * + * @param astNode The AST node on which the execute method is being called + * @param frame The frame that was passed to the execute method + * @param e the exception associated with the unusual return + */ + void leaveExceptional(Node astNode, VirtualFrame frame, Exception e); + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,40 @@ +/* + * 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 receiver of Truffle AST {@link ExecutionEvents}, propagated from a {@link Probe} to which the + * instrument is attached. + *

+ * Disclaimer: experimental interface under development. + */ +public interface Instrument extends ExecutionEvents { + + /** + * @return the {@link Probe} to which this instrument is attached. + */ + Probe getProbe(); + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentEventListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentEventListener.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,67 @@ +/* + * 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 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrumentation.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,66 @@ +/* + * 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 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/InstrumentationFactory.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,36 @@ +/* + * 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 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/KillException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/KillException.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,35 @@ +/* + * 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.nodes.*; + +/** + * Controls breaking out of an execution context, such as a shell or eval. + */ +public final class KillException extends ControlFlowException { + + private static final long serialVersionUID = 3163641880088766957L; +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTag.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTag.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,70 @@ +/* + * 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; + +/** + * 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. + *

+ * 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. + */ +public enum PhylumTag { + + /** + * Marker for a variable assignment. + */ + ASSIGNMENT, + + /** + * Marker for a call site. + */ + CALL, + + /** + * Marker for a location where a guest language exception is about to be thrown. + */ + THROW, + + /** + * Marker for a location where ordinary "stepping" should halt. + */ + STATEMENT; + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTagged.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/PhylumTagged.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,47 @@ +/* + * 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.*; + +/** + * Information about a guest language program element that can be marked as belonging to 0 or more + * {@linkplain PhylumTag tags}. + *

+ * Disclaimer: experimental interface under development. + */ +public interface PhylumTagged { + + /** + * Is this node tagged as belonging to a particular category of language constructs? + */ + boolean isTaggedAs(PhylumTag tag); + + /** + * In which categories has this node been tagged (empty set if none). + */ + Set getPhylumTags(); + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,148 @@ +/* + * 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.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * A collector of {@link ExecutionEvents} at a specific site (node) in a Truffle AST (generated by a + * {@link Wrapper} inserted into the AST) for the purpose of instrumentation. For probes + * associated with programmer-facing tools, there should be no more than one probe associated with a + * particular piece of source code syntax (i.e. a {@link SourceSection}). + *

+ * Any {@linkplain PhylumTag tags} associated with a particular piece of source code syntax are + * managed by the probe. + *

+ * When ASTs are copied, it is presumed that the probe for a site is shared by all AST nodes + * representing that site. + *

+ * A probe holds zero or more {@link Instrument}s, which can be added and removed dynamically. + * Events reported to a probe are propagated to every attached instrument; the order is undefined. + *

+ * Probe methods must be amenable to Truffle/Graal inlining on the assumption that the collection of + * attached instruments seldom changes. The assumption is invalidated when instruments are added or + * 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. + */ +public interface Probe extends PhylumTagged { + + /** + * The source location with which this probe is (presumably uniquely) associated. + */ + SourceSection getSourceLocation(); + + /** + * Mark this probe as being associated with an AST node in some category useful for debugging + * and other tools. + */ + void tagAs(PhylumTag tag); + + /** + * Adds an instrument to this probe. + */ + void addInstrument(Instrument newInstrument); + + /** + * Removes an instrument from this probe. + */ + 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(); + + /** + * @see ExecutionEvents#enter(Node, VirtualFrame) + */ + void notifyEnter(Node astNode, VirtualFrame frame); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame) + */ + void notifyLeave(Node astNode, VirtualFrame frame); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, boolean) + */ + void notifyLeave(Node astNode, VirtualFrame frame, boolean result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, byte) + */ + void notifyLeave(Node astNode, VirtualFrame frame, byte result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, short) + */ + void notifyLeave(Node astNode, VirtualFrame frame, short result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, int) + */ + void notifyLeave(Node astNode, VirtualFrame frame, int result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, long) + */ + void notifyLeave(Node astNode, VirtualFrame frame, long result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, char) + */ + void notifyLeave(Node astNode, VirtualFrame frame, char result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, float) + */ + void notifyLeave(Node astNode, VirtualFrame frame, float result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, double) + */ + void notifyLeave(Node astNode, VirtualFrame frame, double result); + + /** + * @see ExecutionEvents#leave(Node, VirtualFrame, Object) + */ + void notifyLeave(Node astNode, VirtualFrame frame, Object result); + + /** + * @see ExecutionEvents#leaveExceptional(Node, VirtualFrame, Exception) + */ + void notifyLeaveExceptional(Node astNode, VirtualFrame frame, Exception e); + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeListener.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,46 @@ +/* + * 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.*; + +/** + * Client for receiving events relate to {@link Probe} management. Does not report AST copying. + */ +public interface ProbeListener { + + /** + * Notifies that a newly created (untagged) {@link Probe} has been inserted into a Truffle AST. + * There will be no notification when an existing {@link Probe} is shared by an AST copy. + */ + void newProbeInserted(SourceSection location, Probe probe); + + /** + * Notifies that a (fully constructed) {@link Probe} has been tagged. A subsequent marking with + * the same tag is idempotent and generates no notification. + */ + void probeTaggedAs(Probe probe, PhylumTag tag); + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/QuitException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/QuitException.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,35 @@ +/* + * 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.nodes.*; + +/** + * Controls breaking out of all executions and ending Truffle execution. + */ +public final class QuitException extends ControlFlowException { + + private static final long serialVersionUID = -4301115629772778413L; +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,50 @@ +/* + * 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.*; + +/** + * Visualization services for guest language and Truffle information. + */ +public interface Visualizer { + + /** + * Gets a printer for Truffle ASTs, possibly specialized to be helpful for a specific guest + * language implementation. + */ + ASTPrinter getASTPrinter(); + + /** + * Converts a value in the guest language to a display string. + */ + String displayValue(Object value); + + /** + * Converts a slot identifier in the guest language to a display string. + */ + String displayIdentifier(FrameSlot slot); + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Wrapper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Wrapper.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,57 @@ +/* + * 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.nodes.*; + +/** + * A node that can be inserted into a Truffle AST in order to attach instrumentation at a + * particular node. + *

+ * 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. + *

+ * 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. + *

+ * Disclaimer: experimental interface under development. + */ +public interface Wrapper extends PhylumTagged { + + /** + * Gets the AST node being instrumented, which should never be an instance of {@link Wrapper}. + */ + Node getChild(); + + /** + * Gets the {@link Probe} to which events occurring at this wrapper's child are propagated. + */ + Probe getProbe(); + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,168 @@ +/* + * 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 java.io.*; +import java.util.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.nodes.NodeUtil.NodeClass; +import com.oracle.truffle.api.nodes.NodeUtil.NodeField; +import com.oracle.truffle.api.nodes.NodeUtil.NodeFieldKind; + +/** + * A language-agnostic for printing out various pieces of a Truffle AST. + */ +public class DefaultASTPrinter implements ASTPrinter { + + public DefaultASTPrinter() { + } + + public void printTree(PrintWriter p, Node node, int maxDepth, Node markNode) { + printTree(p, node, maxDepth, markNode, 1); + p.println(); + p.flush(); + } + + public String printTreeToString(Node node, int maxDepth, Node markNode) { + StringWriter out = new StringWriter(); + printTree(new PrintWriter(out), node, maxDepth, markNode); + return out.toString(); + } + + public String printTreeToString(Node node, int maxDepth) { + return printTreeToString(node, maxDepth, null); + } + + private static void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, int level) { + if (node == null) { + p.print("null"); + return; + } + + p.print(nodeName(node)); + + String sep = ""; + p.print("("); + + final SourceSection src = node.getSourceSection(); + if (src != null) { + if (!(src instanceof NullSourceSection)) { + p.print(src.getSource().getName() + ":" + src.getStartLine()); + } + } + if (node instanceof PhylumTagged) { + final PhylumTagged taggedNode = (PhylumTagged) node; + String prefix = ""; + for (PhylumTag tag : taggedNode.getPhylumTags()) { + p.print(prefix); + prefix = ","; + p.print(tag.toString()); + } + + } + + ArrayList childFields = new ArrayList<>(); + + for (NodeField field : NodeClass.get(node.getClass()).getFields()) { + if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { + childFields.add(field); + } else if (field.getKind() == NodeFieldKind.DATA) { + // p.print(sep); + // sep = ", "; + // + // final String fieldName = field.getName(); + // switch (fieldName) { + // + // } + // p.print(fieldName); + // p.print(" = "); + // p.print(field.loadValue(node)); + } + } + p.print(")"); + + if (level <= maxDepth) { + + if (childFields.size() != 0) { + p.print(" {"); + for (NodeField field : childFields) { + + Object value = field.loadValue(node); + if (value == null) { + printNewLine(p, level); + p.print(field.getName()); + p.print(" = null "); + } else if (field.getKind() == NodeFieldKind.CHILD) { + final Node valueNode = (Node) value; + printNewLine(p, level, valueNode == markNode); + p.print(field.getName()); + p.print(" = "); + printTree(p, valueNode, maxDepth, markNode, level + 1); + } else if (field.getKind() == NodeFieldKind.CHILDREN) { + printNewLine(p, level); + p.print(field.getName()); + Node[] children = (Node[]) value; + p.print(" = ["); + sep = ""; + for (Node child : children) { + p.print(sep); + sep = ", "; + printTree(p, child, maxDepth, markNode, level + 1); + } + p.print("]"); + } else { + printNewLine(p, level); + p.print(field.getName()); + } + } + printNewLine(p, level - 1); + p.print("}"); + } + } + } + + private static void printNewLine(PrintWriter p, int level, boolean mark) { + p.println(); + for (int i = 0; i < level; i++) { + if (mark && i == 0) { + p.print(" -->"); + } else { + p.print(" "); + } + } + } + + private static void printNewLine(PrintWriter p, int level) { + printNewLine(p, level, false); + } + + private static String nodeName(Node node) { + return node.getClass().getSimpleName(); + } + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultInstrument.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultInstrument.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,84 @@ +/* + * 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.frame.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.nodes.*; + +/** + * An {@link Instrument} that implements all {@link ExecutionEvents} notifications with empty + * methods. + */ +public class DefaultInstrument extends InstrumentationNodeImpl implements Instrument { + + protected DefaultInstrument() { + } + + public void enter(Node astNode, VirtualFrame frame) { + } + + public void leave(Node astNode, VirtualFrame frame) { + } + + public void leave(Node astNode, VirtualFrame frame, boolean result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, byte result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, short result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, int result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, long result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, char result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, float result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, double result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, Object result) { + } + + public void leaveExceptional(Node astNode, VirtualFrame frame, Exception e) { + } + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,50 @@ +/* + * 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.frame.*; +import com.oracle.truffle.api.instrument.*; + +public class DefaultVisualizer implements Visualizer { + + private final ASTPrinter astPrinter; + + public DefaultVisualizer() { + this.astPrinter = new DefaultASTPrinter(); + } + + public ASTPrinter getASTPrinter() { + return astPrinter; + } + + public String displayValue(Object value) { + return value.toString(); + } + + public String displayIdentifier(FrameSlot slot) { + return slot.getIdentifier().toString(); + } + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationImpl.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,145 @@ +/* + * 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.*; + +/** + * @author mlvdv + * + */ +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 = InstrumentationNodeImpl.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 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationNodeImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationNodeImpl.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,448 @@ +/* + * 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.frame.*; +import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Abstract implementation of Truffle {@link Node} to be used for AST probes and instruments. + *

+ * Coordinates propagation of Truffle AST {@link ExecutionEvents}. + */ +public abstract class InstrumentationNodeImpl extends Node implements ExecutionEvents { + + // TODO (mlvdv) This is a pretty awkward design. + + /** + * 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); + } + + /** + * Next in chain. + */ + @Child protected InstrumentationNodeImpl next; + + protected InstrumentationNodeImpl() { + } + + /** + * @return the instance of {@link Probe} to which this instrument is attached. + */ + public Probe getProbe() { + final InstrumentationNodeImpl parent = (InstrumentationNodeImpl) getParent(); + return parent == null ? null : parent.getProbe(); + } + + /** + * Add a probe to the end of this probe chain. + */ + void internalAddInstrument(InstrumentationNodeImpl newInstrument) { + if (next == null) { + this.next = insert(newInstrument); + } else { + next.internalAddInstrument(newInstrument); + } + } + + void internalRemoveInstrument(InstrumentationNodeImpl oldInstrument) { + if (next == null) { + throw new RuntimeException("Couldn't find probe to remove: " + oldInstrument); + } else if (next == oldInstrument) { + if (oldInstrument.next == null) { + this.next = null; + } else { + this.next = insert(oldInstrument.next); + oldInstrument.next = null; + } + } else { + next.internalRemoveInstrument(oldInstrument); + } + } + + /** + * Reports to the instance of {@link Probe} holding this instrument that some essential state + * has changed that requires deoptimization. + */ + @CompilerDirectives.SlowPath + protected void notifyProbeChanged(InstrumentationNodeImpl instrument) { + final ProbeImpl probe = (ProbeImpl) getProbe(); + probe.notifyProbeChanged(instrument); + } + + private void internalEnter(Node astNode, VirtualFrame frame) { + enter(astNode, frame); + if (next != null) { + next.internalEnter(astNode, frame); + } + } + + private 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) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private 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) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private 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) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private 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) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private 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) { + leave(astNode, frame, result); + if (next != null) { + next.internalLeave(astNode, frame, result); + } + } + + private void internalLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { + leaveExceptional(astNode, frame, null); + if (next != null) { + next.internalLeaveExceptional(astNode, frame, e); + } + } + + /** + * Holder of a chain of {@linkplain InstrumentationNodeImpl instruments}: manages the + * {@link Assumption} that none of the instruments have changed since last checked. + *

+ * An instance is intended to be shared by every clone of the AST node with which it is + * originally attached, so it holds no parent pointer. + *

+ * 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 InstrumentationNodeImpl implements Probe { + + final InstrumentationImpl instrumentation; + + final InstrumentEventListener eventListener; + + @CompilerDirectives.CompilationFinal private Assumption probeUnchanged; + + /** + * 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. + */ + private final SourceSection probedSourceSection; + + private final Set tags = EnumSet.noneOf(PhylumTag.class); + + private ProbeImpl(InstrumentationImpl instrumentation, SourceSection sourceSection, InstrumentEventListener eventListener) { + this.instrumentation = instrumentation; + this.probedSourceSection = sourceSection; + this.eventListener = eventListener == null ? NullInstrumentEventListener.INSTANCE : eventListener; + this.probeUnchanged = Truffle.getRuntime().createAssumption(); + this.next = null; + } + + @Override + public Probe getProbe() { + return this; + } + + @Override + protected void notifyProbeChanged(InstrumentationNodeImpl 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) { + probeUnchanged.invalidate(); + final InstrumentationNodeImpl instrumentImpl = (InstrumentationNodeImpl) instrument; + super.internalAddInstrument(instrumentImpl); + probeUnchanged = Truffle.getRuntime().createAssumption(); + } + + @CompilerDirectives.SlowPath + public void removeInstrument(Instrument instrument) { + probeUnchanged.invalidate(); + final InstrumentationNodeImpl instrumentImpl = (InstrumentationNodeImpl) instrument; + super.internalRemoveInstrument(instrumentImpl); + probeUnchanged = Truffle.getRuntime().createAssumption(); + } + + public void notifyEnter(Node astNode, VirtualFrame frame) { + if (stepping || next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + if (stepping) { + eventListener.haltedAt(astNode, frame.materialize()); + } + if (next != null) { + next.internalEnter(astNode, frame); + } + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, boolean result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, byte result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, short result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, int result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, long result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, char result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, float result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, double result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeave(Node astNode, VirtualFrame frame, Object result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void notifyLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeaveExceptional(astNode, frame, e); + } + } + + public void enter(Node astNode, VirtualFrame frame) { + } + + public void leave(Node astNode, VirtualFrame frame) { + } + + public void leave(Node astNode, VirtualFrame frame, boolean result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, byte result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, short result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, int result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, long result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, char result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, float result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, double result) { + leave(astNode, frame, (Object) result); + } + + public void leave(Node astNode, VirtualFrame frame, Object result) { + } + + public void leaveExceptional(Node astNode, VirtualFrame frame, Exception e) { + } + + } + +} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/NullInstrumentEventListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/NullInstrumentEventListener.java Sun Apr 20 20:37:27 2014 -0700 @@ -0,0 +1,57 @@ +/* + * 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 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/DefaultNodeInstrumenter.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/DefaultNodeInstrumenter.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +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.nodes.instrument; - -import com.oracle.truffle.api.nodes.*; - -/** - * A no-op node instrumenter; always returns the node unproxied and unmodified. - */ -public class DefaultNodeInstrumenter implements NodeInstrumenter { - - public Node instrumentAs(Node node, NodePhylum phylum, Object... args) { - return node; - } - -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationNode.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013, 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.nodes.instrument; - -/** - * Marker interface for all Truffle instrumentation nodes: nodes that are do not - * appear in Truffle ASTs as part of a language's execution semantics. - *

- * In documentation related to instrumentation nodes, these are distinguished by referring to all - * other nodes (i.e. ones that do implement language semantics) as AST nodes. - */ -public interface InstrumentationNode { - -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeEvents.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeEvents.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2013, 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.nodes.instrument; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Marker interface for all Truffle instrumentation nodes: nodes that are do not - * appear in Truffle ASTs as part of a language's execution semantics. - *

- * In documentation related to instrumentation nodes, these are distinguished by referring to all - * other nodes (i.e. ones that do implement language semantics) as AST nodes. - */ -public interface InstrumentationProbeEvents { - - /** - * Notifies a probe that receiver that an AST node's execute method has just been entered. - * Callers should assure that a matching call to {@link #leave(Node, VirtualFrame, Object)} - * always follows. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame being passed to the execute method - */ - void enter(Node astNode, VirtualFrame frame); - - /** - * Notifies a probe that an AST Node's void-valued execute method is about to exit. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - */ - void leave(Node astNode, VirtualFrame frame); - - /** - * Notifies a probe that an AST Node's boolean-valued execute method is about to exit. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, boolean result); - - /** - * Notifies a probe that an AST Node's byte-valued execute method is about to exit. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, byte result); - - /** - * Notifies a probe that an AST Node's short-valued execute method is about to exit. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, short result); - - /** - * Notifies a probe that an AST Node's integer-valued execute method is about to exit. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, int result); - - /** - * Notifies a probe that an AST Node's long-valued execute method is about to exit. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, long result); - - /** - * Notifies a probe that an AST Node's float-valued execute method is about to exit. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, float result); - - /** - * Notifies a probe that an AST Node's double-valued execute method is about to exit. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, double result); - - /** - * Notifies a probe that an AST Node's char-valued execute method is about to exit. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, char result); - - /** - * Notifies a probe that an AST Node's object-valued execute method is about to exit. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param result The result of the call to the execute method. - */ - void leave(Node astNode, VirtualFrame frame, Object result); - - /** - * Notifies a probe that an AST Node's execute method is about to leave under exceptional - * conditions, returning no value. - *

- * Callers should assure (via {@code try/finally}) that a matching call to this method always - * follows a call to {@link #enter(Node, VirtualFrame)}. - * - * @param astNode The AST node on which the execute method is being called - * @param frame The frame that was passed to the execute method - * @param e the exception associated with the unusual return - */ - void leaveExceptional(Node astNode, VirtualFrame frame, Exception e); - - /** - * Notifies a probe that an AST node is about to be replaced with another. - * - * @param oldAstNode the AST node currently in the tree - * @param newAstNode the AST replacement node - * @param reason explanation for the replacement - */ - void replace(Node oldAstNode, Node newAstNode, String reason); - -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProbeNode.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,500 +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.nodes.instrument; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * A probe: a Truffle instrumentation node that holds code to perform some action - * when notified (via a {@linkplain InstrumentationProxyNode proxy node} in the AST) of a - * {@linkplain InstrumentationProbeEvents probe event} taking place at the AST node. - *

- * Probes are only active when attached to a {@linkplain ProbeChain "probe chain"} that is referred - * to by one or more {@linkplain InstrumentationProxyNode proxy nodes} in an AST. - */ -public abstract class InstrumentationProbeNode extends Node implements InstrumentationNode, InstrumentationProbeEvents { - - /** - * Next in chain. - */ - @Child protected InstrumentationProbeNode next; - - protected InstrumentationProbeNode() { - } - - protected int countProbes() { - return next == null ? 0 : next.countProbes() + 1; - } - - protected boolean isStepping() { - final InstrumentationProbeNode parent = (InstrumentationProbeNode) getParent(); - return parent.isStepping(); - } - - /** - * Add a probe to the end of this probe chain. - */ - protected void internalAppendProbe(InstrumentationProbeNode newProbeNode) { - if (next == null) { - this.next = insert(newProbeNode); - } else { - next.internalAppendProbe(newProbeNode); - } - } - - protected void internalRemoveProbe(InstrumentationProbeNode oldProbeNode) { - if (next == null) { - throw new RuntimeException("Couldn't find probe to remove: " + oldProbeNode); - } else if (next == oldProbeNode) { - if (oldProbeNode.next == null) { - this.next = null; - } else { - this.next = insert(oldProbeNode.next); - oldProbeNode.next = null; - } - } else { - next.internalRemoveProbe(oldProbeNode); - } - } - - /** - * Passes up the chain notification that a probe has changed its execution state in a way that - * invalidates fast path code. Assumes that there is an instance of {@link ProbeChain} at the - * head of the chain. - */ - @CompilerDirectives.SlowPath - protected void notifyProbeChanged(InstrumentationProbeNode probeNode) { - final InstrumentationProbeNode parent = (InstrumentationProbeNode) getParent(); - parent.notifyProbeChanged(probeNode); - } - - // TODO (mlvdv) making the internal*() methods public is a workaround for a bug/limitation in - // the Truffle compiler; they are intended to be private. - - public void internalEnter(Node astNode, VirtualFrame frame) { - enter(astNode, frame); - if (next != null) { - next.internalEnter(astNode, frame); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame) { - leave(astNode, frame); - if (next != null) { - next.internalLeave(astNode, frame); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, boolean result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, byte result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, short result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, int result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, long result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, char result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, float result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, double result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeave(Node astNode, VirtualFrame frame, Object result) { - leave(astNode, frame, result); - if (next != null) { - next.internalLeave(astNode, frame, result); - } - } - - public void internalLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { - leaveExceptional(astNode, frame, null); - if (next != null) { - next.internalLeaveExceptional(astNode, frame, e); - } - } - - public void internalReplace(Node oldAstNode, Node newAstNode, String reason) { - replace(oldAstNode, newAstNode, reason); - if (next != null) { - next.internalReplace(oldAstNode, newAstNode, reason); - } - } - - /** - * A probe implementation that implements all of {@link InstrumentationProbeEvents} with empty - * methods; concrete subclasses can override only the methods for which something is to be done. - */ - public static class DefaultProbeNode extends InstrumentationProbeNode { - - private final ExecutionContext executionContext; - - protected DefaultProbeNode(ExecutionContext context) { - this.executionContext = context; - } - - public ExecutionContext getContext() { - return executionContext; - } - - public void enter(Node astNode, VirtualFrame frame) { - } - - public void leave(Node astNode, VirtualFrame frame) { - } - - public void leave(Node astNode, VirtualFrame frame, boolean result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, byte result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, short result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, int result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, long result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, char result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, float result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, double result) { - leave(astNode, frame, (Object) result); - } - - public void leave(Node astNode, VirtualFrame frame, Object result) { - } - - public void leaveExceptional(Node astNode, VirtualFrame frame, Exception e) { - } - - public void replace(Node oldAstNode, Node newAstNode, String reason) { - } - - } - - /** - * Holder of a chain of {@linkplain InstrumentationProbeNode probes}: manages the - * {@link Assumption} that the chain has not changed since checked checked. - *

- * May be categorized by one or more {@linkplain NodePhylum node phyla}, signifying information - * useful for instrumentation about its AST location(s). - */ - public static final class ProbeChain extends DefaultProbeNode implements PhylumMarked { - - @CompilerDirectives.CompilationFinal private Assumption probeUnchanged; - - /** - * 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 node to which this probe chain is attached; it isn't - * otherwise available. A probe chain is shared by every copy made during runtime, so there - * is no parent pointer. - */ - private final SourceSection probedSourceSection; - - private final Set phyla = EnumSet.noneOf(NodePhylum.class); - - private final String description; // for debugging - - /** - * Creates a new, empty chain of {@linkplain InstrumentationProbeNode probes}, to which - * probes can be added/removed, and all of which will be notified of - * {@linkplain InstrumentationProbeEvents events} when the chain is notified. - */ - public ProbeChain(ExecutionContext context, SourceSection sourceSection, String description) { - super(context); - this.probeUnchanged = Truffle.getRuntime().createAssumption(); - this.probedSourceSection = sourceSection; - this.description = description; - this.next = null; - } - - public int probeCount() { - return countProbes(); - } - - public String getDescription() { - return description; - } - - public SourceSection getProbedSourceSection() { - return probedSourceSection; - } - - /** - * Mark this probe chain as being associated with an AST node in some category useful for - * debugging and other tools. - */ - public void markAs(NodePhylum phylum) { - assert phylum != null; - phyla.add(phylum); - } - - /** - * Is this probe chain as being associated with an AST node in some category useful for - * debugging and other tools. - */ - public boolean isMarkedAs(NodePhylum phylum) { - assert phylum != null; - return phyla.contains(phylum); - } - - /** - * In which categories is the AST (with which this probe is associated) marked? - */ - public Set getPhylumMarks() { - return phyla; - } - - /** - * Change stepping mode for statements. - */ - public void setStepping(boolean stepping) { - if (this.stepping != stepping) { - this.stepping = stepping; - probeUnchanged.invalidate(); - probeUnchanged = Truffle.getRuntime().createAssumption(); - } - } - - @Override - protected boolean isStepping() { - return stepping; - } - - @Override - protected int countProbes() { - // The head of the chain does not itself hold a probe - return next == null ? 0 : next.countProbes(); - } - - @Override - protected void notifyProbeChanged(InstrumentationProbeNode probeNode) { - probeUnchanged.invalidate(); - probeUnchanged = Truffle.getRuntime().createAssumption(); - } - - @CompilerDirectives.SlowPath - public void appendProbe(InstrumentationProbeNode newProbeNode) { - probeUnchanged.invalidate(); - super.internalAppendProbe(newProbeNode); - probeUnchanged = Truffle.getRuntime().createAssumption(); - } - - @CompilerDirectives.SlowPath - public void removeProbe(InstrumentationProbeNode oldProbeNode) { - probeUnchanged.invalidate(); - super.internalRemoveProbe(oldProbeNode); - probeUnchanged = Truffle.getRuntime().createAssumption(); - } - - public void notifyEnter(Node astNode, VirtualFrame frame) { - if (stepping || next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - if (stepping) { - getContext().getDebugContext().getDebugManager().haltedAt(astNode, frame); - } - if (next != null) { - next.internalEnter(astNode, frame); - } - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, boolean result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, byte result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, short result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, int result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, long result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, char result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, float result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, double result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeave(Node astNode, VirtualFrame frame, Object result) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeave(astNode, frame, result); - } - } - - public void notifyLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalLeaveExceptional(astNode, frame, e); - } - } - - public void notifyReplace(Node oldAstNode, Node newAstNode, String reason) { - if (next != null) { - if (!probeUnchanged.isValid()) { - CompilerDirectives.transferToInterpreter(); - } - next.internalReplace(oldAstNode, newAstNode, reason); - } - } - - } - -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProxyNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/InstrumentationProxyNode.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +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.nodes.instrument; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.instrument.InstrumentationProbeNode.ProbeChain; - -/** - * Interface implemented by language-specific Truffle proxy nodes: nodes that do - * not participate in the language's execution semantics, but which are inserted into an AST so that - * tools (e.g. tracers, analyzers, debuggers) can be notified of AST interpretation events and - * possibly intervene. - *

- * Language-specific proxy nodes call notification methods on an attached {@linkplain ProbeChain - * probe chain} which passes along {@linkplain InstrumentationProbeEvents events} to any - * {@linkplain InstrumentationProbeNode probes} that might have been attached. - */ -public interface InstrumentationProxyNode extends InstrumentationNode, PhylumMarked { - - /** - * Gets the non-instrumentation node being proxied. - */ - Node getChild(); - - /** - * Gets the chain of probes to which events at this node are delegated. Note that a chain of - * probes may be used by more than one proxy. - */ - ProbeChain getProbeChain(); - -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/NodeInstrumenter.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/NodeInstrumenter.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +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.nodes.instrument; - -import com.oracle.truffle.api.nodes.*; - -/** - * Implements the instrumentation of a Truffle AST node and returning either: - *

- */ -public interface NodeInstrumenter { - - /** - * Wraps a {@linkplain InstrumentationProxyNode proxy node} around a node (if not already - * wrapped), marks the location with a {@linkplain NodePhylum phylum (category)} for user - * interaction, and passes along any characteristics of the particular node that are important - * for instrumentation (e.g. the function/method name at a call). - */ - Node instrumentAs(Node node, NodePhylum phylum, Object... args); -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/NodePhylum.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/NodePhylum.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +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.nodes.instrument; - -/** - * Categories of {@link InstrumentationProxyNode}s to be used for defining user-visible debugging - * and other simple tool behavior. These categories (phyla) should correspond to program - * structures that are meaningful to a programmer using the guest language. A Truffle node without a - * proxy carrying some phylum should be treated as an artifact of the guest language implementation - * and should never be visible to the user of a guest language programming tool. - *

- * Note that phyla are not intended to represent a partition of user-visible node categories, as the - * relative categorization of nodes can change with the particular programming tasks at hand. - *

- * 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 phyla 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: this interface is under development and will change. - */ -public enum NodePhylum { - - /** - * Marker for a proxy at a variable assignment. - */ - ASSIGNMENT, - - /** - * Marker for a proxy at a call site. - */ - CALL, - - /** - * Marker for a proxy at which ordinary "stepping" should halt. - */ - STATEMENT; - -} diff -r 0e713dba33bb -r 0c6d8a08e31b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/PhylumMarked.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/instrument/PhylumMarked.java Thu Mar 27 16:38:39 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +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.nodes.instrument; - -import java.util.*; - -import com.oracle.truffle.api.nodes.*; - -/** - * A kind of {@link Node} that can be marked as belong to 0 or more {@linkplain NodePhylum phyla}. - */ -public interface PhylumMarked { - - /** - * Is this proxy tagged as belonging to a particular category of language constructs? - */ - boolean isMarkedAs(NodePhylum phylum); - - /** - * In which categories is this node tagged (empty set if none). - */ - Set getPhylumMarks(); - -}