--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Mon Nov 24 17:02:37 2014 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Mon Nov 24 07:16:38 2014 -0800
@@ -867,15 +867,11 @@
MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
int arity = type().parameterCount();
int spreadArgPos = arity - arrayLength;
- if (USE_LAMBDA_FORM_EDITOR) {
- MethodHandle afterSpread = this.asType(postSpreadType);
- BoundMethodHandle mh = afterSpread.rebind();
- LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
- MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
- return mh.copyWith(preSpreadType, lform);
- } else {
- return MethodHandleImpl.makeSpreadArguments(this, arrayType, spreadArgPos, arrayLength);
- }
+ MethodHandle afterSpread = this.asType(postSpreadType);
+ BoundMethodHandle mh = afterSpread.rebind();
+ LambdaForm lform = mh.editor().spreadArgumentsForm(1 + spreadArgPos, arrayType, arrayLength);
+ MethodType preSpreadType = postSpreadType.replaceParameterTypes(spreadArgPos, arity, arrayType);
+ return mh.copyWith(preSpreadType, lform);
}
/**
@@ -996,23 +992,15 @@
public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
asCollectorChecks(arrayType, arrayLength);
int collectArgPos = type().parameterCount() - 1;
- if (USE_LAMBDA_FORM_EDITOR) {
- BoundMethodHandle mh = rebind();
- MethodType resultType = type().asCollectorType(arrayType, arrayLength);
- MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
- LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
- if (lform != null) {
- return mh.copyWith(resultType, lform);
- }
- lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
- return mh.copyWithExtendL(resultType, lform, newArray);
- } else {
- MethodHandle target = this;
- if (arrayType != type().parameterType(collectArgPos))
- target = MethodHandleImpl.makePairwiseConvert(this, type().changeParameterType(collectArgPos, arrayType), true);
- MethodHandle collector = MethodHandleImpl.varargsArray(arrayType, arrayLength);
- return MethodHandles.collectArguments(target, collectArgPos, collector);
+ BoundMethodHandle mh = rebind();
+ MethodType resultType = type().asCollectorType(arrayType, arrayLength);
+ MethodHandle newArray = MethodHandleImpl.varargsArray(arrayType, arrayLength);
+ LambdaForm lform = mh.editor().collectArgumentArrayForm(1 + collectArgPos, newArray);
+ if (lform != null) {
+ return mh.copyWith(resultType, lform);
}
+ lform = mh.editor().collectArgumentsForm(1 + collectArgPos, newArray.type().basicType());
+ return mh.copyWithExtendL(resultType, lform, newArray);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Mon Nov 24 17:02:37 2014 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Mon Nov 24 07:16:38 2014 -0800
@@ -2103,115 +2103,65 @@
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();
- // Normalize the reordering into a real permutation,
- // by removing duplicates and adding dropped elements.
- // This somewhat improves lambda form caching, as well
- // as simplifying the transform by breaking it up into steps.
- for (int ddIdx; (ddIdx = findFirstDupOrDrop(reorder, newArity)) != 0; ) {
- if (ddIdx > 0) {
- // We found a duplicated entry at reorder[ddIdx].
- // Example: (x,y,z)->asList(x,y,z)
- // permuted by [1*,0,1] => (a0,a1)=>asList(a1,a0,a1)
- // permuted by [0,1,0*] => (a0,a1)=>asList(a0,a1,a0)
- // The starred element corresponds to the argument
- // deleted by the dupArgumentForm transform.
- int srcPos = ddIdx, dstPos = srcPos, dupVal = reorder[srcPos];
- boolean killFirst = false;
- for (int val; (val = reorder[--dstPos]) != dupVal; ) {
- // Set killFirst if the dup is larger than an intervening position.
- // This will remove at least one inversion from the permutation.
- if (dupVal > val) killFirst = true;
- }
- if (!killFirst) {
- srcPos = dstPos;
- dstPos = ddIdx;
- }
- form = form.editor().dupArgumentForm(1 + srcPos, 1 + dstPos);
- assert (reorder[srcPos] == reorder[dstPos]);
- oldType = oldType.dropParameterTypes(dstPos, dstPos + 1);
- // contract the reordering by removing the element at dstPos
- int tailPos = dstPos + 1;
- System.arraycopy(reorder, tailPos, reorder, dstPos, reorder.length - tailPos);
- reorder = Arrays.copyOf(reorder, reorder.length - 1);
- } else {
- int dropVal = ~ddIdx, insPos = 0;
- while (insPos < reorder.length && reorder[insPos] < dropVal) {
- // Find first element of reorder larger than dropVal.
- // This is where we will insert the dropVal.
- insPos += 1;
- }
- Class<?> ptype = newType.parameterType(dropVal);
- form = form.editor().addArgumentForm(1 + insPos, BasicType.basicType(ptype));
- oldType = oldType.insertParameterTypes(insPos, ptype);
- // expand the reordering by inserting an element at insPos
- int tailPos = insPos + 1;
- reorder = Arrays.copyOf(reorder, reorder.length + 1);
- System.arraycopy(reorder, insPos, reorder, tailPos, reorder.length - tailPos);
- reorder[insPos] = dropVal;
+ // first detect dropped arguments and handle them separately
+ int[] originalReorder = reorder;
+ BoundMethodHandle result = target.rebind();
+ LambdaForm form = result.form;
+ int newArity = newType.parameterCount();
+ // Normalize the reordering into a real permutation,
+ // by removing duplicates and adding dropped elements.
+ // This somewhat improves lambda form caching, as well
+ // as simplifying the transform by breaking it up into steps.
+ for (int ddIdx; (ddIdx = findFirstDupOrDrop(reorder, newArity)) != 0; ) {
+ if (ddIdx > 0) {
+ // We found a duplicated entry at reorder[ddIdx].
+ // Example: (x,y,z)->asList(x,y,z)
+ // permuted by [1*,0,1] => (a0,a1)=>asList(a1,a0,a1)
+ // permuted by [0,1,0*] => (a0,a1)=>asList(a0,a1,a0)
+ // The starred element corresponds to the argument
+ // deleted by the dupArgumentForm transform.
+ int srcPos = ddIdx, dstPos = srcPos, dupVal = reorder[srcPos];
+ boolean killFirst = false;
+ for (int val; (val = reorder[--dstPos]) != dupVal; ) {
+ // Set killFirst if the dup is larger than an intervening position.
+ // This will remove at least one inversion from the permutation.
+ if (dupVal > val) killFirst = true;
}
- assert (permuteArgumentChecks(reorder, newType, oldType));
+ if (!killFirst) {
+ srcPos = dstPos;
+ dstPos = ddIdx;
+ }
+ form = form.editor().dupArgumentForm(1 + srcPos, 1 + dstPos);
+ assert (reorder[srcPos] == reorder[dstPos]);
+ oldType = oldType.dropParameterTypes(dstPos, dstPos + 1);
+ // contract the reordering by removing the element at dstPos
+ int tailPos = dstPos + 1;
+ System.arraycopy(reorder, tailPos, reorder, dstPos, reorder.length - tailPos);
+ reorder = Arrays.copyOf(reorder, reorder.length - 1);
+ } else {
+ int dropVal = ~ddIdx, insPos = 0;
+ while (insPos < reorder.length && reorder[insPos] < dropVal) {
+ // Find first element of reorder larger than dropVal.
+ // This is where we will insert the dropVal.
+ insPos += 1;
+ }
+ Class<?> ptype = newType.parameterType(dropVal);
+ form = form.editor().addArgumentForm(1 + insPos, BasicType.basicType(ptype));
+ oldType = oldType.insertParameterTypes(insPos, ptype);
+ // expand the reordering by inserting an element at insPos
+ int tailPos = insPos + 1;
+ reorder = Arrays.copyOf(reorder, reorder.length + 1);
+ System.arraycopy(reorder, insPos, reorder, tailPos, reorder.length - tailPos);
+ reorder[insPos] = dropVal;
}
- assert (reorder.length == newArity); // a perfect permutation
- // 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);
+ assert (permuteArgumentChecks(reorder, newType, oldType));
}
- }
-
- /** 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;
- }
+ assert (reorder.length == newArity); // a perfect permutation
+ // 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);
}
/**
@@ -2502,13 +2452,9 @@
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);
+ int insertFormArg = 1 + pos;
+ for (Class<?> ptype : valueTypes) {
+ lform = lform.editor().addArgumentForm(insertFormArg++, BasicType.basicType(ptype));
}
result = result.copyWith(newType, lform);
return result;
@@ -2659,18 +2605,14 @@
/*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);
- }
+ 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;
}
private static void filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters) {
@@ -2797,21 +2739,17 @@
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);
- if (lform != null) {
- return result.copyWith(newType, lform);
- }
+ 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);
+ if (lform != null) {
+ 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);
}
+ lform = result.editor().collectArgumentsForm(1 + pos, collectorType.basicType());
+ return result.copyWithExtendL(newType, lform, filter);
}
private static MethodType collectArgumentsChecks(MethodHandle target, int pos, MethodHandle filter) throws RuntimeException {
@@ -2890,16 +2828,12 @@
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);
- }
+ 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;
}
private static void filterReturnValueChecks(MethodType targetType, MethodType filterType) throws RuntimeException {
@@ -2993,19 +2927,15 @@
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);
- }
+ 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;
}
private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType) {