From 9710178bb35b7f1de86c0dd23d4427e52088beb1 Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Mon, 15 Mar 2021 21:21:34 +0100 Subject: [PATCH 1/6] Implement static field base and offset methods for Unsafe --- .../oracle/svm/core/jdk/SunMiscSubstitutions.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SunMiscSubstitutions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SunMiscSubstitutions.java index 169cdf9215f9..b6a190d10e10 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SunMiscSubstitutions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SunMiscSubstitutions.java @@ -32,7 +32,11 @@ import java.security.ProtectionDomain; import java.util.function.Function; +import com.oracle.svm.core.StaticFieldsSupport; +import com.oracle.svm.core.config.ObjectLayout; +import jdk.vm.ci.meta.JavaKind; import org.graalvm.compiler.nodes.extended.MembarNode; +import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess; import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; @@ -208,12 +212,19 @@ public void ensureClassInitialized(Class c) { @Substitute private long staticFieldOffset(Field f) { - throw VMError.unsupportedFeature("Unsupported method of Unsafe"); + ObjectLayout layout = ConfigurationValues.getObjectLayout(); + final int baseOffset = layout.getArrayBaseOffset(JavaKind.fromJavaClass(f.getDeclaringClass())); + final long objOffset = GraalUnsafeAccess.getUnsafe().objectFieldOffset(f); + return objOffset - baseOffset; } @Substitute private Object staticFieldBase(Field f) { - throw VMError.unsupportedFeature("Unsupported method of Unsafe"); + if (f.getType().isPrimitive()) { + return StaticFieldsSupport.getStaticPrimitiveFields(); + } else { + return StaticFieldsSupport.getStaticObjectFields(); + } } @Substitute From 8c113532f9aff541947dd5cfedcdbefbb5b05321 Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Tue, 16 Mar 2021 19:57:28 +0100 Subject: [PATCH 2/6] Move `staticFieldOffset` method to the proper place --- .../oracle/svm/core/jdk/SunMiscSubstitutions.java | 11 ----------- ...arget_jdk_internal_misc_Unsafe_Reflection.java | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SunMiscSubstitutions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SunMiscSubstitutions.java index b6a190d10e10..970bf42de5d3 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SunMiscSubstitutions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SunMiscSubstitutions.java @@ -33,10 +33,7 @@ import java.util.function.Function; import com.oracle.svm.core.StaticFieldsSupport; -import com.oracle.svm.core.config.ObjectLayout; -import jdk.vm.ci.meta.JavaKind; import org.graalvm.compiler.nodes.extended.MembarNode; -import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess; import org.graalvm.compiler.serviceprovider.JavaVersionUtil; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; @@ -210,14 +207,6 @@ public void ensureClassInitialized(Class c) { DynamicHub.fromClass(c).ensureInitialized(); } - @Substitute - private long staticFieldOffset(Field f) { - ObjectLayout layout = ConfigurationValues.getObjectLayout(); - final int baseOffset = layout.getArrayBaseOffset(JavaKind.fromJavaClass(f.getDeclaringClass())); - final long objOffset = GraalUnsafeAccess.getUnsafe().objectFieldOffset(f); - return objOffset - baseOffset; - } - @Substitute private Object staticFieldBase(Field f) { if (f.getType().isPrimitive()) { diff --git a/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java b/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java index 0be5575908a4..6cbd02aa041d 100644 --- a/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java +++ b/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java @@ -27,13 +27,22 @@ // Checkstyle: allow reflection +import com.oracle.svm.core.StaticFieldsSupport; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; import com.oracle.svm.core.annotate.TargetElement; +import com.oracle.svm.core.config.ConfigurationValues; +import com.oracle.svm.core.config.ObjectLayout; import com.oracle.svm.core.jdk.JDK11OrLater; import com.oracle.svm.core.jdk.Package_jdk_internal_misc; import com.oracle.svm.core.util.VMError; +import com.oracle.svm.hosted.meta.HostedField; +import com.oracle.svm.reflect.hosted.FieldOffsetComputer; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.MetaUtil; +import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess; import java.lang.reflect.Field; @@ -47,6 +56,7 @@ public long objectFieldOffset(Target_java_lang_reflect_Field field) { if (offset > 0) { return offset; } + throw VMError.unsupportedFeature("The offset of " + field + " is accessed without the field being first registered as unsafe accessed. " + "Please register the field as unsafe accessed. You can do so with a reflection configuration that " + "contains an entry for the field with the attribute \"allowUnsafeAccess\": true. Such a configuration " + @@ -67,4 +77,9 @@ public long objectFieldOffset(Class c, String name) { throw new InternalError(); } } + + @Substitute + private long staticFieldOffset(Target_java_lang_reflect_Field f) { + return f.offset; + } } From 318b011a66eb60522a2e86b892551d5f025adcd5 Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Tue, 16 Mar 2021 19:59:09 +0100 Subject: [PATCH 3/6] Remove unused imports --- .../Target_jdk_internal_misc_Unsafe_Reflection.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java b/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java index 6cbd02aa041d..4ad8c15820b3 100644 --- a/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java +++ b/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java @@ -27,22 +27,13 @@ // Checkstyle: allow reflection -import com.oracle.svm.core.StaticFieldsSupport; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; import com.oracle.svm.core.annotate.TargetElement; -import com.oracle.svm.core.config.ConfigurationValues; -import com.oracle.svm.core.config.ObjectLayout; import com.oracle.svm.core.jdk.JDK11OrLater; import com.oracle.svm.core.jdk.Package_jdk_internal_misc; import com.oracle.svm.core.util.VMError; -import com.oracle.svm.hosted.meta.HostedField; -import com.oracle.svm.reflect.hosted.FieldOffsetComputer; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.MetaUtil; -import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess; import java.lang.reflect.Field; From 63ae40c2ee686e11f76604bffea7443230d61cbe Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Fri, 19 Mar 2021 15:34:35 +0100 Subject: [PATCH 4/6] Fix `staticFieldOffset` in cases when field is not registered as unsafe accessed --- ...t_jdk_internal_misc_Unsafe_Reflection.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java b/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java index 4ad8c15820b3..871c87f31886 100644 --- a/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java +++ b/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java @@ -43,15 +43,7 @@ public final class Target_jdk_internal_misc_Unsafe_Reflection { @Substitute public long objectFieldOffset(Target_java_lang_reflect_Field field) { - int offset = field.root == null ? field.offset : field.root.offset; - if (offset > 0) { - return offset; - } - - throw VMError.unsupportedFeature("The offset of " + field + " is accessed without the field being first registered as unsafe accessed. " + - "Please register the field as unsafe accessed. You can do so with a reflection configuration that " + - "contains an entry for the field with the attribute \"allowUnsafeAccess\": true. Such a configuration " + - "file can be generated for you. Read BuildConfiguration.md and Reflection.md for details."); + return FieldUtils.getFieldOffset(field); } @Substitute @@ -70,7 +62,23 @@ public long objectFieldOffset(Class c, String name) { } @Substitute - private long staticFieldOffset(Target_java_lang_reflect_Field f) { - return f.offset; + public long staticFieldOffset(Target_java_lang_reflect_Field field) { + return FieldUtils.getFieldOffset(field); + } + + + private static class FieldUtils { + private static long getFieldOffset(Target_java_lang_reflect_Field field) { + int offset = field.root == null ? field.offset : field.root.offset; + if (offset > 0) { + return offset; + } + throw VMError.unsupportedFeature( + "The offset of " + field + " is accessed without the field being first registered as unsafe accessed. " + + "Please register the field as unsafe accessed. You can do so with a reflection configuration that " + + "contains an entry for the field with the attribute \"allowUnsafeAccess\": true. Such a configuration " + + "file can be generated for you. Read BuildConfiguration.md and Reflection.md for details." + ); + } } } From e144b468985ef3a8b408190e842302e2832dfe1c Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Fri, 19 Mar 2021 19:04:32 +0100 Subject: [PATCH 5/6] Add comment for clarification --- .../target/Target_jdk_internal_misc_Unsafe_Reflection.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java b/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java index 871c87f31886..d8d4ad35205f 100644 --- a/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java +++ b/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java @@ -63,6 +63,11 @@ public long objectFieldOffset(Class c, String name) { @Substitute public long staticFieldOffset(Target_java_lang_reflect_Field field) { + /* + * Since we store the offset in the `offset` field, which is computed + * through `FieldOffsetComputer#compute`, the implementation for + * this is the same as `objectFieldOffset` method + */ return FieldUtils.getFieldOffset(field); } From 14564353cab4077a6423298fb0e7ed970090fde7 Mon Sep 17 00:00:00 2001 From: ivan-ristovic Date: Sat, 20 Mar 2021 11:55:16 +0100 Subject: [PATCH 6/6] Fix failing style gate --- ...get_jdk_internal_misc_Unsafe_Reflection.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java b/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java index d8d4ad35205f..b8c664d0f31b 100644 --- a/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java +++ b/substratevm/src/com.oracle.svm.reflect/src/com/oracle/svm/reflect/target/Target_jdk_internal_misc_Unsafe_Reflection.java @@ -64,26 +64,23 @@ public long objectFieldOffset(Class c, String name) { @Substitute public long staticFieldOffset(Target_java_lang_reflect_Field field) { /* - * Since we store the offset in the `offset` field, which is computed - * through `FieldOffsetComputer#compute`, the implementation for - * this is the same as `objectFieldOffset` method + * Since we store the offset in the `offset` field, which is computed through + * `FieldOffsetComputer#compute`, the implementation for this is the same as + * `objectFieldOffset` method */ return FieldUtils.getFieldOffset(field); } - private static class FieldUtils { private static long getFieldOffset(Target_java_lang_reflect_Field field) { int offset = field.root == null ? field.offset : field.root.offset; if (offset > 0) { return offset; } - throw VMError.unsupportedFeature( - "The offset of " + field + " is accessed without the field being first registered as unsafe accessed. " + - "Please register the field as unsafe accessed. You can do so with a reflection configuration that " + - "contains an entry for the field with the attribute \"allowUnsafeAccess\": true. Such a configuration " + - "file can be generated for you. Read BuildConfiguration.md and Reflection.md for details." - ); + throw VMError.unsupportedFeature("The offset of " + field + " is accessed without the field being first registered as unsafe accessed. " + + "Please register the field as unsafe accessed. You can do so with a reflection configuration that " + + "contains an entry for the field with the attribute \"allowUnsafeAccess\": true. Such a configuration " + + "file can be generated for you. Read BuildConfiguration.md and Reflection.md for details."); } } }