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

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

Issue 2974403002: Revert "Moves the top_ and end_ words of the Scavenger into mutator thread." (Closed)
Patch Set: Created 3 years, 5 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/scavenger_test.cc » ('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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 // Get the new location of the object. 130 // Get the new location of the object.
131 new_addr = ForwardedAddr(header); 131 new_addr = ForwardedAddr(header);
132 } else { 132 } else {
133 intptr_t size = raw_obj->Size(); 133 intptr_t size = raw_obj->Size();
134 NOT_IN_PRODUCT(intptr_t cid = raw_obj->GetClassId()); 134 NOT_IN_PRODUCT(intptr_t cid = raw_obj->GetClassId());
135 NOT_IN_PRODUCT(ClassTable* class_table = isolate()->class_table()); 135 NOT_IN_PRODUCT(ClassTable* class_table = isolate()->class_table());
136 // Check whether object should be promoted. 136 // Check whether object should be promoted.
137 if (scavenger_->survivor_end_ <= raw_addr) { 137 if (scavenger_->survivor_end_ <= raw_addr) {
138 // Not a survivor of a previous scavenge. Just copy the object into the 138 // Not a survivor of a previous scavenge. Just copy the object into the
139 // to space. 139 // to space.
140 new_addr = scavenger_->AllocateGC(size); 140 new_addr = scavenger_->TryAllocate(size);
141 NOT_IN_PRODUCT(class_table->UpdateLiveNew(cid, size)); 141 NOT_IN_PRODUCT(class_table->UpdateLiveNew(cid, size));
142 } else { 142 } else {
143 // TODO(iposva): Experiment with less aggressive promotion. For example 143 // TODO(iposva): Experiment with less aggressive promotion. For example
144 // a coin toss determines if an object is promoted or whether it should 144 // a coin toss determines if an object is promoted or whether it should
145 // survive in this generation. 145 // survive in this generation.
146 // 146 //
147 // This object is a survivor of a previous scavenge. Attempt to promote 147 // This object is a survivor of a previous scavenge. Attempt to promote
148 // the object. 148 // the object.
149 new_addr = 149 new_addr =
150 page_space_->TryAllocatePromoLocked(size, PageSpace::kForceGrowth); 150 page_space_->TryAllocatePromoLocked(size, PageSpace::kForceGrowth);
151 if (new_addr != 0) { 151 if (new_addr != 0) {
152 // If promotion succeeded then we need to remember it so that it can 152 // If promotion succeeded then we need to remember it so that it can
153 // be traversed later. 153 // be traversed later.
154 scavenger_->PushToPromotedStack(new_addr); 154 scavenger_->PushToPromotedStack(new_addr);
155 bytes_promoted_ += size; 155 bytes_promoted_ += size;
156 NOT_IN_PRODUCT(class_table->UpdateAllocatedOld(cid, size)); 156 NOT_IN_PRODUCT(class_table->UpdateAllocatedOld(cid, size));
157 } else { 157 } else {
158 // Promotion did not succeed. Copy into the to space instead. 158 // Promotion did not succeed. Copy into the to space instead.
159 scavenger_->failed_to_promote_ = true; 159 scavenger_->failed_to_promote_ = true;
160 new_addr = scavenger_->AllocateGC(size); 160 new_addr = scavenger_->TryAllocate(size);
161 NOT_IN_PRODUCT(class_table->UpdateLiveNew(cid, size)); 161 NOT_IN_PRODUCT(class_table->UpdateLiveNew(cid, size));
162 } 162 }
163 } 163 }
164 // During a scavenge we always succeed to at least copy all of the 164 // During a scavenge we always succeed to at least copy all of the
165 // current objects to the to space. 165 // current objects to the to space.
166 ASSERT(new_addr != 0); 166 ASSERT(new_addr != 0);
167 // Copy the object to the new location. 167 // Copy the object to the new location.
168 memmove(reinterpret_cast<void*>(new_addr), 168 memmove(reinterpret_cast<void*>(new_addr),
169 reinterpret_cast<void*>(raw_addr), size); 169 reinterpret_cast<void*>(raw_addr), size);
170 // Remember forwarding address. 170 // Remember forwarding address.
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 return old_size_in_words; 385 return old_size_in_words;
386 } 386 }
387 } 387 }
388 388
389 389
390 SemiSpace* Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) { 390 SemiSpace* Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) {
391 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) { 391 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) {
392 (isolate->gc_prologue_callback())(); 392 (isolate->gc_prologue_callback())();
393 } 393 }
394 isolate->PrepareForGC(); 394 isolate->PrepareForGC();
395
396 // Flip the two semi-spaces so that to_ is always the space for allocating 395 // Flip the two semi-spaces so that to_ is always the space for allocating
397 // objects. 396 // objects.
398 SemiSpace* from = to_; 397 SemiSpace* from = to_;
399 398
400 const intptr_t kVmNameSize = 128; 399 const intptr_t kVmNameSize = 128;
401 char vm_name[kVmNameSize]; 400 char vm_name[kVmNameSize];
402 Heap::RegionName(heap_, Heap::kNew, vm_name, kVmNameSize); 401 Heap::RegionName(heap_, Heap::kNew, vm_name, kVmNameSize);
403 to_ = SemiSpace::New(NewSizeInWords(from->size_in_words()), vm_name); 402 to_ = SemiSpace::New(NewSizeInWords(from->size_in_words()), vm_name);
404 if (to_ == NULL) { 403 if (to_ == NULL) {
405 // TODO(koda): We could try to recover (collect old space, wait for another 404 // TODO(koda): We could try to recover (collect old space, wait for another
406 // isolate to finish scavenge, etc.). 405 // isolate to finish scavenge, etc.).
407 OUT_OF_MEMORY(); 406 OUT_OF_MEMORY();
408 } 407 }
409 UpdateMaxHeapCapacity(); 408 UpdateMaxHeapCapacity();
410 top_ = FirstObjectStart(); 409 top_ = FirstObjectStart();
411 resolved_top_ = top_; 410 resolved_top_ = top_;
412 end_ = to_->end(); 411 end_ = to_->end();
413
414 // Throw out the old information about the from space
415 if (isolate->IsMutatorThreadScheduled()) {
416 Thread* mutator_thread = isolate->mutator_thread();
417 mutator_thread->set_top(top_);
418 mutator_thread->set_end(end_);
419 }
420
421 return from; 412 return from;
422 } 413 }
423 414
424 415
425 void Scavenger::Epilogue(Isolate* isolate, 416 void Scavenger::Epilogue(Isolate* isolate,
426 SemiSpace* from, 417 SemiSpace* from,
427 bool invoke_api_callbacks) { 418 bool invoke_api_callbacks) {
428 // All objects in the to space have been copied from the from space at this 419 // All objects in the to space have been copied from the from space at this
429 // moment. 420 // moment.
430
431 // Ensure the mutator thread now has the up-to-date top_ and end_ of the
432 // semispace
433 if (isolate->IsMutatorThreadScheduled()) {
434 Thread* thread = isolate->mutator_thread();
435 thread->set_top(top_);
436 thread->set_end(end_);
437 }
438
439 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction(); 421 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction();
440 if (stats_history_.Size() >= 2) { 422 if (stats_history_.Size() >= 2) {
441 // Previous scavenge is only given half as much weight. 423 // Previous scavenge is only given half as much weight.
442 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction(); 424 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction();
443 avg_frac /= 1.0 + 0.5; // Normalize. 425 avg_frac /= 1.0 + 0.5; // Normalize.
444 } 426 }
445 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { 427 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) {
446 // Remember the limit to which objects have been copied. 428 // Remember the limit to which objects have been copied.
447 survivor_end_ = top_; 429 survivor_end_ = top_;
448 } else { 430 } else {
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 723
742 WeakProperty::Clear(cur_weak); 724 WeakProperty::Clear(cur_weak);
743 725
744 // Advance to next weak property in the queue. 726 // Advance to next weak property in the queue.
745 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak); 727 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
746 } 728 }
747 } 729 }
748 } 730 }
749 731
750 732
751 void Scavenger::FlushTLS() const {
752 if (heap_ != NULL) { // Added in for the ZeroSizeScavenger Test
753 if (heap_->isolate()->IsMutatorThreadScheduled()) {
754 Thread* mutator_thread = heap_->isolate()->mutator_thread();
755 mutator_thread->heap()->new_space()->set_top(mutator_thread->top());
756 }
757 }
758 }
759
760
761 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { 733 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
762 FlushTLS();
763 uword cur = FirstObjectStart(); 734 uword cur = FirstObjectStart();
764 while (cur < top_) { 735 while (cur < top_) {
765 RawObject* raw_obj = RawObject::FromAddr(cur); 736 RawObject* raw_obj = RawObject::FromAddr(cur);
766 cur += raw_obj->VisitPointers(visitor); 737 cur += raw_obj->VisitPointers(visitor);
767 } 738 }
768 } 739 }
769 740
770 741
771 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { 742 void Scavenger::VisitObjects(ObjectVisitor* visitor) const {
772 FlushTLS();
773 uword cur = FirstObjectStart(); 743 uword cur = FirstObjectStart();
774 while (cur < top_) { 744 while (cur < top_) {
775 RawObject* raw_obj = RawObject::FromAddr(cur); 745 RawObject* raw_obj = RawObject::FromAddr(cur);
776 visitor->VisitObject(raw_obj); 746 visitor->VisitObject(raw_obj);
777 cur += raw_obj->Size(); 747 cur += raw_obj->Size();
778 } 748 }
779 } 749 }
780 750
781 751
782 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const { 752 void Scavenger::AddRegionsToObjectSet(ObjectSet* set) const {
783 set->AddRegion(to_->start(), to_->end()); 753 set->AddRegion(to_->start(), to_->end());
784 } 754 }
785 755
786 756
787 RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const { 757 RawObject* Scavenger::FindObject(FindObjectVisitor* visitor) const {
788 ASSERT(!scavenging_); 758 ASSERT(!scavenging_);
789 FlushTLS();
790 uword cur = FirstObjectStart(); 759 uword cur = FirstObjectStart();
791 if (visitor->VisitRange(cur, top_)) { 760 if (visitor->VisitRange(cur, top_)) {
792 while (cur < top_) { 761 while (cur < top_) {
793 RawObject* raw_obj = RawObject::FromAddr(cur); 762 RawObject* raw_obj = RawObject::FromAddr(cur);
794 uword next = cur + raw_obj->Size(); 763 uword next = cur + raw_obj->Size();
795 if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) { 764 if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) {
796 return raw_obj; // Found object, return it. 765 return raw_obj; // Found object, return it.
797 } 766 }
798 cur = next; 767 cur = next;
799 } 768 }
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 // We need a safepoint here to prevent allocation right before or right after 912 // We need a safepoint here to prevent allocation right before or right after
944 // the scavenge. 913 // the scavenge.
945 // The former can introduce an object that we might fail to collect. 914 // The former can introduce an object that we might fail to collect.
946 // The latter means even if the scavenge promotes every object in the new 915 // The latter means even if the scavenge promotes every object in the new
947 // space, the new allocation means the space is not empty, 916 // space, the new allocation means the space is not empty,
948 // causing the assertion below to fail. 917 // causing the assertion below to fail.
949 SafepointOperationScope scope(Thread::Current()); 918 SafepointOperationScope scope(Thread::Current());
950 919
951 // Forces the next scavenge to promote all the objects in the new space. 920 // Forces the next scavenge to promote all the objects in the new space.
952 survivor_end_ = top_; 921 survivor_end_ = top_;
953
954 if (heap_->isolate()->IsMutatorThreadScheduled()) {
955 Thread* mutator_thread = heap_->isolate()->mutator_thread();
956 survivor_end_ = mutator_thread->top();
957 }
958
959 Scavenge(); 922 Scavenge();
960 923
961 // It is possible for objects to stay in the new space 924 // It is possible for objects to stay in the new space
962 // if the VM cannot create more pages for these objects. 925 // if the VM cannot create more pages for these objects.
963 ASSERT((UsedInWords() == 0) || failed_to_promote_); 926 ASSERT((UsedInWords() == 0) || failed_to_promote_);
964 } 927 }
965 928
966 } // namespace dart 929 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/scavenger.h ('k') | runtime/vm/scavenger_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698