changeset 23314:2d1ca131b8be

get VM internal flags when creating HotSpotResolvedJavaFieldImpl from Field reflection object (JDK-8151266)
author Doug Simon <doug.simon@oracle.com>
date Mon, 07 Mar 2016 10:54:56 +0100
parents 6758183dd36b
children 21fe118a18e6
files jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java src/share/vm/jvmci/jvmciCompilerToVM.cpp
diffstat 3 files changed, 36 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Fri Feb 26 13:21:28 2016 +0100
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Mon Mar 07 10:54:56 2016 +0100
@@ -27,6 +27,7 @@
 import static jdk.vm.ci.inittimer.InitTimer.timer;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
 import jdk.vm.ci.code.BytecodeFrame;
@@ -356,6 +357,12 @@
     native HotSpotResolvedJavaMethodImpl getResolvedJavaMethodAtSlot(Class<?> holder, int slot);
 
     /**
+     * Gets the flags (including VM internal flags) for the field identified by {@code holder} and
+     * slot number {@code slot} (i.e. {@link Field#slot}).
+     */
+    native int getResolvedJavaFieldFlagsAtSlot(Class<?> holder, int slot);
+
+    /**
      * Gets the maximum absolute offset of a PC relative call to {@code address} from any position
      * in the code cache.
      *
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java	Fri Feb 26 13:21:28 2016 +0100
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java	Mon Mar 07 10:54:56 2016 +0100
@@ -85,6 +85,11 @@
     private Field reflectionMethodSlot = getReflectionSlotField(Method.class);
 
     /**
+     * {@link Field} object of {@link Field#slot}.
+     */
+    private Field reflectionFieldSlot = getReflectionSlotField(Field.class);
+
+    /**
      * {@link Field} object of {@link Constructor#slot}.
      */
     private Field reflectionConstructorSlot = getReflectionSlotField(Constructor.class);
@@ -111,22 +116,25 @@
     }
 
     public ResolvedJavaField lookupJavaField(Field reflectionField) {
-        String name = reflectionField.getName();
-        Class<?> fieldHolder = reflectionField.getDeclaringClass();
-        Class<?> fieldType = reflectionField.getType();
-        // java.lang.reflect.Field's modifiers should be enough here since VM internal modifier bits
-        // are not used (yet).
-        final int modifiers = reflectionField.getModifiers();
-        final long offset = Modifier.isStatic(modifiers) ? UNSAFE.staticFieldOffset(reflectionField) : UNSAFE.objectFieldOffset(reflectionField);
+        try {
+            String name = reflectionField.getName();
+            Class<?> fieldHolder = reflectionField.getDeclaringClass();
+            Class<?> fieldType = reflectionField.getType();
+            final int slot = reflectionFieldSlot.getInt(reflectionField);
 
-        HotSpotResolvedObjectType holder = fromObjectClass(fieldHolder);
-        JavaType type = runtime.fromClass(fieldType);
+            HotSpotResolvedObjectType holder = fromObjectClass(fieldHolder);
+            final int flags = runtime.getCompilerToVM().getResolvedJavaFieldFlagsAtSlot(fieldHolder, slot);
+            final long offset = Modifier.isStatic(flags) ? UNSAFE.staticFieldOffset(reflectionField) : UNSAFE.objectFieldOffset(reflectionField);
+            JavaType type = runtime.fromClass(fieldType);
 
-        if (offset != -1) {
-            HotSpotResolvedObjectType resolved = holder;
-            return resolved.createField(name, type, offset, modifiers);
-        } else {
-            throw new JVMCIError("unresolved field %s", reflectionField);
+            if (offset != -1) {
+                HotSpotResolvedObjectType resolved = holder;
+                return resolved.createField(name, type, offset, flags);
+            } else {
+                throw new JVMCIError("unresolved field %s", reflectionField);
+            }
+        } catch (IllegalArgumentException | IllegalAccessException e) {
+            throw new JVMCIError(e);
         }
     }
 
--- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Fri Feb 26 13:21:28 2016 +0100
+++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Mon Mar 07 10:54:56 2016 +0100
@@ -179,6 +179,12 @@
   return JNIHandles::make_local(THREAD, result);
 }
 
+C2V_VMENTRY(jint, getResolvedJavaFieldFlagsAtSlot, (JNIEnv *, jobject, jclass holder_handle, jint slot))
+  oop java_class = JNIHandles::resolve(holder_handle);
+  Klass* holder = java_lang_Class::as_Klass(java_class);
+  return InstanceKlass::cast(holder)->field_access_flags(slot);
+}
+
 C2V_VMENTRY(jobject, getResolvedJavaMethod, (JNIEnv *, jobject, jobject base, jlong offset))
   methodHandle method;
   oop base_object = JNIHandles::resolve(base);
@@ -1247,6 +1253,7 @@
   {CC"getClassInitializer",                          CC"("HS_RESOLVED_KLASS")"HS_RESOLVED_METHOD,                                      FN_PTR(getClassInitializer)},
   {CC"hasFinalizableSubclass",                       CC"("HS_RESOLVED_KLASS")Z",                                                       FN_PTR(hasFinalizableSubclass)},
   {CC"getMaxCallTargetOffset",                       CC"(J)J",                                                                         FN_PTR(getMaxCallTargetOffset)},
+  {CC"getResolvedJavaFieldFlagsAtSlot",              CC"("CLASS"I)I"                 ,                                                 FN_PTR(getResolvedJavaFieldFlagsAtSlot)},
   {CC"getResolvedJavaMethodAtSlot",                  CC"("CLASS"I)"HS_RESOLVED_METHOD,                                                 FN_PTR(getResolvedJavaMethodAtSlot)},
   {CC"getResolvedJavaMethod",                        CC"(Ljava/lang/Object;J)"HS_RESOLVED_METHOD,                                      FN_PTR(getResolvedJavaMethod)},
   {CC"getConstantPool",                              CC"(Ljava/lang/Object;J)"HS_CONSTANT_POOL,                                        FN_PTR(getConstantPool)},