JDK-8360219 : [AIX] assert(locals_base >= l2) failed: bad placement
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 25,26
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: aix
  • CPU: ppc
  • Submitted: 2025-06-23
  • Updated: 2025-09-11
  • Resolved: 2025-09-08
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 26
26 b15Fixed
Related Reports
Relates :  
Description
The following issue is seen sometimes on AIX.
It was triggered a few times by test  java/net/httpclient/HttpClientLocalAddrTest.java
(but also once by JCK) .

#  Internal Error (/priv/jenkins/client-home/workspace/openjdk-jdk-aix_ppc64-dbg/jdk/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp:136), pid=14811546, tid=7318
#  assert(locals_base >= l2) failed: bad placement

No context given, using current context.
Native frame:
iar:  0x0900000018735d4c libjvm.so::AixNativeCallstack::print_callstack_for_context(outputStream*, ucontext_t const*, bool, char*, unsigned long)+0x4ec  (C++ uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:5 parmsonstk:1)
lr:   0x09000000184c3b9c libjvm.so::CompressedOops::decode_not_null(narrowOop)+0xbc  (C++ uses_alloca saves_lr stores_bc gpr_saved:2 fixedparms:1 parmsonstk:1)
sp:   0x0000000127308a10 (base - 0x4E78) 
rtoc: 0x08001000a0462420 
|---stackaddr----|   |----lrsave------|:   <function name>
0x0000000127308e00 - 0x09000000187357e4 libjvm.so::os::Aix::platform_print_native_stack(outputStream*, void const*, char*, int, unsigned char*&)+0x24  (C++ uses_alloca saves_lr stores_bc gpr_saved:1 fixedparms:5 parmsonstk:1)
0x0000000127308e80 - 0x0900000018735698 libjvm.so::NativeStackPrinter::print_stack(outputStream*, char*, int, unsigned char*&, bool, int)+0x58  (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:6 fixedparms:7 parmsonstk:1)
0x0000000127308f90 - 0x0900000018eccbf4 libjvm.so::VMError::report(outputStream*, bool)+0x1cf4  (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:2 parmsonstk:1)
0x0000000127309a80 - 0x09000000184a9030 libjvm.so::VMError::report_and_die(int, char const*, char const*, char*, Thread*, unsigned char*, void const*, void const*, char const*, int, unsigned long)+0x870  (C++ uses_alloca saves_lr stores_bc gpr_saved:18 fixedparms:8 parmsonstk:1)
0x0000000127309c60 - 0x09000000184a84e0 libjvm.so::report_vm_error(char const*, int, char const*, char const*, ...)+0xa0  (C++ uses_alloca saves_lr stores_bc gpr_saved:5 fixedparms:4 parmsonstk:1)
0x0000000127309d20 - 0x0900000018edd640 libjvm.so::AbstractInterpreter::layout_activation(Method*, int, int, int, int, int, int, frame*, frame*, bool, bool)+0x580  (C++ uses_alloca saves_cr saves_lr stores_bc gpr_saved:14 fixedparms:8 parmsonstk:1)
0x0000000127309e00 - 0x090000001930b15c libjvm.so::vframeArrayElement::unpack_on_stack(int, int, int, frame*, bool, bool, int)+0x3bc  (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:8 parmsonstk:1)
0x000000012730a820 - 0x090000001930aa8c libjvm.so::vframeArray::unpack_to_stack(frame&, int, int)+0x84c  (C++ fp_present uses_alloca saves_lr stores_bc gpr_saved:18 fixedparms:4 parmsonstk:1)
0x000000012730b3b0 - 0x0900000019309668 libjvm.so::Deoptimization::unpack_frames(JavaThread*, int)+0x188  (C++ uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:2 parmsonstk:1)
0x000000012730bfa0 - 0x0a000100074af9cc (unknown module)::(unknown function)+?
0x000000012730c010 - 0x0a00010007438540 (unknown module)::(unknown function)+?
0x000000012730c110 - 0x0a00010007438540 (unknown module)::(unknown function)+?
0x000000012730c1e0 - 0x0a00010007438540 (unknown module)::(unknown function)+?
0x000000012730c2a0 - 0x0a00010007438540 (unknown module)::(unknown function)+?
0x000000012730c370 - 0x0a00010007438540 (unknown module)::(unknown function)+?
0x000000012730c440 - 0x0a00010007438540 (unknown module)::(unknown function)+?
0x000000012730c510 - 0x0a00010007438540 (unknown module)::(unknown function)+?
0x000000012730c5e0 - 0x0a00010007418708 (unknown module)::(unknown function)+?
0x000000012730c6d0 - 0x0a00010007d75c9c (unknown module)::(unknown function)+?
0x000000012730c7a0 - 0x0a00010007416744 (unknown module)::(unknown function)+?
0x000000012730c850 - 0x0a000100005b1de8 (unknown module)::(unknown function)+?
0x000000012730c970 - 0x0a000100005a4f08 (unknown module)::(unknown function)+?
0x000000012730ca00 - 0x0a000100005a0e04 (unknown module)::(unknown function)+?
0x000000012730ca70 - 0x0a000100007d2478 (unknown module)::(unknown function)+?
0x000000012730cae0 - 0x0a000100007d3bc0 (unknown module)::(unknown function)+?
0x000000012730cb70 - 0x0a000100005a128c (unknown module)::(unknown function)+?
0x000000012730cbf0 - 0x0a00010007cc8c5c (unknown module)::(unknown function)+?
0x000000012730cc90 - 0x0a00010007418708 (unknown module)::(unknown function)+?
0x000000012730cd80 - 0x0a00010007410b84 (unknown module)::(unknown function)+?
0x000000012730cff0 - 0x090000001873bf28 libjvm.so::JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x3a8  (C++ uses_alloca saves_cr saves_lr stores_bc gpr_saved:9 fixedparms:4 parmsonstk:1)
0x000000012730d130 - 0x090000001873f9fc libjvm.so::os::os_exception_wrapper(void (*)(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*), JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x3c  (C++ uses_alloca saves_lr stores_bc gpr_saved:1 fixedparms:5 parmsonstk:1)
0x000000012730d1b0 - 0x09000000185ba044 libjvm.so::JavaCalls::call_virtual(JavaValue*, Klass*, Symbol*, Symbol*, JavaCallArguments*, JavaThread*)+0x1a4  (C++ fp_present uses_alloca saves_lr stores_bc gpr_saved:9 fixedparms:6 parmsonstk:1)
0x000000012730d300 - 0x09000000185b9df8 libjvm.so::JavaCalls::call_virtual(JavaValue*, Handle, Klass*, Symbol*, Symbol*, JavaThread*)+0x78  (C++ uses_alloca saves_lr stores_bc gpr_saved:2 fixedparms:6 parmsonstk:1)
0x000000012730d400 - 0x09000000197f35c8 libjvm.so::thread_entry(JavaThread*, JavaThread*)+0xe8  (C++ uses_alloca saves_lr stores_bc gpr_saved:3 fixedparms:2 parmsonstk:1)
0x000000012730d4e0 - 0x0900000018724700 libjvm.so::JavaThread::thread_main_inner()+0x220  (C++ uses_alloca saves_lr stores_bc gpr_saved:4 fixedparms:1 parmsonstk:1)
0x000000012730d5b0 - 0x0900000018722794 libjvm.so::JavaThread::run()+0x214  (C++ uses_alloca saves_lr stores_bc gpr_saved:5 fixedparms:1 parmsonstk:1)
0x000000012730d650 - 0x090000001858f128 libjvm.so::Thread::call_run()+0x128  (C++ uses_alloca saves_lr stores_bc gpr_saved:3 fixedparms:1 parmsonstk:1)
0x000000012730d6e0 - 0x090000001858e3ec libjvm.so::thread_native_entry(Thread*)+0x20c  (C++ uses_alloca saves_lr stores_bc gpr_saved:8 fixedparms:1 parmsonstk:1)
0x000000012730d7a0 - 0x090000000056204c libpthreads.a::_pthread_body+0xec  (C saves_lr stores_bc gpr_saved:1 fixedparms:1 )
0x000000012730d820 - 0x0000000000000000 
*** end of backchain ***
-----------------------
Comments
Changeset: bea2b029 Branch: master Author: Richard Reingruber <rrich@openjdk.org> Date: 2025-09-08 08:30:03 +0000 URL: https://git.openjdk.org/jdk/commit/bea2b029a77e126171d17c3a44baec6d5cafed4a
08-09-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/26643 Date: 2025-08-05 14:53:30 +0000
06-08-2025

According to the data from the dbg output there seems to be an overlap of locals array and caller's abi: Local 3 overlaps with abi slot 13: &locals[3] = locals_base - 3*8 = 0x12202c5e8 &caller_abi[13] = (uintptr)caller->sp() + 13*8 = 0x12202c5e8 The failing assertion assumes that in an i2c transition the interpreted caller keeps its frame::top_ijava_frame_abi (in an i2i call it would be trimmed to frame::parent_ijava_frame_abi)[1][2][3]. But this assumption does not hold if caller/callee are thawed from stackChunkOops. There the interpreted caller is thawed with frame::java_abi [4] and it is not changed when the compiled callee is thawed [5]. Because of [6] and since only parent_ijava_frame_abi is used while the caller frame isn't the top frame there is no actual overlap of the locals array and the used abi. [1] Interpreter keeps top_ijava_frame_abi https://github.com/openjdk/jdk/blob/67ba8b45dd632c40d5e6872d2a6ce24f86c22152/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp#L1217C60-L1217C91 [2] i2c changes the caller only if the callee expects stack arguments https://github.com/openjdk/jdk/blob/ba0ae4cb28aa520d5244077349e35ef1bb475b61/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp#L1107 [3] Comment in pr that suggests that the caller keeps top_ijava_frame_abi in an i2c call https://github.com/openjdk/jdk/pull/23557#issuecomment-2662835374 [4] Interpreter frames are thawed with frame::java_abi https://github.com/reinrich/jdk/blob/f5aa4477654d4e2ccc7122ad6f343e5e1224421b/src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp#L405 [5] Compiled frame is thawed without changing the callers abi size https://github.com/reinrich/jdk/blob/f5aa4477654d4e2ccc7122ad6f343e5e1224421b/src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp#L474 [6] frame::java_abi and frame::parent_ijava_frame_abi are equal in size https://github.com/reinrich/jdk/blob/f5aa4477654d4e2ccc7122ad6f343e5e1224421b/src/hotspot/cpu/ppc/frame_ppc.hpp#L191 === Dbg output from attached add_dbg_output.patch locals_base:0x000000012202c600 l2:0x000000012202c608 is_top_frame:0 is_bottom_frame:1 method->max_locals():4 caller_actual_parameters:2 frame::top_ijava_frame_abi_size=112 frame::parent_ijava_frame_abi_size=32 caller->interpreter_frame_esp():0x000000012202c5f0 caller->sp():0x000000012202c580 caller: Interpreted frame (sp=0x000000012202c580 unextended sp=0x000000012202c5b0, fp=0x000000012202c670, real_fp=0x000000012202c670, pc=0x0a00010007418408) ~return entry points [0x0a00010007417540, 0x0a00010007418f30] 6640 bytes BufferBlob (0x0a00010007417088) used for Interpreter - local [0x00000000fafdeea0]; #0 - local [0x00000000fcee30e0]; #1 - local [0x0000000000000000]; #2 - local [0x0000000000000000]; #3 - stack [0x00000000fcee30e0]; #1 - stack [0x00000000fafdeea0]; #0 - monitor[0x000000012202c608] - bcp [0x0a0001009025e88e]; @14 - locals [0x000000012202c6a8] - method [0x0a0001009025e8e8]; virtual void java.io.PrintStream.println(jobject) Bytecodes of interpreted caller: javap -p -l -c java.io.PrintStream public void println(java.lang.String); Code: 0: aload_0 1: invokevirtual #184 // Method java/lang/Object.getClass:()Ljava/lang/Class; 4: ldc #10 // class java/io/PrintStream 6: if_acmpne 20 9: aload_0 10: aload_1 11: invokestatic #180 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; => 14: invokevirtual #190 // Method writeln:(Ljava/lang/String;)V 17: goto 43 ...
06-08-2025

AbstractInterpreter::layout_activation() is called with is_top_frame == true for the *youngest* frame as this comment explains: https://github.com/openjdk/jdk/blob/fe7ec312590ed9f70e6caad4ef454123138bbbcf/src/hotspot/share/runtime/vframeArray.cpp#L602-L603 The following comment contradicts this and is wrong. It should be fixed too. https://github.com/openjdk/jdk/blob/fe7ec312590ed9f70e6caad4ef454123138bbbcf/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp#L102-L103 See also https://github.com/openjdk/jdk/pull/23557#issuecomment-2662835374
23-06-2025

In the PR of JDK-8336042 ( [~dlong] ) there was already a bit of discussion about the assertion. Thanks to [~rrich] for pointing this out.
23-06-2025