use of org.graalvm.compiler.truffle.runtime.OptimizedCallTarget in project graal by oracle.
the class SplittingStrategyTest method testGrowingLimitForTargetsOutsideEngine.
@Test
@SuppressWarnings("try")
public void testGrowingLimitForTargetsOutsideEngine() {
final int expectedGrowingSplits = (int) (2 * TruffleCompilerOptions.getValue(TruffleCompilerOptions.TruffleSplittingGrowthLimit));
final OptimizedCallTarget inner = (OptimizedCallTarget) runtime.createCallTarget(new DummyRootNode());
final OptimizedCallTarget outer = (OptimizedCallTarget) runtime.createCallTarget(new CallsInnerAndSwapsCallNode(inner));
fallbackSplitInfo.setLimitToCount();
try (TruffleCompilerOptions.TruffleOptionsOverrideScope s = TruffleCompilerOptions.overrideOptions(TruffleCompilerOptions.TruffleSplittingMaxNumberOfSplitNodes, fallbackSplitInfo.getSplitCount() + 2 * expectedGrowingSplits)) {
// Create 2 targets to boost the growing limit
runtime.createCallTarget(new DummyRootNode());
runtime.createCallTarget(new DummyRootNode());
SplitCountingListener localListener = new SplitCountingListener();
runtime.addListener(localListener);
for (int i = 0; i < 100; i++) {
outer.call();
}
Assert.assertEquals("Too many of too few splits.", expectedGrowingSplits, localListener.splitCount);
runtime.removeListener(localListener);
}
}
use of org.graalvm.compiler.truffle.runtime.OptimizedCallTarget 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);
}
}
use of org.graalvm.compiler.truffle.runtime.OptimizedCallTarget in project graal by oracle.
the class SplittingStrategyTest method testMaxLimitForTargetsOutsideEngine.
@Test
@SuppressWarnings("try")
public void testMaxLimitForTargetsOutsideEngine() {
final int expectedIncreaseInNodes = 10;
try (TruffleCompilerOptions.TruffleOptionsOverrideScope s = TruffleCompilerOptions.overrideOptions(TruffleCompilerOptions.TruffleSplittingMaxNumberOfSplitNodes, fallbackSplitInfo.getSplitCount() + expectedIncreaseInNodes)) {
final OptimizedCallTarget inner = (OptimizedCallTarget) runtime.createCallTarget(new DummyRootNode());
final OptimizedCallTarget outer = (OptimizedCallTarget) runtime.createCallTarget(new CallsInnerAndSwapsCallNode(inner));
createDummyTargetsToBoostGrowingSplitLimit();
SplitCountingListener localListener = new SplitCountingListener();
runtime.addListener(localListener);
for (int i = 0; i < 100; i++) {
outer.call();
}
Assert.assertEquals("Too many of too few splits.", expectedIncreaseInNodes, localListener.splitCount * DUMMYROOTNODECOUNT);
runtime.removeListener(localListener);
}
}
use of org.graalvm.compiler.truffle.runtime.OptimizedCallTarget in project graal by oracle.
the class TruffleBoundaryExceptionsTest method testExceptionOnTruffleBoundaryWithNoCatch.
@Test
public void testExceptionOnTruffleBoundaryWithNoCatch() {
final int compilationThreshold = TruffleCompilerOptions.getValue(TruffleCompilationThreshold);
class DeoptCountingExceptionOverBoundaryRootNode extends RootNode {
protected DeoptCountingExceptionOverBoundaryRootNode() {
super(null);
}
int deopCounter = 0;
@Override
public Object execute(VirtualFrame frame) {
boolean startedCompiled = CompilerDirectives.inCompiledCode();
throwExceptionBoundary();
if (startedCompiled && CompilerDirectives.inInterpreter()) {
deopCounter++;
}
return null;
}
@CompilerDirectives.TruffleBoundary
public void throwExceptionBoundary() {
throw new RuntimeException();
}
}
final OptimizedCallTarget outerTarget = (OptimizedCallTarget) runtime.createCallTarget(new DeoptCountingExceptionOverBoundaryRootNode());
for (int i = 0; i < compilationThreshold; i++) {
try {
outerTarget.call();
} catch (RuntimeException e) {
// do nothing
}
}
assertCompiled(outerTarget);
final int execCount = 10;
for (int i = 0; i < execCount; i++) {
try {
outerTarget.call();
} catch (RuntimeException e) {
// do nothing
}
}
int deopCount = ((DeoptCountingExceptionOverBoundaryRootNode) outerTarget.getRootNode()).deopCounter;
Assert.assertEquals("Incorrect number of deops detected!", 0, deopCount);
}
use of org.graalvm.compiler.truffle.runtime.OptimizedCallTarget in project graal by oracle.
the class TruffleBoundaryExceptionsTest method testExceptionOnTruffleBoundaryWithNoTransferToInterpreter.
@Test
public void testExceptionOnTruffleBoundaryWithNoTransferToInterpreter() {
final int compilationThreshold = TruffleCompilerOptions.getValue(TruffleCompilationThreshold);
class DeoptCountingExceptionOverBoundaryRootNode extends RootNode {
protected DeoptCountingExceptionOverBoundaryRootNode() {
super(null);
}
int deopCounter = 0;
int catchCounter = 0;
@Override
public Object execute(VirtualFrame frame) {
boolean startedCompiled = CompilerDirectives.inCompiledCode();
try {
throwExceptionBoundary();
} catch (RuntimeException e) {
catchCounter++;
}
if (startedCompiled && CompilerDirectives.inInterpreter()) {
deopCounter++;
}
return null;
}
@CompilerDirectives.TruffleBoundary(transferToInterpreterOnException = false)
public void throwExceptionBoundary() {
throw new RuntimeException();
}
}
final OptimizedCallTarget outerTarget = (OptimizedCallTarget) runtime.createCallTarget(new DeoptCountingExceptionOverBoundaryRootNode());
for (int i = 0; i < compilationThreshold; i++) {
outerTarget.call();
}
assertCompiled(outerTarget);
final int execCount = 10;
for (int i = 0; i < execCount; i++) {
outerTarget.call();
}
final int totalExecutions = compilationThreshold + execCount;
int catchCount = ((DeoptCountingExceptionOverBoundaryRootNode) outerTarget.getRootNode()).catchCounter;
Assert.assertEquals("Incorrect number of catch block executions", totalExecutions, catchCount);
int deopCount = ((DeoptCountingExceptionOverBoundaryRootNode) outerTarget.getRootNode()).deopCounter;
Assert.assertEquals("Incorrect number of deops detected!", 0, deopCount);
}
Aggregations