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 <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "vm/dart.h" | 11 #include "vm/dart.h" |
| 12 #include "vm/dart_api_state.h" | 12 #include "vm/dart_api_state.h" |
| 13 #include "vm/isolate.h" | 13 #include "vm/isolate.h" |
| 14 #include "vm/lockers.h" | 14 #include "vm/lockers.h" |
| 15 #include "vm/object.h" | 15 #include "vm/object.h" |
| 16 #include "vm/object_id_ring.h" | |
| 16 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
| 17 #include "vm/store_buffer.h" | 18 #include "vm/store_buffer.h" |
| 18 #include "vm/verifier.h" | 19 #include "vm/verifier.h" |
| 19 #include "vm/visitor.h" | 20 #include "vm/visitor.h" |
| 20 #include "vm/weak_table.h" | 21 #include "vm/weak_table.h" |
| 21 #include "vm/object_id_ring.h" | |
| 22 | 22 |
| 23 namespace dart { | 23 namespace dart { |
| 24 | 24 |
| 25 DEFINE_FLAG(int, early_tenuring_threshold, 66, | 25 DEFINE_FLAG(int, early_tenuring_threshold, 66, |
| 26 "When more than this percentage of promotion candidates survive, " | 26 "When more than this percentage of promotion candidates survive, " |
| 27 "promote all survivors of next scavenge."); | 27 "promote all survivors of next scavenge."); |
| 28 DEFINE_FLAG(int, new_gen_garbage_threshold, 90, | 28 DEFINE_FLAG(int, new_gen_garbage_threshold, 90, |
| 29 "Grow new gen when less than this percentage is garbage."); | 29 "Grow new gen when less than this percentage is garbage."); |
| 30 DEFINE_FLAG(int, new_gen_growth_factor, 4, "Grow new gen by this factor."); | 30 DEFINE_FLAG(int, new_gen_growth_factor, 4, "Grow new gen by this factor."); |
| 31 | 31 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 | 76 |
| 77 class ScavengerVisitor : public ObjectPointerVisitor { | 77 class ScavengerVisitor : public ObjectPointerVisitor { |
| 78 public: | 78 public: |
| 79 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger) | 79 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger) |
| 80 : ObjectPointerVisitor(isolate), | 80 : ObjectPointerVisitor(isolate), |
| 81 scavenger_(scavenger), | 81 scavenger_(scavenger), |
| 82 heap_(scavenger->heap_), | 82 heap_(scavenger->heap_), |
| 83 vm_heap_(Dart::vm_isolate()->heap()), | 83 vm_heap_(Dart::vm_isolate()->heap()), |
| 84 page_space_(scavenger->heap_->old_space()), | |
| 84 visited_count_(0), | 85 visited_count_(0), |
| 85 handled_count_(0), | 86 handled_count_(0), |
| 86 delayed_weak_stack_(), | 87 delayed_weak_stack_(), |
| 87 bytes_promoted_(0), | 88 bytes_promoted_(0), |
| 88 visiting_old_object_(NULL), | 89 visiting_old_object_(NULL), |
| 89 in_scavenge_pointer_(false) { } | 90 in_scavenge_pointer_(false) { } |
| 90 | 91 |
| 91 void VisitPointers(RawObject** first, RawObject** last) { | 92 void VisitPointers(RawObject** first, RawObject** last) { |
| 92 for (RawObject** current = first; current <= last; current++) { | 93 for (RawObject** current = first; current <= last; current++) { |
| 93 ScavengePointer(current); | 94 ScavengePointer(current); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 // to space. | 198 // to space. |
| 198 new_addr = scavenger_->TryAllocate(size); | 199 new_addr = scavenger_->TryAllocate(size); |
| 199 class_table->UpdateLiveNew(cid, size); | 200 class_table->UpdateLiveNew(cid, size); |
| 200 } else { | 201 } else { |
| 201 // TODO(iposva): Experiment with less aggressive promotion. For example | 202 // TODO(iposva): Experiment with less aggressive promotion. For example |
| 202 // a coin toss determines if an object is promoted or whether it should | 203 // a coin toss determines if an object is promoted or whether it should |
| 203 // survive in this generation. | 204 // survive in this generation. |
| 204 // | 205 // |
| 205 // This object is a survivor of a previous scavenge. Attempt to promote | 206 // This object is a survivor of a previous scavenge. Attempt to promote |
| 206 // the object. | 207 // the object. |
| 207 new_addr = | 208 new_addr = page_space_->TryAllocateDataLocked(size, |
| 208 heap_->TryAllocate(size, Heap::kOld, PageSpace::kForceGrowth); | 209 PageSpace::kForceGrowth); |
| 210 // heap_->TryAllocate(size, Heap::kOld, PageSpace::kForceGrowth); | |
|
koda
2014/08/20 00:10:22
Consider removing Heap::TryAllocate.
Ivan Posva
2014/08/20 03:50:54
Removed Heap::TryAllocate and its used in reading
| |
| 209 if (new_addr != 0) { | 211 if (new_addr != 0) { |
| 210 // If promotion succeeded then we need to remember it so that it can | 212 // If promotion succeeded then we need to remember it so that it can |
| 211 // be traversed later. | 213 // be traversed later. |
| 212 scavenger_->PushToPromotedStack(new_addr); | 214 scavenger_->PushToPromotedStack(new_addr); |
| 213 bytes_promoted_ += size; | 215 bytes_promoted_ += size; |
| 214 class_table->UpdateAllocatedOld(cid, size); | 216 class_table->UpdateAllocatedOld(cid, size); |
| 215 } else { | 217 } else { |
| 216 // Promotion did not succeed. Copy into the to space instead. | 218 // Promotion did not succeed. Copy into the to space instead. |
| 217 new_addr = scavenger_->TryAllocate(size); | 219 new_addr = scavenger_->TryAllocate(size); |
| 218 class_table->UpdateLiveNew(cid, size); | 220 class_table->UpdateLiveNew(cid, size); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 233 *p = new_obj; | 235 *p = new_obj; |
| 234 // Update the store buffer as needed. | 236 // Update the store buffer as needed. |
| 235 if (visiting_old_object_ != NULL) { | 237 if (visiting_old_object_ != NULL) { |
| 236 UpdateStoreBuffer(p, new_obj); | 238 UpdateStoreBuffer(p, new_obj); |
| 237 } | 239 } |
| 238 } | 240 } |
| 239 | 241 |
| 240 Scavenger* scavenger_; | 242 Scavenger* scavenger_; |
| 241 Heap* heap_; | 243 Heap* heap_; |
| 242 Heap* vm_heap_; | 244 Heap* vm_heap_; |
| 245 PageSpace* page_space_; | |
| 243 intptr_t visited_count_; | 246 intptr_t visited_count_; |
| 244 intptr_t handled_count_; | 247 intptr_t handled_count_; |
| 245 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; | 248 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; |
| 246 DelaySet delay_set_; | 249 DelaySet delay_set_; |
| 247 GrowableArray<RawObject*> delayed_weak_stack_; | 250 GrowableArray<RawObject*> delayed_weak_stack_; |
| 248 // TODO(cshapiro): use this value to compute survival statistics for | 251 // TODO(cshapiro): use this value to compute survival statistics for |
| 249 // new space growth policy. | 252 // new space growth policy. |
| 250 intptr_t bytes_promoted_; | 253 intptr_t bytes_promoted_; |
| 251 RawObject* visiting_old_object_; | 254 RawObject* visiting_old_object_; |
| 252 bool in_scavenge_pointer_; | 255 bool in_scavenge_pointer_; |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 774 // the API callbacks should be invoked. | 777 // the API callbacks should be invoked. |
| 775 Scavenge(false); | 778 Scavenge(false); |
| 776 } | 779 } |
| 777 | 780 |
| 778 | 781 |
| 779 void Scavenger::Scavenge(bool invoke_api_callbacks) { | 782 void Scavenger::Scavenge(bool invoke_api_callbacks) { |
| 780 // Scavenging is not reentrant. Make sure that is the case. | 783 // Scavenging is not reentrant. Make sure that is the case. |
| 781 ASSERT(!scavenging_); | 784 ASSERT(!scavenging_); |
| 782 scavenging_ = true; | 785 scavenging_ = true; |
| 783 Isolate* isolate = heap_->isolate(); | 786 Isolate* isolate = heap_->isolate(); |
| 787 PageSpace* page_space = heap_->old_space(); | |
| 784 NoHandleScope no_handles(isolate); | 788 NoHandleScope no_handles(isolate); |
| 785 | 789 |
| 786 if (FLAG_verify_before_gc) { | 790 if (FLAG_verify_before_gc) { |
| 787 OS::PrintErr("Verifying before Scavenge..."); | 791 OS::PrintErr("Verifying before Scavenge..."); |
| 788 heap_->Verify(); | 792 heap_->Verify(); |
| 789 OS::PrintErr(" done.\n"); | 793 OS::PrintErr(" done.\n"); |
| 790 } | 794 } |
| 791 | 795 |
| 792 // Setup the visitor and run a scavenge. | 796 // Setup the visitor and run a scavenge. |
| 793 ScavengerVisitor visitor(isolate, this); | 797 ScavengerVisitor visitor(isolate, this); |
| 794 SpaceUsage usage_before = GetCurrentUsage(); | 798 SpaceUsage usage_before = GetCurrentUsage(); |
| 795 intptr_t promo_candidate_words = | 799 intptr_t promo_candidate_words = |
| 796 (survivor_end_ - FirstObjectStart()) / kWordSize; | 800 (survivor_end_ - FirstObjectStart()) / kWordSize; |
| 797 Prologue(isolate, invoke_api_callbacks); | 801 Prologue(isolate, invoke_api_callbacks); |
| 798 const bool prologue_weak_are_strong = !invoke_api_callbacks; | 802 const bool prologue_weak_are_strong = !invoke_api_callbacks; |
| 803 page_space->AcquireDataLock(); | |
| 799 IterateRoots(isolate, &visitor, prologue_weak_are_strong); | 804 IterateRoots(isolate, &visitor, prologue_weak_are_strong); |
| 800 int64_t start = OS::GetCurrentTimeMicros(); | 805 int64_t start = OS::GetCurrentTimeMicros(); |
| 801 ProcessToSpace(&visitor); | 806 ProcessToSpace(&visitor); |
| 802 int64_t middle = OS::GetCurrentTimeMicros(); | 807 int64_t middle = OS::GetCurrentTimeMicros(); |
| 803 IterateWeakReferences(isolate, &visitor); | 808 IterateWeakReferences(isolate, &visitor); |
| 804 ScavengerWeakVisitor weak_visitor(this, prologue_weak_are_strong); | 809 ScavengerWeakVisitor weak_visitor(this, prologue_weak_are_strong); |
| 805 // Include the prologue weak handles, since we must process any promotion. | 810 // Include the prologue weak handles, since we must process any promotion. |
| 806 const bool visit_prologue_weak_handles = true; | 811 const bool visit_prologue_weak_handles = true; |
| 807 IterateWeakRoots(isolate, &weak_visitor, visit_prologue_weak_handles); | 812 IterateWeakRoots(isolate, &weak_visitor, visit_prologue_weak_handles); |
| 808 visitor.Finalize(); | 813 visitor.Finalize(); |
| 809 ProcessWeakTables(); | 814 ProcessWeakTables(); |
| 815 page_space->ReleaseDataLock(); | |
| 810 int64_t end = OS::GetCurrentTimeMicros(); | 816 int64_t end = OS::GetCurrentTimeMicros(); |
| 811 heap_->RecordTime(kProcessToSpace, middle - start); | 817 heap_->RecordTime(kProcessToSpace, middle - start); |
| 812 heap_->RecordTime(kIterateWeaks, end - middle); | 818 heap_->RecordTime(kIterateWeaks, end - middle); |
| 813 stats_history_.Add(ScavengeStats(start, end, | 819 stats_history_.Add(ScavengeStats(start, end, |
| 814 usage_before, GetCurrentUsage(), | 820 usage_before, GetCurrentUsage(), |
| 815 promo_candidate_words, | 821 promo_candidate_words, |
| 816 visitor.bytes_promoted() >> kWordSizeLog2)); | 822 visitor.bytes_promoted() >> kWordSizeLog2)); |
| 817 Epilogue(isolate, &visitor, invoke_api_callbacks); | 823 Epilogue(isolate, &visitor, invoke_api_callbacks); |
| 818 | 824 |
| 819 if (FLAG_verify_after_gc) { | 825 if (FLAG_verify_after_gc) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 868 } | 874 } |
| 869 | 875 |
| 870 | 876 |
| 871 void Scavenger::FreeExternal(intptr_t size) { | 877 void Scavenger::FreeExternal(intptr_t size) { |
| 872 ASSERT(size >= 0); | 878 ASSERT(size >= 0); |
| 873 external_size_ -= size; | 879 external_size_ -= size; |
| 874 ASSERT(external_size_ >= 0); | 880 ASSERT(external_size_ >= 0); |
| 875 } | 881 } |
| 876 | 882 |
| 877 } // namespace dart | 883 } // namespace dart |
| OLD | NEW |