RFR: 8341127: Extra call to MethodHandle::asType from memory segment var handles fails to inline

Maurizio Cimadamore mcimadamore at openjdk.org
Tue Oct 1 10:14:09 UTC 2024


On Tue, 1 Oct 2024 10:08:54 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

> The fix for JDK-8331865 introduced an accidental performance regression.
> The main issue is that now *all* memory segment var handles go through some round of adaptation.
> Adapting a var handle results in a so called *indirect* var handle.
> When an indirect var handle is called through a *var handle guard*, an extra `MethodHandle::asType` call is triggered.
> In some cases, if `asType` has already been compiled into a big method, it cannot be inlined into the caller, which then results in a failure to inline through the var handle call, resulting in a big performance regression.
> 
> The solution is to make sure that the compiled size of `MethodHandle::asType` stays small: this is done by making sure that the slowpath (the one which populates the cache used by `asType`) is not inlined by the JVM. This is done by consolidating the slow path into a separate method, which is annotated with the internal `@DontInline` annotation.

test/micro/org/openjdk/bench/java/lang/foreign/LoopOverNonConstantAsType.java line 57:

> 55: @State(org.openjdk.jmh.annotations.Scope.Thread)
> 56: @OutputTimeUnit(TimeUnit.MILLISECONDS)
> 57: @Fork(value = 3, jvmArgsAppend = { "-XX:-TieredCompilation" })

The benchmark only reproduces if tiered compilation is disabled. This is due to the fact that some threshold are updated accordingly, and set to a smaller value, which is enough to exhibit the issue.

test/micro/org/openjdk/bench/java/lang/foreign/LoopOverNonConstantAsType.java line 96:

> 94:     static {
> 95:         types = new Class<?>[TYPE_SIZE];
> 96:         ClassLoader customLoader = new URLClassLoader(new URL[0], LoopOverNonConstantAsType.class.getClassLoader());

Technically, using a different class loadrer is not required - but using classes with different class loaders can end up taking even longer code paths when calling `MethodHandle::asType`, so I've added that here.

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

PR Review Comment: https://git.openjdk.org/jdk/pull/21283#discussion_r1782505769
PR Review Comment: https://git.openjdk.org/jdk/pull/21283#discussion_r1782504664


More information about the core-libs-dev mailing list