< 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
*** 394,416 ****
SpeciesData d = lookupCache(types);
if (!d.isPlaceholder())
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());
return d;
}
static SpeciesData getForClass(String types, Class<? extends BoundMethodHandle> clazz) {
// clazz is a new class which is initializing its SPECIES_DATA field
! return updateCache(types, new SpeciesData(types, clazz));
}
private static synchronized SpeciesData lookupCache(String types) {
SpeciesData d = CACHE.get(types);
if (d != null) return d;
d = new SpeciesData(types);
--- 394,418 ----
SpeciesData d = lookupCache(types);
if (!d.isPlaceholder())
return d;
synchronized (d) {
// Use synch. on the placeholder to prevent multiple instantiation of one species.
! SpeciesData d2 = lookupCache(types);
! if (d2.isPlaceholder()) {
! Class<? extends BoundMethodHandle> 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<? extends BoundMethodHandle> clazz) {
// clazz is a new class which is initializing its SPECIES_DATA field
! return new SpeciesData(types, clazz);
}
private static synchronized SpeciesData lookupCache(String types) {
SpeciesData d = CACHE.get(types);
if (d != null) return d;
d = new SpeciesData(types);
*** 434,444 ****
if (rootCls.isAssignableFrom(c)) {
final Class<? extends BoundMethodHandle> cbmh = c.asSubclass(BoundMethodHandle.class);
SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh);
assert(d != null) : cbmh.getName();
assert(d.clazz == cbmh);
! assert(d == lookupCache(d.typeChars));
}
}
} catch (Throwable e) {
throw newInternalError(e);
}
--- 436,446 ----
if (rootCls.isAssignableFrom(c)) {
final Class<? extends BoundMethodHandle> cbmh = c.asSubclass(BoundMethodHandle.class);
SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh);
assert(d != null) : cbmh.getName();
assert(d.clazz == cbmh);
! updateCache(d.typeChars, d);
}
}
} catch (Throwable e) {
throw newInternalError(e);
}
*** 584,607 ****
mv = cw.visitMethod(ACC_PRIVATE, "<init>", makeSignature(types, true), null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0); // this
mv.visitVarInsn(ALOAD, 1); // type
mv.visitVarInsn(ALOAD, 2); // form
-
mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", 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);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
if (t == 'J' || t == 'D') {
++j; // adjust argument register access
}
}
-
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
// emit implementation of speciesData()
--- 586,606 ----
*** 622,631 ****
--- 621,631 ----
mv.visitIntInsn(SIPUSH, fc);
}
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();
// make instance
mv.visitTypeInsn(NEW, className);
*** 640,650 ****
mv.visitVarInsn(typeLoadOp(t), j + 2); // parameters start at 3
if (t == 'J' || t == 'D') {
++j; // adjust argument register access
}
}
-
// finally, invoke the constructor and return
mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
mv.visitInsn(ARETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
--- 640,649 ----
< prev index next >