Mercurial > hg > graal-compiler
changeset 15780:bdf260d8e163
Merge with 9ae1d2f3bda60f9d91243c883c5aa7812e2ab256
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Mon, 19 May 2014 17:21:30 -0700 |
parents | 8c34e2cc4add (diff) 9ae1d2f3bda6 (current diff) |
children | 8b9e7f235d85 6a6cb7f2db90 |
files | graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/ComputeInliningRelevance.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/DepthSearchUtil.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningIterator.java |
diffstat | 9 files changed, 390 insertions(+), 475 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java Mon May 19 14:14:12 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java Mon May 19 17:21:30 2014 -0700 @@ -27,31 +27,131 @@ import java.util.*; import com.oracle.truffle.api.instrument.*; +import com.oracle.truffle.api.instrument.impl.*; import com.oracle.truffle.api.source.*; /** * Access to information and basic services in the runtime context for a Truffle-implemented guest * language. * <p> - * <strong>Disclaimer:</strong> this interface is under development and will change. + * <strong>Disclaimer:</strong> this class is under development and will change. */ -public interface ExecutionContext { +public abstract class ExecutionContext { + + private final ProbeManager probeManager = new ProbeManager(); + private final SourceManager sourceManager = new SourceManager(); + private final List<SourceListener> sourceListeners = new ArrayList<>(); + private Visualizer visualizer = new DefaultVisualizer(); + + protected ExecutionContext() { + } + + public void initialize() { + setSourceCallback(new SourceCallback() { + + public void startLoading(Source source) { + for (SourceListener listener : sourceListeners) { + listener.loadStarting(source); + } + } + + public void endLoading(Source source) { + for (SourceListener listener : sourceListeners) { + listener.loadEnding(source); + } + } + }); + } + + /** + * Gets access to source management services. + */ + public final SourceManager getSourceManager() { + return sourceManager; + } + + /** + * Registers a tool interested in being notified about the loading of {@link Source}s. + */ + public final void addSourceListener(SourceListener listener) { + assert listener != null; + sourceListeners.add(listener); + } + + /** + * Registers a tool interested in being notified about the insertion of a newly created + * {@link Probe} into a Truffle AST. + */ + public final void addProbeListener(ProbeListener listener) { + probeManager.addProbeListener(listener); + } + + /** + * Return the (possibly newly created) {@link Probe} uniquely associated with a particular + * source code location. A newly created probe carries no tags. + * + * @return a probe uniquely associated with an extent of guest language source code. + */ + public final Probe getProbe(SourceSection sourceSection) { + return probeManager.getProbe(sourceSection); + } + + /** + * Returns all existing probes with specific tag, or all probes if {@code tag = null}; empty + * collection if no probes found. + */ + public final Collection<Probe> findProbesTaggedAs(PhylumTag tag) { + return probeManager.findProbesTaggedAs(tag); + } + + /** + * Returns all existing probes with first character on a specified line; empty collection if no + * probes found. + */ + public final Collection<Probe> findProbesByLine(SourceLineLocation lineLocation) { + return probeManager.findProbesByLine(lineLocation); + } + + /** + * Sets a trap that will make a callback at any AST location where a existing probe holds a + * specified tag; only one trap may be set at a time. + * + * @throws IllegalStateException if a trap is already set + */ + public final void setPhylumTrap(PhylumTrap trap) throws IllegalStateException { + // TODO (mlvdv) consider allowing multiple traps (without inhibiting Truffle inlining) + probeManager.setPhylumTrap(trap); + } + + /** + * Clears a trap that will halt execution; only one trap may be set at a time. + * + * @throws IllegalStateException if no trap is set. + */ + public final void clearPhylumTrap() { + probeManager.clearPhylumTrap(); + } + + /** + * Access to information visualization services for the specific language. + */ + public final Visualizer getVisualizer() { + return visualizer; + } + + /** + * Assign guest language-specific visualization support for tools. This must be assigned outside + * the implementation context to avoid build circularities. + */ + public final void setVisualizer(Visualizer visualizer) { + this.visualizer = visualizer; + } /** * Gets the name of the language, possibly with version number. in short enough form that it * might be used for an interactive prompt. */ - String getLanguageShortName(); - - /** - * Gets access to source management services. - */ - SourceManager getSourceManager(); - - /** - * Registers a tool interested in being notified of events related to the loading of sources. - */ - void addSourceListener(SourceListener listener); + public abstract String getLanguageShortName(); /** * Add instrumentation to subsequently constructed Truffle ASTs for the guest language; every @@ -60,51 +160,19 @@ * @throws IllegalStateException if AST instrumentation not enabled * @throws IllegalArgumentException if prober not usable for the guest language implementation. */ - void addNodeProber(ASTNodeProber nodeProber) throws IllegalStateException, IllegalArgumentException; - - /** - * Registers a tool interested in being notified about the insertion of a newly created - * {@link Probe} into a Truffle AST. - */ - void addProbeListener(ProbeListener listener); - - /** - * Return the (possibly newly created) {@link Probe} uniquely associated with a particular - * source code location. A newly created probe carries no tags. - * - * @return a probe uniquely associated with an extent of guest language source code. - */ - Probe getProbe(SourceSection sourceSection); - - /** - * Returns all existing probes with specific tag, or all probes if {@code tag = null}; empty - * collection if no probes found. - */ - Collection<Probe> findProbesTaggedAs(PhylumTag tag); + public abstract void addNodeProber(ASTNodeProber nodeProber) throws IllegalStateException, IllegalArgumentException; /** - * Returns all existing probes with first character on a specified line; empty collection if no - * probes found. + * 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. */ - Collection<Probe> findProbesByLine(SourceLineLocation lineLocation); + public abstract void setASTProber(ASTProber astProber); /** - * Sets a trap that will make a callback at any AST location where a existing probe holds a - * specified tag; only one trap may be set at a time. - * - * @throws IllegalStateException if a trap is already set + * Establishes source event reporting */ - void setTrap(PhylumTrap trap) throws IllegalStateException; + protected abstract void setSourceCallback(SourceCallback sourceCallback); - /** - * Clears a trap that will halt execution; only one trap may be set at a time. - * - * @throws IllegalStateException if no trap is set. - */ - void clearTrap() throws IllegalStateException; - - /** - * Access to information visualization services for the specific language. - */ - Visualizer getVisualizer(); }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractExecutionContext.java Mon May 19 14:14:12 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,217 +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.impl; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.instrument.*; -import com.oracle.truffle.api.instrument.impl.*; -import com.oracle.truffle.api.instrument.impl.InstrumentationNode.ProbeCallback; -import com.oracle.truffle.api.instrument.impl.InstrumentationNode.ProbeImpl; -import com.oracle.truffle.api.source.*; - -public abstract class AbstractExecutionContext implements ExecutionContext { - - // TODO (mlvdv) use weak references. - /** - * Map: SourceSection ==> probe associated with that source section in an AST. - */ - private final Map<SourceSection, ProbeImpl> srcToProbe = new HashMap<>(); - - // TODO (mlvdv) use weak references. - /** - * Map: Source line ==> probes associated with source sections starting on the line. - */ - private final Map<SourceLineLocation, Collection<Probe>> lineToProbes = new HashMap<>(); - - private final SourceManager sourceManager = new SourceManager(); - private final List<SourceListener> sourceListeners = new ArrayList<>(); - private final List<ProbeListener> probeListeners = new ArrayList<>(); - - private final SourceCallback sourceCallback = new SourceCallback() { - - public void startLoading(Source source) { - for (SourceListener listener : sourceListeners) { - listener.loadStarting(source); - } - } - - public void endLoading(Source source) { - for (SourceListener listener : sourceListeners) { - listener.loadEnding(source); - } - } - }; - - private final ProbeCallback probeCallback = new ProbeCallback() { - /** - * Receives (from the {@link Probe} implementation) and distributes notification that a - * {@link Probe} has acquired a new {@linkplain PhylumTag tag}. - */ - public void newTagAdded(ProbeImpl probe, PhylumTag tag) { - for (ProbeListener listener : probeListeners) { - listener.probeTaggedAs(probe, tag); - } - if (trap != null && tag == trap.getTag()) { - probe.setTrap(trap); - } - } - }; - - private Visualizer visualizer = new DefaultVisualizer(); - - /** - * When non-null, "enter" events with matching tags will trigger a callback. - */ - private PhylumTrap trap = null; - - protected AbstractExecutionContext() { - } - - public void initialize() { - setSourceCallback(sourceCallback); - } - - public final SourceManager getSourceManager() { - return sourceManager; - } - - public void addSourceListener(SourceListener listener) { - assert listener != null; - sourceListeners.add(listener); - } - - public void addProbeListener(ProbeListener listener) { - assert listener != null; - probeListeners.add(listener); - } - - public Probe getProbe(SourceSection sourceSection) { - assert sourceSection != null; - - ProbeImpl probe = srcToProbe.get(sourceSection); - - if (probe != null) { - return probe; - } - probe = InstrumentationNode.createProbe(sourceSection, probeCallback); - - // Register new probe by unique SourceSection - srcToProbe.put(sourceSection, probe); - - // Register new probe by source line, there may be more than one - // Create line location for map key - final SourceLineLocation lineLocation = new SourceLineLocation(sourceSection.getSource(), sourceSection.getStartLine()); - - Collection<Probe> 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<Probe> findProbesTaggedAs(PhylumTag tag) { - final List<Probe> probes = new ArrayList<>(); - for (Probe probe : srcToProbe.values()) { - if (tag == null || probe.isTaggedAs(tag)) { - probes.add(probe); - } - } - return probes; - } - - public Collection<Probe> findProbesByLine(SourceLineLocation lineLocation) { - final Collection<Probe> probes = lineToProbes.get(lineLocation); - if (probes == null) { - return Collections.emptyList(); - } - return new ArrayList<>(probes); - } - - // TODO (mlvdv) consider allowing multiple traps (without inhibiting Truffle inlining) - public void setTrap(PhylumTrap trap) { - assert trap != null; - if (this.trap != null) { - throw new IllegalStateException("trap already set"); - } - this.trap = trap; - - for (ProbeImpl probe : srcToProbe.values()) { - if (probe.isTaggedAs(trap.getTag())) { - probe.setTrap(trap); - } - } - } - - public void clearTrap() { - if (this.trap == null) { - throw new IllegalStateException("no trap set"); - } - for (ProbeImpl probe : srcToProbe.values()) { - if (probe.isTaggedAs(trap.getTag())) { - probe.setTrap(null); - } - } - trap = null; - } - - public Visualizer getVisualizer() { - return visualizer; - } - - /** - * 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 abstract void setASTProber(ASTProber astProber); - - /** - * Establishes source event reporting - */ - protected abstract void setSourceCallback(SourceCallback sourceCallback); - -}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Mon May 19 14:14:12 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java Mon May 19 17:21:30 2014 -0700 @@ -31,29 +31,29 @@ import com.oracle.truffle.api.nodes.*; /** - * A receiver of Truffle AST {@link ExecutionEvents}, propagated from a {@link Probe} to which the - * instrument is attached, for the benefit of associated <em>tools</em>. + * A receiver of Truffle AST runtime {@link ExecutionEvents}, propagated from the {@link Probe} to + * which the instrument is attached, for the benefit of associated <em>tools</em>. * <p> - * Guidelines for implementing Instruments, with particular attention to avoiding undesired runtime + * Guidelines for implementing {@link Instrument}s, with particular attention to minimize runtime * performance overhead: * <ol> - * <li>Extend {@link Instrument} and override only the event handling methods for which some action - * is needed.</li> + * <li>Extend this abstract class and override only the {@linkplain ExecutionEvents event handling + * methods} for which intervention is needed.</li> * <li>Instruments are Truffle {@link Node}s and should be coded as much as possible in the desired * <em>Truffle style</em>, documented more thoroughly elsewhere.</li> * <li>Maintain as little state as possible.</li> - * <li>If state is necessary, make it {@code final} if possible.</li> - * <li>If non-final state is necessary, annotate it as {@link CompilationFinal} and call - * {@linkplain InstrumentationNode#notifyProbeChanged(Instrument)} whenever it is modified.</li> + * <li>If state is necessary, make object fields {@code final} if at all possible.</li> + * <li>If non-final object-valued state is necessary, annotate it as {@link CompilationFinal} and + * call {@linkplain InstrumentationNode#notifyProbeChanged(Instrument)} whenever it is modified.</li> * <li>Never store a {@link Frame} value in a field.</li> * <li>Minimize computation in standard execution paths.</li> - * <li>Callbacks to tools should be made via callbacks provided at construction and stored in - * {@code final} fields.</li> - * <li>Tool callback methods should usually be annotated as {@link SlowPath} to prevent them from - * being inlined into fast execution paths.</li> - * <li>If computation is needed, and if performance is important, then the computation is best - * expressed as a guest language AST and evaluated using standard Truffle mechanisms so that - * standard Truffle optimizations can be applied.</li> + * <li>If runtime calls must be made back to a tool, construct the instrument with a callback stored + * in a {@code final} field.</li> + * <li>Tool methods called by the instrument should be annotated as {@link SlowPath} to prevent them + * from being inlined into fast execution paths.</li> + * <li>If computation in the execution path is needed, and if performance is important, then the + * computation is best expressed as a guest language AST and evaluated using standard Truffle + * mechanisms so that standard Truffle optimizations can be applied.</li> * </ol> * <p> * Guidelines for attachment to a {@link Probe}: @@ -65,6 +65,18 @@ * every copy, and so the Instrument will receive events corresponding to the intended syntactic * unit of code, independent of which AST copy is being executed.</li> * </ol> + * <p> + * Guidelines for handling {@link ExecutionEvents}: + * <ol> + * <li>Separate event methods are defined for each kind of possible return: object-valued, + * primitive-valued, void-valued, and exceptional.</li> + * <li>Override "leave*" primitive methods if the language implementation returns primitives and the + * instrument should avoid boxing them.</li> + * <li>On the other hand, if boxing all primitives for instrumentation is desired, it is only + * necessary to override the object-valued return methods, since the default implementation of each + * primitive-valued return method is to box the value and forward it to the object-valued return + * method.</li> + * </ol> * * <p> * <strong>Disclaimer:</strong> experimental; under development. @@ -72,7 +84,7 @@ * @see Probe * @see ASTNodeProber */ -public class Instrument extends InstrumentationNode { +public abstract class Instrument extends InstrumentationNode { protected Instrument() { }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Mon May 19 14:14:12 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Probe.java Mon May 19 17:21:30 2014 -0700 @@ -25,8 +25,6 @@ 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 @@ -54,7 +52,7 @@ * @see Instrument * @see Wrapper */ -public interface Probe extends PhylumTagged { +public interface Probe extends ExecutionEvents, PhylumTagged { /** * The source location with which this probe is (presumably uniquely) associated. @@ -77,66 +75,4 @@ */ void removeInstrument(Instrument oldInstrument); - // TODO (mlvdv) migrate the remaining methods to another interface. - - /** - * @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); - }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/SourceCallback.java Mon May 19 17:21:30 2014 -0700 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.instrument; + +import com.oracle.truffle.api.*; + +/** + * Instrumentation callback for guest language source-related events. + */ +public interface SourceCallback { + + public void startLoading(Source source); + + public void endLoading(Source source); +}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java Mon May 19 14:14:12 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java Mon May 19 17:21:30 2014 -0700 @@ -77,13 +77,14 @@ } if (node instanceof PhylumTagged) { final PhylumTagged taggedNode = (PhylumTagged) node; + p.print("["); String prefix = ""; for (PhylumTag tag : taggedNode.getPhylumTags()) { p.print(prefix); prefix = ","; p.print(tag.toString()); } - + p.print("]"); } ArrayList<NodeField> childFields = new ArrayList<>();
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationNode.java Mon May 19 14:14:12 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/InstrumentationNode.java Mon May 19 17:21:30 2014 -0700 @@ -39,7 +39,7 @@ */ public abstract class InstrumentationNode extends Node implements ExecutionEvents { - public interface ProbeCallback { + interface ProbeCallback { void newTagAdded(ProbeImpl probe, PhylumTag tag); } @@ -49,7 +49,7 @@ * * @return a new probe */ - public static ProbeImpl createProbe(SourceSection sourceSection, ProbeCallback probeCallback) { + static ProbeImpl createProbe(SourceSection sourceSection, ProbeCallback probeCallback) { return new ProbeImpl(sourceSection, probeCallback); } @@ -64,7 +64,7 @@ /** * @return the instance of {@link Probe} to which this instrument is attached. */ - public Probe getProbe() { + protected Probe getProbe() { final InstrumentationNode parent = (InstrumentationNode) getParent(); return parent == null ? null : parent.getProbe(); } @@ -199,7 +199,7 @@ * May be categorized by one or more {@linkplain PhylumTag tags}, signifying information useful * for instrumentation about its AST location(s). */ - public static final class ProbeImpl extends InstrumentationNode implements Probe { + static final class ProbeImpl extends InstrumentationNode implements Probe { private final ProbeCallback probeCallback; @@ -259,7 +259,7 @@ } @Override - public Probe getProbe() { + protected Probe getProbe() { return this; } @@ -271,14 +271,14 @@ } @SlowPath - public void setTrap(PhylumTrap trap) { + void setTrap(PhylumTrap trap) { assert trap == null || isTaggedAs(trap.getTag()); probeUnchanged.invalidate(); this.trap = trap; probeUnchanged = Truffle.getRuntime().createAssumption(); } - public void notifyEnter(Node astNode, VirtualFrame frame) { + public void enter(Node astNode, VirtualFrame frame) { if (trap != null || next != null) { if (!probeUnchanged.isValid()) { CompilerDirectives.transferToInterpreter(); @@ -292,7 +292,7 @@ } } - public void notifyLeave(Node astNode, VirtualFrame frame) { + public void leave(Node astNode, VirtualFrame frame) { if (next != null) { if (!probeUnchanged.isValid()) { CompilerDirectives.transferToInterpreter(); @@ -301,16 +301,7 @@ } } - 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) { + public void leave(Node astNode, VirtualFrame frame, boolean result) { if (next != null) { if (!probeUnchanged.isValid()) { CompilerDirectives.transferToInterpreter(); @@ -319,16 +310,7 @@ } } - 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) { + public void leave(Node astNode, VirtualFrame frame, byte result) { if (next != null) { if (!probeUnchanged.isValid()) { CompilerDirectives.transferToInterpreter(); @@ -337,7 +319,7 @@ } } - public void notifyLeave(Node astNode, VirtualFrame frame, long result) { + public void leave(Node astNode, VirtualFrame frame, short result) { if (next != null) { if (!probeUnchanged.isValid()) { CompilerDirectives.transferToInterpreter(); @@ -346,16 +328,7 @@ } } - 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) { + public void leave(Node astNode, VirtualFrame frame, int result) { if (next != null) { if (!probeUnchanged.isValid()) { CompilerDirectives.transferToInterpreter(); @@ -364,7 +337,16 @@ } } - public void notifyLeave(Node astNode, VirtualFrame frame, double result) { + public void leave(Node astNode, VirtualFrame frame, long result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void leave(Node astNode, VirtualFrame frame, char result) { if (next != null) { if (!probeUnchanged.isValid()) { CompilerDirectives.transferToInterpreter(); @@ -373,7 +355,7 @@ } } - public void notifyLeave(Node astNode, VirtualFrame frame, Object result) { + public void leave(Node astNode, VirtualFrame frame, float result) { if (next != null) { if (!probeUnchanged.isValid()) { CompilerDirectives.transferToInterpreter(); @@ -382,7 +364,25 @@ } } - public void notifyLeaveExceptional(Node astNode, VirtualFrame frame, Exception e) { + public void leave(Node astNode, VirtualFrame frame, double result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void leave(Node astNode, VirtualFrame frame, Object result) { + if (next != null) { + if (!probeUnchanged.isValid()) { + CompilerDirectives.transferToInterpreter(); + } + next.internalLeave(astNode, frame, result); + } + } + + public void leaveExceptional(Node astNode, VirtualFrame frame, Exception e) { if (next != null) { if (!probeUnchanged.isValid()) { CompilerDirectives.transferToInterpreter(); @@ -391,50 +391,6 @@ } } - 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) { - } - } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/ProbeManager.java Mon May 19 17:21:30 2014 -0700 @@ -0,0 +1,159 @@ +/* + * 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.instrument.impl.InstrumentationNode.ProbeCallback; +import com.oracle.truffle.api.instrument.impl.InstrumentationNode.ProbeImpl; +import com.oracle.truffle.api.source.*; + +/** + * Factory and services for AST {@link Probe}s + */ +public final class ProbeManager { + + // TODO (mlvdv) use weak references. + /** + * Map: SourceSection ==> probe associated with that source section in an AST. + */ + private final Map<SourceSection, ProbeImpl> srcToProbe = new HashMap<>(); + + // TODO (mlvdv) use weak references. + /** + * Map: Source line ==> probes associated with source sections starting on the line. + */ + private final Map<SourceLineLocation, Collection<Probe>> lineToProbes = new HashMap<>(); + + private final List<ProbeListener> probeListeners = new ArrayList<>(); + + private final ProbeCallback probeCallback; + + /** + * When non-null, "enter" events with matching tags will trigger a callback. + */ + private PhylumTrap phylumTrap = null; + + public ProbeManager() { + this.probeCallback = new ProbeCallback() { + /** + * Receives (from the {@link Probe} implementation) and distributes notification that a + * {@link Probe} has acquired a new {@linkplain PhylumTag tag}. + */ + public void newTagAdded(ProbeImpl probe, PhylumTag tag) { + for (ProbeListener listener : probeListeners) { + listener.probeTaggedAs(probe, tag); + } + if (phylumTrap != null && tag == phylumTrap.getTag()) { + probe.setTrap(phylumTrap); + } + } + }; + } + + public void addProbeListener(ProbeListener listener) { + assert listener != null; + probeListeners.add(listener); + } + + public Probe getProbe(SourceSection sourceSection) { + assert sourceSection != null; + + ProbeImpl probe = srcToProbe.get(sourceSection); + + if (probe != null) { + return probe; + } + probe = InstrumentationNode.createProbe(sourceSection, probeCallback); + + // Register new probe by unique SourceSection + srcToProbe.put(sourceSection, probe); + + // Register new probe by source line, there may be more than one + // Create line location for map key + final SourceLineLocation lineLocation = new SourceLineLocation(sourceSection.getSource(), sourceSection.getStartLine()); + + Collection<Probe> 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; + } + + public Collection<Probe> findProbesTaggedAs(PhylumTag tag) { + final List<Probe> probes = new ArrayList<>(); + for (Probe probe : srcToProbe.values()) { + if (tag == null || probe.isTaggedAs(tag)) { + probes.add(probe); + } + } + return probes; + } + + public Collection<Probe> findProbesByLine(SourceLineLocation lineLocation) { + final Collection<Probe> probes = lineToProbes.get(lineLocation); + if (probes == null) { + return Collections.emptyList(); + } + return new ArrayList<>(probes); + } + + public void setPhylumTrap(PhylumTrap trap) { + assert trap != null; + if (this.phylumTrap != null) { + throw new IllegalStateException("trap already set"); + } + this.phylumTrap = trap; + + PhylumTag tag = trap.getTag(); + for (ProbeImpl probe : srcToProbe.values()) { + if (probe.isTaggedAs(tag)) { + probe.setTrap(trap); + } + } + } + + public void clearPhylumTrap() { + if (this.phylumTrap == null) { + throw new IllegalStateException("no trap set"); + } + for (ProbeImpl probe : srcToProbe.values()) { + if (probe.isTaggedAs(phylumTrap.getTag())) { + probe.setTrap(null); + } + } + phylumTrap = null; + } + +}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/SourceCallback.java Mon May 19 14:14:12 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.instrument.impl; - -import com.oracle.truffle.api.*; - -/** - * Instrumentation callback for guest language source-related events. - */ -public interface SourceCallback { - - public void startLoading(Source source); - - public void endLoading(Source source); -}