src/java.base/share/classes/java/lang/invoke/MethodHandles.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Nov 19 14:27:41 2014
--- new/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Nov 19 14:27:41 2014
*** 2101,2111 ****
--- 2101,2110 ----
public static
MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
reorder = reorder.clone(); // get a private copy
MethodType oldType = target.type();
permuteArgumentChecks(reorder, newType, oldType);
if (USE_LAMBDA_FORM_EDITOR) {
// first detect dropped arguments and handle them separately
int[] originalReorder = reorder;
BoundMethodHandle result = target.rebind();
LambdaForm form = result.form;
int newArity = newType.parameterCount();
*** 2161,2219 ****
--- 2160,2169 ----
// Note: This may cache too many distinct LFs. Consider backing off to varargs code.
form = form.editor().permuteArgumentsForm(1, reorder);
if (newType == result.type() && form == result.internalForm())
return result;
return result.copyWith(newType, form);
} else {
// first detect dropped arguments and handle them separately
MethodHandle originalTarget = target;
int newArity = newType.parameterCount();
for (int dropIdx; (dropIdx = findFirstDrop(reorder, newArity)) >= 0; ) {
// dropIdx is missing from reorder; add it in at the end
int oldArity = reorder.length;
target = dropArguments(target, oldArity, newType.parameterType(dropIdx));
reorder = Arrays.copyOf(reorder, oldArity + 1);
reorder[oldArity] = dropIdx;
}
assert(target == originalTarget || permuteArgumentChecks(reorder, newType, target.type()));
// Note: This may cache too many distinct LFs. Consider backing off to varargs code.
BoundMethodHandle result = target.rebind();
LambdaForm form = result.form.permuteArguments(1, reorder, basicTypes(newType.parameterList()));
return result.copyWith(newType, form);
}
}
/** Return the first value in [0..newArity-1] that is not present in reorder. */
private static int findFirstDrop(int[] reorder, int newArity) {
final int BIT_LIMIT = 63; // max number of bits in bit mask
if (newArity < BIT_LIMIT) {
long mask = 0;
for (int arg : reorder) {
assert(arg < newArity);
mask |= (1L << arg);
}
if (mask == (1L << newArity) - 1) {
assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity);
return -1;
}
// find first zero
long zeroBit = Long.lowestOneBit(~mask);
int zeroPos = Long.numberOfTrailingZeros(zeroBit);
assert(zeroPos < newArity);
return zeroPos;
} else {
BitSet mask = new BitSet(newArity);
for (int arg : reorder) {
assert (arg < newArity);
mask.set(arg);
}
int zeroPos = mask.nextClearBit(0);
assert(zeroPos <= newArity);
if (zeroPos == newArity)
return -1;
return zeroPos;
}
}
/**
* Return an indication of any duplicate or omission in reorder.
* If the reorder contains a duplicate entry, return the index of the second occurrence.
*** 2500,2517 ****
--- 2450,2463 ----
int dropped = dropArgumentChecks(oldType, pos, valueTypes);
MethodType newType = oldType.insertParameterTypes(pos, valueTypes);
if (dropped == 0) return target;
BoundMethodHandle result = target.rebind();
LambdaForm lform = result.form;
if (USE_LAMBDA_FORM_EDITOR) {
int insertFormArg = 1 + pos;
for (Class<?> ptype : valueTypes) {
lform = lform.editor().addArgumentForm(insertFormArg++, BasicType.basicType(ptype));
}
} else {
lform = lform.addArguments(pos, valueTypes);
}
result = result.copyWith(newType, lform);
return result;
}
private static int dropArgumentChecks(MethodType oldType, int pos, List<Class<?>> valueTypes) {
*** 2657,2678 ****
--- 2603,2620 ----
}
/*non-public*/ static
MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
filterArgumentChecks(target, pos, filter);
if (USE_LAMBDA_FORM_EDITOR) {
MethodType targetType = target.type();
MethodType filterType = filter.type();
BoundMethodHandle result = target.rebind();
Class<?> newParamType = filterType.parameterType(0);
LambdaForm lform = result.editor().filterArgumentForm(1 + pos, BasicType.basicType(newParamType));
MethodType newType = targetType.changeParameterType(pos, newParamType);
result = result.copyWithExtendL(newType, lform, filter);
return result;
} else {
return MethodHandleImpl.makeCollectArguments(target, filter, pos, false);
}
}
private static void filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters) {
MethodType targetType = target.type();
int maxPos = targetType.parameterCount();
*** 2795,2805 ****
--- 2737,2746 ----
* @see MethodHandles#filterReturnValue
*/
public static
MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle filter) {
MethodType newType = collectArgumentsChecks(target, pos, filter);
if (USE_LAMBDA_FORM_EDITOR) {
MethodType collectorType = filter.type();
BoundMethodHandle result = target.rebind();
LambdaForm lform;
if (collectorType.returnType().isArray() && filter.intrinsicName() == Intrinsic.NEW_ARRAY) {
lform = result.editor().collectArgumentArrayForm(1 + pos, filter);
*** 2807,2819 ****
--- 2748,2757 ----
return result.copyWith(newType, lform);
}
}
lform = result.editor().collectArgumentsForm(1 + pos, collectorType.basicType());
return result.copyWithExtendL(newType, lform, filter);
} else {
return MethodHandleImpl.makeCollectArguments(target, filter, pos, false);
}
}
private static MethodType collectArgumentsChecks(MethodHandle target, int pos, MethodHandle filter) throws RuntimeException {
MethodType targetType = target.type();
MethodType filterType = filter.type();
*** 2888,2907 ****
--- 2826,2841 ----
public static
MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
MethodType targetType = target.type();
MethodType filterType = filter.type();
filterReturnValueChecks(targetType, filterType);
if (USE_LAMBDA_FORM_EDITOR) {
BoundMethodHandle result = target.rebind();
BasicType rtype = BasicType.basicType(filterType.returnType());
LambdaForm lform = result.editor().filterReturnForm(rtype, false);
MethodType newType = targetType.changeReturnType(filterType.returnType());
result = result.copyWithExtendL(newType, lform, filter);
return result;
} else {
return MethodHandleImpl.makeCollectArguments(filter, target, 0, false);
}
}
private static void filterReturnValueChecks(MethodType targetType, MethodType filterType) throws RuntimeException {
Class<?> rtype = targetType.returnType();
int filterValues = filterType.parameterCount();
*** 2991,3013 ****
--- 2925,2943 ----
MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
int foldPos = 0;
MethodType targetType = target.type();
MethodType combinerType = combiner.type();
Class<?> rtype = foldArgumentChecks(foldPos, targetType, combinerType);
if (USE_LAMBDA_FORM_EDITOR) {
BoundMethodHandle result = target.rebind();
boolean dropResult = (rtype == void.class);
// Note: This may cache too many distinct LFs. Consider backing off to varargs code.
LambdaForm lform = result.editor().foldArgumentsForm(1 + foldPos, dropResult, combinerType.basicType());
MethodType newType = targetType;
if (!dropResult)
newType = newType.dropParameterTypes(foldPos, foldPos + 1);
result = result.copyWithExtendL(newType, lform, combiner);
return result;
} else {
return MethodHandleImpl.makeCollectArguments(target, combiner, foldPos, true);
}
}
private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType) {
int foldArgs = combinerType.parameterCount();
Class<?> rtype = combinerType.returnType();
src/java.base/share/classes/java/lang/invoke/MethodHandles.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File