src/share/classes/java/lang/invoke/MethodHandle.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/MethodHandle.java

Print this page
rev 10273 : 8049555: Move varargsArray from sun.invoke.util package to java.lang.invoke
Reviewed-by: ?
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 10277 : 8050173: Add j.l.i.MethodHandle.copyWith(MethodType, LambdaForm)
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10278 : imported patch isInvokeSpecial
rev 10279 : 8050057: Improve caching of MethodHandle reinvokers
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com


1375     }
1376 
1377     /*non-public*/
1378     Object internalValues() {
1379         return null;
1380     }
1381 
1382     /*non-public*/
1383     Object internalProperties() {
1384         // Override to something to follow this.form, like "\n& FOO=bar"
1385         return "";
1386     }
1387 
1388     //// Method handle implementation methods.
1389     //// Sub-classes can override these default implementations.
1390     //// All these methods assume arguments are already validated.
1391 
1392     /*non-public*/
1393     abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
1394 
1395     /*non-public*/
1396     BoundMethodHandle rebind() {
1397         // Bind 'this' into a new invoker, of the known class BMH.
1398         MethodType type2 = type();
1399         LambdaForm form2 = reinvokerForm(this);
1400         // form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) }
1401         return BoundMethodHandle.bindSingle(type2, form2, this);
1402     }
1403 
1404     /*non-public*/
1405     MethodHandle reinvokerTarget() {
1406         throw new InternalError("not a reinvoker MH: "+this.getClass().getName()+": "+this);
1407     }
1408 
1409     /** Create a LF which simply reinvokes a target of the given basic type.
1410      *  The target MH must override {@link #reinvokerTarget} to provide the target.
1411      */
1412     static LambdaForm reinvokerForm(MethodHandle target) {
1413         MethodType mtype = target.type().basicType();
1414         LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE);
1415         if (reinvoker != null)  return reinvoker;
1416         if (mtype.parameterSlotCount() >= MethodType.MAX_MH_ARITY)
1417             return makeReinvokerForm(target.type(), target);  // cannot cache this
1418         reinvoker = makeReinvokerForm(mtype, null);
1419         return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, reinvoker);
1420     }
1421     private static LambdaForm makeReinvokerForm(MethodType mtype, MethodHandle customTargetOrNull) {
1422         boolean customized = (customTargetOrNull != null);
1423         MethodHandle MH_invokeBasic = customized ? null : MethodHandles.basicInvoker(mtype);
1424         final int THIS_BMH    = 0;
1425         final int ARG_BASE    = 1;
1426         final int ARG_LIMIT   = ARG_BASE + mtype.parameterCount();
1427         int nameCursor = ARG_LIMIT;
1428         final int NEXT_MH     = customized ? -1 : nameCursor++;
1429         final int REINVOKE    = nameCursor++;
1430         LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
1431         Object[] targetArgs;
1432         MethodHandle targetMH;
1433         if (customized) {
1434             targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class);
1435             targetMH = customTargetOrNull;
1436         } else {
1437             names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]);
1438             targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class);
1439             targetArgs[0] = names[NEXT_MH];  // overwrite this MH with next MH
1440             targetMH = MethodHandles.basicInvoker(mtype);
1441         }
1442         names[REINVOKE] = new LambdaForm.Name(targetMH, targetArgs);
1443         return new LambdaForm("BMH.reinvoke", ARG_LIMIT, names);
1444     }
1445 
1446     private static final LambdaForm.NamedFunction NF_reinvokerTarget;
1447     static {
1448         try {
1449             NF_reinvokerTarget = new LambdaForm.NamedFunction(MethodHandle.class
1450                 .getDeclaredMethod("reinvokerTarget"));
1451         } catch (ReflectiveOperationException ex) {
1452             throw newInternalError(ex);
1453         }
1454     }
1455 
1456     /**
1457      * Replace the old lambda form of this method handle with a new one.
1458      * The new one must be functionally equivalent to the old one.
1459      * Threads may continue running the old form indefinitely,
1460      * but it is likely that the new one will be preferred for new executions.
1461      * Use with discretion.
1462      */
1463     /*non-public*/
1464     void updateForm(LambdaForm newForm) {
1465         if (form == newForm)  return;
1466         assert(this instanceof DirectMethodHandle && this.internalMemberName().isStatic());
1467         // ISSUE: Should we have a memory fence here?
1468         UNSAFE.putObject(this, FORM_OFFSET, newForm);
1469         this.form.prepare();  // as in MethodHandle.<init>
1470     }
1471 
1472     private static final long FORM_OFFSET;
1473     static {
1474         try {


1375     }
1376 
1377     /*non-public*/
1378     Object internalValues() {
1379         return null;
1380     }
1381 
1382     /*non-public*/
1383     Object internalProperties() {
1384         // Override to something to follow this.form, like "\n& FOO=bar"
1385         return "";
1386     }
1387 
1388     //// Method handle implementation methods.
1389     //// Sub-classes can override these default implementations.
1390     //// All these methods assume arguments are already validated.
1391 
1392     /*non-public*/
1393     abstract MethodHandle copyWith(MethodType mt, LambdaForm lf);
1394 
1395     /** Require this method handle to be a BMH, or else replace it with a "wrapper" BMH.
1396      *  Many transforms are implemented only for BMHs.
1397      *  @return a behaviorally equivalent BMH













1398      */
1399     abstract BoundMethodHandle rebind();










































1400 
1401     /**
1402      * Replace the old lambda form of this method handle with a new one.
1403      * The new one must be functionally equivalent to the old one.
1404      * Threads may continue running the old form indefinitely,
1405      * but it is likely that the new one will be preferred for new executions.
1406      * Use with discretion.
1407      */
1408     /*non-public*/
1409     void updateForm(LambdaForm newForm) {
1410         if (form == newForm)  return;
1411         assert(this instanceof DirectMethodHandle && this.internalMemberName().isStatic());
1412         // ISSUE: Should we have a memory fence here?
1413         UNSAFE.putObject(this, FORM_OFFSET, newForm);
1414         this.form.prepare();  // as in MethodHandle.<init>
1415     }
1416 
1417     private static final long FORM_OFFSET;
1418     static {
1419         try {
src/share/classes/java/lang/invoke/MethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File