| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/gc_marker.h" | 5 #include "vm/gc_marker.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 MarkingVisitor(Isolate* isolate, | 148 MarkingVisitor(Isolate* isolate, |
| 149 Heap* heap, | 149 Heap* heap, |
| 150 PageSpace* page_space, | 150 PageSpace* page_space, |
| 151 MarkingStack* marking_stack, | 151 MarkingStack* marking_stack, |
| 152 DelaySet* delay_set, | 152 DelaySet* delay_set, |
| 153 SkippedCodeFunctions* skipped_code_functions) | 153 SkippedCodeFunctions* skipped_code_functions) |
| 154 : ObjectPointerVisitor(isolate), | 154 : ObjectPointerVisitor(isolate), |
| 155 thread_(Thread::Current()), | 155 thread_(Thread::Current()), |
| 156 heap_(heap), | 156 heap_(heap), |
| 157 vm_heap_(Dart::vm_isolate()->heap()), | 157 vm_heap_(Dart::vm_isolate()->heap()), |
| 158 class_table_(isolate->class_table()), | 158 class_stats_count_(isolate->class_table()->NumCids()), |
| 159 class_stats_size_(isolate->class_table()->NumCids()), |
| 159 page_space_(page_space), | 160 page_space_(page_space), |
| 160 work_list_(marking_stack), | 161 work_list_(marking_stack), |
| 161 delay_set_(delay_set), | 162 delay_set_(delay_set), |
| 162 visiting_old_object_(NULL), | 163 visiting_old_object_(NULL), |
| 163 skipped_code_functions_(skipped_code_functions), | 164 skipped_code_functions_(skipped_code_functions), |
| 164 marked_bytes_(0) { | 165 marked_bytes_(0) { |
| 165 ASSERT(heap_ != vm_heap_); | 166 ASSERT(heap_ != vm_heap_); |
| 166 ASSERT(thread_->isolate() == isolate); | 167 ASSERT(thread_->isolate() == isolate); |
| 168 class_stats_count_.SetLength(isolate->class_table()->NumCids()); |
| 169 class_stats_size_.SetLength(isolate->class_table()->NumCids()); |
| 170 for (intptr_t i = 0; i < class_stats_count_.length(); ++i) { |
| 171 class_stats_count_[i] = 0; |
| 172 class_stats_size_[i] = 0; |
| 173 } |
| 167 } | 174 } |
| 168 | 175 |
| 169 uintptr_t marked_bytes() const { return marked_bytes_; } | 176 uintptr_t marked_bytes() const { return marked_bytes_; } |
| 170 | 177 |
| 178 intptr_t live_count(intptr_t class_id) { |
| 179 return class_stats_count_[class_id]; |
| 180 } |
| 181 |
| 182 intptr_t live_size(intptr_t class_id) { |
| 183 return class_stats_size_[class_id]; |
| 184 } |
| 185 |
| 171 // Returns true if some non-zero amount of work was performed. | 186 // Returns true if some non-zero amount of work was performed. |
| 172 bool DrainMarkingStack() { | 187 bool DrainMarkingStack() { |
| 173 RawObject* raw_obj = work_list_.Pop(); | 188 RawObject* raw_obj = work_list_.Pop(); |
| 174 if (raw_obj == NULL) { | 189 if (raw_obj == NULL) { |
| 175 ASSERT(visiting_old_object_ == NULL); | 190 ASSERT(visiting_old_object_ == NULL); |
| 176 return false; | 191 return false; |
| 177 } | 192 } |
| 178 do { | 193 do { |
| 179 VisitingOldObject(raw_obj); | 194 VisitingOldObject(raw_obj); |
| 180 const intptr_t class_id = raw_obj->GetClassId(); | 195 const intptr_t class_id = raw_obj->GetClassId(); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 // TODO(iposva): Add consistency check. | 355 // TODO(iposva): Add consistency check. |
| 341 if ((visiting_old_object_ != NULL) && | 356 if ((visiting_old_object_ != NULL) && |
| 342 !visiting_old_object_->IsRemembered()) { | 357 !visiting_old_object_->IsRemembered()) { |
| 343 ASSERT(p != NULL); | 358 ASSERT(p != NULL); |
| 344 visiting_old_object_->SetRememberedBitUnsynchronized(); | 359 visiting_old_object_->SetRememberedBitUnsynchronized(); |
| 345 thread_->StoreBufferAddObjectGC(visiting_old_object_); | 360 thread_->StoreBufferAddObjectGC(visiting_old_object_); |
| 346 } | 361 } |
| 347 return; | 362 return; |
| 348 } | 363 } |
| 349 if (RawObject::IsVariableSizeClassId(raw_obj->GetClassId())) { | 364 if (RawObject::IsVariableSizeClassId(raw_obj->GetClassId())) { |
| 350 class_table_->UpdateLiveOld(raw_obj->GetClassId(), raw_obj->Size()); | 365 UpdateLiveOld(raw_obj->GetClassId(), raw_obj->Size()); |
| 351 } else { | 366 } else { |
| 352 class_table_->UpdateLiveOld(raw_obj->GetClassId(), 0); | 367 UpdateLiveOld(raw_obj->GetClassId(), 0); |
| 353 } | 368 } |
| 354 | 369 |
| 355 MarkAndPush(raw_obj); | 370 MarkAndPush(raw_obj); |
| 356 } | 371 } |
| 357 | 372 |
| 373 void UpdateLiveOld(intptr_t class_id, intptr_t size) { |
| 374 // TODO(koda): Support growing the array once mutator runs concurrently. |
| 375 ASSERT(class_id < class_stats_count_.length()); |
| 376 class_stats_count_[class_id] += 1; |
| 377 class_stats_size_[class_id] += size; |
| 378 } |
| 379 |
| 358 Thread* thread_; | 380 Thread* thread_; |
| 359 Heap* heap_; | 381 Heap* heap_; |
| 360 Heap* vm_heap_; | 382 Heap* vm_heap_; |
| 361 ClassTable* class_table_; | 383 GrowableArray<intptr_t> class_stats_count_; |
| 384 GrowableArray<intptr_t> class_stats_size_; |
| 362 PageSpace* page_space_; | 385 PageSpace* page_space_; |
| 363 WorkList work_list_; | 386 WorkList work_list_; |
| 364 DelaySet* delay_set_; | 387 DelaySet* delay_set_; |
| 365 RawObject* visiting_old_object_; | 388 RawObject* visiting_old_object_; |
| 366 SkippedCodeFunctions* skipped_code_functions_; | 389 SkippedCodeFunctions* skipped_code_functions_; |
| 367 uintptr_t marked_bytes_; | 390 uintptr_t marked_bytes_; |
| 368 | 391 |
| 369 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); | 392 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); |
| 370 }; | 393 }; |
| 371 | 394 |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 ThreadBarrier* barrier_; | 627 ThreadBarrier* barrier_; |
| 605 bool collect_code_; | 628 bool collect_code_; |
| 606 bool visit_prologue_weak_persistent_handles_; | 629 bool visit_prologue_weak_persistent_handles_; |
| 607 | 630 |
| 608 DISALLOW_COPY_AND_ASSIGN(MarkTask); | 631 DISALLOW_COPY_AND_ASSIGN(MarkTask); |
| 609 }; | 632 }; |
| 610 | 633 |
| 611 | 634 |
| 612 void GCMarker::FinalizeResultsFrom(MarkingVisitor* visitor) { | 635 void GCMarker::FinalizeResultsFrom(MarkingVisitor* visitor) { |
| 613 { | 636 { |
| 614 MonitorLocker ml(&monitor_); | 637 MutexLocker ml(&stats_mutex_); |
| 615 marked_bytes_ += visitor->marked_bytes(); | 638 marked_bytes_ += visitor->marked_bytes(); |
| 639 // Class heap stats are not themselves thread-safe yet, so we update the |
| 640 // stats while holding stats_mutex_. |
| 641 ClassTable* table = heap_->isolate()->class_table(); |
| 642 for (intptr_t i = 0; i < table->NumCids(); ++i) { |
| 643 const intptr_t count = visitor->live_count(i); |
| 644 if (count > 0) { |
| 645 const intptr_t size = visitor->live_size(i); |
| 646 table->UpdateLiveOld(i, size, count); |
| 647 } |
| 648 } |
| 616 } | 649 } |
| 617 visitor->Finalize(); | 650 visitor->Finalize(); |
| 618 } | 651 } |
| 619 | 652 |
| 620 | 653 |
| 621 void GCMarker::MarkObjects(Isolate* isolate, | 654 void GCMarker::MarkObjects(Isolate* isolate, |
| 622 PageSpace* page_space, | 655 PageSpace* page_space, |
| 623 bool invoke_api_callbacks, | 656 bool invoke_api_callbacks, |
| 624 bool collect_code) { | 657 bool collect_code) { |
| 625 Prologue(isolate, invoke_api_callbacks); | 658 Prologue(isolate, invoke_api_callbacks); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 barrier.Exit(); | 711 barrier.Exit(); |
| 679 } | 712 } |
| 680 delay_set.ClearReferences(); | 713 delay_set.ClearReferences(); |
| 681 ProcessWeakTables(page_space); | 714 ProcessWeakTables(page_space); |
| 682 ProcessObjectIdTable(isolate); | 715 ProcessObjectIdTable(isolate); |
| 683 } | 716 } |
| 684 Epilogue(isolate, invoke_api_callbacks); | 717 Epilogue(isolate, invoke_api_callbacks); |
| 685 } | 718 } |
| 686 | 719 |
| 687 } // namespace dart | 720 } // namespace dart |
| OLD | NEW |