[vm] Remove assumption from Instance cluster than the Class cluster comes earlier.

Clusters should not read information produced by any other cluster until PostLoad.

Bug: https://github.com/dart-lang/sdk/issues/41974
Change-Id: I39ec580d9011604f7041615cefaa907aa99a3ff8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164280
Reviewed-by: RĂ©gis Crelier <regis@google.com>
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index d6436b7..b41c47f 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -144,6 +144,40 @@
   size_ += (stop - start);
 }
 
+static UnboxedFieldBitmap CalculateTargetUnboxedFieldsBitmap(
+    Serializer* s,
+    intptr_t class_id) {
+  const auto unboxed_fields_bitmap_host =
+      s->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
+          class_id);
+
+  UnboxedFieldBitmap unboxed_fields_bitmap;
+  if (unboxed_fields_bitmap_host.IsEmpty() ||
+      kWordSize == compiler::target::kWordSize) {
+    unboxed_fields_bitmap = unboxed_fields_bitmap_host;
+  } else {
+    ASSERT(kWordSize == 8 && compiler::target::kWordSize == 4);
+    // A new bitmap is built if the word sizes in the target and
+    // host are different
+    unboxed_fields_bitmap.Reset();
+    intptr_t target_i = 0, host_i = 0;
+
+    while (host_i < UnboxedFieldBitmap::Length()) {
+      // Each unboxed field has constant length, therefore the number of
+      // words used by it should double when compiling from 64-bit to 32-bit.
+      if (unboxed_fields_bitmap_host.Get(host_i++)) {
+        unboxed_fields_bitmap.Set(target_i++);
+        unboxed_fields_bitmap.Set(target_i++);
+      } else {
+        // For object pointers, the field is always one word length
+        target_i++;
+      }
+    }
+  }
+
+  return unboxed_fields_bitmap;
+}
+
 class ClassSerializationCluster : public SerializationCluster {
  public:
   explicit ClassSerializationCluster(intptr_t num_cids)
@@ -236,39 +270,6 @@
   GrowableArray<ClassPtr> predefined_;
   GrowableArray<ClassPtr> objects_;
 
-  UnboxedFieldBitmap CalculateTargetUnboxedFieldsBitmap(Serializer* s,
-                                                        intptr_t class_id) {
-    const auto unboxed_fields_bitmap_host =
-        s->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
-            class_id);
-
-    UnboxedFieldBitmap unboxed_fields_bitmap;
-    if (unboxed_fields_bitmap_host.IsEmpty() ||
-        kWordSize == compiler::target::kWordSize) {
-      unboxed_fields_bitmap = unboxed_fields_bitmap_host;
-    } else {
-      ASSERT(kWordSize == 8 && compiler::target::kWordSize == 4);
-      // A new bitmap is built if the word sizes in the target and
-      // host are different
-      unboxed_fields_bitmap.Reset();
-      intptr_t target_i = 0, host_i = 0;
-
-      while (host_i < UnboxedFieldBitmap::Length()) {
-        // Each unboxed field has constant length, therefore the number of
-        // words used by it should double when compiling from 64-bit to 32-bit.
-        if (unboxed_fields_bitmap_host.Get(host_i++)) {
-          unboxed_fields_bitmap.Set(target_i++);
-          unboxed_fields_bitmap.Set(target_i++);
-        } else {
-          // For object pointers, the field is always one word length
-          target_i++;
-        }
-      }
-    }
-
-    return unboxed_fields_bitmap;
-  }
-
   bool RequireLegacyErasureOfConstants(ClassPtr cls) {
     // Do not generate a core snapshot containing constants that would require
     // a legacy erasure of their types if loaded in an isolate running in weak
@@ -3349,9 +3350,11 @@
     intptr_t next_field_offset = host_next_field_offset_in_words_
                                  << kWordSizeLog2;
     const intptr_t count = objects_.length();
+    s->WriteUnsigned64(CalculateTargetUnboxedFieldsBitmap(s, cid_).Value());
     const auto unboxed_fields_bitmap =
         s->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
             cid_);
+
     for (intptr_t i = 0; i < count; i++) {
       InstancePtr instance = objects_[i];
       AutoTraceObject(instance);
@@ -3407,10 +3410,8 @@
     intptr_t next_field_offset = next_field_offset_in_words_ << kWordSizeLog2;
     intptr_t instance_size =
         Object::RoundedAllocationSize(instance_size_in_words_ * kWordSize);
+    const UnboxedFieldBitmap unboxed_fields_bitmap(d->ReadUnsigned64());
 
-    const auto unboxed_fields_bitmap =
-        d->isolate()->group()->shared_class_table()->GetUnboxedFieldsMapAt(
-            cid_);
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       InstancePtr instance = static_cast<InstancePtr>(d->Ref(id));
       bool is_canonical = d->Read<bool>();