mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8213478: Reduce rebinds when applying repeated filters and conversions
Reviewed-by: vlivanov, jrose
This commit is contained in:
parent
2df435e191
commit
eda5f09014
3 changed files with 198 additions and 101 deletions
|
@ -3864,18 +3864,63 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
|
|||
*/
|
||||
public static
|
||||
MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
|
||||
// In method types arguments start at index 0, while the LF
|
||||
// editor have the MH receiver at position 0 - adjust appropriately.
|
||||
final int MH_RECEIVER_OFFSET = 1;
|
||||
filterArgumentsCheckArity(target, pos, filters);
|
||||
MethodHandle adapter = target;
|
||||
|
||||
// keep track of currently matched filters, as to optimize repeated filters
|
||||
int index = 0;
|
||||
int[] positions = new int[filters.length];
|
||||
MethodHandle filter = null;
|
||||
|
||||
// process filters in reverse order so that the invocation of
|
||||
// the resulting adapter will invoke the filters in left-to-right order
|
||||
for (int i = filters.length - 1; i >= 0; --i) {
|
||||
MethodHandle filter = filters[i];
|
||||
if (filter == null) continue; // ignore null elements of filters
|
||||
adapter = filterArgument(adapter, pos + i, filter);
|
||||
MethodHandle newFilter = filters[i];
|
||||
if (newFilter == null) continue; // ignore null elements of filters
|
||||
|
||||
// flush changes on update
|
||||
if (filter != newFilter) {
|
||||
if (filter != null) {
|
||||
if (index > 1) {
|
||||
adapter = filterRepeatedArgument(adapter, filter, Arrays.copyOf(positions, index));
|
||||
} else {
|
||||
adapter = filterArgument(adapter, positions[0] - 1, filter);
|
||||
}
|
||||
}
|
||||
filter = newFilter;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
filterArgumentChecks(target, pos + i, newFilter);
|
||||
positions[index++] = pos + i + MH_RECEIVER_OFFSET;
|
||||
}
|
||||
if (index > 1) {
|
||||
adapter = filterRepeatedArgument(adapter, filter, Arrays.copyOf(positions, index));
|
||||
} else if (index == 1) {
|
||||
adapter = filterArgument(adapter, positions[0] - 1, filter);
|
||||
}
|
||||
return adapter;
|
||||
}
|
||||
|
||||
private static MethodHandle filterRepeatedArgument(MethodHandle adapter, MethodHandle filter, int[] positions) {
|
||||
MethodType targetType = adapter.type();
|
||||
MethodType filterType = filter.type();
|
||||
BoundMethodHandle result = adapter.rebind();
|
||||
Class<?> newParamType = filterType.parameterType(0);
|
||||
|
||||
Class<?>[] ptypes = targetType.ptypes().clone();
|
||||
for (int pos : positions) {
|
||||
ptypes[pos - 1] = newParamType;
|
||||
}
|
||||
MethodType newType = MethodType.makeImpl(targetType.rtype(), ptypes, true);
|
||||
|
||||
LambdaForm lform = result.editor().filterRepeatedArgumentForm(BasicType.basicType(newParamType), positions);
|
||||
return result.copyWithExtendL(newType, lform, filter);
|
||||
}
|
||||
|
||||
/*non-public*/ static
|
||||
MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
|
||||
filterArgumentChecks(target, pos, filter);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue