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