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