< prev index next >

src/hotspot/share/classfile/fieldLayoutBuilder.hpp

Print this page

  1 /*
  2  * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP
 26 #define SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP
 27 
 28 #include "classfile/classFileParser.hpp"
 29 #include "classfile/classLoaderData.hpp"
 30 #include "memory/allocation.hpp"
 31 #include "oops/fieldStreams.hpp"


 32 #include "utilities/growableArray.hpp"
 33 
 34 // Classes below are used to compute the field layout of classes.
 35 
 36 
 37 // A LayoutRawBlock describes an element of a layout.
 38 // Each field is represented by a LayoutRawBlock.
 39 // LayoutRawBlocks can also represent elements injected by the JVM:
 40 // padding, empty blocks, inherited fields, etc.
 41 // All LayoutRawBlocks must have a size and an alignment. The size is the
 42 // exact size of the field expressed in bytes. The alignment is
 43 // the alignment constraint of the field (1 for byte, 2 for short,
 44 // 4 for int, 8 for long, etc.)
 45 //
 46 // LayoutRawBlock are designed to be used in two data structures:
 47 //   - a linked list in a layout (using _next_block, _prev_block)
 48 //   - a GrowableArray in field group (the growable array contains pointers to LayoutRawBlocks)
 49 //
 50 //  next/prev pointers are included in the LayoutRawBlock class to narrow
 51 //  the number of allocation required during the computation of a layout.
 52 //



 53 class LayoutRawBlock : public ResourceObj {
 54  public:
 55   // Some code relies on the order of values below.
 56   enum Kind {
 57     EMPTY,         // empty slot, space is taken from this to allocate fields
 58     RESERVED,      // reserved for JVM usage (for instance object header)
 59     PADDING,       // padding (because of alignment constraints or @Contended)
 60     REGULAR,       // primitive or oop field (including non-flattened inline fields)
 61     FLATTENED,     // flattened field
 62     INHERITED      // field(s) inherited from super classes

 63   };
 64 
 65  private:
 66   LayoutRawBlock* _next_block;
 67   LayoutRawBlock* _prev_block;
 68   Kind _kind;


 69   int _offset;
 70   int _alignment;
 71   int _size;
 72   int _field_index;
 73   bool _is_reference;
 74 
 75  public:
 76   LayoutRawBlock(Kind kind, int size);
 77   LayoutRawBlock(int index, Kind kind, int size, int alignment, bool is_reference = false);

 78   LayoutRawBlock* next_block() const { return _next_block; }
 79   void set_next_block(LayoutRawBlock* next) { _next_block = next; }
 80   LayoutRawBlock* prev_block() const { return _prev_block; }
 81   void set_prev_block(LayoutRawBlock* prev) { _prev_block = prev; }
 82   Kind kind() const { return _kind; }

 83   int offset() const {
 84     assert(_offset >= 0, "Must be initialized");
 85     return _offset;
 86   }
 87   void set_offset(int offset) { _offset = offset; }
 88   int alignment() const { return _alignment; }
 89   int size() const { return _size; }
 90   void set_size(int size) { _size = size; }
 91   int field_index() const {
 92     assert(_field_index != -1, "Must be initialized");
 93     return _field_index;
 94   }
 95   bool is_reference() const { return _is_reference; }













 96 
 97   bool fit(int size, int alignment);
 98 
 99   static int compare_offset(LayoutRawBlock** x, LayoutRawBlock** y)  { return (*x)->offset() - (*y)->offset(); }
100   // compare_size_inverted() returns the opposite of a regular compare method in order to
101   // sort fields in decreasing order.
102   // Note: with line types, the comparison should include alignment constraint if sizes are equals
103   static int compare_size_inverted(LayoutRawBlock** x, LayoutRawBlock** y)  {
104     int diff = (*y)->size() - (*x)->size();
105     // qsort() may reverse the order of fields with the same size.
106     // The extension is to ensure stable sort.
107     if (diff == 0) {
108       diff = (*x)->field_index() - (*y)->field_index();
109     }
110     return diff;
111   }
112 
113 };
114 
115 // A Field group represents a set of fields that have to be allocated together,
116 // this is the way the @Contended annotation is supported.
117 // Inside a FieldGroup, fields are sorted based on their kind: primitive,
118 // oop, or flattened.
119 //
120 class FieldGroup : public ResourceObj {
121 
122  private:
123   FieldGroup* _next;
124   GrowableArray<LayoutRawBlock*>* _primitive_fields;


125   GrowableArray<LayoutRawBlock*>* _oop_fields;
126   int _contended_group;
127   int _oop_count;
128   static const int INITIAL_LIST_SIZE = 16;
129 
130  public:
131   FieldGroup(int contended_group = -1);
132 
133   FieldGroup* next() const { return _next; }
134   void set_next(FieldGroup* next) { _next = next; }
135   GrowableArray<LayoutRawBlock*>* primitive_fields() const { return _primitive_fields; }

136   GrowableArray<LayoutRawBlock*>* oop_fields() const { return _oop_fields; }
137   int contended_group() const { return _contended_group; }
138   int oop_count() const { return _oop_count; }
139 
140   void add_primitive_field(int idx, BasicType type);
141   void add_oop_field(int idx);


142   void sort_by_size();



143 };
144 
145 // The FieldLayout class represents a set of fields organized
146 // in a layout.
147 // An instance of FieldLayout can either represent the layout
148 // of non-static fields (used in an instance object) or the
149 // layout of static fields (to be included in the class mirror).
150 //
151 // _block is a pointer to a list of LayoutRawBlock ordered by increasing
152 // offsets.
153 // _start points to the LayoutRawBlock with the first offset that can
154 // be used to allocate fields of the current class
155 // _last points to the last LayoutRawBlock of the list. In order to
156 // simplify the code, the LayoutRawBlock list always ends with an
157 // EMPTY block (the kind of LayoutRawBlock from which space is taken
158 // to allocate fields) with a size big enough to satisfy all
159 // field allocations.
160 //
161 class FieldLayout : public ResourceObj {
162  private:
163   GrowableArray<FieldInfo>* _field_info;

164   ConstantPool* _cp;
165   LayoutRawBlock* _blocks;  // the layout being computed
166   LayoutRawBlock* _start;   // points to the first block where a field can be inserted
167   LayoutRawBlock* _last;    // points to the last block of the layout (big empty block)






168 
169  public:
170   FieldLayout(GrowableArray<FieldInfo>* field_info, ConstantPool* cp);
171   void initialize_static_layout();
172   void initialize_instance_layout(const InstanceKlass* ik);
173 
174   LayoutRawBlock* first_empty_block() {
175     LayoutRawBlock* block = _start;
176     while (block->kind() != LayoutRawBlock::EMPTY) {
177       block = block->next_block();
178     }
179     return block;
180   }
181 
182   LayoutRawBlock* start() { return _start; }


183   void set_start(LayoutRawBlock* start) { _start = start; }
184   LayoutRawBlock* last_block() { return _last; }









185 
186   LayoutRawBlock* first_field_block();
187   void add(GrowableArray<LayoutRawBlock*>* list, LayoutRawBlock* start = nullptr);
188   void add_field_at_offset(LayoutRawBlock* blocks, int offset, LayoutRawBlock* start = nullptr);
189   void add_contiguously(GrowableArray<LayoutRawBlock*>* list, LayoutRawBlock* start = nullptr);
190   LayoutRawBlock* insert_field_block(LayoutRawBlock* slot, LayoutRawBlock* block);
191   bool reconstruct_layout(const InstanceKlass* ik);
192   void fill_holes(const InstanceKlass* ik);
193   LayoutRawBlock* insert(LayoutRawBlock* slot, LayoutRawBlock* block);
194   void remove(LayoutRawBlock* block);
195   void print(outputStream* output, bool is_static, const InstanceKlass* super);



196 };
197 
198 
199 // FieldLayoutBuilder is the main entry point for layout computation.
200 // This class has three methods to generate layout: one for regular classes
201 // and two for classes with hard coded offsets (java,lang.ref.Reference
202 // and the boxing classes). The rationale for having multiple methods
203 // is that each kind of class has a different set goals regarding
204 // its layout, so instead of mixing several layout strategies into a
205 // single method, each kind has its own method (see comments below
206 // for more details about the allocation strategies).
207 //
208 // Computing the layout of a class always goes through 4 steps:
209 //   1 - Prologue: preparation of data structure and gathering of
210 //       layout information inherited from super classes
211 //   2 - Field sorting: fields are sorted according to their
212 //       kind (oop, primitive, inline class) and their contention
213 //       annotation (if any)
214 //   3 - Layout is computed from the set of lists generated during
215 //       step 2
216 //   4 - Epilogue: oopmaps are generated, layout information is
217 //       prepared so other VM components can use it (instance size,
218 //       static field size, non-static field size, etc.)
219 //
220 //  Steps 1 and 4 are common to all layout computations. Step 2 and 3
221 //  can vary with the allocation strategy.
222 //
223 class FieldLayoutBuilder : public ResourceObj {
224  private:
225 

226   const Symbol* _classname;

227   const InstanceKlass* _super_klass;
228   ConstantPool* _constant_pool;
229   GrowableArray<FieldInfo>* _field_info;
230   FieldLayoutInfo* _info;

231   FieldGroup* _root_group;
232   GrowableArray<FieldGroup*> _contended_groups;
233   FieldGroup* _static_fields;
234   FieldLayout* _layout;
235   FieldLayout* _static_layout;
236   int _nonstatic_oopmap_count;
237   int _alignment;












238   bool _has_nonstatic_fields;
239   bool _is_contended; // is a contended class?







240 
241  public:
242   FieldLayoutBuilder(const Symbol* classname, const InstanceKlass* super_klass, ConstantPool* constant_pool,
243                      GrowableArray<FieldInfo>* field_info, bool is_contended, FieldLayoutInfo* info);

244 
245   int get_alignment() {
246     assert(_alignment != -1, "Uninitialized");
247     return _alignment;
248   }








249 
250   void build_layout();
251   void compute_regular_layout();

252   void insert_contended_padding(LayoutRawBlock* slot);
253 
254  private:
255   void prologue();
256   void epilogue();
257   void regular_field_sorting();
258   FieldGroup* get_or_create_contended_group(int g);



259 };
260 
261 #endif // SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP

  1 /*
  2  * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP
 26 #define SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP
 27 
 28 #include "classfile/classFileParser.hpp"
 29 #include "classfile/classLoaderData.hpp"
 30 #include "memory/allocation.hpp"
 31 #include "oops/fieldStreams.hpp"
 32 #include "oops/inlineKlass.hpp"
 33 #include "oops/instanceKlass.hpp"
 34 #include "utilities/growableArray.hpp"
 35 
 36 // Classes below are used to compute the field layout of classes.
 37 

 38 // A LayoutRawBlock describes an element of a layout.
 39 // Each field is represented by a LayoutRawBlock.
 40 // LayoutRawBlocks can also represent elements injected by the JVM:
 41 // padding, empty blocks, inherited fields, etc.
 42 // All LayoutRawBlocks must have a size and an alignment. The size is the
 43 // exact size of the field expressed in bytes. The alignment is
 44 // the alignment constraint of the field (1 for byte, 2 for short,
 45 // 4 for int, 8 for long, etc.)
 46 //
 47 // LayoutRawBlock are designed to be used in two data structures:
 48 //   - a linked list in a layout (using _next_block, _prev_block)
 49 //   - a GrowableArray in field group (the growable array contains pointers to LayoutRawBlocks)
 50 //
 51 //  next/prev pointers are included in the LayoutRawBlock class to narrow
 52 //  the number of allocation required during the computation of a layout.
 53 //
 54 
 55 #define MAX_ATOMIC_OP_SIZE sizeof(uint64_t)
 56 
 57 class LayoutRawBlock : public ResourceObj {
 58  public:
 59   // Some code relies on the order of values below.
 60   enum Kind {
 61     EMPTY,                 // empty slot, space is taken from this to allocate fields
 62     RESERVED,              // reserved for JVM usage (for instance object header)
 63     PADDING,               // padding (because of alignment constraints or @Contended)
 64     REGULAR,               // primitive or oop field (including not flat inline type fields)
 65     FLAT,                  // flat field
 66     INHERITED,             // field(s) inherited from super classes
 67     NULL_MARKER            // stores the null marker for a flat field
 68   };
 69 
 70  private:
 71   LayoutRawBlock* _next_block;
 72   LayoutRawBlock* _prev_block;
 73   InlineKlass* _inline_klass;
 74   Kind _block_kind;
 75   LayoutKind _layout_kind;
 76   int _offset;
 77   int _alignment;
 78   int _size;
 79   int _field_index;
 80   int _null_marker_offset;
 81 
 82  public:
 83   LayoutRawBlock(Kind kind, int size);
 84 
 85   LayoutRawBlock(int index, Kind kind, int size, int alignment);
 86   LayoutRawBlock* next_block() const { return _next_block; }
 87   void set_next_block(LayoutRawBlock* next) { _next_block = next; }
 88   LayoutRawBlock* prev_block() const { return _prev_block; }
 89   void set_prev_block(LayoutRawBlock* prev) { _prev_block = prev; }
 90   Kind block_kind() const { return _block_kind; }
 91   void set_block_kind(LayoutRawBlock::Kind kind) { _block_kind = kind; } // Dangerous operation, is only used by remove_null_marker();
 92   int offset() const {
 93     assert(_offset >= 0, "Must be initialized");
 94     return _offset;
 95   }
 96   void set_offset(int offset) { _offset = offset; }
 97   int alignment() const { return _alignment; }
 98   int size() const { return _size; }
 99   void set_size(int size) { _size = size; }
100   int field_index() const {
101     assert(_field_index != -1, "Must be initialized");
102     return _field_index;
103   }
104   void set_field_index(int field_index) {
105     assert(_field_index == -1, "Must not be initialized");
106     _field_index = field_index;
107   }
108   InlineKlass* inline_klass() const {
109     assert(_inline_klass != nullptr, "Must be initialized");
110     return _inline_klass;
111   }
112   void set_inline_klass(InlineKlass* inline_klass) { _inline_klass = inline_klass; }
113   void set_null_marker_offset(int offset) { _null_marker_offset = offset; }
114   int null_marker_offset() const { return _null_marker_offset; }
115 
116   LayoutKind layout_kind() const { return _layout_kind; }
117   void set_layout_kind(LayoutKind kind) { _layout_kind = kind; }
118 
119   bool fit(int size, int alignment);
120 
121   static int compare_offset(LayoutRawBlock** x, LayoutRawBlock** y)  { return (*x)->offset() - (*y)->offset(); }
122   // compare_size_inverted() returns the opposite of a regular compare method in order to
123   // sort fields in decreasing order.
124   // Note: with line types, the comparison should include alignment constraint if sizes are equals
125   static int compare_size_inverted(LayoutRawBlock** x, LayoutRawBlock** y)  {
126     int diff = (*y)->size() - (*x)->size();
127     // qsort() may reverse the order of fields with the same size.
128     // The extension is to ensure stable sort.
129     if (diff == 0) {
130       diff = (*x)->field_index() - (*y)->field_index();
131     }
132     return diff;
133   }

134 };
135 
136 // A Field group represents a set of fields that have to be allocated together,
137 // this is the way the @Contended annotation is supported.
138 // Inside a FieldGroup, fields are sorted based on their kind: primitive,
139 // oop, or flat.
140 //
141 class FieldGroup : public ResourceObj {
142 
143  private:
144   FieldGroup* _next;
145 
146   GrowableArray<LayoutRawBlock*>* _small_primitive_fields;
147   GrowableArray<LayoutRawBlock*>* _big_primitive_fields;
148   GrowableArray<LayoutRawBlock*>* _oop_fields;
149   int _contended_group;
150   int _oop_count;
151   static const int INITIAL_LIST_SIZE = 16;
152 
153  public:
154   FieldGroup(int contended_group = -1);
155 
156   FieldGroup* next() const { return _next; }
157   void set_next(FieldGroup* next) { _next = next; }
158   GrowableArray<LayoutRawBlock*>* small_primitive_fields() const { return _small_primitive_fields; }
159   GrowableArray<LayoutRawBlock*>* big_primitive_fields() const { return _big_primitive_fields; }
160   GrowableArray<LayoutRawBlock*>* oop_fields() const { return _oop_fields; }
161   int contended_group() const { return _contended_group; }
162   int oop_count() const { return _oop_count; }
163 
164   void add_primitive_field(int idx, BasicType type);
165   void add_oop_field(int idx);
166   void add_flat_field(int idx, InlineKlass* vk, LayoutKind lk, int size, int alignment);
167   void add_block(LayoutRawBlock** list, LayoutRawBlock* block);
168   void sort_by_size();
169  private:
170   void add_to_small_primitive_list(LayoutRawBlock* block);
171   void add_to_big_primitive_list(LayoutRawBlock* block);
172 };
173 
174 // The FieldLayout class represents a set of fields organized
175 // in a layout.
176 // An instance of FieldLayout can either represent the layout
177 // of non-static fields (used in an instance object) or the
178 // layout of static fields (to be included in the class mirror).
179 //
180 // _block is a pointer to a list of LayoutRawBlock ordered by increasing
181 // offsets.
182 // _start points to the LayoutRawBlock with the first offset that can
183 // be used to allocate fields of the current class
184 // _last points to the last LayoutRawBlock of the list. In order to
185 // simplify the code, the LayoutRawBlock list always ends with an
186 // EMPTY block (the kind of LayoutRawBlock from which space is taken
187 // to allocate fields) with a size big enough to satisfy all
188 // field allocations.
189 //
190 class FieldLayout : public ResourceObj {
191  private:
192   GrowableArray<FieldInfo>* _field_info;
193   Array<InlineLayoutInfo>* _inline_layout_info_array;
194   ConstantPool* _cp;
195   LayoutRawBlock* _blocks;  // the layout being computed
196   LayoutRawBlock* _start;   // points to the first block where a field can be inserted
197   LayoutRawBlock* _last;    // points to the last block of the layout (big empty block)
198   int _super_first_field_offset;
199   int _super_alignment;
200   int _super_min_align_required;
201   int _null_reset_value_offset;    // offset of the reset value in class mirror, only for static layout of inline classes
202   bool _super_has_fields;
203   bool _has_inherited_fields;
204 
205  public:
206   FieldLayout(GrowableArray<FieldInfo>* field_info, Array<InlineLayoutInfo>* inline_layout_info_array, ConstantPool* cp);
207   void initialize_static_layout();
208   void initialize_instance_layout(const InstanceKlass* ik);
209 
210   LayoutRawBlock* first_empty_block() {
211     LayoutRawBlock* block = _start;
212     while (block->block_kind() != LayoutRawBlock::EMPTY) {
213       block = block->next_block();
214     }
215     return block;
216   }
217 
218   LayoutRawBlock* blocks() const { return _blocks; }
219 
220   LayoutRawBlock* start() const { return _start; }
221   void set_start(LayoutRawBlock* start) { _start = start; }
222   LayoutRawBlock* last_block() const  { return _last; }
223   int super_first_field_offset() const { return _super_first_field_offset; }
224   int super_alignment() const { return _super_alignment; }
225   int super_min_align_required() const { return _super_min_align_required; }
226   int null_reset_value_offset() const {
227     assert(_null_reset_value_offset != -1, "Must have been set");
228     return _null_reset_value_offset;
229   }
230   bool super_has_fields() const { return _super_has_fields; }
231   bool has_inherited_fields() const { return _has_inherited_fields; }
232 
233   LayoutRawBlock* first_field_block();
234   void add(GrowableArray<LayoutRawBlock*>* list, LayoutRawBlock* start = nullptr);
235   void add_field_at_offset(LayoutRawBlock* blocks, int offset, LayoutRawBlock* start = nullptr);
236   void add_contiguously(GrowableArray<LayoutRawBlock*>* list, LayoutRawBlock* start = nullptr);
237   LayoutRawBlock* insert_field_block(LayoutRawBlock* slot, LayoutRawBlock* block);
238   bool reconstruct_layout(const InstanceKlass* ik);
239   void fill_holes(const InstanceKlass* ik);
240   LayoutRawBlock* insert(LayoutRawBlock* slot, LayoutRawBlock* block);
241   void remove(LayoutRawBlock* block);
242   void shift_fields(int shift);
243   LayoutRawBlock* find_null_marker();
244   void remove_null_marker();
245   void print(outputStream* output, bool is_static, const InstanceKlass* super, Array<InlineLayoutInfo>* inline_fields);
246 };
247 
248 
249 // FieldLayoutBuilder is the main entry point for layout computation.
250 // This class has two methods to generate layout: one for identity classes
251 // and one for inline classes. The rational for having two methods
252 // is that each kind of classes has a different set goals regarding
253 // its layout, so instead of mixing two layout strategies into a

254 // single method, each kind has its own method (see comments below
255 // for more details about the allocation strategies).
256 //
257 // Computing the layout of a class always goes through 4 steps:
258 //   1 - Prologue: preparation of data structure and gathering of
259 //       layout information inherited from super classes
260 //   2 - Field sorting: fields are sorted according to their
261 //       kind (oop, primitive, inline class) and their contention
262 //       annotation (if any)
263 //   3 - Layout is computed from the set of lists generated during
264 //       step 2
265 //   4 - Epilogue: oopmaps are generated, layout information is
266 //       prepared so other VM components can use it (instance size,
267 //       static field size, non-static field size, etc.)
268 //
269 //  Steps 1 and 4 are common to all layout computations. Step 2 and 3
270 //  differ for inline classes and identity classes.
271 //
272 class FieldLayoutBuilder : public ResourceObj {

273 
274  private:
275   const Symbol* _classname;
276   ClassLoaderData* _loader_data;
277   const InstanceKlass* _super_klass;
278   ConstantPool* _constant_pool;
279   GrowableArray<FieldInfo>* _field_info;
280   FieldLayoutInfo* _info;
281   Array<InlineLayoutInfo>* _inline_layout_info_array;
282   FieldGroup* _root_group;
283   GrowableArray<FieldGroup*> _contended_groups;
284   FieldGroup* _static_fields;
285   FieldLayout* _layout;
286   FieldLayout* _static_layout;
287   int _nonstatic_oopmap_count;
288   int _payload_alignment;
289   int _payload_offset;
290   int _null_marker_offset; // if any, -1 means no internal null marker
291   int _payload_size_in_bytes;
292   int _non_atomic_layout_size_in_bytes;
293   int _non_atomic_layout_alignment;
294   int _atomic_layout_size_in_bytes;
295   int _nullable_layout_size_in_bytes;
296   int _fields_size_sum;
297   int _declared_non_static_fields_count;
298   bool _has_non_naturally_atomic_fields;
299   bool _is_naturally_atomic;
300   bool _must_be_atomic;
301   bool _has_nonstatic_fields;
302   bool _has_inline_type_fields;
303   bool _is_contended;
304   bool _is_inline_type;
305   bool _is_abstract_value;
306   bool _has_flattening_information;
307   bool _is_empty_inline_class;
308 
309   FieldGroup* get_or_create_contended_group(int g);
310 
311  public:
312   FieldLayoutBuilder(const Symbol* classname, ClassLoaderData* loader_data, const InstanceKlass* super_klass, ConstantPool* constant_pool,
313                      GrowableArray<FieldInfo>* field_info, bool is_contended, bool is_inline_type, bool is_abstract_value,
314                      bool must_be_atomic, FieldLayoutInfo* info, Array<InlineLayoutInfo>* inline_layout_info_array);
315 
316   int payload_offset() const               { assert(_payload_offset != -1, "Uninitialized"); return _payload_offset; }
317   int  payload_layout_size_in_bytes() const    { return _payload_size_in_bytes; }
318   int  payload_layout_alignment() const        { assert(_payload_alignment != -1, "Uninitialized"); return _payload_alignment; }
319   bool has_non_atomic_flat_layout() const      { return _non_atomic_layout_size_in_bytes != -1; }
320   int  non_atomic_layout_size_in_bytes() const { return _non_atomic_layout_size_in_bytes; }
321   int  non_atomic_layout_alignment() const     { return _non_atomic_layout_alignment; }
322   bool has_atomic_layout() const               { return _atomic_layout_size_in_bytes != -1; }
323   int  atomic_layout_size_in_bytes() const     { return _atomic_layout_size_in_bytes; }
324   bool has_nullable_atomic_layout() const      { return _nullable_layout_size_in_bytes != -1; }
325   int  nullable_layout_size_in_bytes() const   { return _nullable_layout_size_in_bytes; }
326   int  null_marker_offset() const              { return _null_marker_offset; }
327   bool is_empty_inline_class() const           { return _is_empty_inline_class; }
328 
329   void build_layout();
330   void compute_regular_layout();
331   void compute_inline_class_layout();
332   void insert_contended_padding(LayoutRawBlock* slot);
333 
334  protected:
335   void prologue();
336   void epilogue();
337   void regular_field_sorting();
338   void inline_class_field_sorting();
339   void add_flat_field_oopmap(OopMapBlocksBuilder* nonstatic_oop_map, InlineKlass* vk, int offset);
340   void register_embedded_oops_from_list(OopMapBlocksBuilder* nonstatic_oop_maps, GrowableArray<LayoutRawBlock*>* list);
341   void register_embedded_oops(OopMapBlocksBuilder* nonstatic_oop_maps, FieldGroup* group);
342 };
343 
344 #endif // SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP
< prev index next >