changeset 52910:84c4bed32dd2 amber-demo

Automatic merge with datum
author mcimadamore
date Wed, 24 Oct 2018 05:30:33 +0200
parents ec835e2ed021 9fca582660cc
children 334332456aa1
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
diffstat 14 files changed, 250 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/make/hotspot/symbols/symbols-unix	Tue Oct 23 05:55:40 2018 +0200
+++ b/make/hotspot/symbols/symbols-unix	Wed Oct 24 05:30:33 2018 +0200
@@ -123,6 +123,7 @@
 JVM_GetNestMembers
 JVM_GetPrimitiveArrayElement
 JVM_GetProtectionDomain
+JVM_GetRecordParameters
 JVM_GetSimpleBinaryName
 JVM_GetStackAccessControlContext
 JVM_GetSystemPackage
--- a/src/hotspot/share/classfile/classFileParser.cpp	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Wed Oct 24 05:30:33 2018 +0200
@@ -3789,7 +3789,7 @@
   this_klass->set_nest_host_index(_nest_host);
   this_klass->set_local_interfaces(_local_interfaces);
   this_klass->set_annotations(_combined_annotations);
-  this_klass->set_recordParams(_record_params, record_params_count);
+  this_klass->set_record_params(_record_params, record_params_count);
   // Delay the setting of _transitive_interfaces until after initialize_supers() in
   // fill_instance_klass(). It is because the _transitive_interfaces may be shared with
   // its _super. If an OOM occurs while loading the current klass, its _super field
--- a/src/hotspot/share/include/jvm.h	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/hotspot/share/include/jvm.h	Wed Oct 24 05:30:33 2018 +0200
@@ -515,6 +515,9 @@
 JNIEXPORT jobjectArray JNICALL
 JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly);
 
+JNIEXPORT jobjectArray JNICALL
+JVM_GetRecordParameters(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
    class file rather than searching the InnerClasses attribute (if
--- a/src/hotspot/share/oops/instanceKlass.cpp	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Wed Oct 24 05:30:33 2018 +0200
@@ -564,6 +564,12 @@
   }
   set_nest_members(NULL);
 
+  if (record_params() != NULL &&
+      record_params() != Universe::the_empty_short_array()) {
+    MetadataFactory::free_array<jushort>(loader_data, record_params());
+  }
+  set_record_params(NULL, 0);
+
   // We should deallocate the Annotations instance if it's not in shared spaces.
   if (annotations() != NULL && !annotations()->is_shared()) {
     MetadataFactory::free_metadata(loader_data, annotations());
@@ -2270,7 +2276,7 @@
   }
 
   it->push(&_nest_members);
-  it->push(&_recordParams);
+  it->push(&_record_params);
 }
 
 void InstanceKlass::remove_unshareable_info() {
--- a/src/hotspot/share/oops/instanceKlass.hpp	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Wed Oct 24 05:30:33 2018 +0200
@@ -35,6 +35,7 @@
 #include "oops/fieldInfo.hpp"
 #include "oops/instanceOop.hpp"
 #include "oops/klassVtable.hpp"
+#include "oops/recordParamInfo.hpp"
 #include "runtime/handles.hpp"
 #include "runtime/os.hpp"
 #include "utilities/accessFlags.hpp"
@@ -188,7 +189,7 @@
   // if this class is unloaded.
   Symbol*         _array_name;
 
-  Array<u2>*      _recordParams;
+  Array<u2>*      _record_params;
 
   // Number of heapOopSize words used by non-static fields in this klass
   // (including inherited fields but after header_size()).
@@ -433,6 +434,8 @@
   friend class fieldDescriptor;
   FieldInfo* field(int index) const { return FieldInfo::from_field_array(_fields, index); }
 
+  RecordParamInfo* record_param(int index) const { return RecordParamInfo::from_record_params_array(_fields, index); }
+
  public:
   int     field_offset      (int index) const { return field(index)->offset(); }
   int     field_access_flags(int index) const { return field(index)->access_flags(); }
@@ -461,12 +464,18 @@
   jushort nest_host_index() const { return _nest_host_index; }
   void set_nest_host_index(u2 i)  { _nest_host_index = i; }
 
+  // record parameters
+  int     record_param_access_flags(int index) const { return record_param(index)->access_flags(); }
+  Symbol* record_param_name(int index) const { return record_param(index)->name(constants()); }
+  Symbol* record_param_signature(int index) const { return record_param(index)->signature(constants()); }
+  Symbol* record_param_descriptor(int index) const { return record_param(index)->signature(constants()); }
+
   int record_params_count() const       { return (int)_record_params_count; }
 
-  Array<u2>* recordParams() const       { return _recordParams; }
-  void set_recordParams(Array<u2>* recordParams, u2 record_params_count) {
-    guarantee(_recordParams == NULL || recordParams == NULL, "Just checking");
-    _recordParams = recordParams;
+  Array<u2>* record_params() const       { return _record_params; }
+  void set_record_params(Array<u2>* record_params, u2 record_params_count) {
+    guarantee(_record_params == NULL || record_params == NULL, "Just checking");
+    _record_params = record_params;
     _record_params_count = record_params_count;
   }
 
--- a/src/hotspot/share/oops/recordParamInfo.hpp	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/hotspot/share/oops/recordParamInfo.hpp	Wed Oct 24 05:30:33 2018 +0200
@@ -37,6 +37,8 @@
 
 class RecordParamInfo {
   friend class ClassFileParser;
+  friend class RecordParameterStreamBase;
+  friend class JavaRecordParameterStream;
   enum ParamOffset {
     access_flags_offset      = 0,
     name_index_offset        = 1,
@@ -48,13 +50,26 @@
 private:
   u2 _shorts[param_slots];
 
-  void set_name_index(u2 val)                    { _shorts[name_index_offset] = val;         }
-  void set_descriptor_index(u2 val)              { _shorts[descriptor_index_offset] = val;   }
-  void set_signature_index(u2 val)               { _shorts[signature_index_offset] = val;    }
+  void set_name_index(u2 val)                              { _shorts[name_index_offset] = val;         }
+  void set_descriptor_index(u2 val)                        { _shorts[descriptor_index_offset] = val;   }
+  void set_signature_index(u2 val)                         { _shorts[signature_index_offset] = val;    }
 
-  u2 name_index() const                          { return _shorts[name_index_offset];        }
-  u2 descriptor_index() const                    { return _shorts[descriptor_index_offset];  }
-  u2 signature_index() const                     { return _shorts[signature_index_offset];   }
+  u2 name_index() const                                    { return _shorts[name_index_offset];        }
+  u2 descriptor_index() const                              { return _shorts[descriptor_index_offset];  }
+  u2 signature_index() const                               { return _shorts[signature_index_offset];   }
+public:
+  static RecordParamInfo* from_record_params_array(Array<u2>* record_params, int index) {
+    return ((RecordParamInfo*)record_params->adr_at(index * param_slots));
+  }
+  static RecordParamInfo* from_record_param_array(u2* record_params, int index) {
+    return ((RecordParamInfo*)(record_params + index * param_slots));
+  }
+
+  u2 access_flags() const                                   { return _shorts[access_flags_offset];      }
+  Symbol* name(const constantPoolHandle& cp) const          { return cp->symbol_at(name_index());       }
+  Symbol* signature(const constantPoolHandle& cp) const     { return cp->symbol_at(signature_index());  }
+  Symbol* descriptor(const constantPoolHandle& cp) const    { return cp->symbol_at(descriptor_index()); }
+  void set_access_flags(u2 val)                             { _shorts[access_flags_offset] = val;       }
 };
 
 #endif // SHARE_VM_OOPS_RECORDPARAMINFO_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/oops/recordParamStreams.hpp	Wed Oct 24 05:30:33 2018 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_RECORDPARAMSTREAMS_HPP
+#define SHARE_VM_OOPS_RECORDPARAMSTREAMS_HPP
+
+#include "oops/instanceKlass.hpp"
+#include "oops/recordParamInfo.hpp"
+
+// The is the base class for iteration over the record parameters array
+// describing the parameters in a record.
+class RecordParameterStreamBase : public StackObj {
+ protected:
+  Array<u2>*          _record_parameters;
+  constantPoolHandle  _constants;
+  int                 _index;
+  int                 _limit;
+
+  RecordParamInfo* record_param() const { return RecordParamInfo::from_record_params_array(_record_parameters, _index); }
+  InstanceKlass* record_param_holder() const { return _constants->pool_holder(); }
+
+  RecordParameterStreamBase(Array<u2>* record_params, const constantPoolHandle& constants, int start, int limit) {
+    _record_parameters = record_params;
+    _constants = constants;
+    _index = start;
+    int num_record_parameters = record_params->length() / RecordParamInfo::param_slots;
+    if (limit < start) {
+      _limit = num_record_parameters;
+    } else {
+      _limit = limit;
+    }
+  }
+
+  RecordParameterStreamBase(Array<u2>* record_params, const constantPoolHandle& constants) {
+    _record_parameters = record_params;
+    _constants = constants;
+    _index = 0;
+    _limit = record_params->length() / RecordParamInfo::param_slots;;
+  }
+
+ public:
+  RecordParameterStreamBase(InstanceKlass* klass) {
+    _record_parameters = klass->record_params();
+    _constants = klass->constants();
+    _index = 0;
+    _limit = klass->record_params_count();
+    assert(klass == record_param_holder(), "");
+  }
+
+  // accessors
+  int index() const                 { return _index; }
+
+  void next() {
+    _index += 1;
+  }
+  bool done() const { return _index >= _limit; }
+
+  // Accessors for current record parameter
+  AccessFlags access_flags() const {
+    AccessFlags flags;
+    flags.set_flags(record_param()->access_flags());
+    return flags;
+  }
+
+  void set_access_flags(u2 flags) const {
+    record_param()->set_access_flags(flags);
+  }
+
+  void set_access_flags(AccessFlags flags) const {
+    set_access_flags(flags.as_short());
+  }
+
+  Symbol* name() const {
+    return record_param()->name(_constants);
+  }
+
+  Symbol* descriptor() const {
+    return record_param()->descriptor(_constants);
+  }
+
+  Symbol* signature() const {
+    return record_param()->signature(_constants);
+  }
+};
+
+// Iterate over the record parameters
+class JavaRecordParameterStream : public RecordParameterStreamBase {
+ public:
+  JavaRecordParameterStream(const InstanceKlass* k): RecordParameterStreamBase(k->record_params(), k->constants(), 0, k->record_params_count()) {}
+
+  int name_index() const {
+    return record_param()->name_index();
+  }
+  void set_name_index(int index) {
+    record_param()->set_name_index(index);
+  }
+  int descriptor_index() const {
+    return record_param()->descriptor_index();
+  }
+  void set_descriptor_index(int index) {
+    record_param()->set_descriptor_index(index);
+  }
+  int signature_index() const {
+    return record_param()->signature_index();
+  }
+  void set_generic_signature_index(int index) {
+    record_param()->set_signature_index(index);
+  }
+};
+
+#endif // SHARE_VM_OOPS_RECORDPARAMSTREAMS_HPP
--- a/src/hotspot/share/prims/jvm.cpp	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/hotspot/share/prims/jvm.cpp	Wed Oct 24 05:30:33 2018 +0200
@@ -51,6 +51,7 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/recordParamStreams.hpp"
 #include "prims/jvm_misc.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiThreadState.hpp"
@@ -1787,6 +1788,69 @@
 }
 JVM_END
 
+JVM_ENTRY(jobjectArray, JVM_GetRecordParameters(JNIEnv *env, jclass ofClass))
+{
+  JVMWrapper("JVM_GetRecordParameters");
+  JvmtiVMObjectAllocEventCollector oam;
+
+  // Exclude primitive types and array types
+  if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
+      java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_array_klass()) {
+    // Return empty array
+    oop res = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), 0, CHECK_NULL);
+    return (jobjectArray) JNIHandles::make_local(env, res);
+  }
+
+  InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)));
+  constantPoolHandle cp(THREAD, k->constants());
+
+  // Ensure class is linked
+  k->link_class(CHECK_NULL);
+
+  // Allocate result
+  int num_record_params = k->record_params_count();
+  if (num_record_params == 0) {
+    oop res = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), 0, CHECK_NULL);
+    return (jobjectArray) JNIHandles::make_local(env, res);
+  }
+
+  // all record components are public
+  int num_of_public_fields = 0;
+  for (JavaFieldStream fileStream(k); !fileStream.done(); fileStream.next()) {
+    if (fileStream.access_flags().is_public()) ++num_of_public_fields;
+  }
+
+  objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), num_record_params, CHECK_NULL);
+  objArrayHandle result (THREAD, r);
+
+  int out_idx = 0;
+  fieldDescriptor fd;
+  if (num_record_params == num_of_public_fields) {
+    // all the fields are record components so just return the fields
+    for (JavaFieldStream fileStream(k); !fileStream.done(); fileStream.next()) {
+      fd.reinitialize(k, fileStream.index());
+      oop field = Reflection::new_field(&fd, CHECK_NULL);
+      result->obj_at_put(out_idx, field);
+      ++out_idx;
+    }
+  } else {
+    // it gets a bit more complicated some fields are record params and some not
+    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;
+        }
+      }
+    }
+  }
+  assert(out_idx == num_record_params, "just checking");
+  return (jobjectArray) JNIHandles::make_local(env, result());
+}
+JVM_END
+
 static bool select_method(const methodHandle& method, bool want_constructor) {
   if (want_constructor) {
     return (method->is_initializer() && !method->is_static());
--- a/src/java.base/share/classes/java/lang/Class.java	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/java.base/share/classes/java/lang/Class.java	Wed Oct 24 05:30:33 2018 +0200
@@ -3394,6 +3394,7 @@
     private native Method[]      getDeclaredMethods0(boolean publicOnly);
     private native Constructor<T>[] getDeclaredConstructors0(boolean publicOnly);
     private native Class<?>[]   getDeclaredClasses0();
+    private native Field[]      getRecordParameters0();
 
     /**
      * Helper method to get the method name from arguments.
--- a/src/java.base/share/native/libjava/Class.c	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/java.base/share/native/libjava/Class.c	Wed Oct 24 05:30:33 2018 +0200
@@ -76,6 +76,7 @@
     {"getRawTypeAnnotations", "()" BA,      (void *)&JVM_GetClassTypeAnnotations},
     {"getNestHost0",         "()" CLS,      (void *)&JVM_GetNestHost},
     {"getNestMembers0",      "()[" CLS,     (void *)&JVM_GetNestMembers},
+    {"getRecordParameters0",  "()[" FLD,     (void *)&JVM_GetRecordParameters},
 };
 
 #undef OBJ
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Oct 24 05:30:33 2018 +0200
@@ -359,7 +359,7 @@
         return (flags_field & DEPRECATED) != 0;
     }
 
-    public boolean isDatum() {
+    public boolean isRecord() {
         return (flags_field & RECORD) != 0;
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Wed Oct 24 05:30:33 2018 +0200
@@ -3115,7 +3115,7 @@
             } else if (target == names.PARAMETER) {
                 if (s.kind == VAR &&
                     (s.owner.kind == MTH && (s.flags() & PARAMETER) != 0) ||
-                    (s.owner.kind == TYP && s.owner.isDatum())) {
+                    (s.owner.kind == TYP && s.owner.isRecord())) {
                     return true;
                 }
             } else if (target == names.CONSTRUCTOR) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Oct 24 05:30:33 2018 +0200
@@ -1108,7 +1108,7 @@
         List<VarSymbol> vars = List.nil();
         int numParams = 0;
         for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
-            if (sym.kind == VAR && sym.isDatum()) {
+            if (sym.kind == VAR && sym.isRecord()) {
                 vars = vars.prepend((VarSymbol)sym);
                 numParams++;
             }
@@ -1916,7 +1916,7 @@
             }
         }
 
-        if (c.isDatum()) {
+        if (c.isRecord()) {
             acount += writeRecordAttribute(c);
         }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Oct 23 05:55:40 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Wed Oct 24 05:30:33 2018 +0200
@@ -2185,7 +2185,7 @@
             this.endPosTable = toplevel.endPositions;
             c.pool = pool;
             pool.reset();
-            if (c.isDatum()) {
+            if (c.isRecord()) {
                 Attribute.Compound attribute = c.attribute(syms.dataAnnotationType.tsym);
                 if (attribute == null) {
                     attribute = new Attribute.Compound(syms.dataAnnotationType, List.nil());