Commit 250ba28a authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap, deserializer] Restore marking invariant for deserialized maps

when black allocation is on.

The scenario:
1) Incremental marking is off.
2) Partial deserialization starts and calls Heap::ReserveSpace.
2) ReserveSpace creates (white) reservations in old space.
3) ReserveSpace allocates map placeholders. One of these allocations
starts incremental marking, which starts black allocation (currently
when concurrent marking is on). Subsequent maps are black allocated.
4) ReserveSpace succeeds without triggering a GC.
5) Deserialization continues. Some maps are black. Note that
deserialization emits only old->new write barriers and skips
marking write barriers.
6) Deserialization finishes and re-visits the black allocated
reservations and large object. This misses black allocated maps.
7) There is black->white descriptor array pointer in one of these map.

BUG=chromium:723600

Change-Id: Ifffe46f22a7d7dbc5cff2e882190234fcc722ccb
Reviewed-on: https://chromium-review.googlesource.com/581187
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46816}
parent a9428d52
......@@ -4481,10 +4481,10 @@ void Heap::FinalizeIncrementalMarkingIfComplete(
}
void Heap::RegisterDeserializedObjectsForBlackAllocation(
Reservation* reservations, List<HeapObject*>* large_objects) {
// TODO(hpayer): We do not have to iterate reservations on black objects
// for marking. We just have to execute the special visiting side effect
// code that adds objects to global data structures, e.g. for array buffers.
Reservation* reservations, List<HeapObject*>* large_objects,
List<Address>* maps) {
// TODO(ulan): pause black allocation during deserialization to avoid
// iterating all these objects in one go.
if (!incremental_marking()->black_allocation()) return;
......@@ -4514,6 +4514,12 @@ void Heap::RegisterDeserializedObjectsForBlackAllocation(
for (HeapObject* object : *large_objects) {
incremental_marking()->ProcessBlackAllocatedObject(object);
}
// Map space doesn't use reservations, so it needs custom handling.
for (Address addr : *maps) {
incremental_marking()->ProcessBlackAllocatedObject(
HeapObject::FromAddress(addr));
}
}
void Heap::NotifyObjectLayoutChange(HeapObject* object,
......
......@@ -1184,7 +1184,8 @@ class Heap {
void FinalizeIncrementalMarkingIfComplete(GarbageCollectionReason gc_reason);
void RegisterDeserializedObjectsForBlackAllocation(
Reservation* reservations, List<HeapObject*>* large_objects);
Reservation* reservations, List<HeapObject*>* large_objects,
List<Address>* maps);
IncrementalMarking* incremental_marking() { return incremental_marking_; }
......
......@@ -153,7 +153,7 @@ MaybeHandle<Object> Deserializer::DeserializePartial(
DeserializeEmbedderFields(embedder_fields_deserializer);
isolate->heap()->RegisterDeserializedObjectsForBlackAllocation(
reservations_, &deserialized_large_objects_);
reservations_, &deserialized_large_objects_, &allocated_maps_);
// There's no code deserialized here. If this assert fires then that's
// changed and logging should be added to notify the profiler et al of the
......@@ -181,7 +181,7 @@ MaybeHandle<HeapObject> Deserializer::DeserializeObject(Isolate* isolate) {
FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects();
result = Handle<HeapObject>(HeapObject::cast(root));
isolate->heap()->RegisterDeserializedObjectsForBlackAllocation(
reservations_, &deserialized_large_objects_);
reservations_, &deserialized_large_objects_, &allocated_maps_);
}
CommitPostProcessedObjects(isolate);
return scope.CloseAndEscape(result);
......
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