Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8318694

[JVMCI] disable can_call_java in most contexts for libjvmci compiler threads

XMLWordPrintable

    • b22

      Because JVMCI is normally just Java code it must be permitted to call into Java code but allowing unrestricted Java up calls from the JIT exposes the compiler thread to potential deadlocks. In particular some of the resolve_or_null style functions expect an exception to be thrown and then caught so that null can be returned instead. When these functions are called in the context of a JIT thread a preallocated exception should be thrown This is controlled by the return value of can_call_java so it currently ends up throwing a real Java exception by calling up into Java for JVMCI threads. For libjvmci we should default to disallowing can_call_java by default with a scoped way to allow it for any special cases that must perform Java upcalls.

      == More Details ==

      The special cases are related to Truffle.

      There is Truffle-specific support in Graal for:
      * optimizing the compilation a Truffle interpreter (as opposed to Truffle compilation of a Truffle guest application)[1].

          V [libjvm.dylib+0x4da488] JavaCallWrapper::JavaCallWrapper(methodHandle const&, Handle, JavaValue*, JavaThread*)+0xa0
          V [libjvm.dylib+0x4db6a0] JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x17c
          V [libjvm.dylib+0x545808] jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, JavaThread*)+0x334
          V [libjvm.dylib+0x549464] jni_CallObjectMethodA+0x104
          C [libjvmcicompiler.dylib+0x16f0bc4] JNIUtil_getClassLoader_762ce5b9b3bb2eebb9cb0d4d86c3d4a172c50752+0xb4
          C [libjvmcicompiler.dylib+0x56858c] FactoryMethodHolder_TruffleFromLibGraalCalls_constructor_5a2a9e771013c34291a2d87afe3ef6481b538ae2_9480e4b8e54413a2af198b3bbbc600d424b94a5c+0x3c
          C [libjvmcicompiler.dylib+0x14af3fc] TruffleHostEnvironment_get_aa74305634256124f50f5409627297cabe4de749+0x1fc
          C [libjvmcicompiler.dylib+0x14aa3e8] HostInliningPhase_run_36e8e7104608f467a8c9df7a6d72bd53d11b7bc9+0xa8
          C [libjvmcicompiler.dylib+0x1271944] BasePhase_apply_44016f05de8431a364e6ea368a1079e364e66586+0x634

      * applying Truffle Partial Evaluation to a constant Truffle AST encountered by the EE inliner during JIT compilation.

          V [libjvm.dylib+0x4da488] JavaCallWrapper::JavaCallWrapper(methodHandle const&, Handle, JavaValue*, JavaThread*)+0xa0
          V [libjvm.dylib+0x4db6a0] JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x17c
          V [libjvm.dylib+0x545808] jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, JavaThread*)+0x334
          V [libjvm.dylib+0x549464] jni_CallObjectMethodA+0x104
          C [libjvmcicompiler.dylib+0x56876c] TruffleFromLibGraalCalls_resolvePeer_506d32be5212a621015d1c71cbcc0de64bde870c+0xbc
          C [libjvmcicompiler.dylib+0x562e98] FactoryMethodHolder_HSTruffleCompilerRuntime_constructor_46ef636baef6c26cc4e37345308b0cd55c826406_6937318ad6cba334a06cb8ed477b862c083f3045+0xc8
          C [libjvmcicompiler.dylib+0x568244] LibGraalTruffleHostEnvironmentLookup_lookup_1c5bf08bbe512ad04d04961796a1a551efb83dad+0xb4
          C [libjvmcicompiler.dylib+0x588bd8] TruffleInliningPolicy_isSpecialCallTarget_3e54990957f0a6c8b7838f9baae23b71b1761cbe+0x138
          C [libjvmcicompiler.dylib+0x1ef410] CallTree_expandCutoffNode_8c75e620d2c889496e3be6e6a6b372f27b6bfb02+0x120

      Both of these cases require being able to call from libgraal into Truffle runtime code running on the Java heap as shown by the partial stack traces above.

      Note that it's still possible in other circumstances for a CompileBroker thread to *want* to make a Java call. For example, LinkResolver::linktime_resolve_virtual_method_or_null is called by both ciEnv and jvmciEnv and will usually raise an exception when linking fails. However, if can_call_java is false for the current thread, a special preallocated exception is thrown instead[3]. libgraal threads should return false for can_call_java in these cases.

      The general idea is to introduce a `bool CompilerThread::_can_call_java` field that is initialized to false except for a jargraal compiler thread.
      There will be a scoping mechanism for temporarily setting this field to true to support the Truffle use cases.

      [1] https://github.com/oracle/graal/blob/master/truffle/docs/HostCompilation.md#host-inlining
      [2] https://github.com/oracle/graal/blob/d5a3b1a6c2cdbbfbeafa61fc567a5fd155a7b2bb/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/host/HostInliningPhase.java#L98
      [3] https://bugs.openjdk.org/browse/JDK-8317953?focusedCommentId=14619346&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14619346

            dnsimon Douglas Simon
            never Tom Rodriguez
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: