4545import org .graalvm .nativeimage .c .function .CodePointer ;
4646import org .graalvm .nativeimage .c .struct .SizeOf ;
4747import org .graalvm .nativeimage .hosted .RuntimeProxyCreation ;
48- import org .graalvm .nativeimage .hosted .RuntimeReflection ;
4948import org .graalvm .nativeimage .hosted .RuntimeSerialization ;
5049import org .graalvm .word .Pointer ;
5150import org .graalvm .word .PointerBase ;
9998import com .oracle .svm .hosted .ReachabilityCallbackNode ;
10099import com .oracle .svm .hosted .SharedArenaSupport ;
101100import com .oracle .svm .hosted .code .SubstrateCompilationDirectives ;
101+ import com .oracle .svm .hosted .dynamicaccess .JVMCIRuntimeReflection ;
102102import com .oracle .svm .hosted .dynamicaccessinference .DynamicAccessInferenceLog ;
103103import com .oracle .svm .hosted .dynamicaccessinference .StrictDynamicAccessInferenceFeature ;
104104import com .oracle .svm .hosted .nodes .DeoptProxyNode ;
105105import com .oracle .svm .hosted .nodes .ReadReservedRegister ;
106106import com .oracle .svm .hosted .substitute .AnnotationSubstitutionProcessor ;
107107import com .oracle .svm .util .AnnotationUtil ;
108+ import com .oracle .svm .util .JVMCIReflectionUtil ;
108109import com .oracle .svm .util .OriginalClassProvider ;
109110import 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