JDK-8335977 : Deoptimization fails with assert "object should be reallocated already"
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 22,23,24
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2024-07-09
  • Updated: 2024-11-11
  • Resolved: 2024-10-31
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 24
24 b23Fixed
Related Reports
Blocks :  
Blocks :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description
Various stress tests intermittently hit below assert with -XX:+StressUnstableIfTraps (JDK-8335334):

# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/open/src/hotspot/share/runtime/vframeArray.cpp:133), pid=1768113, tid=1768171
#  assert(!value->obj_is_scalar_replaced() || realloc_failures) failed: object should be reallocated already
#
# JRE version: Java(TM) SE Runtime Environment (24.0) (fastdebug build 24-internal-2024-07-08-1313517.tobias.hartmann.jdk2)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 24-internal-2024-07-08-1313517.tobias.hartmann.jdk2, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0x187877c]  vframeArrayElement::fill_in(compiledVFrame*, bool)+0x4ac

Stack: [0x00007fce5ed78000,0x00007fce5ee78000],  sp=0x00007fce5ee72160,  free space=1000k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x187877c]  vframeArrayElement::fill_in(compiledVFrame*, bool)+0x4ac  (vframeArray.cpp:133)
V  [libjvm.so+0x187a326]  vframeArray::fill_in(JavaThread*, int, GrowableArray<compiledVFrame*>*, RegisterMap const*, bool)+0x66  (vframeArray.cpp:533)
V  [libjvm.so+0x187a544]  vframeArray::allocate(JavaThread*, int, GrowableArray<compiledVFrame*>*, RegisterMap*, frame, frame, frame, bool)+0x104  (vframeArray.cpp:520)
V  [libjvm.so+0xabbb5d]  Deoptimization::create_vframeArray(JavaThread*, frame, RegisterMap*, GrowableArray<compiledVFrame*>*, bool)+0x14d  (deoptimization.cpp:1678)
V  [libjvm.so+0xabf465]  Deoptimization::fetch_unroll_info_helper(JavaThread*, int)+0x4f5  (deoptimization.cpp:560)
V  [libjvm.so+0xac08c2]  Deoptimization::uncommon_trap(JavaThread*, int, int)+0x32  (deoptimization.cpp:2598)
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
v  ~UncommonTrapBlob 0x00007fce83e90081
J 22039 c2 jdk.nio.zipfs.ZipFileSystem.iteratorOf(Ljdk/nio/zipfs/ZipPath;Ljava/nio/file/DirectoryStream$Filter;)Ljava/util/Iterator; jdk.zipfs@24-internal (150 bytes) @ 0x00007fce84e23238 [0x00007fce84e20420+0x0000000000002e18]
J 19358 c1 jdk.nio.zipfs.ZipDirectoryStream.iterator()Ljava/util/Iterator; jdk.zipfs@24-internal (73 bytes) @ 0x00007fce7e6c91ac [0x00007fce7e6c9020+0x000000000000018c]
J 19492 c1 java.nio.file.FileTreeWalker$DirectoryNode.<init>(Ljava/nio/file/Path;Ljava/lang/Object;Ljava/nio/file/DirectoryStream;)V java.base@24-internal (30 bytes) @ 0x00007fce7e6cab8c [0x00007fce7e6caa20+0x000000000000016c]
j  java.nio.file.FileTreeWalker.visit(Ljava/nio/file/Path;ZZ)Ljava/nio/file/FileTreeWalker$Event;+184 java.base@24-internal
j  java.nio.file.FileTreeWalker.next()Ljava/nio/file/FileTreeWalker$Event;+134 java.base@24-internal
[...]

And with compiler/codegen/aes/TestAESMain.java:

Stack: [0x0000000171adc000,0x0000000171cdf000],  sp=0x0000000171cdccc0,  free space=2051k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.dylib+0x11303e4]  VMError::report_and_die(int, char const*, char const*, char*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x544  (vframeArray.cpp:133)
V  [libjvm.dylib+0x1130b94]  VMError::report_and_die(Thread*, unsigned int, unsigned char*, void*, void*)+0x0
V  [libjvm.dylib+0x54c850]  print_error_for_unit_test(char const*, char const*, char*)+0x0
V  [libjvm.dylib+0x1119650]  vframeArrayElement::fill_in(compiledVFrame*, bool)+0xc94
V  [libjvm.dylib+0x111ae74]  vframeArray::fill_in(JavaThread*, int, GrowableArray<compiledVFrame*>*, RegisterMap const*, bool)+0x64
V  [libjvm.dylib+0x111adf0]  vframeArray::allocate(JavaThread*, int, GrowableArray<compiledVFrame*>*, RegisterMap*, frame, frame, frame, bool)+0xe8
V  [libjvm.dylib+0x56d068]  Deoptimization::create_vframeArray(JavaThread*, frame, RegisterMap*, GrowableArray<compiledVFrame*>*, bool)+0x178
V  [libjvm.dylib+0x56ad28]  Deoptimization::fetch_unroll_info_helper(JavaThread*, int)+0x61c
V  [libjvm.dylib+0x575dd4]  Deoptimization::uncommon_trap(JavaThread*, int, int)+0xa4
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
v  ~UncommonTrapBlob 0x0000000113cf4fac
J 1439 c2 compiler.codegen.aes.TestAESEncode.run()V (201 bytes) @ 0x00000001143180cc [0x00000001143174c0+0x0000000000000c0c]
j  compiler.codegen.aes.TestAESMain.main([Ljava/lang/String;)V+316
Comments
Changeset: 7d8bd21e Branch: master Author: Cesar Soares Lucas <cslucas@openjdk.org> Date: 2024-10-31 17:11:11 +0000 URL: https://git.openjdk.org/jdk/commit/7d8bd21eb0187647ec574abf4fac4f99c435c60b
31-10-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/21624 Date: 2024-10-21 20:27:10 +0000
21-10-2024

No worries, thanks Cesar for letting us know!
15-10-2024

Thank you for working on reproducing the issue!
14-10-2024

Sorry for the delay getting to this - I was on vacation. I'm starting to investigate this today.
14-10-2024

I closed JDK-8338656 as duplicate of this because it does not reproduce anymore with -XX:-ReduceAllocationMerges. Once the fix is ready, we should verify that it does indeed fix the issue.
16-09-2024

Thanks Tobias! I've just attached another simple reproducer (Test3.java) which does not even require -XX:+DeoptimizeALot which allows us to run the test with a product build since DeoptimzeALot is a debug only flag. When doing so, we get a null pointer access. This could explain the various null pointer sightings we've seen in the recent months. $ java -Xbatch Test3.java $ java -Xbatch -XX:CompileOnly=Test3::test Test3.java Product build output: Exception in thread "main" java.lang.NullPointerException: Cannot read field "i" because "<local2>" is null at Test3.test(Test3.java:19) at Test3.main(Test3.java:11) Debug build fails with: # assert(!value->obj_is_scalar_replaced() || realloc_failures) failed: object should be reallocated already
13-09-2024

Great work Christian!
13-09-2024

Attached a simple reproducer (Test2.java) which does not require mainline changes: $ java -Xbatch -XX:+DeoptimizeALot Test2.java $ java -Xbatch -XX:+DeoptimizeALot -XX:CompileOnly=Test2::test Test2.java
13-09-2024

I was finally able to reproduce this reliably with attached Test.java and my (not yet integrated) -XX:+StressUnstableIfTraps option from JDK-8335334: - Apply prototype patch for JDK-8335334: https://github.com/openjdk/jdk/compare/master...TobiHartmann:jdk:JDK-8335334.diff - Run test with -XX:+UnlockDiagnosticVMOptions -Xbatch -XX:-TieredCompilation -XX:+StressUnstableIfTraps -XX:StressSeed=3066853545 -XX:+TraceDeoptimization -XX:CompileCommand=compileonly,Test::test -XX:CompileCommand=quiet -XX:+PrintCompilation -XX:+PrintInlining Test.java Debug build: UNCOMMON TRAP method=java.lang.String.indexOf(Ljava/lang/String;)I bci=17 pc=0x000078e279160fb8, relative_pc=0x0000000000000938, debug_id=0 compiler=c2 compile_id=84 (@0x000078e279160fb8) thread=823081 reason=unstable_if action=reinterpret unloaded_class_index=-1 debug_id=0 3637 84 Test::test (17 bytes) made not entrant REALLOC OBJECTS in thread 0x000078e27402e180 object <0x000000062c7bfcc8> of type 'java/lang/String'[] allocated (32 bytes) object <0x000000062c7bfce8> of type 'java/lang/String' allocated (24 bytes) # # A fatal error has been detected by the Java Runtime Environment: # # Internal Error (/oracle/jdk2/open/src/hotspot/share/runtime/vframeArray.cpp:133), pid=823080, tid=823081 # assert(!value->obj_is_scalar_replaced() || realloc_failures) failed: object should be reallocated already # # JRE version: Java(TM) SE Runtime Environment (24.0) (fastdebug build 24-internal-2024-09-12-1018311.tobias...) # Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 24-internal-2024-09-12-1018311.tobias..., mixed mode, compressed oops, compressed class ptrs, g1 gc, linux-amd64) # Problematic frame: # V [libjvm.so+0x18a335c] vframeArrayElement::fill_in(compiledVFrame*, bool)+0x4ac Release build: Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.indexOf(int, int)" because "transformation" is null at java.base/javax.crypto.Cipher.tokenizeTransformation(Cipher.java:333) at java.base/javax.crypto.Cipher.getTransforms(Cipher.java:448) at java.base/javax.crypto.Cipher.getInstance(Cipher.java:709) at java.base/javax.crypto.Cipher.getInstance(Cipher.java:645) at Test.test(Test.java:33) at Test.main(Test.java:38) This seems to be a regression from JDK-8287061, -XX:-ReduceAllocationMerges serves as workaround. It's important to add that we've also seen this failure mode with latest JDK mainline without any stress option but could never reproduce (so it's not a false positive).
12-09-2024

Cesar, could you please have a look?
12-09-2024

[Updated] ILW = Assert during deoptimization or incorrect result, intermittent with stress option but reproducible, -XX:-ReduceAllocationMerges = HMM = P2
12-09-2024