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

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

Issue 2991343003: Makes new space iterable by filling up the mutator's TLAB (Closed)
Patch Set: Removes a safepoint assertion in FillRemainingTLAB 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
« no previous file with comments | « runtime/vm/scavenger.h ('k') | runtime/vm/thread.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 if (to_ == NULL) { 387 if (to_ == NULL) {
388 // TODO(koda): We could try to recover (collect old space, wait for another 388 // TODO(koda): We could try to recover (collect old space, wait for another
389 // isolate to finish scavenge, etc.). 389 // isolate to finish scavenge, etc.).
390 OUT_OF_MEMORY(); 390 OUT_OF_MEMORY();
391 } 391 }
392 UpdateMaxHeapCapacity(); 392 UpdateMaxHeapCapacity();
393 top_ = FirstObjectStart(); 393 top_ = FirstObjectStart();
394 resolved_top_ = top_; 394 resolved_top_ = top_;
395 end_ = to_->end(); 395 end_ = to_->end();
396 396
397 // Throw out the old information about the from space
398 if (isolate->IsMutatorThreadScheduled()) {
399 Thread* mutator_thread = isolate->mutator_thread();
400 mutator_thread->set_top(top_);
401 mutator_thread->set_end(end_);
402 }
403
404 return from; 397 return from;
405 } 398 }
406 399
407 void Scavenger::Epilogue(Isolate* isolate, 400 void Scavenger::Epilogue(Isolate* isolate,
408 SemiSpace* from, 401 SemiSpace* from,
409 bool invoke_api_callbacks) { 402 bool invoke_api_callbacks) {
410 // All objects in the to space have been copied from the from space at this 403 // All objects in the to space have been copied from the from space at this
411 // moment. 404 // moment.
412 405
413 // Ensure the mutator thread now has the up-to-date top_ and end_ of the 406 // Ensure the mutator thread will fail the next allocation. This will force
414 // semispace 407 // mutator to allocate a new TLAB
415 if (isolate->IsMutatorThreadScheduled()) { 408 if (isolate->IsMutatorThreadScheduled()) {
416 Thread* thread = isolate->mutator_thread(); 409 Thread* mutator_thread = isolate->mutator_thread();
417 thread->set_top(top_); 410 ASSERT(!mutator_thread->HasActiveTLAB());
418 thread->set_end(end_);
419 } 411 }
420 412
421 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction(); 413 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction();
422 if (stats_history_.Size() >= 2) { 414 if (stats_history_.Size() >= 2) {
423 // Previous scavenge is only given half as much weight. 415 // Previous scavenge is only given half as much weight.
424 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction(); 416 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction();
425 avg_frac /= 1.0 + 0.5; // Normalize. 417 avg_frac /= 1.0 + 0.5; // Normalize.
426 } 418 }
427 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { 419 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) {
428 // Remember the limit to which objects have been copied. 420 // Remember the limit to which objects have been copied.
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 #endif // defined(DEBUG) 707 #endif // defined(DEBUG)
716 708
717 WeakProperty::Clear(cur_weak); 709 WeakProperty::Clear(cur_weak);
718 710
719 // Advance to next weak property in the queue. 711 // Advance to next weak property in the queue.
720 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak); 712 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
721 } 713 }
722 } 714 }
723 } 715 }
724 716
725 void Scavenger::FlushTLS() const { 717 uword Scavenger::FlushTLS() const {
726 ASSERT(heap_ != NULL); 718 ASSERT(heap_ != NULL);
727 if (heap_->isolate()->IsMutatorThreadScheduled()) { 719 uword saved_top = top_;
720 if (heap_->isolate()->IsMutatorThreadScheduled() && !scavenging_) {
728 Thread* mutator_thread = heap_->isolate()->mutator_thread(); 721 Thread* mutator_thread = heap_->isolate()->mutator_thread();
729 mutator_thread->heap()->new_space()->set_top(mutator_thread->top()); 722 saved_top = mutator_thread->heap()->new_space()->top();
723 if (mutator_thread->HasActiveTLAB()) {
724 ASSERT(mutator_thread->top() <=
725 mutator_thread->heap()->new_space()->top());
726 heap_->FillRemainingTLAB(mutator_thread);
727 }
728 }
729 return saved_top;
730 }
731
732 void Scavenger::UnflushTLS(uword value) const {
733 ASSERT(heap_ != NULL);
734 if (heap_->isolate()->IsMutatorThreadScheduled() && !scavenging_) {
735 Thread* mutator_thread = heap_->isolate()->mutator_thread();
736 mutator_thread->heap()->new_space()->set_top(value);
737 ASSERT(mutator_thread->top() <= mutator_thread->heap()->new_space()->top());
730 } 738 }
731 } 739 }
732 740
733 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { 741 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
734 FlushTLS(); 742 uword saved_top = FlushTLS();
735 uword cur = FirstObjectStart(); 743 uword cur = FirstObjectStart();
736 while (cur < top_) { 744 while (cur < top_) {
737 RawObject* raw_obj = RawObject::FromAddr(cur); 745 RawObject* raw_obj = RawObject::FromAddr(cur);
738 cur += raw_obj->VisitPointers(visitor); 746 cur += raw_obj->VisitPointers(visitor);
739 } 747 }
748 UnflushTLS(saved_top);
740 } 749 }
741 750
742 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { 751 void Scavenger::VisitObjects(ObjectVisitor* visitor) const {
743 FlushTLS(); 752 uword saved_top = FlushTLS();
744 uword cur = FirstObjectStart(); 753 uword cur = FirstObjectStart();
745 while (cur < top_) { 754 while (cur < top_) {
746 RawObject* raw_obj = RawObject::FromAddr(cur); 755 RawObject* raw_obj = RawObject::FromAddr(cur);
747 visitor->VisitObject(raw_obj); 756 visitor->VisitObject(raw_obj);
748 cur += raw_obj->Size(); 757 cur += raw_obj->Size();
749 } 758 }
759 UnflushTLS(saved_top);
750 } 760 }
751 761
752 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const { 762 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const {
753 set->AddRegion(to_->start(), to_->end()); 763 set->AddRegion(to_->start(), to_->end());
754 } 764 }
755 765
756 RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const { 766 RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const {
757 ASSERT(!scavenging_); 767 ASSERT(!scavenging_);
758 FlushTLS(); 768 uword saved_top = FlushTLS();
759 uword cur = FirstObjectStart(); 769 uword cur = FirstObjectStart();
760 if (visitor->VisitRange(cur, top_)) { 770 if (visitor->VisitRange(cur, top_)) {
761 while (cur < top_) { 771 while (cur < top_) {
762 RawObject* raw_obj = RawObject::FromAddr(cur); 772 RawObject* raw_obj = RawObject::FromAddr(cur);
763 uword next = cur + raw_obj->Size(); 773 uword next = cur + raw_obj->Size();
764 if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) { 774 if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) {
775 UnflushTLS(saved_top);
765 return raw_obj; // Found object, return it. 776 return raw_obj; // Found object, return it.
766 } 777 }
767 cur = next; 778 cur = next;
768 } 779 }
769 ASSERT(cur == top_); 780 ASSERT(cur == top_);
770 } 781 }
782 UnflushTLS(saved_top);
771 return Object::null(); 783 return Object::null();
772 } 784 }
773 785
774 void Scavenger::Scavenge() { 786 void Scavenger::Scavenge() {
775 // TODO(cshapiro): Add a decision procedure for determining when the 787 // TODO(cshapiro): Add a decision procedure for determining when the
776 // the API callbacks should be invoked. 788 // the API callbacks should be invoked.
777 Scavenge(false); 789 Scavenge(false);
778 } 790 }
779 791
780 void Scavenger::Scavenge(bool invoke_api_callbacks) { 792 void Scavenger::Scavenge(bool invoke_api_callbacks) {
(...skipping 14 matching lines...) Expand all
795 scavenging_ = true; 807 scavenging_ = true;
796 808
797 failed_to_promote_ = false; 809 failed_to_promote_ = false;
798 810
799 PageSpace* page_space = heap_->old_space(); 811 PageSpace* page_space = heap_->old_space();
800 NoSafepointScope no_safepoints; 812 NoSafepointScope no_safepoints;
801 813
802 int64_t post_safe_point = OS::GetCurrentMonotonicMicros(); 814 int64_t post_safe_point = OS::GetCurrentMonotonicMicros();
803 heap_->RecordTime(kSafePoint, post_safe_point - pre_safe_point); 815 heap_->RecordTime(kSafePoint, post_safe_point - pre_safe_point);
804 816
817 if (isolate->IsMutatorThreadScheduled()) {
818 Thread* mutator_thread = isolate->mutator_thread();
819 if (mutator_thread->HasActiveTLAB()) {
820 heap_->AbandonRemainingTLAB(mutator_thread);
821 }
822 }
823
805 // TODO(koda): Make verification more compatible with concurrent sweep. 824 // TODO(koda): Make verification more compatible with concurrent sweep.
806 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) { 825 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) {
807 OS::PrintErr("Verifying before Scavenge..."); 826 OS::PrintErr("Verifying before Scavenge...");
808 heap_->Verify(kForbidMarked); 827 heap_->Verify(kForbidMarked);
809 OS::PrintErr(" done.\n"); 828 OS::PrintErr(" done.\n");
810 } 829 }
811 830
812 // Prepare for a scavenge. 831 // Prepare for a scavenge.
813 SpaceUsage usage_before = GetCurrentUsage(); 832 SpaceUsage usage_before = GetCurrentUsage();
814 intptr_t promo_candidate_words = 833 intptr_t promo_candidate_words =
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 // The latter means even if the scavenge promotes every object in the new 927 // The latter means even if the scavenge promotes every object in the new
909 // space, the new allocation means the space is not empty, 928 // space, the new allocation means the space is not empty,
910 // causing the assertion below to fail. 929 // causing the assertion below to fail.
911 SafepointOperationScope scope(Thread::Current()); 930 SafepointOperationScope scope(Thread::Current());
912 931
913 // Forces the next scavenge to promote all the objects in the new space. 932 // Forces the next scavenge to promote all the objects in the new space.
914 survivor_end_ = top_; 933 survivor_end_ = top_;
915 934
916 if (heap_->isolate()->IsMutatorThreadScheduled()) { 935 if (heap_->isolate()->IsMutatorThreadScheduled()) {
917 Thread* mutator_thread = heap_->isolate()->mutator_thread(); 936 Thread* mutator_thread = heap_->isolate()->mutator_thread();
918 survivor_end_ = mutator_thread->top(); 937 if (mutator_thread->HasActiveTLAB()) {
938 survivor_end_ = mutator_thread->top();
939 }
919 } 940 }
920 941
921 Scavenge(); 942 Scavenge();
922 943
923 // It is possible for objects to stay in the new space 944 // It is possible for objects to stay in the new space
924 // if the VM cannot create more pages for these objects. 945 // if the VM cannot create more pages for these objects.
925 ASSERT((UsedInWords() == 0) || failed_to_promote_); 946 ASSERT((UsedInWords() == 0) || failed_to_promote_);
926 } 947 }
927 948
949 int64_t Scavenger::UsedInWords() const {
950 uword saved_top = FlushTLS();
951 int64_t used_in_words = (top_ - FirstObjectStart()) >> kWordSizeLog2;
952 UnflushTLS(saved_top);
953 return used_in_words;
954 }
955
928 } // namespace dart 956 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/scavenger.h ('k') | runtime/vm/thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698