< prev index next >

src/hotspot/share/classfile/fieldLayoutBuilder.hpp

Print this page
*** 1,7 ***
  /*
!  * Copyright (c) 2020, 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.
--- 1,7 ---
  /*
!  * Copyright (c) 2019, 2020, 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.

*** 31,11 ***
  #include "oops/fieldStreams.hpp"
  #include "utilities/growableArray.hpp"
  
  // Classes below are used to compute the field layout of classes.
  
- 
  // A LayoutRawBlock describes an element of a layout.
  // Each field is represented by a LayoutRawBlock.
  // LayoutRawBlocks can also represent elements injected by the JVM:
  // padding, empty blocks, inherited fields, etc.
  // All LayoutRawBlocks must have a size and an alignment. The size is the
--- 31,10 ---

*** 52,21 ***
  //
  class LayoutRawBlock : public ResourceObj {
   public:
    // Some code relies on the order of values below.
    enum Kind {
!     EMPTY,         // empty slot, space is taken from this to allocate fields
!     RESERVED,      // reserved for JVM usage (for instance object header)
!     PADDING,       // padding (because of alignment constraints or @Contended)
!     REGULAR,       // primitive or oop field (including non-flattened inline fields)
!     FLATTENED,     // flattened field
!     INHERITED      // field(s) inherited from super classes
    };
  
   private:
    LayoutRawBlock* _next_block;
    LayoutRawBlock* _prev_block;
    Kind _kind;
    int _offset;
    int _alignment;
    int _size;
    int _field_index;
--- 51,22 ---
  //
  class LayoutRawBlock : public ResourceObj {
   public:
    // Some code relies on the order of values below.
    enum Kind {
!     EMPTY,            // empty slot, space is taken from this to allocate fields
!     RESERVED,         // reserved for JVM usage (for instance object header)
!     PADDING,          // padding (because of alignment constraints or @Contended)
!     REGULAR,          // primitive or oop field (including inline type fields not inlined)
!     INLINED,          // field inlined
!     INHERITED         // field(s) inherited from super classes
    };
  
   private:
    LayoutRawBlock* _next_block;
    LayoutRawBlock* _prev_block;
+   InlineKlass* _inline_klass;
    Kind _kind;
    int _offset;
    int _alignment;
    int _size;
    int _field_index;

*** 91,10 ***
--- 91,15 ---
    int field_index() const {
      assert(_field_index != -1, "Must be initialized");
      return _field_index;
    }
    bool is_reference() const { return _is_reference; }
+   InlineKlass* inline_klass() const {
+     assert(_inline_klass != NULL, "Must be initialized");
+     return _inline_klass;
+   }
+   void set_inline_klass(InlineKlass* inline_klass) { _inline_klass = inline_klass; }
  
    bool fit(int size, int alignment);
  
    static int compare_offset(LayoutRawBlock** x, LayoutRawBlock** y)  { return (*x)->offset() - (*y)->offset(); }
    // compare_size_inverted() returns the opposite of a regular compare method in order to

*** 111,41 ***
      return diff;
  #else
      return (*y)->size() - (*x)->size();
  #endif // _WINDOWS
    }
- 
  };
  
  // A Field group represents a set of fields that have to be allocated together,
  // this is the way the @Contended annotation is supported.
  // Inside a FieldGroup, fields are sorted based on their kind: primitive,
! // oop, or flattened.
  //
  class FieldGroup : public ResourceObj {
  
   private:
    FieldGroup* _next;
!   GrowableArray<LayoutRawBlock*>* _primitive_fields;
    GrowableArray<LayoutRawBlock*>* _oop_fields;
    int _contended_group;
    int _oop_count;
    static const int INITIAL_LIST_SIZE = 16;
  
   public:
    FieldGroup(int contended_group = -1);
  
    FieldGroup* next() const { return _next; }
    void set_next(FieldGroup* next) { _next = next; }
!   GrowableArray<LayoutRawBlock*>* primitive_fields() const { return _primitive_fields; }
    GrowableArray<LayoutRawBlock*>* oop_fields() const { return _oop_fields; }
    int contended_group() const { return _contended_group; }
    int oop_count() const { return _oop_count; }
  
    void add_primitive_field(AllFieldStream fs, BasicType type);
    void add_oop_field(AllFieldStream fs);
    void sort_by_size();
  };
  
  // The FieldLayout class represents a set of fields organized
  // in a layout.
  // An instance of FieldLayout can either represent the layout
--- 116,48 ---
      return diff;
  #else
      return (*y)->size() - (*x)->size();
  #endif // _WINDOWS
    }
  };
  
  // A Field group represents a set of fields that have to be allocated together,
  // this is the way the @Contended annotation is supported.
  // Inside a FieldGroup, fields are sorted based on their kind: primitive,
! // oop, or inlined.
  //
  class FieldGroup : public ResourceObj {
  
   private:
    FieldGroup* _next;
! 
+   GrowableArray<LayoutRawBlock*>* _small_primitive_fields;
+   GrowableArray<LayoutRawBlock*>* _big_primitive_fields;
    GrowableArray<LayoutRawBlock*>* _oop_fields;
    int _contended_group;
    int _oop_count;
    static const int INITIAL_LIST_SIZE = 16;
  
   public:
    FieldGroup(int contended_group = -1);
  
    FieldGroup* next() const { return _next; }
    void set_next(FieldGroup* next) { _next = next; }
!   GrowableArray<LayoutRawBlock*>* small_primitive_fields() const { return _small_primitive_fields; }
+   GrowableArray<LayoutRawBlock*>* big_primitive_fields() const { return _big_primitive_fields; }
    GrowableArray<LayoutRawBlock*>* oop_fields() const { return _oop_fields; }
    int contended_group() const { return _contended_group; }
    int oop_count() const { return _oop_count; }
  
    void add_primitive_field(AllFieldStream fs, BasicType type);
    void add_oop_field(AllFieldStream fs);
+   void add_inlined_field(AllFieldStream fs, InlineKlass* vk);
+   void add_block(LayoutRawBlock** list, LayoutRawBlock* block);
    void sort_by_size();
+  private:
+   void add_to_small_primitive_list(LayoutRawBlock* block);
+   void add_to_big_primitive_list(LayoutRawBlock* block);
  };
  
  // The FieldLayout class represents a set of fields organized
  // in a layout.
  // An instance of FieldLayout can either represent the layout

*** 181,10 ***
--- 193,12 ---
        block = block->next_block();
      }
      return block;
    }
  
+   LayoutRawBlock* blocks() { return _blocks; }
+ 
    LayoutRawBlock* start() { return _start; }
    void set_start(LayoutRawBlock* start) { _start = start; }
    LayoutRawBlock* last_block() { return _last; }
  
    LayoutRawBlock* first_field_block();

*** 199,15 ***
    void print(outputStream* output, bool is_static, const InstanceKlass* super);
  };
  
  
  // FieldLayoutBuilder is the main entry point for layout computation.
! // This class has three methods to generate layout: one for regular classes
! // and two for classes with hard coded offsets (java,lang.ref.Reference
! // and the boxing classes). The rationale for having multiple methods
! // is that each kind of class has a different set goals regarding
- // its layout, so instead of mixing several layout strategies into a
  // single method, each kind has its own method (see comments below
  // for more details about the allocation strategies).
  //
  // Computing the layout of a class always goes through 4 steps:
  //   1 - Prologue: preparation of data structure and gathering of
--- 213,14 ---
    void print(outputStream* output, bool is_static, const InstanceKlass* super);
  };
  
  
  // FieldLayoutBuilder is the main entry point for layout computation.
! // This class has two methods to generate layout: one for identity classes
! // and one for inline classes. The rational for having two methods
! // is that each kind of classes has a different set goals regarding
! // its layout, so instead of mixing two layout strategies into a
  // single method, each kind has its own method (see comments below
  // for more details about the allocation strategies).
  //
  // Computing the layout of a class always goes through 4 steps:
  //   1 - Prologue: preparation of data structure and gathering of

*** 220,46 ***
  //   4 - Epilogue: oopmaps are generated, layout information is
  //       prepared so other VM components can use it (instance size,
  //       static field size, non-static field size, etc.)
  //
  //  Steps 1 and 4 are common to all layout computations. Step 2 and 3
! //  can vary with the allocation strategy.
  //
  class FieldLayoutBuilder : public ResourceObj {
   private:
- 
    const Symbol* _classname;
    const InstanceKlass* _super_klass;
    ConstantPool* _constant_pool;
    Array<u2>* _fields;
    FieldLayoutInfo* _info;
    FieldGroup* _root_group;
    GrowableArray<FieldGroup*> _contended_groups;
    FieldGroup* _static_fields;
    FieldLayout* _layout;
    FieldLayout* _static_layout;
    int _nonstatic_oopmap_count;
    int _alignment;
    bool _has_nonstatic_fields;
!   bool _is_contended; // is a contended class?
  
   public:
    FieldLayoutBuilder(const Symbol* classname, const InstanceKlass* super_klass, ConstantPool* constant_pool,
!                      Array<u2>* fields, bool is_contended, FieldLayoutInfo* info);
  
    int get_alignment() {
      assert(_alignment != -1, "Uninitialized");
      return _alignment;
    }
  
!   void build_layout();
    void compute_regular_layout();
    void insert_contended_padding(LayoutRawBlock* slot);
  
!  private:
    void prologue();
    void epilogue();
    void regular_field_sorting();
!   FieldGroup* get_or_create_contended_group(int g);
  };
  
  #endif // SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP
--- 233,71 ---
  //   4 - Epilogue: oopmaps are generated, layout information is
  //       prepared so other VM components can use it (instance size,
  //       static field size, non-static field size, etc.)
  //
  //  Steps 1 and 4 are common to all layout computations. Step 2 and 3
! //  differ for inline classes and identity classes.
  //
  class FieldLayoutBuilder : public ResourceObj {
   private:
    const Symbol* _classname;
    const InstanceKlass* _super_klass;
    ConstantPool* _constant_pool;
    Array<u2>* _fields;
    FieldLayoutInfo* _info;
    FieldGroup* _root_group;
    GrowableArray<FieldGroup*> _contended_groups;
    FieldGroup* _static_fields;
    FieldLayout* _layout;
    FieldLayout* _static_layout;
+   ClassLoaderData* _class_loader_data;
+   Handle _protection_domain;
    int _nonstatic_oopmap_count;
    int _alignment;
+   int _first_field_offset;
+   int _exact_size_in_bytes;
    bool _has_nonstatic_fields;
!   bool _has_inline_type_fields;
+   bool _is_contended;
+   bool _is_inline_type;
+   bool _has_flattening_information;
+   bool _has_nonatomic_values;
+   int _atomic_field_count;
+ 
+   FieldGroup* get_or_create_contended_group(int g);
  
   public:
    FieldLayoutBuilder(const Symbol* classname, const InstanceKlass* super_klass, ConstantPool* constant_pool,
!       Array<u2>* fields, bool is_contended, bool is_inline_type, ClassLoaderData* class_loader_data,
+       Handle protection_domain, FieldLayoutInfo* info);
  
    int get_alignment() {
      assert(_alignment != -1, "Uninitialized");
      return _alignment;
    }
  
!   int get_first_field_offset() {
+     assert(_first_field_offset != -1, "Uninitialized");
+     return _first_field_offset;
+   }
+ 
+   int get_exact_size_in_byte() {
+     assert(_exact_size_in_bytes != -1, "Uninitialized");
+     return _exact_size_in_bytes;
+   }
+ 
+   void build_layout(TRAPS);
    void compute_regular_layout();
+   void compute_inline_class_layout(TRAPS);
    void insert_contended_padding(LayoutRawBlock* slot);
  
!  protected:
    void prologue();
    void epilogue();
    void regular_field_sorting();
!   void inline_class_field_sorting(TRAPS);
+   void add_inlined_field_oopmap(OopMapBlocksBuilder* nonstatic_oop_map, InlineKlass* vk, int offset);
+   void register_embedded_oops_from_list(OopMapBlocksBuilder* nonstatic_oop_maps, GrowableArray<LayoutRawBlock*>* list);
+   void register_embedded_oops(OopMapBlocksBuilder* nonstatic_oop_maps, FieldGroup* group);
  };
  
  #endif // SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP
< prev index next >