JDK-8336042 : Caller/callee param size mismatch in deoptimization causes crash
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8,11,17,18,21,23,24,25
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2024-07-10
  • Updated: 2025-04-02
  • Resolved: 2025-03-04
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 21 JDK 24 JDK 25
21.0.8-oracleFixed 24.0.2Fixed 25 b13Fixed
Related Reports
Relates :  
Relates :  
Description
For interpreter frames, the caller contains the locals.  Some platforms also align the callee frame, so they compute locals in layout_activation relative to the caller last_sp and not the callee sender_sp.  When calling certain MethodHandle.linkTo* methods, the interpreter pushes 1 extra trailing arg for the MemberName, which is removed before calling the callee taret method.  However, the interpreter takes the snapshot of last_sp before popping the trailing arg, and the return entry point pops the number of args represented by the resolved method in the constant pool.  This is a synthetic method whose signature includes the MemberName.  The deoptimization code in vframeArray::unpack_to_stack has logic to check has_member_arg() on the resolved target method and make the proper adjustments.  However, the adjustment is missing for the oldest/bottom deoptimized frame, causing the computation of the callee locals based on the caller last_sp to be off by one, allowing the last local to overwrite the bottom of the callee frame (on aarch64 this is the return pc).

Instead of the correct logic for the is_bottom frame, there is code that sets caller_was_method_handle based on if the invoke is invokedynamic or invokehandle.  This code dates back to ricochet frames when there could be an arbitrary mismatch between the arg count of the caller's invoke and the callee.  However, this code fails to take into account all cases of calls to has_member_arg() MH linkTo* intrinsics.

In addition, the last_frame_adjust() logic is also broken.  The adjustment can be done when not needed, and the same caller frame can be adjusted multiple times (every time the callee is deoptimized), resulting in unbounded frame/stack size growth.
Comments
[jdk21u-fix-request] Approval Request from Paul Hohensee Backport for parity with Oracle 21.0.8. Passes tier2 and the new test. Low risk, clean, adds asserts and a minor refactoring to isolate the fix.
02-04-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk21u-dev/pull/1573 Date: 2025-04-02 14:24:43 +0000
02-04-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk24u/pull/156 Date: 2025-03-24 18:45:45 +0000
24-03-2025

Fix Request (JDK 24u) This fix solves an issue leading to a crash during deoptimization. The fix is medium risk but was already thoroughly tested in Oracle JDK 21u and JDK 25. The fix was put into mainline 4 Mar 2025 and was reviewed by Patricio Chilano Mateo, Richard Reingruber, Vladimir Ivanov and Tom Rodriguez. The backport applies cleanly to JDK 24u.
24-03-2025

Sounds good, I'll take care of that.
13-03-2025

Indeed, a backport to JDK21 would be welcome.
13-03-2025

A backport to at least 21 might be a good idea but I think for most of our purposes getting it fixed in master is sufficient. [~ffarquet] Does that seem right to you Francois?
12-03-2025

Changeset: 20ea218c Branch: master Author: Dean Long <dlong@openjdk.org> Date: 2025-03-04 23:10:52 +0000 URL: https://git.openjdk.org/jdk/commit/20ea218ce52f79704445acfe2d4a3dc9d04e86d2
04-03-2025

[~thartmann], it does seem a little on the risky side for proactive backports, but we might consider limited backports as needed, like to fix JDK-8333309 with Graal if they still need to benchmark older releases.
03-03-2025

[~dlong] should this fix be backported or is it too risky?
03-03-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/23557 Date: 2025-02-11 07:59:01 +0000
12-02-2025

While investigating this issue, other potential problems came to light: For invokedynamic/invokehandle, we may need to know if an appendix needs to be added. But this information is not available in the signature from the constant pool. It is only available after the invoke has been resolved. Unfortunately, it seems we can compile an invoke w/o always resolving the constant pool ResolvedMethodEntry/ResolvedIndyEntry. There is a hack in AbstractInterpreter::deopt_continue_after_entry() to call set_num_parameters() on these possibly-unresolved entries. However, if they are unresolved, we can't trust the has_appendix information. With a specially-crafted test, it seems possible to create a linkTo adapter chain that drops an arbitrary number of arguments.
10-01-2025

[~thartmann] Please defer it.
09-10-2024

[~dlong] do you plan to fix this for JDK 24 or should we pro-actively defer?
09-10-2024

Added reproducer test ReadObjectTest.java written by [~never].
10-07-2024

ILW = Crash during stack walking, reproducer test on aarch64, no known workaround but disable compilation of affected method = HLM = P3
10-07-2024