mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8212726: Replace some use of drop- and foldArguments with filtering argument combinator in StringConcatFactory
Reviewed-by: jlaskey, vlivanov
This commit is contained in:
parent
a633b90085
commit
06a2bb5274
3 changed files with 121 additions and 82 deletions
|
@ -4316,28 +4316,6 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* As {@see foldArguments(MethodHandle, int, MethodHandle)}, but with the
|
||||
* added capability of selecting the arguments from the targets parameters
|
||||
* to call the combiner with. This allows us to avoid some simple cases of
|
||||
* permutations and padding the combiner with dropArguments to select the
|
||||
* right argument, which may ultimately produce fewer intermediaries.
|
||||
*/
|
||||
static MethodHandle foldArguments(MethodHandle target, int pos, MethodHandle combiner, int ... argPositions) {
|
||||
MethodType targetType = target.type();
|
||||
MethodType combinerType = combiner.type();
|
||||
Class<?> rtype = foldArgumentChecks(pos, targetType, combinerType, argPositions);
|
||||
BoundMethodHandle result = target.rebind();
|
||||
boolean dropResult = rtype == void.class;
|
||||
LambdaForm lform = result.editor().foldArgumentsForm(1 + pos, dropResult, combinerType.basicType(), argPositions);
|
||||
MethodType newType = targetType;
|
||||
if (!dropResult) {
|
||||
newType = newType.dropParameterTypes(pos, pos + 1);
|
||||
}
|
||||
result = result.copyWithExtendL(newType, lform, combiner);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType) {
|
||||
int foldArgs = combinerType.parameterCount();
|
||||
Class<?> rtype = combinerType.returnType();
|
||||
|
@ -4359,15 +4337,78 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
|||
return rtype;
|
||||
}
|
||||
|
||||
private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType, int ... argPos) {
|
||||
int foldArgs = combinerType.parameterCount();
|
||||
if (argPos.length != foldArgs) {
|
||||
/**
|
||||
* Adapts a target method handle by pre-processing some of its arguments, then calling the target with the result
|
||||
* of the pre-processing replacing the argument at the given position.
|
||||
*
|
||||
* @param target the method handle to invoke after arguments are combined
|
||||
* @param position the position at which to start folding and at which to insert the folding result; if this is {@code
|
||||
* 0}, the effect is the same as for {@link #foldArguments(MethodHandle, MethodHandle)}.
|
||||
* @param combiner method handle to call initially on the incoming arguments
|
||||
* @param argPositions indexes of the target to pick arguments sent to the combiner from
|
||||
* @return method handle which incorporates the specified argument folding logic
|
||||
* @throws NullPointerException if either argument is null
|
||||
* @throws IllegalArgumentException if either of the following two conditions holds:
|
||||
* (1) {@code combiner}'s return type is not the same as the argument type at position
|
||||
* {@code pos} of the target signature;
|
||||
* (2) the {@code N} argument types at positions {@code argPositions[1...N]} of the target signature are
|
||||
* not identical with the argument types of {@code combiner}.
|
||||
*/
|
||||
/*non-public*/ static MethodHandle filterArgumentsWithCombiner(MethodHandle target, int position, MethodHandle combiner, int ... argPositions) {
|
||||
return argumentsWithCombiner(true, target, position, combiner, argPositions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts a target method handle by pre-processing some of its arguments, calling the target with the result of
|
||||
* the pre-processing inserted into the original sequence of arguments at the given position.
|
||||
*
|
||||
* @param target the method handle to invoke after arguments are combined
|
||||
* @param position the position at which to start folding and at which to insert the folding result; if this is {@code
|
||||
* 0}, the effect is the same as for {@link #foldArguments(MethodHandle, MethodHandle)}.
|
||||
* @param combiner method handle to call initially on the incoming arguments
|
||||
* @param argPositions indexes of the target to pick arguments sent to the combiner from
|
||||
* @return method handle which incorporates the specified argument folding logic
|
||||
* @throws NullPointerException if either argument is null
|
||||
* @throws IllegalArgumentException if either of the following two conditions holds:
|
||||
* (1) {@code combiner}'s return type is non-{@code void} and not the same as the argument type at position
|
||||
* {@code pos} of the target signature;
|
||||
* (2) the {@code N} argument types at positions {@code argPositions[1...N]} of the target signature
|
||||
* (skipping {@code position} where the {@code combiner}'s return will be folded in) are not identical
|
||||
* with the argument types of {@code combiner}.
|
||||
*/
|
||||
/*non-public*/ static MethodHandle foldArgumentsWithCombiner(MethodHandle target, int position, MethodHandle combiner, int ... argPositions) {
|
||||
return argumentsWithCombiner(false, target, position, combiner, argPositions);
|
||||
}
|
||||
|
||||
private static MethodHandle argumentsWithCombiner(boolean filter, MethodHandle target, int position, MethodHandle combiner, int ... argPositions) {
|
||||
MethodType targetType = target.type();
|
||||
MethodType combinerType = combiner.type();
|
||||
Class<?> rtype = argumentsWithCombinerChecks(position, filter, targetType, combinerType, argPositions);
|
||||
BoundMethodHandle result = target.rebind();
|
||||
|
||||
MethodType newType = targetType;
|
||||
LambdaForm lform;
|
||||
if (filter) {
|
||||
lform = result.editor().filterArgumentsForm(1 + position, combinerType.basicType(), argPositions);
|
||||
} else {
|
||||
boolean dropResult = rtype == void.class;
|
||||
lform = result.editor().foldArgumentsForm(1 + position, dropResult, combinerType.basicType(), argPositions);
|
||||
if (!dropResult) {
|
||||
newType = newType.dropParameterTypes(position, position + 1);
|
||||
}
|
||||
}
|
||||
result = result.copyWithExtendL(newType, lform, combiner);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Class<?> argumentsWithCombinerChecks(int position, boolean filter, MethodType targetType, MethodType combinerType, int ... argPos) {
|
||||
int combinerArgs = combinerType.parameterCount();
|
||||
if (argPos.length != combinerArgs) {
|
||||
throw newIllegalArgumentException("combiner and argument map must be equal size", combinerType, argPos.length);
|
||||
}
|
||||
Class<?> rtype = combinerType.returnType();
|
||||
int foldVals = rtype == void.class ? 0 : 1;
|
||||
boolean ok = true;
|
||||
for (int i = 0; i < foldArgs; i++) {
|
||||
|
||||
for (int i = 0; i < combinerArgs; i++) {
|
||||
int arg = argPos[i];
|
||||
if (arg < 0 || arg > targetType.parameterCount()) {
|
||||
throw newIllegalArgumentException("arg outside of target parameterRange", targetType, arg);
|
||||
|
@ -4378,11 +4419,9 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
|||
+ " -> " + combinerType + ", map: " + Arrays.toString(argPos));
|
||||
}
|
||||
}
|
||||
if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos)) {
|
||||
ok = false;
|
||||
}
|
||||
if (!ok)
|
||||
if (filter && combinerType.returnType() != targetType.parameterType(position)) {
|
||||
throw misMatchedTypes("target and combiner types", targetType, combinerType);
|
||||
}
|
||||
return rtype;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue