changeset 56906:7241fb1920dc records-and-sealed

sync the reflection API for records with the specification
author vromero
date Wed, 26 Jun 2019 20:09:35 -0400
parents 8d093ef9814e
children 8997e7fb45a7 8cbd278a7204
files make/hotspot/symbols/symbols-unix src/hotspot/share/include/jvm.h src/hotspot/share/prims/jvm.cpp src/java.base/share/classes/java/lang/Class.java src/java.base/share/native/libjava/Class.c
diffstat 5 files changed, 53 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- a/make/hotspot/symbols/symbols-unix	Wed Jun 26 17:52:40 2019 -0400
+++ b/make/hotspot/symbols/symbols-unix	Wed Jun 26 20:09:35 2019 -0400
@@ -123,8 +123,7 @@
 JVM_GetPrimitiveArrayElement
 JVM_GetProperties
 JVM_GetProtectionDomain
-JVM_GetRecordParameters
-JVM_GetRecordParametersCount
+JVM_GetRecordComponentNames
 JVM_GetSimpleBinaryName
 JVM_GetStackAccessControlContext
 JVM_GetSystemPackage
--- a/src/hotspot/share/include/jvm.h	Wed Jun 26 17:52:40 2019 -0400
+++ b/src/hotspot/share/include/jvm.h	Wed Jun 26 20:09:35 2019 -0400
@@ -518,10 +518,7 @@
 JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly);
 
 JNIEXPORT jobjectArray JNICALL
-JVM_GetRecordParameters(JNIEnv *env, jclass ofClass);
-
-JNIEXPORT jint JNICALL
-JVM_GetRecordParametersCount(JNIEnv *env, jclass ofClass);
+JVM_GetRecordComponentNames(JNIEnv *env, jclass ofClass);
 
 /* Differs from JVM_GetClassModifiers in treatment of inner classes.
    This returns the access flags for the class as specified in the
--- a/src/hotspot/share/prims/jvm.cpp	Wed Jun 26 17:52:40 2019 -0400
+++ b/src/hotspot/share/prims/jvm.cpp	Wed Jun 26 20:09:35 2019 -0400
@@ -1661,24 +1661,10 @@
 }
 JVM_END
 
-JVM_ENTRY(jint, JVM_GetRecordParametersCount(JNIEnv *env, jclass ofClass))
+JVM_ENTRY(jobjectArray, JVM_GetRecordComponentNames(JNIEnv *env, jclass ofClass))
 {
   // current is not a primitive or array class
-  JVMWrapper("JVM_GetRecordParametersCount");
-  JvmtiVMObjectAllocEventCollector oam;
-
-  InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)));
-  // Ensure class is linked
-  k->link_class(CHECK_0);
-
-  return k->record_params_count();
-}
-JVM_END
-
-JVM_ENTRY(jobjectArray, JVM_GetRecordParameters(JNIEnv *env, jclass ofClass))
-{
-  // current is not a primitive or array class
-  JVMWrapper("JVM_GetRecordParameters");
+  JVMWrapper("JVM_GetRecordComponentNames");
   JvmtiVMObjectAllocEventCollector oam;
 
   InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)));
@@ -1698,23 +1684,17 @@
     return (jobjectArray) JNIHandles::make_local(env, res);
   }
 
-  objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), num_record_params, CHECK_NULL);
-  objArrayHandle result (THREAD, r);
+  objArrayOop  dest_o = oopFactory::new_objArray(SystemDictionary::String_klass(), num_record_params, CHECK_NULL);
+  objArrayHandle dest(THREAD, dest_o);
 
   int out_idx = 0;
-  fieldDescriptor fd;
   for (JavaRecordParameterStream recordParamsStream(k); !recordParamsStream.done(); recordParamsStream.next()) {
-    for (JavaFieldStream fileStream(k); !fileStream.done(); fileStream.next()) {
-      if (fileStream.name() == recordParamsStream.name()) {
-        fd.reinitialize(k, fileStream.index());
-        oop field = Reflection::new_field(&fd, CHECK_NULL);
-        result->obj_at_put(out_idx, field);
-        ++out_idx;
-      }
-    }
+    Handle str = java_lang_String::create_from_symbol(recordParamsStream.name(), CHECK_NULL);
+    dest->obj_at_put(out_idx, str());
+    ++out_idx;
   }
   assert(out_idx == num_record_params, "just checking");
-  return (jobjectArray) JNIHandles::make_local(env, result());
+  return (jobjectArray) JNIHandles::make_local(dest());
 }
 JVM_END
 
--- a/src/java.base/share/classes/java/lang/Class.java	Wed Jun 26 17:52:40 2019 -0400
+++ b/src/java.base/share/classes/java/lang/Class.java	Wed Jun 26 20:09:35 2019 -0400
@@ -2253,24 +2253,28 @@
      * TBD
      * @return TBD
      * @throws SecurityException TBD
-     * @since 1.12
+     * @throws NoSuchMethodException TBD
+     * @since 1.14
      */
     @CallerSensitive
-    public Field[] getRecordParameters() throws SecurityException {
+    public Method[] getRecordAccessors() throws SecurityException, NoSuchMethodException {
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
         }
-        return isPrimitive() || isArray() ? new Field[0] : copyFields(privateGetRecordParameters());
-    }
-
-    /**
-     * Returns the number of record parameters if this class is a record, 0 if not
-     * @return the number of record parameters
-     * @since 1.12
-     */
-    public int getRecordParametersCount() {
-        return isPrimitive() || isArray() ? 0 : getRecordParametersCount0();
+        if (isPrimitive() || isArray()) {
+            return new Method[0];
+        }
+        String[] componentNames = getRecordComponentNames0();
+        if (componentNames == null || componentNames.length == 0) {
+            return new Method[0];
+        }
+        Method[] result = new Method[componentNames.length];
+        int i = 0;
+        for (String componentName : componentNames) {
+            result[i] = getMethod(componentName);
+        }
+        return result;
     }
 
     /**
@@ -2973,8 +2977,6 @@
         volatile Field[] declaredPublicFields;
         volatile Method[] declaredPublicMethods;
         volatile Class<?>[] interfaces;
-        // record parameters
-        volatile Field[] recordParameters;
 
         // Cached names
         String simpleName;
@@ -3095,21 +3097,6 @@
         return res;
     }
 
-    private Field[] privateGetRecordParameters() {
-        Field[] res;
-        ReflectionData<T> rd = reflectionData();
-        if (rd != null) {
-            res = rd.recordParameters;
-            if (res != null) return res;
-        }
-        // No cached value available; request value from VM
-        res = Reflection.filterFields(this, getRecordParameters0());
-        if (rd != null) {
-            rd.recordParameters = res;
-        }
-        return res;
-    }
-
     // Returns an array of "root" fields. These Field objects must NOT
     // be propagated to the outside world, but must instead be copied
     // via ReflectionFactory.copyField.
@@ -3447,8 +3434,7 @@
     private native Method[]      getDeclaredMethods0(boolean publicOnly);
     private native Constructor<T>[] getDeclaredConstructors0(boolean publicOnly);
     private native Class<?>[]   getDeclaredClasses0();
-    private native Field[]      getRecordParameters0();
-    private native int          getRecordParametersCount0();
+    private native String[]     getRecordComponentNames0();
 
     /**
      * Helper method to get the method name from arguments.
@@ -3558,48 +3544,6 @@
         return false;
     }
 
-    /**
-     * Returns an array with the names of the components
-     *
-     * @return an array with the names of the components
-     * @since 1.12
-     */
-    public String[] getRecordParameterNames() {
-        if (isRecord()) {
-            Field[] recordParameters = getRecordParameters();
-            String[] names = new String[recordParameters.length];
-            int i = 0;
-            for (Field field : recordParameters) {
-                names[i] = field.getName();
-                i++;
-            }
-            return names;
-        } else {
-            return new String[0];
-        }
-    }
-
-    /**
-     * Returns an array with the types of the record parameters
-     *
-     * @return an array with the types of the record parameters
-     * @since 1.12
-     */
-    public Class<?>[] getRecordParameterTypes() {
-        if (isRecord()) {
-            Field[] recordParameters = getRecordParameters();
-            Class<?>[] types = new Class<?>[recordParameters.length];
-            int i = 0;
-            for (Field field : recordParameters) {
-                types[i] = field.getType();
-                i++;
-            }
-            return types;
-        } else {
-            return new Class<?>[0];
-        }
-    }
-
     // Fetches the factory for reflective objects
     private static ReflectionFactory getReflectionFactory() {
         if (reflectionFactory == null) {
--- a/src/java.base/share/native/libjava/Class.c	Wed Jun 26 17:52:40 2019 -0400
+++ b/src/java.base/share/native/libjava/Class.c	Wed Jun 26 20:09:35 2019 -0400
@@ -52,33 +52,32 @@
 #define BA  "[B"
 
 static JNINativeMethod methods[] = {
-    {"initClassName",    "()" STR,          (void *)&JVM_InitClassName},
-    {"getSuperclass",    "()" CLS,          NULL},
-    {"getInterfaces0",   "()[" CLS,         (void *)&JVM_GetClassInterfaces},
-    {"isInterface",      "()Z",             (void *)&JVM_IsInterface},
-    {"getSigners",       "()[" OBJ,         (void *)&JVM_GetClassSigners},
-    {"setSigners",       "([" OBJ ")V",     (void *)&JVM_SetClassSigners},
-    {"isArray",          "()Z",             (void *)&JVM_IsArrayClass},
-    {"isPrimitive",      "()Z",             (void *)&JVM_IsPrimitiveClass},
-    {"getModifiers",     "()I",             (void *)&JVM_GetClassModifiers},
-    {"getDeclaredFields0","(Z)[" FLD,       (void *)&JVM_GetClassDeclaredFields},
-    {"getDeclaredMethods0","(Z)[" MHD,      (void *)&JVM_GetClassDeclaredMethods},
-    {"getDeclaredConstructors0","(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors},
-    {"getProtectionDomain0", "()" PD,       (void *)&JVM_GetProtectionDomain},
-    {"getDeclaredClasses0",  "()[" CLS,     (void *)&JVM_GetDeclaredClasses},
-    {"getDeclaringClass0",   "()" CLS,      (void *)&JVM_GetDeclaringClass},
-    {"getSimpleBinaryName0", "()" STR,      (void *)&JVM_GetSimpleBinaryName},
-    {"getGenericSignature0", "()" STR,      (void *)&JVM_GetClassSignature},
-    {"getRawAnnotations",      "()" BA,     (void *)&JVM_GetClassAnnotations},
-    {"getConstantPool",     "()" CPL,       (void *)&JVM_GetClassConstantPool},
-    {"desiredAssertionStatus0","("CLS")Z",  (void *)&JVM_DesiredAssertionStatus},
-    {"getEnclosingMethod0", "()[" OBJ,      (void *)&JVM_GetEnclosingMethodInfo},
-    {"getRawTypeAnnotations", "()" BA,      (void *)&JVM_GetClassTypeAnnotations},
-    {"getNestHost0",         "()" CLS,      (void *)&JVM_GetNestHost},
-    {"getNestMembers0",      "()[" CLS,     (void *)&JVM_GetNestMembers},
-    {"getPermittedSubtypes0", "()[" CLS,    (void *)&JVM_GetPermittedSubtypes},
-    {"getRecordParameters0",  "()[" FLD,    (void *)&JVM_GetRecordParameters},
-    {"getRecordParametersCount0", "()I",    (void *)&JVM_GetRecordParametersCount},
+    {"initClassName",    "()" STR,              (void *)&JVM_InitClassName},
+    {"getSuperclass",    "()" CLS,              NULL},
+    {"getInterfaces0",   "()[" CLS,             (void *)&JVM_GetClassInterfaces},
+    {"isInterface",      "()Z",                 (void *)&JVM_IsInterface},
+    {"getSigners",       "()[" OBJ,             (void *)&JVM_GetClassSigners},
+    {"setSigners",       "([" OBJ ")V",         (void *)&JVM_SetClassSigners},
+    {"isArray",          "()Z",                 (void *)&JVM_IsArrayClass},
+    {"isPrimitive",      "()Z",                 (void *)&JVM_IsPrimitiveClass},
+    {"getModifiers",     "()I",                 (void *)&JVM_GetClassModifiers},
+    {"getDeclaredFields0","(Z)[" FLD,           (void *)&JVM_GetClassDeclaredFields},
+    {"getDeclaredMethods0","(Z)[" MHD,          (void *)&JVM_GetClassDeclaredMethods},
+    {"getDeclaredConstructors0","(Z)[" CTR,     (void *)&JVM_GetClassDeclaredConstructors},
+    {"getProtectionDomain0", "()" PD,           (void *)&JVM_GetProtectionDomain},
+    {"getDeclaredClasses0",  "()[" CLS,         (void *)&JVM_GetDeclaredClasses},
+    {"getDeclaringClass0",   "()" CLS,          (void *)&JVM_GetDeclaringClass},
+    {"getSimpleBinaryName0", "()" STR,          (void *)&JVM_GetSimpleBinaryName},
+    {"getGenericSignature0", "()" STR,          (void *)&JVM_GetClassSignature},
+    {"getRawAnnotations",      "()" BA,         (void *)&JVM_GetClassAnnotations},
+    {"getConstantPool",     "()" CPL,           (void *)&JVM_GetClassConstantPool},
+    {"desiredAssertionStatus0","("CLS")Z",      (void *)&JVM_DesiredAssertionStatus},
+    {"getEnclosingMethod0", "()[" OBJ,          (void *)&JVM_GetEnclosingMethodInfo},
+    {"getRawTypeAnnotations", "()" BA,          (void *)&JVM_GetClassTypeAnnotations},
+    {"getNestHost0",         "()" CLS,          (void *)&JVM_GetNestHost},
+    {"getNestMembers0",      "()[" CLS,         (void *)&JVM_GetNestMembers},
+    {"getPermittedSubtypes0", "()[" CLS,        (void *)&JVM_GetPermittedSubtypes},
+    {"getRecordComponentNames0",  "()[" STR,    (void *)&JVM_GetRecordComponentNames},
 };
 
 #undef OBJ