src/share/classes/java/lang/invoke/BoundMethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/share/classes/java/lang/invoke

src/share/classes/java/lang/invoke/BoundMethodHandle.java

Print this page
rev 10274 : 8050052: Small cleanups in java.lang.invoke code
Reviewed-by: ?


  49  * when the handle is created, not when it is invoked.
  50  *
  51  * All bound arguments are encapsulated in dedicated species.
  52  */
  53 /* non-public */ abstract class BoundMethodHandle extends MethodHandle {
  54 
  55     /* non-public */ BoundMethodHandle(MethodType type, LambdaForm form) {
  56         super(type, form);
  57     }
  58 
  59     //
  60     // BMH API and internals
  61     //
  62 
  63     static MethodHandle bindSingle(MethodType type, LambdaForm form, BasicType xtype, Object x) {
  64         // for some type signatures, there exist pre-defined concrete BMH classes
  65         try {
  66             switch (xtype) {
  67             case L_TYPE:
  68                 if (true)  return bindSingle(type, form, x);  // Use known fast path.
  69                 return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(L_TYPE).constructor[0].invokeBasic(type, form, x);
  70             case I_TYPE:
  71                 return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(I_TYPE).constructor[0].invokeBasic(type, form, ValueConversions.widenSubword(x));
  72             case J_TYPE:
  73                 return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(J_TYPE).constructor[0].invokeBasic(type, form, (long) x);
  74             case F_TYPE:
  75                 return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(F_TYPE).constructor[0].invokeBasic(type, form, (float) x);
  76             case D_TYPE:
  77                 return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(D_TYPE).constructor[0].invokeBasic(type, form, (double) x);
  78             default : throw newInternalError("unexpected xtype: " + xtype);
  79             }
  80         } catch (Throwable t) {
  81             throw newInternalError(t);
  82         }
  83     }
  84 
  85     static MethodHandle bindSingle(MethodType type, LambdaForm form, Object x) {
  86             return new Species_L(type, form, x);
  87     }
  88 
  89     MethodHandle cloneExtend(MethodType type, LambdaForm form, BasicType xtype, Object x) {
  90         try {
  91             switch (xtype) {
  92             case L_TYPE: return copyWithExtendL(type, form, x);
  93             case I_TYPE: return copyWithExtendI(type, form, ValueConversions.widenSubword(x));
  94             case J_TYPE: return copyWithExtendJ(type, form, (long) x);
  95             case F_TYPE: return copyWithExtendF(type, form, (float) x);
  96             case D_TYPE: return copyWithExtendD(type, form, (double) x);
  97             }


 202         @Override MethodHandle reinvokerTarget() { return (MethodHandle) argL0; }
 203         @Override
 204         /*non-public*/ SpeciesData speciesData() {
 205             return SPECIES_DATA;
 206         }
 207         @Override
 208         /*non-public*/ int fieldCount() {
 209             return 1;
 210         }
 211         /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
 212         /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
 213             return new Species_L(mt, lf, argL0);
 214         }
 215         @Override
 216         /*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
 217             return new Species_L(mt, lf, argL0);
 218         }
 219         @Override
 220         /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
 221             try {
 222                 return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg);
 223             } catch (Throwable ex) {
 224                 throw uncaughtException(ex);
 225             }
 226         }
 227         @Override
 228         /*non-public*/ final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
 229             try {
 230                 return (BoundMethodHandle) SPECIES_DATA.extendWith(I_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg);
 231             } catch (Throwable ex) {
 232                 throw uncaughtException(ex);
 233             }
 234         }
 235         @Override
 236         /*non-public*/ final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
 237             try {
 238                 return (BoundMethodHandle) SPECIES_DATA.extendWith(J_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg);
 239             } catch (Throwable ex) {
 240                 throw uncaughtException(ex);
 241             }
 242         }
 243         @Override
 244         /*non-public*/ final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
 245             try {
 246                 return (BoundMethodHandle) SPECIES_DATA.extendWith(F_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg);
 247             } catch (Throwable ex) {
 248                 throw uncaughtException(ex);
 249             }
 250         }
 251         @Override
 252         /*non-public*/ final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
 253             try {
 254                 return (BoundMethodHandle) SPECIES_DATA.extendWith(D_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg);
 255             } catch (Throwable ex) {
 256                 throw uncaughtException(ex);
 257             }
 258         }
 259     }
 260 
 261     //
 262     // BMH species meta-data
 263     //
 264 
 265     /**
 266      * Meta-data wrapper for concrete BMH types.
 267      * Each BMH type corresponds to a given sequence of basic field types (LIJFD).
 268      * The fields are immutable; their values are fully specified at object construction.
 269      * Each BMH type supplies an array of getter functions which may be used in lambda forms.
 270      * A BMH is constructed by cloning a shorter BMH and adding one or more new field values.
 271      * As a degenerate and common case, the "shorter BMH" can be missing, and contributes zero prior fields.
 272      */
 273     static class SpeciesData {
 274         final String                             typeChars;


 287         /*non-public*/ BasicType fieldType(int i) {
 288             return typeCodes[i];
 289         }
 290         /*non-public*/ char fieldTypeChar(int i) {
 291             return typeChars.charAt(i);
 292         }
 293 
 294         public String toString() {
 295             return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+typeChars+"]";
 296         }
 297 
 298         /**
 299          * Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
 300          * represents a MH bound to a generic invoker, which in turn forwards to the corresponding
 301          * getter.
 302          */
 303         NamedFunction getterFunction(int i) {
 304             return nominalGetters[i];
 305         }
 306 




 307         static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class);
 308 
 309         private SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) {
 310             this.typeChars = types;
 311             this.typeCodes = basicTypes(types);
 312             this.clazz = clazz;
 313             if (!INIT_DONE) {
 314                 this.constructor = new MethodHandle[1];  // only one ctor
 315                 this.getters = new MethodHandle[types.length()];
 316                 this.nominalGetters = new NamedFunction[types.length()];
 317             } else {
 318                 this.constructor = Factory.makeCtors(clazz, types, null);
 319                 this.getters = Factory.makeGetters(clazz, types, null);
 320                 this.nominalGetters = Factory.makeNominalGetters(types, null, this.getters);
 321             }
 322             this.extensions = new SpeciesData[ARG_TYPE_LIMIT];
 323         }
 324 
 325         private void initForBootstrap() {
 326             assert(!INIT_DONE);
 327             if (constructor[0] == null) {
 328                 String types = typeChars;
 329                 Factory.makeCtors(clazz, types, this.constructor);
 330                 Factory.makeGetters(clazz, types, this.getters);
 331                 Factory.makeNominalGetters(types, this.nominalGetters, this.getters);
 332             }
 333         }
 334 
 335         private SpeciesData(String typeChars) {
 336             // Placeholder only.
 337             this.typeChars = typeChars;
 338             this.typeCodes = basicTypes(typeChars);
 339             this.clazz = null;
 340             this.constructor = null;
 341             this.getters = null;
 342             this.nominalGetters = null;
 343             this.extensions = null;
 344         }
 345         private boolean isPlaceholder() { return clazz == null; }
 346 
 347         private static final HashMap<String, SpeciesData> CACHE = new HashMap<>();


 491          * final class Species_LLI extends BoundMethodHandle {
 492          *     final Object argL0;
 493          *     final Object argL1;
 494          *     final int argI2;
 495          *     private Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
 496          *         super(mt, lf);
 497          *         this.argL0 = argL0;
 498          *         this.argL1 = argL1;
 499          *         this.argI2 = argI2;
 500          *     }
 501          *     final SpeciesData speciesData() { return SPECIES_DATA; }
 502          *     final int fieldCount() { return 3; }
 503          *     static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class);
 504          *     static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
 505          *         return new Species_LLI(mt, lf, argL0, argL1, argI2);
 506          *     }
 507          *     final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
 508          *         return new Species_LLI(mt, lf, argL0, argL1, argI2);
 509          *     }
 510          *     final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
 511          *         return SPECIES_DATA.extendWith(L_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
 512          *     }
 513          *     final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
 514          *         return SPECIES_DATA.extendWith(I_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
 515          *     }
 516          *     final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
 517          *         return SPECIES_DATA.extendWith(J_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
 518          *     }
 519          *     final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
 520          *         return SPECIES_DATA.extendWith(F_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
 521          *     }
 522          *     public final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
 523          *         return SPECIES_DATA.extendWith(D_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
 524          *     }
 525          * }
 526          * </pre>
 527          *
 528          * @param types the type signature, wherein reference types are erased to 'L'
 529          * @return the generated concrete BMH class
 530          */
 531         static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) {
 532             final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
 533 
 534             String shortTypes = LambdaForm.shortenSignature(types);
 535             final String className  = SPECIES_PREFIX_PATH + shortTypes;
 536             final String sourceFile = SPECIES_PREFIX_NAME + shortTypes;
 537             final int NOT_ACC_PUBLIC = 0;  // not ACC_PUBLIC
 538             cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
 539             cw.visitSource(sourceFile, null);
 540 
 541             // emit static types and SPECIES_DATA fields
 542             cw.visitField(NOT_ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd();
 543 


 636             // make instance
 637             mv.visitTypeInsn(NEW, className);
 638             mv.visitInsn(DUP);
 639             // load mt, lf
 640             mv.visitVarInsn(ALOAD, 1);
 641             mv.visitVarInsn(ALOAD, 2);
 642             // put fields on the stack
 643             emitPushFields(types, className, mv);
 644             // finally, invoke the constructor and return
 645             mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
 646             mv.visitInsn(ARETURN);
 647             mv.visitMaxs(0, 0);
 648             mv.visitEnd();
 649 
 650             // for each type, emit copyWithExtendT()
 651             for (BasicType type : BasicType.ARG_TYPES) {
 652                 int ord = type.ordinal();
 653                 char btChar = type.basicTypeChar();
 654                 mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWithExtend" + btChar, makeSignature(String.valueOf(btChar), false), null, E_THROWABLE);
 655                 mv.visitCode();
 656                 // return SPECIES_DATA.extendWith(t).constructor[0].invokeBasic(mt, lf, argL0, ..., narg)
 657                 // obtain constructor
 658                 mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
 659                 int iconstInsn = ICONST_0 + ord;
 660                 assert(iconstInsn <= ICONST_5);
 661                 mv.visitInsn(iconstInsn);
 662                 mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWith", BMHSPECIES_DATA_EWI_SIG, false);
 663                 mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
 664                 mv.visitInsn(ICONST_0);
 665                 mv.visitInsn(AALOAD);
 666                 // load mt, lf
 667                 mv.visitVarInsn(ALOAD, 1);
 668                 mv.visitVarInsn(ALOAD, 2);
 669                 // put fields on the stack
 670                 emitPushFields(types, className, mv);
 671                 // put narg on stack
 672                 mv.visitVarInsn(typeLoadOp(btChar), 3);
 673                 // finally, invoke the constructor and return
 674                 mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + btChar, false), false);
 675                 mv.visitInsn(ARETURN);
 676                 mv.visitMaxs(0, 0);
 677                 mv.visitEnd();
 678             }
 679 
 680             // emit class initializer
 681             mv = cw.visitMethod(NOT_ACC_PUBLIC | ACC_STATIC, "<clinit>", VOID_SIG, null, null);
 682             mv.visitCode();
 683             mv.visitLdcInsn(types);
 684             mv.visitLdcInsn(Type.getObjectType(className));
 685             mv.visitMethodInsn(INVOKESTATIC, SPECIES_DATA, "getForClass", BMHSPECIES_DATA_GFC_SIG, false);




  49  * when the handle is created, not when it is invoked.
  50  *
  51  * All bound arguments are encapsulated in dedicated species.
  52  */
  53 /* non-public */ abstract class BoundMethodHandle extends MethodHandle {
  54 
  55     /* non-public */ BoundMethodHandle(MethodType type, LambdaForm form) {
  56         super(type, form);
  57     }
  58 
  59     //
  60     // BMH API and internals
  61     //
  62 
  63     static MethodHandle bindSingle(MethodType type, LambdaForm form, BasicType xtype, Object x) {
  64         // for some type signatures, there exist pre-defined concrete BMH classes
  65         try {
  66             switch (xtype) {
  67             case L_TYPE:
  68                 if (true)  return bindSingle(type, form, x);  // Use known fast path.
  69                 return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(L_TYPE).constructor().invokeBasic(type, form, x);
  70             case I_TYPE:
  71                 return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(I_TYPE).constructor().invokeBasic(type, form, ValueConversions.widenSubword(x));
  72             case J_TYPE:
  73                 return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(J_TYPE).constructor().invokeBasic(type, form, (long) x);
  74             case F_TYPE:
  75                 return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(F_TYPE).constructor().invokeBasic(type, form, (float) x);
  76             case D_TYPE:
  77                 return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(D_TYPE).constructor().invokeBasic(type, form, (double) x);
  78             default : throw newInternalError("unexpected xtype: " + xtype);
  79             }
  80         } catch (Throwable t) {
  81             throw newInternalError(t);
  82         }
  83     }
  84 
  85     static MethodHandle bindSingle(MethodType type, LambdaForm form, Object x) {
  86             return new Species_L(type, form, x);
  87     }
  88 
  89     MethodHandle cloneExtend(MethodType type, LambdaForm form, BasicType xtype, Object x) {
  90         try {
  91             switch (xtype) {
  92             case L_TYPE: return copyWithExtendL(type, form, x);
  93             case I_TYPE: return copyWithExtendI(type, form, ValueConversions.widenSubword(x));
  94             case J_TYPE: return copyWithExtendJ(type, form, (long) x);
  95             case F_TYPE: return copyWithExtendF(type, form, (float) x);
  96             case D_TYPE: return copyWithExtendD(type, form, (double) x);
  97             }


 202         @Override MethodHandle reinvokerTarget() { return (MethodHandle) argL0; }
 203         @Override
 204         /*non-public*/ SpeciesData speciesData() {
 205             return SPECIES_DATA;
 206         }
 207         @Override
 208         /*non-public*/ int fieldCount() {
 209             return 1;
 210         }
 211         /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
 212         /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
 213             return new Species_L(mt, lf, argL0);
 214         }
 215         @Override
 216         /*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
 217             return new Species_L(mt, lf, argL0);
 218         }
 219         @Override
 220         /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
 221             try {
 222                 return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
 223             } catch (Throwable ex) {
 224                 throw uncaughtException(ex);
 225             }
 226         }
 227         @Override
 228         /*non-public*/ final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
 229             try {
 230                 return (BoundMethodHandle) SPECIES_DATA.extendWith(I_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
 231             } catch (Throwable ex) {
 232                 throw uncaughtException(ex);
 233             }
 234         }
 235         @Override
 236         /*non-public*/ final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
 237             try {
 238                 return (BoundMethodHandle) SPECIES_DATA.extendWith(J_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
 239             } catch (Throwable ex) {
 240                 throw uncaughtException(ex);
 241             }
 242         }
 243         @Override
 244         /*non-public*/ final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
 245             try {
 246                 return (BoundMethodHandle) SPECIES_DATA.extendWith(F_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
 247             } catch (Throwable ex) {
 248                 throw uncaughtException(ex);
 249             }
 250         }
 251         @Override
 252         /*non-public*/ final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
 253             try {
 254                 return (BoundMethodHandle) SPECIES_DATA.extendWith(D_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
 255             } catch (Throwable ex) {
 256                 throw uncaughtException(ex);
 257             }
 258         }
 259     }
 260 
 261     //
 262     // BMH species meta-data
 263     //
 264 
 265     /**
 266      * Meta-data wrapper for concrete BMH types.
 267      * Each BMH type corresponds to a given sequence of basic field types (LIJFD).
 268      * The fields are immutable; their values are fully specified at object construction.
 269      * Each BMH type supplies an array of getter functions which may be used in lambda forms.
 270      * A BMH is constructed by cloning a shorter BMH and adding one or more new field values.
 271      * As a degenerate and common case, the "shorter BMH" can be missing, and contributes zero prior fields.
 272      */
 273     static class SpeciesData {
 274         final String                             typeChars;


 287         /*non-public*/ BasicType fieldType(int i) {
 288             return typeCodes[i];
 289         }
 290         /*non-public*/ char fieldTypeChar(int i) {
 291             return typeChars.charAt(i);
 292         }
 293 
 294         public String toString() {
 295             return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+typeChars+"]";
 296         }
 297 
 298         /**
 299          * Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
 300          * represents a MH bound to a generic invoker, which in turn forwards to the corresponding
 301          * getter.
 302          */
 303         NamedFunction getterFunction(int i) {
 304             return nominalGetters[i];
 305         }
 306 
 307         MethodHandle constructor() {
 308             return constructor[0];
 309         }
 310 
 311         static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class);
 312 
 313         private SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) {
 314             this.typeChars = types;
 315             this.typeCodes = basicTypes(types);
 316             this.clazz = clazz;
 317             if (!INIT_DONE) {
 318                 this.constructor = new MethodHandle[1];  // only one ctor
 319                 this.getters = new MethodHandle[types.length()];
 320                 this.nominalGetters = new NamedFunction[types.length()];
 321             } else {
 322                 this.constructor = Factory.makeCtors(clazz, types, null);
 323                 this.getters = Factory.makeGetters(clazz, types, null);
 324                 this.nominalGetters = Factory.makeNominalGetters(types, null, this.getters);
 325             }
 326             this.extensions = new SpeciesData[ARG_TYPE_LIMIT];
 327         }
 328 
 329         private void initForBootstrap() {
 330             assert(!INIT_DONE);
 331             if (constructor() == null) {
 332                 String types = typeChars;
 333                 Factory.makeCtors(clazz, types, this.constructor);
 334                 Factory.makeGetters(clazz, types, this.getters);
 335                 Factory.makeNominalGetters(types, this.nominalGetters, this.getters);
 336             }
 337         }
 338 
 339         private SpeciesData(String typeChars) {
 340             // Placeholder only.
 341             this.typeChars = typeChars;
 342             this.typeCodes = basicTypes(typeChars);
 343             this.clazz = null;
 344             this.constructor = null;
 345             this.getters = null;
 346             this.nominalGetters = null;
 347             this.extensions = null;
 348         }
 349         private boolean isPlaceholder() { return clazz == null; }
 350 
 351         private static final HashMap<String, SpeciesData> CACHE = new HashMap<>();


 495          * final class Species_LLI extends BoundMethodHandle {
 496          *     final Object argL0;
 497          *     final Object argL1;
 498          *     final int argI2;
 499          *     private Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
 500          *         super(mt, lf);
 501          *         this.argL0 = argL0;
 502          *         this.argL1 = argL1;
 503          *         this.argI2 = argI2;
 504          *     }
 505          *     final SpeciesData speciesData() { return SPECIES_DATA; }
 506          *     final int fieldCount() { return 3; }
 507          *     static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class);
 508          *     static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
 509          *         return new Species_LLI(mt, lf, argL0, argL1, argI2);
 510          *     }
 511          *     final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
 512          *         return new Species_LLI(mt, lf, argL0, argL1, argI2);
 513          *     }
 514          *     final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
 515          *         return SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
 516          *     }
 517          *     final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
 518          *         return SPECIES_DATA.extendWith(I_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
 519          *     }
 520          *     final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
 521          *         return SPECIES_DATA.extendWith(J_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
 522          *     }
 523          *     final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
 524          *         return SPECIES_DATA.extendWith(F_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
 525          *     }
 526          *     public final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
 527          *         return SPECIES_DATA.extendWith(D_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
 528          *     }
 529          * }
 530          * </pre>
 531          *
 532          * @param types the type signature, wherein reference types are erased to 'L'
 533          * @return the generated concrete BMH class
 534          */
 535         static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) {
 536             final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
 537 
 538             String shortTypes = LambdaForm.shortenSignature(types);
 539             final String className  = SPECIES_PREFIX_PATH + shortTypes;
 540             final String sourceFile = SPECIES_PREFIX_NAME + shortTypes;
 541             final int NOT_ACC_PUBLIC = 0;  // not ACC_PUBLIC
 542             cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
 543             cw.visitSource(sourceFile, null);
 544 
 545             // emit static types and SPECIES_DATA fields
 546             cw.visitField(NOT_ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd();
 547 


 640             // make instance
 641             mv.visitTypeInsn(NEW, className);
 642             mv.visitInsn(DUP);
 643             // load mt, lf
 644             mv.visitVarInsn(ALOAD, 1);
 645             mv.visitVarInsn(ALOAD, 2);
 646             // put fields on the stack
 647             emitPushFields(types, className, mv);
 648             // finally, invoke the constructor and return
 649             mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
 650             mv.visitInsn(ARETURN);
 651             mv.visitMaxs(0, 0);
 652             mv.visitEnd();
 653 
 654             // for each type, emit copyWithExtendT()
 655             for (BasicType type : BasicType.ARG_TYPES) {
 656                 int ord = type.ordinal();
 657                 char btChar = type.basicTypeChar();
 658                 mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWithExtend" + btChar, makeSignature(String.valueOf(btChar), false), null, E_THROWABLE);
 659                 mv.visitCode();
 660                 // return SPECIES_DATA.extendWith(t).constructor().invokeBasic(mt, lf, argL0, ..., narg)
 661                 // obtain constructor
 662                 mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
 663                 int iconstInsn = ICONST_0 + ord;
 664                 assert(iconstInsn <= ICONST_5);
 665                 mv.visitInsn(iconstInsn);
 666                 mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWith", BMHSPECIES_DATA_EWI_SIG, false);
 667                 mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "constructor", "()" + MH_SIG, false);


 668                 // load mt, lf
 669                 mv.visitVarInsn(ALOAD, 1);
 670                 mv.visitVarInsn(ALOAD, 2);
 671                 // put fields on the stack
 672                 emitPushFields(types, className, mv);
 673                 // put narg on stack
 674                 mv.visitVarInsn(typeLoadOp(btChar), 3);
 675                 // finally, invoke the constructor and return
 676                 mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + btChar, false), false);
 677                 mv.visitInsn(ARETURN);
 678                 mv.visitMaxs(0, 0);
 679                 mv.visitEnd();
 680             }
 681 
 682             // emit class initializer
 683             mv = cw.visitMethod(NOT_ACC_PUBLIC | ACC_STATIC, "<clinit>", VOID_SIG, null, null);
 684             mv.visitCode();
 685             mv.visitLdcInsn(types);
 686             mv.visitLdcInsn(Type.getObjectType(className));
 687             mv.visitMethodInsn(INVOKESTATIC, SPECIES_DATA, "getForClass", BMHSPECIES_DATA_GFC_SIG, false);


src/share/classes/java/lang/invoke/BoundMethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File