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

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

Issue 11363226: Fail new space promotions only when old space is truly exhausted. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: correct growth policy default Created 8 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/heap.h ('k') | no next file » | 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 <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 66
67 67
68 class ScavengerVisitor : public ObjectPointerVisitor { 68 class ScavengerVisitor : public ObjectPointerVisitor {
69 public: 69 public:
70 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger) 70 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger)
71 : ObjectPointerVisitor(isolate), 71 : ObjectPointerVisitor(isolate),
72 scavenger_(scavenger), 72 scavenger_(scavenger),
73 heap_(scavenger->heap_), 73 heap_(scavenger->heap_),
74 vm_heap_(Dart::vm_isolate()->heap()), 74 vm_heap_(Dart::vm_isolate()->heap()),
75 delayed_weak_stack_(), 75 delayed_weak_stack_(),
76 growth_policy_(PageSpace::kControlGrowth),
77 bytes_promoted_(0),
76 visiting_old_pointers_(false), 78 visiting_old_pointers_(false),
77 in_scavenge_pointer_(false) {} 79 in_scavenge_pointer_(false) {}
78 80
79 void VisitPointers(RawObject** first, RawObject** last) { 81 void VisitPointers(RawObject** first, RawObject** last) {
80 for (RawObject** current = first; current <= last; current++) { 82 for (RawObject** current = first; current <= last; current++) {
81 ScavengePointer(current); 83 ScavengePointer(current);
82 } 84 }
83 } 85 }
84 86
85 GrowableArray<RawObject*>* DelayedWeakStack() { 87 GrowableArray<RawObject*>* DelayedWeakStack() {
(...skipping 14 matching lines...) Expand all
100 delay_set_.insert(std::make_pair(raw_key, raw_weak)); 102 delay_set_.insert(std::make_pair(raw_key, raw_weak));
101 } 103 }
102 104
103 void Finalize() { 105 void Finalize() {
104 DelaySet::iterator it = delay_set_.begin(); 106 DelaySet::iterator it = delay_set_.begin();
105 for (; it != delay_set_.end(); ++it) { 107 for (; it != delay_set_.end(); ++it) {
106 WeakProperty::Clear(it->second); 108 WeakProperty::Clear(it->second);
107 } 109 }
108 } 110 }
109 111
112 intptr_t bytes_promoted() { return bytes_promoted_; }
113
110 private: 114 private:
111 void UpdateStoreBuffer(RawObject** p, RawObject* obj) { 115 void UpdateStoreBuffer(RawObject** p, RawObject* obj) {
112 uword ptr = reinterpret_cast<uword>(p); 116 uword ptr = reinterpret_cast<uword>(p);
113 ASSERT(obj->IsHeapObject()); 117 ASSERT(obj->IsHeapObject());
114 ASSERT(!scavenger_->Contains(ptr)); 118 ASSERT(!scavenger_->Contains(ptr));
115 ASSERT(!heap_->CodeContains(ptr)); 119 ASSERT(!heap_->CodeContains(ptr));
116 ASSERT(heap_->Contains(ptr)); 120 ASSERT(heap_->Contains(ptr));
117 // If the newly written object is not a new object, drop it immediately. 121 // If the newly written object is not a new object, drop it immediately.
118 if (!obj->IsNewObject()) return; 122 if (!obj->IsNewObject()) return;
119 isolate()->store_buffer()->AddPointer(ptr); 123 isolate()->store_buffer()->AddPointer(ptr);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 // Not a survivor of a previous scavenge. Just copy the object into the 172 // Not a survivor of a previous scavenge. Just copy the object into the
169 // to space. 173 // to space.
170 new_addr = scavenger_->TryAllocate(size); 174 new_addr = scavenger_->TryAllocate(size);
171 } else { 175 } else {
172 // TODO(iposva): Experiment with less aggressive promotion. For example 176 // TODO(iposva): Experiment with less aggressive promotion. For example
173 // a coin toss determines if an object is promoted or whether it should 177 // a coin toss determines if an object is promoted or whether it should
174 // survive in this generation. 178 // survive in this generation.
175 // 179 //
176 // This object is a survivor of a previous scavenge. Attempt to promote 180 // This object is a survivor of a previous scavenge. Attempt to promote
177 // the object. 181 // the object.
178 new_addr = heap_->TryAllocate(size, Heap::kOld); 182 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_);
179 if (new_addr != 0) { 183 if (new_addr != 0) {
180 // If promotion succeeded then we need to remember it so that it can 184 // If promotion succeeded then we need to remember it so that it can
181 // be traversed later. 185 // be traversed later.
182 scavenger_->PushToPromotedStack(new_addr); 186 scavenger_->PushToPromotedStack(new_addr);
187 bytes_promoted_ += size;
188 } else if (!scavenger_->had_promotion_failure_) {
189 // Signal a promotion failure and set the growth policy for
190 // this, and all subsequent promotion allocations, to force
191 // growth.
192 scavenger_->had_promotion_failure_ = true;
193 growth_policy_ = PageSpace::kForceGrowth;
194 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_);
195 if (new_addr != 0) {
196 scavenger_->PushToPromotedStack(new_addr);
197 bytes_promoted_ += size;
198 } else {
199 // Promotion did not succeed. Copy into the to space
200 // instead.
201 new_addr = scavenger_->TryAllocate(size);
202 }
183 } else { 203 } else {
204 ASSERT(growth_policy_ == PageSpace::kForceGrowth);
184 // Promotion did not succeed. Copy into the to space instead. 205 // Promotion did not succeed. Copy into the to space instead.
185 scavenger_->had_promotion_failure_ = true;
186 new_addr = scavenger_->TryAllocate(size); 206 new_addr = scavenger_->TryAllocate(size);
187 } 207 }
188 } 208 }
189 // During a scavenge we always succeed to at least copy all of the 209 // During a scavenge we always succeed to at least copy all of the
190 // current objects to the to space. 210 // current objects to the to space.
191 ASSERT(new_addr != 0); 211 ASSERT(new_addr != 0);
192 // Copy the object to the new location. 212 // Copy the object to the new location.
193 memmove(reinterpret_cast<void*>(new_addr), 213 memmove(reinterpret_cast<void*>(new_addr),
194 reinterpret_cast<void*>(raw_addr), 214 reinterpret_cast<void*>(raw_addr),
195 size); 215 size);
196 // Remember forwarding address. 216 // Remember forwarding address.
197 ForwardTo(raw_addr, new_addr); 217 ForwardTo(raw_addr, new_addr);
198 } 218 }
199 // Update the reference. 219 // Update the reference.
200 RawObject* new_obj = RawObject::FromAddr(new_addr); 220 RawObject* new_obj = RawObject::FromAddr(new_addr);
201 *p = new_obj; 221 *p = new_obj;
202 // Update the store buffer as needed. 222 // Update the store buffer as needed.
203 if (visiting_old_pointers_) { 223 if (visiting_old_pointers_) {
204 UpdateStoreBuffer(p, new_obj); 224 UpdateStoreBuffer(p, new_obj);
205 } 225 }
206 } 226 }
207 227
208 Scavenger* scavenger_; 228 Scavenger* scavenger_;
209 Heap* heap_; 229 Heap* heap_;
210 Heap* vm_heap_; 230 Heap* vm_heap_;
211 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; 231 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet;
212 DelaySet delay_set_; 232 DelaySet delay_set_;
213 GrowableArray<RawObject*> delayed_weak_stack_; 233 GrowableArray<RawObject*> delayed_weak_stack_;
234 PageSpace::GrowthPolicy growth_policy_;
235 intptr_t bytes_promoted_;
214 236
215 bool visiting_old_pointers_; 237 bool visiting_old_pointers_;
216 bool in_scavenge_pointer_; 238 bool in_scavenge_pointer_;
217 239
218 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); 240 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor);
219 }; 241 };
220 242
221 243
222 class ScavengerWeakVisitor : public HandleVisitor { 244 class ScavengerWeakVisitor : public HandleVisitor {
223 public: 245 public:
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 OS::PrintErr("Verifying before Scavenge..."); 630 OS::PrintErr("Verifying before Scavenge...");
609 heap_->Verify(); 631 heap_->Verify();
610 OS::PrintErr(" done.\n"); 632 OS::PrintErr(" done.\n");
611 } 633 }
612 634
613 if (FLAG_verbose_gc) { 635 if (FLAG_verbose_gc) {
614 OS::PrintErr("Start scavenge for %s collection\n", gc_reason); 636 OS::PrintErr("Start scavenge for %s collection\n", gc_reason);
615 } 637 }
616 Timer timer(FLAG_verbose_gc, "Scavenge"); 638 Timer timer(FLAG_verbose_gc, "Scavenge");
617 timer.Start(); 639 timer.Start();
640
641 intptr_t in_use_before = in_use();
642
618 // Setup the visitor and run a scavenge. 643 // Setup the visitor and run a scavenge.
619 ScavengerVisitor visitor(isolate, this); 644 ScavengerVisitor visitor(isolate, this);
620 Prologue(isolate, invoke_api_callbacks); 645 Prologue(isolate, invoke_api_callbacks);
621 IterateRoots(isolate, &visitor, !invoke_api_callbacks); 646 IterateRoots(isolate, &visitor, !invoke_api_callbacks);
622 ProcessToSpace(&visitor); 647 ProcessToSpace(&visitor);
623 IterateWeakReferences(isolate, &visitor); 648 IterateWeakReferences(isolate, &visitor);
624 ScavengerWeakVisitor weak_visitor(this); 649 ScavengerWeakVisitor weak_visitor(this);
625 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); 650 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks);
626 visitor.Finalize(); 651 visitor.Finalize();
627 ProcessPeerReferents(); 652 ProcessPeerReferents();
628 Epilogue(isolate, invoke_api_callbacks); 653 Epilogue(isolate, invoke_api_callbacks);
629 timer.Stop(); 654 timer.Stop();
655
630 if (FLAG_verbose_gc) { 656 if (FLAG_verbose_gc) {
631 OS::PrintErr("Scavenge[%d]: %"Pd64"us\n", 657 const intptr_t KB2 = KB / 2;
658 OS::PrintErr("Scavenge[%d]: %"Pd64"us (%"Pd"K -> %"Pd"K, %"Pd"K)\n"
659 "Promoted %"Pd"K\n",
632 count_, 660 count_,
633 timer.TotalElapsedTime()); 661 timer.TotalElapsedTime(),
662 (in_use_before + KB2) / KB,
663 (in_use() + KB2) / KB,
664 (capacity() + KB2) / KB,
665 (visitor.bytes_promoted() + KB2) / KB);
634 } 666 }
635 667
636 if (FLAG_verify_after_gc) { 668 if (FLAG_verify_after_gc) {
637 OS::PrintErr("Verifying after Scavenge..."); 669 OS::PrintErr("Verifying after Scavenge...");
638 heap_->Verify(); 670 heap_->Verify();
639 OS::PrintErr(" done.\n"); 671 OS::PrintErr(" done.\n");
640 } 672 }
641 673
642 count_++; 674 count_++;
643 // Done scavenging. Reset the marker. 675 // Done scavenging. Reset the marker.
(...skipping 21 matching lines...) Expand all
665 PeerTable::iterator it = peer_table_.find(raw_obj); 697 PeerTable::iterator it = peer_table_.find(raw_obj);
666 return (it == peer_table_.end()) ? NULL : it->second; 698 return (it == peer_table_.end()) ? NULL : it->second;
667 } 699 }
668 700
669 701
670 int64_t Scavenger::PeerCount() const { 702 int64_t Scavenger::PeerCount() const {
671 return static_cast<int64_t>(peer_table_.size()); 703 return static_cast<int64_t>(peer_table_.size());
672 } 704 }
673 705
674 } // namespace dart 706 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698