src/share/classes/java/lang/invoke/BoundMethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/share/classes/java/lang/invoke

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

Print this page
rev 10274 : 8050052: Small cleanups in java.lang.invoke code
Reviewed-by: ?
rev 10276 : 8050166: Get rid of some package-private methods on arguments in j.l.i.MethodHandle
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10279 : 8050057: Improve caching of MethodHandle reinvokers
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com


 100     }
 101     /*non-public*/
 102     BoundMethodHandle bindArgumentJ(int pos, long value) {
 103         MethodType type = type().dropParameterTypes(pos, pos+1);
 104         LambdaForm form = internalForm().bind(1+pos, speciesData());
 105         return copyWithExtendJ(type, form, value);
 106     }
 107     /*non-public*/
 108     BoundMethodHandle bindArgumentF(int pos, float value) {
 109         MethodType type = type().dropParameterTypes(pos, pos+1);
 110         LambdaForm form = internalForm().bind(1+pos, speciesData());
 111         return copyWithExtendF(type, form, value);
 112     }
 113     /*non-public*/
 114     BoundMethodHandle bindArgumentD(int pos, double value) {
 115         MethodType type = type().dropParameterTypes(pos, pos + 1);
 116         LambdaForm form = internalForm().bind(1+pos, speciesData());
 117         return copyWithExtendD(type, form, value);
 118     }
 119 

























 120     /**
 121      * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a
 122      * static field containing this value, and they must accordingly implement this method.
 123      */
 124     /*non-public*/ abstract SpeciesData speciesData();
 125 
 126     /**
 127      * Return the number of fields in this BMH.  Equivalent to speciesData().fieldCount().
 128      */
 129     /*non-public*/ abstract int fieldCount();
 130 
 131     @Override
 132     Object internalProperties() {
 133         return "\n& BMH="+internalValues();
 134     }
 135 
 136     @Override
 137     final Object internalValues() {
 138         Object[] boundValues = new Object[speciesData().fieldCount()];
 139         for (int i = 0; i < boundValues.length; ++i) {


 151             case F_TYPE: return (float)  speciesData().getters[i].invokeBasic(this);
 152             case D_TYPE: return (double) speciesData().getters[i].invokeBasic(this);
 153             }
 154         } catch (Throwable ex) {
 155             throw newInternalError(ex);
 156         }
 157         throw new InternalError("unexpected type: " + speciesData().typeChars+"."+i);
 158     }
 159 
 160     //
 161     // cloning API
 162     //
 163 
 164     /*non-public*/ abstract BoundMethodHandle copyWith(MethodType mt, LambdaForm lf);
 165     /*non-public*/ abstract BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg);
 166     /*non-public*/ abstract BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int    narg);
 167     /*non-public*/ abstract BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long   narg);
 168     /*non-public*/ abstract BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float  narg);
 169     /*non-public*/ abstract BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg);
 170 
 171     // The following is a grossly irregular hack:
 172     @Override MethodHandle reinvokerTarget() {
 173         try {
 174             return (MethodHandle) arg(0);
 175         } catch (Throwable ex) {
 176             throw newInternalError(ex);
 177         }
 178     }
 179 
 180     //
 181     // concrete BMH classes required to close bootstrap loops
 182     //
 183 
 184     private  // make it private to force users to access the enclosing class first
 185     static final class Species_L extends BoundMethodHandle {
 186         final Object argL0;
 187         private Species_L(MethodType mt, LambdaForm lf, Object argL0) {
 188             super(mt, lf);
 189             this.argL0 = argL0;
 190         }
 191         // The following is a grossly irregular hack:
 192         @Override MethodHandle reinvokerTarget() { return (MethodHandle) argL0; }
 193         @Override
 194         /*non-public*/ SpeciesData speciesData() {
 195             return SPECIES_DATA;
 196         }
 197         @Override
 198         /*non-public*/ int fieldCount() {
 199             return 1;
 200         }
 201         /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
 202         /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
 203             return new Species_L(mt, lf, argL0);
 204         }
 205         @Override
 206         /*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
 207             return new Species_L(mt, lf, argL0);
 208         }
 209         @Override
 210         /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
 211             try {
 212                 return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);


 552             mv.visitVarInsn(ALOAD, 1); // type
 553             mv.visitVarInsn(ALOAD, 2); // form
 554 
 555             mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true), false);
 556 
 557             for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
 558                 // i counts the arguments, j counts corresponding argument slots
 559                 char t = types.charAt(i);
 560                 mv.visitVarInsn(ALOAD, 0);
 561                 mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
 562                 mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
 563                 if (t == 'J' || t == 'D') {
 564                     ++j; // adjust argument register access
 565                 }
 566             }
 567 
 568             mv.visitInsn(RETURN);
 569             mv.visitMaxs(0, 0);
 570             mv.visitEnd();
 571 
 572             // emit implementation of reinvokerTarget()
 573             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "reinvokerTarget", "()" + MH_SIG, null, null);
 574             mv.visitCode();
 575             mv.visitVarInsn(ALOAD, 0);
 576             mv.visitFieldInsn(GETFIELD, className, "argL0", JLO_SIG);
 577             mv.visitTypeInsn(CHECKCAST, MH);
 578             mv.visitInsn(ARETURN);
 579             mv.visitMaxs(0, 0);
 580             mv.visitEnd();
 581 
 582             // emit implementation of speciesData()
 583             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
 584             mv.visitCode();
 585             mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
 586             mv.visitInsn(ARETURN);
 587             mv.visitMaxs(0, 0);
 588             mv.visitEnd();
 589 
 590             // emit implementation of fieldCount()
 591             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "fieldCount", INT_SIG, null, null);
 592             mv.visitCode();
 593             int fc = types.length();
 594             if (fc <= (ICONST_5 - ICONST_0)) {
 595                 mv.visitInsn(ICONST_0 + fc);
 596             } else {
 597                 mv.visitIntInsn(SIPUSH, fc);
 598             }
 599             mv.visitInsn(IRETURN);
 600             mv.visitMaxs(0, 0);
 601             mv.visitEnd();




 100     }
 101     /*non-public*/
 102     BoundMethodHandle bindArgumentJ(int pos, long value) {
 103         MethodType type = type().dropParameterTypes(pos, pos+1);
 104         LambdaForm form = internalForm().bind(1+pos, speciesData());
 105         return copyWithExtendJ(type, form, value);
 106     }
 107     /*non-public*/
 108     BoundMethodHandle bindArgumentF(int pos, float value) {
 109         MethodType type = type().dropParameterTypes(pos, pos+1);
 110         LambdaForm form = internalForm().bind(1+pos, speciesData());
 111         return copyWithExtendF(type, form, value);
 112     }
 113     /*non-public*/
 114     BoundMethodHandle bindArgumentD(int pos, double value) {
 115         MethodType type = type().dropParameterTypes(pos, pos + 1);
 116         LambdaForm form = internalForm().bind(1+pos, speciesData());
 117         return copyWithExtendD(type, form, value);
 118     }
 119 
 120     @Override
 121     BoundMethodHandle rebind() {
 122         if (!tooComplex()) {
 123             return this;
 124         }
 125         return makeReinvoker(this);
 126     }
 127 
 128     private boolean tooComplex() {
 129         return (fieldCount() > FIELD_COUNT_THRESHOLD ||
 130                 form.expressionCount() > FORM_EXPRESSION_THRESHOLD);
 131     }
 132     private static int FIELD_COUNT_THRESHOLD = 12;  // largest convenient BMH field count
 133     private static int FORM_EXPRESSION_THRESHOLD = 24;  // largest convenient BMH expression count
 134 
 135     /**
 136      * A reinvoker MH has this form:
 137      * {@code lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) }}
 138      */
 139     static BoundMethodHandle makeReinvoker(MethodHandle target) {
 140         LambdaForm form = DelegatingMethodHandle.makeReinvokerForm(
 141                 target, MethodTypeForm.LF_REBIND, Species_L.SPECIES_DATA.getterFunction(0) );
 142         return Species_L.make(target.type(), form, target);
 143     }
 144 
 145     /**
 146      * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a
 147      * static field containing this value, and they must accordingly implement this method.
 148      */
 149     /*non-public*/ abstract SpeciesData speciesData();
 150 
 151     /**
 152      * Return the number of fields in this BMH.  Equivalent to speciesData().fieldCount().
 153      */
 154     /*non-public*/ abstract int fieldCount();
 155 
 156     @Override
 157     Object internalProperties() {
 158         return "\n& BMH="+internalValues();
 159     }
 160 
 161     @Override
 162     final Object internalValues() {
 163         Object[] boundValues = new Object[speciesData().fieldCount()];
 164         for (int i = 0; i < boundValues.length; ++i) {


 176             case F_TYPE: return (float)  speciesData().getters[i].invokeBasic(this);
 177             case D_TYPE: return (double) speciesData().getters[i].invokeBasic(this);
 178             }
 179         } catch (Throwable ex) {
 180             throw newInternalError(ex);
 181         }
 182         throw new InternalError("unexpected type: " + speciesData().typeChars+"."+i);
 183     }
 184 
 185     //
 186     // cloning API
 187     //
 188 
 189     /*non-public*/ abstract BoundMethodHandle copyWith(MethodType mt, LambdaForm lf);
 190     /*non-public*/ abstract BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg);
 191     /*non-public*/ abstract BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int    narg);
 192     /*non-public*/ abstract BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long   narg);
 193     /*non-public*/ abstract BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float  narg);
 194     /*non-public*/ abstract BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg);
 195 









 196     //
 197     // concrete BMH classes required to close bootstrap loops
 198     //
 199 
 200     private  // make it private to force users to access the enclosing class first
 201     static final class Species_L extends BoundMethodHandle {
 202         final Object argL0;
 203         private Species_L(MethodType mt, LambdaForm lf, Object argL0) {
 204             super(mt, lf);
 205             this.argL0 = argL0;
 206         }


 207         @Override
 208         /*non-public*/ SpeciesData speciesData() {
 209             return SPECIES_DATA;
 210         }
 211         @Override
 212         /*non-public*/ int fieldCount() {
 213             return 1;
 214         }
 215         /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
 216         /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
 217             return new Species_L(mt, lf, argL0);
 218         }
 219         @Override
 220         /*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
 221             return new Species_L(mt, lf, argL0);
 222         }
 223         @Override
 224         /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) {
 225             try {
 226                 return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor().invokeBasic(mt, lf, argL0, narg);


 566             mv.visitVarInsn(ALOAD, 1); // type
 567             mv.visitVarInsn(ALOAD, 2); // form
 568 
 569             mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true), false);
 570 
 571             for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
 572                 // i counts the arguments, j counts corresponding argument slots
 573                 char t = types.charAt(i);
 574                 mv.visitVarInsn(ALOAD, 0);
 575                 mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
 576                 mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
 577                 if (t == 'J' || t == 'D') {
 578                     ++j; // adjust argument register access
 579                 }
 580             }
 581 
 582             mv.visitInsn(RETURN);
 583             mv.visitMaxs(0, 0);
 584             mv.visitEnd();
 585 










 586             // emit implementation of speciesData()
 587             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
 588             mv.visitCode();
 589             mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
 590             mv.visitInsn(ARETURN);
 591             mv.visitMaxs(0, 0);
 592             mv.visitEnd();
 593 
 594             // emit implementation of fieldCount()
 595             mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "fieldCount", INT_SIG, null, null);
 596             mv.visitCode();
 597             int fc = types.length();
 598             if (fc <= (ICONST_5 - ICONST_0)) {
 599                 mv.visitInsn(ICONST_0 + fc);
 600             } else {
 601                 mv.visitIntInsn(SIPUSH, fc);
 602             }
 603             mv.visitInsn(IRETURN);
 604             mv.visitMaxs(0, 0);
 605             mv.visitEnd();


src/share/classes/java/lang/invoke/BoundMethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File