RFR: 8316694: Implement relocation of nmethod within CodeCache [v24]

Chad Rakoczy duke at openjdk.org
Tue Jun 17 20:29:39 UTC 2025


On Tue, 17 Jun 2025 04:08:18 GMT, Dean Long <dlong at openjdk.org> wrote:

>> Isn't this logic only required because of Graal (JDK-8358096)?  For HotSpot, there should always be a trampoline if one is needed [1], even taking into account possible nmethod relocation, because MacroAssembler::trampoline_call() uses is_always_within_branch_range(), which makes its decision based only on the codecache size, boundaries, and the target, not the address of the call site.
>> Further, my understanding is that the Graal vs HotSpot issue is because Graal uses the A64 ISA "hard" limit reachability limit, while HotSpot uses a "soft" limit thanks to this constant with a lower value for debug:
>> 
>>   static const uint64_t branch_range = NOT_DEBUG(128 * M) DEBUG_ONLY(2 * M);
>> 
>> [1] By "needed" here, I mean the hard A64 ISA limit.  It might be useful to have a version of reachable_from_branch_at() that used the hard limit when working with JVMCI-generate code, because ca
>> 
>>> So it is incorrectly updating the offset when it needs to stay the same.
>> 
>> I don't understand what exactly is going with that, but after working on JDK-8321509, I wouldn't be surprised if there were assumptions that break when trying relocate, and you indeed might need to move the logic up a level, or even take into account what type of relocation it is, or the fact that the source is a finalized nmethod and not a BufferBlob.
>
> I took another look, and I think the problem with CallRelocation::fix_relocation_after_move() is the ambiguity of "destination" for a trampoline call.  There is the near instruction destination inside the same nmethod, and there is the effective final far destination contained in the trampoline stub.  For nmethod to nmethod relocation, I think you want a customized version of this function instead of trying to use it as-is.  The customized version could continue to use the near destination, but fixed up with new_addr_for, or maybe simpler would be to use the final far destination, which is always going to be outside the nmethod if you clear inline caches first, which I think you would need to do, otherwise recursive self calls to the Java method would not get relocated correctly.

> Isn't this logic only required because of Graal (JDK-8358096)?

I think it is needed for HotSpot as well. Just because a trampoline was generated for a call does mean it is being used. We still need this check in the event that there is a direct call that no longer reaches.

> For nmethod to nmethod relocation, I think you want a customized version of this function instead of trying to use it as-is.

I moved this logic to [CallRelocation::fix_relocation_after_move()](https://github.com/chadrako/jdk/blob/03bfce8779a0f9c9a2c276fc6cf084698e6725d7/src/hotspot/share/code/relocInfo.cpp#L373-L402). It first checks if the destination is within the source and also check if the call is too far.

> otherwise recursive self calls to the Java method would not get relocated correctly

What do you mean by this? I don't see how recursive calls would behave differently. There is a check for intra-nmethod calls which I think would cover this case

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/23573#discussion_r2153109852


More information about the hotspot-compiler-dev mailing list