OutOfMemoryError on my BF interpreter

Cristian Esquivias cristian.esquivias at gmail.com
Wed May 2 08:46:52 UTC 2018

Hi Josef,

Thanks for the context. I'll try to build the GraalVM and see if it
solves the issue.

After reading the bug report, here's a little bit more info that I hope helps:

* The report says the SSA register allocator could be the problem on
"large inputs". I'm not sure what constitutes a large input, but my
mandelbrot script creates around 11,000 nodes in total. That's
probably not a huge amount, but they're all within one function since
BF doesn't have the concept of functions. That's probably a little
more unusual.
* My interpreter doesn't put pressure on the heap. After an initial
allocation of a 1,000-10,000 size int array no more allocations are
done for the rest of a script's life. This is proven out by jvisualvm.
The heap stays flat throughout most of the run and only spikes right
before the OOME occurs.
* There are very few (essentially no) opportunities for adding
TruffleBoundary annotations since nearly all my nodes' execute methods
are one line that do little more than fetch an item out of my array
and inc/dec the value. The only calls out to external methods are
calls to VirtualFrame.get [1]/set [2] some variable values, calls to
stdout's print method [3] and stdin's read method [4]. A truffle
expert's help would definitely be appreciated here since I'm just
making an educated guess.
* The OOME occurs inside a loop node. Could this OOME be caused by
loop unrolling [5]?


[1]: https://github.com/cesquivias/bf-graal/blob/master/lang/src/main/java/cesquivias/bf/DecDataNode.java
[2]: https://github.com/cesquivias/bf-graal/blob/master/lang/src/main/java/cesquivias/bf/DecPointerNode.java
[3]: https://github.com/cesquivias/bf-graal/blob/master/lang/src/main/java/cesquivias/bf/PrintDataNode.java
[4]: https://github.com/cesquivias/bf-graal/blob/master/lang/src/main/java/cesquivias/bf/ReadDataNode.java
[5]: https://github.com/cesquivias/bf-graal/blob/master/lang/src/main/java/cesquivias/bf/BFRepeatingNode.java

On Wed, May 2, 2018 at 12:37 AM, Josef Eisl <josef.eisl at jku.at> wrote:
> Hi Cristian!
> Thanks for your report. We have very recently merged a change to
> mitigate the OOME in this part of linear scan [1]. Unfortunately this
> was after the release so it is not included in 1.0.0 RC1. You would need
> to build your own GraalVM from source to see if the change helps.
> That said, the root cause of the OOME is usually a huge compilation unit
> thrown into the compiler. For more details, see also the discussion on
> the OpenJDK bug tracker [2].
> The reasons for big compilation units can me manifold. In case of
> Truffle, the issues can often be solved by adding TruffleBoundaries [3],
> i.e., instructing the compiler not to inline specified methods into the
> truffle graph. Maybe a Truffle expert can give you more hints on that.
> Hope that helps,
> Josef
> [1]:
> https://github.com/oracle/graal/commit/c0a15c562daa0338f61a6e7c22476cf145af5a66
> [2]: https://bugs.openjdk.java.net/browse/JDK-8199890
> [3]:
> http://www.graalvm.org/truffle/javadoc/com/oracle/truffle/api/CompilerDirectives.TruffleBoundary.html
> On 01/05/18 08:24, Cristian Esquivias wrote:
>> With the release of 1.0.0-RC1 I thought I'd come back and see how
>> Graal is doing. Great job; Graal is really starting to look like the
>> platform everyone should pay attention to.
>> To get back into it, I built a Brainf*ck interpreter with Truffle
>> (https://github.com/cesquivias/bf-graal). I modeled it after
>> simplelanguage so it should be easy to build and run.
>> While running the mandelbrot program, about halfway through the
>> program, the VM starts throwing OutOfMemoryError exceptions (one
>> pasted below). It created a zip file under dumps/ but it contains a
>> .bgv file I don't what to do with and a log file that just contains
>> the stacktrace.
>> I ran jvisualvm and took a heap dump. There are ~200k long[] objects
>> alone created by graal taking up ~50% of the memory. Digging through
>> the references it seems to be created/retained in
>> org.graalvm.compiler.lir.alloc.lsra.LinearScanLifetimeAnalysisPhase$$Lambda$48#1
>> [GC root - Java frame]
>> I'd provide some file from jvisualvm but the save button is grayed
>> out. I hope this is enough info. My interpreter is up on GitHub so
>> feel free to test it out.
>> I tested this both on the community & enterprise edition on Ubuntu
>> 18.04 in VirtualBox.
>> - Cristian
>> Thread[TruffleCompilerThread-12,10,main]: Compilation of
>> BFRepeatingNode at 222b298d<OSR> failed: java.lang.OutOfMemoryError: Java
>> heap space
>> at org.graalvm.compiler.lir.util.IndexedValueMap.<init>(IndexedValueMap.java:55)
>> at org.graalvm.compiler.lir.dfa.RegStackValueSet.<init>(RegStackValueSet.java:62)
>> at org.graalvm.compiler.lir.dfa.RegStackValueSet.copy(RegStackValueSet.java:70)
>> at org.graalvm.compiler.lir.dfa.RegStackValueSet.copy(RegStackValueSet.java:46)
>> at org.graalvm.compiler.lir.dfa.LocationMarker.processBlock(LocationMarker.java:107)
>> at org.graalvm.compiler.lir.dfa.LocationMarker.build(LocationMarker.java:81)
>> at org.graalvm.compiler.lir.dfa.LocationMarkerPhase.run(LocationMarkerPhase.java:51)
>> at org.graalvm.compiler.lir.dfa.LocationMarkerPhase.run(LocationMarkerPhase.java:47)
>> at org.graalvm.compiler.lir.phases.LIRPhase.apply(LIRPhase.java:115)
>> at org.graalvm.compiler.lir.phases.LIRPhase.apply(LIRPhase.java:107)
>> at org.graalvm.compiler.lir.phases.LIRPhaseSuite.run(LIRPhaseSuite.java:96)
>> at org.graalvm.compiler.lir.phases.LIRPhase.apply(LIRPhase.java:115)
>> at org.graalvm.compiler.lir.phases.LIRPhase.apply(LIRPhase.java:107)
>> at org.graalvm.compiler.core.GraalCompiler.emitLowLevel(GraalCompiler.java:367)
>> at org.graalvm.compiler.core.GraalCompiler.emitLIR0(GraalCompiler.java:336)
>> at org.graalvm.compiler.core.GraalCompiler.emitLIR(GraalCompiler.java:295)
>> at org.graalvm.compiler.core.GraalCompiler.emitBackEnd(GraalCompiler.java:275)
>> at org.graalvm.compiler.core.GraalCompiler.compile(GraalCompiler.java:175)
>> at org.graalvm.compiler.core.GraalCompiler.compileGraph(GraalCompiler.java:160)
>> at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.compilePEGraph(TruffleCompilerImpl.java:445)
>> at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.compileAST(TruffleCompilerImpl.java:391)
>> at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl$TruffleCompilationWrapper.performCompilation(TruffleCompilerImpl.java:544)
>> at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl$TruffleCompilationWrapper.performCompilation(TruffleCompilerImpl.java:493)
>> at org.graalvm.compiler.core.CompilationWrapper.run(CompilationWrapper.java:167)
>> at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.doCompile(TruffleCompilerImpl.java:222)
>> at org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime.doCompile(GraalTruffleRuntime.java:679)
>> at org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime$1.run(GraalTruffleRuntime.java:745)
>> 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)
>> To disable compilation failure notifications, set
>> CompilationFailureAction to Silent (e.g.,
>> -Dgraal.CompilationFailureAction=Silent).
>> To print a message for a compilation failure without retrying the
>> compilation, set CompilationFailureAction to Print (e.g.,
>> -Dgraal.CompilationFailureAction=Print).
>> Retrying compilation of BFRepeatingNode at 222b298d<OSR>

More information about the graal-dev mailing list