RFR: 8339358: Optimize TypeKind#from

ExE Boss duke at openjdk.org
Sun Sep 1 23:34:57 UTC 2024


On Thu, 29 Aug 2024 05:34:37 GMT, Shaojin Wen <swen at openjdk.org> wrote:

> TypeKind.from(Class) is a frequently called method, which provides a specialized method to improve performance.
> 
> The following Compiler log shows that the call stack level is reduced and two reference accesses (descriptorString() -> String.value) are reduced, which can reduce the performance degradation caused by cache misses.
> 
> * baseline
> 
> @ 48   java.lang.classfile.TypeKind::from (25 bytes)   inline
>   @ 1   java.lang.Class::isPrimitive (0 bytes)   intrinsic
>   @ 10   java.lang.Class::descriptorString (170 bytes)   failed to inline: callee is too large
>   @ 15   java.lang.classfile.TypeKind::fromDescriptor (232 bytes)   failed to inline: callee is too large
> 
> 
> * current
> 
> @ 52   java.lang.classfile.TypeKind::from (103 bytes)   failed to inline: callee is too large

src/java.base/share/classes/java/lang/classfile/TypeKind.java line 35:

> 33: import jdk.internal.vm.annotation.Stable;
> 34: 
> 35: import static java.lang.constant.ConstantDescs.*;

Maybe import the primitive class descriptors from `PrimitiveClassDescImpl` in order to avoid unnecessary initialisation of unrelated `ConstantDesc`s:
Suggestion:

import static jdk.internal.constant.PrimitiveClassDescImpl.*;

src/java.base/share/classes/java/lang/classfile/TypeKind.java line 176:

> 174:         if (cl == double.class ) return DoubleType;
> 175:         if (cl == void.class   ) return VoidType;
> 176:         else                     return ReferenceType;

This can call `Class​::isPrimitive()` to perform an implicit null check and short‑circuit for reference types:
Suggestion:

        if (cl.isPrimitive()) { // implicit null check
            if (cl == boolean.class) return BooleanType;
            if (cl == byte.class   ) return ByteType;
            if (cl == char.class   ) return CharType;
            if (cl == int.class    ) return IntType;
            if (cl == long.class   ) return LongType;
            if (cl == short.class  ) return ShortType;
            if (cl == float.class  ) return FloatType;
            if (cl == double.class ) return DoubleType;
            if (cl == void.class   ) return VoidType;
        }
        return ReferenceType;

src/java.base/share/classes/java/lang/classfile/TypeKind.java line 258:

> 256:         if (desc == CD_double ) return DOUBLE;
> 257:         if (desc == CD_void   ) return VOID;
> 258:         else                    return REFERENCE;

This can short‑circuit when `desc` is not a `PrimitiveClassDescImpl`:
Suggestion:

        if (desc instanceof PrimitiveClassDescImpl) {
            if (desc == CD_boolean) return BOOLEAN;
            if (desc == CD_byte   ) return BYTE;
            if (desc == CD_char   ) return CHAR;
            if (desc == CD_int    ) return INT;
            if (desc == CD_long   ) return LONG;
            if (desc == CD_short  ) return SHORT;
            if (desc == CD_float  ) return FLOAT;
            if (desc == CD_double ) return DOUBLE;
            if (desc == CD_void   ) return VOID;
        }
        return REFERENCE;

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

PR Review Comment: https://git.openjdk.org/jdk/pull/20762#discussion_r1739629316
PR Review Comment: https://git.openjdk.org/jdk/pull/20762#discussion_r1737538239
PR Review Comment: https://git.openjdk.org/jdk/pull/20762#discussion_r1739630850


More information about the core-libs-dev mailing list