Mercurial > hg > graal-jvmci-8
view graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractExecutionContext.java @ 15605:bb9473723904
Truffle/Instrumentation:
- Merge instrumentation support into the general execution context; remove separate Instrumentation interface and implementation
- Generalize the ?tagging? mechanism for extensibility: the enum PhylumTag is now an interface, and the standard tags moved to the new enum StandardTag
- A new ?trap? mechanism interrupts program execution at any probed node holding a specified PhylumTag; this replaces some other special-purpose code.
- Refine several interface by factoring out callback methods and simplifying collaboration among key implementation classes.
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Mon, 12 May 2014 20:17:25 -0700 |
parents | be0c151d912b |
children |
line wrap: on
line source
/* * 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); }