RFR: 8297784: Optimize @Stable field for Method.isCallerSensitive

Alan Bateman alanb at openjdk.org
Wed Nov 30 07:57:15 UTC 2022


On Tue, 29 Nov 2022 19:39:02 GMT, Aleksey Shipilev <shade at openjdk.org> wrote:

> [JDK-8271820](https://bugs.openjdk.org/browse/JDK-8271820) introduced the `@Stable private Boolean callerSensitive;` cache in `Method`. That field is essentially a tri-state `Boolean` that relies on its `null` value to serve as "not initialized" value for `@Stable`.
> 
> This works well when the holder `Method` instance is constant: JIT compilers fold `@Stable` well. But if such folding fails, we always dereference the full-blown reference to "boxed" `Boolean` from the field on every access. We can instead do a more lean tri-state primitive field to improve that non-optimized case without sacrificing optimized case.
> 
> I chose `byte` and `-1`, `0`, `1` to let the fastpath encode well on most (all?) architectures.
> 
> On adhoc benchmark like:
> 
> 
> @State(Scope.Thread)
> public class WrapperConstness {
>     static final Method CONST;
>     static Method NON_CONST;
> 
>     static {
>         try {
>             CONST = WrapperConstness.class.getDeclaredMethod("target");
>             NON_CONST = CONST;
>         } catch (NoSuchMethodException e) {
>             throw new RuntimeException(e);
>         }
>     }
> 
>     public void target() {}
> 
>     @Benchmark
>     public void nonConstant() throws Exception {
>         NON_CONST.invoke(this);
>     }
> 
>     @Benchmark
>     public void constant() throws Exception {
>         CONST.invoke(this);
>     }
> }
> 
> 
> We have a minor improvement for non-const case, confirmed due to better `isCallerSensitive` access:
> 
> 
> Benchmark                     Mode  Cnt  Score   Error  Units
> 
> # Baseline
> WrapperConstness.constant     avgt   25  0.410 ± 0.010  ns/op
> WrapperConstness.nonConstant  avgt   25  7.283 ± 0.025  ns/op
> 
> # Patched
> WrapperConstness.constant     avgt    5  0.407 ± 0.008  ns/op
> WrapperConstness.nonConstant  avgt    5  7.054 ± 0.027  ns/op  ; -3%
> 
> 
> Additional testing:
>  - [x] Ad-hoc benchmarks
>  - [x] Linux x86_64 fastdebug `java/lang/reflect`
>  - [ ] Linux x86_64 fastdebug `tier1`, `tier2`

Marked as reviewed by alanb (Reviewer).

src/java.base/share/classes/java/lang/reflect/Method.java line 612:

> 610:     // -1 = initialized, not CS
> 611:     @Stable private byte callerSensitive;
> 612:     private boolean isCallerSensitive() {

A minor nit but a blank line between the declaration and the method would be good here, only to see that the comment is on the field, not the boolean returning method.

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

PR: https://git.openjdk.org/jdk/pull/11422


More information about the core-libs-dev mailing list