RFR: 8351748: Classes of method handles in AOT cache should be AOT-inited

Ioi Lam iklam at openjdk.org
Fri Mar 14 22:07:53 UTC 2025


On Thu, 13 Mar 2025 16:51:36 GMT, Vladimir Ivanov <vlivanov at openjdk.org> wrote:

> > Could you elaborate how this can be done?
> 
> For `MethodHandle`s `DirectMethodHandle.shouldBeInitialized(Class)` determines whether a barrier is needed or not. It can be tweaked to behave conservatively during assembly phase and report `true` irrespective of whether the target class is initialized or not. (And it can take AOT-inited classes into account as well.)
> 
> (`VarHandle`s use `Unsafe.shouldBeInitialized(Class)` directly.)

In offline discussion, we agreed that blindly initializing every class may cause undesirable side effects. 

One option is to hard code all the classes that will be used by cached method handles. I wrote a prototype to check it what classes need to explicitly initialized. It found the usual suspects (`LambdaMetafactory` and `StringConcatFactory`), but even for a very simple test case, it also found `java.lang.StringConcatHelper`, which is internally used by StringConcatFactory. So it would be difficult to maintain such an explicit list to match changes inside the JDK.

I tried another suggestion from @iwanowww -- always emit init barriers in the cached  Method/Var handles. This seems to work.

My rough prototype is here: https://github.com/openjdk/jdk/commit/1baaaac1501df7c52a7dd4ab0722849d70265d4d . I can improve it by filtering out the classes that we know are aot-initialized.

Bytecode traces shows the presence of the init barrier in the generated bytecodes, so `LambdaMetafactory.<clinit>` is now executed before the target method is entered.


[3757812] static jobject java.lang.invoke.LambdaForm$DMH/0x800000005.invokeStaticInit(jobject, jobject, jobject, jobject, jobject, jobject, jobject)
[3757812]   233022     0  nofast_aload_0
[3757812]   233023     1  invokestatic 17 <java/lang/invoke/DirectMethodHandle.internalMemberNameEnsureInit(Ljava/lang/Object;)Ljava/lang/Object;> 

[3757812] static jobject java.lang.invoke.DirectMethodHandle.internalMemberNameEnsureInit(jobject)
[3757812]   233024     0  nofast_aload_0
[3757812]   233025     1  checkcast 3 <java/lang/invoke/DirectMethodHandle>
[3757812]   233026     4  astore_1
[3757812]   233027     5  aload_1
[3757812]   233028     6  invokevirtual 427 <java/lang/invoke/DirectMethodHandle.ensureInitialized()V> 

[3757812] virtual void java.lang.invoke.DirectMethodHandle.ensureInitialized()
[3757812]   233029     0  nofast_aload_0
[3757812]   233030     1  nofast_getfield 80 <java/lang/invoke/DirectMethodHandle.member:Ljava/lang/invoke/MemberName;> 
[3757812]   233031     4  invokestatic 453 <java/lang/invoke/DirectMethodHandle.checkInitialized(Ljava/lang/invoke/MemberName;)Z> 

[3757812] static jboolean java.lang.invoke.DirectMethodHandle.checkInitialized(jobject)
[3757812]   233032     0  nofast_aload_0
[3757812]   233033     1  invokevirtual 28 <java/lang/invoke/MemberName.getDeclaringClass()Ljava/lang/Class;> 

[3757812] virtual jobject java.lang.invoke.MemberName.getDeclaringClass()
[3757812]   233034     0  nofast_aload_0
[3757812]   233035     1  nofast_getfield 7 <java/lang/invoke/MemberName.clazz:Ljava/lang/Class;> 
[3757812]   233036     4  areturn

[3757812] static jboolean java.lang.invoke.DirectMethodHandle.checkInitialized(jobject)
[3757812]   233037     4  astore_1
[3757812]   233038     5  getstatic 436 <java/lang/invoke/MethodHandleStatics.UNSAFE:Ljdk/internal/misc/Unsafe;> 
[3757812]   233039     8  aload_1
[3757812]   233040     9  invokevirtual 440 <jdk/internal/misc/Unsafe.ensureClassInitialized(Ljava/lang/Class;)V> 

[3757812] virtual void jdk.internal.misc.Unsafe.ensureClassInitialized(jobject)
[3757812]   233041     0  aload_1
[3757812]   233042     1  ifnonnull 12
[3757812]   233043    12  nofast_aload_0
[3757812]   233044    13  aload_1
[3757812]   233045    14  invokevirtual 273 <jdk/internal/misc/Unsafe.ensureClassInitialized0(Ljava/lang/Class;)V> 

[3757812] static void java.lang.invoke.LambdaMetafactory.<clinit>()
[3757812]   233046     0  iconst_0
[3757812]   233047     1  anewarray java/lang/Class

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

PR Comment: https://git.openjdk.org/jdk/pull/24004#issuecomment-2725861980


More information about the hotspot-runtime-dev mailing list