< prev index next >

src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java

Print this page
rev 49208 : 8199471: Enable generation of callSiteForms at link time
Reviewed-by: psandoz

@@ -67,19 +67,23 @@
     private static final String DMH_INVOKE_INTERFACE = "invokeInterface";
     private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit";
 
     private static final String DELEGATING_HOLDER = "java/lang/invoke/DelegatingMethodHandle$Holder";
     private static final String BASIC_FORMS_HOLDER = "java/lang/invoke/LambdaForm$Holder";
-    private static final String INVOKERS_HOLDER = "java/lang/invoke/Invokers$Holder";
+
+    private static final String INVOKERS_HOLDER_NAME = "java.lang.invoke.Invokers$Holder";
+    private static final String INVOKERS_HOLDER_INTERNAL_NAME = INVOKERS_HOLDER_NAME.replace('.', '/');
 
     private static final JavaLangInvokeAccess JLIA
             = SharedSecrets.getJavaLangInvokeAccess();
 
     Set<String> speciesTypes = Set.of();
 
     Set<String> invokerTypes = Set.of();
 
+    Set<String> callSiteTypes = Set.of();
+
     Map<String, Set<String>> dmhMethods = Map.of();
 
     String mainArgument;
 
     public GenerateJLIClassesPlugin() {

@@ -126,11 +130,11 @@
 
     /**
      * @return the default invoker forms to generate.
      */
     private static Set<String> defaultInvokers() {
-        return Set.of("LL_L", "LL_I", "LILL_I", "L6_L");
+        return Set.of("LL_L", "LL_I", "LLLL_L", "LLLL_I", "LLIL_L", "LLIL_I", "L6_L");
     }
 
     /**
      * @return the list of default DirectMethodHandle methods to generate.
      */

@@ -207,10 +211,12 @@
         // Use TreeSet/TreeMap to keep things sorted in a deterministic
         // order to avoid scrambling the layout on small changes and to
         // ease finding methods in the generated code
         speciesTypes = new TreeSet<>(speciesTypes);
         invokerTypes = new TreeSet<>(invokerTypes);
+        callSiteTypes = new TreeSet<>(callSiteTypes);
+
         TreeMap<String, Set<String>> newDMHMethods = new TreeMap<>();
         for (Map.Entry<String, Set<String>> entry : dmhMethods.entrySet()) {
             newDMHMethods.put(entry.getKey(), new TreeSet<>(entry.getValue()));
         }
         dmhMethods = newDMHMethods;

@@ -227,12 +233,17 @@
                         }
                         break;
                     case "[LF_RESOLVE]":
                         String methodType = parts[3];
                         validateMethodType(methodType);
-                        if (parts[1].contains("Invokers")) {
+                        if (parts[1].equals(INVOKERS_HOLDER_NAME)) {
+                            if ("linkToTargetMethod".equals(parts[2]) ||
+                                    "linkToCallSite".equals(parts[2])) {
+                                callSiteTypes.add(methodType);
+                            } else {
                             invokerTypes.add(methodType);
+                            }
                         } else if (parts[1].contains("DirectMethodHandle")) {
                             String dmh = parts[2];
                             // ignore getObject etc for now (generated
                             // by default)
                             if (DMH_METHOD_TYPE_MAP.containsKey(dmh)) {

@@ -292,14 +303,15 @@
     public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
         initialize(in);
         // Copy all but DMH_ENTRY to out
         in.transformAndCopy(entry -> {
                 // filter out placeholder entries
-                if (entry.path().equals(DIRECT_METHOD_HOLDER_ENTRY) ||
-                    entry.path().equals(DELEGATING_METHOD_HOLDER_ENTRY) ||
-                    entry.path().equals(INVOKERS_HOLDER_ENTRY) ||
-                    entry.path().equals(BASIC_FORMS_HOLDER_ENTRY)) {
+                String path = entry.path();
+                if (path.equals(DIRECT_METHOD_HOLDER_ENTRY) ||
+                    path.equals(DELEGATING_METHOD_HOLDER_ENTRY) ||
+                    path.equals(INVOKERS_HOLDER_ENTRY) ||
+                    path.equals(BASIC_FORMS_HOLDER_ENTRY)) {
                     return null;
                 } else {
                     return entry;
                 }
             }, out);

@@ -359,27 +371,44 @@
                 directMethodTypes[index] = mt.dropParameterTypes(0, 1);
                 dmhTypes[index] = DMH_METHOD_TYPE_MAP.get(dmhType);
                 index++;
             }
         }
+
+        // The invoker type to ask for is retrieved by removing the first
+        // and the last argument, which needs to be of Object.class
         MethodType[] invokerMethodTypes = new MethodType[this.invokerTypes.size()];
         int i = 0;
         for (String invokerType : invokerTypes) {
-            // The invoker type to ask for is retrieved by removing the first
-            // and the last argument, which needs to be of Object.class
             MethodType mt = asMethodType(invokerType);
             final int lastParam = mt.parameterCount() - 1;
             if (mt.parameterCount() < 2 ||
                     mt.parameterType(0) != Object.class ||
                     mt.parameterType(lastParam) != Object.class) {
                 throw new PluginException(
-                        "Invoker type parameter must start and end with L");
+                        "Invoker type parameter must start and end with Object: " + invokerType);
             }
             mt = mt.dropParameterTypes(lastParam, lastParam + 1);
             invokerMethodTypes[i] = mt.dropParameterTypes(0, 1);
             i++;
         }
+
+        // The callSite type to ask for is retrieved by removing the last
+        // argument, which needs to be of Object.class
+        MethodType[] callSiteMethodTypes = new MethodType[this.callSiteTypes.size()];
+        i = 0;
+        for (String callSiteType : callSiteTypes) {
+            MethodType mt = asMethodType(callSiteType);
+            final int lastParam = mt.parameterCount() - 1;
+            if (mt.parameterCount() < 1 ||
+                    mt.parameterType(lastParam) != Object.class) {
+                throw new PluginException(
+                        "CallSite type parameter must end with Object: " + callSiteType);
+            }
+            callSiteMethodTypes[i] = mt.dropParameterTypes(lastParam, lastParam + 1);
+            i++;
+        }
         try {
             byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes(
                     DIRECT_HOLDER, directMethodTypes, dmhTypes);
             ResourcePoolEntry ndata = ResourcePoolEntry
                     .create(DIRECT_METHOD_HOLDER_ENTRY, bytes);

@@ -388,12 +417,12 @@
             bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes(
                     DELEGATING_HOLDER, directMethodTypes);
             ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HOLDER_ENTRY, bytes);
             out.add(ndata);
 
-            bytes = JLIA.generateInvokersHolderClassBytes(INVOKERS_HOLDER,
-                    invokerMethodTypes);
+            bytes = JLIA.generateInvokersHolderClassBytes(INVOKERS_HOLDER_INTERNAL_NAME,
+                    invokerMethodTypes, callSiteMethodTypes);
             ndata = ResourcePoolEntry.create(INVOKERS_HOLDER_ENTRY, bytes);
             out.add(ndata);
 
             bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HOLDER);
             ndata = ResourcePoolEntry.create(BASIC_FORMS_HOLDER_ENTRY, bytes);

@@ -407,11 +436,11 @@
     private static final String DELEGATING_METHOD_HOLDER_ENTRY =
             "/java.base/" + DELEGATING_HOLDER + ".class";
     private static final String BASIC_FORMS_HOLDER_ENTRY =
             "/java.base/" + BASIC_FORMS_HOLDER + ".class";
     private static final String INVOKERS_HOLDER_ENTRY =
-            "/java.base/" + INVOKERS_HOLDER + ".class";
+            "/java.base/" + INVOKERS_HOLDER_INTERNAL_NAME + ".class";
 
     // Convert LL -> LL, L3 -> LLL
     public static String expandSignature(String signature) {
         StringBuilder sb = new StringBuilder();
         char last = 'X';
< prev index next >