1354 |
1359 |
1355 /*non-public*/ |
1360 /*non-public*/ |
1356 MethodHandle rebind() { |
1361 MethodHandle rebind() { |
1357 // Bind 'this' into a new invoker, of the known class BMH. |
1362 // Bind 'this' into a new invoker, of the known class BMH. |
1358 MethodType type2 = type(); |
1363 MethodType type2 = type(); |
1359 LambdaForm form2 = reinvokerForm(type2.basicType()); |
1364 LambdaForm form2 = reinvokerForm(this); |
1360 // form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) } |
1365 // form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) } |
1361 return BoundMethodHandle.bindSingle(type2, form2, this); |
1366 return BoundMethodHandle.bindSingle(type2, form2, this); |
1362 } |
1367 } |
1363 |
1368 |
1364 /*non-public*/ |
1369 /*non-public*/ |
1367 } |
1372 } |
1368 |
1373 |
1369 /** Create a LF which simply reinvokes a target of the given basic type. |
1374 /** Create a LF which simply reinvokes a target of the given basic type. |
1370 * The target MH must override {@link #reinvokerTarget} to provide the target. |
1375 * The target MH must override {@link #reinvokerTarget} to provide the target. |
1371 */ |
1376 */ |
1372 static LambdaForm reinvokerForm(MethodType mtype) { |
1377 static LambdaForm reinvokerForm(MethodHandle target) { |
1373 mtype = mtype.basicType(); |
1378 MethodType mtype = target.type().basicType(); |
1374 LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE); |
1379 LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE); |
1375 if (reinvoker != null) return reinvoker; |
1380 if (reinvoker != null) return reinvoker; |
1376 MethodHandle MH_invokeBasic = MethodHandles.basicInvoker(mtype); |
1381 if (mtype.parameterSlotCount() >= MethodType.MAX_MH_ARITY) |
|
1382 return makeReinvokerForm(target.type(), target); // cannot cache this |
|
1383 reinvoker = makeReinvokerForm(mtype, null); |
|
1384 return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, reinvoker); |
|
1385 } |
|
1386 private static LambdaForm makeReinvokerForm(MethodType mtype, MethodHandle customTargetOrNull) { |
|
1387 boolean customized = (customTargetOrNull != null); |
|
1388 MethodHandle MH_invokeBasic = customized ? null : MethodHandles.basicInvoker(mtype); |
1377 final int THIS_BMH = 0; |
1389 final int THIS_BMH = 0; |
1378 final int ARG_BASE = 1; |
1390 final int ARG_BASE = 1; |
1379 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); |
1391 final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); |
1380 int nameCursor = ARG_LIMIT; |
1392 int nameCursor = ARG_LIMIT; |
1381 final int NEXT_MH = nameCursor++; |
1393 final int NEXT_MH = customized ? -1 : nameCursor++; |
1382 final int REINVOKE = nameCursor++; |
1394 final int REINVOKE = nameCursor++; |
1383 LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); |
1395 LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); |
1384 names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]); |
1396 Object[] targetArgs; |
1385 Object[] targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class); |
1397 MethodHandle targetMH; |
1386 targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH |
1398 if (customized) { |
1387 names[REINVOKE] = new LambdaForm.Name(MH_invokeBasic, targetArgs); |
1399 targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); |
1388 return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, new LambdaForm("BMH.reinvoke", ARG_LIMIT, names)); |
1400 targetMH = customTargetOrNull; |
|
1401 } else { |
|
1402 names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]); |
|
1403 targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class); |
|
1404 targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH |
|
1405 targetMH = MethodHandles.basicInvoker(mtype); |
|
1406 } |
|
1407 names[REINVOKE] = new LambdaForm.Name(targetMH, targetArgs); |
|
1408 return new LambdaForm("BMH.reinvoke", ARG_LIMIT, names); |
1389 } |
1409 } |
1390 |
1410 |
1391 private static final LambdaForm.NamedFunction NF_reinvokerTarget; |
1411 private static final LambdaForm.NamedFunction NF_reinvokerTarget; |
1392 static { |
1412 static { |
1393 try { |
1413 try { |