[vm] Include the content of image pages into --print-snapshot-sizes-verbose.

E.g.,
             Cluster   Objs     Size Fraction Cumulative
    (RO)Instructions      0 11465312 0.500079 0.500079
        (RO)StackMap  97579  3525312 0.153763 0.653842
   (RO)CodeSourceMap  22358  1752087 0.076420 0.730262
   (RO)OneByteString  30427  1644273 0.071718 0.801980
          ObjectPool  27233  1077927 0.047016 0.848995
               Array  25995  1029434 0.044901 0.893896
            Function  36468   924984 0.040345 0.934241
                Code  35686   782093 0.034112 0.968353
               Class   4026   177417 0.007738 0.976091
           TypedData  33768   125511 0.005474 0.981566
                 ...

Change-Id: I9f1e45ce85df6a4509f6d9fb2c28b41157872941
Reviewed-on: https://dart-review.googlesource.com/20262
Reviewed-by: Siva Chandra <sivachandra@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2017-11-11 00:19:18 +00:00 committed by commit-bot@chromium.org
parent 7686dce346
commit cbb7cb360b
4 changed files with 91 additions and 41 deletions

View file

@ -47,10 +47,13 @@ void Deserializer::InitializeHeader(RawObject* raw,
}
void SerializationCluster::WriteAndMeasureAlloc(Serializer* serializer) {
intptr_t start = serializer->bytes_written();
intptr_t start_size = serializer->bytes_written() + serializer->GetDataSize();
intptr_t start_objects = serializer->next_ref_index();
WriteAlloc(serializer);
intptr_t stop = serializer->bytes_written();
size_ += (stop - start);
intptr_t stop_size = serializer->bytes_written() + serializer->GetDataSize();
intptr_t stop_objects = serializer->next_ref_index();
size_ += (stop_size - start_size);
num_objects_ += (stop_objects - start_objects);
}
void SerializationCluster::WriteAndMeasureFill(Serializer* serializer) {
@ -2028,8 +2031,8 @@ class ObjectPoolDeserializationCluster : public DeserializationCluster {
// PcDescriptor, StackMap, OneByteString, TwoByteString
class RODataSerializationCluster : public SerializationCluster {
public:
explicit RODataSerializationCluster(intptr_t cid)
: SerializationCluster("ROData"), cid_(cid) {}
RODataSerializationCluster(const char* name, intptr_t cid)
: SerializationCluster(name), cid_(cid) {}
virtual ~RODataSerializationCluster() {}
void Trace(Serializer* s, RawObject* object) {
@ -4564,6 +4567,21 @@ class TwoByteStringDeserializationCluster : public DeserializationCluster {
}
};
#if !defined(DART_PRECOMPILED_RUNTIME)
class FakeSerializationCluster : public SerializationCluster {
public:
explicit FakeSerializationCluster(const char* name, intptr_t size)
: SerializationCluster(name) {
size_ = size;
}
virtual ~FakeSerializationCluster() {}
void Trace(Serializer* s, RawObject* object) { UNREACHABLE(); }
void WriteAlloc(Serializer* s) { UNREACHABLE(); }
void WriteFill(Serializer* s) { UNREACHABLE(); }
};
#endif // !DART_PRECOMPILED_RUNTIME
Serializer::Serializer(Thread* thread,
Snapshot::Kind kind,
uint8_t** buffer,
@ -4653,11 +4671,13 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
case kObjectPoolCid:
return new (Z) ObjectPoolSerializationCluster();
case kPcDescriptorsCid:
return new (Z) RODataSerializationCluster(kPcDescriptorsCid);
return new (Z)
RODataSerializationCluster("(RO)PcDescriptors", kPcDescriptorsCid);
case kCodeSourceMapCid:
return new (Z) RODataSerializationCluster(kCodeSourceMapCid);
return new (Z)
RODataSerializationCluster("(RO)CodeSourceMap", kCodeSourceMapCid);
case kStackMapCid:
return new (Z) RODataSerializationCluster(kStackMapCid);
return new (Z) RODataSerializationCluster("(RO)StackMap", kStackMapCid);
case kExceptionHandlersCid:
return new (Z) ExceptionHandlersSerializationCluster();
case kContextCid:
@ -4710,14 +4730,16 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
return new (Z) ArraySerializationCluster(kImmutableArrayCid);
case kOneByteStringCid: {
if (Snapshot::IncludesCode(kind_)) {
return new (Z) RODataSerializationCluster(kOneByteStringCid);
return new (Z)
RODataSerializationCluster("(RO)OneByteString", kOneByteStringCid);
} else {
return new (Z) OneByteStringSerializationCluster();
}
}
case kTwoByteStringCid: {
if (Snapshot::IncludesCode(kind_)) {
return new (Z) RODataSerializationCluster(kTwoByteStringCid);
return new (Z)
RODataSerializationCluster("(RO)TwoByteString", kTwoByteStringCid);
} else {
return new (Z) TwoByteStringSerializationCluster();
}
@ -4746,6 +4768,20 @@ int32_t Serializer::GetDataOffset(RawObject* object) const {
return image_writer_->GetDataOffsetFor(object);
}
intptr_t Serializer::GetDataSize() const {
if (image_writer_ == NULL) {
return 0;
}
return image_writer_->data_size();
}
intptr_t Serializer::GetTextSize() const {
if (image_writer_ == NULL) {
return 0;
}
return image_writer_->text_size();
}
void Serializer::Push(RawObject* object) {
if (!object->IsHeapObject()) {
RawSmi* smi = Smi::RawCast(object);
@ -4860,6 +4896,7 @@ void Serializer::WriteVersionAndFeatures() {
static const int32_t kSectionMarker = 0xABAB;
#endif
#if !defined(DART_PRECOMPILED_RUNTIME)
static int CompareClusters(SerializationCluster* const* a,
SerializationCluster* const* b) {
if ((*a)->size() > (*b)->size()) {
@ -4870,6 +4907,7 @@ static int CompareClusters(SerializationCluster* const* a,
return 0;
}
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
void Serializer::Serialize() {
while (stack_.length() > 0) {
@ -4918,8 +4956,9 @@ void Serializer::Serialize() {
}
}
#if !defined(DART_PRECOMPILED_RUNTIME)
if (FLAG_print_snapshot_sizes_verbose) {
OS::Print(" Cluster Size Fraction Cumulative\n");
OS::Print(" Cluster Objs Size Fraction Cumulative\n");
GrowableArray<SerializationCluster*> clusters_by_size;
for (intptr_t cid = 1; cid < num_cids_; cid++) {
SerializationCluster* cluster = clusters_by_cid_[cid];
@ -4927,17 +4966,24 @@ void Serializer::Serialize() {
clusters_by_size.Add(cluster);
}
}
if (GetTextSize() != 0) {
clusters_by_size.Add(new (zone_) FakeSerializationCluster(
"(RO)Instructions", GetTextSize()));
}
clusters_by_size.Sort(CompareClusters);
double total_size = static_cast<double>(bytes_written());
double total_size =
static_cast<double>(bytes_written() + GetDataSize() + GetTextSize());
double cumulative_fraction = 0.0;
for (intptr_t i = 0; i < clusters_by_size.length(); i++) {
SerializationCluster* cluster = clusters_by_size[i];
double fraction = static_cast<double>(cluster->size()) / total_size;
cumulative_fraction += fraction;
OS::Print("%20s %8" Pd " %lf %lf\n", cluster->name(), cluster->size(),
fraction, cumulative_fraction);
OS::Print("%20s %6" Pd " %8" Pd " %lf %lf\n", cluster->name(),
cluster->num_objects(), cluster->size(), fraction,
cumulative_fraction);
}
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
void Serializer::AddVMIsolateBaseObjects() {
@ -5579,7 +5625,7 @@ FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind,
clustered_vm_size_(0),
clustered_isolate_size_(0),
mapped_data_size_(0),
mapped_instructions_size_(0) {
mapped_text_size_(0) {
ASSERT(alloc_ != NULL);
ASSERT(isolate() != NULL);
ASSERT(heap() != NULL);
@ -5658,7 +5704,7 @@ intptr_t FullSnapshotWriter::WriteVMSnapshot() {
if (Snapshot::IncludesCode(kind_)) {
vm_image_writer_->Write(serializer.stream(), true);
mapped_data_size_ += vm_image_writer_->data_size();
mapped_instructions_size_ += vm_image_writer_->text_size();
mapped_text_size_ += vm_image_writer_->text_size();
vm_image_writer_->ResetOffsets();
}
@ -5687,7 +5733,7 @@ void FullSnapshotWriter::WriteIsolateSnapshot(intptr_t num_base_objects) {
if (Snapshot::IncludesCode(kind_)) {
isolate_image_writer_->Write(serializer.stream(), false);
mapped_data_size_ += isolate_image_writer_->data_size();
mapped_instructions_size_ += isolate_image_writer_->text_size();
mapped_text_size_ += isolate_image_writer_->text_size();
isolate_image_writer_->ResetOffsets();
}
@ -5712,10 +5758,10 @@ void FullSnapshotWriter::WriteFullSnapshot() {
OS::Print("VMIsolate(CodeSize): %" Pd "\n", clustered_vm_size_);
OS::Print("Isolate(CodeSize): %" Pd "\n", clustered_isolate_size_);
OS::Print("ReadOnlyData(CodeSize): %" Pd "\n", mapped_data_size_);
OS::Print("Instructions(CodeSize): %" Pd "\n", mapped_instructions_size_);
OS::Print("Instructions(CodeSize): %" Pd "\n", mapped_text_size_);
OS::Print("Total(CodeSize): %" Pd "\n",
clustered_vm_size_ + clustered_isolate_size_ + mapped_data_size_ +
mapped_instructions_size_);
mapped_text_size_);
}
}

View file

@ -49,7 +49,8 @@ class ImageReader;
class SerializationCluster : public ZoneAllocated {
public:
explicit SerializationCluster(const char* name) : name_(name), size_(0) {}
explicit SerializationCluster(const char* name)
: name_(name), size_(0), num_objects_(0) {}
virtual ~SerializationCluster() {}
// Add [object] to the cluster and push its outgoing references.
@ -68,10 +69,12 @@ class SerializationCluster : public ZoneAllocated {
const char* name() const { return name_; }
intptr_t size() const { return size_; }
intptr_t num_objects() const { return num_objects_; }
private:
protected:
const char* name_;
intptr_t size_;
intptr_t num_objects_;
};
class DeserializationCluster : public ZoneAllocated {
@ -251,8 +254,11 @@ class Serializer : public StackResource {
int32_t GetTextOffset(RawInstructions* instr, RawCode* code) const;
int32_t GetDataOffset(RawObject* object) const;
intptr_t GetDataSize() const;
intptr_t GetTextSize() const;
Snapshot::Kind kind() const { return kind_; }
intptr_t next_ref_index() const { return next_ref_index_; }
private:
Heap* heap_;
@ -424,7 +430,7 @@ class FullSnapshotWriter {
intptr_t clustered_vm_size_;
intptr_t clustered_isolate_size_;
intptr_t mapped_data_size_;
intptr_t mapped_instructions_size_;
intptr_t mapped_text_size_;
DISALLOW_COPY_AND_ASSIGN(FullSnapshotWriter);
};

View file

@ -16,16 +16,16 @@ namespace dart {
int32_t ImageWriter::GetTextOffsetFor(RawInstructions* instructions,
RawCode* code) {
intptr_t heap_size = instructions->Size();
intptr_t offset = next_offset_;
next_offset_ += heap_size;
intptr_t offset = next_text_offset_;
next_text_offset_ += heap_size;
instructions_.Add(InstructionsData(instructions, code, offset));
return offset;
}
int32_t ImageWriter::GetDataOffsetFor(RawObject* raw_object) {
intptr_t heap_size = raw_object->Size();
intptr_t offset = next_object_offset_;
next_object_offset_ += heap_size;
intptr_t offset = next_data_offset_;
next_data_offset_ += heap_size;
objects_.Add(ObjectData(raw_object));
return offset;
}
@ -66,7 +66,7 @@ void ImageWriter::WriteROData(WriteStream* stream) {
// Heap page starts here.
stream->WriteWord(next_object_offset_); // Data length.
stream->WriteWord(next_data_offset_); // Data length.
COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment);
stream->Align(OS::kMaxPreferredCodeAlignment);
@ -100,7 +100,6 @@ AssemblyImageWriter::AssemblyImageWriter(uint8_t** assembly_buffer,
intptr_t initial_size)
: ImageWriter(),
assembly_stream_(assembly_buffer, alloc, initial_size),
text_size_(0),
dwarf_(NULL) {
#if defined(DART_PRECOMPILER)
Zone* zone = Thread::Current()->zone();
@ -139,7 +138,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
// This head also provides the gap to make the instructions snapshot
// look like a HeapPage.
intptr_t instructions_length = next_offset_;
intptr_t instructions_length = next_text_offset_;
WriteWordLiteralText(instructions_length);
intptr_t header_words = Image::kHeaderSize / sizeof(uword);
for (intptr_t i = 1; i < header_words; i++) {
@ -332,7 +331,7 @@ void AssemblyImageWriter::WriteByteSequence(uword start, uword end) {
void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
// This header provides the gap to make the instructions snapshot look like a
// HeapPage.
intptr_t instructions_length = next_offset_;
intptr_t instructions_length = next_text_offset_;
instructions_blob_stream_.WriteWord(instructions_length);
intptr_t header_words = Image::kHeaderSize / sizeof(uword);
for (intptr_t i = 1; i < header_words; i++) {

View file

@ -64,14 +64,17 @@ class ImageReader : public ZoneAllocated {
class ImageWriter : public ZoneAllocated {
public:
ImageWriter()
: next_offset_(0), next_object_offset_(0), instructions_(), objects_() {
: next_text_offset_(0),
next_data_offset_(0),
instructions_(),
objects_() {
ResetOffsets();
}
virtual ~ImageWriter() {}
void ResetOffsets() {
next_offset_ = Image::kHeaderSize;
next_object_offset_ = Image::kHeaderSize;
next_text_offset_ = Image::kHeaderSize;
next_data_offset_ = Image::kHeaderSize;
instructions_.Clear();
objects_.Clear();
}
@ -79,8 +82,8 @@ class ImageWriter : public ZoneAllocated {
int32_t GetDataOffsetFor(RawObject* raw_object);
void Write(WriteStream* clustered_stream, bool vm);
virtual intptr_t text_size() const = 0;
intptr_t data_size() const { return next_object_offset_; }
intptr_t text_size() const { return next_text_offset_; }
intptr_t data_size() const { return next_data_offset_; }
protected:
void WriteROData(WriteStream* stream);
@ -112,8 +115,8 @@ class ImageWriter : public ZoneAllocated {
};
};
intptr_t next_offset_;
intptr_t next_object_offset_;
intptr_t next_text_offset_;
intptr_t next_data_offset_;
GrowableArray<InstructionsData> instructions_;
GrowableArray<ObjectData> objects_;
@ -129,7 +132,6 @@ class AssemblyImageWriter : public ImageWriter {
void Finalize();
virtual void WriteText(WriteStream* clustered_stream, bool vm);
virtual intptr_t text_size() const { return text_size_; }
intptr_t AssemblySize() const { return assembly_stream_.bytes_written(); }
@ -144,11 +146,9 @@ class AssemblyImageWriter : public ImageWriter {
#else
assembly_stream_.Print(".long 0x%0.8" Px "\n", value);
#endif
text_size_ += sizeof(value);
}
WriteStream assembly_stream_;
intptr_t text_size_;
Dwarf* dwarf_;
DISALLOW_COPY_AND_ASSIGN(AssemblyImageWriter);
@ -165,7 +165,6 @@ class BlobImageWriter : public ImageWriter {
initial_size) {}
virtual void WriteText(WriteStream* clustered_stream, bool vm);
virtual intptr_t text_size() const { return InstructionsBlobSize(); }
intptr_t InstructionsBlobSize() const {
return instructions_blob_stream_.bytes_written();