| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 class ScavengerVisitor : public ObjectPointerVisitor { | 72 class ScavengerVisitor : public ObjectPointerVisitor { |
| 73 public: | 73 public: |
| 74 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger) | 74 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger) |
| 75 : ObjectPointerVisitor(isolate), | 75 : ObjectPointerVisitor(isolate), |
| 76 scavenger_(scavenger), | 76 scavenger_(scavenger), |
| 77 heap_(scavenger->heap_), | 77 heap_(scavenger->heap_), |
| 78 vm_heap_(Dart::vm_isolate()->heap()), | 78 vm_heap_(Dart::vm_isolate()->heap()), |
| 79 visited_count_(0), | 79 visited_count_(0), |
| 80 handled_count_(0), | 80 handled_count_(0), |
| 81 delayed_weak_stack_(), | 81 delayed_weak_stack_(), |
| 82 growth_policy_(PageSpace::kControlGrowth), | |
| 83 bytes_promoted_(0), | 82 bytes_promoted_(0), |
| 84 visiting_old_object_(NULL), | 83 visiting_old_object_(NULL), |
| 85 in_scavenge_pointer_(false) { } | 84 in_scavenge_pointer_(false) { } |
| 86 | 85 |
| 87 void VisitPointers(RawObject** first, RawObject** last) { | 86 void VisitPointers(RawObject** first, RawObject** last) { |
| 88 for (RawObject** current = first; current <= last; current++) { | 87 for (RawObject** current = first; current <= last; current++) { |
| 89 ScavengePointer(current); | 88 ScavengePointer(current); |
| 90 } | 89 } |
| 91 } | 90 } |
| 92 | 91 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 // to space. | 192 // to space. |
| 194 new_addr = scavenger_->TryAllocate(size); | 193 new_addr = scavenger_->TryAllocate(size); |
| 195 class_table->UpdateLiveNew(cid, size); | 194 class_table->UpdateLiveNew(cid, size); |
| 196 } else { | 195 } else { |
| 197 // TODO(iposva): Experiment with less aggressive promotion. For example | 196 // TODO(iposva): Experiment with less aggressive promotion. For example |
| 198 // a coin toss determines if an object is promoted or whether it should | 197 // a coin toss determines if an object is promoted or whether it should |
| 199 // survive in this generation. | 198 // survive in this generation. |
| 200 // | 199 // |
| 201 // This object is a survivor of a previous scavenge. Attempt to promote | 200 // This object is a survivor of a previous scavenge. Attempt to promote |
| 202 // the object. | 201 // the object. |
| 203 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_); | 202 new_addr = |
| 203 heap_->TryAllocate(size, Heap::kOld, PageSpace::kForceGrowth); |
| 204 if (new_addr != 0) { | 204 if (new_addr != 0) { |
| 205 // If promotion succeeded then we need to remember it so that it can | 205 // If promotion succeeded then we need to remember it so that it can |
| 206 // be traversed later. | 206 // be traversed later. |
| 207 scavenger_->PushToPromotedStack(new_addr); | 207 scavenger_->PushToPromotedStack(new_addr); |
| 208 bytes_promoted_ += size; | 208 bytes_promoted_ += size; |
| 209 class_table->UpdateAllocatedOld(cid, size); | 209 class_table->UpdateAllocatedOld(cid, size); |
| 210 } else if (!scavenger_->had_promotion_failure_) { | |
| 211 // Signal a promotion failure and set the growth policy for | |
| 212 // this, and all subsequent promotion allocations, to force | |
| 213 // growth. | |
| 214 scavenger_->had_promotion_failure_ = true; | |
| 215 growth_policy_ = PageSpace::kForceGrowth; | |
| 216 new_addr = heap_->TryAllocate(size, Heap::kOld, growth_policy_); | |
| 217 if (new_addr != 0) { | |
| 218 scavenger_->PushToPromotedStack(new_addr); | |
| 219 bytes_promoted_ += size; | |
| 220 class_table->UpdateAllocatedOld(cid, size); | |
| 221 } else { | |
| 222 // Promotion did not succeed. Copy into the to space | |
| 223 // instead. | |
| 224 new_addr = scavenger_->TryAllocate(size); | |
| 225 class_table->UpdateLiveNew(cid, size); | |
| 226 } | |
| 227 } else { | 210 } else { |
| 228 ASSERT(growth_policy_ == PageSpace::kForceGrowth); | |
| 229 // Promotion did not succeed. Copy into the to space instead. | 211 // Promotion did not succeed. Copy into the to space instead. |
| 230 new_addr = scavenger_->TryAllocate(size); | 212 new_addr = scavenger_->TryAllocate(size); |
| 231 class_table->UpdateLiveNew(cid, size); | 213 class_table->UpdateLiveNew(cid, size); |
| 232 } | 214 } |
| 233 } | 215 } |
| 234 // During a scavenge we always succeed to at least copy all of the | 216 // During a scavenge we always succeed to at least copy all of the |
| 235 // current objects to the to space. | 217 // current objects to the to space. |
| 236 ASSERT(new_addr != 0); | 218 ASSERT(new_addr != 0); |
| 237 // Copy the object to the new location. | 219 // Copy the object to the new location. |
| 238 memmove(reinterpret_cast<void*>(new_addr), | 220 memmove(reinterpret_cast<void*>(new_addr), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 251 } | 233 } |
| 252 | 234 |
| 253 Scavenger* scavenger_; | 235 Scavenger* scavenger_; |
| 254 Heap* heap_; | 236 Heap* heap_; |
| 255 Heap* vm_heap_; | 237 Heap* vm_heap_; |
| 256 intptr_t visited_count_; | 238 intptr_t visited_count_; |
| 257 intptr_t handled_count_; | 239 intptr_t handled_count_; |
| 258 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; | 240 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; |
| 259 DelaySet delay_set_; | 241 DelaySet delay_set_; |
| 260 GrowableArray<RawObject*> delayed_weak_stack_; | 242 GrowableArray<RawObject*> delayed_weak_stack_; |
| 261 PageSpace::GrowthPolicy growth_policy_; | |
| 262 // TODO(cshapiro): use this value to compute survival statistics for | 243 // TODO(cshapiro): use this value to compute survival statistics for |
| 263 // new space growth policy. | 244 // new space growth policy. |
| 264 intptr_t bytes_promoted_; | 245 intptr_t bytes_promoted_; |
| 265 RawObject* visiting_old_object_; | 246 RawObject* visiting_old_object_; |
| 266 bool in_scavenge_pointer_; | 247 bool in_scavenge_pointer_; |
| 267 | 248 |
| 268 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); | 249 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); |
| 269 }; | 250 }; |
| 270 | 251 |
| 271 | 252 |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 // TODO(cshapiro): Add a decision procedure for determining when the | 675 // TODO(cshapiro): Add a decision procedure for determining when the |
| 695 // the API callbacks should be invoked. | 676 // the API callbacks should be invoked. |
| 696 Scavenge(false); | 677 Scavenge(false); |
| 697 } | 678 } |
| 698 | 679 |
| 699 | 680 |
| 700 void Scavenger::Scavenge(bool invoke_api_callbacks) { | 681 void Scavenger::Scavenge(bool invoke_api_callbacks) { |
| 701 // Scavenging is not reentrant. Make sure that is the case. | 682 // Scavenging is not reentrant. Make sure that is the case. |
| 702 ASSERT(!scavenging_); | 683 ASSERT(!scavenging_); |
| 703 scavenging_ = true; | 684 scavenging_ = true; |
| 704 had_promotion_failure_ = false; | |
| 705 Isolate* isolate = Isolate::Current(); | 685 Isolate* isolate = Isolate::Current(); |
| 706 NoHandleScope no_handles(isolate); | 686 NoHandleScope no_handles(isolate); |
| 707 | 687 |
| 708 if (FLAG_verify_before_gc) { | 688 if (FLAG_verify_before_gc) { |
| 709 OS::PrintErr("Verifying before Scavenge..."); | 689 OS::PrintErr("Verifying before Scavenge..."); |
| 710 heap_->Verify(); | 690 heap_->Verify(); |
| 711 OS::PrintErr(" done.\n"); | 691 OS::PrintErr(" done.\n"); |
| 712 } | 692 } |
| 713 | 693 |
| 714 // Setup the visitor and run a scavenge. | 694 // Setup the visitor and run a scavenge. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 } | 749 } |
| 770 | 750 |
| 771 | 751 |
| 772 void Scavenger::FreeExternal(intptr_t size) { | 752 void Scavenger::FreeExternal(intptr_t size) { |
| 773 ASSERT(size >= 0); | 753 ASSERT(size >= 0); |
| 774 external_size_ -= size; | 754 external_size_ -= size; |
| 775 ASSERT(external_size_ >= 0); | 755 ASSERT(external_size_ >= 0); |
| 776 } | 756 } |
| 777 | 757 |
| 778 } // namespace dart | 758 } // namespace dart |
| OLD | NEW |