--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Sep 10 19:19:47 2014 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Sep 10 19:19:47 2014 +0400
@@ -50,9 +50,9 @@
*
* All bound arguments are encapsulated in dedicated species.
*/
-/* non-public */ abstract class BoundMethodHandle extends MethodHandle {
+/*non-public*/ abstract class BoundMethodHandle extends MethodHandle {
- /* non-public */ BoundMethodHandle(MethodType type, LambdaForm form) {
+ /*non-public*/ BoundMethodHandle(MethodType type, LambdaForm form) {
super(type, form);
}
@@ -66,15 +66,15 @@
switch (xtype) {
case L_TYPE:
if (true) return bindSingle(type, form, x); // Use known fast path.
- return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(L_TYPE).constructor[0].invokeBasic(type, form, x);
+ return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(L_TYPE).constructor().invokeBasic(type, form, x);
case I_TYPE:
- return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(I_TYPE).constructor[0].invokeBasic(type, form, ValueConversions.widenSubword(x));
+ return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(I_TYPE).constructor().invokeBasic(type, form, ValueConversions.widenSubword(x));
case J_TYPE:
- return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(J_TYPE).constructor[0].invokeBasic(type, form, (long) x);
+ return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(J_TYPE).constructor().invokeBasic(type, form, (long) x);
case F_TYPE:
- return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(F_TYPE).constructor[0].invokeBasic(type, form, (float) x);
+ return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(F_TYPE).constructor().invokeBasic(type, form, (float) x);
case D_TYPE:
- return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(D_TYPE).constructor[0].invokeBasic(type, form, (double) x);
+ return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(D_TYPE).constructor().invokeBasic(type, form, (double) x);
default : throw newInternalError("unexpected xtype: " + xtype);
}
} catch (Throwable t) {
@@ -139,8 +139,8 @@
/*non-public*/ abstract int fieldCount();
@Override
- final Object internalProperties() {
- return "/BMH="+internalValues();
+ Object internalProperties() {
+ return "\n& BMH="+internalValues();
}
@Override
@@ -219,7 +219,7 @@
@Override
/*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
try {
- return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg);
+ return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
} catch (Throwable ex) {
throw uncaughtException(ex);
}
@@ -227,7 +227,7 @@
@Override
/*non-public*/ final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
try {
- return (BoundMethodHandle) SPECIES_DATA.extendWith(I_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg);
+ return (BoundMethodHandle) SPECIES_DATA.extendWith(I_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
} catch (Throwable ex) {
throw uncaughtException(ex);
}
@@ -235,7 +235,7 @@
@Override
/*non-public*/ final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
try {
- return (BoundMethodHandle) SPECIES_DATA.extendWith(J_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg);
+ return (BoundMethodHandle) SPECIES_DATA.extendWith(J_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
} catch (Throwable ex) {
throw uncaughtException(ex);
}
@@ -243,7 +243,7 @@
@Override
/*non-public*/ final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
try {
- return (BoundMethodHandle) SPECIES_DATA.extendWith(F_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg);
+ return (BoundMethodHandle) SPECIES_DATA.extendWith(F_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
} catch (Throwable ex) {
throw uncaughtException(ex);
}
@@ -251,7 +251,7 @@
@Override
/*non-public*/ final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
try {
- return (BoundMethodHandle) SPECIES_DATA.extendWith(D_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg);
+ return (BoundMethodHandle) SPECIES_DATA.extendWith(D_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);
} catch (Throwable ex) {
throw uncaughtException(ex);
}
@@ -268,18 +268,20 @@
* The fields are immutable; their values are fully specified at object construction.
* Each BMH type supplies an array of getter functions which may be used in lambda forms.
* A BMH is constructed by cloning a shorter BMH and adding one or more new field values.
- * As a degenerate and common case, the "shorter BMH" can be missing, and contributes zero prior fields.
+ * The shortest possible BMH has zero fields; its class is SimpleMethodHandle.
+ * BMH species are not interrelated by subtyping, even though it would appear that
+ * a shorter BMH could serve as a supertype of a longer one which extends it.
*/
static class SpeciesData {
- final String typeChars;
- final BasicType[] typeCodes;
- final Class<? extends BoundMethodHandle> clazz;
+ private final String typeChars;
+ private final BasicType[] typeCodes;
+ private final Class<? extends BoundMethodHandle> clazz;
// Bootstrapping requires circular relations MH -> BMH -> SpeciesData -> MH
// Therefore, we need a non-final link in the chain. Use array elements.
- final MethodHandle[] constructor;
- final MethodHandle[] getters;
- final NamedFunction[] nominalGetters;
- final SpeciesData[] extensions;
+ @Stable private final MethodHandle[] constructor;
+ @Stable private final MethodHandle[] getters;
+ @Stable private final NamedFunction[] nominalGetters;
+ @Stable private final SpeciesData[] extensions;
/*non-public*/ int fieldCount() {
return typeCodes.length;
@@ -290,9 +292,14 @@
/*non-public*/ char fieldTypeChar(int i) {
return typeChars.charAt(i);
}
-
+ Object fieldSignature() {
+ return typeChars;
+ }
+ public Class<? extends BoundMethodHandle> fieldHolder() {
+ return clazz;
+ }
public String toString() {
- return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+typeChars+"]";
+ return "SpeciesData<"+fieldSignature()+">";
}
/**
@@ -301,7 +308,20 @@
* getter.
*/
NamedFunction getterFunction(int i) {
- return nominalGetters[i];
+ NamedFunction nf = nominalGetters[i];
+ assert(nf.memberDeclaringClassOrNull() == fieldHolder());
+ assert(nf.returnType() == fieldType(i));
+ return nf;
+ }
+
+ NamedFunction[] getterFunctions() {
+ return nominalGetters;
+ }
+
+ MethodHandle[] getterHandles() { return getters; }
+
+ MethodHandle constructor() {
+ return constructor[0];
}
static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class);
@@ -324,7 +344,7 @@
private void initForBootstrap() {
assert(!INIT_DONE);
- if (constructor[0] == null) {
+ if (constructor() == null) {
String types = typeChars;
Factory.makeCtors(clazz, types, this.constructor);
Factory.makeGetters(clazz, types, this.getters);
@@ -508,19 +528,19 @@
* return new Species_LLI(mt, lf, argL0, argL1, argI2);
* }
* final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
- * return SPECIES_DATA.extendWith(L_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+ * return SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* }
* final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) {
- * return SPECIES_DATA.extendWith(I_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+ * return SPECIES_DATA.extendWith(I_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* }
* final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) {
- * return SPECIES_DATA.extendWith(J_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+ * return SPECIES_DATA.extendWith(J_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* }
* final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) {
- * return SPECIES_DATA.extendWith(F_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+ * return SPECIES_DATA.extendWith(F_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* }
* public final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) {
- * return SPECIES_DATA.extendWith(D_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+ * return SPECIES_DATA.extendWith(D_TYPE).constructor().invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* }
* }
* </pre>
@@ -653,16 +673,14 @@
char btChar = type.basicTypeChar();
mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWithExtend" + btChar, makeSignature(String.valueOf(btChar), false), null, E_THROWABLE);
mv.visitCode();
- // return SPECIES_DATA.extendWith(t).constructor[0].invokeBasic(mt, lf, argL0, ..., narg)
+ // return SPECIES_DATA.extendWith(t).constructor().invokeBasic(mt, lf, argL0, ..., narg)
// obtain constructor
mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
int iconstInsn = ICONST_0 + ord;
assert(iconstInsn <= ICONST_5);
mv.visitInsn(iconstInsn);
mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWith", BMHSPECIES_DATA_EWI_SIG, false);
- mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
- mv.visitInsn(ICONST_0);
- mv.visitInsn(AALOAD);
+ mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "constructor", "()" + MH_SIG, false);
// load mt, lf
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);