jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java
changeset 26467 d69abed3a07d
parent 25859 3317bb8137f4
child 26469 e6bc14fae1cf
--- 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);