RFR: 8280872: Reorder code cache segments to improve code density [v2]

Evgeny Astigeevich duke at openjdk.java.net
Mon Feb 28 18:52:18 UTC 2022


On Wed, 23 Feb 2022 21:52:11 GMT, Boris Ulasevich <bulasevich at openjdk.org> wrote:

>> Currently the codecache segment order is [non-nmethod, non-profiled, profiled]. With this change we move the non-nmethod segment between two code segments. It changes nothing for any platform besides AARCH.
>> 
>> In AARCH the offset limit for a branch instruction is 128MB. The bigger jumps are encoded with three instructions. Most of far branches are jumps into the non-nmethod blobs. With the non-nmethod segment in between code segments the jump distance from method to the stub becomes shorter. The result is a 4% reduction in generated code size for the CodeCache range from 128MB to 240MB.
>> 
>> As a side effect, the performance of some tests is slightly improved:
>> ``ArraysFill.testCharFill      10  thrpt   15  170235.720 -> 178477.212  ops/ms``
>> 
>> Testing: jdk/hotspot jtreg and microbenchmarks on AMD and AARCH
>
> Boris Ulasevich has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains two commits:
> 
>  - fix name: is_non_nmethod, adding target_needs_far_branch func
>  - change codecache segments order: nonprofiled-nonmethod-profiled
>    increase far jump threshold: sideof(codecache)=128M -> sizeof(nonprofiled+nonmethod)=128M

src/hotspot/cpu/aarch64/icBuffer_aarch64.cpp line 55:

> 53:   Label l;
> 54:   __ ldr(rscratch2, l);
> 55:   __ far_jump(ExternalAddress(entry_point), NULL, rscratch1, true);

This complicates `assemble_ic_buffer_code`. You need to know `far_jump` implementation, especially the generation of  NOPs. I understand why we need those NOPs.
Do we have calls of non-nmethod code here?

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp line 393:

> 391:   assert(CodeCache::find_blob(entry.target()) != NULL,
> 392:          "destination of far call not found in code cache");
> 393:   assert(CodeCache::is_non_nmethod(entry.target()), "must be a call to the code stub");

This restricts far calls to be calls of non-nmethod code.

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp line 4379:

> 4377:       postcond(pc() == badAddress);
> 4378:       return NULL;
> 4379:     }

I believe replacing `trampoline_call` by `far_call` should be a separate PR.

src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp line 533:

> 531:   address stub = NULL;
> 532: 
> 533:   if (a.codecache_branch_needs_far_jump()

I prefer it to be `a.target_needs_far_jump(dest)`. `codecache_branch` looks like code cache  branches need far jumps. It is strange because the code cache is just a storage. It is the code generator has to use far jumps.

src/hotspot/share/code/codeCache.cpp line 898:

> 896: }
> 897: 
> 898: size_t CodeCache::max_distance_to_codestub() {

`max_distance_to_non_nmethod_heap`?
As this is public API, it sounds strange without the start point.
If someone changes positions of the heap, would it work as expected?

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

PR: https://git.openjdk.java.net/jdk/pull/7517


More information about the hotspot-dev mailing list