JDK-8076227 : Cleanup unused method invocation logic
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9,10
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2015-03-30
  • Updated: 2021-04-27
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.
Related Reports
Relates :  
Currently, the VM treats method handle call sites in a special way. As a method handle is assumed to change the SP of its caller, the caller's SP is saved to a convenient location (e.g., a callee-saved register). The special treatment of method handle invocations adds complexity to the VM, as not only call sites, but also deoptimization handlers and stack walking must distinguish method handle call sites from other call sites.

JDK-8068945 investigated this issue on x86. Method handle invocations do not alter the SP of their caller, therefore saving/restoring the SP can be disabled on x86.

The goal of this enhancement is to investigate the way method handle invocations work on all other supported platforms. If method handle invocations do not change their caller's SP on any supported platform, the special treatment of method handle invocations can be removed that will result in somewhat simplified VM code.

It is general issue. Will work on it when have time.

I plan to first investigate the different calling sequences and will then inform you on what I think could be done.

In the interpreter, if a call to M is replaced by a call to M', the SP will change if the transition from M to M' adds or deletes an argument. So the interpreter needs this sort of thing. (The indy and invokehandle instructions add an argument. The MH.linkTo* methods delete an argument. All argument changes are currently at the right hand side of the argument list, i.e, the top of the interpreter stack.) In the compiler, these effects are muted, and perhaps non-existent, since the compiler can pre-allocate argument storage for the larger of the argument lists. The MH.linkTo* methods are designed to allow argument dropping simply by changing view points (no instructions execute). One place to look carefully: If compiled code calls the interpreter, and the interpreter adjusts the argument list before entry to an interpreted method (via a MH.linkTo*), it is possible that the return to the compiled code will get a bad SP. But this seems unlikely, since C2I adapters already take care to restore stack pointers (I think���check this). (In the interpreter, SP is saved and restored with care everywhere (I think). The main problem with interpreter SP logic is that outgoing arguments are not properly handed over to the callee. The stack walking code pretends that the caller's SP is "extended" into the locals area of the callee. This is a useless and dangerous fiction, since the callee takes over the argument list and (often) reuses it for local storage; in general the callee can store completely independent data values in that storage (changing oops to ints and vice versa). The runtime has a concept of "unextended SP" which is the correct concept that we should be using.) So, the SP-saving protocol might be useless for compiled code. There are two residual reasons for keeping the saved SP in compiled code. First, it could be demoted to asserts optionally inserted in a debugging mode, to make sure that the existing logic (which is excessively complex) preserves the SP on return. There is logic for this under -XX:+VerifyStackAtCalls which we should maintain. But that option uses a mark word of 0xbadb100d instead of a saved SP. Should we use both? Unclear. Second, a SP-saving protocol would be useful in the future for tail call elimination. If a series of tail calls begins at some point, the SP needs to be saved so that the eventual return will restore the stack correctly, even after some callees have expanded it. But it seems likely that such a mechanism is better implemented using a separate, small stack frame between the caller and the series of tail-callees.

Did this enhancement come out of a discussion with John? I wanted to remove that logic for quite some time now but John said there might be a future use of it. [~jrose], is that still the case?