All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.oracle.truffle.api.instrumentation.Instrumenter Maven / Gradle / Ivy

Go to download

Truffle is a multi-language framework for executing dynamic languages that achieves high performance when combined with Graal.

There is a newer version: 1.0.0-rc7
Show newest version
/*
 * Copyright (c) 2016, 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.instrumentation;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;

/**
 * Provides capabilities to attach listeners for execution, load, output and allocation events. The
 * instrumenter remains usable as long as the engine is not closed. The instrumenter methods are
 * safe to be used from arbitrary other threads.
 *
 * @since 0.12
 */
public abstract class Instrumenter {

    Instrumenter() {
    }

    /**
     * @since 0.12
     * @deprecated in 0.32 use
     *             {@link #attachExecutionEventFactory(SourceSectionFilter, ExecutionEventNodeFactory)
     *             instead (rename only)
     */
    @Deprecated
    public final  EventBinding attachFactory(SourceSectionFilter eventFilter, T factory) {
        return attachExecutionEventFactory(eventFilter, null, factory);
    }

    /**
     * @since 0.12
     * @deprecated in 0.32 use
     *             {@link #attachExecutionEventFactory(SourceSectionFilter, ExecutionEventNodeFactory)}
     *             instead (rename only)
     */
    @Deprecated
    public final  EventBinding attachListener(SourceSectionFilter eventFilter, T listener) {
        return attachExecutionEventListener(eventFilter, null, listener);
    }

    /**
     * Starts execution event notification for a given {@link SourceSectionFilter event filter} and
     * {@link ExecutionEventListener listener}. The execution events are delivered to the
     * {@link ExecutionEventListener}.
     * 

* Returns a {@link EventBinding binding} which allows to dispose the attached execution event * binding. Disposing the binding removes all probes and wrappers from the AST that were created * for this instrument. The removal of probes and wrappers is performed lazily on the next * execution of the AST. *

* By default no * {@link ExecutionEventNode#onInputValue(com.oracle.truffle.api.frame.VirtualFrame, EventContext, int, Object) * input value events} are delivered to the listener. To deliver inputs events use * {@link #attachExecutionEventListener(SourceSectionFilter, SourceSectionFilter, ExecutionEventListener)} * instead. * * @param eventFilter filters the events that are reported to the given * {@link ExecutionEventListener listener} * @param listener that listens to execution events. * @see ExecutionEventListener * @since 0.33 */ public final EventBinding attachExecutionEventListener(SourceSectionFilter eventFilter, T listener) { return attachExecutionEventListener(eventFilter, null, listener); } /** * Starts execution event notification for a given {@link SourceSectionFilter event filter} and * {@link ExecutionEventNodeFactory factory}. Events are delivered to the * {@link ExecutionEventNode} instances created by the factory. *

* Returns a {@link EventBinding binding} which allows to dispose the attached execution event * binding. Disposing the binding removes all probes and wrappers from the AST that were created * for this instrument. The removal of probes and wrappers is performed lazily on the next * execution of the AST. *

* By default no * {@link ExecutionEventNode#onInputValue(com.oracle.truffle.api.frame.VirtualFrame, EventContext, int, Object) * input value events} are delivered to the created execution event nodes. To deliver inputs * events use * {@link #attachExecutionEventFactory(SourceSectionFilter, SourceSectionFilter, ExecutionEventNodeFactory)} * instead. * * @param eventFilter filters the events that are reported to the {@link ExecutionEventNode * execution event nodes} created by the factory. * @param factory the factory that creates {@link ExecutionEventNode execution event nodes}. * @see ExecutionEventNodeFactory * @see #attachExecutionEventFactory(SourceSectionFilter, SourceSectionFilter, * ExecutionEventNodeFactory) * @since 0.33 */ public final EventBinding attachExecutionEventFactory(SourceSectionFilter eventFilter, T factory) { return attachExecutionEventFactory(eventFilter, null, factory); } /** * Starts execution event notification for a given {@link SourceSectionFilter event filter} and * {@link ExecutionEventListener listener}. The execution events are delivered to the * {@link ExecutionEventListener}. *

* Returns a {@link EventBinding binding} which allows to dispose the attached execution event * binding. Disposing the binding removes all probes and wrappers from the AST that were created * for this instrument. The removal of probes and wrappers is performed lazily on the next * execution of the AST. *

* The input filter argument filters which * {@link ExecutionEventListener#onInputValue(EventContext, com.oracle.truffle.api.frame.VirtualFrame, EventContext, int, Object) * input events} are delivered to the created execution event nodes. * * @param eventFilter filters the events that are reported to the given * {@link ExecutionEventListener listener} * @param inputFilter filters input events, null for no input values * @param listener that listens to execution events. * @see ExecutionEventListener * @see ExecutionEventListener#onInputValue(EventContext, * com.oracle.truffle.api.frame.VirtualFrame, EventContext, int, Object) * @since 0.33 */ public abstract EventBinding attachExecutionEventListener(SourceSectionFilter eventFilter, SourceSectionFilter inputFilter, T listener); /** * Starts execution event notification for a given {@link SourceSectionFilter event filter} and * {@link ExecutionEventNodeFactory factory}. Events are delivered to the * {@link ExecutionEventNode} instances created by the factory. *

* Returns a {@link EventBinding binding} which allows to dispose the attached execution event * binding. Disposing the binding removes all probes and wrappers from the AST that were created * for this instrument. The removal of probes and wrappers is performed lazily on the next * execution of the AST. *

* The input filter argument filters which * {@link ExecutionEventNode#onInputValue(com.oracle.truffle.api.frame.VirtualFrame, EventContext, int, Object) * input events} are delivered to the created execution event nodes. * * @param eventFilter filters the events that are reported to the {@link ExecutionEventNode * execution event nodes} created by the factory. * @param inputFilter filters input events, null for no input values * @param factory the factory that creates {@link ExecutionEventNode execution event nodes}. * @see ExecutionEventNodeFactory * @see ExecutionEventNode#onInputValue(com.oracle.truffle.api.frame.VirtualFrame, EventContext, * int, Object) * @since 0.33 */ public abstract EventBinding attachExecutionEventFactory(SourceSectionFilter eventFilter, SourceSectionFilter inputFilter, T factory); /** * Starts notifications for each newly loaded {@link Source} and returns a * {@linkplain EventBinding binding} that can be used to terminate notifications. Only * subsequent loads will be notified unless {@code includeExistingSources} is true, in which * case a notification for each previous load will be delivered before this method returns. *

* Note: the provided {@link SourceSectionFilter} must only contain filters on * {@link SourceSectionFilter.Builder#sourceIs(Source...) sources} or * {@link SourceSectionFilter.Builder#mimeTypeIs(String...) mime types}. * * @param filter a filter on which sources trigger events. Only source filters are allowed. * @param listener a listener that gets notified if a source was loaded * @param includeExistingSources whether or not this listener should be notified for sources * which were already loaded at the time when this listener was attached. * @return a handle for stopping the notification stream * * @see LoadSourceListener#onLoad(LoadSourceEvent) * * @since 0.15 * @deprecated Use {@link #attachLoadSourceListener(SourceFilter, LoadSourceListener, boolean)} */ @Deprecated public abstract EventBinding attachLoadSourceListener(SourceSectionFilter filter, T listener, boolean includeExistingSources); /** * Starts notifications for each newly loaded {@link Source} and returns a * {@linkplain EventBinding binding} that can be used to terminate notifications. Only * subsequent loads will be notified unless {@code includeExistingSources} is true, in which * case a notification for each previous load will be delivered before this method returns. * * @param filter a filter on which sources events are triggered. * @param listener a listener that gets notified if a source was loaded * @param includeExistingSources whether or not this listener should be notified for sources * which were already loaded at the time when this listener was attached. * @return a handle for stopping the notification stream * * @see LoadSourceListener#onLoad(LoadSourceEvent) * * @since 0.33 */ public abstract EventBinding attachLoadSourceListener(SourceFilter filter, T listener, boolean includeExistingSources); /** * Starts notifications for each newly executed {@link Source} and returns a * {@linkplain EventBinding binding} that can be used to terminate notifications. Only * subsequent executions will be notified unless {@code includeExecutedSources} is true, in * which case a notification for each previously executed source will be delivered before this * method returns. A source is reported as executed if any of it's {@link RootNode}s start to be * executed. * * @param filter a filter on which source events are triggered. * @param listener a listener that gets notified if a source was loaded * @param includeExecutedSources whether or not this listener should be notified for sources * which were already executed at the time when this listener was attached. * @return a handle for stopping the notification stream * * @see ExecuteSourceListener#onExecute(ExecuteSourceEvent) * * @since 0.33 */ public abstract EventBinding attachExecuteSourceListener(SourceFilter filter, T listener, boolean includeExecutedSources); /** * Starts notifications for each {@link SourceSection} in every newly loaded {@link Source} and * returns a {@linkplain EventBinding binding} that can be used to terminate notifications. Only * subsequent loads will be notified unless {@code includeExistingSourceSections} is true, in * which case a notification for each previous load will be delivered before this method * returns. * * @param filter a filter on which sources sections trigger events * @param listener a listener that gets notified if a source section was loaded * @param includeExistingSourceSections whether or not this listener should be notified for * sources which were already loaded at the time when this listener was attached. * @return a handle for stopping the notification stream * * @see LoadSourceSectionListener#onLoad(LoadSourceSectionEvent) * * @since 0.15 */ public abstract EventBinding attachLoadSourceSectionListener(SourceSectionFilter filter, T listener, boolean includeExistingSourceSections); /** * Notifies the listener for each {@link SourceSection} in every loaded {@link Source} that * corresponds to the filter. Only loaded sections are notified, synchronously. * * @param filter a filter on which source sections trigger events * @param listener a listener that gets notified with loaded source sections * * @see LoadSourceSectionListener#onLoad(LoadSourceSectionEvent) * * @since 1.0 */ public abstract void visitLoadedSourceSections(SourceSectionFilter filter, LoadSourceSectionListener listener); /** * Attach an output stream as a consumer of the {@link TruffleInstrument.Env#out() standard * output}. The consumer output stream receives all output that goes to * {@link TruffleInstrument.Env#out()} since this call, including output emitted by the * {@link org.graalvm.polyglot.Engine} this instrumenter is being executed in, output from * instruments (including this one), etc. Be sure to {@link EventBinding#dispose() dispose} the * binding when it's not used any more. * * @since 0.25 */ public abstract EventBinding attachOutConsumer(T stream); /** * Attach an output stream as a consumer of the {@link TruffleInstrument.Env#err() error output} * . The consumer output stream receives all error output that goes to * {@link TruffleInstrument.Env#err()} since this call, including error output emitted by the * {@link org.graalvm.polyglot.Engine} this instrumenter is being executed in, error output from * instruments (including this one), etc. Be sure to {@link EventBinding#dispose() dispose} the * binding when it's not used any more. * * @since 0.25 */ public abstract EventBinding attachErrConsumer(T stream); /** * Attach a {@link AllocationListener listener} to be notified about allocations of guest * language values. Be sure to {@link EventBinding#dispose() dispose} the binding when it's not * used any more. * * @since 0.27 */ public abstract EventBinding attachAllocationListener(AllocationEventFilter filter, T listener); /** * Attach a {@link ContextsListener listener} to be notified about changes in contexts in guest * language application. This is supported in {@link TruffleInstrument.Env#getInstrumenter()} * only. * * @param listener a listener to receive the context events * @param includeActiveContexts whether or not this listener should be notified for present * active contexts * @return a handle for unregistering the listener * @since 0.30 */ public abstract EventBinding attachContextsListener(T listener, boolean includeActiveContexts); /** * Attach a {@link ThreadsListener listener} to be notified about changes in threads in guest * language application. This is supported in {@link TruffleInstrument.Env#getInstrumenter()} * only. * * @param listener a listener to receive the context events * @param includeInitializedThreads whether or not this listener should be notified for present * initialized threads * @return a handle for unregistering the listener * @since 0.30 */ public abstract EventBinding attachThreadsListener(T listener, boolean includeInitializedThreads); /** * Returns a filtered list of loaded {@link SourceSection} instances. * * @param filter criterion for inclusion * @return unmodifiable list of instances that pass the filter * * @since 0.18 */ public final List querySourceSections(SourceSectionFilter filter) { final List sourceSectionList = new ArrayList<>(); visitLoadedSourceSections(filter, new LoadSourceSectionListener() { @Override public void onLoad(LoadSourceSectionEvent event) { sourceSectionList.add(event.getSourceSection()); } }); return Collections.unmodifiableList(sourceSectionList); } /** * Returns an unmodifiable {@link Set} of tag classes which where associated with this node. If * the instrumenter is used as a {@link TruffleLanguage} then only nodes can be queried for tags * that are associated with the current language otherwise an {@link IllegalArgumentException} * is thrown. The given node must not be null. If the given node is not * instrumentable, the given node is not yet adopted by a {@link RootNode} or the given tag was * not {@link ProvidedTags provided} by the language then always an empty {@link Set} is * returned. * * @param node the node to query * @return an unmodifiable {@link Set} of tag classes which where associated with this node. * @since 0.12 */ public abstract Set> queryTags(Node node); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy