JDK-8191227 : Unsafe handle resolution in ConstantOopWriteValue::write_on() / print_on() and LIR_Assembler::jobject2reg()
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8,9,10
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2017-11-14
  • Updated: 2020-02-26
  • Resolved: 2017-11-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10 Other
10 b36Fixed openjdk8u252Fixed
Related Reports
Blocks :  
Relates :  
Description
There's an assert in ConstantOopWriteValue::write_on() which does JNIHandles::resolve(). The problem is current thread is compiler thread and it isn't in VM (but in native) at that moment. So, it's unsafe to resolve a handle and access the naked oop.

void ConstantOopWriteValue::write_on(DebugInfoWriteStream* stream) {
  assert(JNIHandles::resolve(value()) == NULL ||
         Universe::heap()->is_in_reserved(JNIHandles::resolve(value())),
         "Should be in heap");
  stream->write_int(CONSTANT_OOP_CODE);
  stream->write_handle(value());
}

Original report:
http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2017-November/027546.html
Comments
Fix Request (8u) This fixes the corner case with accessing naked oops that breaks some GCs (notably Shenandoah 8u). Patch applies with reshuffling and minor reapplies. 8u RFR (reviewed by andrew): https://mail.openjdk.java.net/pipermail/jdk8u-dev/2020-February/011202.html
20-02-2020

RFR - http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2017-November/027675.html webrev - http://cr.openjdk.java.net/~rraghavan/8191227/webrev.02/
23-11-2017

These failures happen because JVMCI compiler already transitioned the thread into VM state. So, either ThreadInVMfromUnknown or equivalent of GUARDED_VM_QUICK_ENTRY() from ciEnv should fix it. If you choose ThreadInVMfromUnknown, please, add a comment describing that in case of JVMCI, the thread is already in VM state.
22-11-2017

Notes - 1. got following type failures - # Internal Error (/scratch/opt/mach5/mesos/work_dir..../open/src/hotspot/share/runtime/interfaceSupport.hpp:181), pid=17494, tid=17495 # assert(thread->thread_state() == _thread_in_native) failed: coming from wrong thread state for tests - - compiler/jvmci/errors/TestInvalidDebugInfo.java,[,tier1,tier2],[linux-x64-debug,macosx-x64-debug,solaris-sparcv9-debug,windows-x64-debug] - compiler/aot/RecompilationTest.java,[,tier1,tier2],[linux-x64-debug,macosx-x64-debug,windows-x64-debug] etc. with the earlier mentioned possible fix in comments - https://bugs.openjdk.java.net/browse/JDK-8191227?focusedCommentId=14130874&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14130874 (fix using ThreadInVMfromNative) 2. So In place of 'ThreadInVMfromNative', tried to use 'ThreadInVMfromUnknown' to fix the issue!! e.g.: http://cr.openjdk.java.net/~rraghavan/8191227/webrev.01/ (testing in progress, no issues so far)
22-11-2017

This could lead to instability and unlucky crashes in testing, so you really should fix this sooner rather than later.
16-11-2017

ILW = possible failures due to unsafe handle resolution; only in debug builds; no workaround = MLH = P4
15-11-2017

Possible fix: diff --git a/src/hotspot/share/code/debugInfo.cpp b/src/hotspot/share/code/debugInfo.cpp --- a/src/hotspot/share/code/debugInfo.cpp +++ b/src/hotspot/share/code/debugInfo.cpp @@ -28,6 +28,8 @@ #include "code/nmethod.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" +#include "runtime/interfaceSupport.hpp" +#include "runtime/thread.hpp" // Constructors @@ -209,9 +211,13 @@ // ConstantOopWriteValue void ConstantOopWriteValue::write_on(DebugInfoWriteStream* stream) { - assert(JNIHandles::resolve(value()) == NULL || - Universe::heap()->is_in_reserved(JNIHandles::resolve(value())), - "Should be in heap"); +#ifdef ASSERT + { ThreadInVMfromNative tiv(JavaThread::current()); + assert(JNIHandles::resolve(value()) == NULL || + Universe::heap()->is_in_reserved(JNIHandles::resolve(value())), + "Should be in heap"); + } +#endif stream->write_int(CONSTANT_OOP_CODE); stream->write_handle(value()); }
14-11-2017