Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: runtime/vm/heap_histogram.cc

Issue 19870006: Support stacktrace and objecthistogram service commands (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/heap_histogram.h ('k') | runtime/vm/isolate.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/heap_histogram.h" 5 #include "vm/heap_histogram.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/object.h" 9 #include "vm/object.h"
10 #include "vm/json_stream.h"
10 11
11 namespace dart { 12 namespace dart {
12 13
13 DEFINE_FLAG(bool, print_object_histogram, false, 14 DEFINE_FLAG(bool, print_object_histogram, false,
14 "Print average object histogram at isolate shutdown"); 15 "Print average object histogram at isolate shutdown");
15 16
16 class ObjectHistogramVisitor : public ObjectVisitor { 17 class ObjectHistogramVisitor : public ObjectVisitor {
17 public: 18 public:
18 explicit ObjectHistogramVisitor(Isolate* isolate) : ObjectVisitor(isolate) { } 19 explicit ObjectHistogramVisitor(Isolate* isolate) : ObjectVisitor(isolate) { }
19 20
(...skipping 11 matching lines...) Expand all
31 ObjectHistogramVisitor object_visitor(isolate_); 32 ObjectHistogramVisitor object_visitor(isolate_);
32 isolate_->heap()->IterateObjects(&object_visitor); 33 isolate_->heap()->IterateObjects(&object_visitor);
33 } 34 }
34 35
35 36
36 ObjectHistogram::ObjectHistogram(Isolate* isolate) { 37 ObjectHistogram::ObjectHistogram(Isolate* isolate) {
37 isolate_ = isolate; 38 isolate_ = isolate;
38 major_gc_count_ = 0; 39 major_gc_count_ = 0;
39 table_length_ = 512; 40 table_length_ = 512;
40 table_ = reinterpret_cast<Element*>( 41 table_ = reinterpret_cast<Element*>(
41 calloc(table_length_, sizeof(Element))); // NOLINT 42 calloc(table_length_, sizeof(Element))); // NOLINT
42 for (int index = 0; index < table_length_; index++) { 43 for (intptr_t index = 0; index < table_length_; index++) {
43 table_[index].class_id_ = index; 44 table_[index].class_id_ = index;
44 } 45 }
45 } 46 }
46 47
47 48
48 ObjectHistogram::~ObjectHistogram() { 49 ObjectHistogram::~ObjectHistogram() {
49 free(table_); 50 free(table_);
50 } 51 }
51 52
52 53
53 void ObjectHistogram::RegisterClass(const Class& cls) { 54 void ObjectHistogram::RegisterClass(const Class& cls) {
54 int class_id = cls.id(); 55 intptr_t class_id = cls.id();
55 if (class_id < table_length_) return; 56 if (class_id < table_length_) return;
56 // Resize the table. 57 // Resize the table.
57 int new_table_length = table_length_ * 2; 58 intptr_t new_table_length = table_length_ * 2;
58 Element* new_table = reinterpret_cast<Element*>( 59 Element* new_table = reinterpret_cast<Element*>(
59 realloc(table_, new_table_length * sizeof(Element))); // NOLINT 60 realloc(table_, new_table_length * sizeof(Element))); // NOLINT
60 for (int i = table_length_; i < new_table_length; i++) { 61 for (intptr_t i = table_length_; i < new_table_length; i++) {
61 new_table[i].class_id_ = i; 62 new_table[i].class_id_ = i;
62 new_table[i].count_ = 0; 63 new_table[i].count_ = 0;
63 new_table[i].size_ = 0; 64 new_table[i].size_ = 0;
64 } 65 }
65 table_ = new_table; 66 table_ = new_table;
66 table_length_ = new_table_length; 67 table_length_ = new_table_length;
67 ASSERT(class_id < table_length_); 68 ASSERT(class_id < table_length_);
68 } 69 }
69 70
70 71
71 void ObjectHistogram::Add(RawObject* obj) { 72 void ObjectHistogram::Add(RawObject* obj) {
72 intptr_t class_id = obj->GetClassId(); 73 intptr_t class_id = obj->GetClassId();
73 if (class_id == kFreeListElement) return; 74 if (class_id == kFreeListElement) return;
74 ASSERT(class_id < table_length_); 75 ASSERT(class_id < table_length_);
75 table_[class_id].Add(obj->Size()); 76 table_[class_id].Add(obj->Size());
76 } 77 }
77 78
78 79
79 int ObjectHistogram::compare(const Element** a, const Element** b) { 80 int ObjectHistogram::compare(const Element** a, const Element** b) {
80 return (*b)->size_ - (*a)->size_; 81 return (*b)->size_ - (*a)->size_;
81 } 82 }
82 83
83 84
84 void ObjectHistogram::Print() { 85 ObjectHistogram::Element** ObjectHistogram::GetSortedArray(
85 OS::Print("Printing Object Histogram\n"); 86 intptr_t* array_length) {
86 OS::Print("____bytes___count_description____________\n"); 87 intptr_t length = 0;
87 // First count the number of non empty entries. 88 for (intptr_t index = 0; index < table_length_; index++) {
88 int length = 0;
89 for (int index = 0; index < table_length_; index++) {
90 if (table_[index].count_ > 0) length++; 89 if (table_[index].count_ > 0) length++;
91 } 90 }
92 // Then add them to a new array and sort. 91 // Then add them to a new array and sort.
93 Element** array = reinterpret_cast<Element**>( 92 Element** array = reinterpret_cast<Element**>(
94 calloc(length, sizeof(Element*))); // NOLINT 93 calloc(length, sizeof(Element*))); // NOLINT
95 int pos = 0; 94 intptr_t pos = 0;
96 for (int index = 0; index < table_length_; index++) { 95 for (intptr_t index = 0; index < table_length_; index++) {
97 if (table_[index].count_ > 0) array[pos++] = &table_[index]; 96 if (table_[index].count_ > 0) array[pos++] = &table_[index];
98 } 97 }
99 typedef int (*CmpFunc)(const void*, const void*); 98 typedef int (*CmpFunc)(const void*, const void*);
100 qsort(array, length, sizeof(Element*), // NOLINT 99 qsort(array, length, sizeof(Element*), // NOLINT
101 reinterpret_cast<CmpFunc>(compare)); 100 reinterpret_cast<CmpFunc>(compare));
102 101
102 *array_length = length;
103 return array;
104 }
105
106 void ObjectHistogram::Print() {
107 OS::Print("Printing Object Histogram\n");
108 OS::Print("____bytes___count_description____________\n");
109 // First count the number of non empty entries.
110
111 intptr_t length = 0;
112 Element** array = NULL;
113
114 array = GetSortedArray(&length);
115 ASSERT(array != NULL);
116
103 // Finally print the sorted array. 117 // Finally print the sorted array.
104 Class& cls = Class::Handle(); 118 Class& cls = Class::Handle();
105 String& str = String::Handle(); 119 String& str = String::Handle();
106 Library& lib = Library::Handle(); 120 Library& lib = Library::Handle();
107 for (pos = 0; pos < length; pos++) { 121 for (intptr_t pos = 0; pos < length; pos++) {
108 Element* e = array[pos]; 122 Element* e = array[pos];
109 if (e->count_ > 0) { 123 if (e->count_ > 0) {
110 cls = isolate_->class_table()->At(e->class_id_); 124 cls = isolate_->class_table()->At(e->class_id_);
111 str = cls.Name(); 125 str = cls.Name();
112 lib = cls.library(); 126 lib = cls.library();
113 OS::Print("%9"Pd" %7"Pd" ", 127 OS::Print("%9"Pd" %7"Pd" ",
114 e->size_ / major_gc_count_, 128 e->size_ / major_gc_count_,
115 e->count_ / major_gc_count_); 129 e->count_ / major_gc_count_);
116 if (e->class_id_ < kInstanceCid) { 130 if (e->class_id_ < kInstanceCid) {
117 OS::Print("`%s`", str.ToCString()); // VM names. 131 OS::Print("`%s`", str.ToCString()); // VM names.
118 } else { 132 } else {
119 OS::Print("%s", str.ToCString()); 133 OS::Print("%s", str.ToCString());
120 } 134 }
121 if (lib.IsNull()) { 135 if (lib.IsNull()) {
122 OS::Print("\n"); 136 OS::Print("\n");
123 } else { 137 } else {
124 str = lib.url(); 138 str = lib.url();
125 OS::Print(", library \'%s\'\n", str.ToCString()); 139 OS::Print(", library \'%s\'\n", str.ToCString());
126 } 140 }
127 } 141 }
128 } 142 }
129 // Deallocate the array for sorting. 143 // Deallocate the array for sorting.
130 free(array); 144 free(array);
131 } 145 }
132 146
147 void ObjectHistogram::PrintToJSONStream(JSONStream* stream) {
148 intptr_t length = 0;
149 Element** array = NULL;
150
151 array = GetSortedArray(&length);
152 ASSERT(array != NULL);
153
154 // Finally print the sorted array.
155 Class& cls = Class::Handle();
156 String& str = String::Handle();
157 Library& lib = Library::Handle();
158
159 intptr_t size_sum = 0;
160 intptr_t count_sum = 0;
161 stream->OpenObject();
162 stream->PrintProperty("type", "ObjectHistogram");
163 stream->OpenArray("properties");
164 stream->PrintValue("size");
165 stream->PrintValue("count");
166 stream->CloseArray();
167 stream->OpenArray("members");
168 for (intptr_t pos = 0; pos < length; pos++) {
169 Element* e = array[pos];
170 if (e->count_ > 0) {
171 cls = isolate_->class_table()->At(e->class_id_);
172 str = cls.Name();
173 lib = cls.library();
174 stream->OpenObject();
175 stream->PrintProperty("type", "ObjectHistogramEntry");
176 // It should not be possible to overflow here because the total
177 // size of the heap is bounded and we are dividing the value
178 // by the number of major gcs that have occurred.
179 size_sum += (e->size_ / major_gc_count_);
180 count_sum += (e->count_ / major_gc_count_);
181 stream->PrintProperty("size", e->size_ / major_gc_count_);
182 stream->PrintProperty("count", e->count_ / major_gc_count_);
183 stream->PrintProperty("name", str.ToCString());
184 if (lib.IsNull()) {
185 stream->PrintProperty("category", "");
186 } else {
187 str = lib.url();
188 stream->PrintProperty("category", str.ToCString());
189 }
190 stream->CloseObject();
191 }
192 }
193 stream->CloseArray();
194 stream->OpenObject("sums");
195 stream->PrintProperty("size", size_sum);
196 stream->PrintProperty("count", count_sum);
197 stream->CloseObject();
198 stream->CloseObject();
199
200 // Deallocate the array for sorting.
201 free(array);
202 }
203
204
133 } // namespace dart 205 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/heap_histogram.h ('k') | runtime/vm/isolate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698