Skip to content

Commit 13bde79

Browse files
authored
Precomputing accessors and Carrier constructor for the synthetic pattern. (openjdk#21)
1 parent 1ff137d commit 13bde79

File tree

1 file changed

+40
-19
lines changed

1 file changed

+40
-19
lines changed

src/java.base/share/classes/java/lang/runtime/PatternBootstraps.java

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ private static class StaticHolders {
6666
static {
6767
try {
6868
SYNTHETIC_PATTERN = LOOKUP.findStatic(PatternBootstraps.class, "syntheticPattern",
69-
MethodType.methodType(Object.class, Class.class, Object.class));
69+
MethodType.methodType(Object.class, Method[].class, MethodHandle.class, Object.class));
7070
}
7171
catch (ReflectiveOperationException e) {
7272
throw new ExceptionInInitializerError(e);
@@ -111,6 +111,23 @@ public static CallSite invokePattern(MethodHandles.Lookup lookup,
111111
String invocationName,
112112
MethodType invocationType,
113113
String mangledName) {
114+
if (invocationType.parameterCount() == 2) {
115+
Class<?> receiverType = invocationType.parameterType(0);
116+
Class<?> selectorType = invocationType.parameterType(1);
117+
if ((!invocationType.returnType().equals(Object.class)))
118+
throw new IllegalArgumentException("Illegal invocation type " + invocationType);
119+
120+
MethodHandle target = null;
121+
try {
122+
// Attempt 1: discover the pattern declaration
123+
target = lookup.findStatic(receiverType, mangledName, MethodType.methodType(Object.class, receiverType, selectorType));
124+
125+
return new ConstantCallSite(target);
126+
} catch (Throwable t) {
127+
throw new IllegalArgumentException("Cannot find a pattern");
128+
}
129+
}
130+
114131
Class<?> selectorType = invocationType.parameterType(0);
115132
if (invocationType.parameterCount() != 1
116133
|| (!invocationType.returnType().equals(Object.class)))
@@ -137,7 +154,25 @@ public static CallSite invokePattern(MethodHandles.Lookup lookup,
137154
throw new IllegalArgumentException("\nUnexpected pattern at use site: " + mangledName + "\nWas expecting: " + expectedMangledName);
138155
}
139156

140-
target = MethodHandles.insertArguments(StaticHolders.SYNTHETIC_PATTERN, 0, selectorType).asType(invocationType);
157+
@SuppressWarnings("removal")
158+
final RecordComponent[] components = AccessController.doPrivileged(
159+
(PrivilegedAction<RecordComponent[]>) selectorType::getRecordComponents);
160+
161+
Method[] accessors = Arrays.stream(components).map(c -> {
162+
Method accessor = c.getAccessor();
163+
accessor.setAccessible(true);
164+
return accessor;
165+
}).toArray(Method[]::new);
166+
167+
Class<?>[] ctypes = Arrays.stream(components).map(c -> c.getType()).toArray(Class<?>[]::new);
168+
169+
Carriers.CarrierElements carrierElements = Carriers.CarrierFactory.of(ctypes);
170+
171+
MethodHandle initializingConstructor = carrierElements.initializingConstructor();
172+
173+
MethodHandle carrierCreator = initializingConstructor.asSpreader(Object[].class, ctypes.length);
174+
175+
target = MethodHandles.insertArguments(StaticHolders.SYNTHETIC_PATTERN, 0, accessors, carrierCreator).asType(invocationType);
141176

142177
return new ConstantCallSite(target);
143178
}
@@ -153,20 +188,8 @@ public static CallSite invokePattern(MethodHandles.Lookup lookup,
153188
*
154189
* @throws Throwable throws if invocation of synthetic pattern fails
155190
*/
156-
@SuppressWarnings("removal")
157-
private static Object syntheticPattern(Class<?> matchCandidateType, Object matchCandidateInstance) throws Throwable {
158-
final RecordComponent[] components = AccessController.doPrivileged(
159-
(PrivilegedAction<RecordComponent[]>) matchCandidateType::getRecordComponents);
160-
161-
Class<?>[] ctypes = Arrays.stream(components).map(c -> c.getType()).toArray(Class<?>[]::new);
162-
163-
Carriers.CarrierElements carrierElements = Carriers.CarrierFactory.of(ctypes);
164-
165-
MethodHandle initializingConstructor = carrierElements.initializingConstructor();
166-
167-
Object[] extracted = Arrays.stream(components).map(c -> {
168-
Method accessor = c.getAccessor();
169-
accessor.setAccessible(true);
191+
private static Object syntheticPattern(Method[] accessors, MethodHandle carrierCreator, Object matchCandidateInstance) throws Throwable {
192+
Object[] extracted = Arrays.stream(accessors).map(accessor -> {
170193
try {
171194
return accessor.invoke(matchCandidateInstance);
172195
} catch (IllegalAccessException e) {
@@ -176,9 +199,7 @@ private static Object syntheticPattern(Class<?> matchCandidateType, Object match
176199
}
177200
}).toArray();
178201

179-
MethodHandle spreadedPatternInvoker = initializingConstructor.asSpreader(Object[].class, ctypes.length);
180-
181-
Object carrier = spreadedPatternInvoker.invoke(extracted);
202+
Object carrier = carrierCreator.invoke(extracted);
182203

183204
return carrier;
184205
}

0 commit comments

Comments
 (0)