Serializer: collect and output memory statistics.

R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/1086363002

Cr-Commit-Position: refs/heads/master@{#27887}
This commit is contained in:
yangguo 2015-04-16 06:39:21 -07:00 committed by Commit bot
parent da12c7c7c7
commit a2baf44bf6
3 changed files with 83 additions and 0 deletions

View File

@ -732,6 +732,8 @@ DEFINE_INT(hash_seed, 0,
// snapshot-common.cc // snapshot-common.cc
DEFINE_BOOL(profile_deserialization, false, DEFINE_BOOL(profile_deserialization, false,
"Print the time it takes to deserialize the snapshot.") "Print the time it takes to deserialize the snapshot.")
DEFINE_BOOL(serialization_statistics, false,
"Collect statistics on serialized objects.")
// Regexp // Regexp
DEFINE_BOOL(regexp_optimization, true, "generate optimized regexp code") DEFINE_BOOL(regexp_optimization, true, "generate optimized regexp code")

View File

@ -1217,11 +1217,68 @@ Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink)
max_chunk_size_[i] = static_cast<uint32_t>( max_chunk_size_[i] = static_cast<uint32_t>(
MemoryAllocator::PageAreaSize(static_cast<AllocationSpace>(i))); MemoryAllocator::PageAreaSize(static_cast<AllocationSpace>(i)));
} }
#ifdef OBJECT_PRINT
if (FLAG_serialization_statistics) {
instance_type_count_ = NewArray<int>(kInstanceTypes);
instance_type_size_ = NewArray<size_t>(kInstanceTypes);
for (int i = 0; i < kInstanceTypes; i++) {
instance_type_count_[i] = 0;
instance_type_size_[i] = 0;
}
} else {
instance_type_count_ = NULL;
instance_type_size_ = NULL;
}
#endif // OBJECT_PRINT
} }
Serializer::~Serializer() { Serializer::~Serializer() {
if (code_address_map_ != NULL) delete code_address_map_; if (code_address_map_ != NULL) delete code_address_map_;
#ifdef OBJECT_PRINT
if (instance_type_count_ != NULL) {
DeleteArray(instance_type_count_);
DeleteArray(instance_type_size_);
}
#endif // OBJECT_PRINT
}
#ifdef OBJECT_PRINT
void Serializer::CountInstanceType(HeapObject* obj) {
int instance_type = obj->map()->instance_type();
instance_type_count_[instance_type]++;
instance_type_size_[instance_type] += obj->Size();
}
#endif // OBJECT_PRINT
void Serializer::OutputStatistics(const char* name) {
if (!FLAG_serialization_statistics) return;
PrintF("%s:\n", name);
PrintF(" Spaces (bytes):\n");
for (int space = 0; space < kNumberOfSpaces; space++) {
PrintF("%16s", AllocationSpaceName(static_cast<AllocationSpace>(space)));
}
PrintF("\n");
for (int space = 0; space < kNumberOfPreallocatedSpaces; space++) {
size_t s = pending_chunk_[space];
for (uint32_t chunk_size : completed_chunks_[space]) s += chunk_size;
PrintF("%16" V8_PTR_PREFIX "d", s);
}
PrintF("%16d\n", large_objects_total_size_);
#ifdef OBJECT_PRINT
PrintF(" Instance types (count and bytes):\n");
#define PRINT_INSTANCE_TYPE(Name) \
if (instance_type_count_[Name]) { \
PrintF("%10d %10" V8_PTR_PREFIX "d %s\n", instance_type_count_[Name], \
instance_type_size_[Name], #Name); \
}
INSTANCE_TYPE_LIST(PRINT_INSTANCE_TYPE)
#undef PRINT_INSTANCE_TYPE
PrintF("\n");
#endif // OBJECT_PRINT
} }
@ -1637,6 +1694,12 @@ void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
sink_->PutInt(encoded_size, "ObjectSizeInWords"); sink_->PutInt(encoded_size, "ObjectSizeInWords");
} }
#ifdef OBJECT_PRINT
if (FLAG_serialization_statistics) {
serializer_->CountInstanceType(object_);
}
#endif // OBJECT_PRINT
// Mark this object as already serialized. // Mark this object as already serialized.
serializer_->back_reference_map()->Add(object_, back_reference); serializer_->back_reference_map()->Add(object_, back_reference);

View File

@ -617,6 +617,10 @@ class Serializer : public SerializerDeserializer {
BackReferenceMap* back_reference_map() { return &back_reference_map_; } BackReferenceMap* back_reference_map() { return &back_reference_map_; }
RootIndexMap* root_index_map() { return &root_index_map_; } RootIndexMap* root_index_map() { return &root_index_map_; }
#ifdef OBJECT_PRINT
void CountInstanceType(HeapObject* obj);
#endif // OBJECT_PRINT
protected: protected:
class ObjectSerializer : public ObjectVisitor { class ObjectSerializer : public ObjectVisitor {
public: public:
@ -718,6 +722,8 @@ class Serializer : public SerializerDeserializer {
SnapshotByteSink* sink() const { return sink_; } SnapshotByteSink* sink() const { return sink_; }
void OutputStatistics(const char* name);
Isolate* isolate_; Isolate* isolate_;
SnapshotByteSink* sink_; SnapshotByteSink* sink_;
@ -746,6 +752,12 @@ class Serializer : public SerializerDeserializer {
List<byte> code_buffer_; List<byte> code_buffer_;
#ifdef OBJECT_PRINT
static const int kInstanceTypes = 256;
int* instance_type_count_;
size_t* instance_type_size_;
#endif // OBJECT_PRINT
DISALLOW_COPY_AND_ASSIGN(Serializer); DISALLOW_COPY_AND_ASSIGN(Serializer);
}; };
@ -761,6 +773,8 @@ class PartialSerializer : public Serializer {
InitializeCodeAddressMap(); InitializeCodeAddressMap();
} }
~PartialSerializer() { OutputStatistics("PartialSerializer"); }
// Serialize the objects reachable from a single object pointer. // Serialize the objects reachable from a single object pointer.
void Serialize(Object** o); void Serialize(Object** o);
virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
@ -803,6 +817,8 @@ class StartupSerializer : public Serializer {
InitializeCodeAddressMap(); InitializeCodeAddressMap();
} }
~StartupSerializer() { OutputStatistics("StartupSerializer"); }
// The StartupSerializer has to serialize the root array, which is slightly // The StartupSerializer has to serialize the root array, which is slightly
// different. // different.
void VisitPointers(Object** start, Object** end) OVERRIDE; void VisitPointers(Object** start, Object** end) OVERRIDE;
@ -859,6 +875,8 @@ class CodeSerializer : public Serializer {
back_reference_map_.AddSourceString(source); back_reference_map_.AddSourceString(source);
} }
~CodeSerializer() { OutputStatistics("CodeSerializer"); }
virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) OVERRIDE; WhereToPoint where_to_point, int skip) OVERRIDE;