Chromium Code Reviews| Index: runtime/vm/heap_histogram.cc |
| =================================================================== |
| --- runtime/vm/heap_histogram.cc (revision 0) |
| +++ runtime/vm/heap_histogram.cc (revision 0) |
| @@ -0,0 +1,133 @@ |
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +#include "vm/heap_histogram.h" |
| + |
| +#include "platform/assert.h" |
| +#include "vm/flags.h" |
| +#include "vm/object.h" |
| + |
| +namespace dart { |
| + |
| +DEFINE_FLAG(bool, print_object_histogram, false, |
| + "Print average object histogram at isolate shutdown"); |
| + |
| +class ObjectHistogramVisitor : public ObjectVisitor { |
| + public: |
| + explicit ObjectHistogramVisitor(Isolate* isolate) : ObjectVisitor(isolate) { } |
| + |
| + virtual void VisitObject(RawObject* obj) { |
| + isolate()->object_histogram()->Add(obj); |
| + } |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(ObjectHistogramVisitor); |
| +}; |
| + |
| + |
| +void ObjectHistogram::Collect() { |
| + major_gc_count_++; |
| + ObjectHistogramVisitor object_visitor(Isolate::Current()); |
| + isolate_->heap()->IterateObjects(&object_visitor); |
| +} |
| + |
| + |
| +ObjectHistogram::ObjectHistogram(Isolate* isolate) { |
| + isolate_ = isolate; |
| + major_gc_count_ = 0; |
| + table_length_ = 512; |
| + table_ = reinterpret_cast<Element*>( |
| + calloc(table_length_, sizeof(Element))); // NOLINT |
| + for (int index = 0; index < table_length_; index++) { |
| + table_[index].class_id = index; |
| + } |
| +} |
| + |
| + |
| +ObjectHistogram::~ObjectHistogram() { |
| + free(table_); |
| +} |
| + |
| + |
| +void ObjectHistogram::RegisterClass(const Class& cls) { |
| + int class_id = cls.id(); |
| + if (class_id < table_length_) return; |
| + // resize the table. |
|
ahe
2013/06/12 11:24:01
Make proper sentence: start with uppercase letter.
bakster
2013/06/12 11:34:21
Done.
|
| + int new_table_length = table_length_ * 2; |
| + Element* new_table = reinterpret_cast<Element*>( |
| + realloc(table_, new_table_length * sizeof(Element))); // NOLINT |
| + for (int i = table_length_; i < new_table_length; i++) { |
| + new_table[i].class_id = i; |
| + new_table[i].count = 0; |
| + new_table[i].size = 0; |
| + } |
| + table_ = new_table; |
| + table_length_ = new_table_length; |
| + ASSERT(class_id < table_length_); |
| +} |
| + |
| + |
| +void ObjectHistogram::Add(RawObject* obj) { |
| + intptr_t class_id = obj->GetClassId(); |
| + if (class_id == kFreeListElement) return; |
| + ASSERT(class_id < table_length_); |
| + table_[class_id].Add(obj->Size()); |
| +} |
| + |
| + |
| +int ObjectHistogram::compare(const Element** a, const Element** b) { |
| + return (*b)->size - (*a)->size; |
| +} |
| + |
| + |
| +void ObjectHistogram::Print() { |
| + HandleScope handle_scope(isolate_); |
| + OS::Print("Printing Object Histogram\n"); |
| + OS::Print("____bytes___count_description____________\n"); |
| + // First count the number of non empty entries. |
| + int length = 0; |
| + for (int index = 0; index < table_length_; index++) { |
| + if (table_[index].count > 0) length++; |
| + } |
| + // Then add them to a new array and sort. |
| + Element** array = reinterpret_cast<Element**>( |
| + calloc(length, sizeof(Element*))); // NOLINT |
| + int pos = 0; |
| + for (int index = 0; index < table_length_; index++) { |
| + if (table_[index].count > 0) array[pos++] = &table_[index]; |
| + } |
| + typedef int (*CmpFunc)(const void*, const void*); |
| + qsort(array, length, sizeof(Element*), reinterpret_cast<CmpFunc>(compare)); // NOLINT |
|
ahe
2013/06/12 11:24:01
Long line.
bakster
2013/06/12 11:34:21
Done.
bakster
2013/06/12 11:34:21
Done.
|
| + |
| + // Finally print the sorted array. |
| + Class& cls = Class::Handle(); |
| + String& str = String::Handle(); |
| + Library& lib = Library::Handle(); |
| + for (pos = 0; pos < length; pos++) { |
| + Element* e = array[pos]; |
| + if (e->count > 0) { |
| + cls = isolate_->class_table()->At(e->class_id); |
| + str = cls.Name(); |
| + lib = cls.library(); |
| + OS::Print("%9d %7d ", |
| + e->size / major_gc_count_, |
| + e->count / major_gc_count_); |
| + if (e->class_id < kNumPredefinedCids) { |
| + OS::Print("`%s`", str.ToCString()); // VM names. |
| + } else { |
| + OS::Print("%s", str.ToCString()); |
| + } |
| + if (lib.IsNull()) { |
| + OS::Print("\n"); |
| + } else { |
| + str = lib.url(); |
| + OS::Print(", library \'%s\'\n", str.ToCString()); |
| + } |
| + } |
| + } |
| + // Deallocate the array for sorting. |
| + free(array); |
| +} |
| + |
| +} // namespace dart |