diff -r 5d2adef239d6 -r e06f9607f370 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java --- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java Fri Mar 16 11:26:05 2018 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java Fri Mar 16 22:59:32 2018 -0700 @@ -25,6 +25,7 @@ import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; +import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode; import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode; import org.graalvm.compiler.nodes.ConstantNode; @@ -37,6 +38,11 @@ import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.ConstantPool; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; public final class HotSpotClassInitializationPlugin implements ClassInitializationPlugin { @Override @@ -73,4 +79,47 @@ result.setStateBefore(frameState); return result; } + + private static final Class hscp; + private static final MethodHandle loadReferencedTypeIIZMH; + + static { + MethodHandle m = null; + Class c = null; + try { + c = Class.forName("jdk.vm.ci.hotspot.HotSpotConstantPool").asSubclass(ConstantPool.class); + m = MethodHandles.lookup().findVirtual(c, "loadReferencedType", MethodType.methodType(void.class, int.class, int.class, boolean.class)); + } catch (Exception e) { + } + loadReferencedTypeIIZMH = m; + hscp = c; + } + + private static boolean isHotSpotConstantPool(ConstantPool cp) { + // jdk.vm.ci.hotspot.HotSpotConstantPool is final, so we can + // directly compare Classes. + return cp.getClass() == hscp; + } + + @Override + public boolean supportsLazyInitialization(ConstantPool cp) { + if (loadReferencedTypeIIZMH != null && isHotSpotConstantPool(cp)) { + return true; + } + return false; + } + + @Override + public void loadReferencedType(GraphBuilderContext builder, ConstantPool cp, int cpi, int opcode) { + if (loadReferencedTypeIIZMH != null && isHotSpotConstantPool(cp)) { + try { + loadReferencedTypeIIZMH.invoke(cp, cpi, opcode, false); + } catch (Throwable t) { + throw GraalError.shouldNotReachHere(t); + } + } else { + cp.loadReferencedType(cpi, opcode); + } + } + }