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) { ...@@ -88,6 +88,31 @@ ScriptData* CodeSerializer::Serialize(Handle<HeapObject> obj) {
return data.GetScriptData(); 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, void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) { WhereToPoint where_to_point, int skip) {
if (SerializeHotObject(obj, how_to_code, where_to_point, skip)) return; if (SerializeHotObject(obj, how_to_code, where_to_point, skip)) return;
...@@ -100,6 +125,8 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, ...@@ -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 (SerializeBackReference(obj, how_to_code, where_to_point, skip)) return;
if (SerializeReadOnlyObject(obj, how_to_code, where_to_point, skip)) return;
FlushSkip(skip); FlushSkip(skip);
if (obj->IsCode()) { if (obj->IsCode()) {
......
...@@ -78,6 +78,9 @@ class CodeSerializer : public Serializer<> { ...@@ -78,6 +78,9 @@ class CodeSerializer : public Serializer<> {
void SerializeCodeStub(Code* code_stub, HowToCode how_to_code, void SerializeCodeStub(Code* code_stub, HowToCode how_to_code,
WhereToPoint where_to_point); WhereToPoint where_to_point);
bool SerializeReadOnlyObject(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip);
DisallowHeapAllocation no_gc_; DisallowHeapAllocation no_gc_;
uint32_t source_hash_; uint32_t source_hash_;
std::vector<uint32_t> stub_keys_; std::vector<uint32_t> stub_keys_;
......
...@@ -70,6 +70,11 @@ bool DefaultSerializerAllocator::BackReferenceIsAlreadyAllocated( ...@@ -70,6 +70,11 @@ bool DefaultSerializerAllocator::BackReferenceIsAlreadyAllocated(
return reference.large_object_index() < seen_large_objects_index_; return reference.large_object_index() < seen_large_objects_index_;
} else if (space == MAP_SPACE) { } else if (space == MAP_SPACE) {
return reference.map_index() < num_maps_; 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 { } else {
size_t chunk_index = reference.chunk_index(); size_t chunk_index = reference.chunk_index();
if (chunk_index == completed_chunks_[space].size()) { if (chunk_index == completed_chunks_[space].size()) {
......
...@@ -281,6 +281,18 @@ HeapObject* Deserializer<AllocatorT>::GetBackReferencedObject(int space) { ...@@ -281,6 +281,18 @@ HeapObject* Deserializer<AllocatorT>::GetBackReferencedObject(int space) {
case MAP_SPACE: case MAP_SPACE:
obj = allocator()->GetMap(back_reference.map_index()); obj = allocator()->GetMap(back_reference.map_index());
break; 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: default:
obj = allocator()->GetObject(static_cast<AllocationSpace>(space), obj = allocator()->GetObject(static_cast<AllocationSpace>(space),
back_reference.chunk_index(), 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