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

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

Issue 3005623002: Revert "Puts TLABs back into the build and fixes assert failure." (Closed)
Patch Set: Created 3 years, 3 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 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()) {
329 // Verify assumptions about the first word in objects which the scavenger is 328 // Verify assumptions about the first word in objects which the scavenger is
330 // going to use for forwarding pointers. 329 // going to use for forwarding pointers.
331 ASSERT(Object::tags_offset() == 0); 330 ASSERT(Object::tags_offset() == 0);
332 331
333 // Set initial size resulting in a total of three different levels. 332 // Set initial size resulting in a total of three different levels.
334 const intptr_t initial_semi_capacity_in_words = 333 const intptr_t initial_semi_capacity_in_words =
335 max_semi_capacity_in_words / 334 max_semi_capacity_in_words /
336 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor); 335 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor);
337 336
338 const intptr_t kVmNameSize = 128; 337 const intptr_t kVmNameSize = 128;
(...skipping 10 matching lines...) Expand all
349 348
350 survivor_end_ = FirstObjectStart(); 349 survivor_end_ = FirstObjectStart();
351 350
352 UpdateMaxHeapCapacity(); 351 UpdateMaxHeapCapacity();
353 UpdateMaxHeapUsage(); 352 UpdateMaxHeapUsage();
354 } 353 }
355 354
356 Scavenger::~Scavenger() { 355 Scavenger::~Scavenger() {
357 ASSERT(!scavenging_); 356 ASSERT(!scavenging_);
358 to_->Delete(); 357 to_->Delete();
359 delete space_lock_;
360 } 358 }
361 359
362 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const { 360 intptr_t Scavenger::NewSizeInWords(intptr_t old_size_in_words) const {
363 if (stats_history_.Size() == 0) { 361 if (stats_history_.Size() == 0) {
364 return old_size_in_words; 362 return old_size_in_words;
365 } 363 }
366 double garbage = stats_history_.Get(0).ExpectedGarbageFraction(); 364 double garbage = stats_history_.Get(0).ExpectedGarbageFraction();
367 if (garbage < (FLAG_new_gen_garbage_threshold / 100.0)) { 365 if (garbage < (FLAG_new_gen_garbage_threshold / 100.0)) {
368 return Utils::Minimum(max_semi_capacity_in_words_, 366 return Utils::Minimum(max_semi_capacity_in_words_,
369 old_size_in_words * FLAG_new_gen_growth_factor); 367 old_size_in_words * FLAG_new_gen_growth_factor);
(...skipping 16 matching lines...) Expand all
386 if (to_ == NULL) { 384 if (to_ == NULL) {
387 // TODO(koda): We could try to recover (collect old space, wait for another 385 // TODO(koda): We could try to recover (collect old space, wait for another
388 // isolate to finish scavenge, etc.). 386 // isolate to finish scavenge, etc.).
389 OUT_OF_MEMORY(); 387 OUT_OF_MEMORY();
390 } 388 }
391 UpdateMaxHeapCapacity(); 389 UpdateMaxHeapCapacity();
392 top_ = FirstObjectStart(); 390 top_ = FirstObjectStart();
393 resolved_top_ = top_; 391 resolved_top_ = top_;
394 end_ = to_->end(); 392 end_ = to_->end();
395 393
394 // Throw out the old information about the from space
395 if (isolate->IsMutatorThreadScheduled()) {
396 Thread* mutator_thread = isolate->mutator_thread();
397 mutator_thread->set_top(top_);
398 mutator_thread->set_end(end_);
399 }
400
396 return from; 401 return from;
397 } 402 }
398 403
399 void Scavenger::Epilogue(Isolate* isolate, SemiSpace* from) { 404 void Scavenger::Epilogue(Isolate* isolate, SemiSpace* from) {
400 // All objects in the to space have been copied from the from space at this 405 // All objects in the to space have been copied from the from space at this
401 // moment. 406 // moment.
402 407
403 // Ensure the mutator thread will fail the next allocation. This will force 408 // Ensure the mutator thread now has the up-to-date top_ and end_ of the
404 // mutator to allocate a new TLAB 409 // semispace
405 Thread* mutator_thread = isolate->mutator_thread(); 410 if (isolate->IsMutatorThreadScheduled()) {
406 ASSERT((mutator_thread == NULL) || (!mutator_thread->HasActiveTLAB())); 411 Thread* thread = isolate->mutator_thread();
412 thread->set_top(top_);
413 thread->set_end(end_);
414 }
407 415
408 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction(); 416 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction();
409 if (stats_history_.Size() >= 2) { 417 if (stats_history_.Size() >= 2) {
410 // Previous scavenge is only given half as much weight. 418 // Previous scavenge is only given half as much weight.
411 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction(); 419 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction();
412 avg_frac /= 1.0 + 0.5; // Normalize. 420 avg_frac /= 1.0 + 0.5; // Normalize.
413 } 421 }
414 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { 422 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) {
415 // Remember the limit to which objects have been copied. 423 // Remember the limit to which objects have been copied.
416 survivor_end_ = top_; 424 survivor_end_ = top_;
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 #endif // defined(DEBUG) 707 #endif // defined(DEBUG)
700 708
701 WeakProperty::Clear(cur_weak); 709 WeakProperty::Clear(cur_weak);
702 710
703 // Advance to next weak property in the queue. 711 // Advance to next weak property in the queue.
704 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak); 712 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
705 } 713 }
706 } 714 }
707 } 715 }
708 716
709 void Scavenger::MakeAllTLABsIterable(Isolate* isolate) const { 717 void Scavenger::FlushTLS() const {
710 MonitorLocker ml(isolate->threads_lock(), false);
711 Thread* current = heap_->isolate()->thread_registry()->active_list();
712 while (current != NULL) {
713 if (current->HasActiveTLAB()) {
714 heap_->MakeTLABIterable(current);
715 }
716 current = current->next();
717 }
718 Thread* mutator_thread = isolate->mutator_thread();
719 if ((mutator_thread != NULL) && (!isolate->IsMutatorThreadScheduled())) {
720 heap_->MakeTLABIterable(mutator_thread);
721 }
722 }
723
724 void Scavenger::MakeNewSpaceIterable() const {
725 ASSERT(heap_ != NULL); 718 ASSERT(heap_ != NULL);
726 if (!scavenging_) { 719 if (heap_->isolate()->IsMutatorThreadScheduled()) {
727 MakeAllTLABsIterable(heap_->isolate()); 720 Thread* mutator_thread = heap_->isolate()->mutator_thread();
728 } 721 mutator_thread->heap()->new_space()->set_top(mutator_thread->top());
729 }
730
731 void Scavenger::AbandonAllTLABs(Isolate* isolate) {
732 MonitorLocker ml(isolate->threads_lock(), false);
733 Thread* current = isolate->thread_registry()->active_list();
734 while (current != NULL) {
735 heap_->AbandonRemainingTLAB(current);
736 current = current->next();
737 }
738 Thread* mutator_thread = isolate->mutator_thread();
739 if ((mutator_thread != NULL) && (!isolate->IsMutatorThreadScheduled())) {
740 heap_->AbandonRemainingTLAB(mutator_thread);
741 } 722 }
742 } 723 }
743 724
744 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { 725 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
745 ASSERT(Thread::Current()->IsAtSafepoint() || 726 ASSERT(Thread::Current()->IsAtSafepoint() ||
746 (Thread::Current()->task_kind() == Thread::kMarkerTask)); 727 (Thread::Current()->task_kind() == Thread::kMarkerTask));
747 MakeNewSpaceIterable(); 728 FlushTLS();
748 uword cur = FirstObjectStart(); 729 uword cur = FirstObjectStart();
749 while (cur < top_) { 730 while (cur < top_) {
750 RawObject* raw_obj = RawObject::FromAddr(cur); 731 RawObject* raw_obj = RawObject::FromAddr(cur);
751 cur += raw_obj->VisitPointers(visitor); 732 cur += raw_obj->VisitPointers(visitor);
752 } 733 }
753 } 734 }
754 735
755 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { 736 void Scavenger::VisitObjects(ObjectVisitor* visitor) const {
756 ASSERT(Thread::Current()->IsAtSafepoint() || 737 ASSERT(Thread::Current()->IsAtSafepoint() ||
757 (Thread::Current()->task_kind() == Thread::kMarkerTask)); 738 (Thread::Current()->task_kind() == Thread::kMarkerTask));
758 MakeNewSpaceIterable(); 739 FlushTLS();
759 uword cur = FirstObjectStart(); 740 uword cur = FirstObjectStart();
760 while (cur < top_) { 741 while (cur < top_) {
761 RawObject* raw_obj = RawObject::FromAddr(cur); 742 RawObject* raw_obj = RawObject::FromAddr(cur);
762 visitor->VisitObject(raw_obj); 743 visitor->VisitObject(raw_obj);
763 cur += raw_obj->Size(); 744 cur += raw_obj->Size();
764 } 745 }
765 } 746 }
766 747
767 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const { 748 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const {
768 set->AddRegion(to_->start(), to_->end()); 749 set->AddRegion(to_->start(), to_->end());
769 } 750 }
770 751
771 RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const { 752 RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const {
772 ASSERT(!scavenging_); 753 ASSERT(!scavenging_);
773 MakeNewSpaceIterable(); 754 FlushTLS();
774 uword cur = FirstObjectStart(); 755 uword cur = FirstObjectStart();
775 if (visitor->VisitRange(cur, top_)) { 756 if (visitor->VisitRange(cur, top_)) {
776 while (cur < top_) { 757 while (cur < top_) {
777 RawObject* raw_obj = RawObject::FromAddr(cur); 758 RawObject* raw_obj = RawObject::FromAddr(cur);
778 uword next = cur + raw_obj->Size(); 759 uword next = cur + raw_obj->Size();
779 if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) { 760 if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) {
780 return raw_obj; // Found object, return it. 761 return raw_obj; // Found object, return it.
781 } 762 }
782 cur = next; 763 cur = next;
783 } 764 }
(...skipping 20 matching lines...) Expand all
804 scavenging_ = true; 785 scavenging_ = true;
805 786
806 failed_to_promote_ = false; 787 failed_to_promote_ = false;
807 788
808 PageSpace* page_space = heap_->old_space(); 789 PageSpace* page_space = heap_->old_space();
809 NoSafepointScope no_safepoints; 790 NoSafepointScope no_safepoints;
810 791
811 int64_t post_safe_point = OS::GetCurrentMonotonicMicros(); 792 int64_t post_safe_point = OS::GetCurrentMonotonicMicros();
812 heap_->RecordTime(kSafePoint, post_safe_point - pre_safe_point); 793 heap_->RecordTime(kSafePoint, post_safe_point - pre_safe_point);
813 794
814 AbandonAllTLABs(isolate);
815
816 // TODO(koda): Make verification more compatible with concurrent sweep. 795 // TODO(koda): Make verification more compatible with concurrent sweep.
817 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) { 796 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) {
818 OS::PrintErr("Verifying before Scavenge..."); 797 OS::PrintErr("Verifying before Scavenge...");
819 heap_->Verify(kForbidMarked); 798 heap_->Verify(kForbidMarked);
820 OS::PrintErr(" done.\n"); 799 OS::PrintErr(" done.\n");
821 } 800 }
822 801
823 // Prepare for a scavenge. 802 // Prepare for a scavenge.
824 SpaceUsage usage_before = GetCurrentUsage(); 803 SpaceUsage usage_before = GetCurrentUsage();
825 intptr_t promo_candidate_words = 804 intptr_t promo_candidate_words =
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 // the scavenge. 896 // the scavenge.
918 // The former can introduce an object that we might fail to collect. 897 // The former can introduce an object that we might fail to collect.
919 // The latter means even if the scavenge promotes every object in the new 898 // The latter means even if the scavenge promotes every object in the new
920 // space, the new allocation means the space is not empty, 899 // space, the new allocation means the space is not empty,
921 // causing the assertion below to fail. 900 // causing the assertion below to fail.
922 SafepointOperationScope scope(Thread::Current()); 901 SafepointOperationScope scope(Thread::Current());
923 902
924 // Forces the next scavenge to promote all the objects in the new space. 903 // Forces the next scavenge to promote all the objects in the new space.
925 survivor_end_ = top_; 904 survivor_end_ = top_;
926 905
906 if (heap_->isolate()->IsMutatorThreadScheduled()) {
907 Thread* mutator_thread = heap_->isolate()->mutator_thread();
908 survivor_end_ = mutator_thread->top();
909 }
910
927 Scavenge(); 911 Scavenge();
928 912
929 // It is possible for objects to stay in the new space 913 // It is possible for objects to stay in the new space
930 // if the VM cannot create more pages for these objects. 914 // if the VM cannot create more pages for these objects.
931 ASSERT((UsedInWords() == 0) || failed_to_promote_); 915 ASSERT((UsedInWords() == 0) || failed_to_promote_);
932 } 916 }
933 917
934 int64_t Scavenger::FreeSpaceInWords(Isolate* isolate) const {
935 MonitorLocker ml(isolate->threads_lock(), false);
936 Thread* current = isolate->thread_registry()->active_list();
937 int64_t free_space = 0;
938 while (current != NULL) {
939 if (current->HasActiveTLAB()) {
940 free_space += current->end() - current->top();
941 }
942 current = current->next();
943 }
944
945 Thread* mutator_thread = isolate->mutator_thread();
946 if ((mutator_thread != NULL) && (!isolate->IsMutatorThreadScheduled())) {
947 free_space += mutator_thread->end() - mutator_thread->top();
948 }
949 return free_space >> kWordSizeLog2;
950 }
951
952 int64_t Scavenger::UsedInWords() const {
953 int64_t free_space_in_tlab = FreeSpaceInWords(heap_->isolate());
954 int64_t max_space_used = (top_ - FirstObjectStart()) >> kWordSizeLog2;
955 return max_space_used - free_space_in_tlab;
956 }
957
958 } // namespace dart 918 } // 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