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 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 bool* _addr; | 72 bool* _addr; |
| 73 bool _value; | 73 bool _value; |
| 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 from_start_(scavenger_->from_->start()), | |
|
koda
2014/08/25 22:49:26
It would be nice to somehow assert here that the "
Ivan Posva
2014/08/25 22:56:23
The "assertion" is the fact that from_ is NULL if
| |
| 83 from_size_(scavenger_->from_->end() - scavenger_->from_->start()), | |
| 82 heap_(scavenger->heap_), | 84 heap_(scavenger->heap_), |
| 83 vm_heap_(Dart::vm_isolate()->heap()), | 85 vm_heap_(Dart::vm_isolate()->heap()), |
| 84 page_space_(scavenger->heap_->old_space()), | 86 page_space_(scavenger->heap_->old_space()), |
| 85 delayed_weak_stack_(), | 87 delayed_weak_stack_(), |
| 86 bytes_promoted_(0), | 88 bytes_promoted_(0), |
| 87 visiting_old_object_(NULL), | 89 visiting_old_object_(NULL), |
| 88 in_scavenge_pointer_(false) { } | 90 in_scavenge_pointer_(false) { } |
| 89 | 91 |
| 90 void VisitPointers(RawObject** first, RawObject** last) { | 92 void VisitPointers(RawObject** first, RawObject** last) { |
| 91 for (RawObject** current = first; current <= last; current++) { | 93 for (RawObject** current = first; current <= last; current++) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 BoolScope bs(&in_scavenge_pointer_, true); | 147 BoolScope bs(&in_scavenge_pointer_, true); |
| 146 #endif | 148 #endif |
| 147 | 149 |
| 148 RawObject* raw_obj = *p; | 150 RawObject* raw_obj = *p; |
| 149 | 151 |
| 150 // Fast exit if the raw object is a Smi or an old object. | 152 // Fast exit if the raw object is a Smi or an old object. |
| 151 if (!raw_obj->IsHeapObject() || raw_obj->IsOldObject()) { | 153 if (!raw_obj->IsHeapObject() || raw_obj->IsOldObject()) { |
| 152 return; | 154 return; |
| 153 } | 155 } |
| 154 | 156 |
| 157 // Objects should be contained in the heap. | |
| 158 // TODO(iposva): Add an appropriate assert here or in the return block | |
| 159 // below. | |
| 160 | |
| 161 // The scavenger is only interested in objects located in the from space. | |
| 162 // | |
| 163 // We are using address math here and relying on the unsigned underflow | |
| 164 // in the code below to avoid having two checks. | |
| 165 uword obj_offset = reinterpret_cast<uword>(raw_obj) - from_start_; | |
| 166 if (obj_offset > from_size_) { | |
| 167 return; | |
| 168 } | |
| 169 | |
| 155 uword raw_addr = RawObject::ToAddr(raw_obj); | 170 uword raw_addr = RawObject::ToAddr(raw_obj); |
| 156 // Objects should be contained in the heap. | |
| 157 // TODO(iposva): Add an appropriate assert here or in the return block | |
| 158 // below. | |
| 159 // The scavenger is only interested in objects located in the from space. | |
| 160 if (!scavenger_->from_->Contains(raw_addr)) { | |
| 161 return; | |
| 162 } | |
| 163 | |
| 164 // Read the header word of the object and determine if the object has | 171 // Read the header word of the object and determine if the object has |
| 165 // already been copied. | 172 // already been copied. |
| 166 uword header = *reinterpret_cast<uword*>(raw_addr); | 173 uword header = *reinterpret_cast<uword*>(raw_addr); |
| 167 uword new_addr = 0; | 174 uword new_addr = 0; |
| 168 if (IsForwarding(header)) { | 175 if (IsForwarding(header)) { |
| 169 // Get the new location of the object. | 176 // Get the new location of the object. |
| 170 new_addr = ForwardedAddr(header); | 177 new_addr = ForwardedAddr(header); |
| 171 } else { | 178 } else { |
| 172 if (raw_obj->IsWatched()) { | 179 if (raw_obj->IsWatched()) { |
| 173 raw_obj->ClearWatchedBit(); | 180 raw_obj->ClearWatchedBit(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 // Update the reference. | 233 // Update the reference. |
| 227 RawObject* new_obj = RawObject::FromAddr(new_addr); | 234 RawObject* new_obj = RawObject::FromAddr(new_addr); |
| 228 *p = new_obj; | 235 *p = new_obj; |
| 229 // Update the store buffer as needed. | 236 // Update the store buffer as needed. |
| 230 if (visiting_old_object_ != NULL) { | 237 if (visiting_old_object_ != NULL) { |
| 231 UpdateStoreBuffer(p, new_obj); | 238 UpdateStoreBuffer(p, new_obj); |
| 232 } | 239 } |
| 233 } | 240 } |
| 234 | 241 |
| 235 Scavenger* scavenger_; | 242 Scavenger* scavenger_; |
| 243 uword from_start_; | |
| 244 uword from_size_; | |
| 236 Heap* heap_; | 245 Heap* heap_; |
| 237 Heap* vm_heap_; | 246 Heap* vm_heap_; |
| 238 PageSpace* page_space_; | 247 PageSpace* page_space_; |
| 239 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; | 248 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; |
| 240 DelaySet delay_set_; | 249 DelaySet delay_set_; |
| 241 GrowableArray<RawObject*> delayed_weak_stack_; | 250 GrowableArray<RawObject*> delayed_weak_stack_; |
| 242 // TODO(cshapiro): use this value to compute survival statistics for | 251 // TODO(cshapiro): use this value to compute survival statistics for |
| 243 // new space growth policy. | 252 // new space growth policy. |
| 244 intptr_t bytes_promoted_; | 253 intptr_t bytes_promoted_; |
| 245 RawObject* visiting_old_object_; | 254 RawObject* visiting_old_object_; |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 773 Isolate* isolate = heap_->isolate(); | 782 Isolate* isolate = heap_->isolate(); |
| 774 PageSpace* page_space = heap_->old_space(); | 783 PageSpace* page_space = heap_->old_space(); |
| 775 NoHandleScope no_handles(isolate); | 784 NoHandleScope no_handles(isolate); |
| 776 | 785 |
| 777 if (FLAG_verify_before_gc) { | 786 if (FLAG_verify_before_gc) { |
| 778 OS::PrintErr("Verifying before Scavenge..."); | 787 OS::PrintErr("Verifying before Scavenge..."); |
| 779 heap_->Verify(); | 788 heap_->Verify(); |
| 780 OS::PrintErr(" done.\n"); | 789 OS::PrintErr(" done.\n"); |
| 781 } | 790 } |
| 782 | 791 |
| 783 // Setup the visitor and run a scavenge. | 792 // Prepare for a scavenge. |
| 784 ScavengerVisitor visitor(isolate, this); | |
| 785 SpaceUsage usage_before = GetCurrentUsage(); | 793 SpaceUsage usage_before = GetCurrentUsage(); |
| 786 intptr_t promo_candidate_words = | 794 intptr_t promo_candidate_words = |
| 787 (survivor_end_ - FirstObjectStart()) / kWordSize; | 795 (survivor_end_ - FirstObjectStart()) / kWordSize; |
| 788 Prologue(isolate, invoke_api_callbacks); | 796 Prologue(isolate, invoke_api_callbacks); |
| 789 const bool prologue_weak_are_strong = !invoke_api_callbacks; | 797 const bool prologue_weak_are_strong = !invoke_api_callbacks; |
| 798 | |
| 799 // Setup the visitor and run the scavenge. | |
| 800 ScavengerVisitor visitor(isolate, this); | |
| 790 page_space->AcquireDataLock(); | 801 page_space->AcquireDataLock(); |
| 791 IterateRoots(isolate, &visitor, prologue_weak_are_strong); | 802 IterateRoots(isolate, &visitor, prologue_weak_are_strong); |
| 792 int64_t start = OS::GetCurrentTimeMicros(); | 803 int64_t start = OS::GetCurrentTimeMicros(); |
| 793 ProcessToSpace(&visitor); | 804 ProcessToSpace(&visitor); |
| 794 int64_t middle = OS::GetCurrentTimeMicros(); | 805 int64_t middle = OS::GetCurrentTimeMicros(); |
| 795 IterateWeakReferences(isolate, &visitor); | 806 IterateWeakReferences(isolate, &visitor); |
| 796 ScavengerWeakVisitor weak_visitor(this, prologue_weak_are_strong); | 807 ScavengerWeakVisitor weak_visitor(this, prologue_weak_are_strong); |
| 797 // Include the prologue weak handles, since we must process any promotion. | 808 // Include the prologue weak handles, since we must process any promotion. |
| 798 const bool visit_prologue_weak_handles = true; | 809 const bool visit_prologue_weak_handles = true; |
| 799 IterateWeakRoots(isolate, &weak_visitor, visit_prologue_weak_handles); | 810 IterateWeakRoots(isolate, &weak_visitor, visit_prologue_weak_handles); |
| 800 visitor.Finalize(); | 811 visitor.Finalize(); |
| 801 ProcessWeakTables(); | 812 ProcessWeakTables(); |
| 802 page_space->ReleaseDataLock(); | 813 page_space->ReleaseDataLock(); |
| 814 | |
| 815 // Scavenge finished. Run accounting and epilogue. | |
| 803 int64_t end = OS::GetCurrentTimeMicros(); | 816 int64_t end = OS::GetCurrentTimeMicros(); |
| 804 heap_->RecordTime(kProcessToSpace, middle - start); | 817 heap_->RecordTime(kProcessToSpace, middle - start); |
| 805 heap_->RecordTime(kIterateWeaks, end - middle); | 818 heap_->RecordTime(kIterateWeaks, end - middle); |
| 806 stats_history_.Add(ScavengeStats(start, end, | 819 stats_history_.Add(ScavengeStats(start, end, |
| 807 usage_before, GetCurrentUsage(), | 820 usage_before, GetCurrentUsage(), |
| 808 promo_candidate_words, | 821 promo_candidate_words, |
| 809 visitor.bytes_promoted() >> kWordSizeLog2)); | 822 visitor.bytes_promoted() >> kWordSizeLog2)); |
| 810 Epilogue(isolate, &visitor, invoke_api_callbacks); | 823 Epilogue(isolate, &visitor, invoke_api_callbacks); |
| 811 | 824 |
| 812 if (FLAG_verify_after_gc) { | 825 if (FLAG_verify_after_gc) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 861 } | 874 } |
| 862 | 875 |
| 863 | 876 |
| 864 void Scavenger::FreeExternal(intptr_t size) { | 877 void Scavenger::FreeExternal(intptr_t size) { |
| 865 ASSERT(size >= 0); | 878 ASSERT(size >= 0); |
| 866 external_size_ -= size; | 879 external_size_ -= size; |
| 867 ASSERT(external_size_ >= 0); | 880 ASSERT(external_size_ >= 0); |
| 868 } | 881 } |
| 869 | 882 |
| 870 } // namespace dart | 883 } // namespace dart |
| OLD | NEW |