You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using the ScriptEngine API to compile scripts fails when called from different threads.
This is because the GraalJSBindings of the engine context are accessed during compilation, leading to at least three different types of errors:
Exception in thread "main" java.lang.NullPointerException
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:542)
at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:567)
at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:670)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:765)
at Test.main(Test.java:25)
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.Map.entrySet()" because "this.global" is null
at com.oracle.truffle.js.scriptengine.GraalJSBindings.entrySet(GraalJSBindings.java:198)
at java.base/java.util.AbstractMap.containsKey(AbstractMap.java:148)
at java.scripting/javax.script.SimpleScriptContext.getAttribute(SimpleScriptContext.java:158)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.createSource(GraalJSScriptEngine.java:462)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.compile(GraalJSScriptEngine.java:653)
...
java.lang.IllegalStateException: Multi threaded access requested by thread Thread[#32,ForkJoinPool.commonPool-worker-10,5,main] but is not allowed for language(s) js.
at com.oracle.truffle.polyglot.PolyglotEngineException.illegalState(PolyglotEngineException.java:133)
at com.oracle.truffle.polyglot.PolyglotContextImpl.throwDeniedThreadAccess(PolyglotContextImpl.java:1392)
at com.oracle.truffle.polyglot.PolyglotContextImpl.checkAllThreadAccesses(PolyglotContextImpl.java:1058)
at com.oracle.truffle.polyglot.PolyglotContextImpl.enterThreadChanged(PolyglotContextImpl.java:884)
at com.oracle.truffle.polyglot.PolyglotEngineImpl.enterCached(PolyglotEngineImpl.java:2080)
at com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:109)
at com.oracle.truffle.api.impl.DefaultCallTarget.callDirectOrIndirect(DefaultCallTarget.java:85)
at com.oracle.truffle.api.impl.DefaultCallTarget.call(DefaultCallTarget.java:102)
at com.oracle.truffle.polyglot.PolyglotMap.entrySet(PolyglotMap.java:124)
at com.oracle.truffle.js.scriptengine.GraalJSBindings.entrySet(GraalJSBindings.java:198)
at java.base/java.util.AbstractMap.containsKey(AbstractMap.java:148)
at java.scripting/javax.script.SimpleScriptContext.getAttribute(SimpleScriptContext.java:158)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.createSource(GraalJSScriptEngine.java:462)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.compile(GraalJSScriptEngine.java:653)
...
Suppressed: Attached Guest Language Frames (1)
java.lang.IllegalStateException: Multi threaded access requested by thread Thread[#44,ForkJoinPool.commonPool-worker-11,5,main] but is not allowed for language(s) js.
at com.oracle.truffle.polyglot.PolyglotEngineException.illegalState(PolyglotEngineException.java:133)
at com.oracle.truffle.polyglot.PolyglotContextImpl.throwDeniedThreadAccess(PolyglotContextImpl.java:1392)
at com.oracle.truffle.polyglot.PolyglotContextImpl.checkAllThreadAccesses(PolyglotContextImpl.java:1058)
at com.oracle.truffle.polyglot.PolyglotContextImpl.enterThreadChanged(PolyglotContextImpl.java:884)
at com.oracle.truffle.polyglot.PolyglotEngineImpl.enterCached(PolyglotEngineImpl.java:2080)
at com.oracle.truffle.polyglot.PolyglotEngineImpl.enterIfNeeded(PolyglotEngineImpl.java:2008)
at com.oracle.truffle.polyglot.PolyglotValueDispatch.hostEnter(PolyglotValueDispatch.java:1256)
at com.oracle.truffle.polyglot.PolyglotContextImpl.parse(PolyglotContextImpl.java:1649)
at com.oracle.truffle.polyglot.PolyglotContextDispatch.parse(PolyglotContextDispatch.java:65)
at org.graalvm.polyglot.Context.parse(Context.java:483)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.checkSyntax(GraalJSScriptEngine.java:680)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.compile(GraalJSScriptEngine.java:664)
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.compile(GraalJSScriptEngine.java:654)
...
How to reproduce
Here is a simple reproducer: reproducer.zip
Commented out lines work around these issues (explained below).
Possible workaround
Synchronize on the engine bindings to fix all compliation errors:
It resolves compilation slowdowns by initializing the GraalJSBindings context early.
Synchonization from 1) somehow does not take care of this internal race condition. Maybe it's a thread visibility issue, not sure.
Another workaround would be to just replace the engine bindings with SimpleBindings, but this massively degrades script compilation performance, because the engine will then create new GraalJSBindings + context per compilation.
Using the ScriptEngine API to compile scripts fails when called from different threads.
This is because the GraalJSBindings of the engine context are accessed during compilation, leading to at least three different types of errors:
How to reproduce
Here is a simple reproducer: reproducer.zip
Commented out lines work around these issues (explained below).
Possible workaround
Synchonization from 1) somehow does not take care of this internal race condition. Maybe it's a thread visibility issue, not sure.
Another workaround would be to just replace the engine bindings with SimpleBindings, but this massively degrades script compilation performance, because the engine will then create new GraalJSBindings + context per compilation.
Solution?
Synchronize on the context here
graaljs/graal-js/src/com.oracle.truffle.js.scriptengine/src/com/oracle/truffle/js/scriptengine/GraalJSScriptEngine.java
Line 462 in 39b63b9
graaljs/graal-js/src/com.oracle.truffle.js.scriptengine/src/com/oracle/truffle/js/scriptengine/GraalJSScriptEngine.java
Line 680 in 39b63b9
Maybe additional synchronization here would fix performance issues from 2):
graaljs/graal-js/src/com.oracle.truffle.js.scriptengine/src/com/oracle/truffle/js/scriptengine/GraalJSBindings.java
Lines 88 to 92 in 39b63b9
The text was updated successfully, but these errors were encountered: