[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>();