RFR: 8163369: Enable generating DMH classes at link time
    Aleksey Shipilev 
    aleksey.shipilev at gmail.com
       
    Mon Aug  8 12:28:46 UTC 2016
    
    
  
On 08/08/2016 02:46 PM, Claes Redestad wrote:
> Hi,
> 
> please review this change to add the ability to generate
> DirectMethodHandles to the --generate-jli-classes jlink plugin.
> 
> The implementation generates all the specified DMHs as methods into a
> single class, java.lang.invoke.DirectMethodHandle$DMH. At runtime when a
> DMH's LF is set up, we speculatively resolve the member from this class
> instead of generating and loading the bytecode as a distinct anonymous
> class. This avoids loading a potentially large number of anonymous
> classes at runtime, and also enables other startup optimizations such as
> allowing CDS to see and dump this class to the shared archive.
> 
> webrev: http://cr.openjdk.java.net/~redestad/8163369/webrev.01/
DirectMethodHandle:
 * DMH placeholder class might better be called
DirectMethodHandle.Holder, or something else that clearly spells out the
intent?
InvokerBytecodeGenerator:
 * Both generateNamedFunctionInvokerImpl() and
generateLambdaFormInterpreterEntryPointBytes() have methodEpilog() call,
but no methodPrologue()? classFilePrologue() used to do the prologue.
GenerateJLIClassesPlugin:
 * Do we actually need this block in this form?
       // DirectMethodHandles
       // Enable by default
       boolean dmhEnabled = true;
       if (mainArgument != null) {
           Set<String> args = Arrays.stream(mainArgument.split(","))
                   .collect(Collectors.toSet());
           if (!args.contains(DMH_PARAM)) {
               dmhEnabled = false;
           }
       }
 seems equivalent to a simpler:
       boolean dmhEnabled = true;
       if (mainArgument != null) {
           List<String> args = Arrays.asList(mainArgument.split(","));
           if (!args.contains(DMH_PARAM)) {
               dmhEnabled = false;
           }
        }
 You can even split the mainArgument once and reuse throughout configure()?
 * This block does not check the first argument as the comment suggests,
only checks the second group:
    String[] typeParts = type.split("_");
    if (typeParts.length != 2 || typeParts[1].length() != 1
        || "LJIFDV".indexOf(typeParts[1].charAt(0)) == -1) {
       throw new PluginException(
             "Method type signature must be of form [LJIFD]*_[LJIFDV]");
    }
 * primitiveType('Z') would throw a misleading "Not a primitive: Z"
 * This can iterate over values only:
   for (Map.Entry<String, List<String>> entry : dmhMethods.entrySet()) {
      count += entry.getValue().size();
   }
 * I don't know the module visibility rules between jlink and java.base,
but can we reference DirectMethodHandle.DMH class as literal from the
plugin?
 * requireBasicType(last) is loop invariant here:
    for (int j = 1; j < count; j++) {
        requireBasicType(last);
        sb.append(last);
    }
Thanks,
-Aleksey
    
    
More information about the core-libs-dev
mailing list