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 {
|