changeset 52905:ec835e2ed021 amber-demo

Automatic merge with datum
author mcimadamore
date Tue, 23 Oct 2018 05:55:40 +0200
parents 11e665279521 429ef256f955
children 84c4bed32dd2
files
diffstat 6 files changed, 186 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/classfile/classFileParser.cpp	Fri Oct 19 15:20:19 2018 -0400
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Tue Oct 23 05:55:40 2018 +0200
@@ -54,6 +54,7 @@
 #include "oops/metadata.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/recordParamInfo.hpp"
 #include "oops/symbol.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiThreadState.hpp"
@@ -1742,6 +1743,7 @@
       _fields->at_put(i++, fa[j]);
     }
     assert(_fields->length() == i, "");
+    //tty->print_cr("length of the _fields array %d for class %s", i, _class_name->as_klass_external_name());
   }
 
   if (_need_verify && length > 1) {
@@ -3256,6 +3258,83 @@
   return length;
 }
 
+void ClassFileParser::parse_classfile_record_attribute(const ClassFileStream* const cfs,
+                                                           const u1* const record_attribute_start,
+                                                           ConstantPool* cp,
+                                                           u2* const record_params_count_ptr,
+                                                           TRAPS) {
+  assert(NULL == _record_params, "invariant");
+
+  const u1* const current_mark = cfs->current();
+  u2 num_of_params = 0;
+  if (record_attribute_start != NULL) {
+    cfs->set_current(record_attribute_start);
+    cfs->guarantee_more(2, CHECK);  // length
+    num_of_params = cfs->get_u2_fast();
+    // DEBUG
+    // tty->print_cr("this record has %d parameters", num_of_params);
+  }
+
+  *record_params_count_ptr = num_of_params;
+
+  ResourceMark rm(THREAD);
+  u2* const record_params_array = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD,
+                                              u2,
+                                              num_of_params * (RecordParamInfo::param_slots + 1));
+  for (int n = 0; n < num_of_params; n++) {
+    cfs->guarantee_more(RecordParamInfo::param_slots, CHECK);
+
+    const u2 name_index = cfs->get_u2_fast();
+    check_property(valid_symbol_at(name_index),
+      "Invalid constant pool index %u for record parameter name in class file %s",
+      name_index, CHECK);
+    const Symbol* const name = cp->symbol_at(name_index);
+    verify_legal_field_name(name, CHECK);
+    // DEBUG
+    // tty->print_cr("name read %s", name->as_klass_external_name());
+
+    AccessFlags access_flags;
+    const jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_FIELD_MODIFIERS;
+    verify_legal_field_modifiers(flags, false, CHECK);
+    access_flags.set_flags(flags);
+
+    const u2 descriptor_index = cfs->get_u2_fast();
+    check_property(valid_symbol_at(descriptor_index),
+      "Invalid constant pool index %u for record parameter descriptor in class file %s",
+      descriptor_index, CHECK);
+    const Symbol* const descriptor = cp->symbol_at(descriptor_index);
+    verify_legal_field_signature(name, descriptor, CHECK);
+    // DEBUG
+    // tty->print_cr("descriptor read %s", descriptor->as_klass_external_name());
+
+    const u2 signature_index = cfs->get_u2_fast();
+    check_property(valid_symbol_at(signature_index),
+      "Invalid constant pool index %u for record parameter signature in class file %s",
+      signature_index, CHECK);
+    const Symbol* const sig = cp->symbol_at(signature_index);
+    // DEBUG
+    // tty->print_cr("signature read %s", sig->as_klass_external_name());
+  }
+
+  assert(NULL == _record_params, "invariant");
+
+  _record_params = MetadataFactory::new_array<u2>(_loader_data,
+                                     num_of_params * RecordParamInfo::param_slots,
+                                     CHECK);
+  {
+    int i = 0;
+    for (; i < num_of_params * RecordParamInfo::param_slots; i++) {
+      _record_params->at_put(i, record_params_array[i]);
+    }
+    assert(_record_params->length() == i, "");
+    // DEBUG
+    // tty->print_cr("length of the _record_params array %d for class %s", i, _class_name->as_klass_external_name());
+  }
+
+  // Restore buffer's current position.
+  cfs->set_current(current_mark);
+}
+
 void ClassFileParser::parse_classfile_synthetic_attribute(TRAPS) {
   set_class_synthetic_flag(true);
 }
@@ -3365,6 +3444,8 @@
   _inner_classes = Universe::the_empty_short_array();
   // Set nest members attribute to default sentinel
   _nest_members = Universe::the_empty_short_array();
+  // Set nest members attribute to default sentinel
+  _record_params = Universe::the_empty_short_array();
   cfs->guarantee_more(2, CHECK);  // attributes_count
   u2 attributes_count = cfs->get_u2_fast();
   bool parsed_sourcefile_attribute = false;
@@ -3586,7 +3667,7 @@
           cfs->skip_u1(record_attribute_length, CHECK);
         }
       } else {
-        // Unknown attribute 
+        // Unknown attribute
         cfs->skip_u1(attribute_length, CHECK);
       }
     } else {
@@ -3632,6 +3713,15 @@
     }
   }
 
+  if (parsed_record_attribute) {
+    parse_classfile_record_attribute(
+                            cfs,
+                            record_attribute_start,
+                            cp,
+                            &_record_params_count,
+                            CHECK);
+  }
+
   if (_max_bootstrap_specifier_index >= 0) {
     guarantee_property(parsed_bootstrap_methods_attribute,
                        "Missing BootstrapMethods attribute in class file %s", CHECK);
@@ -3686,7 +3776,8 @@
 // Transfer ownership of metadata allocated to the InstanceKlass.
 void ClassFileParser::apply_parsed_class_metadata(
                                             InstanceKlass* this_klass,
-                                            int java_fields_count, TRAPS) {
+                                            int java_fields_count,
+                                            int record_params_count, TRAPS) {
   assert(this_klass != NULL, "invariant");
 
   _cp->set_pool_holder(this_klass);
@@ -3698,6 +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);
   // 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
@@ -5575,7 +5667,7 @@
 
   // this transfers ownership of a lot of arrays from
   // the parser onto the InstanceKlass*
-  apply_parsed_class_metadata(ik, _java_fields_count, CHECK);
+  apply_parsed_class_metadata(ik, _java_fields_count, _record_params_count, CHECK);
 
   // note that is not safe to use the fields in the parser from this point on
   assert(NULL == _cp, "invariant");
@@ -5585,6 +5677,7 @@
   assert(NULL == _nest_members, "invariant");
   assert(NULL == _local_interfaces, "invariant");
   assert(NULL == _combined_annotations, "invariant");
+  assert(NULL == _record_params, "invariant");
 
   if (_has_final_method) {
     ik->set_has_final_method();
@@ -5854,6 +5947,7 @@
   _inner_classes(NULL),
   _nest_members(NULL),
   _nest_host(0),
+  _record_params(NULL),
   _local_interfaces(NULL),
   _transitive_interfaces(NULL),
   _combined_annotations(NULL),
@@ -5887,6 +5981,7 @@
   _super_class_index(0),
   _itfs_len(0),
   _java_fields_count(0),
+  _record_params_count(0),
   _need_verify(false),
   _relax_verify(false),
   _has_nonstatic_concrete_methods(false),
@@ -5963,6 +6058,7 @@
   _combined_annotations = NULL;
   _annotations = _type_annotations = NULL;
   _fields_annotations = _fields_type_annotations = NULL;
+  _record_params = NULL;
 }
 
 // Destructor to clean up
@@ -5988,6 +6084,10 @@
     MetadataFactory::free_array<u2>(_loader_data, _nest_members);
   }
 
+  if (_record_params != NULL && _record_params != Universe::the_empty_short_array()) {
+    MetadataFactory::free_array<u2>(_loader_data, _record_params);
+  }
+
   // Free interfaces
   InstanceKlass::deallocate_interfaces(_loader_data, _super_klass,
                                        _local_interfaces, _transitive_interfaces);
--- a/src/hotspot/share/classfile/classFileParser.hpp	Fri Oct 19 15:20:19 2018 -0400
+++ b/src/hotspot/share/classfile/classFileParser.hpp	Tue Oct 23 05:55:40 2018 +0200
@@ -99,6 +99,7 @@
   Array<u2>* _inner_classes;
   Array<u2>* _nest_members;
   u2 _nest_host;
+  Array<u2>* _record_params;
   Array<InstanceKlass*>* _local_interfaces;
   Array<InstanceKlass*>* _transitive_interfaces;
   Annotations* _combined_annotations;
@@ -153,6 +154,7 @@
   u2 _super_class_index;
   u2 _itfs_len;
   u2 _java_fields_count;
+  u2 _record_params_count;
 
   bool _need_verify;
   bool _relax_verify;
@@ -188,7 +190,7 @@
 
   void create_combined_annotations(TRAPS);
   void apply_parsed_class_attributes(InstanceKlass* k);  // update k
-  void apply_parsed_class_metadata(InstanceKlass* k, int fields_count, TRAPS);
+  void apply_parsed_class_metadata(InstanceKlass* k, int fields_count, int record_params_count, TRAPS);
   void clear_class_metadata();
 
   // Constant pool parsing
@@ -296,6 +298,12 @@
                                             const u1* const nest_members_attribute_start,
                                             TRAPS);
 
+  void parse_classfile_record_attribute(const ClassFileStream* const cfs,
+                                        const u1* const record_attribute_start,
+                                        ConstantPool* cp,
+                                        u2* const record_params_count_ptr,
+                                        TRAPS);
+
   void parse_classfile_attributes(const ClassFileStream* const cfs,
                                   ConstantPool* cp,
                                   ClassAnnotationCollector* parsed_annotations,
--- a/src/hotspot/share/oops/instanceKlass.cpp	Fri Oct 19 15:20:19 2018 -0400
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Tue Oct 23 05:55:40 2018 +0200
@@ -2270,6 +2270,7 @@
   }
 
   it->push(&_nest_members);
+  it->push(&_recordParams);
 }
 
 void InstanceKlass::remove_unshareable_info() {
--- a/src/hotspot/share/oops/instanceKlass.hpp	Fri Oct 19 15:20:19 2018 -0400
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Tue Oct 23 05:55:40 2018 +0200
@@ -188,6 +188,8 @@
   // if this class is unloaded.
   Symbol*         _array_name;
 
+  Array<u2>*      _recordParams;
+
   // Number of heapOopSize words used by non-static fields in this klass
   // (including inherited fields but after header_size()).
   int             _nonstatic_field_size;
@@ -200,6 +202,7 @@
   u2              _source_file_name_index;
   u2              _static_oop_field_count;// number of static oop fields in this klass
   u2              _java_fields_count;    // The number of declared Java fields
+  u2              _record_params_count;  // The number of record parameters
   int             _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
 
   int             _itable_len;           // length of Java itable (in words)
@@ -458,6 +461,15 @@
   jushort nest_host_index() const { return _nest_host_index; }
   void set_nest_host_index(u2 i)  { _nest_host_index = i; }
 
+  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;
+    _record_params_count = record_params_count;
+  }
+
 private:
   // Called to verify that k is a member of this nest - does not look at k's nest-host
   bool has_nest_member(InstanceKlass* k, TRAPS) const;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/oops/recordParamInfo.hpp	Tue Oct 23 05:55:40 2018 +0200
@@ -0,0 +1,60 @@
+/*
+ * 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_RECORDPARAMINFO_HPP
+#define SHARE_VM_OOPS_RECORDPARAMINFO_HPP
+
+#include "oops/constantPool.hpp"
+#include "oops/typeArrayOop.hpp"
+#include "classfile/vmSymbols.hpp"
+
+// This class represents the parameter information contained in the recordParams
+// array of an InstanceKlass.  Currently it's laid on top an array of
+// Java shorts but in the future it could simply be used as a real
+// array type.  RecordParamInfo generally shouldn't be used directly.
+// Record parameters should be queried through InstanceKlass.
+
+class RecordParamInfo {
+  friend class ClassFileParser;
+  enum ParamOffset {
+    access_flags_offset      = 0,
+    name_index_offset        = 1,
+    descriptor_index_offset  = 2,
+    signature_index_offset   = 3,
+    param_slots              = 4
+  };
+
+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;    }
+
+  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];   }
+};
+
+#endif // SHARE_VM_OOPS_RECORDPARAMINFO_HPP
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Oct 19 15:20:19 2018 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Oct 23 05:55:40 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) {
+            if (sym.kind == VAR && sym.isDatum()) {
                 vars = vars.prepend((VarSymbol)sym);
                 numParams++;
             }