Search in sources :

Example 56 with Node

use of com.oracle.truffle.api.nodes.Node in project graal by oracle.

the class InstrumentationHandler method insertWrapperImpl.

@SuppressWarnings({ "unchecked", "deprecation" })
private void insertWrapperImpl(Node originalNode, SourceSection sourceSection) {
    Node node = originalNode;
    Node parent = node.getParent();
    if (parent instanceof com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode) {
        // already wrapped, need to invalidate the wrapper something changed
        invalidateWrapperImpl((com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode) parent, node);
        return;
    }
    ProbeNode probe = new ProbeNode(InstrumentationHandler.this, sourceSection);
    com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode wrapper;
    try {
        if (node instanceof InstrumentableNode) {
            wrapper = ((InstrumentableNode) node).createWrapper(probe);
            if (wrapper == null) {
                throw new IllegalStateException("No wrapper returned for " + originalNode);
            }
        } else {
            Class<?> factory = null;
            Class<?> currentClass = originalNode.getClass();
            while (currentClass != null) {
                Instrumentable instrumentable = currentClass.getAnnotation(Instrumentable.class);
                if (instrumentable != null) {
                    factory = instrumentable.factory();
                    break;
                }
                currentClass = currentClass.getSuperclass();
            }
            if (factory == null) {
                if (TRACE) {
                    trace("No wrapper inserted for %s, section %s. Not annotated with @Instrumentable.%n", node, sourceSection);
                }
                // node or superclass is not annotated with @Instrumentable
                return;
            }
            if (TRACE) {
                trace("Insert wrapper for %s, section %s%n", node, sourceSection);
            }
            wrapper = ((InstrumentableFactory<Node>) factory.newInstance()).createWrapper(originalNode, probe);
        }
    } catch (Exception e) {
        throw new IllegalStateException("Failed to create wrapper node. ", e);
    }
    if (!(wrapper instanceof Node)) {
        throw new IllegalStateException(String.format("Implementation of %s must be a subclass of %s.", com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode.class.getSimpleName(), Node.class.getSimpleName()));
    }
    final Node wrapperNode = (Node) wrapper;
    if (wrapperNode.getParent() != null) {
        throw new IllegalStateException(String.format("Instance of provided %s is already adopted by another parent.", com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode.class.getSimpleName()));
    }
    if (parent == null) {
        throw new IllegalStateException(String.format("Instance of instrumentable %s is not adopted by a parent.", Node.class.getSimpleName()));
    }
    if (!NodeUtil.isReplacementSafe(parent, node, wrapperNode)) {
        throw new IllegalStateException(String.format("WrapperNode implementation %s cannot be safely replaced in parent node class %s.", wrapperNode.getClass().getName(), parent.getClass().getName()));
    }
    originalNode.replace(wrapperNode, "Insert instrumentation wrapper node.");
    assert probe.getContext().validEventContext();
}
Also used : EventChainNode(com.oracle.truffle.api.instrumentation.ProbeNode.EventChainNode) RootNode(com.oracle.truffle.api.nodes.RootNode) Node(com.oracle.truffle.api.nodes.Node) NoSuchElementException(java.util.NoSuchElementException)

Example 57 with Node

use of com.oracle.truffle.api.nodes.Node in project graal by oracle.

the class ProbeNode method findParentChain.

@SuppressWarnings("deprecation")
private EventChainNode findParentChain(VirtualFrame frame, EventBinding<?> binding) {
    Node node = getParent().getParent();
    while (node != null) {
        // TODO we should avoid materializing the source section here
        if (node instanceof com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode) {
            ProbeNode probe = ((com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode) node).getProbeNode();
            EventChainNode c = probe.lazyUpdate(frame);
            if (c != null) {
                c = c.find(binding);
            }
            if (c != null) {
                return c;
            }
        } else if (node instanceof RootNode) {
            break;
        }
        node = node.getParent();
    }
    if (node == null) {
        throw new IllegalStateException("The AST node is not yet adopted. ");
    }
    return null;
}
Also used : RootNode(com.oracle.truffle.api.nodes.RootNode) RootNode(com.oracle.truffle.api.nodes.RootNode) Node(com.oracle.truffle.api.nodes.Node)

Example 58 with Node

use of com.oracle.truffle.api.nodes.Node in project graal by oracle.

the class SLLexicalScope method findParent.

public SLLexicalScope findParent() {
    if (parentBlock == null) {
        // This was a root scope.
        return null;
    }
    if (parent == null) {
        Node node = block;
        SLBlockNode newBlock = parentBlock;
        // Test if there is a next parent block. If not, we're in the root scope.
        SLBlockNode newParentBlock = getParentBlock(newBlock);
        if (newParentBlock == null) {
            parent = new SLLexicalScope(node, newBlock, newBlock.getRootNode());
        } else {
            parent = new SLLexicalScope(node, newBlock, newParentBlock);
        }
    }
    return parent;
}
Also used : SLBlockNode(com.oracle.truffle.sl.nodes.controlflow.SLBlockNode) SLStatementNode(com.oracle.truffle.sl.nodes.SLStatementNode) RootNode(com.oracle.truffle.api.nodes.RootNode) Node(com.oracle.truffle.api.nodes.Node) SLEvalRootNode(com.oracle.truffle.sl.nodes.SLEvalRootNode) SLBlockNode(com.oracle.truffle.sl.nodes.controlflow.SLBlockNode)

Example 59 with Node

use of com.oracle.truffle.api.nodes.Node in project graal by oracle.

the class SLLexicalScope method collectArgs.

private static Map<String, FrameSlot> collectArgs(Node block) {
    // Arguments are pushed to frame slots at the beginning of the function block.
    // To collect argument slots, search for SLReadArgumentNode inside of
    // SLWriteLocalVariableNode.
    Map<String, FrameSlot> args = new LinkedHashMap<>(4);
    NodeUtil.forEachChild(block, new NodeVisitor() {

        // The current write node containing a slot
        private SLWriteLocalVariableNode wn;

        @Override
        public boolean visit(Node node) {
            // When there is a write node, search for SLReadArgumentNode among its children:
            if (node instanceof SLWriteLocalVariableNode) {
                wn = (SLWriteLocalVariableNode) node;
                boolean all = NodeUtil.forEachChild(node, this);
                wn = null;
                return all;
            } else if (wn != null && (node instanceof SLReadArgumentNode)) {
                FrameSlot slot = wn.getSlot();
                String name = Objects.toString(slot.getIdentifier());
                assert !args.containsKey(name) : name + " argument exists already.";
                args.put(name, slot);
                return true;
            } else if (wn == null && (node instanceof SLStatementNode)) {
                // A different SL node - we're done.
                return false;
            } else {
                return NodeUtil.forEachChild(node, this);
            }
        }
    });
    return args;
}
Also used : FrameSlot(com.oracle.truffle.api.frame.FrameSlot) SLStatementNode(com.oracle.truffle.sl.nodes.SLStatementNode) RootNode(com.oracle.truffle.api.nodes.RootNode) Node(com.oracle.truffle.api.nodes.Node) SLEvalRootNode(com.oracle.truffle.sl.nodes.SLEvalRootNode) SLBlockNode(com.oracle.truffle.sl.nodes.controlflow.SLBlockNode) SLStatementNode(com.oracle.truffle.sl.nodes.SLStatementNode) LinkedHashMap(java.util.LinkedHashMap) NodeVisitor(com.oracle.truffle.api.nodes.NodeVisitor)

Example 60 with Node

use of com.oracle.truffle.api.nodes.Node in project graal by oracle.

the class SplittingStrategyTest method testDefaultStrategyStabilises.

@Test
@SuppressWarnings("try")
public void testDefaultStrategyStabilises() {
    try (TruffleCompilerOptions.TruffleOptionsOverrideScope s = TruffleCompilerOptions.overrideOptions(TruffleCompilerOptions.TruffleSplittingMaxNumberOfSplitNodes, fallbackSplitInfo.getSplitLimit() + 1000)) {
        createDummyTargetsToBoostGrowingSplitLimit();
        class InnerRootNode extends SplittableRootNode {

            OptimizedCallTarget target;

            @Child
            private DirectCallNode callNode1;

            @Child
            private Node polymorphic = new Node() {

                @Override
                public NodeCost getCost() {
                    return NodeCost.POLYMORPHIC;
                }
            };

            protected InnerRootNode() {
                super();
            }

            @Override
            public Object execute(VirtualFrame frame) {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                if (callNode1 == null) {
                    callNode1 = runtime.createDirectCallNode(target);
                    adoptChildren();
                }
                if (frame.getArguments().length > 0) {
                    if ((Integer) frame.getArguments()[0] < 100) {
                        callNode1.call(frame.getArguments());
                    }
                }
                return null;
            }

            @Override
            public String toString() {
                return "INNER";
            }
        }
        final InnerRootNode innerRootNode = new InnerRootNode();
        final OptimizedCallTarget inner = (OptimizedCallTarget) runtime.createCallTarget(innerRootNode);
        final OptimizedCallTarget mid = (OptimizedCallTarget) runtime.createCallTarget(new SplittableRootNode() {

            @Child
            private DirectCallNode callNode = null;

            @Child
            private Node polymorphic = new Node() {

                @Override
                public NodeCost getCost() {
                    return NodeCost.POLYMORPHIC;
                }
            };

            @Override
            public Object execute(VirtualFrame frame) {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                if (callNode == null) {
                    callNode = runtime.createDirectCallNode(inner);
                    adoptChildren();
                }
                Object[] arguments = frame.getArguments();
                if ((Integer) arguments[0] < 100) {
                    callNode.call(new Object[] { ((Integer) arguments[0]) + 1 });
                }
                return null;
            }

            @Override
            public String toString() {
                return "MID";
            }
        });
        OptimizedCallTarget outside = (OptimizedCallTarget) runtime.createCallTarget(new SplittableRootNode() {

            // runtime.createDirectCallNode(mid);
            @Child
            private DirectCallNode outsideCallNode = null;

            @Override
            public Object execute(VirtualFrame frame) {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                // Emulates builtin i.e. Split immediately
                if (outsideCallNode == null) {
                    outsideCallNode = runtime.createDirectCallNode(mid);
                    adoptChildren();
                    outsideCallNode.cloneCallTarget();
                }
                return outsideCallNode.call(frame.getArguments());
            }

            @Override
            public String toString() {
                return "OUTSIDE";
            }
        });
        innerRootNode.target = outside;
        createDummyTargetsToBoostGrowingSplitLimit();
        final int baseSplitCount = listener.splitCount;
        outside.call(1);
        // Expected 14
        // OUTSIDE MID
        // MID <split> INNER
        // INNER <split> OUTSIDE
        // OUTSIDE <split> MID
        // INNER OUTSIDE
        // OUTSIDE <split> MID
        // MID <split> INNER
        // MID <split> INNER
        // INNER <split> OUTSIDE
        // OUTSIDE <split> MID
        // INNER <split> OUTSIDE
        // OUTSIDE <split> MID
        // MID <split> INNER
        Assert.assertEquals("Not the right number of splits.", baseSplitCount + 13, listener.splitCount);
    }
}
Also used : Node(com.oracle.truffle.api.nodes.Node) DirectCallNode(com.oracle.truffle.api.nodes.DirectCallNode) RootNode(com.oracle.truffle.api.nodes.RootNode) OptimizedDirectCallNode(org.graalvm.compiler.truffle.runtime.OptimizedDirectCallNode) OptimizedCallTarget(org.graalvm.compiler.truffle.runtime.OptimizedCallTarget) NodeCost(com.oracle.truffle.api.nodes.NodeCost) VirtualFrame(com.oracle.truffle.api.frame.VirtualFrame) TruffleCompilerOptions(org.graalvm.compiler.truffle.common.TruffleCompilerOptions) DirectCallNode(com.oracle.truffle.api.nodes.DirectCallNode) OptimizedDirectCallNode(org.graalvm.compiler.truffle.runtime.OptimizedDirectCallNode) Test(org.junit.Test)

Aggregations

Node (com.oracle.truffle.api.nodes.Node)101 RootNode (com.oracle.truffle.api.nodes.RootNode)65 Test (org.junit.Test)46 InstrumentableNode (com.oracle.truffle.api.instrumentation.InstrumentableNode)21 ProbeNode (com.oracle.truffle.api.instrumentation.ProbeNode)21 Source (com.oracle.truffle.api.source.Source)16 NodeVisitor (com.oracle.truffle.api.nodes.NodeVisitor)11 CallTarget (com.oracle.truffle.api.CallTarget)9 TruffleObject (com.oracle.truffle.api.interop.TruffleObject)9 DirectCallNode (com.oracle.truffle.api.nodes.DirectCallNode)8 WrapperNode (com.oracle.truffle.api.instrumentation.InstrumentableNode.WrapperNode)7 TruffleRuntime (com.oracle.truffle.api.TruffleRuntime)6 SourceSection (com.oracle.truffle.api.source.SourceSection)6 TestHelper.createNode (com.oracle.truffle.api.dsl.test.TestHelper.createNode)5 ValueNode (com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode)5 SLEvalRootNode (com.oracle.truffle.sl.nodes.SLEvalRootNode)5 SLStatementNode (com.oracle.truffle.sl.nodes.SLStatementNode)5 SLBlockNode (com.oracle.truffle.sl.nodes.controlflow.SLBlockNode)5 LinkedHashMap (java.util.LinkedHashMap)5 TruffleInstrument (com.oracle.truffle.api.instrumentation.TruffleInstrument)4