I am currently writing my own implementation of simplelanguage (https://github.com/graalvm/simplelanguage/) in order to learn how to use Truffle.
I wrote a few programs to test my implementations, for instance the following implementations of the fibonacci algorithm.
function fib(num) {
if (num <= 1) {return 1;}
else {return fib(num-1) + fib(num-2); }
}
function fib(num) {
if (num < 1) {return 0;}
n1 = 0;
n2 = 1;
i = 1;
while (i < num) {
next = n2 + n1;
n1 = n2;
n2 = next;
i = i + 1;
}
return n2;
}
While the non-recursive version can be executed with any large parameter value (e.g 10000), the recursive version quickly throws a runtime error.
For instance I developed an simple test which execute the recursive fib function with incremental values and I obtains the following result:
fib(1) = 1(61)
fib(2) = 2(14)
fib(3) = 3(1)
fib(4) = 5(2)
fib(5) = 8(5)
fib(6) = 13(13)
fib(7) = 21(28)
fib(8) = 34(24)
fib(9) = 55(40)
fib(10) = 89(30)
fib(11) = 144(25)
fib(12) = 233(93)
fib(13) = 377(127)
fib(14) = 610(86)
fib(15) = 987(118)
fib(16) = 1597(248)
fib(17) = 2584(314)
fib(18) = 4181(402)
fib(19) = 6765(524)
fib(20) = 10946(372)
fib(21) = 17711(646)
[truffle] opt fail Root@62804e23 |Reason org.graalvm.compiler.code.SourceStackTraceBailoutException$1: Object of type Lorg/graalvm/compiler/truffle/runtime/FrameWithoutBoxing; should not be materialized (must not let virtual object escape at node 10349|EndNode):
org.graalvm.compiler.code.SourceStackTraceBailoutException$1: Object of type Lorg/graalvm/compiler/truffle/runtime/FrameWithoutBoxing; should not be materialized (must not let virtual object escape at node 10349|EndNode):
at fr.mleduc.simplelanguage.revisitor.revisitors.ExecSLRevisitor$6.eval(ExecSLRevisitor.java:527)
at fr.mleduc.simplelanguage.revisitor.model.objects.Root.execute(Root.java:34)
at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callProxy(OptimizedCallTarget.java:262)
at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callRoot(OptimizedCallTarget.java:251)
Caused by: org.graalvm.compiler.graph.VerificationError: Object of type Lorg/graalvm/compiler/truffle/runtime/FrameWithoutBoxing; should not be materialized (must not let virtual object escape at node 10349|EndNode):
at org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode.ensureVirtualFailure(EnsureVirtualizedNode.java:98)
at org.graalvm.compiler.nodes.virtual.CommitAllocationNode.lower(CommitAllocationNode.java:117)
at org.graalvm.compiler.phases.common.LoweringPhase$Round.process(LoweringPhase.java:464)
at org.graalvm.compiler.phases.common.LoweringPhase$Round.access$200(LoweringPhase.java:340)
at org.graalvm.compiler.phases.common.LoweringPhase$Round$ProcessFrame.preprocess(LoweringPhase.java:404)
at org.graalvm.compiler.phases.common.LoweringPhase.processBlock(LoweringPhase.java:563)
at org.graalvm.compiler.phases.common.LoweringPhase$Round.run(LoweringPhase.java:389)
at org.graalvm.compiler.phases.Phase.run(Phase.java:49)
at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:197)
at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:139)
at org.graalvm.compiler.phases.PhaseSuite.run(PhaseSuite.java:212)
at org.graalvm.compiler.phases.common.IncrementalCanonicalizerPhase.run(IncrementalCanonicalizerPhase.java:56)
at org.graalvm.compiler.phases.common.IncrementalCanonicalizerPhase.run(IncrementalCanonicalizerPhase.java:38)
at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:197)
at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:139)
at org.graalvm.compiler.phases.common.LoweringPhase.lower(LoweringPhase.java:260)
at org.graalvm.compiler.phases.common.LoweringPhase.run(LoweringPhase.java:253)
at org.graalvm.compiler.phases.common.LoweringPhase.run(LoweringPhase.java:92)
at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:197)
at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:139)
at org.graalvm.compiler.phases.PhaseSuite.run(PhaseSuite.java:212)
at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:197)
at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:139)
at org.graalvm.compiler.core.GraalCompiler.emitFrontEnd(GraalCompiler.java:256)
at org.graalvm.compiler.core.GraalCompiler.compile(GraalCompiler.java:180)
at org.graalvm.compiler.core.GraalCompiler.compileGraph(GraalCompiler.java:165)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.compilePEGraph(TruffleCompilerImpl.java:447)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.compileAST(TruffleCompilerImpl.java:393)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl$TruffleCompilationWrapper.performCompilation(TruffleCompilerImpl.java:546)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl$TruffleCompilationWrapper.performCompilation(TruffleCompilerImpl.java:495)
at org.graalvm.compiler.core.CompilationWrapper.run(CompilationWrapper.java:169)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.doCompile(TruffleCompilerImpl.java:224)
at org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime.doCompile(GraalTruffleRuntime.java:710)
at org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime$1.run(GraalTruffleRuntime.java:776)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
at org.graalvm.compiler.core.CompilerThread.run(CompilerThread.java:42)
fib(22) = 28657(570)
fib(23) = 46368(735)
fib(24) = 75025(1235)
I tried to compare my own implementation with the official simplelanguage implementation without finding a way to identify the origin of the problem.
So my question is, how can I find the root cause of the issue ?
PS: So far I don't have enough information to identify the relevant snippet to include in this question but feel free to ask for more details if needed. Thanks :)
The error here is that you are letting a VirtualFrame
object escape from the scope of partial evaluation. The first part of the stack trace is in fact a stack trace of your interpreter under partial evaluation. in particular:
at fr.mleduc.simplelanguage.revisitor.revisitors.ExecSLRevisitor$6.eval(ExecSLRevisitor.java:527)
at fr.mleduc.simplelanguage.revisitor.model.objects.Root.execute(Root.java:34)
Something around ExecSLRevisitor.java:527
is letting a VirtualFrame
escape but it's hard to tell what without seeing the code.
There are 2 solutions:
VirtualFrame
)