To reproduce
git clone https://github.com/prawnpdf/prawn.git
cd prawn
bundle install
bundle exec rspec spec/manual_spec.rb
It starts hanging up after a while and you need to terminate it using Ctrl + C/Command + C. Mostly after several minutes (5 – 7 minutes). These steps reproduce always this issue on my machine. Probably, there is a simpler way how to reproduce it but this is how I found it.
Error
Prawn specs: Running on Ruby Version: 2.4.4
^C
RSpec is shutting down and will print the summary report... Interrupt again to force quit.
org.graalvm.compiler.code.SourceStackTraceBailoutException$1: too many loop explosion iterations - does the explosion not terminate for method SubstrateMethod<StringNodes$DeleteBangNode.argRopes>?
Caused by: org.graalvm.compiler.core.common.PermanentBailoutException: too many loop explosion iterations - does the explosion not terminate for method SubstrateMethod<StringNodes$DeleteBangNode.argRopes>?
at org.graalvm.compiler.replacements.PEGraphDecoder.tooManyLoopExplosionIterations(PEGraphDecoder.java:649)
at org.graalvm.compiler.replacements.PEGraphDecoder.checkLoopExplosionIteration(PEGraphDecoder.java:643)
at org.graalvm.compiler.nodes.GraphDecoder.handleLoopExplosionEnd(GraphDecoder.java:755)
at org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:553)
at org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:415)
at org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:597)
at org.graalvm.compiler.truffle.compiler.PartialEvaluator.doGraphPE(PartialEvaluator.java:481)
at com.oracle.svm.truffle.api.SubstratePartialEvaluator.doGraphPE(SubstratePartialEvaluator.java:81)
at org.graalvm.compiler.truffle.compiler.PartialEvaluator.fastPartialEvaluation(PartialEvaluator.java:519)
at org.graalvm.compiler.truffle.compiler.PartialEvaluator.createGraph(PartialEvaluator.java:245)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.compileAST(TruffleCompilerImpl.java:439)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl$TruffleCompilationWrapper.performCompilation(TruffleCompilerImpl.java:620)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl$TruffleCompilationWrapper.performCompilation(TruffleCompilerImpl.java:564)
at org.graalvm.compiler.core.CompilationWrapper.run(CompilationWrapper.java:172)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.doCompile(TruffleCompilerImpl.java:280)
at org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime.doCompile(GraalTruffleRuntime.java:691)
at org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime.doCompile(GraalTruffleRuntime.java:715)
at org.graalvm.compiler.truffle.runtime.BackgroundCompileQueue$Request.run(BackgroundCompileQueue.java:83)
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.truffle.runtime.BackgroundCompileQueue$TruffleCompilerThreadFactory$1.run(BackgroundCompileQueue.java:163)
at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:481)
at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
org.graalvm.compiler.code.SourceStackTraceBailoutException$1: too many loop explosion iterations - does the explosion not terminate for method SubstrateMethod<StringNodes$DeleteBangNode.argRopes>?
Caused by: org.graalvm.compiler.core.common.PermanentBailoutException: too many loop explosion iterations - does the explosion not terminate for method SubstrateMethod<StringNodes$DeleteBangNode.argRopes>?
at org.graalvm.compiler.replacements.PEGraphDecoder.tooManyLoopExplosionIterations(PEGraphDecoder.java:649)
at org.graalvm.compiler.replacements.PEGraphDecoder.checkLoopExplosionIteration(PEGraphDecoder.java:643)
at org.graalvm.compiler.nodes.GraphDecoder.handleLoopExplosionEnd(GraphDecoder.java:755)
at org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:553)
at org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:415)
at org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:597)
at org.graalvm.compiler.truffle.compiler.PartialEvaluator.doGraphPE(PartialEvaluator.java:481)
at com.oracle.svm.truffle.api.SubstratePartialEvaluator.doGraphPE(SubstratePartialEvaluator.java:81)
at org.graalvm.compiler.truffle.compiler.PartialEvaluator.fastPartialEvaluation(PartialEvaluator.java:519)
at org.graalvm.compiler.truffle.compiler.PartialEvaluator.createGraph(PartialEvaluator.java:245)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.compileAST(TruffleCompilerImpl.java:439)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl$TruffleCompilationWrapper.performCompilation(TruffleCompilerImpl.java:620)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl$TruffleCompilationWrapper.performCompilation(TruffleCompilerImpl.java:564)
at org.graalvm.compiler.core.CompilationWrapper.run(CompilationWrapper.java:172)
at org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.doCompile(TruffleCompilerImpl.java:280)
at org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime.doCompile(GraalTruffleRuntime.java:691)
at org.graalvm.compiler.truffle.runtime.GraalTruffleRuntime.doCompile(GraalTruffleRuntime.java:715)
at org.graalvm.compiler.truffle.runtime.BackgroundCompileQueue$Request.run(BackgroundCompileQueue.java:83)
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.truffle.runtime.BackgroundCompileQueue$TruffleCompilerThreadFactory$1.run(BackgroundCompileQueue.java:163)
at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:481)
at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
F
Failures:
1) Prawn manual contains no unexpected changes
Failure/Error: expect(hash).to eq MANUAL_HASH
expected: "d8b6b220c2ce749f45108cab3a9e710ade90b1316a3e01a64ddd65f389c06bf95af8d1ff6086a5b3e1b1c7da001f577199e7de12e09545af01751b05e3a70c93"
got: "63466feb0e40f15f20c80668a1ef803c8215a07e4e1cb6d36276090eff0c7932a58565898fc1cb191d1cd3e419613f97418d18774e4046979a92c95c50239ded"
(compared using ==)
# ./spec/manual_spec.rb:31:in `block (3 levels) in <top (required)>'
Finished in 7 minutes 50 seconds (files took 2.28 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/manual_spec.rb:23 # Prawn manual contains no unexpected changes
The relevant part of the error (I removed some less relevant parts) is:
too many loop explosion iterations - does the explosion not terminate for method StringNodes$DeleteBangNode.argRopes?
Which means it's a bug of StringNodes$DeleteBangNode most likely.
jt ruby --graal -e 'd=["z"]; loop { "abc".delete(*d) }'
is a simple reproducer for this bug.
Thank you for reporting this. I've found two places where this type of problem could occur, and I'm testing a fix internally right now.
@deepj just to let you know I have found one other memory related issue in the tests. I have a fix which I'm testing in our CI environment now, and can successfully run the whole test suite locally (apart from manual_spec.rb which will need a new case for TruffleRuby.
All the fixes for this issue are now merged.