| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/class_table.h" | 5 #include "vm/class_table.h" |
| 6 | 6 |
| 7 #include "vm/atomic.h" | 7 #include "vm/atomic.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/freelist.h" | 9 #include "vm/freelist.h" |
| 10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
| 11 #include "vm/heap.h" | 11 #include "vm/heap.h" |
| 12 #include "vm/object.h" | 12 #include "vm/object.h" |
| 13 #include "vm/raw_object.h" | 13 #include "vm/raw_object.h" |
| 14 #include "vm/visitor.h" | 14 #include "vm/visitor.h" |
| 15 | 15 |
| 16 namespace dart { | 16 namespace dart { |
| 17 | 17 |
| 18 DEFINE_FLAG(bool, print_class_table, false, "Print initial class table."); | 18 DEFINE_FLAG(bool, print_class_table, false, "Print initial class table."); |
| 19 | 19 |
| 20 ClassTable::ClassTable() | 20 ClassTable::ClassTable() |
| 21 : top_(kNumPredefinedCids), capacity_(0), table_(NULL), | 21 : top_(kNumPredefinedCids), capacity_(0), table_(NULL), |
| 22 old_tables_(new MallocGrowableArray<RawClass**>()), | 22 old_tables_(new MallocGrowableArray<RawClass**>()) { |
| 23 class_heap_stats_table_(NULL), | |
| 24 predefined_class_heap_stats_table_(NULL) { | |
| 25 if (Dart::vm_isolate() == NULL) { | 23 if (Dart::vm_isolate() == NULL) { |
| 26 capacity_ = initial_capacity_; | 24 capacity_ = initial_capacity_; |
| 27 table_ = reinterpret_cast<RawClass**>( | 25 table_ = reinterpret_cast<RawClass**>( |
| 28 calloc(capacity_, sizeof(RawClass*))); // NOLINT | 26 calloc(capacity_, sizeof(RawClass*))); // NOLINT |
| 29 } else { | 27 } else { |
| 30 // Duplicate the class table from the VM isolate. | 28 // Duplicate the class table from the VM isolate. |
| 31 ClassTable* vm_class_table = Dart::vm_isolate()->class_table(); | 29 ClassTable* vm_class_table = Dart::vm_isolate()->class_table(); |
| 32 capacity_ = vm_class_table->capacity_; | 30 capacity_ = vm_class_table->capacity_; |
| 33 table_ = reinterpret_cast<RawClass**>( | 31 table_ = reinterpret_cast<RawClass**>( |
| 34 calloc(capacity_, sizeof(RawClass*))); // NOLINT | 32 calloc(capacity_, sizeof(RawClass*))); // NOLINT |
| 35 for (intptr_t i = kObjectCid; i < kInstanceCid; i++) { | 33 for (intptr_t i = kObjectCid; i < kInstanceCid; i++) { |
| 36 table_[i] = vm_class_table->At(i); | 34 table_[i] = vm_class_table->At(i); |
| 37 } | 35 } |
| 38 table_[kFreeListElement] = vm_class_table->At(kFreeListElement); | 36 table_[kFreeListElement] = vm_class_table->At(kFreeListElement); |
| 39 table_[kForwardingCorpse] = vm_class_table->At(kForwardingCorpse); | 37 table_[kForwardingCorpse] = vm_class_table->At(kForwardingCorpse); |
| 40 table_[kDynamicCid] = vm_class_table->At(kDynamicCid); | 38 table_[kDynamicCid] = vm_class_table->At(kDynamicCid); |
| 41 table_[kVoidCid] = vm_class_table->At(kVoidCid); | 39 table_[kVoidCid] = vm_class_table->At(kVoidCid); |
| 40 |
| 41 #ifndef PRODUCT |
| 42 class_heap_stats_table_ = reinterpret_cast<ClassHeapStats*>( | 42 class_heap_stats_table_ = reinterpret_cast<ClassHeapStats*>( |
| 43 calloc(capacity_, sizeof(ClassHeapStats))); // NOLINT | 43 calloc(capacity_, sizeof(ClassHeapStats))); // NOLINT |
| 44 for (intptr_t i = 0; i < capacity_; i++) { | 44 for (intptr_t i = 0; i < capacity_; i++) { |
| 45 class_heap_stats_table_[i].Initialize(); | 45 class_heap_stats_table_[i].Initialize(); |
| 46 } | 46 } |
| 47 #endif // !PRODUCT |
| 47 } | 48 } |
| 49 #ifndef PRODUCT |
| 48 predefined_class_heap_stats_table_ = reinterpret_cast<ClassHeapStats*>( | 50 predefined_class_heap_stats_table_ = reinterpret_cast<ClassHeapStats*>( |
| 49 calloc(kNumPredefinedCids, sizeof(ClassHeapStats))); // NOLINT | 51 calloc(kNumPredefinedCids, sizeof(ClassHeapStats))); // NOLINT |
| 50 for (intptr_t i = 0; i < kNumPredefinedCids; i++) { | 52 for (intptr_t i = 0; i < kNumPredefinedCids; i++) { |
| 51 predefined_class_heap_stats_table_[i].Initialize(); | 53 predefined_class_heap_stats_table_[i].Initialize(); |
| 52 } | 54 } |
| 55 #endif // !PRODUCT |
| 53 } | 56 } |
| 54 | 57 |
| 55 | 58 |
| 56 ClassTable::ClassTable(ClassTable* original) | 59 ClassTable::ClassTable(ClassTable* original) |
| 57 : top_(original->top_), | 60 : top_(original->top_), |
| 58 capacity_(original->top_), | 61 capacity_(original->top_), |
| 59 table_(original->table_), | 62 table_(original->table_), |
| 60 old_tables_(NULL), | 63 old_tables_(NULL) { |
| 61 class_heap_stats_table_(NULL), | 64 NOT_IN_PRODUCT(class_heap_stats_table_ = NULL); |
| 62 predefined_class_heap_stats_table_(NULL) { | 65 NOT_IN_PRODUCT(predefined_class_heap_stats_table_ = NULL); |
| 63 } | 66 } |
| 64 | 67 |
| 65 | 68 |
| 66 ClassTable::~ClassTable() { | 69 ClassTable::~ClassTable() { |
| 67 if (old_tables_ != NULL) { | 70 if (old_tables_ != NULL) { |
| 68 FreeOldTables(); | 71 FreeOldTables(); |
| 69 delete old_tables_; | 72 delete old_tables_; |
| 70 free(table_); | 73 free(table_); |
| 71 free(predefined_class_heap_stats_table_); | 74 NOT_IN_PRODUCT(free(predefined_class_heap_stats_table_)); |
| 72 free(class_heap_stats_table_); | 75 NOT_IN_PRODUCT(free(class_heap_stats_table_)); |
| 73 } else { | 76 } else { |
| 74 // This instance was a shallow copy. It doesn't own any memory. | 77 // This instance was a shallow copy. It doesn't own any memory. |
| 75 ASSERT(predefined_class_heap_stats_table_ == NULL); | 78 NOT_IN_PRODUCT(ASSERT(predefined_class_heap_stats_table_ == NULL)); |
| 76 ASSERT(class_heap_stats_table_ == NULL); | 79 NOT_IN_PRODUCT(ASSERT(class_heap_stats_table_ == NULL)); |
| 77 } | 80 } |
| 78 } | 81 } |
| 79 | 82 |
| 80 | 83 |
| 81 void ClassTable::FreeOldTables() { | 84 void ClassTable::FreeOldTables() { |
| 82 while (old_tables_->length() > 0) { | 85 while (old_tables_->length() > 0) { |
| 83 free(old_tables_->RemoveLast()); | 86 free(old_tables_->RemoveLast()); |
| 84 } | 87 } |
| 85 } | 88 } |
| 86 | 89 |
| 87 | 90 |
| 91 #ifndef PRODUCT |
| 88 void ClassTable::SetTraceAllocationFor(intptr_t cid, bool trace) { | 92 void ClassTable::SetTraceAllocationFor(intptr_t cid, bool trace) { |
| 89 ClassHeapStats* stats = PreliminaryStatsAt(cid); | 93 ClassHeapStats* stats = PreliminaryStatsAt(cid); |
| 90 stats->set_trace_allocation(trace); | 94 stats->set_trace_allocation(trace); |
| 91 } | 95 } |
| 92 | 96 |
| 93 | 97 |
| 94 bool ClassTable::TraceAllocationFor(intptr_t cid) { | 98 bool ClassTable::TraceAllocationFor(intptr_t cid) { |
| 95 ClassHeapStats* stats = PreliminaryStatsAt(cid); | 99 ClassHeapStats* stats = PreliminaryStatsAt(cid); |
| 96 return stats->trace_allocation(); | 100 return stats->trace_allocation(); |
| 97 } | 101 } |
| 102 #endif // !PRODUCT |
| 98 | 103 |
| 99 | 104 |
| 100 void ClassTable::Register(const Class& cls) { | 105 void ClassTable::Register(const Class& cls) { |
| 101 ASSERT(Thread::Current()->IsMutatorThread()); | 106 ASSERT(Thread::Current()->IsMutatorThread()); |
| 102 intptr_t index = cls.id(); | 107 intptr_t index = cls.id(); |
| 103 if (index != kIllegalCid) { | 108 if (index != kIllegalCid) { |
| 104 ASSERT(index > 0); | 109 ASSERT(index > 0); |
| 105 ASSERT(index < kNumPredefinedCids); | 110 ASSERT(index < kNumPredefinedCids); |
| 106 ASSERT(table_[index] == 0); | 111 ASSERT(table_[index] == 0); |
| 107 ASSERT(index < capacity_); | 112 ASSERT(index < capacity_); |
| 108 table_[index] = cls.raw(); | 113 table_[index] = cls.raw(); |
| 109 // Add the vtable for this predefined class into the static vtable registry | 114 // Add the vtable for this predefined class into the static vtable registry |
| 110 // if it has not been setup yet. | 115 // if it has not been setup yet. |
| 111 cpp_vtable cls_vtable = cls.handle_vtable(); | 116 cpp_vtable cls_vtable = cls.handle_vtable(); |
| 112 AtomicOperations::CompareAndSwapWord( | 117 AtomicOperations::CompareAndSwapWord( |
| 113 &(Object::builtin_vtables_[index]), 0, cls_vtable); | 118 &(Object::builtin_vtables_[index]), 0, cls_vtable); |
| 114 ASSERT(Object::builtin_vtables_[index] == cls_vtable); | 119 ASSERT(Object::builtin_vtables_[index] == cls_vtable); |
| 115 } else { | 120 } else { |
| 116 if (top_ == capacity_) { | 121 if (top_ == capacity_) { |
| 117 // Grow the capacity of the class table. | 122 // Grow the capacity of the class table. |
| 118 // TODO(koda): Add ClassTable::Grow to share code. | 123 // TODO(koda): Add ClassTable::Grow to share code. |
| 119 intptr_t new_capacity = capacity_ + capacity_increment_; | 124 intptr_t new_capacity = capacity_ + capacity_increment_; |
| 120 RawClass** new_table = reinterpret_cast<RawClass**>( | 125 RawClass** new_table = reinterpret_cast<RawClass**>( |
| 121 malloc(new_capacity * sizeof(RawClass*))); // NOLINT | 126 malloc(new_capacity * sizeof(RawClass*))); // NOLINT |
| 122 memmove(new_table, table_, capacity_ * sizeof(RawClass*)); | 127 memmove(new_table, table_, capacity_ * sizeof(RawClass*)); |
| 128 #ifndef PRODUCT |
| 123 ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>( | 129 ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>( |
| 124 realloc(class_heap_stats_table_, | 130 realloc(class_heap_stats_table_, |
| 125 new_capacity * sizeof(ClassHeapStats))); // NOLINT | 131 new_capacity * sizeof(ClassHeapStats))); // NOLINT |
| 132 #endif |
| 126 for (intptr_t i = capacity_; i < new_capacity; i++) { | 133 for (intptr_t i = capacity_; i < new_capacity; i++) { |
| 127 new_table[i] = NULL; | 134 new_table[i] = NULL; |
| 128 new_stats_table[i].Initialize(); | 135 NOT_IN_PRODUCT(new_stats_table[i].Initialize()); |
| 129 } | 136 } |
| 130 capacity_ = new_capacity; | 137 capacity_ = new_capacity; |
| 131 old_tables_->Add(table_); | 138 old_tables_->Add(table_); |
| 132 table_ = new_table; // TODO(koda): This should use atomics. | 139 table_ = new_table; // TODO(koda): This should use atomics. |
| 133 class_heap_stats_table_ = new_stats_table; | 140 NOT_IN_PRODUCT(class_heap_stats_table_ = new_stats_table); |
| 134 } | 141 } |
| 135 ASSERT(top_ < capacity_); | 142 ASSERT(top_ < capacity_); |
| 136 if (!Class::is_valid_id(top_)) { | 143 if (!Class::is_valid_id(top_)) { |
| 137 FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n", | 144 FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n", |
| 138 top_); | 145 top_); |
| 139 } | 146 } |
| 140 cls.set_id(top_); | 147 cls.set_id(top_); |
| 141 table_[top_] = cls.raw(); | 148 table_[top_] = cls.raw(); |
| 142 top_++; // Increment next index. | 149 top_++; // Increment next index. |
| 143 } | 150 } |
| 144 } | 151 } |
| 145 | 152 |
| 146 | 153 |
| 147 void ClassTable::AllocateIndex(intptr_t index) { | 154 void ClassTable::AllocateIndex(intptr_t index) { |
| 148 if (index >= capacity_) { | 155 if (index >= capacity_) { |
| 149 // Grow the capacity of the class table. | 156 // Grow the capacity of the class table. |
| 150 // TODO(koda): Add ClassTable::Grow to share code. | 157 // TODO(koda): Add ClassTable::Grow to share code. |
| 151 intptr_t new_capacity = index + capacity_increment_; | 158 intptr_t new_capacity = index + capacity_increment_; |
| 152 if (!Class::is_valid_id(index) || new_capacity < capacity_) { | 159 if (!Class::is_valid_id(index) || new_capacity < capacity_) { |
| 153 FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n", | 160 FATAL1("Fatal error in ClassTable::Register: invalid index %" Pd "\n", |
| 154 index); | 161 index); |
| 155 } | 162 } |
| 156 RawClass** new_table = reinterpret_cast<RawClass**>( | 163 RawClass** new_table = reinterpret_cast<RawClass**>( |
| 157 malloc(new_capacity * sizeof(RawClass*))); // NOLINT | 164 malloc(new_capacity * sizeof(RawClass*))); // NOLINT |
| 158 memmove(new_table, table_, capacity_ * sizeof(RawClass*)); | 165 memmove(new_table, table_, capacity_ * sizeof(RawClass*)); |
| 166 #ifndef PRODUCT |
| 159 ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>( | 167 ClassHeapStats* new_stats_table = reinterpret_cast<ClassHeapStats*>( |
| 160 realloc(class_heap_stats_table_, | 168 realloc(class_heap_stats_table_, |
| 161 new_capacity * sizeof(ClassHeapStats))); // NOLINT | 169 new_capacity * sizeof(ClassHeapStats))); // NOLINT |
| 170 #endif |
| 162 for (intptr_t i = capacity_; i < new_capacity; i++) { | 171 for (intptr_t i = capacity_; i < new_capacity; i++) { |
| 163 new_table[i] = NULL; | 172 new_table[i] = NULL; |
| 164 new_stats_table[i].Initialize(); | 173 NOT_IN_PRODUCT(new_stats_table[i].Initialize()); |
| 165 } | 174 } |
| 166 capacity_ = new_capacity; | 175 capacity_ = new_capacity; |
| 167 old_tables_->Add(table_); | 176 old_tables_->Add(table_); |
| 168 table_ = new_table; // TODO(koda): This should use atomics. | 177 table_ = new_table; // TODO(koda): This should use atomics. |
| 169 class_heap_stats_table_ = new_stats_table; | 178 NOT_IN_PRODUCT(class_heap_stats_table_ = new_stats_table); |
| 170 ASSERT(capacity_increment_ >= 1); | 179 ASSERT(capacity_increment_ >= 1); |
| 171 } | 180 } |
| 172 | 181 |
| 173 ASSERT(table_[index] == 0); | 182 ASSERT(table_[index] == 0); |
| 174 if (index >= top_) { | 183 if (index >= top_) { |
| 175 top_ = index + 1; | 184 top_ = index + 1; |
| 176 } | 185 } |
| 177 } | 186 } |
| 178 | 187 |
| 179 | 188 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 { | 254 { |
| 246 JSONArray members(object, "classes"); | 255 JSONArray members(object, "classes"); |
| 247 for (intptr_t i = 1; i < top_; i++) { | 256 for (intptr_t i = 1; i < top_; i++) { |
| 248 if (HasValidClassAt(i)) { | 257 if (HasValidClassAt(i)) { |
| 249 cls = At(i); | 258 cls = At(i); |
| 250 members.AddValue(cls); | 259 members.AddValue(cls); |
| 251 } | 260 } |
| 252 } | 261 } |
| 253 } | 262 } |
| 254 } | 263 } |
| 255 #endif // PRODUCT | |
| 256 | 264 |
| 257 | 265 |
| 258 void ClassHeapStats::Initialize() { | 266 void ClassHeapStats::Initialize() { |
| 259 pre_gc.Reset(); | 267 pre_gc.Reset(); |
| 260 post_gc.Reset(); | 268 post_gc.Reset(); |
| 261 recent.Reset(); | 269 recent.Reset(); |
| 262 accumulated.Reset(); | 270 accumulated.Reset(); |
| 263 last_reset.Reset(); | 271 last_reset.Reset(); |
| 264 promoted_count = 0; | 272 promoted_count = 0; |
| 265 promoted_size = 0; | 273 promoted_size = 0; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 accumulated.Reset(); | 333 accumulated.Reset(); |
| 326 } | 334 } |
| 327 | 335 |
| 328 | 336 |
| 329 void ClassHeapStats::UpdatePromotedAfterNewGC() { | 337 void ClassHeapStats::UpdatePromotedAfterNewGC() { |
| 330 promoted_count = recent.old_count - old_pre_new_gc_count_; | 338 promoted_count = recent.old_count - old_pre_new_gc_count_; |
| 331 promoted_size = recent.old_size - old_pre_new_gc_size_; | 339 promoted_size = recent.old_size - old_pre_new_gc_size_; |
| 332 } | 340 } |
| 333 | 341 |
| 334 | 342 |
| 335 #ifndef PRODUCT | |
| 336 void ClassHeapStats::PrintToJSONObject(const Class& cls, | 343 void ClassHeapStats::PrintToJSONObject(const Class& cls, |
| 337 JSONObject* obj) const { | 344 JSONObject* obj) const { |
| 338 if (!FLAG_support_service) { | 345 if (!FLAG_support_service) { |
| 339 return; | 346 return; |
| 340 } | 347 } |
| 341 obj->AddProperty("type", "ClassHeapStats"); | 348 obj->AddProperty("type", "ClassHeapStats"); |
| 342 obj->AddProperty("class", cls); | 349 obj->AddProperty("class", cls); |
| 343 { | 350 { |
| 344 JSONArray new_stats(obj, "new"); | 351 JSONArray new_stats(obj, "new"); |
| 345 new_stats.AddValue(pre_gc.new_count); | 352 new_stats.AddValue(pre_gc.new_count); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 362 old_stats.AddValue(recent.old_count); | 369 old_stats.AddValue(recent.old_count); |
| 363 old_stats.AddValue(recent.old_size); | 370 old_stats.AddValue(recent.old_size); |
| 364 old_stats.AddValue64(accumulated.old_count + recent.old_count - | 371 old_stats.AddValue64(accumulated.old_count + recent.old_count - |
| 365 last_reset.old_count); | 372 last_reset.old_count); |
| 366 old_stats.AddValue64(accumulated.old_size + recent.old_size - | 373 old_stats.AddValue64(accumulated.old_size + recent.old_size - |
| 367 last_reset.old_size); | 374 last_reset.old_size); |
| 368 } | 375 } |
| 369 obj->AddProperty("promotedInstances", promoted_count); | 376 obj->AddProperty("promotedInstances", promoted_count); |
| 370 obj->AddProperty("promotedBytes", promoted_size); | 377 obj->AddProperty("promotedBytes", promoted_size); |
| 371 } | 378 } |
| 372 #endif | |
| 373 | 379 |
| 374 | 380 |
| 375 void ClassTable::UpdateAllocatedNew(intptr_t cid, intptr_t size) { | 381 void ClassTable::UpdateAllocatedNew(intptr_t cid, intptr_t size) { |
| 376 ClassHeapStats* stats = PreliminaryStatsAt(cid); | 382 ClassHeapStats* stats = PreliminaryStatsAt(cid); |
| 377 ASSERT(stats != NULL); | 383 ASSERT(stats != NULL); |
| 378 ASSERT(size != 0); | 384 ASSERT(size != 0); |
| 379 stats->recent.AddNew(size); | 385 stats->recent.AddNew(size); |
| 380 } | 386 } |
| 381 | 387 |
| 382 | 388 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 | 495 |
| 490 intptr_t ClassTable::SizeOffsetFor(intptr_t cid, bool is_new_space) { | 496 intptr_t ClassTable::SizeOffsetFor(intptr_t cid, bool is_new_space) { |
| 491 const uword class_offset = ClassOffsetFor(cid); | 497 const uword class_offset = ClassOffsetFor(cid); |
| 492 const uword size_field_offset = is_new_space | 498 const uword size_field_offset = is_new_space |
| 493 ? ClassHeapStats::allocated_size_since_gc_new_space_offset() | 499 ? ClassHeapStats::allocated_size_since_gc_new_space_offset() |
| 494 : ClassHeapStats::allocated_size_since_gc_old_space_offset(); | 500 : ClassHeapStats::allocated_size_since_gc_old_space_offset(); |
| 495 return class_offset + size_field_offset; | 501 return class_offset + size_field_offset; |
| 496 } | 502 } |
| 497 | 503 |
| 498 | 504 |
| 499 #ifndef PRODUCT | |
| 500 void ClassTable::AllocationProfilePrintJSON(JSONStream* stream) { | 505 void ClassTable::AllocationProfilePrintJSON(JSONStream* stream) { |
| 501 if (!FLAG_support_service) { | 506 if (!FLAG_support_service) { |
| 502 return; | 507 return; |
| 503 } | 508 } |
| 504 Isolate* isolate = Isolate::Current(); | 509 Isolate* isolate = Isolate::Current(); |
| 505 ASSERT(isolate != NULL); | 510 ASSERT(isolate != NULL); |
| 506 Heap* heap = isolate->heap(); | 511 Heap* heap = isolate->heap(); |
| 507 ASSERT(heap != NULL); | 512 ASSERT(heap != NULL); |
| 508 JSONObject obj(stream); | 513 JSONObject obj(stream); |
| 509 obj.AddProperty("type", "AllocationProfile"); | 514 obj.AddProperty("type", "AllocationProfile"); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 531 for (intptr_t i = 1; i < top_; i++) { | 536 for (intptr_t i = 1; i < top_; i++) { |
| 532 const ClassHeapStats* stats = StatsWithUpdatedSize(i); | 537 const ClassHeapStats* stats = StatsWithUpdatedSize(i); |
| 533 if (stats != NULL) { | 538 if (stats != NULL) { |
| 534 JSONObject obj(&arr); | 539 JSONObject obj(&arr); |
| 535 cls = At(i); | 540 cls = At(i); |
| 536 stats->PrintToJSONObject(cls, &obj); | 541 stats->PrintToJSONObject(cls, &obj); |
| 537 } | 542 } |
| 538 } | 543 } |
| 539 } | 544 } |
| 540 } | 545 } |
| 541 #endif | |
| 542 | 546 |
| 543 | 547 |
| 544 void ClassTable::ResetAllocationAccumulators() { | 548 void ClassTable::ResetAllocationAccumulators() { |
| 545 for (intptr_t i = 1; i < top_; i++) { | 549 for (intptr_t i = 1; i < top_; i++) { |
| 546 ClassHeapStats* stats = StatsWithUpdatedSize(i); | 550 ClassHeapStats* stats = StatsWithUpdatedSize(i); |
| 547 if (stats != NULL) { | 551 if (stats != NULL) { |
| 548 stats->ResetAccumulator(); | 552 stats->ResetAccumulator(); |
| 549 } | 553 } |
| 550 } | 554 } |
| 551 } | 555 } |
| 552 | 556 |
| 553 | 557 |
| 554 void ClassTable::UpdateLiveOld(intptr_t cid, intptr_t size, intptr_t count) { | 558 void ClassTable::UpdateLiveOld(intptr_t cid, intptr_t size, intptr_t count) { |
| 555 ClassHeapStats* stats = PreliminaryStatsAt(cid); | 559 ClassHeapStats* stats = PreliminaryStatsAt(cid); |
| 556 ASSERT(stats != NULL); | 560 ASSERT(stats != NULL); |
| 557 ASSERT(size >= 0); | 561 ASSERT(size >= 0); |
| 558 ASSERT(count >= 0); | 562 ASSERT(count >= 0); |
| 559 stats->post_gc.AddOld(size, count); | 563 stats->post_gc.AddOld(size, count); |
| 560 } | 564 } |
| 561 | 565 |
| 562 | 566 |
| 563 void ClassTable::UpdateLiveNew(intptr_t cid, intptr_t size) { | 567 void ClassTable::UpdateLiveNew(intptr_t cid, intptr_t size) { |
| 564 ClassHeapStats* stats = PreliminaryStatsAt(cid); | 568 ClassHeapStats* stats = PreliminaryStatsAt(cid); |
| 565 ASSERT(stats != NULL); | 569 ASSERT(stats != NULL); |
| 566 ASSERT(size >= 0); | 570 ASSERT(size >= 0); |
| 567 stats->post_gc.AddNew(size); | 571 stats->post_gc.AddNew(size); |
| 568 } | 572 } |
| 573 #endif // !PRODUCT |
| 569 | 574 |
| 570 | 575 |
| 571 } // namespace dart | 576 } // namespace dart |
| OLD | NEW |