Relates :
|
|
Relates :
|
This was found during the work on indify String concat (JDK-8085796). In short, when javac is asked to produce an indy method call, it accumulates the bootstrap methods in the map below: /** The bootstrap methods to be written in the corresponding class attribute * (one for each invokedynamic) */ Map<DynamicMethod, MethodHandle> bootstrapMethods; DynamicMethod's equals treats dynamic arguments for the call as key (through Method.equals() supercall), which makes javac to emit duplicate entries in BootstrapMethods, while a common entry is sometimes enough. For example, different "shapes" of dynamic arguments all call into the same bootstrap method with the same static args, but each indy produces its own BSM entry: 600: invokedynamic #202, 0 // InvokeDynamic #0:stringConcat:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;...;Ljava/lang/String;)Ljava/lang/String; ... 30253: invokedynamic #10004, 0 // InvokeDynamic #1:stringConcat:(Ljava/lang/String;)Ljava/lang/String; ... 30258: invokedynamic #10005, 0 // InvokeDynamic #2:stringConcat:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;...;Ljava/lang/String;)Ljava/lang/String; BootstrapMethods: 0: #10120 invokestatic java/lang/invoke/StringConcatFactory.stringConcat:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; Method arguments: 1: #10120 invokestatic java/lang/invoke/StringConcatFactory.stringConcat:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; Method arguments: 2: #10120 invokestatic java/lang/invoke/StringConcatFactory.stringConcat:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; Method arguments: After the proof-of-concept patch: http://cr.openjdk.java.net/~shade/8129547/webrev.00/ 600: invokedynamic #202, 0 // InvokeDynamic #0:stringConcat:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;...;Ljava/lang/String;)Ljava/lang/String; ... 30253: invokedynamic #10004, 0 // InvokeDynamic #0:stringConcat:(Ljava/lang/String;)Ljava/lang/String; ... 30258: invokedynamic #10005, 0 // InvokeDynamic #0:stringConcat:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;...;Ljava/lang/String;)Ljava/lang/String; BootstrapMethods: 0: #10120 invokestatic java/lang/invoke/StringConcatFactory.stringConcat:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; Method arguments: For indify String concat project, this improves the bytecode footprint from 100.000.006 bytes to 99.998.563 bytes (-1443 bytes) when the entire JDK is compiled.