Skip to content

Commit 299c651

Browse files
author
Christian Wimmer
committed
Remove reflection
1 parent 7771d39 commit 299c651

File tree

2 files changed

+32
-63
lines changed

2 files changed

+32
-63
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/IntrinsifyMethodHandlesInvocationPlugin.java

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.createStandardInlineInfo;
2828

2929
import java.lang.invoke.MethodHandle;
30+
import java.lang.invoke.VarHandle;
3031
import java.lang.reflect.Field;
3132
import java.lang.reflect.Method;
3233
import java.util.Arrays;
@@ -96,7 +97,6 @@
9697
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
9798
import org.graalvm.compiler.phases.util.Providers;
9899
import org.graalvm.compiler.replacements.MethodHandlePlugin;
99-
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
100100
import org.graalvm.compiler.word.WordOperationPlugin;
101101
import org.graalvm.nativeimage.ImageSingletons;
102102

@@ -160,6 +160,19 @@
160160
*/
161161
public class IntrinsifyMethodHandlesInvocationPlugin implements NodePlugin {
162162

163+
private static final Field varHandleVFormField;
164+
private static final Method varFormInitMethod;
165+
166+
static {
167+
varHandleVFormField = ReflectionUtil.lookupField(VarHandle.class, "vform");
168+
try {
169+
Class<?> varFormClass = Class.forName("java.lang.invoke.VarForm");
170+
varFormInitMethod = ReflectionUtil.lookupMethod(varFormClass, "getMethodType_V", int.class);
171+
} catch (ClassNotFoundException ex) {
172+
throw VMError.shouldNotReachHere(ex);
173+
}
174+
}
175+
163176
public static class IntrinsificationRegistry extends IntrinsificationPluginRegistry {
164177
}
165178

@@ -174,14 +187,7 @@ public static class IntrinsificationRegistry extends IntrinsificationPluginRegis
174187
private final IntrinsificationRegistry intrinsificationRegistry;
175188

176189
private final ResolvedJavaType methodHandleType;
177-
178-
private final Class<?> varHandleClass;
179-
private final Class<?> varHandleAccessModeClass;
180190
private final ResolvedJavaType varHandleType;
181-
private final Field varHandleVFormField;
182-
private final Method varFormInitMethod;
183-
private final Method varHandleIsAccessModeSupportedMethod;
184-
private final Method varHandleAccessModeTypeMethod;
185191

186192
public IntrinsifyMethodHandlesInvocationPlugin(ParsingReason reason, Providers providers, AnalysisUniverse aUniverse, HostedUniverse hUniverse) {
187193
this.reason = reason;
@@ -201,30 +207,8 @@ public IntrinsifyMethodHandlesInvocationPlugin(ParsingReason reason, Providers p
201207
intrinsificationRegistry = ImageSingletons.lookup(IntrinsificationRegistry.class);
202208
}
203209

204-
methodHandleType = universeProviders.getMetaAccess().lookupJavaType(java.lang.invoke.MethodHandle.class);
205-
206-
if (JavaVersionUtil.JAVA_SPEC >= 11) {
207-
try {
208-
varHandleClass = Class.forName("java.lang.invoke.VarHandle");
209-
varHandleAccessModeClass = Class.forName("java.lang.invoke.VarHandle$AccessMode");
210-
varHandleType = universeProviders.getMetaAccess().lookupJavaType(varHandleClass);
211-
varHandleVFormField = ReflectionUtil.lookupField(varHandleClass, "vform");
212-
Class<?> varFormClass = Class.forName("java.lang.invoke.VarForm");
213-
varFormInitMethod = ReflectionUtil.lookupMethod(varFormClass, "getMethodType_V", int.class);
214-
varHandleIsAccessModeSupportedMethod = ReflectionUtil.lookupMethod(varHandleClass, "isAccessModeSupported", varHandleAccessModeClass);
215-
varHandleAccessModeTypeMethod = ReflectionUtil.lookupMethod(varHandleClass, "accessModeType", varHandleAccessModeClass);
216-
} catch (ClassNotFoundException ex) {
217-
throw VMError.shouldNotReachHere(ex);
218-
}
219-
} else {
220-
varHandleClass = null;
221-
varHandleAccessModeClass = null;
222-
varHandleType = null;
223-
varHandleVFormField = null;
224-
varFormInitMethod = null;
225-
varHandleIsAccessModeSupportedMethod = null;
226-
varHandleAccessModeTypeMethod = null;
227-
}
210+
methodHandleType = universeProviders.getMetaAccess().lookupJavaType(MethodHandle.class);
211+
varHandleType = universeProviders.getMetaAccess().lookupJavaType(VarHandle.class);
228212
}
229213

230214
@Override
@@ -332,7 +316,7 @@ private boolean isVarHandleMethod(ResolvedJavaMethod method, ValueNode[] args) {
332316
* initialization has happened. We force initialization by invoking the method
333317
* VarHandle.vform.getMethodType_V(0).
334318
*/
335-
Object varHandle = SubstrateObjectConstant.asObject(args[0].asJavaConstant());
319+
VarHandle varHandle = (VarHandle) SubstrateObjectConstant.asObject(args[0].asJavaConstant());
336320
Object varForm = varHandleVFormField.get(varHandle);
337321
varFormInitMethod.invoke(varForm, 0);
338322

@@ -342,17 +326,17 @@ private boolean isVarHandleMethod(ResolvedJavaMethod method, ValueNode[] args) {
342326
* method. Initializing all AccessMode enum values is easier than trying to extract
343327
* the actual AccessMode.
344328
*/
345-
for (Object accessMode : varHandleAccessModeClass.getEnumConstants()) {
329+
for (VarHandle.AccessMode accessMode : VarHandle.AccessMode.values()) {
346330
/*
347331
* Force initialization of the @Stable field VarHandle.vform.memberName_table.
348332
* Starting with JDK 17, this field is lazily initialized.
349333
*/
350-
varHandleIsAccessModeSupportedMethod.invoke(varHandle, accessMode);
334+
varHandle.isAccessModeSupported(accessMode);
351335
/*
352336
* Force initialization of the @Stable field
353337
* VarHandle.typesAndInvokers.methodType_table.
354338
*/
355-
varHandleAccessModeTypeMethod.invoke(varHandle, accessMode);
339+
varHandle.accessModeType(accessMode);
356340
}
357341
} catch (ReflectiveOperationException ex) {
358342
throw VMError.shouldNotReachHere(ex);

substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/serialize/hosted/SerializationFeature.java

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
import com.oracle.svm.reflect.serialize.SerializationSupport;
6666
import com.oracle.svm.util.ReflectionUtil;
6767

68+
import jdk.internal.reflect.ReflectionFactory;
69+
6870
@AutomaticFeature
6971
public class SerializationFeature implements Feature {
7072
private SerializationBuilder serializationBuilder;
@@ -167,11 +169,9 @@ public boolean isAllowed(Class<?> clazz) {
167169

168170
final class SerializationBuilder extends ConditionalConfigurationRegistry implements RuntimeSerializationSupport {
169171

170-
private final Object reflectionFactory;
171-
private final Method newConstructorForSerializationMethod1;
172-
private final Method newConstructorForSerializationMethod2;
173-
private final Method getConstructorAccessorMethod;
174-
private final Method getExternalizableConstructorMethod;
172+
private static final Method getConstructorAccessorMethod = ReflectionUtil.lookupMethod(Constructor.class, "getConstructorAccessor");
173+
private static final Method getExternalizableConstructorMethod = ReflectionUtil.lookupMethod(ObjectStreamClass.class, "getExternalizableConstructor", Class.class);
174+
175175
private final Constructor<?> stubConstructor;
176176

177177
private final SerializationSupport serializationSupport;
@@ -181,17 +181,6 @@ final class SerializationBuilder extends ConditionalConfigurationRegistry implem
181181
private boolean sealed;
182182

183183
SerializationBuilder(SerializationDenyRegistry serializationDenyRegistry, ConfigurationTypeResolver typeResolver) {
184-
try {
185-
Class<?> reflectionFactoryClass = jdk.internal.reflect.ReflectionFactory.class;
186-
Method getReflectionFactoryMethod = ReflectionUtil.lookupMethod(reflectionFactoryClass, "getReflectionFactory");
187-
reflectionFactory = getReflectionFactoryMethod.invoke(null);
188-
newConstructorForSerializationMethod1 = ReflectionUtil.lookupMethod(reflectionFactoryClass, "newConstructorForSerialization", Class.class);
189-
newConstructorForSerializationMethod2 = ReflectionUtil.lookupMethod(reflectionFactoryClass, "newConstructorForSerialization", Class.class, Constructor.class);
190-
getConstructorAccessorMethod = ReflectionUtil.lookupMethod(Constructor.class, "getConstructorAccessor");
191-
getExternalizableConstructorMethod = ReflectionUtil.lookupMethod(ObjectStreamClass.class, "getExternalizableConstructor", Class.class);
192-
} catch (ReflectiveOperationException e) {
193-
throw VMError.shouldNotReachHere(e);
194-
}
195184
stubConstructor = newConstructorForSerialization(SerializationSupport.StubForAbstractClass.class, null);
196185
this.denyRegistry = serializationDenyRegistry;
197186
this.typeResolver = typeResolver;
@@ -300,27 +289,23 @@ private static void registerFields(Class<?> serializationTargetClass) {
300289
RuntimeReflection.register(serializationTargetClass.getDeclaredFields());
301290
}
302291

303-
private Constructor<?> newConstructorForSerialization(Class<?> serializationTargetClass, Constructor<?> customConstructorToCall) {
304-
try {
305-
if (customConstructorToCall == null) {
306-
return (Constructor<?>) newConstructorForSerializationMethod1.invoke(reflectionFactory, serializationTargetClass);
307-
} else {
308-
return (Constructor<?>) newConstructorForSerializationMethod2.invoke(reflectionFactory, serializationTargetClass, customConstructorToCall);
309-
}
310-
} catch (ReflectiveOperationException e) {
311-
throw VMError.shouldNotReachHere(e);
292+
private static Constructor<?> newConstructorForSerialization(Class<?> serializationTargetClass, Constructor<?> customConstructorToCall) {
293+
if (customConstructorToCall == null) {
294+
return ReflectionFactory.getReflectionFactory().newConstructorForSerialization(serializationTargetClass);
295+
} else {
296+
return ReflectionFactory.getReflectionFactory().newConstructorForSerialization(serializationTargetClass, customConstructorToCall);
312297
}
313298
}
314299

315-
private Object getConstructorAccessor(Constructor<?> constructor) {
300+
private static Object getConstructorAccessor(Constructor<?> constructor) {
316301
try {
317302
return getConstructorAccessorMethod.invoke(constructor);
318303
} catch (ReflectiveOperationException e) {
319304
throw VMError.shouldNotReachHere(e);
320305
}
321306
}
322307

323-
private Constructor<?> getExternalizableConstructor(Class<?> serializationTargetClass) {
308+
private static Constructor<?> getExternalizableConstructor(Class<?> serializationTargetClass) {
324309
try {
325310
return (Constructor<?>) getExternalizableConstructorMethod.invoke(null, serializationTargetClass);
326311
} catch (ReflectiveOperationException e) {

0 commit comments

Comments
 (0)