OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #include "vm/heap_histogram.h" | |
6 | |
7 #include "platform/assert.h" | |
8 #include "vm/flags.h" | |
9 #include "vm/object.h" | |
10 | |
11 namespace dart { | |
12 | |
13 DEFINE_FLAG(bool, print_object_histogram, false, | |
14 "Print average object histogram at isolate shutdown"); | |
15 | |
16 class ObjectHistogramVisitor : public ObjectVisitor { | |
17 public: | |
18 explicit ObjectHistogramVisitor(Isolate* isolate) : ObjectVisitor(isolate) { } | |
19 | |
20 virtual void VisitObject(RawObject* obj) { | |
21 isolate()->object_histogram()->Add(obj); | |
22 } | |
23 | |
24 private: | |
25 DISALLOW_COPY_AND_ASSIGN(ObjectHistogramVisitor); | |
26 }; | |
27 | |
28 | |
29 void ObjectHistogram::Collect() { | |
30 major_gc_count_++; | |
31 ObjectHistogramVisitor object_visitor(Isolate::Current()); | |
32 isolate_->heap()->IterateObjects(&object_visitor); | |
33 } | |
34 | |
35 | |
36 ObjectHistogram::ObjectHistogram(Isolate* isolate) { | |
37 isolate_ = isolate; | |
38 major_gc_count_ = 0; | |
39 table_length_ = 512; | |
40 table_ = reinterpret_cast<Element*>( | |
41 calloc(table_length_, sizeof(Element))); // NOLINT | |
42 for (int index = 0; index < table_length_; index++) { | |
43 table_[index].class_id = index; | |
44 } | |
45 } | |
46 | |
47 | |
48 ObjectHistogram::~ObjectHistogram() { | |
49 free(table_); | |
50 } | |
51 | |
52 | |
53 void ObjectHistogram::RegisterClass(const Class& cls) { | |
54 int class_id = cls.id(); | |
55 if (class_id < table_length_) return; | |
56 // 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.
| |
57 int new_table_length = table_length_ * 2; | |
58 Element* new_table = reinterpret_cast<Element*>( | |
59 realloc(table_, new_table_length * sizeof(Element))); // NOLINT | |
60 for (int i = table_length_; i < new_table_length; i++) { | |
61 new_table[i].class_id = i; | |
62 new_table[i].count = 0; | |
63 new_table[i].size = 0; | |
64 } | |
65 table_ = new_table; | |
66 table_length_ = new_table_length; | |
67 ASSERT(class_id < table_length_); | |
68 } | |
69 | |
70 | |
71 void ObjectHistogram::Add(RawObject* obj) { | |
72 intptr_t class_id = obj->GetClassId(); | |
73 if (class_id == kFreeListElement) return; | |
74 ASSERT(class_id < table_length_); | |
75 table_[class_id].Add(obj->Size()); | |
76 } | |
77 | |
78 | |
79 int ObjectHistogram::compare(const Element** a, const Element** b) { | |
80 return (*b)->size - (*a)->size; | |
81 } | |
82 | |
83 | |
84 void ObjectHistogram::Print() { | |
85 HandleScope handle_scope(isolate_); | |
86 OS::Print("Printing Object Histogram\n"); | |
87 OS::Print("____bytes___count_description____________\n"); | |
88 // First count the number of non empty entries. | |
89 int length = 0; | |
90 for (int index = 0; index < table_length_; index++) { | |
91 if (table_[index].count > 0) length++; | |
92 } | |
93 // Then add them to a new array and sort. | |
94 Element** array = reinterpret_cast<Element**>( | |
95 calloc(length, sizeof(Element*))); // NOLINT | |
96 int pos = 0; | |
97 for (int index = 0; index < table_length_; index++) { | |
98 if (table_[index].count > 0) array[pos++] = &table_[index]; | |
99 } | |
100 typedef int (*CmpFunc)(const void*, const void*); | |
101 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.
| |
102 | |
103 // Finally print the sorted array. | |
104 Class& cls = Class::Handle(); | |
105 String& str = String::Handle(); | |
106 Library& lib = Library::Handle(); | |
107 for (pos = 0; pos < length; pos++) { | |
108 Element* e = array[pos]; | |
109 if (e->count > 0) { | |
110 cls = isolate_->class_table()->At(e->class_id); | |
111 str = cls.Name(); | |
112 lib = cls.library(); | |
113 OS::Print("%9d %7d ", | |
114 e->size / major_gc_count_, | |
115 e->count / major_gc_count_); | |
116 if (e->class_id < kNumPredefinedCids) { | |
117 OS::Print("`%s`", str.ToCString()); // VM names. | |
118 } else { | |
119 OS::Print("%s", str.ToCString()); | |
120 } | |
121 if (lib.IsNull()) { | |
122 OS::Print("\n"); | |
123 } else { | |
124 str = lib.url(); | |
125 OS::Print(", library \'%s\'\n", str.ToCString()); | |
126 } | |
127 } | |
128 } | |
129 // Deallocate the array for sorting. | |
130 free(array); | |
131 } | |
132 | |
133 } // namespace dart | |
OLD | NEW |