< prev index next >

src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java

Print this page
rev 49071 : 8198888: Reduce string allocation churn in InvokerBytecodeGenerator
Reviewed-by: psandoz, plevart


  76     private static final String SOURCE_PREFIX = "LambdaForm$";
  77 
  78     /** Name of its super class*/
  79     static final String INVOKER_SUPER_NAME = OBJ;
  80 
  81     /** Name of new class */
  82     private final String className;
  83 
  84     private final LambdaForm lambdaForm;
  85     private final String     invokerName;
  86     private final MethodType invokerType;
  87 
  88     /** Info about local variables in compiled lambda form */
  89     private int[]       localsMap;    // index
  90     private Class<?>[]  localClasses; // type
  91 
  92     /** ASM bytecode generation. */
  93     private ClassWriter cw;
  94     private MethodVisitor mv;
  95 




  96     private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
  97     private static final Class<?> HOST_CLASS = LambdaForm.class;
  98 
  99     /** Main constructor; other constructors delegate to this one. */
 100     private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
 101                                      String className, String invokerName, MethodType invokerType) {
 102         int p = invokerName.indexOf('.');
 103         if (p > -1) {
 104             className = invokerName.substring(0, p);
 105             invokerName = invokerName.substring(p + 1);
 106         }
 107         if (DUMP_CLASS_FILES) {
 108             className = makeDumpableClassName(className);
 109         }
 110         this.className  = className;
 111         this.lambdaForm = lambdaForm;
 112         this.invokerName = invokerName;
 113         this.invokerType = invokerType;
 114         this.localsMap = new int[localsMapSize+1]; // last entry of localsMap is count of allocated local slots
 115         this.localClasses = new Class<?>[localsMapSize+1];


 585     }
 586 
 587     /**
 588      * Emits an actual return instruction conforming to the given return type.
 589      */
 590     private void emitReturnInsn(BasicType type) {
 591         int opcode;
 592         switch (type) {
 593         case I_TYPE:  opcode = Opcodes.IRETURN;  break;
 594         case J_TYPE:  opcode = Opcodes.LRETURN;  break;
 595         case F_TYPE:  opcode = Opcodes.FRETURN;  break;
 596         case D_TYPE:  opcode = Opcodes.DRETURN;  break;
 597         case L_TYPE:  opcode = Opcodes.ARETURN;  break;
 598         case V_TYPE:  opcode = Opcodes.RETURN;   break;
 599         default:
 600             throw new InternalError("unknown return type: " + type);
 601         }
 602         mv.visitInsn(opcode);
 603     }
 604 
 605     private static String getInternalName(Class<?> c) {
 606         if (c == Object.class)             return OBJ;
 607         else if (c == Object[].class)      return OBJARY;
 608         else if (c == Class.class)         return CLS;
 609         else if (c == MethodHandle.class)  return MH;
 610         assert(VerifyAccess.isTypeVisible(c, Object.class)) : c.getName();
 611         return c.getName().replace('.', '/');





 612     }
 613 
 614     private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
 615         MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
 616         MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
 617         if (TRACE_RESOLVE) {
 618             System.out.println("[LF_RESOLVE] " + holder.getName() + " " + name + " " +
 619                     shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") );
 620         }
 621         return resolvedMember;
 622     }
 623 
 624     private static MemberName lookupPregenerated(LambdaForm form, MethodType invokerType) {
 625         if (form.customized != null) {
 626             // No pre-generated version for customized LF
 627             return null;
 628         }
 629         String name = form.kind.methodName;
 630         switch (form.kind) {
 631             case BOUND_REINVOKER: {




  76     private static final String SOURCE_PREFIX = "LambdaForm$";
  77 
  78     /** Name of its super class*/
  79     static final String INVOKER_SUPER_NAME = OBJ;
  80 
  81     /** Name of new class */
  82     private final String className;
  83 
  84     private final LambdaForm lambdaForm;
  85     private final String     invokerName;
  86     private final MethodType invokerType;
  87 
  88     /** Info about local variables in compiled lambda form */
  89     private int[]       localsMap;    // index
  90     private Class<?>[]  localClasses; // type
  91 
  92     /** ASM bytecode generation. */
  93     private ClassWriter cw;
  94     private MethodVisitor mv;
  95 
  96     /** Single element internal class name lookup cache. */
  97     private Class<?> lastClass;
  98     private String lastInternalName;
  99 
 100     private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
 101     private static final Class<?> HOST_CLASS = LambdaForm.class;
 102 
 103     /** Main constructor; other constructors delegate to this one. */
 104     private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
 105                                      String className, String invokerName, MethodType invokerType) {
 106         int p = invokerName.indexOf('.');
 107         if (p > -1) {
 108             className = invokerName.substring(0, p);
 109             invokerName = invokerName.substring(p + 1);
 110         }
 111         if (DUMP_CLASS_FILES) {
 112             className = makeDumpableClassName(className);
 113         }
 114         this.className  = className;
 115         this.lambdaForm = lambdaForm;
 116         this.invokerName = invokerName;
 117         this.invokerType = invokerType;
 118         this.localsMap = new int[localsMapSize+1]; // last entry of localsMap is count of allocated local slots
 119         this.localClasses = new Class<?>[localsMapSize+1];


 589     }
 590 
 591     /**
 592      * Emits an actual return instruction conforming to the given return type.
 593      */
 594     private void emitReturnInsn(BasicType type) {
 595         int opcode;
 596         switch (type) {
 597         case I_TYPE:  opcode = Opcodes.IRETURN;  break;
 598         case J_TYPE:  opcode = Opcodes.LRETURN;  break;
 599         case F_TYPE:  opcode = Opcodes.FRETURN;  break;
 600         case D_TYPE:  opcode = Opcodes.DRETURN;  break;
 601         case L_TYPE:  opcode = Opcodes.ARETURN;  break;
 602         case V_TYPE:  opcode = Opcodes.RETURN;   break;
 603         default:
 604             throw new InternalError("unknown return type: " + type);
 605         }
 606         mv.visitInsn(opcode);
 607     }
 608 
 609     private String getInternalName(Class<?> c) {
 610         if (c == Object.class)             return OBJ;
 611         else if (c == Object[].class)      return OBJARY;
 612         else if (c == Class.class)         return CLS;
 613         else if (c == MethodHandle.class)  return MH;
 614         assert(VerifyAccess.isTypeVisible(c, Object.class)) : c.getName();
 615 
 616         if (c == lastClass) {
 617             return lastInternalName;
 618         }
 619         lastClass = c;
 620         return lastInternalName = c.getName().replace('.', '/');
 621     }
 622 
 623     private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
 624         MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
 625         MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
 626         if (TRACE_RESOLVE) {
 627             System.out.println("[LF_RESOLVE] " + holder.getName() + " " + name + " " +
 628                     shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") );
 629         }
 630         return resolvedMember;
 631     }
 632 
 633     private static MemberName lookupPregenerated(LambdaForm form, MethodType invokerType) {
 634         if (form.customized != null) {
 635             // No pre-generated version for customized LF
 636             return null;
 637         }
 638         String name = form.kind.methodName;
 639         switch (form.kind) {
 640             case BOUND_REINVOKER: {


< prev index next >