Index: runtime/vm/heap_class_stats.cc |
diff --git a/runtime/vm/heap_class_stats.cc b/runtime/vm/heap_class_stats.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..97ef88b9721cd9ebda9d02798188b5f5932ece68 |
--- /dev/null |
+++ b/runtime/vm/heap_class_stats.cc |
@@ -0,0 +1,117 @@ |
+// 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 "platform/assert.h" |
+#include "vm/object.h" |
+#include "vm/heap_class_stats.h" |
+ |
+namespace dart { |
+ |
+class HeapClassStatsVisitor : public ObjectVisitor { |
+ public: |
+ explicit HeapClassStatsVisitor(Isolate* isolate) : ObjectVisitor(isolate) { } |
+ |
+ virtual void VisitObject(RawObject* obj) { |
+ intptr_t cid = obj->GetClassId(); |
+ if (!obj->IsHeapObject()) { |
+ return; |
+ } |
+ bool new_space = obj->IsNewObject(); |
+ HeapClassStatistics* heap_class_stats = isolate()->heap_class_stats(); |
+ if (new_space) { |
+ heap_class_stats->ReportLiveNewSpace(cid); |
+ } else { |
+ heap_class_stats->ReportLiveOldSpace(cid); |
+ } |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(HeapClassStatsVisitor); |
+}; |
+ |
+ |
+HeapClassStatistics::HeapClassStatistics(Isolate* isolate) : isolate_(isolate) { |
+ class_table_size_ = 512; |
+ class_table_ = reinterpret_cast<HeapClassData*>( |
+ calloc(class_table_size_, sizeof(HeapClassData))); // NOLINT |
+} |
+ |
+ |
+HeapClassStatistics::~HeapClassStatistics() { |
+ free(class_table_); |
+} |
+ |
+ |
+void HeapClassStatistics::RegisterClass(const Class& cls) { |
+ intptr_t cid = cls.id(); |
+ if (cid < class_table_size_) { |
+ // Already have room. |
+ return; |
+ } |
+ // Resize the table. |
+ const intptr_t new_class_table_size = class_table_size_ * 2; |
+ HeapClassData* new_class_table = reinterpret_cast<HeapClassData*>( |
+ realloc(class_table_, |
+ new_class_table_size * sizeof(HeapClassData))); // NOLINT |
+ for (intptr_t i = class_table_size_; i < new_class_table_size; i++) { |
+ new_class_table[i].live_old_space = 0; |
+ new_class_table[i].live_new_space = 0; |
+ new_class_table[i].allocated_since_gc = 0; |
+ } |
+ class_table_ = new_class_table; |
+ class_table_size_ = new_class_table_size; |
+ ASSERT(cid < class_table_size_); |
+} |
+ |
+ |
+void HeapClassStatistics::AllocateClass(intptr_t cid) { |
+ ASSERT(cid < class_table_size_); |
+ class_table_[cid].allocated_since_gc++; |
+} |
+ |
+ |
+void HeapClassStatistics::Collect() { |
+ HeapClassStatsVisitor visitor(isolate_); |
+ // debugging. |
+ for (intptr_t i = 0; i < class_table_size_; i++) { |
+ break; |
+ const HeapClassData& data = class_table_[i]; |
+ if ((data.live_old_space == 0) && (data.live_new_space == 0) && |
+ (data.allocated_since_gc == 0)) { |
+ continue; |
+ } |
+ printf("%ld %ld %ld %ld\n", i, data.live_old_space, data.live_new_space, |
+ data.allocated_since_gc); |
+ } |
+ ResetCounters(); |
+ isolate_->heap()->IterateObjects(&visitor); |
+} |
+ |
+ |
+uword HeapClassStatistics::ClassStatsTableAddress() { |
+ return reinterpret_cast<uword>(&class_table_); |
+} |
+ |
+ |
+void HeapClassStatistics::ResetCounters() { |
+ for (intptr_t i = 0; i < class_table_size_; i++) { |
+ class_table_[i].live_old_space = 0; |
+ class_table_[i].live_new_space = 0; |
+ class_table_[i].allocated_since_gc = 0; |
+ } |
+} |
+ |
+ |
+void HeapClassStatistics::ReportLiveOldSpace(intptr_t cid) { |
+ ASSERT(cid < class_table_size_); |
+ class_table_[cid].live_old_space++; |
+} |
+ |
+ |
+void HeapClassStatistics::ReportLiveNewSpace(intptr_t cid) { |
+ ASSERT(cid < class_table_size_); |
+ class_table_[cid].live_new_space++; |
+} |
+ |
+} // namespace dart |