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();
}
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;
}
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;
}
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;
}
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);
}
}
Aggregations