< prev index next >

src/hotspot/share/classfile/classFileParser.hpp

Print this page

        

@@ -26,10 +26,11 @@
 #define SHARE_CLASSFILE_CLASSFILEPARSER_HPP
 
 #include "memory/referenceType.hpp"
 #include "oops/annotations.hpp"
 #include "oops/constantPool.hpp"
+#include "oops/instanceKlass.hpp"
 #include "oops/typeArrayOop.hpp"
 #include "utilities/accessFlags.hpp"
 
 class Annotations;
 template <typename T>

@@ -42,21 +43,109 @@
 template <typename T>
 class GrowableArray;
 class InstanceKlass;
 class Symbol;
 class TempNewSymbol;
+class FieldLayoutBuilder;
+
+
+class AnnotationCollector : public ResourceObj{
+public:
+  enum Location { _in_field, _in_method, _in_class };
+  enum ID {
+    _unknown = 0,
+    _method_CallerSensitive,
+    _method_ForceInline,
+    _method_DontInline,
+    _method_InjectedProfile,
+    _method_LambdaForm_Compiled,
+    _method_Hidden,
+    _method_HotSpotIntrinsicCandidate,
+    _jdk_internal_vm_annotation_Contended,
+    _field_Stable,
+    _jdk_internal_vm_annotation_ReservedStackAccess,
+    _annotation_LIMIT
+  };
+  const Location _location;
+  int _annotations_present;
+  u2 _contended_group;
+
+  AnnotationCollector(Location location)
+    : _location(location), _annotations_present(0)
+  {
+    assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
+  }
+  // If this annotation name has an ID, report it (or _none).
+  ID annotation_index(const ClassLoaderData* loader_data, const Symbol* name);
+  // Set the annotation name:
+  void set_annotation(ID id) {
+    assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
+    _annotations_present |= nth_bit((int)id);
+  }
+
+  void remove_annotation(ID id) {
+    assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
+    _annotations_present &= ~nth_bit((int)id);
+  }
+
+  // Report if the annotation is present.
+  bool has_any_annotations() const { return _annotations_present != 0; }
+  bool has_annotation(ID id) const { return (nth_bit((int)id) & _annotations_present) != 0; }
+
+  void set_contended_group(u2 group) { _contended_group = group; }
+  u2 contended_group() const { return _contended_group; }
+
+  bool is_contended() const { return has_annotation(_jdk_internal_vm_annotation_Contended); }
+
+  void set_stable(bool stable) { set_annotation(_field_Stable); }
+  bool is_stable() const { return has_annotation(_field_Stable); }
+};
+
+// Utility to collect and compact oop maps during layout
+class OopMapBlocksBuilder : public ResourceObj {
+public:
+  OopMapBlock*  nonstatic_oop_maps;
+  unsigned int  nonstatic_oop_map_count;
+  unsigned int  max_nonstatic_oop_maps;
+
+ public:
+  OopMapBlocksBuilder(unsigned int  max_blocks, TRAPS);
+  OopMapBlock* last_oop_map() const;
+  void initialize_inherited_blocks(OopMapBlock* blocks, unsigned int nof_blocks);
+  void add(int offset, int count);
+  void copy(OopMapBlock* dst);
+  void compact(TRAPS);
+  void print_on(outputStream* st) const;
+  void print_value_on(outputStream* st) const;
+};
+
+// Values needed for oopmap and InstanceKlass creation
+class FieldLayoutInfo : public ResourceObj {
+ public:
+  OopMapBlocksBuilder* oop_map_blocks;
+  int           instance_size;
+  int           nonstatic_field_size;
+  int           static_field_size;
+  bool          has_nonstatic_fields;
+};
 
 // Parser for for .class files
 //
 // The bytes describing the class file structure is read from a Stream object
 
 class ClassFileParser {
+ friend class FieldLayoutBuilder;
+ friend class FieldLayout;
 
- class ClassAnnotationCollector;
+
+ class ClassAnnotationCollector : public AnnotationCollector {
+ public:
+   ClassAnnotationCollector() : AnnotationCollector(_in_class) { }
+   void apply_to(InstanceKlass* ik);
+ };
  class FieldAllocationCount;
  class FieldAnnotationCollector;
- class FieldLayoutInfo;
 
  public:
   // The ClassFileParser has an associated "publicity" level
   // It is used to control which subsystems (if any)
   // will observe the parsing (logging, events, tracing).

@@ -121,10 +210,14 @@
   int _vtable_size;
   int _itable_size;
 
   int _num_miranda_methods;
 
+  int _alignment;
+  int _first_field_offset;
+  int _exact_size_in_bytes;
+
   ReferenceType _rt;
   Handle _protection_domain;
   AccessFlags _access_flags;
 
   // for tracing and notifications

@@ -157,10 +250,12 @@
   bool _relax_verify;
 
   bool _has_nonstatic_concrete_methods;
   bool _declares_nonstatic_concrete_methods;
   bool _has_final_method;
+  bool _has_flattenable_fields;
+  bool _is_empty_value;
 
   // precomputed flags
   bool _has_finalizer;
   bool _has_empty_finalizer;
   bool _has_vanilla_constructor;

@@ -224,25 +319,28 @@
                               FieldAnnotationCollector* parsed_annotations,
                               TRAPS);
 
   void parse_fields(const ClassFileStream* const cfs,
                     bool is_interface,
+                    bool is_value_type,
                     FieldAllocationCount* const fac,
                     ConstantPool* cp,
                     const int cp_size,
                     u2* const java_fields_count_ptr,
                     TRAPS);
 
   // Method parsing
   Method* parse_method(const ClassFileStream* const cfs,
                        bool is_interface,
+                       bool is_value_type,
                        const ConstantPool* cp,
                        AccessFlags* const promoted_flags,
                        TRAPS);
 
   void parse_methods(const ClassFileStream* const cfs,
                      bool is_interface,
+                     bool is_value_type,
                      AccessFlags* const promoted_flags,
                      bool* const has_final_method,
                      bool* const declares_nonstatic_concrete_methods,
                      TRAPS);
 

@@ -304,11 +402,11 @@
                                         int runtime_visible_annotations_length,
                                         const u1* const runtime_invisible_annotations,
                                         int runtime_invisible_annotations_length,
                                         TRAPS);
 
-  void set_precomputed_flags(InstanceKlass* k);
+  void set_precomputed_flags(InstanceKlass* k, TRAPS);
 
   // Format checker methods
   void classfile_parse_error(const char* msg, TRAPS) const;
   void classfile_parse_error(const char* msg, int index, TRAPS) const;
   void classfile_parse_error(const char* msg, const char *name, TRAPS) const;

@@ -388,10 +486,15 @@
   void throwIllegalSignature(const char* type,
                              const Symbol* name,
                              const Symbol* sig,
                              TRAPS) const;
 
+  void throwValueTypeLimitation(THREAD_AND_LOCATION_DECL,
+                                const char* msg,
+                                const Symbol* name = NULL,
+                                const Symbol* sig  = NULL) const;
+
   void verify_constantvalue(const ConstantPool* const cp,
                             int constantvalue_index,
                             int signature_index,
                             TRAPS) const;
 

@@ -406,13 +509,17 @@
   int  verify_legal_method_signature(const Symbol* methodname,
                                      const Symbol* signature,
                                      TRAPS) const;
 
   void verify_legal_class_modifiers(jint flags, TRAPS) const;
-  void verify_legal_field_modifiers(jint flags, bool is_interface, TRAPS) const;
+  void verify_legal_field_modifiers(jint flags,
+                                    bool is_interface,
+                                    bool is_value_type,
+                                    TRAPS) const;
   void verify_legal_method_modifiers(jint flags,
                                      bool is_interface,
+                                     bool is_value_type,
                                      const Symbol* name,
                                      TRAPS) const;
 
   const char* skip_over_field_signature(const char* signature,
                                         bool void_ok,

@@ -487,10 +594,13 @@
                      FieldLayoutInfo* info,
                      TRAPS);
 
    void update_class_name(Symbol* new_name);
 
+  // Check if the class file supports value types
+  bool supports_value_types() const;
+
  public:
   ClassFileParser(ClassFileStream* stream,
                   Symbol* name,
                   ClassLoaderData* loader_data,
                   Handle protection_domain,

@@ -516,10 +626,15 @@
 
   u2 this_class_index() const { return _this_class_index; }
 
   bool is_unsafe_anonymous() const { return _unsafe_anonymous_host != NULL; }
   bool is_interface() const { return _access_flags.is_interface(); }
+  bool is_value_type() const { return _access_flags.is_value_type(); }
+  bool is_value_capable_class() const;
+  bool has_flattenable_fields() const { return _has_flattenable_fields; }
+
+  u2 java_fields_count() const { return _java_fields_count; }
 
   const InstanceKlass* unsafe_anonymous_host() const { return _unsafe_anonymous_host; }
   const GrowableArray<Handle>* cp_patches() const { return _cp_patches; }
   ClassLoaderData* loader_data() const { return _loader_data; }
   const Symbol* class_name() const { return _class_name; }
< prev index next >