< prev index next >

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

Print this page
rev 12972 : 8131129: Attempt to define a duplicate BMH$Species class


 379 
 380         SpeciesData extendWith(byte type) {
 381             return extendWith(BasicType.basicType(type));
 382         }
 383 
 384         SpeciesData extendWith(BasicType type) {
 385             int ord = type.ordinal();
 386             SpeciesData d = extensions[ord];
 387             if (d != null)  return d;
 388             extensions[ord] = d = get(typeChars+type.basicTypeChar());
 389             return d;
 390         }
 391 
 392         private static SpeciesData get(String types) {
 393             // Acquire cache lock for query.
 394             SpeciesData d = lookupCache(types);
 395             if (!d.isPlaceholder())
 396                 return d;
 397             synchronized (d) {
 398                 // Use synch. on the placeholder to prevent multiple instantiation of one species.
 399                 // Creating this class forces a recursive call to getForClass.
 400                 if (lookupCache(types).isPlaceholder())
 401                     Factory.generateConcreteBMHClass(types);
 402             }
 403             // Reacquire cache lock.
 404             d = lookupCache(types);
 405             // Class loading must have upgraded the cache.
 406             assert(d != null && !d.isPlaceholder());


 407             return d;
 408         }
 409         static SpeciesData getForClass(String types, Class<? extends BoundMethodHandle> clazz) {
 410             // clazz is a new class which is initializing its SPECIES_DATA field
 411             return updateCache(types, new SpeciesData(types, clazz));
 412         }
 413         private static synchronized SpeciesData lookupCache(String types) {
 414             SpeciesData d = CACHE.get(types);
 415             if (d != null)  return d;
 416             d = new SpeciesData(types);
 417             assert(d.isPlaceholder());
 418             CACHE.put(types, d);
 419             return d;
 420         }
 421         private static synchronized SpeciesData updateCache(String types, SpeciesData d) {
 422             SpeciesData d2;
 423             assert((d2 = CACHE.get(types)) == null || d2.isPlaceholder());
 424             assert(!d.isPlaceholder());
 425             CACHE.put(types, d);
 426             return d;
 427         }
 428 
 429         static {
 430             // pre-fill the BMH speciesdata cache with BMH's inner classes
 431             final Class<BoundMethodHandle> rootCls = BoundMethodHandle.class;
 432             try {
 433                 for (Class<?> c : rootCls.getDeclaredClasses()) {
 434                     if (rootCls.isAssignableFrom(c)) {
 435                         final Class<? extends BoundMethodHandle> cbmh = c.asSubclass(BoundMethodHandle.class);
 436                         SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh);
 437                         assert(d != null) : cbmh.getName();
 438                         assert(d.clazz == cbmh);
 439                         assert(d == lookupCache(d.typeChars));
 440                     }
 441                 }
 442             } catch (Throwable e) {
 443                 throw newInternalError(e);
 444             }
 445 
 446             for (SpeciesData d : CACHE.values()) {
 447                 d.initForBootstrap();
 448             }
 449             // Note:  Do not simplify this, because INIT_DONE must not be
 450             // a compile-time constant during bootstrapping.
 451             INIT_DONE = Boolean.TRUE;
 452         }
 453     }
 454 
 455     static SpeciesData getSpeciesData(String types) {
 456         return SpeciesData.get(types);
 457     }
 458 
 459     /**


 569 
 570             // emit static types and SPECIES_DATA fields
 571             cw.visitField(NOT_ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd();
 572 
 573             // emit bound argument fields
 574             for (int i = 0; i < types.length(); ++i) {
 575                 final char t = types.charAt(i);
 576                 final String fieldName = makeFieldName(types, i);
 577                 final String fieldDesc = t == 'L' ? JLO_SIG : String.valueOf(t);
 578                 cw.visitField(ACC_FINAL, fieldName, fieldDesc, null, null).visitEnd();
 579             }
 580 
 581             MethodVisitor mv;
 582 
 583             // emit constructor
 584             mv = cw.visitMethod(ACC_PRIVATE, "<init>", makeSignature(types, true), null, null);
 585             mv.visitCode();
 586             mv.visitVarInsn(ALOAD, 0); // this
 587             mv.visitVarInsn(ALOAD, 1); // type
 588             mv.visitVarInsn(ALOAD, 2); // form
 589 
 590             mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true), false);
 591 
 592             for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
 593                 // i counts the arguments, j counts corresponding argument slots
 594                 char t = types.charAt(i);
 595                 mv.visitVarInsn(ALOAD, 0);
 596                 mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
 597                 mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
 598                 if (t == 'J' || t == 'D') {
 599                     ++j; // adjust argument register access
 600                 }
 601             }
 602 
 603             mv.visitInsn(RETURN);
 604             mv.visitMaxs(0, 0);
 605             mv.visitEnd();
 606 
 607             // emit implementation of speciesData()
 608             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
 609             mv.visitCode();
 610             mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
 611             mv.visitInsn(ARETURN);
 612             mv.visitMaxs(0, 0);
 613             mv.visitEnd();
 614 
 615             // emit implementation of fieldCount()
 616             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "fieldCount", INT_SIG, null, null);
 617             mv.visitCode();
 618             int fc = types.length();
 619             if (fc <= (ICONST_5 - ICONST_0)) {
 620                 mv.visitInsn(ICONST_0 + fc);
 621             } else {
 622                 mv.visitIntInsn(SIPUSH, fc);
 623             }
 624             mv.visitInsn(IRETURN);
 625             mv.visitMaxs(0, 0);
 626             mv.visitEnd();

 627             // emit make()  ...factory method wrapping constructor
 628             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_STATIC, "make", makeSignature(types, false), null, null);
 629             mv.visitCode();
 630             // make instance
 631             mv.visitTypeInsn(NEW, className);
 632             mv.visitInsn(DUP);
 633             // load mt, lf
 634             mv.visitVarInsn(ALOAD, 0);  // type
 635             mv.visitVarInsn(ALOAD, 1);  // form
 636             // load factory method arguments
 637             for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
 638                 // i counts the arguments, j counts corresponding argument slots
 639                 char t = types.charAt(i);
 640                 mv.visitVarInsn(typeLoadOp(t), j + 2); // parameters start at 3
 641                 if (t == 'J' || t == 'D') {
 642                     ++j; // adjust argument register access
 643                 }
 644             }
 645 
 646             // finally, invoke the constructor and return
 647             mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
 648             mv.visitInsn(ARETURN);
 649             mv.visitMaxs(0, 0);
 650             mv.visitEnd();
 651 
 652             // emit copyWith()
 653             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWith", makeSignature("", false), null, null);
 654             mv.visitCode();
 655             // make instance
 656             mv.visitTypeInsn(NEW, className);
 657             mv.visitInsn(DUP);
 658             // load mt, lf
 659             mv.visitVarInsn(ALOAD, 1);
 660             mv.visitVarInsn(ALOAD, 2);
 661             // put fields on the stack
 662             emitPushFields(types, className, mv);
 663             // finally, invoke the constructor and return
 664             mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
 665             mv.visitInsn(ARETURN);




 379 
 380         SpeciesData extendWith(byte type) {
 381             return extendWith(BasicType.basicType(type));
 382         }
 383 
 384         SpeciesData extendWith(BasicType type) {
 385             int ord = type.ordinal();
 386             SpeciesData d = extensions[ord];
 387             if (d != null)  return d;
 388             extensions[ord] = d = get(typeChars+type.basicTypeChar());
 389             return d;
 390         }
 391 
 392         private static SpeciesData get(String types) {
 393             // Acquire cache lock for query.
 394             SpeciesData d = lookupCache(types);
 395             if (!d.isPlaceholder())
 396                 return d;
 397             synchronized (d) {
 398                 // Use synch. on the placeholder to prevent multiple instantiation of one species.
 399                 SpeciesData d2 = lookupCache(types);
 400                 if (d2.isPlaceholder()) {
 401                     Class<? extends BoundMethodHandle> bmhcl = Factory.generateConcreteBMHClass(types);
 402                     // install new SpeciesData into cache
 403                     d2 = Factory.speciesDataFromConcreteBMHClass(bmhcl);
 404                     assert(!d2.isPlaceholder());
 405                     updateCache(d2.typeChars, d2);
 406                 }
 407                 d = d2;
 408             }
 409             return d;
 410         }
 411         static SpeciesData getForClass(String types, Class<? extends BoundMethodHandle> clazz) {
 412             // clazz is a new class which is initializing its SPECIES_DATA field
 413             return new SpeciesData(types, clazz);
 414         }
 415         private static synchronized SpeciesData lookupCache(String types) {
 416             SpeciesData d = CACHE.get(types);
 417             if (d != null)  return d;
 418             d = new SpeciesData(types);
 419             assert(d.isPlaceholder());
 420             CACHE.put(types, d);
 421             return d;
 422         }
 423         private static synchronized SpeciesData updateCache(String types, SpeciesData d) {
 424             SpeciesData d2;
 425             assert((d2 = CACHE.get(types)) == null || d2.isPlaceholder());
 426             assert(!d.isPlaceholder());
 427             CACHE.put(types, d);
 428             return d;
 429         }
 430 
 431         static {
 432             // pre-fill the BMH speciesdata cache with BMH's inner classes
 433             final Class<BoundMethodHandle> rootCls = BoundMethodHandle.class;
 434             try {
 435                 for (Class<?> c : rootCls.getDeclaredClasses()) {
 436                     if (rootCls.isAssignableFrom(c)) {
 437                         final Class<? extends BoundMethodHandle> cbmh = c.asSubclass(BoundMethodHandle.class);
 438                         SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh);
 439                         assert(d != null) : cbmh.getName();
 440                         assert(d.clazz == cbmh);
 441                         updateCache(d.typeChars, d);
 442                     }
 443                 }
 444             } catch (Throwable e) {
 445                 throw newInternalError(e);
 446             }
 447 
 448             for (SpeciesData d : CACHE.values()) {
 449                 d.initForBootstrap();
 450             }
 451             // Note:  Do not simplify this, because INIT_DONE must not be
 452             // a compile-time constant during bootstrapping.
 453             INIT_DONE = Boolean.TRUE;
 454         }
 455     }
 456 
 457     static SpeciesData getSpeciesData(String types) {
 458         return SpeciesData.get(types);
 459     }
 460 
 461     /**


 571 
 572             // emit static types and SPECIES_DATA fields
 573             cw.visitField(NOT_ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd();
 574 
 575             // emit bound argument fields
 576             for (int i = 0; i < types.length(); ++i) {
 577                 final char t = types.charAt(i);
 578                 final String fieldName = makeFieldName(types, i);
 579                 final String fieldDesc = t == 'L' ? JLO_SIG : String.valueOf(t);
 580                 cw.visitField(ACC_FINAL, fieldName, fieldDesc, null, null).visitEnd();
 581             }
 582 
 583             MethodVisitor mv;
 584 
 585             // emit constructor
 586             mv = cw.visitMethod(ACC_PRIVATE, "<init>", makeSignature(types, true), null, null);
 587             mv.visitCode();
 588             mv.visitVarInsn(ALOAD, 0); // this
 589             mv.visitVarInsn(ALOAD, 1); // type
 590             mv.visitVarInsn(ALOAD, 2); // form

 591             mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true), false);

 592             for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
 593                 // i counts the arguments, j counts corresponding argument slots
 594                 char t = types.charAt(i);
 595                 mv.visitVarInsn(ALOAD, 0);
 596                 mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
 597                 mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
 598                 if (t == 'J' || t == 'D') {
 599                     ++j; // adjust argument register access
 600                 }
 601             }

 602             mv.visitInsn(RETURN);
 603             mv.visitMaxs(0, 0);
 604             mv.visitEnd();
 605 
 606             // emit implementation of speciesData()
 607             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
 608             mv.visitCode();
 609             mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
 610             mv.visitInsn(ARETURN);
 611             mv.visitMaxs(0, 0);
 612             mv.visitEnd();
 613 
 614             // emit implementation of fieldCount()
 615             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "fieldCount", INT_SIG, null, null);
 616             mv.visitCode();
 617             int fc = types.length();
 618             if (fc <= (ICONST_5 - ICONST_0)) {
 619                 mv.visitInsn(ICONST_0 + fc);
 620             } else {
 621                 mv.visitIntInsn(SIPUSH, fc);
 622             }
 623             mv.visitInsn(IRETURN);
 624             mv.visitMaxs(0, 0);
 625             mv.visitEnd();
 626 
 627             // emit make()  ...factory method wrapping constructor
 628             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_STATIC, "make", makeSignature(types, false), null, null);
 629             mv.visitCode();
 630             // make instance
 631             mv.visitTypeInsn(NEW, className);
 632             mv.visitInsn(DUP);
 633             // load mt, lf
 634             mv.visitVarInsn(ALOAD, 0);  // type
 635             mv.visitVarInsn(ALOAD, 1);  // form
 636             // load factory method arguments
 637             for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
 638                 // i counts the arguments, j counts corresponding argument slots
 639                 char t = types.charAt(i);
 640                 mv.visitVarInsn(typeLoadOp(t), j + 2); // parameters start at 3
 641                 if (t == 'J' || t == 'D') {
 642                     ++j; // adjust argument register access
 643                 }
 644             }

 645             // finally, invoke the constructor and return
 646             mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
 647             mv.visitInsn(ARETURN);
 648             mv.visitMaxs(0, 0);
 649             mv.visitEnd();
 650 
 651             // emit copyWith()
 652             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWith", makeSignature("", false), null, null);
 653             mv.visitCode();
 654             // make instance
 655             mv.visitTypeInsn(NEW, className);
 656             mv.visitInsn(DUP);
 657             // load mt, lf
 658             mv.visitVarInsn(ALOAD, 1);
 659             mv.visitVarInsn(ALOAD, 2);
 660             // put fields on the stack
 661             emitPushFields(types, className, mv);
 662             // finally, invoke the constructor and return
 663             mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
 664             mv.visitInsn(ARETURN);


< prev index next >