Chromium Code Reviews| 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/scavenger.h" | 5 #include "vm/scavenger.h" |
| 6 | 6 |
| 7 #include "vm/dart.h" | 7 #include "vm/dart.h" |
| 8 #include "vm/dart_api_state.h" | 8 #include "vm/dart_api_state.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/lockers.h" | 10 #include "vm/lockers.h" |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 intptr_t max_semi_capacity_in_words, | 317 intptr_t max_semi_capacity_in_words, |
| 318 uword object_alignment) | 318 uword object_alignment) |
| 319 : heap_(heap), | 319 : heap_(heap), |
| 320 max_semi_capacity_in_words_(max_semi_capacity_in_words), | 320 max_semi_capacity_in_words_(max_semi_capacity_in_words), |
| 321 object_alignment_(object_alignment), | 321 object_alignment_(object_alignment), |
| 322 scavenging_(false), | 322 scavenging_(false), |
| 323 delayed_weak_properties_(NULL), | 323 delayed_weak_properties_(NULL), |
| 324 gc_time_micros_(0), | 324 gc_time_micros_(0), |
| 325 collections_(0), | 325 collections_(0), |
| 326 external_size_(0), | 326 external_size_(0), |
| 327 failed_to_promote_(false) { | 327 failed_to_promote_(false), |
| 328 space_lock_(new Mutex()) { | |
| 328 // Verify assumptions about the first word in objects which the scavenger is | 329 // Verify assumptions about the first word in objects which the scavenger is |
| 329 // going to use for forwarding pointers. | 330 // going to use for forwarding pointers. |
| 330 ASSERT(Object::tags_offset() == 0); | 331 ASSERT(Object::tags_offset() == 0); |
| 331 | 332 |
| 332 // Set initial size resulting in a total of three different levels. | 333 // Set initial size resulting in a total of three different levels. |
| 333 const intptr_t initial_semi_capacity_in_words = | 334 const intptr_t initial_semi_capacity_in_words = |
| 334 max_semi_capacity_in_words / | 335 max_semi_capacity_in_words / |
| 335 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor); | 336 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor); |
| 336 | 337 |
| 337 const intptr_t kVmNameSize = 128; | 338 const intptr_t kVmNameSize = 128; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 348 | 349 |
| 349 survivor_end_ = FirstObjectStart(); | 350 survivor_end_ = FirstObjectStart(); |
| 350 | 351 |
| 351 UpdateMaxHeapCapacity(); | 352 UpdateMaxHeapCapacity(); |
| 352 UpdateMaxHeapUsage(); | 353 UpdateMaxHeapUsage(); |
| 353 } | 354 } |
| 354 | 355 |
| 355 Scavenger::~Scavenger() { | 356 Scavenger::~Scavenger() { |
| 356 ASSERT(!scavenging_); | 357 ASSERT(!scavenging_); |
| 357 to_->Delete(); | 358 to_->Delete(); |
| 359 delete space_lock_; | |
| 358 } | 360 } |
| 359 | 361 |
| 360 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const { | 362 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const { |
| 361 if (stats_history_.Size() == 0) { | 363 if (stats_history_.Size() == 0) { |
| 362 return old_size_in_words; | 364 return old_size_in_words; |
| 363 } | 365 } |
| 364 double garbage = stats_history_.Get(0).GarbageFraction(); | 366 double garbage = stats_history_.Get(0).GarbageFraction(); |
| 365 if (garbage < (FLAG_new_gen_garbage_threshold / 100.0)) { | 367 if (garbage < (FLAG_new_gen_garbage_threshold / 100.0)) { |
| 366 return Utils::Minimum(max_semi_capacity_in_words_, | 368 return Utils::Minimum(max_semi_capacity_in_words_, |
| 367 old_size_in_words * FLAG_new_gen_growth_factor); | 369 old_size_in_words * FLAG_new_gen_growth_factor); |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 708 #endif // defined(DEBUG) | 710 #endif // defined(DEBUG) |
| 709 | 711 |
| 710 WeakProperty::Clear(cur_weak); | 712 WeakProperty::Clear(cur_weak); |
| 711 | 713 |
| 712 // Advance to next weak property in the queue. | 714 // Advance to next weak property in the queue. |
| 713 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak); | 715 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak); |
| 714 } | 716 } |
| 715 } | 717 } |
| 716 } | 718 } |
| 717 | 719 |
| 720 uword Scavenger::FindTopOfSpace(Isolate* isolate) const { | |
| 721 Thread* current = heap_->isolate()->thread_registry()->active_list(); | |
| 722 uword furthest_addr = 0; | |
|
rmacnak
2017/08/01 21:51:25
If we make all outstanding TLABs walkable, everyth
danunez
2017/08/01 23:25:34
That make sense. However, I am going to split this
| |
| 723 while (current != NULL) { | |
| 724 if (current->HasActiveTLAB() && current->top() > furthest_addr) { | |
| 725 furthest_addr = current->top(); | |
| 726 heap_->FillRemainingTLAB(current); | |
| 727 } | |
| 728 current = current->next(); | |
| 729 } | |
| 730 return furthest_addr; | |
| 731 } | |
| 732 | |
| 718 uword Scavenger::FlushTLS() const { | 733 uword Scavenger::FlushTLS() const { |
| 719 ASSERT(heap_ != NULL); | 734 ASSERT(heap_ != NULL); |
|
rmacnak
2017/08/01 21:51:25
Per comment above, I think this could be replaced
danunez
2017/08/01 23:25:34
Done.
| |
| 720 uword saved_top = top_; | 735 uword saved_top = top_; |
| 721 if (heap_->isolate()->IsMutatorThreadScheduled() && !scavenging_) { | 736 if (!scavenging_) { |
| 722 Thread* mutator_thread = heap_->isolate()->mutator_thread(); | 737 Thread* mutator_thread = heap_->isolate()->mutator_thread(); |
| 723 saved_top = mutator_thread->heap()->new_space()->top(); | 738 uword furthest_addr = FindTopOfSpace(heap_->isolate()); |
| 724 if (mutator_thread->HasActiveTLAB()) { | 739 if (furthest_addr > 0) { |
| 725 ASSERT(mutator_thread->top() <= | 740 ASSERT(furthest_addr <= mutator_thread->heap()->new_space()->top()); |
| 726 mutator_thread->heap()->new_space()->top()); | 741 mutator_thread->heap()->new_space()->set_top(furthest_addr); |
| 727 mutator_thread->heap()->new_space()->set_top(mutator_thread->top()); | |
| 728 } | 742 } |
| 729 } | 743 } |
| 730 return saved_top; | 744 return saved_top; |
| 731 } | 745 } |
| 732 | 746 |
| 733 void Scavenger::UnflushTLS(uword value) const { | 747 void Scavenger::UnflushTLS(uword value) const { |
|
rmacnak
2017/08/01 21:51:25
...which should make this a no-op.
danunez
2017/08/01 23:25:34
Done.
| |
| 734 ASSERT(heap_ != NULL); | 748 ASSERT(heap_ != NULL); |
| 735 if (heap_->isolate()->IsMutatorThreadScheduled() && !scavenging_) { | 749 if (heap_->isolate()->IsMutatorThreadScheduled() && !scavenging_) { |
| 736 Thread* mutator_thread = heap_->isolate()->mutator_thread(); | 750 Thread* mutator_thread = heap_->isolate()->mutator_thread(); |
| 737 mutator_thread->heap()->new_space()->set_top(value); | 751 mutator_thread->heap()->new_space()->set_top(value); |
| 738 ASSERT(mutator_thread->top() <= mutator_thread->heap()->new_space()->top()); | 752 ASSERT(mutator_thread->top() <= mutator_thread->heap()->new_space()->top()); |
| 739 } | 753 } |
| 740 } | 754 } |
| 741 | 755 |
| 756 void Scavenger::AbandonAllTLABs() { | |
| 757 Thread* current = heap_->isolate()->thread_registry()->active_list(); | |
| 758 while (current != NULL) { | |
| 759 heap_->AbandonRemainingTLAB(current); | |
| 760 current = current->next(); | |
| 761 } | |
| 762 } | |
| 763 | |
| 742 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { | 764 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
| 743 uword saved_top = FlushTLS(); | 765 uword saved_top = FlushTLS(); |
| 744 uword cur = FirstObjectStart(); | 766 uword cur = FirstObjectStart(); |
| 745 while (cur < top_) { | 767 while (cur < top_) { |
| 746 RawObject* raw_obj = RawObject::FromAddr(cur); | 768 RawObject* raw_obj = RawObject::FromAddr(cur); |
| 747 cur += raw_obj->VisitPointers(visitor); | 769 cur += raw_obj->VisitPointers(visitor); |
| 748 } | 770 } |
| 749 UnflushTLS(saved_top); | 771 UnflushTLS(saved_top); |
| 750 } | 772 } |
| 751 | 773 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 808 scavenging_ = true; | 830 scavenging_ = true; |
| 809 | 831 |
| 810 failed_to_promote_ = false; | 832 failed_to_promote_ = false; |
| 811 | 833 |
| 812 PageSpace* page_space = heap_->old_space(); | 834 PageSpace* page_space = heap_->old_space(); |
| 813 NoSafepointScope no_safepoints; | 835 NoSafepointScope no_safepoints; |
| 814 | 836 |
| 815 int64_t post_safe_point = OS::GetCurrentMonotonicMicros(); | 837 int64_t post_safe_point = OS::GetCurrentMonotonicMicros(); |
| 816 heap_->RecordTime(kSafePoint, post_safe_point - pre_safe_point); | 838 heap_->RecordTime(kSafePoint, post_safe_point - pre_safe_point); |
| 817 | 839 |
| 818 if (isolate->IsMutatorThreadScheduled()) { | 840 // TODO(danunez): Abandon all threads' TLABs. Every thread should be stopped |
| 819 Thread* mutator_thread = isolate->mutator_thread(); | 841 // here anyway. |
| 820 if (mutator_thread->HasActiveTLAB()) { | 842 AbandonAllTLABs(); |
| 821 heap_->AbandonRemainingTLAB(mutator_thread); | |
| 822 } | |
| 823 } | |
| 824 | 843 |
| 825 // TODO(koda): Make verification more compatible with concurrent sweep. | 844 // TODO(koda): Make verification more compatible with concurrent sweep. |
| 826 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) { | 845 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) { |
| 827 OS::PrintErr("Verifying before Scavenge..."); | 846 OS::PrintErr("Verifying before Scavenge..."); |
| 828 heap_->Verify(kForbidMarked); | 847 heap_->Verify(kForbidMarked); |
| 829 OS::PrintErr(" done.\n"); | 848 OS::PrintErr(" done.\n"); |
| 830 } | 849 } |
| 831 | 850 |
| 832 // Prepare for a scavenge. | 851 // Prepare for a scavenge. |
| 833 SpaceUsage usage_before = GetCurrentUsage(); | 852 SpaceUsage usage_before = GetCurrentUsage(); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 942 } | 961 } |
| 943 | 962 |
| 944 Scavenge(); | 963 Scavenge(); |
| 945 | 964 |
| 946 // It is possible for objects to stay in the new space | 965 // It is possible for objects to stay in the new space |
| 947 // if the VM cannot create more pages for these objects. | 966 // if the VM cannot create more pages for these objects. |
| 948 ASSERT((UsedInWords() == 0) || failed_to_promote_); | 967 ASSERT((UsedInWords() == 0) || failed_to_promote_); |
| 949 } | 968 } |
| 950 | 969 |
| 951 } // namespace dart | 970 } // namespace dart |
| OLD | NEW |