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

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

Issue 2992753002: Prepares allocation for proper sync with mutator and bg threads. (Closed)
Patch Set: Created 3 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
OLDNEW
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
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
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
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
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
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
OLDNEW
« runtime/vm/heap.cc ('K') | « runtime/vm/scavenger.h ('k') | runtime/vm/thread_registry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698