@@ -275,6 +275,47 @@ inline void ValuePayload::print_on(outputStream* st) const {
275275 }
276276}
277277
278+ inline void ValuePayload::assert_is_flat_field (const InstanceKlass* klass, int offset) const {
279+ OnVMError on_assertion_failure_field_descriptor ([&](outputStream* st) {
280+ st->print_cr (" === assert_is_flat_field(" PTR_FORMAT " , %d) failure ===" , p2i (klass), offset);
281+ StreamIndentor si (st);
282+ if (klass != nullptr ) {
283+ klass->print_on (st);
284+ st->cr ();
285+ }
286+ });
287+
288+ fieldDescriptor field_descriptor;
289+ postcond (klass->find_flat_field_containing_offset (offset, &field_descriptor));
290+
291+ const InlineLayoutInfo inline_layout_info = field_descriptor.field_holder ()->inline_layout_info (field_descriptor.index ());
292+
293+ OnVMError on_assertion_failure_inline_layout_info ([&](outputStream* st) {
294+ st->print_cr (" === assert_is_flat_field(" PTR_FORMAT " , %d) failure ===" , p2i (klass), offset);
295+ StreamIndentor si (st);
296+ st->print (" field_descriptor: " );
297+ field_descriptor.print_on (st);
298+ st->cr ();
299+ st->print (" inline_layout_info: " );
300+ inline_layout_info.print_on (st);
301+ st->cr ();
302+ });
303+
304+ if (inline_layout_info.klass () == this ->klass ()) {
305+ // Found the field in klass
306+ postcond (offset == field_descriptor.offset ());
307+ postcond (inline_layout_info.kind () == layout_kind ());
308+ postcond (field_descriptor.layout_kind () == layout_kind ());
309+ postcond (field_descriptor.is_flat ());
310+ } else {
311+ // Nested flat field
312+ postcond (offset >= field_descriptor.offset ());
313+ const InlineKlass* const field_klass = inline_layout_info.klass ();
314+ const int payload_offset = field_klass->payload_offset ();
315+ assert_is_flat_field (field_klass, offset - field_descriptor.offset () + payload_offset);
316+ }
317+ }
318+
278319inline void ValuePayload::assert_post_construction_invariants () const {
279320 OnVMError on_assertion_failure ([&](outputStream* st) {
280321 st->print_cr (" === assert_post_construction_invariants failure ===" );
@@ -283,12 +324,38 @@ inline void ValuePayload::assert_post_construction_invariants() const {
283324 st->cr ();
284325 });
285326
286- postcond (uses_absolute_addr () || container () != nullptr );
287327 postcond (layout_kind () != LayoutKind::REFERENCE);
288328 postcond (layout_kind () != LayoutKind::UNKNOWN);
289329 postcond (klass ()->is_layout_supported (layout_kind ()));
290- postcond (uses_absolute_addr () || (container ()->klass () == klass ()) ==
291- (layout_kind () == LayoutKind::BUFFERED));
330+
331+ if (!uses_absolute_addr ()) {
332+ postcond (container () != nullptr );
333+ const Klass* const container_klass = container ()->klass ();
334+ if (container_klass == klass ()) {
335+ postcond (layout_kind () == LayoutKind::BUFFERED);
336+ } else {
337+ postcond (layout_kind () != LayoutKind::BUFFERED);
338+ if (container_klass->is_mirror_instance_klass ()) {
339+ fatal (" java.lang.Class has no flat fields. Static fields are not flattened" );
340+ } else if (container_klass->is_instance_klass ()) {
341+ assert_is_flat_field (InstanceKlass::cast (container_klass), checked_cast<int >(offset ()));
342+ } else {
343+ const FlatArrayKlass* const container_flat_array_klass = FlatArrayKlass::cast (container_klass);
344+ if (container_flat_array_klass->element_klass () == klass ()) {
345+ postcond (container_flat_array_klass->layout_kind () == layout_kind ());
346+ } else {
347+ // Accessing nested flat field
348+ const InlineKlass* const element_klass = container_flat_array_klass->element_klass ();
349+ const int element_offset =
350+ (checked_cast<int >(this ->offset ()) -
351+ checked_cast<int >(flatArrayOopDesc::base_offset_in_bytes ())) %
352+ container_flat_array_klass->element_byte_size ();
353+ const int payload_offset = element_klass->payload_offset ();
354+ assert_is_flat_field (element_klass, element_offset + payload_offset);
355+ }
356+ }
357+ }
358+ }
292359}
293360
294361inline void ValuePayload::assert_pre_copy_invariants (const ValuePayload& src,
@@ -525,6 +592,40 @@ inline FlatFieldPayload::FlatFieldPayload(instanceOop container,
525592 InlineLayoutInfo* inline_layout_info)
526593 : FlatValuePayload(container, offset, inline_layout_info->klass (), inline_layout_info->kind()) {}
527594
595+ #ifdef ASSERT
596+
597+ inline void FlatFieldPayload::assert_post_construction_invariants (instanceOop container,
598+ ResolvedFieldEntry* resolved_field_entry,
599+ InstanceKlass* klass) const {
600+ OnVMError on_assertion_failure ([&](outputStream* st) {
601+ st->print_cr (" === assert_post_construction_invariants failure ===" );
602+ StreamIndentor si (st);
603+ print_on (st);
604+ st->cr ();
605+ });
606+
607+ postcond (container->klass ()->is_subclass_of (klass));
608+ postcond (klass == resolved_field_entry->field_holder ());
609+ postcond (resolved_field_entry->is_flat ());
610+ }
611+
612+ inline void FlatFieldPayload::assert_post_construction_invariants (instanceOop container,
613+ fieldDescriptor* field_descriptor,
614+ InstanceKlass* klass) const {
615+ OnVMError on_assertion_failure ([&](outputStream* st) {
616+ st->print_cr (" === assert_post_construction_invariants failure ===" );
617+ StreamIndentor si (st);
618+ print_on (st);
619+ st->cr ();
620+ });
621+
622+ postcond (container->klass ()->is_subclass_of (klass));
623+ postcond (klass == field_descriptor->field_holder ());
624+ postcond (field_descriptor->is_flat ());
625+ }
626+
627+ #endif // ASSERT
628+
528629inline FlatFieldPayload::FlatFieldPayload (instanceOop container,
529630 fieldDescriptor* field_descriptor)
530631 : FlatFieldPayload(container, field_descriptor,
@@ -536,7 +637,7 @@ inline FlatFieldPayload::FlatFieldPayload(instanceOop container,
536637 : FlatFieldPayload(container,
537638 field_descriptor->offset (),
538639 klass->inline_layout_info_adr(field_descriptor->index ())) {
539- postcond (container-> klass () == klass);
640+ assert_post_construction_invariants (container, field_descriptor, klass);
540641}
541642
542643inline FlatFieldPayload::FlatFieldPayload (instanceOop container,
@@ -551,7 +652,7 @@ inline FlatFieldPayload::FlatFieldPayload(instanceOop container,
551652 : FlatFieldPayload(container,
552653 resolved_field_entry->field_offset (),
553654 klass->inline_layout_info_adr(resolved_field_entry->field_index ())) {
554- postcond (container-> klass ()-> is_subclass_of (klass) );
655+ assert_post_construction_invariants (container, resolved_field_entry, klass);
555656}
556657
557658inline instanceOop FlatFieldPayload::container () const {
0 commit comments