@@ -126,17 +126,19 @@ void FieldLayout::initialize_static_layout() {
126126 }
127127}
128128
129- void FieldLayout::initialize_instance_layout (const InstanceKlass* super_klass) {
129+ void FieldLayout::initialize_instance_layout (const InstanceKlass* super_klass, bool & super_ends_with_oop ) {
130130 if (super_klass == nullptr ) {
131+ super_ends_with_oop = false ;
131132 _blocks = new LayoutRawBlock (LayoutRawBlock::EMPTY, INT_MAX);
132133 _blocks->set_offset (0 );
133134 _last = _blocks;
134135 _start = _blocks;
135136 insert (first_empty_block (), new LayoutRawBlock (LayoutRawBlock::RESERVED, instanceOopDesc::base_offset_in_bytes ()));
136137 } else {
137- bool has_fields = reconstruct_layout (super_klass);
138+ bool super_has_instance_fields = false ;
139+ reconstruct_layout (super_klass, super_has_instance_fields, super_ends_with_oop);
138140 fill_holes (super_klass);
139- if (!super_klass->has_contended_annotations () || !has_fields ) {
141+ if (!super_klass->has_contended_annotations () || !super_has_instance_fields ) {
140142 _start = _blocks; // start allocating fields from the first empty block
141143 } else {
142144 _start = _last; // append fields at the end of the reconstructed layout
@@ -293,15 +295,21 @@ LayoutRawBlock* FieldLayout::insert_field_block(LayoutRawBlock* slot, LayoutRawB
293295 return block;
294296}
295297
296- bool FieldLayout::reconstruct_layout (const InstanceKlass* ik) {
297- bool has_instance_fields = false ;
298+ void FieldLayout::reconstruct_layout (const InstanceKlass* ik, bool & has_instance_fields, bool & ends_with_oop ) {
299+ has_instance_fields = ends_with_oop = false ;
298300 GrowableArray<LayoutRawBlock*>* all_fields = new GrowableArray<LayoutRawBlock*>(32 );
301+ BasicType last_type;
302+ int last_offset = -1 ;
299303 while (ik != nullptr ) {
300304 for (AllFieldStream fs (ik->fieldinfo_stream (), ik->constants ()); !fs.done (); fs.next ()) {
301305 BasicType type = Signature::basic_type (fs.signature ());
302306 // distinction between static and non-static fields is missing
303307 if (fs.access_flags ().is_static ()) continue ;
304308 has_instance_fields = true ;
309+ if (fs.offset () > last_offset) {
310+ last_offset = fs.offset ();
311+ last_type = type;
312+ }
305313 int size = type2aelembytes (type);
306314 // INHERITED blocks are marked as non-reference because oop_maps are handled by their holder class
307315 LayoutRawBlock* block = new LayoutRawBlock (fs.index (), LayoutRawBlock::INHERITED, size, size, false );
@@ -310,6 +318,11 @@ bool FieldLayout::reconstruct_layout(const InstanceKlass* ik) {
310318 }
311319 ik = ik->super () == nullptr ? nullptr : InstanceKlass::cast (ik->super ());
312320 }
321+ assert (last_offset == -1 || last_offset > 0 , " Sanity" );
322+ if (last_offset > 0 &&
323+ (last_type == BasicType::T_ARRAY || last_type == BasicType::T_OBJECT)) {
324+ ends_with_oop = true ;
325+ }
313326
314327 all_fields->sort (LayoutRawBlock::compare_offset);
315328 _blocks = new LayoutRawBlock (LayoutRawBlock::RESERVED, instanceOopDesc::base_offset_in_bytes ());
@@ -323,7 +336,6 @@ bool FieldLayout::reconstruct_layout(const InstanceKlass* ik) {
323336 _last = b;
324337 }
325338 _start = _blocks;
326- return has_instance_fields;
327339}
328340
329341// Called during the reconstruction of a layout, after fields from super
@@ -516,7 +528,7 @@ FieldGroup* FieldLayoutBuilder::get_or_create_contended_group(int g) {
516528void FieldLayoutBuilder::prologue () {
517529 _layout = new FieldLayout (_field_info, _constant_pool);
518530 const InstanceKlass* super_klass = _super_klass;
519- _layout->initialize_instance_layout (super_klass);
531+ _layout->initialize_instance_layout (super_klass, _super_ends_with_oop );
520532 if (super_klass != nullptr ) {
521533 _has_nonstatic_fields = super_klass->has_nonstatic_fields ();
522534 }
@@ -594,8 +606,14 @@ void FieldLayoutBuilder::insert_contended_padding(LayoutRawBlock* slot) {
594606// Computation of regular classes layout is an evolution of the previous default layout
595607// (FieldAllocationStyle 1):
596608// - primitive fields are allocated first (from the biggest to the smallest)
597- // - then oop fields are allocated, either in existing gaps or at the end of
598- // the layout
609+ // - oop fields are allocated, either in existing gaps or at the end of
610+ // the layout. We allocate oops in a single block to have a single oop map entry.
611+ // - if the super class ended with an oop, we lead with oops. That will cause the
612+ // trailing oop map entry of the super class and the oop map entry of this class
613+ // to be folded into a single entry later. Correspondingly, if the super class
614+ // ends with a primitive field, we gain nothing by leading with oops; therefore
615+ // we let oop fields trail, thus giving future derived classes the chance to apply
616+ // the same trick.
599617void FieldLayoutBuilder::compute_regular_layout () {
600618 bool need_tail_padding = false ;
601619 prologue ();
@@ -608,8 +626,14 @@ void FieldLayoutBuilder::compute_regular_layout() {
608626 insert_contended_padding (_layout->start ());
609627 need_tail_padding = true ;
610628 }
611- _layout->add (_root_group->primitive_fields ());
612- _layout->add (_root_group->oop_fields ());
629+
630+ if (_super_ends_with_oop) {
631+ _layout->add (_root_group->oop_fields ());
632+ _layout->add (_root_group->primitive_fields ());
633+ } else {
634+ _layout->add (_root_group->primitive_fields ());
635+ _layout->add (_root_group->oop_fields ());
636+ }
613637
614638 if (!_contended_groups.is_empty ()) {
615639 for (int i = 0 ; i < _contended_groups.length (); i++) {
0 commit comments