--- old/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java 2015-10-28 09:54:40.000000000 +0100 +++ new/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java 2015-10-28 09:54:40.000000000 +0100 @@ -396,19 +396,21 @@ return d; synchronized (d) { // Use synch. on the placeholder to prevent multiple instantiation of one species. - // Creating this class forces a recursive call to getForClass. - if (lookupCache(types).isPlaceholder()) - Factory.generateConcreteBMHClass(types); - } - // Reacquire cache lock. - d = lookupCache(types); - // Class loading must have upgraded the cache. - assert(d != null && !d.isPlaceholder()); + SpeciesData d2 = lookupCache(types); + if (d2.isPlaceholder()) { + Class bmhcl = Factory.generateConcreteBMHClass(types); + // install new SpeciesData into cache + d2 = Factory.speciesDataFromConcreteBMHClass(bmhcl); + assert(!d2.isPlaceholder()); + updateCache(d2.typeChars, d2); + } + d = d2; + } return d; } static SpeciesData getForClass(String types, Class clazz) { // clazz is a new class which is initializing its SPECIES_DATA field - return updateCache(types, new SpeciesData(types, clazz)); + return new SpeciesData(types, clazz); } private static synchronized SpeciesData lookupCache(String types) { SpeciesData d = CACHE.get(types); @@ -436,7 +438,7 @@ SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh); assert(d != null) : cbmh.getName(); assert(d.clazz == cbmh); - assert(d == lookupCache(d.typeChars)); + updateCache(d.typeChars, d); } } } catch (Throwable e) { @@ -586,9 +588,7 @@ mv.visitVarInsn(ALOAD, 0); // this mv.visitVarInsn(ALOAD, 1); // type mv.visitVarInsn(ALOAD, 2); // form - mv.visitMethodInsn(INVOKESPECIAL, BMH, "", makeSignature("", true), false); - for (int i = 0, j = 0; i < types.length(); ++i, ++j) { // i counts the arguments, j counts corresponding argument slots char t = types.charAt(i); @@ -599,7 +599,6 @@ ++j; // adjust argument register access } } - mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); @@ -624,6 +623,7 @@ mv.visitInsn(IRETURN); mv.visitMaxs(0, 0); mv.visitEnd(); + // emit make() ...factory method wrapping constructor mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_STATIC, "make", makeSignature(types, false), null, null); mv.visitCode(); @@ -642,7 +642,6 @@ ++j; // adjust argument register access } } - // finally, invoke the constructor and return mv.visitMethodInsn(INVOKESPECIAL, className, "", makeSignature(types, true), false); mv.visitInsn(ARETURN);