JDK-8336906 : C2: assert(bb->is_reachable()) failed: getting result from unreachable basicblock
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 11,17,21,22,23,24,25,26
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2024-07-22
  • Updated: 2025-06-06
  • Resolved: 2025-05-14
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 25
25 b23Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
I would appreciate some credit in the PR, I spent many hours extracting this test from a collection of class files. The original reproducer only reproduced on M1, now it reproduces everywhere, including my x64 machine.

We have a Test.jasm with two classes A.java and B.java.

We hit a deoptimization in the "getstatic" in Test.test. It has reason "null_assert_or_unreached0". This assumes that "A.val" is null, and because it is not, we trap. In this trap, the "VerifyStack" somehow looks beyond the "return" opcode, and finds unreachable code there. That triggers the assert.

I could reproduce it with JDK24-JDK11. Did not manage it with JDK8 though.

Luckily, the assert happens in the section of Deoptimization::unpack_frames  that is under the not-product flag VerifyStack. Product does not seem to be affected.

It looks similar to JDK-8074292, but I'm not convinced yet that it is a duplicate.

I reproduce it like this:

java -jar ~/Documents/asmtools-7.0-build/release/lib/asmtools.jar jasm Test.jasm
javac *.java

/oracle-work/jdk-22.0.1/fastdebug/bin/java -XX:+VerifyStack -XX:+TraceDeoptimization -XX:+PrintDeoptimizationDetails -Xbatch -XX:+TraceOopMapRewrites "-XX:CompileCommand=print,st::test" "-XX:CompileCommand=compileonly,Test::test" "-XX:CompileCommand=print,Test::test" -Xcomp Test


....
UNCOMMON TRAP method=Test.test()Ljava/lang/Object;  bci=3 pc=0x00007f487c7e01f0, relative_pc=0x0000000000000050, debug_id=0 compiler=c2 compile_id=2 (@0x00007f487c7e01f0) thread=772160 reason=null_assert_or_unreached0 action=make_not_entrant unloaded_class_index=-1 debug_id=0
DEOPT PACKING thread=0x00007f488c02bf00 vframeArray=0x00007f488c2a1610
   Compiled frame (sp=0x00007f48926c5900 unextended sp=0x00007f48926c5900, fp=0x00000000c6b025b7, real_fp=0x00007f48926c5920, pc=0x00007f487c7e01f0)
     nmethod142    2       4       Test::test (5 bytes)
   Virtual frames (innermost/newest first):
      VFrame 0 (0x00007f488c02f3d0) - Test.test()Ljava/lang/Object; - areturn @ bci=3 

DEOPT UNPACKING thread=0x00007f488c02bf00 vframeArray=0x00007f488c2a1610 mode=2
   Virtual frames (outermost/oldest first):
      VFrame 0 (0x00007f488c2a28f0) - Test.test()Ljava/lang/Object; - areturn @ bci=3 sp=0x00007f48926c58c0
Expressions size: 1
 - Reconstructed expression 0 (OBJECT): B
Locals size: 0
[1. Interpreted Frame]
Interpreted frame (sp=0x00007f48926c58c0 unextended sp=0x00007f48926c58c0, fp=0x00007f48926c5910, real_fp=0x00007f48926c5910, pc=0x00007f487c0c75c0)
~deoptimization entry points  [0x00007f487c0c75c0, 0x00007f487c0cabd8]  13848 bytes
     BufferBlob (0x00007f487c0a6a90) used for Interpreter
 - stack  [0x0000000635812db8]; #0
 - monitor[0x00007f48926c58c8]
 - bcp    [0x00007f480a40035b]; @3
 - locals [0x00007f48926c5918]
 - method [0x00007f480a400360]; static jobject Test.test()
	{method} {0x00007f480a400360} 'test' '()Ljava/lang/Object;' in 'Test'
	bci:    3
	expressions:
	   0 a 'B'{0x0000000635812db8} <0x0000000635812db8>


#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/opt/mach5/mesos/work_dir/slaves/0db9c48f-6638-40d0-9a4b-bd9cc7533eb8-S9823/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/d7a39ecb-8e74-462f-9377-5fdd29fc3ad4/runs/e53d9f60-7204-454a-984d-c6ce345ab850/workspace/open/src/hotspot/share/oops/generateOopMap.cpp:2222), pid=772159, tid=772160
#  assert(bb->is_reachable()) failed: getting result from unreachable basicblock
#
# JRE version: Java(TM) SE Runtime Environment (22.0.1+7) (fastdebug build 22.0.1+7-15)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 22.0.1+7-15, compiled mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0xd7913c]  GenerateOopMap::result_for_basicblock(int)+0xcc
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E" (or dumping to /oracle-work/triage/current/core.772159)
#
# An error report file with more information is saved as:
# /oracle-work/triage/current/hs_err_pid772159.log
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
#
Aborted (core dumped)

Stack trace:

Stack: [0x00007f48925c6000,0x00007f48926c7000],  sp=0x00007f48926c41b0,  free space=1016k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0xd7913c]  GenerateOopMap::result_for_basicblock(int)+0xcc  (generateOopMap.cpp:2222)
V  [libjvm.so+0x148c7d4]  OopMapForCacheEntry::compute_map(Thread*)+0xf4
V  [libjvm.so+0x148dc70]  OopMapCacheEntry::fill(methodHandle const&, int)+0xd0
V  [libjvm.so+0x148e777]  OopMapCache::compute_one_oop_map(methodHandle const&, int, InterpreterOopMap*)+0x67
V  [libjvm.so+0xad7733]  Deoptimization::unpack_frames(JavaThread*, int)+0xb73
v  ~UncommonTrapBlob 0x00007f487c1bffc7
j  Test.test()Ljava/lang/Object;+3
j  Test.main([Ljava/lang/String;)V+20
v  ~StubRoutines::call_stub 0x00007f487c09fd21
V  [libjvm.so+0xe84c79]  JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x4a9
V  [libjvm.so+0xfb9460]  jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, JavaThread*) [clone .constprop.1]+0x360
V  [libjvm.so+0xfbcb63]  jni_CallStaticVoidMethod+0x193
C  [libjli.so+0x39f0]  invokeStaticMainWithArgs+0x70
C  [libjli.so+0x49cd]  JavaMain+0xd9d
C  [libjli.so+0x7ca9]  ThreadJavaMain+0x9
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
v  ~UncommonTrapBlob 0x00007f487c1bff94
j  Test.test()Ljava/lang/Object;+3
j  Test.main([Ljava/lang/String;)V+20
v  ~StubRoutines::call_stub 0x00007f487c09fd21



Comments
Changeset: 97b0dd21 Branch: master Author: Manuel Hässig <mhaessig@openjdk.org> Committer: Tobias Hartmann <thartmann@openjdk.org> Date: 2025-05-14 14:12:10 +0000 URL: https://git.openjdk.org/jdk/commit/97b0dd2167530b3d237e748cd5da0130e38e8af2
14-05-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/25118 Date: 2025-05-08 13:22:55 +0000
08-05-2025

[~chagedorn], I am planning to get this in before the fork.
05-05-2025

I'm deferring this to JDK 26 for now. [~mhassig] if you still plan to get this into JDK 25 before the fork in a month, please re-target again, thanks!
05-05-2025

Unassigning this one, as Monty does not have time for it.
28-03-2025

Assigned it to myself, but giving it to this external contributor to work on: Monty Bichouna<stmontydev@gmail.com>
05-12-2024

I quickly verified [~dlong]'s idea, and added the "areturn" bytecode - it works! We will have to add all such bytecodes, and add tests for all of them. emanuel@emanuel-oracle:/oracle-work/jdk-fork4/open$ git diff diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index cf82ad7c027..bb6259061c7 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -838,6 +838,7 @@ static bool falls_through(Bytecodes::Code bc) { case Bytecodes::_goto: case Bytecodes::_goto_w: case Bytecodes::_athrow: + case Bytecodes::_areturn: return false; default: return true;
23-07-2024

I asked [~dlong] if this is related to JDK-8074292, I quote/paraphrase his answer: They sound very similar, but I think JDK-8074292 requires an asynchronous exception to trigger. For JDK-8336906, is it the deoptimization code that is asking about the unreachable bci, or is it asking about the return right before, and the oopmap code is going past the return? See also 8271055, which sounds like yours. There is a falls_through() function in the JDK-8271055 PR that checks for goto and athrow. If you add all the return bytecodes there, does your test pass?
23-07-2024

ILW = Assert due to unreachable bytecode (only affects debug build), edge case with -XX:+VerifyStack, no known workaround but disable compilation of affected method = MLH = P4
22-07-2024