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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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* thread = isolate->mutator_thread(); |
| 417 thread->set_top(top_); | 410 thread->set_top(top_); |
|
rmacnak
2017/07/25 21:02:45
Can this use zeroes?
danunez
2017/07/26 20:19:20
Good call. Found a latent error by changing this t
| |
| 418 thread->set_end(end_); | 411 thread->set_end(top_); |
| 419 } | 412 } |
| 420 | 413 |
| 421 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction(); | 414 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction(); |
| 422 if (stats_history_.Size() >= 2) { | 415 if (stats_history_.Size() >= 2) { |
| 423 // Previous scavenge is only given half as much weight. | 416 // Previous scavenge is only given half as much weight. |
| 424 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction(); | 417 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction(); |
| 425 avg_frac /= 1.0 + 0.5; // Normalize. | 418 avg_frac /= 1.0 + 0.5; // Normalize. |
| 426 } | 419 } |
| 427 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { | 420 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { |
| 428 // Remember the limit to which objects have been copied. | 421 // Remember the limit to which objects have been copied. |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 711 #endif // defined(DEBUG) | 704 #endif // defined(DEBUG) |
| 712 | 705 |
| 713 WeakProperty::Clear(cur_weak); | 706 WeakProperty::Clear(cur_weak); |
| 714 | 707 |
| 715 // Advance to next weak property in the queue. | 708 // Advance to next weak property in the queue. |
| 716 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak); | 709 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak); |
| 717 } | 710 } |
| 718 } | 711 } |
| 719 } | 712 } |
| 720 | 713 |
| 721 void Scavenger::FlushTLS() const { | 714 uword Scavenger::FlushTLS() const { |
| 722 ASSERT(heap_ != NULL); | 715 ASSERT(heap_ != NULL); |
| 723 if (heap_->isolate()->IsMutatorThreadScheduled()) { | 716 uword top_bk = top_; |
|
rmacnak
2017/07/25 21:02:45
Throughout this file: saved_top
danunez
2017/07/26 20:19:20
Done.
| |
| 717 if (heap_->isolate()->IsMutatorThreadScheduled() && !scavenging_) { | |
| 724 Thread* mutator_thread = heap_->isolate()->mutator_thread(); | 718 Thread* mutator_thread = heap_->isolate()->mutator_thread(); |
| 719 top_bk = mutator_thread->heap()->new_space()->top(); | |
| 720 ASSERT(mutator_thread->top() <= mutator_thread->heap()->new_space()->top()); | |
| 725 mutator_thread->heap()->new_space()->set_top(mutator_thread->top()); | 721 mutator_thread->heap()->new_space()->set_top(mutator_thread->top()); |
| 726 } | 722 } |
| 723 return top_bk; | |
| 724 } | |
| 725 | |
| 726 void Scavenger::UnflushTLS(uword value) const { | |
| 727 ASSERT(heap_ != NULL); | |
| 728 if (heap_->isolate()->IsMutatorThreadScheduled() && !scavenging_) { | |
| 729 Thread* mutator_thread = heap_->isolate()->mutator_thread(); | |
| 730 mutator_thread->heap()->new_space()->set_top(value); | |
| 731 ASSERT(mutator_thread->top() <= mutator_thread->heap()->new_space()->top()); | |
| 732 } | |
| 727 } | 733 } |
| 728 | 734 |
| 729 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { | 735 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
| 730 FlushTLS(); | 736 uword backup = FlushTLS(); |
| 731 uword cur = FirstObjectStart(); | 737 uword cur = FirstObjectStart(); |
| 732 while (cur < top_) { | 738 while (cur < top_) { |
| 733 RawObject* raw_obj = RawObject::FromAddr(cur); | 739 RawObject* raw_obj = RawObject::FromAddr(cur); |
| 734 cur += raw_obj->VisitPointers(visitor); | 740 cur += raw_obj->VisitPointers(visitor); |
| 735 } | 741 } |
| 742 UnflushTLS(backup); | |
| 736 } | 743 } |
| 737 | 744 |
| 738 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { | 745 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { |
| 739 FlushTLS(); | 746 uword backup = FlushTLS(); |
| 740 uword cur = FirstObjectStart(); | 747 uword cur = FirstObjectStart(); |
| 741 while (cur < top_) { | 748 while (cur < top_) { |
| 742 RawObject* raw_obj = RawObject::FromAddr(cur); | 749 RawObject* raw_obj = RawObject::FromAddr(cur); |
| 743 visitor->VisitObject(raw_obj); | 750 visitor->VisitObject(raw_obj); |
| 744 cur += raw_obj->Size(); | 751 cur += raw_obj->Size(); |
| 745 } | 752 } |
| 753 UnflushTLS(backup); | |
| 746 } | 754 } |
| 747 | 755 |
| 748 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const { | 756 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const { |
| 749 set->AddRegion(to_->start(), to_->end()); | 757 set->AddRegion(to_->start(), to_->end()); |
| 750 } | 758 } |
| 751 | 759 |
| 752 RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const { | 760 RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const { |
| 753 ASSERT(!scavenging_); | 761 ASSERT(!scavenging_); |
| 754 FlushTLS(); | 762 uword backup = FlushTLS(); |
| 755 uword cur = FirstObjectStart(); | 763 uword cur = FirstObjectStart(); |
| 756 if (visitor->VisitRange(cur, top_)) { | 764 if (visitor->VisitRange(cur, top_)) { |
| 757 while (cur < top_) { | 765 while (cur < top_) { |
| 758 RawObject* raw_obj = RawObject::FromAddr(cur); | 766 RawObject* raw_obj = RawObject::FromAddr(cur); |
| 759 uword next = cur + raw_obj->Size(); | 767 uword next = cur + raw_obj->Size(); |
| 760 if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) { | 768 if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) { |
| 769 UnflushTLS(backup); | |
| 761 return raw_obj; // Found object, return it. | 770 return raw_obj; // Found object, return it. |
| 762 } | 771 } |
| 763 cur = next; | 772 cur = next; |
| 764 } | 773 } |
| 765 ASSERT(cur == top_); | 774 ASSERT(cur == top_); |
| 766 } | 775 } |
| 776 UnflushTLS(backup); | |
| 767 return Object::null(); | 777 return Object::null(); |
| 768 } | 778 } |
| 769 | 779 |
| 770 void Scavenger::Scavenge() { | 780 void Scavenger::Scavenge() { |
| 771 // TODO(cshapiro): Add a decision procedure for determining when the | 781 // TODO(cshapiro): Add a decision procedure for determining when the |
| 772 // the API callbacks should be invoked. | 782 // the API callbacks should be invoked. |
| 773 Scavenge(false); | 783 Scavenge(false); |
| 774 } | 784 } |
| 775 | 785 |
| 776 void Scavenger::Scavenge(bool invoke_api_callbacks) { | 786 void Scavenger::Scavenge(bool invoke_api_callbacks) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 791 scavenging_ = true; | 801 scavenging_ = true; |
| 792 | 802 |
| 793 failed_to_promote_ = false; | 803 failed_to_promote_ = false; |
| 794 | 804 |
| 795 PageSpace* page_space = heap_->old_space(); | 805 PageSpace* page_space = heap_->old_space(); |
| 796 NoSafepointScope no_safepoints; | 806 NoSafepointScope no_safepoints; |
| 797 | 807 |
| 798 int64_t post_safe_point = OS::GetCurrentMonotonicMicros(); | 808 int64_t post_safe_point = OS::GetCurrentMonotonicMicros(); |
| 799 heap_->RecordTime(kSafePoint, post_safe_point - pre_safe_point); | 809 heap_->RecordTime(kSafePoint, post_safe_point - pre_safe_point); |
| 800 | 810 |
| 811 if (thread->IsMutatorThread() && isolate->IsMutatorThreadScheduled()) { | |
| 812 heap_->MakeTLABIterable(thread->top(), thread->end()); | |
| 813 } | |
| 814 | |
| 801 // TODO(koda): Make verification more compatible with concurrent sweep. | 815 // TODO(koda): Make verification more compatible with concurrent sweep. |
| 802 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) { | 816 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) { |
| 803 OS::PrintErr("Verifying before Scavenge..."); | 817 OS::PrintErr("Verifying before Scavenge..."); |
| 804 heap_->Verify(kForbidMarked); | 818 heap_->Verify(kForbidMarked); |
| 805 OS::PrintErr(" done.\n"); | 819 OS::PrintErr(" done.\n"); |
| 806 } | 820 } |
| 807 | 821 |
| 808 // Prepare for a scavenge. | 822 // Prepare for a scavenge. |
| 809 SpaceUsage usage_before = GetCurrentUsage(); | 823 SpaceUsage usage_before = GetCurrentUsage(); |
| 810 intptr_t promo_candidate_words = | 824 intptr_t promo_candidate_words = |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 915 } | 929 } |
| 916 | 930 |
| 917 Scavenge(); | 931 Scavenge(); |
| 918 | 932 |
| 919 // It is possible for objects to stay in the new space | 933 // It is possible for objects to stay in the new space |
| 920 // if the VM cannot create more pages for these objects. | 934 // if the VM cannot create more pages for these objects. |
| 921 ASSERT((UsedInWords() == 0) || failed_to_promote_); | 935 ASSERT((UsedInWords() == 0) || failed_to_promote_); |
| 922 } | 936 } |
| 923 | 937 |
| 924 } // namespace dart | 938 } // namespace dart |
| OLD | NEW |