Commit 12427d0d authored by Dan Elphick's avatar Dan Elphick Committed by Commit Bot

[snapshot] Repair FreeSpace objects in RO_SPACE

Move fixing up Filler objects after deserialization from the
StartupDeserializer to the ReadOnlyDeserializer since that's what
deserializes the Filler maps.

Since only RO_SPACE can contain such objects, skip iterating over all
the spaces and just fix them up directly in RO_SPACE. To this end, the
PagedSpace code is moved to ReadOnlySpace and the Heap fix up method is
removed.

Change-Id: I7a01f1ef298e6d5e74d3173620fb7764c3b598f2
Reviewed-on: https://chromium-review.googlesource.com/c/1299013Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57015}
parent 69f370b6
......@@ -607,14 +607,6 @@ const char* Heap::GetSpaceName(int idx) {
return nullptr;
}
void Heap::RepairFreeListsAfterDeserialization() {
PagedSpaces spaces(this);
for (PagedSpace* space = spaces.next(); space != nullptr;
space = spaces.next()) {
space->RepairFreeListsAfterDeserialization();
}
}
void Heap::MergeAllocationSitePretenuringFeedback(
const PretenuringFeedbackMap& local_pretenuring_feedback) {
AllocationSite* site = nullptr;
......
......@@ -343,9 +343,6 @@ class Heap {
inline Address* OldSpaceAllocationTopAddress();
inline Address* OldSpaceAllocationLimitAddress();
// FreeSpace objects have a null map after deserialization. Update the map.
void RepairFreeListsAfterDeserialization();
// Move len elements within a given array from src_index index to dst_index
// index.
void MoveElements(FixedArray* array, int dst_index, int src_index, int len,
......
......@@ -3129,34 +3129,6 @@ size_t PagedSpace::SizeOfObjects() {
return Size() - (limit() - top());
}
// After we have booted, we have created a map which represents free space
// on the heap. If there was already a free list then the elements on it
// were created with the wrong FreeSpaceMap (normally nullptr), so we need to
// fix them.
void PagedSpace::RepairFreeListsAfterDeserialization() {
free_list_.RepairLists(heap());
// Each page may have a small free space that is not tracked by a free list.
// Those free spaces still contain null as their map pointer.
// Overwrite them with new fillers.
for (Page* page : *this) {
int size = static_cast<int>(page->wasted_memory());
if (size == 0) {
// If there is no wasted memory then all free space is in the free list.
continue;
}
Address start = page->HighWaterMark();
Address end = page->area_end();
if (start < end - size) {
// A region at the high watermark is already in free list.
HeapObject* filler = HeapObject::FromAddress(start);
CHECK(filler->IsFiller());
start += filler->Size();
}
CHECK_EQ(size, static_cast<int>(end - start));
heap()->CreateFillerObjectAt(start, size, ClearRecordedSlots::kNo);
}
}
bool PagedSpace::SweepAndRetryAllocation(int size_in_bytes) {
MarkCompactCollector* collector = heap()->mark_compact_collector();
if (collector->sweeping_in_progress()) {
......@@ -3292,6 +3264,34 @@ void ReadOnlySpace::SetPermissionsForPages(PageAllocator::Permission access) {
}
}
// After we have booted, we have created a map which represents free space
// on the heap. If there was already a free list then the elements on it
// were created with the wrong FreeSpaceMap (normally nullptr), so we need to
// fix them.
void ReadOnlySpace::RepairFreeListsAfterDeserialization() {
free_list_.RepairLists(heap());
// Each page may have a small free space that is not tracked by a free list.
// Those free spaces still contain null as their map pointer.
// Overwrite them with new fillers.
for (Page* page : *this) {
int size = static_cast<int>(page->wasted_memory());
if (size == 0) {
// If there is no wasted memory then all free space is in the free list.
continue;
}
Address start = page->HighWaterMark();
Address end = page->area_end();
if (start < end - size) {
// A region at the high watermark is already in free list.
HeapObject* filler = HeapObject::FromAddress(start);
CHECK(filler->IsFiller());
start += filler->Size();
}
CHECK_EQ(size, static_cast<int>(end - start));
heap()->CreateFillerObjectAt(start, size, ClearRecordedSlots::kNo);
}
}
void ReadOnlySpace::ClearStringPaddingIfNeeded() {
if (is_string_padding_cleared_) return;
......
......@@ -2077,10 +2077,6 @@ class V8_EXPORT_PRIVATE PagedSpace
// Does the space need executable memory?
Executability executable() { return executable_; }
// During boot the free_space_map is created, and afterwards we may need
// to write it into the free list nodes that were already created.
void RepairFreeListsAfterDeserialization();
// Prepares for a mark-compact GC.
void PrepareForMarkCompact();
......@@ -2929,6 +2925,10 @@ class ReadOnlySpace : public PagedSpace {
void ClearStringPaddingIfNeeded();
void MarkAsReadOnly();
// During boot the free_space_map is created, and afterwards we may need
// to write it into the free list nodes that were already created.
void RepairFreeListsAfterDeserialization();
private:
void MarkAsReadWrite();
void SetPermissionsForPages(PageAllocator::Permission access);
......
......@@ -34,6 +34,7 @@ void ReadOnlyDeserializer::DeserializeInto(Isolate* isolate) {
DisallowHeapAllocation no_gc;
ReadOnlyRoots(isolate).Iterate(this);
isolate->heap()->read_only_space()->RepairFreeListsAfterDeserialization();
// Deserialize the Read-only Object Cache.
std::vector<Object*>* cache = isolate->read_only_object_cache();
......
......@@ -42,7 +42,6 @@ void StartupDeserializer::DeserializeInto(Isolate* isolate) {
DisallowHeapAllocation no_gc;
isolate->heap()->IterateSmiRoots(this);
isolate->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG);
isolate->heap()->RepairFreeListsAfterDeserialization();
isolate->heap()->IterateWeakRoots(this, VISIT_FOR_SERIALIZATION);
DeserializeDeferredObjects();
RestoreExternalReferenceRedirectors(accessor_infos());
......
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