Commit 734898a7 authored by yangguo's avatar yangguo Committed by Commit bot

[serializer] encode recent long-encoded root list items as hot objects.

We have a lot of long-encoded root list items in type feedback vectors.

Review-Url: https://codereview.chromium.org/2090563002
Cr-Commit-Position: refs/heads/master@{#37237}
parent 3f0ada1d
......@@ -47,13 +47,15 @@ ScriptData* CodeSerializer::Serialize(Isolate* isolate,
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;
int root_index = root_index_map_.Lookup(obj);
if (root_index != RootIndexMap::kInvalidRootIndex) {
PutRoot(root_index, obj, how_to_code, where_to_point, skip);
return;
}
if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
if (SerializeBackReference(obj, how_to_code, where_to_point, skip)) return;
FlushSkip(skip);
......
......@@ -475,6 +475,7 @@ bool Deserializer::ReadData(Object** current, Object** limit, int source_space,
Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(id); \
new_object = isolate->heap()->root(root_index); \
emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
hot_objects_.Add(HeapObject::cast(new_object)); \
} else if (where == kPartialSnapshotCache) { \
int cache_index = source_.GetInt(); \
new_object = isolate->partial_snapshot_cache()->at(cache_index); \
......
......@@ -51,12 +51,16 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
// Replace typed arrays by undefined.
if (obj->IsJSTypedArray()) obj = isolate_->heap()->undefined_value();
if (SerializeHotObject(obj, how_to_code, where_to_point, skip)) return;
int root_index = root_index_map_.Lookup(obj);
if (root_index != RootIndexMap::kInvalidRootIndex) {
PutRoot(root_index, obj, how_to_code, where_to_point, skip);
return;
}
if (SerializeBackReference(obj, how_to_code, where_to_point, skip)) return;
if (ShouldBeInThePartialSnapshotCache(obj)) {
FlushSkip(skip);
......@@ -77,16 +81,16 @@ void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
// Function and object templates are not context specific.
DCHECK(!obj->IsTemplateInfo());
if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
FlushSkip(skip);
// Clear literal boilerplates.
if (obj->IsJSFunction()) {
LiteralsArray* literals = JSFunction::cast(obj)->literals();
JSFunction* function = JSFunction::cast(obj);
LiteralsArray* literals = function->literals();
for (int i = 0; i < literals->literals_count(); i++) {
literals->set_literal_undefined(i);
}
function->ClearTypeFeedbackInfo();
}
// Object has not yet been serialized. Serialize it here.
......
......@@ -140,62 +140,61 @@ bool Serializer::BackReferenceIsAlreadyAllocated(
}
#endif // DEBUG
bool Serializer::SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) {
if (how_to_code == kPlain && where_to_point == kStartOfObject) {
// Encode a reference to a hot object by its index in the working set.
int index = hot_objects_.Find(obj);
if (index != HotObjectsList::kNotFound) {
DCHECK(index >= 0 && index < kNumberOfHotObjects);
if (FLAG_trace_serializer) {
PrintF(" Encoding hot object %d:", index);
obj->ShortPrint();
PrintF("\n");
}
if (skip != 0) {
sink_.Put(kHotObjectWithSkip + index, "HotObjectWithSkip");
sink_.PutInt(skip, "HotObjectSkipDistance");
} else {
sink_.Put(kHotObject + index, "HotObject");
}
return true;
}
bool Serializer::SerializeHotObject(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) {
if (how_to_code != kPlain || where_to_point != kStartOfObject) return false;
// Encode a reference to a hot object by its index in the working set.
int index = hot_objects_.Find(obj);
if (index == HotObjectsList::kNotFound) return false;
DCHECK(index >= 0 && index < kNumberOfHotObjects);
if (FLAG_trace_serializer) {
PrintF(" Encoding hot object %d:", index);
obj->ShortPrint();
PrintF("\n");
}
if (skip != 0) {
sink_.Put(kHotObjectWithSkip + index, "HotObjectWithSkip");
sink_.PutInt(skip, "HotObjectSkipDistance");
} else {
sink_.Put(kHotObject + index, "HotObject");
}
return true;
}
bool Serializer::SerializeBackReference(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) {
SerializerReference reference = reference_map_.Lookup(obj);
if (reference.is_valid()) {
// Encode the location of an already deserialized object in order to write
// its location into a later object. We can encode the location as an
// offset fromthe start of the deserialized objects or as an offset
// backwards from thecurrent allocation pointer.
if (reference.is_attached_reference()) {
FlushSkip(skip);
if (FLAG_trace_serializer) {
PrintF(" Encoding attached reference %d\n",
reference.attached_reference_index());
}
PutAttachedReference(reference, how_to_code, where_to_point);
} else {
DCHECK(reference.is_back_reference());
if (FLAG_trace_serializer) {
PrintF(" Encoding back reference to: ");
obj->ShortPrint();
PrintF("\n");
}
if (!reference.is_valid()) return false;
// Encode the location of an already deserialized object in order to write
// its location into a later object. We can encode the location as an
// offset fromthe start of the deserialized objects or as an offset
// backwards from thecurrent allocation pointer.
if (reference.is_attached_reference()) {
FlushSkip(skip);
if (FLAG_trace_serializer) {
PrintF(" Encoding attached reference %d\n",
reference.attached_reference_index());
}
PutAttachedReference(reference, how_to_code, where_to_point);
} else {
DCHECK(reference.is_back_reference());
if (FLAG_trace_serializer) {
PrintF(" Encoding back reference to: ");
obj->ShortPrint();
PrintF("\n");
}
PutAlignmentPrefix(obj);
AllocationSpace space = reference.space();
if (skip == 0) {
sink_.Put(kBackref + how_to_code + where_to_point + space, "BackRef");
} else {
sink_.Put(kBackrefWithSkip + how_to_code + where_to_point + space,
"BackRefWithSkip");
sink_.PutInt(skip, "BackRefSkipDistance");
}
PutBackReference(obj, reference);
PutAlignmentPrefix(obj);
AllocationSpace space = reference.space();
if (skip == 0) {
sink_.Put(kBackref + how_to_code + where_to_point + space, "BackRef");
} else {
sink_.Put(kBackrefWithSkip + how_to_code + where_to_point + space,
"BackRefWithSkip");
sink_.PutInt(skip, "BackRefSkipDistance");
}
return true;
PutBackReference(obj, reference);
}
return false;
return true;
}
void Serializer::PutRoot(int root_index, HeapObject* object,
......@@ -221,6 +220,7 @@ void Serializer::PutRoot(int root_index, HeapObject* object,
FlushSkip(skip);
sink_.Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
sink_.PutInt(root_index, "root_index");
hot_objects_.Add(object);
}
}
......
......@@ -171,9 +171,13 @@ class Serializer : public SerializerDeserializer {
// Emit alignment prefix if necessary, return required padding space in bytes.
int PutAlignmentPrefix(HeapObject* object);
// Returns true if the object was successfully serialized.
bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip);
// Returns true if the object was successfully serialized as hot object.
bool SerializeHotObject(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip);
// Returns true if the object was successfully serialized as back reference.
bool SerializeBackReference(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip);
inline void FlushSkip(int skip) {
if (skip != 0) {
......
......@@ -50,6 +50,8 @@ void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
}
}
if (SerializeHotObject(obj, how_to_code, where_to_point, skip)) return;
int root_index = root_index_map_.Lookup(obj);
// We can only encode roots as such if it has already been serialized.
// That applies to root indices below the wave front.
......@@ -60,7 +62,7 @@ void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
}
}
if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
if (SerializeBackReference(obj, how_to_code, where_to_point, skip)) return;
FlushSkip(skip);
......
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