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 |