Commit 378e8846 authored by Dan Elphick's avatar Dan Elphick Committed by Commit Bot

[snapshot] CodeSerializer never allocates in RO_SPACE

When serializing/deserializing RO_SPACE objects in CodeSerializer use
BackReferences to avoid re-allocating inside RO_SPACE.

Change-Id: Ie9063a43a4f758f0401ad59dfcc61c4b759591bc
Reviewed-on: https://chromium-review.googlesource.com/997837
Commit-Queue: Dan Elphick <delphick@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52429}
parent 2c3654c4
......@@ -88,6 +88,31 @@ ScriptData* CodeSerializer::Serialize(Handle<HeapObject> obj) {
return data.GetScriptData();
}
bool CodeSerializer::SerializeReadOnlyObject(HeapObject* obj,
HowToCode how_to_code,
WhereToPoint where_to_point,
int skip) {
PagedSpace* read_only_space = isolate()->heap()->read_only_space();
if (!read_only_space->Contains(obj)) return false;
// For objects in RO_SPACE, never serialize the object, but instead create a
// back reference that encodes the page number as the chunk_index and the
// offset within the page as the chunk_offset.
Address address = obj->address();
Page* page = Page::FromAddress(address);
uint32_t chunk_index = 0;
for (Page* p : *read_only_space) {
if (p == page) break;
++chunk_index;
}
uint32_t chunk_offset = static_cast<uint32_t>(page->Offset(address));
SerializerReference back_reference =
SerializerReference::BackReference(RO_SPACE, chunk_index, chunk_offset);
reference_map()->Add(obj, back_reference);
CHECK(SerializeBackReference(obj, how_to_code, where_to_point, skip));
return true;
}
void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) {
if (SerializeHotObject(obj, how_to_code, where_to_point, skip)) return;
......@@ -100,6 +125,8 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
if (SerializeBackReference(obj, how_to_code, where_to_point, skip)) return;
if (SerializeReadOnlyObject(obj, how_to_code, where_to_point, skip)) return;
FlushSkip(skip);
if (obj->IsCode()) {
......
......@@ -78,6 +78,9 @@ class CodeSerializer : public Serializer<> {
void SerializeCodeStub(Code* code_stub, HowToCode how_to_code,
WhereToPoint where_to_point);
bool SerializeReadOnlyObject(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip);
DisallowHeapAllocation no_gc_;
uint32_t source_hash_;
std::vector<uint32_t> stub_keys_;
......
......@@ -70,6 +70,11 @@ bool DefaultSerializerAllocator::BackReferenceIsAlreadyAllocated(
return reference.large_object_index() < seen_large_objects_index_;
} else if (space == MAP_SPACE) {
return reference.map_index() < num_maps_;
} else if (space == RO_SPACE &&
serializer_->isolate()->heap()->deserialization_complete()) {
// If not deserializing the isolate itself, then we create BackReferences
// for all RO_SPACE objects without ever allocating.
return true;
} else {
size_t chunk_index = reference.chunk_index();
if (chunk_index == completed_chunks_[space].size()) {
......
......@@ -281,6 +281,18 @@ HeapObject* Deserializer<AllocatorT>::GetBackReferencedObject(int space) {
case MAP_SPACE:
obj = allocator()->GetMap(back_reference.map_index());
break;
case RO_SPACE:
if (isolate()->heap()->deserialization_complete()) {
PagedSpace* read_only_space = isolate()->heap()->read_only_space();
Page* page = read_only_space->FirstPage();
for (uint32_t i = 0; i < back_reference.chunk_index(); ++i) {
page = page->next_page();
}
Address address = page->OffsetToAddress(back_reference.chunk_offset());
obj = HeapObject::FromAddress(address);
break;
}
V8_FALLTHROUGH;
default:
obj = allocator()->GetObject(static_cast<AllocationSpace>(space),
back_reference.chunk_index(),
......
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