Commit 07d40b74 authored by yangguo's avatar yangguo Committed by Commit bot

[serializer] Ensure immortal immovable roots are deserialized correctly.

The serializer collects objects in iteration order, not in allocation
order. This means that the deserializer will put these objects in
iteration order onto the reserved pages as well. There is no guarantee
that objects that were on the first page will end up on the first page
after deserialization.

Until now we got lucky, since we only ever need one space per page for
the default snapshot. For roots, the iteration order and allocation
order also do not differ enough to cause any issue for immortal
immovable root objects. These objects need to stay on the first page of
its allocated space to not move.

However, let's make sure it stays this way, and we realize soon enough
if this assumption does not hold.

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/1675553002

Cr-Commit-Position: refs/heads/master@{#33810}
parent 3ef573e9
......@@ -17,10 +17,10 @@ RootIndexMap::RootIndexMap(Isolate* isolate) {
for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) {
Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i);
Object* root = isolate->heap()->root(root_index);
if (!root->IsHeapObject()) continue;
// Omit root entries that can be written after initialization. They must
// not be referenced through the root list in the snapshot.
if (root->IsHeapObject() &&
isolate->heap()->RootCanBeTreatedAsConstant(root_index)) {
if (isolate->heap()->RootCanBeTreatedAsConstant(root_index)) {
HeapObject* heap_object = HeapObject::cast(root);
HashMap::Entry* entry = LookupEntry(map_, heap_object, false);
if (entry != NULL) {
......@@ -29,6 +29,11 @@ RootIndexMap::RootIndexMap(Isolate* isolate) {
} else {
SetValue(LookupEntry(map_, heap_object, true), i);
}
} else {
// Immortal immovable root objects are constant and allocated on the first
// page of old space. Non-constant roots cannot be immortal immovable. The
// root index map contains all immortal immmovable root objects.
CHECK(!Heap::RootIsImmortalImmovable(root_index));
}
}
isolate->set_root_index_map(map_);
......
......@@ -1717,12 +1717,16 @@ void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
}
int root_index = root_index_map_.Lookup(obj);
bool is_immortal_immovable_root = false;
// We can only encode roots as such if it has already been serialized.
// That applies to root indices below the wave front.
if (root_index != RootIndexMap::kInvalidRootIndex &&
root_index < root_index_wave_front_) {
PutRoot(root_index, obj, how_to_code, where_to_point, skip);
return;
if (root_index != RootIndexMap::kInvalidRootIndex) {
if (root_index < root_index_wave_front_) {
PutRoot(root_index, obj, how_to_code, where_to_point, skip);
return;
} else {
is_immortal_immovable_root = Heap::RootIsImmortalImmovable(root_index);
}
}
if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
......@@ -1733,6 +1737,14 @@ void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
ObjectSerializer object_serializer(this, obj, sink_, how_to_code,
where_to_point);
object_serializer.Serialize();
if (is_immortal_immovable_root) {
// Make sure that the immortal immovable root has been included in the first
// chunk of its reserved space , so that it is deserialized onto the first
// page of its space and stays immortal immovable.
BackReference ref = back_reference_map_.Lookup(obj);
CHECK(ref.is_valid() && ref.chunk_index() == 0);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment