RFR: 8280481: Duplicated stubs to interpreter for static calls

Doug Simon dnsimon at openjdk.org
Wed Jun 12 07:20:28 UTC 2024


On Tue, 30 Aug 2022 09:04:21 GMT, Evgeny Astigeevich <eastigeevich at openjdk.org> wrote:

>>> Hi @eastig , I'd like to ask you how to get the experiment results, aka. `Saved bytes`, `Nmethods with shared stubs`,`Final # of nmethods`. Thank you!
>> 
>> You can get `Final # of nmethods` with `-XX:+PrintCodeCache`.
>> To get `Saved bytes`, `Nmethods with shared stubs` you need to instrument `emit_shared_stubs_to_interp` to count shared stubs and nmethods sharing them.
>
>> Hi @eastig ,
>> I would like to recurring your experimental data and I would be very grateful if you could provide a small patch to help me get the result of `Saved bytes` and `Nmethods with shared stubs`.
>> Thank you!
> 
> 
> diff --git a/src/hotspot/share/asm/codeBuffer.inline.hpp b/src/hotspot/share/asm/codeBuffer.inline.hpp
> index 045cff13f25..9af26730cbd 100644
> --- a/src/hotspot/share/asm/codeBuffer.inline.hpp
> +++ b/src/hotspot/share/asm/codeBuffer.inline.hpp
> @@ -45,6 +45,7 @@ bool emit_shared_stubs_to_interp(CodeBuffer* cb, SharedStubToInterpRequests* sha
>    };
>    shared_stub_to_interp_requests->sort(by_shared_method);
>    MacroAssembler masm(cb);
> +  bool has_shared = false;
>    for (int i = 0; i < shared_stub_to_interp_requests->length();) {
>      address stub = masm.start_a_stub(CompiledStaticCall::to_interp_stub_size());
>      if (stub == NULL) {
> @@ -53,13 +54,22 @@ bool emit_shared_stubs_to_interp(CodeBuffer* cb, SharedStubToInterpRequests* sha
>      }
> 
>      ciMethod* method = shared_stub_to_interp_requests->at(i).shared_method();
> +    int shared = 0;
>      do {
>        address caller_pc = cb->insts_begin() + shared_stub_to_interp_requests->at(i).call_offset();
>        masm.relocate(static_stub_Relocation::spec(caller_pc), relocate_format);
>        ++i;
> +      ++shared;
>      } while (i < shared_stub_to_interp_requests->length() && shared_stub_to_interp_requests->at(i).shared_method() == method);
>      masm.emit_static_call_stub();
>      masm.end_a_stub();
> +    if (UseNewCode && shared > 1) {
> +      has_shared = true;
> +      tty->print_cr("Saved: %d", (shared - 1) * CompiledStaticCall::to_interp_stub_size());
> +    }
> +  }
> +  if (has_shared) {
> +    tty->print_cr("nm_has_shared");
>    }
>    return true;
>  }
> 
> 
> You will need to use `-XX:+UseNewCode` in your runs.
> `grep nm_has_shared  run.log | wc -l` is a number of nmethods having a shared stub.
> `grep Saved: run.log | awk '{print $2}' | grep -o '[0-9]*' | paste -s -d+ - | bc` prints a number of saved bytes.

@eastig as I understand, this optimization is about saving code cache memory. The sharing is within an nmethod, not across nmethods, correct?
I'm trying to prioritize an effort to adopt this optimization in Graal. In addition to the numbers you present for code cache bytes saved in the benchmarks, can you say anything about how much that is relative to the code cache used in the benchmarks?

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

PR Comment: https://git.openjdk.org/jdk/pull/8816#issuecomment-2162285030


More information about the hotspot-compiler-dev mailing list