src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java
changeset 49451 e06f9607f370
parent 47216 71c04702a3d5
child 50858 2d3e99a72541
--- 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<? extends ConstantPool> hscp;
+    private static final MethodHandle loadReferencedTypeIIZMH;
+
+    static {
+        MethodHandle m = null;
+        Class<? extends ConstantPool> 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);
+        }
+    }
+
 }