JDK-8316422 : TestIntegerUnsignedDivMod.java triggers "invalid layout" assert in FrameValues::validate
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u341,11,17,21,22
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2023-09-18
  • Updated: 2023-12-04
  • Resolved: 2023-11-29
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 22
22 b26Fixed
Related Reports
Relates :  
Relates :  
Description
Running compiler/intrinsics/TestIntegerUnsignedDivMod.java with '-Xcomp -XX:TieredStopAtLevel=1 -XX:+DeoptimizeALot -XX:+VerifyStack' triggers the following failure:

DEOPT PACKING thread=0x00007ffb3002be60 vframeArray=0x00007ffb304c9c20
   Deoptimized frame (sp=0x00007ffb36410280 unextended sp=0x00007ffb36410280, fp=0x00007ffb36410848, real_fp=0x00007ffb36410370, pc=0x00007ffb2dd6a277)
     nmethod  39602 3890   !   1       compiler.intrinsics.TestIntegerUnsignedDivMod::testDivModUnsigned (44 bytes)
   Virtual frames (innermost/newest first):
      VFrame 0 (0x00007ffb304f0660) - java.lang.Integer.divideUnsigned(II)I - ldiv @ bci=8 
      VFrame 1 (0x00007ffb304f1a00) - compiler.intrinsics.TestIntegerUnsignedDivMod.divmod(III)V - invokestatic @ bci=7 
      VFrame 2 (0x00007ffb304f2d48) - compiler.intrinsics.TestIntegerUnsignedDivMod.testDivModUnsigned()V - invokevirtual @ bci=24 

Deoptimizing method containing inlining
DEOPT UNPACKING thread=0x00007ffb3002be60 vframeArray=0x00007ffb304c9c20 mode=1
   Virtual frames (outermost/oldest first):
      VFrame 2 (0x00007ffb304cafe0) - compiler.intrinsics.TestIntegerUnsignedDivMod.testDivModUnsigned()V - invokevirtual @ bci=24 sp=0x00007ffb364102e0
      VFrame 1 (0x00007ffb304caf70) - compiler.intrinsics.TestIntegerUnsignedDivMod.divmod(III)V - invokestatic @ bci=7 sp=0x00007ffb36410278
      VFrame 0 (0x00007ffb304caf00) - java.lang.Integer.divideUnsigned(II)I - ldiv @ bci=8 sp=0x00007ffb36410220

overlapping storage
 0x00007ffb36410280: 0x0000000000000000 stack 0
 0x00007ffb36410280: 0x0000000000000000 local 0
overlapping storage
 0x00007ffb36410278: 0x0000000000000000 stack 1
 0x00007ffb36410278: 0x0000000000000000 local 1

# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/workspace/open/src/hotspot/share/runtime/frame.cpp:1574), pid=1408068, tid=1408069
#  assert(!error) failed: invalid layout
#
# JRE version: Java(TM) SE Runtime Environment (22.0+16) (fastdebug build 22-ea+16-1189)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 22-ea+16-1189, compiled mode, emulated-client, sharing, tiered, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0xc0716c]  FrameValues::validate()+0x1cc

Stack: [0x00007fb622e16000,0x00007fb622f17000],  sp=0x00007fb622f11da0,  free space=1007k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0xc0716c]  FrameValues::validate()+0x1cc  (frame.cpp:1574)
V  [libjvm.so+0xec2a11]  JavaThread::print_frame_layout(int, bool)+0x121  (javaThread.cpp:1903)
V  [libjvm.so+0xad6374]  Deoptimization::unpack_frames(JavaThread*, int)+0x194  (javaThread.hpp:959)
v  ~DeoptimizationBlob 0x00007fb61cb6a906
j  java.lang.Integer.divideUnsigned(II)I+8 java.base@22-ea
j  compiler.intrinsics.TestIntegerUnsignedDivMod.divmod(III)V+7
j  compiler.intrinsics.TestIntegerUnsignedDivMod.testDivModUnsigned()V+24
Comments
Changeset: 5e1b771a Author: Dean Long <dlong@openjdk.org> Date: 2023-11-29 03:06:32 +0000 URL: https://git.openjdk.org/jdk/commit/5e1b771a19962042a0020a9148e94e14d63025ee
29-11-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/16297 Date: 2023-10-20 21:58:06 +0000
20-10-2023

I took another look at c2, and in add_safepoint_edges() it does appear that it does zero stack slots and local slots for both the top frame and caller frames, but it does not truncate like c1.
19-10-2023

Thanks Tom, that makes sense. We could have compute_debug_info_for_scope() detect this, by doing the same thing VerifyStack does and check the stack size vs OopMapCache::compute_one_oop_map, but I think it would be simpler for EmptyExceptionState to zero out stack/lock slots instead of truncating. That way compute_debug_info_for_scope() can trust what it is given and it will still set an illegal value if it sees a null pointer. If the only way to detect this problem is with VerifyStack, then I could argue that this state is actually OK and VerifyStack could be adjusted to allow it. However, I suspect that with the right dtrace/jfr/JVMTI events enabled, we could possibly hit a safepoint along the unwind path, so we actually need these slots. And if external event handlers can run, those handlers could try to look at the stack values, so I would argue that zeroing them is not correct either. Also, I couldn't find c2 doing the same zeroing for caller exception states. So I'm leaning towards preserving expression stack values and zeroing dead locals instead of truncating.
19-10-2023

The local removal is special. The debug info generation automatically generates empty debug for all required locals if the ValueStack doesn't have any. Look in LinearScan::compute_debug_info_for_scope at the EmptyExceptionState case. It simply adds the required number of locals as illegal. This is what I was suggesting for the non-empty stack case but you'd have remember how deep the stack should be to inject the correct number of values or compute it in some fashion.
18-10-2023

Now I'm wondering why we aren't also hitting this assert from vframeArrayElement::on_stack_size(): assert(method()->max_locals() == locals()->size(), "just checking"); because it looks like c1 will also remove the locals from the exception state, at least in some cases.
18-10-2023

Great, thanks a lot Dean. Feel free to adjust ILW/priority accordingly.
09-10-2023

I have experimental code that I believe will fix this.
06-10-2023

Thanks for all the feedback, I'm definitely lacking some expertise in exception handling to move forward with this. I also need to work on other things and will therefore put this aside for now. [~dlong], feel free to pick this up. Or maybe [~roland] remembers some details from JDK-6986046?
06-10-2023

Can't we just truncate the exception state to this? --> Test::test@8 (line 11) Locals - l0: stack[136] - l1: empty Or does the exception state represent where it is thrown, not where it is caught?
30-09-2023

I think it would be ok to make the contents of the expression stack in the caller into illegal or T_CONFLICT since their contents are dead but it does seem like C1 should be describing the stack depth correctly for the caller frames. If the ValueStack kept track of the actual stack depth for the exception state, then LinearScan::compute_debug_info_for_scope could properly fill the expression stack with _illegal_value as it does for locals in the case of EmptyExceptionState. That would avoid perturbing the contents of the ValueStack itself. It does seem like some asserts during debug info construction could have caught this. There were various attempts to statically verify debug info and I don't remember the state of it but verifying the stack depth of caller frames seems like a clear and simple thing to check.
22-09-2023

It looks like the problem was introduced by JDK-6986046, but I can't tell if it was intentional or not. The comment only mentions clearing out locals, not the expression stack.
21-09-2023

It's normal to empty the expression stack at a throw point so why would this particular case somehow be wrong? Doesn't this imply that all uses of exception_state are somehow wrong? That seems impossible. It seems like a problem that the layout print is ignoring the actual top of the expression stack in favor of the InterpreterOopMap. Notice that even in the interpreter description the stack is actually empty but it's still printing stack elements. 0x00007f134af94368: 0x00007f134af94368 interpreter_frame_initial_sp unextended_sp for #1 sp for #1 0x00007f134af94360: 0x00007f134100ac8c expression stack for #1 stack 0 0x00007f134af94358: 0x00007f134100ad0f stack 1 0x00007f134af94350: 0x00007f134af943b0 stack 2 0x00007f134af94348: 0x00007f134402a5c0 stack 3 sp is before the purported first stack trace element which indicates that they have been popped off. Looking at the debug info again, it seems like all expression stacks have been cleared but only the top expression stack should be. So it's emitting this: PcDesc(pc=0x00007f21fd1f4d22 offset=e2 bits=0): Test::div@2 (line 23) Locals - l0: empty - l1: empty - l2: empty - l3: empty Test::divZero@6 (line 19) Test::test@8 (line 11) Locals - l0: stack[124] - l1: empty and the full state is PcDesc(pc=0x00007f21fd1f4d22 offset=ea bits=0): Test::div@2 (line 23) Locals - l0: 0 - l1: 0 - l2: 0 - l3: 0 Expression stack - @0: 0 - @1: 0 - @2: 0 - @3: 0 Test::divZero@6 (line 19) Expression stack - @0: 0 - @1: stack[120],long Test::test@8 (line 11) Locals - l0: stack[136] - l1: empty but the proper exception state would have an empty stack in div and a non-empty one in divZero. PcDesc(pc=0x00007f21fd1f4d22 offset=ea bits=0): Test::div@2 (line 23) Locals - l0: 0 - l1: 0 - l2: 0 - l3: 0 Test::divZero@6 (line 19) Expression stack - @0: 0 - @1: stack[120],long Test::test@8 (line 11) Locals - l0: stack[136] - l1: empty So the question is why is the callers expression stack cleared? This is definitely an invalid deopt state. I thought there was some logic to detect these kind of problem during debug info construction?
21-09-2023

Thanks for looking at this, Tom and Dean! > I don't see how the expression stack of div should have any effect on this layout unless some code is consulting the wrong method. [~never] The interpreter frame is created based on the _expressions size that comes directly from the compiledVFrame, i.e. from the PcDesc in C1 compiled code, see https://github.com/openjdk/jdk/blob/master/src/hotspot/share/runtime/vframeArray.cpp#L282 and https://github.com/openjdk/jdk/blob/8661b8e11568f752c0bc515a028092f77bcaf940/src/hotspot/share/runtime/vframeArray.cpp#L146 > You might execute this code only in the interpreter and print the interpreter frame layout when the exception is thrown to see what it really should look like. I attached the printed frames: (1) Failing case: frame_failing.txt (2) Interpreter only: frame_interpreter.txt (3) Using state_before in C1: frame_full_state.txt As expected, (2) and (3) are equivalent. The relevant difference between (1) and (2) is: expression stack for #2 locals for #1 stack 0 local 0 stack 1 local 1 local 2 local 3 expression stack for #2 stack 0 stack 1 locals for #1 local 0 local 1 local 2 local 3 > The value of unextended_sp for #3 also doesn't seem right. I think it's supposed to point after the last non-parameter expression stack value. I think the code is simply ignoring the expression stack depth for some reason. I think it's correct. At least it's the same in the interpreter-only run. > As an aside, the expression stack isn't empty because there are no handlers but because throwing conceptually clears the expression stack so that it can redirect control flow. Exception handlers implicitly have the thrown exception on the top of stack so it must be empty prior to that otherwise it would never be clear what the contents of the stack are. Makes sense, thanks for the explanation. > It computes mask.expression_stack_size() from the bytecodes rather than trusting what is in the interpreter frame, so this is incompatible with the C1 exception state used to layout the divZero frame. [~dlong] Right, that's in-line with my understanding: The interpreter frame is created based on the debug information provided by C1 and the result is not equivalent to how the interpreter execution would have done it.
21-09-2023

I think the main problem is the way frame:describe determines the number of stack expressions: // Compute the actual expression stack size InterpreterOopMap mask; OopMapCache::compute_one_oop_map(methodHandle(Thread::current(), m), bci, &mask); It computes mask.expression_stack_size() from the bytecodes rather than trusting what is in the interpreter frame, so this is incompatible with the C1 exception state used to layout the divZero frame.
21-09-2023

I don't see how the expression stack of div should have any effect on this layout unless some code is consulting the wrong method. The locals of div should be allocated just after the expression stack of divZero since that's how the interpreter execution would have done it. At the div call site in divZero there would be 3 longs on the expression stack before the call and the last 2 longs become the locals of div. The expression stack values passed as parameters simply become the local space of the callee and the caller frame is expanded to include space for the non-parameter locals. The value of unextended_sp for #3 also doesn't seem right. I think it's supposed to point after the last non-parameter expression stack value. I think the code is simply ignoring the expression stack depth for some reason. You might execute this code only in the interpreter and print the interpreter frame layout when the exception is thrown to see what it really should look like. As an aside, the expression stack isn't empty because there are no handlers but because throwing conceptually clears the expression stack so that it can redirect control flow. Exception handlers implicitly have the thrown exception on the top of stack so it must be empty prior to that otherwise it would never be clear what the contents of the stack are.
19-09-2023

We deopt due to an ArithmeticException (division by zero) from 'Test::div' via the throw_div0_exception stub: ;; DivByZeroStub slow case 0x00007f21fd1f4d1d: callq 0x00007f21fd038bc0 ; ImmutableOopMap {rax=Oop } ;*ldiv {reexecute=0 rethrow=0 return_oop=0} ; - Test::div@2 (line 23) ; - Test::divZero@6 (line 19) ; - Test::test@8 (line 11) ; {runtime_call throw_div0_exception Runtime1 stub} 0x00007f21fd1f4d22: movabs $0x7f2208bbb725,%rdi ; {external_word} Corresponding debug info: PcDesc(pc=0x00007f21fd1f4d22 offset=e2 bits=0): Test::div@2 (line 23) Locals - l0: empty - l1: empty - l2: empty - l3: empty Test::divZero@6 (line 19) Test::test@8 (line 11) Locals - l0: stack[124] - l1: empty C1 omits the expression stacks in the PcDesc because they are not part of the exception_state(): https://github.com/openjdk/jdk/blob/8661b8e11568f752c0bc515a028092f77bcaf940/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp#L492 https://github.com/openjdk/jdk/blob/8661b8e11568f752c0bc515a028092f77bcaf940/src/hotspot/share/c1/c1_LIRGenerator.cpp#L458 This is because neither 'div' nor 'divZero' have an exception handler and therefore the stack values can't be live/observed. Full locals/stack information would look like this: PcDesc(pc=0x00007f21fd1f4d22 offset=ea bits=0): Test::div@2 (line 23) Locals - l0: 0 - l1: 0 - l2: 0 - l3: 0 Expression stack - @0: 0 - @1: 0 - @2: 0 - @3: 0 Test::divZero@6 (line 19) Expression stack - @0: 0 - @1: stack[120],long Test::test@8 (line 11) Locals - l0: stack[136] - l1: empty We then assert during deoptimization because the expression stack for the 'divZero' method overlaps with locals for the callee method 'div'. As I understand, that's because in vframeArrayElement::unpack_on_stack -> Interpreter::layout_activation, the size of the stack of the interpreter frame is set according to expressions()->size() which is 0 for (see below) because stack values are omitted. Deoptimizing method containing inlining DEOPT UNPACKING thread=0x00007f220002bc40 vframeArray=0x00007f2200a2da90 mode=1 Virtual frames (outermost/oldest first): VFrame 2 (0x00007f2200a2ee50) - Test.test()V - invokestatic @ bci=8 sp=0x00007f2207012448 Expressions size: 0 Locals size: 2 - Reconstructed local 0 (INT): 20 [1. Interpreted Frame] Interpreted frame (sp=0x00007f2207012448 unextended sp=0x00007f2207012448, fp=0x00007f2207012490, real_fp=0x00007f2207012490, pc=0x00007f21fd008112) ~return entry points [0x00007f21fd007da0, 0x00007f21fd008648] 2216 bytes BufferBlob (0x00007f21fd007a90) used for Interpreter - local [0xdeaddeaf00000014]; #0 - local [0x0000000000000000]; #1 - monitor[0x00007f2207012448] - bcp [0x00007f21d4ea0378]; @8 - locals [0x00007f22070124a8] - method [0x00007f21d4ea03a0]; static void Test.test() {method} {0x00007f21d4ea03a0} 'test' '()V' in 'Test' bci: 8 locals: 0 20 (int) 0,000000 (float) 14 (hex) 0 (long) 0,000000000000000e+00 (double) 0x0000000000000000 (longhex) 1 0 (int) 0,000000 (float) 0 (hex) VFrame 1 (0x00007f2200a2ede0) - Test.divZero()V - invokestatic @ bci=6 sp=0x00007f22070123d0 Expressions size: 0 Locals size: 0 [2. Interpreted Frame] Interpreted frame (sp=0x00007f22070123d0 unextended sp=0x00007f22070123d0, fp=0x00007f2207012438, real_fp=0x00007f2207012438, pc=0x00007f21fd0081f0) ~return entry points [0x00007f21fd007da0, 0x00007f21fd008648] 2216 bytes BufferBlob (0x00007f21fd007a90) used for Interpreter - stack [0x0000000000000014]; #3 - stack [0x0000000000000000]; #2 - stack [0x0000000000000000]; #1 - stack [0x00000005eb64de38]; #0 - monitor[0x00007f22070123f0] - bcp [0x00007f21d4ea0466]; @6 - locals [0x00007f2207012440] - method [0x00007f21d4ea0478]; static void Test.divZero() {method} {0x00007f21d4ea0478} 'divZero' '()V' in 'Test' bci: 6 expressions: 0 -345711048 (int) -276684485249000640805339136,000000 (float) eb64de38 (hex) 0 (long) 0,000000000000000e+00 (double) 0x0000000000000000 (longhex) 1 0 (int) 0,000000 (float) 0 (hex) VFrame 0 (0x00007f2200a2ed70) - Test.div(JJ)J - ldiv @ bci=2 sp=0x00007f2207012378 Expressions size: 0 Locals size: 4 [3. Interpreted Frame] Interpreted frame (sp=0x00007f2207012378 unextended sp=0x00007f2207012378, fp=0x00007f22070123c0, real_fp=0x00007f22070123c0, pc=0x00007f21fd00ac60) ~exception handling [0x00007f21fd00ac60, 0x00007f21fd00beb0] 4688 bytes BufferBlob (0x00007f21fd007a90) used for Interpreter - local [0x0000000000000000]; #0 - local [0x0000000000000000]; #1 - local [0x0000000000000000]; #2 - local [0x0000000000000000]; #3 - monitor[0x00007f2207012378] - bcp [0x00007f21d4ea0522]; @2 - locals [0x00007f22070123e8] - method [0x00007f21d4ea0528]; static jlong Test.div(jlong, jlong) {method} {0x00007f21d4ea0528} 'div' '(JJ)J' in 'Test' bci: 2 locals: 0 0 (int) 0,000000 (float) 0 (hex) 0 (long) 0,000000000000000e+00 (double) 0x0000000000000000 (longhex) 1 0 (int) 0,000000 (float) 0 (hex) 0 (long) 0,000000000000000e+00 (double) 0x0000000000000000 (longhex) 2 0 (int) 0,000000 (float) 0 (hex) 0 (long) 0,000000000000000e+00 (double) 0x0000000000000000 (longhex) 3 0 (int) 0,000000 (float) 0 (hex) expressions: 0 0 (int) 0,000000 (float) 0 (hex) 0 (long) 0,000000000000000e+00 (double) 0x0000000000000000 (longhex) 1 0 (int) 0,000000 (float) 0 (hex) 0 (long) 0,000000000000000e+00 (double) 0x0000000000000000 (longhex) 2 0 (int) 0,000000 (float) 0 (hex) 0 (long) 0,000000000000000e+00 (double) 0x0000000000000000 (longhex) 3 0 (int) 0,000000 (float) 0 (hex) The interpreter frames then look like this: 0x00007f2207012438: 0x00007f2207012490 #3 method Test.divZero()V @ 6 - 0 locals 7 max stack - codelet: return entry points saved fp 0x00007f2207012430: 0x00007f2207012448 interpreter_frame_sender_sp 0x00007f2207012428: 0x00007f22070123d0 interpreter_frame_last_sp 0x00007f2207012420: 0x00007f21d4ea0478 interpreter_frame_method 0x00007f2207012418: 0x00000005eb633d50 interpreter_frame_mirror oop for #3 0x00007f2207012410: 0x00007f21d4ea02c0 interpreter_frame_mdp 0x00007f2207012408: 0x00007f21d4ea0688 interpreter_frame_cache 0x00007f2207012400: 0x0000000000000001 interpreter_frame_locals 0x00007f22070123f8: 0x00007f21d4ea0466 interpreter_frame_bcp 0x00007f22070123f0: 0x00007f22070123f0 interpreter_frame_initial_sp 0x00007f22070123e8: 0x0000000000000000 expression stack for #3 locals for #2 stack 0 local 0 0x00007f22070123e0: 0x0000000000000000 stack 1 local 1 0x00007f22070123d8: 0x0000000000000000 local 2 0x00007f22070123d0: 0x0000000000000000 local 3 unextended_sp for #3 sp for #3 0x00007f22070123c8: 0x00007f21fd0081f0 return address 0x00007f22070123c0: 0x00007f2207012438 #2 method Test.div(JJ)J @ 2 - 4 locals 5 max stack - codelet: exception handling saved fp 0x00007f22070123b8: 0x00007f22070123d0 interpreter_frame_sender_sp 0x00007f22070123b0: 0x00007f2207012378 interpreter_frame_last_sp 0x00007f22070123a8: 0x00007f21d4ea0528 interpreter_frame_method 0x00007f22070123a0: 0x00000005eb633d50 interpreter_frame_mirror oop for #2 0x00007f2207012398: 0x00007f220948f000 interpreter_frame_mdp 0x00007f2207012390: 0x00007f21d4ea0688 interpreter_frame_cache 0x00007f2207012388: 0x0000000000000005 interpreter_frame_locals 0x00007f2207012380: 0x00007f21d4ea0522 interpreter_frame_bcp 0x00007f2207012378: 0x00007f2207012378 #1 <DeoptimizationBlob> interpreter_frame_initial_sp unextended_sp for #2 sp for #2 0x00007f2207012370: 0x00007f21fd00ac60 expression stack for #2 stack 0 0x00007f2207012368: 0x00007f22070123c0 stack 1 0x00007f2207012360: 0x0000000000000000 stack 2 0x00007f2207012358: 0x0000000000000000 stack 3 Triggering the assert: overlapping storage 0x00007f22070123e8: 0x0000000000000000 stack 0 owner = 3 0x00007f22070123e8: 0x0000000000000000 local 0 owner = 2 overlapping storage 0x00007f22070123e0: 0x0000000000000000 stack 1 owner = 3 0x00007f22070123e0: 0x0000000000000000 local 1 owner = 2 [~never], you seem to have added that verification code with JDK-7009361, any thoughts? Using the full state would "fix" it: --- a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp @@ -489,7 +489,8 @@ void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) { CallingConvention* cc = frame_map()->c_calling_convention(&signature); // check for division by zero (destroys registers of right operand!) - CodeEmitInfo* info = state_for(x); + CodeEmitInfo* info = state_for(x, x->state_before());
19-09-2023

Attached simple Test.java reproduces this: java -Xcomp -XX:TieredStopAtLevel=1 -XX:+DeoptimizeALot -XX:+VerifyStack -XX:CompileCommand=compileonly,Test::test Test.java overlapping storage 0x00007fc615ec03e8: 0x0000000000000000 stack 0 0x00007fc615ec03e8: 0x0000000000000000 local 0 overlapping storage 0x00007fc615ec03e0: 0x0000000000000000 stack 1 0x00007fc615ec03e0: 0x0000000000000000 local 1 # # A fatal error has been detected by the Java Runtime Environment: # # Internal Error (/oracle/jdk/open/src/hotspot/share/runtime/frame.cpp:1565), pid=1016244, tid=1016245 # assert(!error) failed: invalid layout # # JRE version: Java(TM) SE Runtime Environment (22.0) (fastdebug build 22-internal-2023-08-07-1346088.tobias...) # Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 22-internal-2023-08-07-1346088.tobias..., compiled mode, emulated-client, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64) # Problematic frame: # V [libjvm.so+0xc0486c] FrameValues::validate()+0x1cc This is an old issue and already reproduces with JDK 1.8.0_391.
19-09-2023

ILW = Invalid frame layout during deoptimization from C1 compiled code (looks like false positive), single test with -XX:+DeoptimizeALot -XX:+VerifyStack, no workaround but disable compilation of affected method = MLH = P4
19-09-2023