RFR: 8285487: Do not generate trampolines for runtime calls if they are not needed [v3]
Vladimir Kozlov
kvn at openjdk.java.net
Fri Apr 29 19:35:47 UTC 2022
On Fri, 29 Apr 2022 15:06:20 GMT, Evgeny Astigeevich <duke at openjdk.java.net> wrote:
>> src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp line 579:
>>
>>> 577: // when a new callee address out of 128M range.
>>> 578: bool need_trampoline = (entry.rspec().type() == relocInfo::runtime_call_type) ?
>>> 579: target_needs_far_branch(entry.target()) : far_branches();
>>
>> This is all very confusing too. Can't `target_needs_far_branch()` handle all cases? So we don't need a conditional expression here.
>
> I'll update `MacroAssembler::trampoline_call` doc when it should be used. All runtime calls into `CodeCache` must use `far_call`. `far_call` is more compact and faster vs `trampoline_call`:
> far call:
>
> adrp
> add
> blr
>
> trampoline call:
>
> bl trampoline
> trampoline:
> ldr [embedded]
> br
> embedded:
> 8 bytes of target address
>
>
> What do you think?
To be clear. `relocInfo::runtime_call_type` is used for stubs calls which are inside CodeCache and for VM runtime calls which are outside CodeCache. Depending on call's distance you can use all 3 types of instruction for all cases - even VM runtime method could be near CodeCache so you can use "near" call. So when you are asking what type of call should be generated you can get all 3 answers.
The optimization is that for other calls (inside CodeCache) you need only 2 types of call: far and near. And `MacroAssembler::far_call()` handles it correctly.
Back to `trampoline_call()` function.
1. The header comment is incorrect: "If the code cache is small trampolines won't be emitted."
2. New `assert(CodeCache::contains(entry.target())` is wrong.
3. I would like to know why `trampoline_call()` could be used for `relocInfo::virtual_call_type` and `relocInfo::opt_virtual_call_type` (based on assert). They should be inside CodeCache and you don't need trampoline for it. Right? Unless you generate code outside CodeCache.
4. I don't understand how call to trampoline is handled (lines 603-607) they do not reference `stub` value returned by `emit_trampoline_stub()`. Why not use `far_call()` to call trampoline code?
5. `target_needs_far_branch()` works only inside CodeCache. You need separate `target_needs_trampoline()` for `relocInfo::runtime_call_type`. New method should check distance to target vs CodeCache boundaries like we do for x86: https://github.com/openjdk/jdk/blob/master/src/hotspot/cpu/x86/assembler_x86.cpp#L11701
I think the code could be like this:
if (entry.rspec().type() != relocInfo::runtime_call_type ||
CodeCache::find_blob(entry.target()) != NULL) {
// Call inside CodeCache
far_call(entry, cbuf, rscratch1);
return pc();
}
if (target_needs_trampoline(entry)) { // Check distance from CodeCache
// Generate trampoline to call outside CodeCache
stub = emit_trampoline_stub();
// Call to trampoline
far_call(stub, cbuf, rscratch1);
} else {
// Far call outside CodeCache.
// Near call can't be used because generated code could be posted in any place in CodeCache when installed.
adrp
add
blr
}
return pc();
-------------
PR: https://git.openjdk.java.net/jdk/pull/8403
More information about the hotspot-dev
mailing list