Search in sources :

Example 1 with Tag

use of com.oracle.truffle.api.instrumentation.Tag in project graal by oracle.

the class PolyglotEngineDispatch method attachExecutionListener.

@Override
public ExecutionListener attachExecutionListener(Object engineReceiver, Consumer<ExecutionEvent> onEnter, Consumer<ExecutionEvent> onReturn, boolean expressions, boolean statements, boolean roots, Predicate<Source> sourceFilter, Predicate<String> rootFilter, boolean collectInputValues, boolean collectReturnValues, boolean collectExceptions) {
    PolyglotEngineImpl engine = (PolyglotEngineImpl) engineReceiver;
    Instrumenter instrumenter = (Instrumenter) EngineAccessor.INSTRUMENT.getEngineInstrumenter(engine.instrumentationHandler);
    List<Class<? extends Tag>> tags = new ArrayList<>();
    if (expressions) {
        tags.add(StandardTags.ExpressionTag.class);
    }
    if (statements) {
        tags.add(StandardTags.StatementTag.class);
    }
    if (roots) {
        tags.add(StandardTags.RootTag.class);
    }
    if (tags.isEmpty()) {
        throw new IllegalArgumentException("No elements specified to listen to for execution listener. Need to specify at least one element kind: expressions, statements or roots.");
    }
    if (onReturn == null && onEnter == null) {
        throw new IllegalArgumentException("At least one event consumer must be provided for onEnter or onReturn.");
    }
    SourceSectionFilter.Builder filterBuilder = SourceSectionFilter.newBuilder().tagIs(tags.toArray(new Class<?>[0]));
    filterBuilder.includeInternal(false);
    PolyglotExecutionListenerDispatch.ListenerImpl config = new PolyglotExecutionListenerDispatch.ListenerImpl(polyglot.getExecutionEventDispatch(), engine, onEnter, onReturn, collectInputValues, collectReturnValues, collectExceptions);
    filterBuilder.sourceIs(new SourceSectionFilter.SourcePredicate() {

        public boolean test(com.oracle.truffle.api.source.Source s) {
            String language = s.getLanguage();
            if (language == null) {
                return false;
            } else if (!engine.idToLanguage.containsKey(language)) {
                return false;
            } else if (sourceFilter != null) {
                try {
                    return sourceFilter.test(PolyglotImpl.getOrCreatePolyglotSource(polyglot, s));
                } catch (Throwable e) {
                    if (config.closing) {
                        // configuration is closing ignore errors.
                        return false;
                    }
                    throw engine.host.toHostException(null, e);
                }
            } else {
                return true;
            }
        }
    });
    if (rootFilter != null) {
        filterBuilder.rootNameIs(new Predicate<String>() {

            public boolean test(String s) {
                try {
                    return rootFilter.test(s);
                } catch (Throwable e) {
                    if (config.closing) {
                        // configuration is closing ignore errors.
                        return false;
                    }
                    throw engine.host.toHostException(null, e);
                }
            }
        });
    }
    SourceSectionFilter filter = filterBuilder.build();
    EventBinding<?> binding;
    try {
        boolean mayNeedInputValues = config.collectInputValues && config.onReturn != null;
        boolean mayNeedReturnValue = config.collectReturnValues && config.onReturn != null;
        boolean mayNeedExceptions = config.collectExceptions;
        if (mayNeedInputValues || mayNeedReturnValue || mayNeedExceptions) {
            binding = instrumenter.attachExecutionEventFactory(filter, mayNeedInputValues ? filter : null, new ExecutionEventNodeFactory() {

                public ExecutionEventNode create(EventContext context) {
                    return new PolyglotExecutionListenerDispatch.ProfilingNode(config, context);
                }
            });
        } else {
            // fast path no collection of additional profiles
            binding = instrumenter.attachExecutionEventFactory(filter, null, new ExecutionEventNodeFactory() {

                public ExecutionEventNode create(EventContext context) {
                    return new PolyglotExecutionListenerDispatch.DefaultNode(config, context);
                }
            });
        }
    } catch (Throwable t) {
        throw PolyglotImpl.guestToHostException(engine, t);
    }
    config.binding = binding;
    return polyglot.getManagement().newExecutionListener(polyglot.getExecutionListenerDispatch(), config);
}
Also used : ArrayList(java.util.ArrayList) SourceSectionFilter(com.oracle.truffle.api.instrumentation.SourceSectionFilter) StandardTags(com.oracle.truffle.api.instrumentation.StandardTags) Instrumenter(com.oracle.truffle.api.instrumentation.Instrumenter) ExecutionEventNodeFactory(com.oracle.truffle.api.instrumentation.ExecutionEventNodeFactory) EventContext(com.oracle.truffle.api.instrumentation.EventContext) Tag(com.oracle.truffle.api.instrumentation.Tag)

Example 2 with Tag

use of com.oracle.truffle.api.instrumentation.Tag in project graal by oracle.

the class LanguageCache method getProvidedTags.

@SuppressWarnings("unchecked")
Set<? extends Class<? extends Tag>> getProvidedTags() {
    Set<Class<? extends Tag>> res = providedTags;
    if (res == null) {
        ProvidedTags tags = provider.getClass().getAnnotation(ProvidedTags.class);
        if (tags == null) {
            res = Collections.emptySet();
        } else {
            res = new HashSet<>();
            Collections.addAll(res, (Class<? extends Tag>[]) tags.value());
            res = Collections.unmodifiableSet(res);
        }
        providedTags = res;
    }
    return res;
}
Also used : ProvidedTags(com.oracle.truffle.api.instrumentation.ProvidedTags) Tag(com.oracle.truffle.api.instrumentation.Tag)

Example 3 with Tag

use of com.oracle.truffle.api.instrumentation.Tag in project graal by oracle.

the class InstrumentationTest method testNearestExecutionNode.

@Test
public void testNearestExecutionNode() throws IOException {
    NearestExecutionNodeTester tester = new NearestExecutionNodeTester();
    Source source = Source.create(InstrumentationTestLanguage.ID, "ROOT(DEFINE(foo1, ROOT(STATEMENT, VARIABLE(a, 10), STATEMENT, EXPRESSION))," + "DEFINE(foo2, ROOT(EXPRESSION, CALL(foo1), STATEMENT, STATEMENT(EXPRESSION))))");
    tester.set(StandardTags.StatementTag.class, (offset, node) -> {
        int pos = node.getSourceSection().getCharIndex();
        if (offset <= 31) {
            return pos == 23;
        } else if (offset <= 75) {
            return pos == 51;
        } else if (offset <= 125) {
            return pos == 117;
        } else {
            return pos == 128;
        }
    });
    instrumentEnv.getInstrumenter().attachExecuteSourceListener(SourceFilter.ANY, new ExecuteSourceListener() {

        @Override
        public void onExecute(ExecuteSourceEvent event) {
            int length = event.getSource().getLength();
            instrumentEnv.getInstrumenter().attachLoadSourceSectionListener(SourceSectionFilter.ANY, new LoadSourceSectionListener() {

                @Override
                public void onLoad(LoadSourceSectionEvent evt) {
                    if (!(evt.getNode() instanceof InstrumentableNode)) {
                        return;
                    }
                    InstrumentableNode node = (InstrumentableNode) evt.getNode();
                    SourceSection ss = evt.getNode().getSourceSection();
                    if (ss == null || ss.getCharacters().toString().startsWith("ROOT(DEFINE")) {
                        // No SourceSection, or the outer function
                        return;
                    }
                    Class<? extends Tag> tag = tester.getTag();
                    Set<Class<? extends Tag>> tags = Collections.singleton(tag);
                    for (int offset = 0; offset < length; offset++) {
                        if (ss.getCharIndex() <= offset && offset < ss.getCharEndIndex()) {
                            Node nearestNode = node.findNearestNodeAt(offset, tags);
                            tester.checkNearest(offset, nearestNode);
                        }
                    }
                }
            }, true);
        }
    }, true);
    run(source);
    assertNull(tester.getFailures());
}
Also used : LoadSourceSectionEvent(com.oracle.truffle.api.instrumentation.LoadSourceSectionEvent) ExecuteSourceListener(com.oracle.truffle.api.instrumentation.ExecuteSourceListener) RootNode(com.oracle.truffle.api.nodes.RootNode) DirectCallNode(com.oracle.truffle.api.nodes.DirectCallNode) ExecutableNode(com.oracle.truffle.api.nodes.ExecutableNode) ProbeNode(com.oracle.truffle.api.instrumentation.ProbeNode) Node(com.oracle.truffle.api.nodes.Node) ExecutionEventNode(com.oracle.truffle.api.instrumentation.ExecutionEventNode) InstrumentableNode(com.oracle.truffle.api.instrumentation.InstrumentableNode) LoadSourceSectionListener(com.oracle.truffle.api.instrumentation.LoadSourceSectionListener) Source(org.graalvm.polyglot.Source) StandardTags(com.oracle.truffle.api.instrumentation.StandardTags) ExecuteSourceEvent(com.oracle.truffle.api.instrumentation.ExecuteSourceEvent) InstrumentableNode(com.oracle.truffle.api.instrumentation.InstrumentableNode) SourceSection(com.oracle.truffle.api.source.SourceSection) Tag(com.oracle.truffle.api.instrumentation.Tag) Test(org.junit.Test)

Example 4 with Tag

use of com.oracle.truffle.api.instrumentation.Tag in project graal by oracle.

the class InsightFilter method create.

static InsightFilter.Data create(AgentType at, Object[] arr) throws IllegalArgumentException, UnsupportedMessageException {
    List<Class<? extends Tag>> allTags = new ArrayList<>();
    String rootNameRegExp = null;
    Object rootNameFn = null;
    Object sourceFilterFn = null;
    if (arr != null && arr.length > 2) {
        Object config = arr[2];
        final InteropLibrary iop = InteropLibrary.getFactory().getUncached();
        Map<String, Object> map = new LinkedHashMap<>();
        if (iop.hasHashEntries(config)) {
            Object it = iop.getHashEntriesIterator(config);
            while (iop.hasIteratorNextElement(it)) {
                try {
                    Object keyAndValue = iop.getIteratorNextElement(it);
                    Object key;
                    Object value;
                    try {
                        key = iop.readArrayElement(keyAndValue, 0);
                        value = iop.readArrayElement(keyAndValue, 1);
                    } catch (InvalidArrayIndexException ex) {
                        throw CompilerDirectives.shouldNotReachHere(ex);
                    }
                    String type = iop.asString(key);
                    map.put(type, value);
                } catch (StopIterationException ex) {
                    break;
                }
            }
        } else {
            Object allMembers = iop.getMembers(config, false);
            long allMembersSize = iop.getArraySize(allMembers);
            for (int i = 0; i < allMembersSize; i++) {
                Object atI;
                try {
                    atI = iop.readArrayElement(allMembers, i);
                } catch (InvalidArrayIndexException ex) {
                    continue;
                }
                String type = iop.asString(atI);
                Object value;
                try {
                    value = iop.readMember(config, type);
                } catch (UnknownIdentifierException ex) {
                    continue;
                }
                map.put(type, value);
            }
        }
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String type = entry.getKey();
            switch(type) {
                case "expressions":
                    if (isSet(iop, map, "expressions")) {
                        allTags.add(StandardTags.ExpressionTag.class);
                    }
                    break;
                case "statements":
                    if (isSet(iop, map, "statements")) {
                        allTags.add(StandardTags.StatementTag.class);
                    }
                    break;
                case "roots":
                    if (isSet(iop, map, "roots")) {
                        allTags.add(StandardTags.RootBodyTag.class);
                    }
                    break;
                case "rootNameFilter":
                    {
                        Object fn = map.get("rootNameFilter");
                        if (fn != null && !iop.isNull(fn)) {
                            if (iop.isString(fn)) {
                                rootNameRegExp = iop.asString(fn);
                            } else {
                                if (!iop.isExecutable(fn)) {
                                    throw new IllegalArgumentException("rootNameFilter should be a string, a regular expression!");
                                }
                                rootNameFn = fn;
                            }
                        }
                        break;
                    }
                case "sourceFilter":
                    {
                        Object fn = map.get("sourceFilter");
                        if (fn != null && !iop.isNull(fn)) {
                            if (!iop.isExecutable(fn)) {
                                throw new IllegalArgumentException("sourceFilter has to be a function!");
                            }
                            sourceFilterFn = fn;
                        }
                        break;
                    }
                default:
                    throw InsightException.unknownAttribute(type);
            }
        }
    }
    if (allTags.isEmpty()) {
        throw new IllegalArgumentException("No elements specified to listen to for execution listener. Need to specify at least one element kind: expressions, statements or roots.");
    }
    allTags.sort((c1, c2) -> c1.getName().compareTo(c2.getName()));
    InsightFilter filter = new InsightFilter(allTags, rootNameRegExp, rootNameFn != null, sourceFilterFn != null);
    return new Data(at, filter, arr[1], rootNameFn, sourceFilterFn);
}
Also used : StopIterationException(com.oracle.truffle.api.interop.StopIterationException) ArrayList(java.util.ArrayList) StandardTags(com.oracle.truffle.api.instrumentation.StandardTags) LinkedHashMap(java.util.LinkedHashMap) InvalidArrayIndexException(com.oracle.truffle.api.interop.InvalidArrayIndexException) UnknownIdentifierException(com.oracle.truffle.api.interop.UnknownIdentifierException) InteropLibrary(com.oracle.truffle.api.interop.InteropLibrary) Tag(com.oracle.truffle.api.instrumentation.Tag) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Aggregations

Tag (com.oracle.truffle.api.instrumentation.Tag)4 StandardTags (com.oracle.truffle.api.instrumentation.StandardTags)3 ArrayList (java.util.ArrayList)2 EventContext (com.oracle.truffle.api.instrumentation.EventContext)1 ExecuteSourceEvent (com.oracle.truffle.api.instrumentation.ExecuteSourceEvent)1 ExecuteSourceListener (com.oracle.truffle.api.instrumentation.ExecuteSourceListener)1 ExecutionEventNode (com.oracle.truffle.api.instrumentation.ExecutionEventNode)1 ExecutionEventNodeFactory (com.oracle.truffle.api.instrumentation.ExecutionEventNodeFactory)1 InstrumentableNode (com.oracle.truffle.api.instrumentation.InstrumentableNode)1 Instrumenter (com.oracle.truffle.api.instrumentation.Instrumenter)1 LoadSourceSectionEvent (com.oracle.truffle.api.instrumentation.LoadSourceSectionEvent)1 LoadSourceSectionListener (com.oracle.truffle.api.instrumentation.LoadSourceSectionListener)1 ProbeNode (com.oracle.truffle.api.instrumentation.ProbeNode)1 ProvidedTags (com.oracle.truffle.api.instrumentation.ProvidedTags)1 SourceSectionFilter (com.oracle.truffle.api.instrumentation.SourceSectionFilter)1 InteropLibrary (com.oracle.truffle.api.interop.InteropLibrary)1 InvalidArrayIndexException (com.oracle.truffle.api.interop.InvalidArrayIndexException)1 StopIterationException (com.oracle.truffle.api.interop.StopIterationException)1 UnknownIdentifierException (com.oracle.truffle.api.interop.UnknownIdentifierException)1 DirectCallNode (com.oracle.truffle.api.nodes.DirectCallNode)1