JDK-8287061 : Support for rematerializing scalar replaced objects participating in allocation merges
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 17,19,21,22
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2022-05-20
  • Updated: 2024-10-01
  • Resolved: 2023-07-17
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 b07Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
After allocation merges are "simplified" from the IR graph and the merged objects are scalar replaced we need a way to rematerialize the scalarized objects when/if the execution executes a trap.

As suggested in this thread (https://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2022-April/055256.html) we might be able to do this using a similar mechanism as used by SafePointScalarObjectNode.
Comments
IMO refactoring get_int to return the "correct" value independent of big/little endian would be ideal. There `(jint)*((jint*)&val)` is scattered all over the code base. However, there are some places where the current behavior of get_int is expected (or doesn't matter) and that would need to be taken into account. That being said, I'm fine with just adding a `get_jint` as you suggested - but I'm not a reviewer and unfortunately, I can't test the patch on a BigEndian machine.
24-07-2023

> Probably some helper method would be helpful , maybe something like StackValue.get_jint() that does what is done in the patch? I agree.
21-07-2023

Probably some helper method would be helpful , maybe something like StackValue.get_jint() that does what is done in the patch?
21-07-2023

Yeah, I agree, it seems that `jint selector = (jint)*((jint*)&val);` is necessary to make the code portable.
20-07-2023

The following might be a fix modified src/hotspot/share/code/debugInfo.cpp @@ -242,7 +242,9 @@ void ObjectValue::print_fields_on(outputStream* st) const { // of the object. ObjectValue* ObjectMergeValue::select(frame& fr, RegisterMap& reg_map) { StackValue* sv_selector = StackValue::create_stack_value(&fr, &reg_map, _selector); - jint selector = sv_selector->get_int(); + intptr_t val = sv_selector->get_int(); + jint selector = (jint)*((jint*)&val); + I couldn't reproduce the issue with it. Will do more testing... See also https://github.com/openjdk/jdk/blob/8d29329138d44800ee4c0c02dacc01a06097de66/src/hotspot/share/runtime/deoptimization.cpp#L1358-L1391 https://github.com/openjdk/jdk/blob/8d29329138d44800ee4c0c02dacc01a06097de66/src/hotspot/share/runtime/deoptimization.cpp#L1489-L1519
20-07-2023

Selector after deserializing is always -559030609. That's 0xDEADDEAF ``` _selector is location: 1 _selector is constant_int: 0 _selector -> stack[64] ``` I guess the right data is at stack[64] + 4 on big endian systems. Likely the location type is int_in_long. I wonder how StackValue::create_stack_value is supposed to work for int_in_long on big endian. Maybe was never reached so far? EDIT: location type seems to be Location::normal + tty->print_cr("_selector location type: %d",((LocationValue *)_selector)->location().type()); prints _selector location type: 1 I don't understand how handling of Location::normal in create_stack_value() https://github.com/openjdk/jdk/blob/94eb44b192ba421692549a178c386ea34164ea50/src/hotspot/share/runtime/stackValue.cpp#L208-L213 is supposed to work with StackValue::get_int() https://github.com/openjdk/jdk/blob/94eb44b192ba421692549a178c386ea34164ea50/src/hotspot/share/runtime/stackValue.hpp#L82-L85 get_int() will always return a result that contains DEADDEAF
20-07-2023

This is the output of 3 crashes: https://cr.openjdk.org/~rrich/tmp/8287061/traces.zip
20-07-2023

This should help to rule out some issues: https://gist.github.com/JohnTortugo/5efef342fa2b5b712abeed461f9dbec8
20-07-2023

Hi Cesar, this is likely an endianess issue. We can reproduce it on big endian systems (AIX, Linux/PPC64, Linux/S390). Could you provide a patch that we can apply to produce the output you're interested in? Thanks, Richard.
19-07-2023

Thanks for reporting this and sorry for the trouble. Unfortunately, I don't have access right now to an AIX system to debug this. I'll try to reproduce it in another system. In the meantime could you please try: 1) to print _selector right before it's used on line 263 and let me know what you get? 2) What's the value of the selector before serialization (https://github.com/openjdk/jdk/blob/master/src/hotspot/share/opto/output.cpp#L782)?
19-07-2023

Looks like the crash on AIX happens at https://github.com/openjdk/jdk/blob/master/src/hotspot/share/code/debugInfo.cpp#L263 (at least this is what gdb tells me). _selected = (ObjectValue*) _possible_objects.at(selector); where _possible_objects is the GrowableArray that seems to cause the assertion above : # assert(0 <= i && i < _len) failed: illegal index With an enhanced assertion in growableArray.hpp I get : # # Internal Error (/jdk/src/hotspot/share/utilities/growableArray.hpp:145), pid=20185428, tid=258 # assert(0 <= i && i < _len) failed: illegal index -559030609, 2 accessible elements # so we are badly out of bounds.
19-07-2023

After JDK-8287061 has been pushed, we run on AIX (btw. big-endian platform) into various crashes that look a bit related. Example vmTestbase/vm/mlvm/meth/stress/compiler/sequences/Test.java opt : # # SIGSEGV (0xb) at pc=0x090000000447705c, pid=9503064, tid=14393 # # Problematic frame: # V [libjvm.so+0x2c005c] ObjectMergeValue::select(frame&, RegisterMap&)+0x60 --------------- T H R E A D --------------- Current thread (0x000000011bd43480): JavaThread "Thread-31" [_thread_in_Java, id=14393, stack(0x000000011bd50000,0x000000011bf5d888) (2102K)] Stack: [0x000000011bd50000,0x000000011bf5d888], sp=0x000000011bf5b370, free space=2092k Native frame: iar: 0x090000000447705c libjvm.so::ObjectMergeValue::select(frame&, RegisterMap&)+0x60 (C++ fp_present uses_alloca saves_lr stores_bc gpr_saved:6 fixedparms:3 parmsonstk:1) lr: 0x0900000004477040 libjvm.so::ObjectMergeValue::select(frame&, RegisterMap&)+0x44 (C++ fp_present uses_alloca saves_lr stores_bc gpr_saved:6 fixedparms:3 parmsonstk:1) sp: 0x000000011bf5b370 (base - 0x2518) rtoc: 0x08001000a018d068 |---stackaddr----| |----lrsave------|: <function name> 0x000000011bf5b420 - 0x0900000004476e3c libjvm.so::ScopeDesc::objects_to_rematerialize(frame&, RegisterMap&)+0x130 (C++ fp_present uses_alloca saves_lr stores_bc gpr_saved:9 fixedparms:3 parmsonstk:1) 0x000000011bf5b4e0 - 0x0900000004476598 libjvm.so::rematerialize_objects(JavaThread*, int, CompiledMethod*, frame&, RegisterMap&, GrowableArray<compiledVFrame*>*, bool&)+0xa8 (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:7 parmsonstk:1) 0x000000011bf5b6e0 - 0x0900000004c81ae4 libjvm.so::Deoptimization::fetch_unroll_info_helper(JavaThread*, int)+0x2d0 (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:2 parmsonstk:1) 0x000000011bf5c680 - 0x0900000004c85dc4 libjvm.so::Deoptimization::uncommon_trap(JavaThread*, int, int)+0x50 (C++ uses_alloca saves_lr stores_bc gpr_saved:4 fixedparms:3 parmsonstk:1) 0x000000011bf5c750 - 0x0a00010007415b5c (unknown module)::(unknown function)+? 0x000000011bf5c7c0 - 0x0a00010007c56260 (unknown module)::(unknown function)+? 0x000000011bf5c820 - 0x0a000100074187b0 (unknown module)::(unknown function)+? 0x000000011bf5c900 - 0x0a000100074184cc (unknown module)::(unknown function)+? 0x000000011bf5c9a0 - 0x0a000100074184cc (unknown module)::(unknown function)+? 0x000000011bf5ca60 - 0x0a000100074184cc (unknown module)::(unknown function)+? 0x000000011bf5cbc0 - 0x0a000100074185b0 (unknown module)::(unknown function)+? 0x000000011bf5cc70 - 0x0a000100074187b0 (unknown module)::(unknown function)+? 0x000000011bf5cd20 - 0x0a00010007418e70 (unknown module)::(unknown function)+? 0x000000011bf5cdb0 - 0x0a000100074187b0 (unknown module)::(unknown function)+? 0x000000011bf5ce50 - 0x0a000100074108cc (unknown module)::(unknown function)+? 0x000000011bf5cfd0 - 0x0900000004247d34 libjvm.so::JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x36c (C++ uses_alloca saves_cr saves_lr stores_bc gpr_saved:12 fixedparms:4 parmsonstk:1) 0x000000011bf5d120 - 0x09000000042d095c 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) 0x000000011bf5d1a0 - 0x0900000004242de4 libjvm.so::JavaCalls::call_virtual(JavaValue*, Klass*, Symbol*, Symbol*, JavaCallArguments*, JavaThread*)+0x190 (C++ fp_present uses_alloca saves_lr stores_bc gpr_saved:7 fixedparms:6 parmsonstk:1) 0x000000011bf5d2e0 - 0x0900000004242bbc libjvm.so::JavaCalls::call_virtual(JavaValue*, Handle, Klass*, Symbol*, Symbol*, JavaThread*)+0x74 (C++ uses_alloca saves_lr stores_bc gpr_saved:2 fixedparms:6 parmsonstk:1) 0x000000011bf5d3e0 - 0x0900000004de7250 libjvm.so::thread_entry(JavaThread*, JavaThread*)+0xbc (C++ uses_alloca saves_lr stores_bc gpr_saved:3 fixedparms:2 parmsonstk:1) 0x000000011bf5d4c0 - 0x0900000004406b84 libjvm.so::JavaThread::thread_main_inner()+0xf4 (C++ uses_alloca saves_lr stores_bc gpr_saved:7 fixedparms:1 parmsonstk:1) 0x000000011bf5d5a0 - 0x09000000044055bc libjvm.so::JavaThread::run()+0xa0 (C++ uses_alloca saves_lr stores_bc gpr_saved:2 fixedparms:1 parmsonstk:1) 0x000000011bf5d620 - 0x090000000434a548 libjvm.so::Thread::call_run()+0xfc (C++ uses_alloca saves_lr stores_bc gpr_saved:4 fixedparms:1 parmsonstk:1) 0x000000011bf5d6d0 - 0x0900000004349cec libjvm.so::thread_native_entry(Thread*)+0x178 (C++ uses_alloca saves_lr stores_bc gpr_saved:9 fixedparms:1 parmsonstk:1) 0x000000011bf5d7a0 - 0x090000000056204c libpthreads.a::_pthread_body+0xec (C saves_lr stores_bc gpr_saved:1 fixedparms:1 ) 0x000000011bf5d820 - 0x0000000000000000 *** end of backchain *** ----------------------- fastdebug shows an assertion (but has also ObjectMergeValue::select in the backtrace): # Internal Error (/rs6000_64/jdk-dev/src/hotspot/share/utilities/growableArray.hpp:145), pid=17039618, tid=6683 # assert(0 <= i && i < _len) failed: illegal index # --------------- T H R E A D --------------- Current thread (0x0000000118a056b0): JavaThread "Thread-2" [_thread_in_Java, id=6683, stack(0x0000000118c50000,0x0000000118e6d888) (2166K)] Stack: [0x0000000118c50000,0x0000000118e6d888], sp=0x0000000118e6afe0, free space=2155k No context given, using current context. Native frame: iar: 0x0900000009e80dfc libjvm.so::AixNativeCallstack::print_callstack_for_context(outputStream*, ucontext_t const*, bool, char*, unsigned long)+0x4d4 (C++ uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:5 parmsonstk:1) lr: 0x0000000118e6a520 (unknown module)::(unknown function)+? sp: 0x0000000118e6a2a0 (base - 0x35E8) rtoc: 0x08001000a03c41f0 |---stackaddr----| |----lrsave------|: <function name> 0x0000000118e6a690 - 0x0900000009e808b4 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) 0x0000000118e6a710 - 0x0900000009973820 libjvm.so::VMError::report(outputStream*, bool)+0x1b7c (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:2 parmsonstk:1) 0x0000000118e6aff0 - 0x0900000009965dc8 libjvm.so::VMError::report_and_die(int, char const*, char const*, char*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x7cc (C++ uses_alloca saves_lr stores_bc gpr_saved:18 fixedparms:8 parmsonstk:1) 0x0000000118e6b1e0 - 0x09000000099655b0 libjvm.so::VMError::report_and_die(Thread*, void*, char const*, int, char const*, char const*, char*)+0x58 (C++ uses_alloca saves_lr stores_bc gpr_saved:2 fixedparms:7 parmsonstk:1) 0x0000000118e6b280 - 0x0900000009965290 libjvm.so::report_vm_error(char const*, int, char const*, char const*, ...)+0x8c (C++ uses_alloca saves_lr stores_bc gpr_saved:5 fixedparms:4 parmsonstk:1) 0x0000000118e6b320 - 0x0900000009c8162c libjvm.so::ObjectMergeValue::select(frame&, RegisterMap&)+0x294 (C++ fp_present uses_alloca saves_lr stores_bc gpr_saved:11 fixedparms:3 parmsonstk:1) 0x0000000118e6b3f0 - 0x0900000009c81140 libjvm.so::ScopeDesc::objects_to_rematerialize(frame&, RegisterMap&)+0x214 (C++ fp_present uses_alloca saves_lr stores_bc gpr_saved:9 fixedparms:3 parmsonstk:1) 0x0000000118e6b4b0 - 0x0900000009c8038c libjvm.so::rematerialize_objects(JavaThread*, int, CompiledMethod*, frame&, RegisterMap&, GrowableArray<compiledVFrame*>*, bool&)+0xfc (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:7 parmsonstk:1) 0x0000000118e6b6f0 - 0x090000000a9cf88c libjvm.so::Deoptimization::fetch_unroll_info_helper(JavaThread*, int)+0x458 (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:2 parmsonstk:1) 0x0000000118e6c6f0 - 0x090000000a9d5f10 libjvm.so::Deoptimization::uncommon_trap(JavaThread*, int, int)+0x4c (C++ uses_alloca saves_lr stores_bc gpr_saved:4 fixedparms:3 parmsonstk:1) 0x0000000118e6c7c0 - 0x0a0001000752a2f4 (unknown module)::(unknown function)+? 0x0000000118e6c830 - 0x0a00010007c8cc04 (unknown module)::(unknown function)+?
19-07-2023

Changeset: a53345ad Author: Cesar Soares Lucas <cslucas@openjdk.org> Committer: Vladimir Kozlov <kvn@openjdk.org> Date: 2023-07-17 23:01:35 +0000 URL: https://git.openjdk.org/jdk/commit/a53345ad03e07ab2a990721a506ebc25eed0f7c9
17-07-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/12897 Date: 2023-03-07 01:40:48 +0000
07-03-2023