Skip to content

Commit 8a3fc87

Browse files
committed
svm: migrate SubstrateGraphBuilderPlugins to JVMCIReflection
1 parent fcf61bb commit 8a3fc87

File tree

1 file changed

+38
-27
lines changed

1 file changed

+38
-27
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/SubstrateGraphBuilderPlugins.java

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import org.graalvm.nativeimage.c.function.CodePointer;
4646
import org.graalvm.nativeimage.c.struct.SizeOf;
4747
import org.graalvm.nativeimage.hosted.RuntimeProxyCreation;
48-
import org.graalvm.nativeimage.hosted.RuntimeReflection;
4948
import org.graalvm.nativeimage.hosted.RuntimeSerialization;
5049
import org.graalvm.word.Pointer;
5150
import org.graalvm.word.PointerBase;
@@ -99,12 +98,14 @@
9998
import com.oracle.svm.hosted.ReachabilityCallbackNode;
10099
import com.oracle.svm.hosted.SharedArenaSupport;
101100
import com.oracle.svm.hosted.code.SubstrateCompilationDirectives;
101+
import com.oracle.svm.hosted.dynamicaccess.JVMCIRuntimeReflection;
102102
import com.oracle.svm.hosted.dynamicaccessinference.DynamicAccessInferenceLog;
103103
import com.oracle.svm.hosted.dynamicaccessinference.StrictDynamicAccessInferenceFeature;
104104
import com.oracle.svm.hosted.nodes.DeoptProxyNode;
105105
import com.oracle.svm.hosted.nodes.ReadReservedRegister;
106106
import com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor;
107107
import com.oracle.svm.util.AnnotationUtil;
108+
import com.oracle.svm.util.JVMCIReflectionUtil;
108109
import com.oracle.svm.util.OriginalClassProvider;
109110
import com.oracle.svm.util.ReflectionUtil;
110111

@@ -297,6 +298,13 @@ public static <T> T asConstantObject(GraphBuilderContext b, Class<T> type, Value
297298
return StandardGraphBuilderPlugins.asConstantObject(b, type, node);
298299
}
299300

301+
public static ResolvedJavaType asConstantType(GraphBuilderContext b, ValueNode node) {
302+
if (node instanceof ConstantNode constantNode && constantNode.getValue() instanceof JavaConstant javaConstant && javaConstant.isNonNull()) {
303+
return b.getConstantReflection().asJavaType(javaConstant);
304+
}
305+
return null;
306+
}
307+
300308
public static int asConstantIntegerOrMinusOne(ValueNode node) {
301309
if (node instanceof ConstantNode constantNode && constantNode.getValue() instanceof JavaConstant javaConstant) {
302310
return javaConstant.asInt();
@@ -739,18 +747,18 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
739747
* them for reflection/unsafe access.
740748
*/
741749
private static void interceptUpdaterInvoke(GraphBuilderContext b, ValueNode tclassNode, ValueNode fieldNameNode) {
742-
Class<?> tclass = asConstantObject(b, Class.class, tclassNode);
750+
ResolvedJavaType type = asConstantType(b, tclassNode);
743751
String fieldName = asConstantObject(b, String.class, fieldNameNode);
744-
if (tclass != null && fieldName != null) {
752+
if (type != null && fieldName != null) {
745753
try {
746-
Field field = tclass.getDeclaredField(fieldName);
754+
ResolvedJavaField field = JVMCIReflectionUtil.getDeclaredField(type, fieldName);
747755
/*
748756
* Register the holder class and the field for reflection. This also registers the
749757
* field for unsafe access.
750758
*/
751-
RuntimeReflection.register(tclass);
752-
RuntimeReflection.register(field);
753-
} catch (NoSuchFieldException e) {
759+
JVMCIRuntimeReflection.register(type);
760+
JVMCIRuntimeReflection.register(field);
761+
} catch (NoSuchFieldError e) {
754762
/*
755763
* Ignore the exception. If the field does not exist, there will be an error at run
756764
* time. That is then the same behavior as on HotSpot. The allocation of the
@@ -791,17 +799,15 @@ private static void registerUnsafePlugins(InvocationPlugins plugins) {
791799
r.register(new RequiredInvocationPlugin("objectFieldOffset", Receiver.class, Class.class, String.class) {
792800
@Override
793801
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode classNode, ValueNode nameNode) {
794-
Class<?> clazz = asConstantObject(b, Class.class, classNode);
802+
ResolvedJavaType type = asConstantType(b, classNode);
795803
String fieldName = asConstantObject(b, String.class, nameNode);
796-
if (clazz != null && fieldName != null) {
797-
Field targetField;
798-
try {
799-
targetField = clazz.getDeclaredField(fieldName);
800-
} catch (ReflectiveOperationException | LinkageError e) {
801-
return false;
804+
if (type != null && fieldName != null) {
805+
ResolvedJavaField targetField = JVMCIReflectionUtil.getDeclaredField(false, type, fieldName);
806+
if (targetField != null) {
807+
return processFieldOffset(b, receiver, false, targetField);
802808
}
803-
return processFieldOffset(b, receiver, targetField, false);
804809
}
810+
/* A NullPointerException will be thrown at run time for this call. */
805811
return false;
806812
}
807813
});
@@ -819,8 +825,10 @@ private static void registerUnsafePlugins(Registration r, boolean isSunMiscUnsaf
819825
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode fieldNode) {
820826
Field targetField = asConstantObject(b, Field.class, fieldNode);
821827
if (targetField != null) {
822-
return processFieldOffset(b, receiver, targetField, isSunMiscUnsafe);
828+
ResolvedJavaField resolvedJavaField = b.getMetaAccess().lookupJavaField(targetField);
829+
return processFieldOffset(b, receiver, isSunMiscUnsafe, resolvedJavaField);
823830
}
831+
/* A NullPointerException will be thrown at run time for this call. */
824832
return false;
825833
}
826834
});
@@ -840,8 +848,10 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
840848
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode fieldNode) {
841849
Field targetField = asConstantObject(b, Field.class, fieldNode);
842850
if (targetField != null) {
843-
return processFieldOffset(b, receiver, targetField, isSunMiscUnsafe);
851+
ResolvedJavaField resolvedJavaField = b.getMetaAccess().lookupJavaField(targetField);
852+
return processFieldOffset(b, receiver, isSunMiscUnsafe, resolvedJavaField);
844853
}
854+
/* A NullPointerException will be thrown at run time for this call. */
845855
return false;
846856
}
847857
});
@@ -869,8 +879,8 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
869879
});
870880
}
871881

872-
private static boolean processFieldOffset(GraphBuilderContext b, Receiver receiver, Field targetField, boolean isSunMiscUnsafe) {
873-
if (!isValidField(targetField, isSunMiscUnsafe)) {
882+
private static boolean processFieldOffset(GraphBuilderContext b, Receiver receiver, boolean isSunMiscUnsafe, ResolvedJavaField resolvedJavaField) {
883+
if (!isValidField(resolvedJavaField, isSunMiscUnsafe)) {
874884
return false;
875885
}
876886

@@ -880,15 +890,11 @@ private static boolean processFieldOffset(GraphBuilderContext b, Receiver receiv
880890
* The static analysis registers the field for unsafe access if the node remains in the
881891
* graph until then.
882892
*/
883-
b.addPush(JavaKind.Long, FieldOffsetNode.create(JavaKind.Long, b.getMetaAccess().lookupJavaField(targetField)));
893+
b.addPush(JavaKind.Long, FieldOffsetNode.create(JavaKind.Long, resolvedJavaField));
884894
return true;
885895
}
886896

887-
private static boolean isValidField(Field targetField, boolean isSunMiscUnsafe) {
888-
if (targetField == null) {
889-
/* A NullPointerException will be thrown at run time for this call. */
890-
return false;
891-
}
897+
private static boolean isValidField(ResolvedJavaField targetField, boolean isSunMiscUnsafe) {
892898
/*
893899
* sun.misc.Unsafe performs a few more checks than jdk.internal.misc.Unsafe to explicitly
894900
* disallow hidden classes and records.
@@ -897,13 +903,18 @@ private static boolean isValidField(Field targetField, boolean isSunMiscUnsafe)
897903
}
898904

899905
private static boolean processStaticFieldBase(GraphBuilderContext b, Receiver receiver, Field targetField, boolean isSunMiscUnsafe) {
900-
if (!isValidField(targetField, isSunMiscUnsafe)) {
906+
if (targetField == null) {
907+
/* A NullPointerException will be thrown at run time for this call. */
908+
return false;
909+
}
910+
ResolvedJavaField resolvedJavaField = b.getMetaAccess().lookupJavaField(targetField);
911+
if (!isValidField(resolvedJavaField, isSunMiscUnsafe)) {
901912
return false;
902913
}
903914

904915
/* Emits a null-check for the otherwise unused receiver. */
905916
receiver.get(true);
906-
b.addPush(JavaKind.Object, StaticFieldsSupport.createStaticFieldBaseNode(b.getMetaAccess().lookupJavaField(targetField)));
917+
b.addPush(JavaKind.Object, StaticFieldsSupport.createStaticFieldBaseNode(resolvedJavaField));
907918
return true;
908919
}
909920

0 commit comments

Comments
 (0)