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
|
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 _default_value_offset; // offset of the default value in class mirror, only for static layout of inline classes
202 int _null_reset_value_offset; // offset of the reset value in class mirror, only for static layout of inline classes
203 bool _super_has_fields;
204 bool _has_inherited_fields;
205
206 public:
207 FieldLayout(GrowableArray<FieldInfo>* field_info, Array<InlineLayoutInfo>* inline_layout_info_array, ConstantPool* cp);
208 void initialize_static_layout();
209 void initialize_instance_layout(const InstanceKlass* ik);
210
211 LayoutRawBlock* first_empty_block() {
212 LayoutRawBlock* block = _start;
213 while (block->block_kind() != LayoutRawBlock::EMPTY) {
214 block = block->next_block();
215 }
216 return block;
217 }
218
219 LayoutRawBlock* blocks() const { return _blocks; }
220
221 LayoutRawBlock* start() const { return _start; }
222 void set_start(LayoutRawBlock* start) { _start = start; }
223 LayoutRawBlock* last_block() const { return _last; }
224 int super_first_field_offset() const { return _super_first_field_offset; }
225 int super_alignment() const { return _super_alignment; }
226 int super_min_align_required() const { return _super_min_align_required; }
227 int default_value_offset() const {
228 assert(_default_value_offset != -1, "Must have been set");
229 return _default_value_offset;
230 }
231 int null_reset_value_offset() const {
232 assert(_null_reset_value_offset != -1, "Must have been set");
233 return _null_reset_value_offset;
234 }
235 bool super_has_fields() const { return _super_has_fields; }
236 bool has_inherited_fields() const { return _has_inherited_fields; }
237
238 LayoutRawBlock* first_field_block();
239 void add(GrowableArray<LayoutRawBlock*>* list, LayoutRawBlock* start = nullptr);
240 void add_field_at_offset(LayoutRawBlock* blocks, int offset, LayoutRawBlock* start = nullptr);
241 void add_contiguously(GrowableArray<LayoutRawBlock*>* list, LayoutRawBlock* start = nullptr);
242 LayoutRawBlock* insert_field_block(LayoutRawBlock* slot, LayoutRawBlock* block);
243 bool reconstruct_layout(const InstanceKlass* ik);
244 void fill_holes(const InstanceKlass* ik);
245 LayoutRawBlock* insert(LayoutRawBlock* slot, LayoutRawBlock* block);
246 void remove(LayoutRawBlock* block);
247 void shift_fields(int shift);
248 LayoutRawBlock* find_null_marker();
249 void remove_null_marker();
250 void print(outputStream* output, bool is_static, const InstanceKlass* super, Array<InlineLayoutInfo>* inline_fields);
251 };
252
253
254 // FieldLayoutBuilder is the main entry point for layout computation.
255 // This class has two methods to generate layout: one for identity classes
256 // and one for inline classes. The rational for having two methods
257 // is that each kind of classes has a different set goals regarding
258 // its layout, so instead of mixing two layout strategies into a
259 // single method, each kind has its own method (see comments below
260 // for more details about the allocation strategies).
261 //
262 // Computing the layout of a class always goes through 4 steps:
263 // 1 - Prologue: preparation of data structure and gathering of
264 // layout information inherited from super classes
265 // 2 - Field sorting: fields are sorted according to their
266 // kind (oop, primitive, inline class) and their contention
267 // annotation (if any)
268 // 3 - Layout is computed from the set of lists generated during
269 // step 2
270 // 4 - Epilogue: oopmaps are generated, layout information is
271 // prepared so other VM components can use it (instance size,
272 // static field size, non-static field size, etc.)
273 //
274 // Steps 1 and 4 are common to all layout computations. Step 2 and 3
275 // differ for inline classes and identity classes.
276 //
277 class FieldLayoutBuilder : public ResourceObj {
278
279 private:
280 const Symbol* _classname;
281 ClassLoaderData* _loader_data;
282 const InstanceKlass* _super_klass;
283 ConstantPool* _constant_pool;
284 GrowableArray<FieldInfo>* _field_info;
285 FieldLayoutInfo* _info;
286 Array<InlineLayoutInfo>* _inline_layout_info_array;
287 FieldGroup* _root_group;
288 GrowableArray<FieldGroup*> _contended_groups;
289 FieldGroup* _static_fields;
290 FieldLayout* _layout;
291 FieldLayout* _static_layout;
292 int _nonstatic_oopmap_count;
293 int _payload_alignment;
294 int _first_field_offset;
295 int _null_marker_offset; // if any, -1 means no internal null marker
296 int _payload_size_in_bytes;
297 int _non_atomic_layout_size_in_bytes;
298 int _non_atomic_layout_alignment;
299 int _atomic_layout_size_in_bytes;
300 int _nullable_layout_size_in_bytes;
301 int _fields_size_sum;
302 int _declared_non_static_fields_count;
303 bool _has_non_naturally_atomic_fields;
304 bool _is_naturally_atomic;
305 bool _must_be_atomic;
306 bool _has_nonstatic_fields;
307 bool _has_inline_type_fields;
308 bool _is_contended;
309 bool _is_inline_type;
310 bool _is_abstract_value;
311 bool _has_flattening_information;
312 bool _is_empty_inline_class;
313
314 FieldGroup* get_or_create_contended_group(int g);
315
316 public:
317 FieldLayoutBuilder(const Symbol* classname, ClassLoaderData* loader_data, const InstanceKlass* super_klass, ConstantPool* constant_pool,
318 GrowableArray<FieldInfo>* field_info, bool is_contended, bool is_inline_type, bool is_abstract_value,
319 bool must_be_atomic, FieldLayoutInfo* info, Array<InlineLayoutInfo>* inline_layout_info_array);
320
321 int first_field_offset() const { assert(_first_field_offset != -1, "Uninitialized"); return _first_field_offset; }
322 int payload_layout_size_in_bytes() const { return _payload_size_in_bytes; }
323 int payload_layout_alignment() const { assert(_payload_alignment != -1, "Uninitialized"); return _payload_alignment; }
324 bool has_non_atomic_flat_layout() const { return _non_atomic_layout_size_in_bytes != -1; }
325 int non_atomic_layout_size_in_bytes() const { return _non_atomic_layout_size_in_bytes; }
326 int non_atomic_layout_alignment() const { return _non_atomic_layout_alignment; }
327 bool has_atomic_layout() const { return _atomic_layout_size_in_bytes != -1; }
328 int atomic_layout_size_in_bytes() const { return _atomic_layout_size_in_bytes; }
329 bool has_nullable_layout() const { return _nullable_layout_size_in_bytes != -1; }
330 int nullable_layout_size_in_bytes() const { return _nullable_layout_size_in_bytes; }
331 int null_marker_offset() const { return _null_marker_offset; }
332 bool is_empty_inline_class() const { return _is_empty_inline_class; }
333
334 void build_layout();
335 void compute_regular_layout();
336 void compute_inline_class_layout();
337 void insert_contended_padding(LayoutRawBlock* slot);
338
339 protected:
340 void prologue();
341 void epilogue();
342 void regular_field_sorting();
343 void inline_class_field_sorting();
344 void add_flat_field_oopmap(OopMapBlocksBuilder* nonstatic_oop_map, InlineKlass* vk, int offset);
345 void register_embedded_oops_from_list(OopMapBlocksBuilder* nonstatic_oop_maps, GrowableArray<LayoutRawBlock*>* list);
346 void register_embedded_oops(OopMapBlocksBuilder* nonstatic_oop_maps, FieldGroup* group);
347 };
348
349 #endif // SHARE_CLASSFILE_FIELDLAYOUTBUILDER_HPP
|