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

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

Issue 2001713002: - Removed the kWatchedBit and the associated weak property handling (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months 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
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>
8 #include <map>
9 #include <utility>
10
11 #include "vm/dart.h" 7 #include "vm/dart.h"
12 #include "vm/dart_api_state.h" 8 #include "vm/dart_api_state.h"
13 #include "vm/isolate.h" 9 #include "vm/isolate.h"
14 #include "vm/lockers.h" 10 #include "vm/lockers.h"
15 #include "vm/object.h" 11 #include "vm/object.h"
16 #include "vm/object_id_ring.h" 12 #include "vm/object_id_ring.h"
17 #include "vm/safepoint.h" 13 #include "vm/safepoint.h"
18 #include "vm/stack_frame.h" 14 #include "vm/stack_frame.h"
19 #include "vm/store_buffer.h" 15 #include "vm/store_buffer.h"
20 #include "vm/thread_registry.h" 16 #include "vm/thread_registry.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 } 52 }
57 53
58 54
59 static inline void ForwardTo(uword original, uword target) { 55 static inline void ForwardTo(uword original, uword target) {
60 // Make sure forwarding can be encoded. 56 // Make sure forwarding can be encoded.
61 ASSERT((target & kForwardingMask) == 0); 57 ASSERT((target & kForwardingMask) == 0);
62 *reinterpret_cast<uword*>(original) = target | kForwarded; 58 *reinterpret_cast<uword*>(original) = target | kForwarded;
63 } 59 }
64 60
65 61
66 class BoolScope : public ValueObject {
67 public:
68 BoolScope(bool* addr, bool value) : _addr(addr), _value(*addr) {
69 *_addr = value;
70 }
71 ~BoolScope() {
72 *_addr = _value;
73 }
74
75 private:
76 bool* _addr;
77 bool _value;
78 };
79
80
81 class ScavengerVisitor : public ObjectPointerVisitor { 62 class ScavengerVisitor : public ObjectPointerVisitor {
82 public: 63 public:
83 explicit ScavengerVisitor(Isolate* isolate, 64 explicit ScavengerVisitor(Isolate* isolate,
84 Scavenger* scavenger, 65 Scavenger* scavenger,
85 SemiSpace* from) 66 SemiSpace* from)
86 : ObjectPointerVisitor(isolate), 67 : ObjectPointerVisitor(isolate),
87 thread_(Thread::Current()), 68 thread_(Thread::Current()),
88 scavenger_(scavenger), 69 scavenger_(scavenger),
89 from_(from), 70 from_(from),
90 heap_(scavenger->heap_), 71 heap_(scavenger->heap_),
91 vm_heap_(Dart::vm_isolate()->heap()), 72 vm_heap_(Dart::vm_isolate()->heap()),
92 page_space_(scavenger->heap_->old_space()), 73 page_space_(scavenger->heap_->old_space()),
93 delayed_weak_stack_(),
94 bytes_promoted_(0), 74 bytes_promoted_(0),
95 visiting_old_object_(NULL), 75 visiting_old_object_(NULL) { }
96 in_scavenge_pointer_(false) { }
97 76
98 void VisitPointers(RawObject** first, RawObject** last) { 77 void VisitPointers(RawObject** first, RawObject** last) {
78 ASSERT((visiting_old_object_ != NULL) ||
79 scavenger_->Contains(reinterpret_cast<uword>(first)) ||
80 !heap_->Contains(reinterpret_cast<uword>(first)));
99 for (RawObject** current = first; current <= last; current++) { 81 for (RawObject** current = first; current <= last; current++) {
100 ScavengePointer(current); 82 ScavengePointer(current);
101 } 83 }
102 } 84 }
103 85
104 GrowableArray<RawObject*>* DelayedWeakStack() {
105 return &delayed_weak_stack_;
106 }
107
108 void VisitingOldObject(RawObject* obj) { 86 void VisitingOldObject(RawObject* obj) {
109 ASSERT((obj == NULL) || obj->IsOldObject()); 87 ASSERT((obj == NULL) || obj->IsOldObject());
110 visiting_old_object_ = obj; 88 visiting_old_object_ = obj;
111 } 89 }
112 90
113 void DelayWeakProperty(RawWeakProperty* raw_weak) {
114 RawObject* raw_key = raw_weak->ptr()->key_;
115 DelaySet::iterator it = delay_set_.find(raw_key);
116 if (it != delay_set_.end()) {
117 ASSERT(raw_key->IsWatched());
118 } else {
119 ASSERT(!raw_key->IsWatched());
120 raw_key->SetWatchedBitUnsynchronized();
121 }
122 delay_set_.insert(std::make_pair(raw_key, raw_weak));
123 }
124
125 void Finalize() {
126 DelaySet::iterator it = delay_set_.begin();
127 for (; it != delay_set_.end(); ++it) {
128 WeakProperty::Clear(it->second);
129 }
130 }
131
132 intptr_t bytes_promoted() const { return bytes_promoted_; } 91 intptr_t bytes_promoted() const { return bytes_promoted_; }
133 92
134 private: 93 private:
135 void UpdateStoreBuffer(RawObject** p, RawObject* obj) { 94 void UpdateStoreBuffer(RawObject** p, RawObject* obj) {
136 uword ptr = reinterpret_cast<uword>(p); 95 uword ptr = reinterpret_cast<uword>(p);
137 ASSERT(obj->IsHeapObject()); 96 ASSERT(obj->IsHeapObject());
138 ASSERT(!scavenger_->Contains(ptr)); 97 ASSERT(!scavenger_->Contains(ptr));
139 ASSERT(!heap_->CodeContains(ptr)); 98 ASSERT(!heap_->CodeContains(ptr));
140 ASSERT(heap_->Contains(ptr)); 99 ASSERT(heap_->Contains(ptr));
141 // If the newly written object is not a new object, drop it immediately. 100 // If the newly written object is not a new object, drop it immediately.
142 if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) { 101 if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) {
143 return; 102 return;
144 } 103 }
145 visiting_old_object_->SetRememberedBit(); 104 visiting_old_object_->SetRememberedBit();
146 thread_->StoreBufferAddObjectGC(visiting_old_object_); 105 thread_->StoreBufferAddObjectGC(visiting_old_object_);
147 } 106 }
148 107
149 void ScavengePointer(RawObject** p) { 108 void ScavengePointer(RawObject** p) {
150 // ScavengePointer cannot be called recursively. 109 // ScavengePointer cannot be called recursively.
151 #ifdef DEBUG
152 ASSERT(!in_scavenge_pointer_);
153 BoolScope bs(&in_scavenge_pointer_, true);
154 #endif
155
156 RawObject* raw_obj = *p; 110 RawObject* raw_obj = *p;
157 111
158 if (raw_obj->IsSmiOrOldObject()) { 112 if (raw_obj->IsSmiOrOldObject()) {
159 return; 113 return;
160 } 114 }
161 115
162 uword raw_addr = RawObject::ToAddr(raw_obj); 116 uword raw_addr = RawObject::ToAddr(raw_obj);
163 // The scavenger is only expects objects located in the from space. 117 // The scavenger is only expects objects located in the from space.
164 ASSERT(from_->Contains(raw_addr)); 118 ASSERT(from_->Contains(raw_addr));
165 // Read the header word of the object and determine if the object has 119 // Read the header word of the object and determine if the object has
166 // already been copied. 120 // already been copied.
167 uword header = *reinterpret_cast<uword*>(raw_addr); 121 uword header = *reinterpret_cast<uword*>(raw_addr);
168 uword new_addr = 0; 122 uword new_addr = 0;
169 if (IsForwarding(header)) { 123 if (IsForwarding(header)) {
170 // Get the new location of the object. 124 // Get the new location of the object.
171 new_addr = ForwardedAddr(header); 125 new_addr = ForwardedAddr(header);
172 } else { 126 } else {
173 if (raw_obj->IsWatched()) {
174 raw_obj->ClearWatchedBitUnsynchronized();
175 std::pair<DelaySet::iterator, DelaySet::iterator> ret;
176 // Visit all elements with a key equal to this raw_obj.
177 ret = delay_set_.equal_range(raw_obj);
178 for (DelaySet::iterator it = ret.first; it != ret.second; ++it) {
179 // Remember the delayed WeakProperty. These objects have been
180 // forwarded, but have not been scavenged because their key was not
181 // known to be reachable. Now that the key object is known to be
182 // reachable, we need to visit its key and value pointers.
183 delayed_weak_stack_.Add(it->second);
184 }
185 delay_set_.erase(ret.first, ret.second);
186 }
187 intptr_t size = raw_obj->Size(); 127 intptr_t size = raw_obj->Size();
188 intptr_t cid = raw_obj->GetClassId(); 128 intptr_t cid = raw_obj->GetClassId();
189 ClassTable* class_table = isolate()->class_table(); 129 ClassTable* class_table = isolate()->class_table();
190 // Check whether object should be promoted. 130 // Check whether object should be promoted.
191 if (scavenger_->survivor_end_ <= raw_addr) { 131 if (scavenger_->survivor_end_ <= raw_addr) {
192 // Not a survivor of a previous scavenge. Just copy the object into the 132 // Not a survivor of a previous scavenge. Just copy the object into the
193 // to space. 133 // to space.
194 new_addr = scavenger_->TryAllocate(size); 134 new_addr = scavenger_->TryAllocate(size);
195 class_table->UpdateLiveNew(cid, size); 135 class_table->UpdateLiveNew(cid, size);
196 } else { 136 } else {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 UpdateStoreBuffer(p, new_obj); 174 UpdateStoreBuffer(p, new_obj);
235 } 175 }
236 } 176 }
237 177
238 Thread* thread_; 178 Thread* thread_;
239 Scavenger* scavenger_; 179 Scavenger* scavenger_;
240 SemiSpace* from_; 180 SemiSpace* from_;
241 Heap* heap_; 181 Heap* heap_;
242 Heap* vm_heap_; 182 Heap* vm_heap_;
243 PageSpace* page_space_; 183 PageSpace* page_space_;
244 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; 184 RawWeakProperty* delayed_weak_properties_;
245 DelaySet delay_set_;
246 GrowableArray<RawObject*> delayed_weak_stack_;
247 // TODO(cshapiro): use this value to compute survival statistics for
248 // new space growth policy.
249 intptr_t bytes_promoted_; 185 intptr_t bytes_promoted_;
250 RawObject* visiting_old_object_; 186 RawObject* visiting_old_object_;
251 bool in_scavenge_pointer_; 187
188 friend class Scavenger;
252 189
253 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); 190 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor);
254 }; 191 };
255 192
256 193
257 class ScavengerWeakVisitor : public HandleVisitor { 194 class ScavengerWeakVisitor : public HandleVisitor {
258 public: 195 public:
259 explicit ScavengerWeakVisitor(Scavenger* scavenger) 196 explicit ScavengerWeakVisitor(Scavenger* scavenger)
260 : HandleVisitor(Thread::Current()), 197 : HandleVisitor(Thread::Current()),
261 scavenger_(scavenger) { 198 scavenger_(scavenger) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 } 327 }
391 328
392 329
393 Scavenger::Scavenger(Heap* heap, 330 Scavenger::Scavenger(Heap* heap,
394 intptr_t max_semi_capacity_in_words, 331 intptr_t max_semi_capacity_in_words,
395 uword object_alignment) 332 uword object_alignment)
396 : heap_(heap), 333 : heap_(heap),
397 max_semi_capacity_in_words_(max_semi_capacity_in_words), 334 max_semi_capacity_in_words_(max_semi_capacity_in_words),
398 object_alignment_(object_alignment), 335 object_alignment_(object_alignment),
399 scavenging_(false), 336 scavenging_(false),
337 delayed_weak_properties_(NULL),
400 gc_time_micros_(0), 338 gc_time_micros_(0),
401 collections_(0), 339 collections_(0),
402 external_size_(0) { 340 external_size_(0) {
403 // Verify assumptions about the first word in objects which the scavenger is 341 // Verify assumptions about the first word in objects which the scavenger is
404 // going to use for forwarding pointers. 342 // going to use for forwarding pointers.
405 ASSERT(Object::tags_offset() == 0); 343 ASSERT(Object::tags_offset() == 0);
406 344
407 // Set initial size resulting in a total of three different levels. 345 // Set initial size resulting in a total of three different levels.
408 const intptr_t initial_semi_capacity_in_words = max_semi_capacity_in_words / 346 const intptr_t initial_semi_capacity_in_words = max_semi_capacity_in_words /
409 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor); 347 (FLAG_new_gen_growth_factor * FLAG_new_gen_growth_factor);
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 return true; 532 return true;
595 } 533 }
596 534
597 535
598 void Scavenger::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) { 536 void Scavenger::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) {
599 isolate->VisitWeakPersistentHandles(visitor); 537 isolate->VisitWeakPersistentHandles(visitor);
600 } 538 }
601 539
602 540
603 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) { 541 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) {
604 GrowableArray<RawObject*>* delayed_weak_stack = visitor->DelayedWeakStack();
605
606 // Iterate until all work has been drained. 542 // Iterate until all work has been drained.
607 while ((resolved_top_ < top_) || 543 while ((resolved_top_ < top_) ||
608 PromotedStackHasMore() || 544 PromotedStackHasMore()) {
609 !delayed_weak_stack->is_empty()) {
610 while (resolved_top_ < top_) { 545 while (resolved_top_ < top_) {
611 RawObject* raw_obj = RawObject::FromAddr(resolved_top_); 546 RawObject* raw_obj = RawObject::FromAddr(resolved_top_);
612 intptr_t class_id = raw_obj->GetClassId(); 547 intptr_t class_id = raw_obj->GetClassId();
613 if (class_id != kWeakPropertyCid) { 548 if (class_id != kWeakPropertyCid) {
614 resolved_top_ += raw_obj->VisitPointers(visitor); 549 resolved_top_ += raw_obj->VisitPointers(visitor);
615 } else { 550 } else {
616 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); 551 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj);
617 resolved_top_ += ProcessWeakProperty(raw_weak, visitor); 552 resolved_top_ += ProcessWeakProperty(raw_weak, visitor);
618 } 553 }
619 } 554 }
620 { 555 {
556 // Visit all the promoted objects and update/scavenge their internal
557 // pointers. Potentially this adds more objects to the to space.
621 while (PromotedStackHasMore()) { 558 while (PromotedStackHasMore()) {
622 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack()); 559 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack());
623 // Resolve or copy all objects referred to by the current object. This 560 // Resolve or copy all objects referred to by the current object. This
624 // can potentially push more objects on this stack as well as add more 561 // can potentially push more objects on this stack as well as add more
625 // objects to be resolved in the to space. 562 // objects to be resolved in the to space.
626 ASSERT(!raw_object->IsRemembered()); 563 ASSERT(!raw_object->IsRemembered());
627 visitor->VisitingOldObject(raw_object); 564 visitor->VisitingOldObject(raw_object);
628 raw_object->VisitPointers(visitor); 565 raw_object->VisitPointers(visitor);
629 } 566 }
630 visitor->VisitingOldObject(NULL); 567 visitor->VisitingOldObject(NULL);
631 } 568 }
632 while (!delayed_weak_stack->is_empty()) { 569 {
633 // Pop the delayed weak object from the stack and visit its pointers. 570 // Finished this round of scavenging. Process the pending weak properties
634 RawObject* weak_property = delayed_weak_stack->RemoveLast(); 571 // for which the keys have become reachable. Potentially this adds more
635 weak_property->VisitPointers(visitor); 572 // objects to the to space.
573 RawWeakProperty* cur_weak = delayed_weak_properties_;
574 delayed_weak_properties_ = NULL;
575 while (cur_weak != NULL) {
576 uword next_weak = cur_weak->ptr()->next_;
577 // Promoted weak properties are not enqueued. So we can guarantee that
578 // we do not need to think about store barriers here.
579 ASSERT(cur_weak->IsNewObject());
580 RawObject* raw_key = cur_weak->ptr()->key_;
581 ASSERT(raw_key->IsHeapObject());
582 // Key still points into from space even if the object has been
583 // promoted to old space by now. The key will be updated accordingly
584 // below when VisitPointers is run.
585 ASSERT(raw_key->IsNewObject());
586 uword raw_addr = RawObject::ToAddr(raw_key);
587 ASSERT(visitor->from_->Contains(raw_addr));
588 uword header = *reinterpret_cast<uword*>(raw_addr);
589 // Reset the next pointer in the weak property.
590 cur_weak->ptr()->next_ = 0;
591 if (IsForwarding(header)) {
592 cur_weak->VisitPointers(visitor);
593 } else {
594 EnqueueWeakProperty(cur_weak);
595 }
596 // Advance to next weak property in the queue.
597 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
598 }
636 } 599 }
637 } 600 }
638 } 601 }
639 602
640 603
641 void Scavenger::UpdateMaxHeapCapacity() { 604 void Scavenger::UpdateMaxHeapCapacity() {
642 if (heap_ == NULL) { 605 if (heap_ == NULL) {
643 // Some unit tests. 606 // Some unit tests.
644 return; 607 return;
645 } 608 }
(...skipping 12 matching lines...) Expand all
658 return; 621 return;
659 } 622 }
660 ASSERT(to_ != NULL); 623 ASSERT(to_ != NULL);
661 ASSERT(heap_ != NULL); 624 ASSERT(heap_ != NULL);
662 Isolate* isolate = heap_->isolate(); 625 Isolate* isolate = heap_->isolate();
663 ASSERT(isolate != NULL); 626 ASSERT(isolate != NULL);
664 isolate->GetHeapNewUsedMaxMetric()->SetValue(UsedInWords() * kWordSize); 627 isolate->GetHeapNewUsedMaxMetric()->SetValue(UsedInWords() * kWordSize);
665 } 628 }
666 629
667 630
631 void Scavenger::EnqueueWeakProperty(RawWeakProperty* raw_weak) {
632 ASSERT(raw_weak->IsHeapObject());
633 ASSERT(raw_weak->IsNewObject());
634 ASSERT(raw_weak->IsWeakProperty());
635 DEBUG_ONLY(
636 uword raw_addr = RawObject::ToAddr(raw_weak);
637 uword header = *reinterpret_cast<uword*>(raw_addr);
638 ASSERT(!IsForwarding(header));
639 )
640 ASSERT(raw_weak->ptr()->next_ == 0);
641 raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_);
642 delayed_weak_properties_ = raw_weak;
643 }
644
645
668 uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak, 646 uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak,
669 ScavengerVisitor* visitor) { 647 ScavengerVisitor* visitor) {
670 // The fate of the weak property is determined by its key. 648 // The fate of the weak property is determined by its key.
671 RawObject* raw_key = raw_weak->ptr()->key_; 649 RawObject* raw_key = raw_weak->ptr()->key_;
672 if (raw_key->IsHeapObject() && raw_key->IsNewObject()) { 650 if (raw_key->IsHeapObject() && raw_key->IsNewObject()) {
673 uword raw_addr = RawObject::ToAddr(raw_key); 651 uword raw_addr = RawObject::ToAddr(raw_key);
674 uword header = *reinterpret_cast<uword*>(raw_addr); 652 uword header = *reinterpret_cast<uword*>(raw_addr);
675 if (!IsForwarding(header)) { 653 if (!IsForwarding(header)) {
676 // Key is white. Delay the weak property. 654 // Key is white. Enqueue the weak property.
677 visitor->DelayWeakProperty(raw_weak); 655 EnqueueWeakProperty(raw_weak);
678 return raw_weak->Size(); 656 return raw_weak->Size();
679 } 657 }
680 } 658 }
681 // Key is gray or black. Make the weak property black. 659 // Key is gray or black. Make the weak property black.
682 return raw_weak->VisitPointers(visitor); 660 return raw_weak->VisitPointers(visitor);
683 } 661 }
684 662
685 663
686 void Scavenger::ProcessWeakTables() { 664 void Scavenger::ProcessWeakReferences() {
665 // Rehash the weak tables now that we know which objects survive this cycle.
687 for (int sel = 0; 666 for (int sel = 0;
688 sel < Heap::kNumWeakSelectors; 667 sel < Heap::kNumWeakSelectors;
689 sel++) { 668 sel++) {
690 WeakTable* table = heap_->GetWeakTable( 669 WeakTable* table = heap_->GetWeakTable(
691 Heap::kNew, static_cast<Heap::WeakSelector>(sel)); 670 Heap::kNew, static_cast<Heap::WeakSelector>(sel));
692 heap_->SetWeakTable(Heap::kNew, 671 heap_->SetWeakTable(Heap::kNew,
693 static_cast<Heap::WeakSelector>(sel), 672 static_cast<Heap::WeakSelector>(sel),
694 WeakTable::NewFrom(table)); 673 WeakTable::NewFrom(table));
695 intptr_t size = table->size(); 674 intptr_t size = table->size();
696 for (intptr_t i = 0; i < size; i++) { 675 for (intptr_t i = 0; i < size; i++) {
697 if (table->IsValidEntryAt(i)) { 676 if (table->IsValidEntryAt(i)) {
698 RawObject* raw_obj = table->ObjectAt(i); 677 RawObject* raw_obj = table->ObjectAt(i);
699 ASSERT(raw_obj->IsHeapObject()); 678 ASSERT(raw_obj->IsHeapObject());
700 uword raw_addr = RawObject::ToAddr(raw_obj); 679 uword raw_addr = RawObject::ToAddr(raw_obj);
701 uword header = *reinterpret_cast<uword*>(raw_addr); 680 uword header = *reinterpret_cast<uword*>(raw_addr);
702 if (IsForwarding(header)) { 681 if (IsForwarding(header)) {
703 // The object has survived. Preserve its record. 682 // The object has survived. Preserve its record.
704 uword new_addr = ForwardedAddr(header); 683 uword new_addr = ForwardedAddr(header);
705 raw_obj = RawObject::FromAddr(new_addr); 684 raw_obj = RawObject::FromAddr(new_addr);
706 heap_->SetWeakEntry(raw_obj, 685 heap_->SetWeakEntry(raw_obj,
707 static_cast<Heap::WeakSelector>(sel), 686 static_cast<Heap::WeakSelector>(sel),
708 table->ValueAt(i)); 687 table->ValueAt(i));
709 } 688 }
710 } 689 }
711 } 690 }
712 // Remove the old table as it has been replaced with the newly allocated 691 // Remove the old table as it has been replaced with the newly allocated
713 // table above. 692 // table above.
714 delete table; 693 delete table;
715 } 694 }
695
696 // The queued weak properties at this point do not refer to reachable keys,
697 // so we clear their key and value fields.
698 {
699 RawWeakProperty* cur_weak = delayed_weak_properties_;
700 delayed_weak_properties_ = NULL;
701 while (cur_weak != NULL) {
702 uword next_weak = cur_weak->ptr()->next_;
703 // Reset the next pointer in the weak property.
704 cur_weak->ptr()->next_ = 0;
705
706 DEBUG_ONLY(
707 RawObject* raw_key = cur_weak->ptr()->key_;
708 uword raw_addr = RawObject::ToAddr(raw_key);
709 uword header = *reinterpret_cast<uword*>(raw_addr);
710 ASSERT(!IsForwarding(header));
711 ASSERT(raw_key->IsHeapObject());
712 ASSERT(raw_key->IsNewObject()); // Key still points into from space.
713 )
714
715 WeakProperty::Clear(cur_weak);
716
717 // Advance to next weak property in the queue.
718 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
719 }
720 }
716 } 721 }
717 722
718 723
719 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { 724 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
720 uword cur = FirstObjectStart(); 725 uword cur = FirstObjectStart();
721 while (cur < top_) { 726 while (cur < top_) {
722 RawObject* raw_obj = RawObject::FromAddr(cur); 727 RawObject* raw_obj = RawObject::FromAddr(cur);
723 cur += raw_obj->VisitPointers(visitor); 728 cur += raw_obj->VisitPointers(visitor);
724 } 729 }
725 } 730 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 StackZone zone(Thread::Current()); 799 StackZone zone(Thread::Current());
795 // Setup the visitor and run the scavenge. 800 // Setup the visitor and run the scavenge.
796 ScavengerVisitor visitor(isolate, this, from); 801 ScavengerVisitor visitor(isolate, this, from);
797 page_space->AcquireDataLock(); 802 page_space->AcquireDataLock();
798 IterateRoots(isolate, &visitor); 803 IterateRoots(isolate, &visitor);
799 int64_t start = OS::GetCurrentTimeMicros(); 804 int64_t start = OS::GetCurrentTimeMicros();
800 ProcessToSpace(&visitor); 805 ProcessToSpace(&visitor);
801 int64_t middle = OS::GetCurrentTimeMicros(); 806 int64_t middle = OS::GetCurrentTimeMicros();
802 ScavengerWeakVisitor weak_visitor(this); 807 ScavengerWeakVisitor weak_visitor(this);
803 IterateWeakRoots(isolate, &weak_visitor); 808 IterateWeakRoots(isolate, &weak_visitor);
804 visitor.Finalize(); 809 ProcessWeakReferences();
805 ProcessWeakTables();
806 page_space->ReleaseDataLock(); 810 page_space->ReleaseDataLock();
807 811
808 // Scavenge finished. Run accounting. 812 // Scavenge finished. Run accounting.
809 int64_t end = OS::GetCurrentTimeMicros(); 813 int64_t end = OS::GetCurrentTimeMicros();
810 heap_->RecordTime(kProcessToSpace, middle - start); 814 heap_->RecordTime(kProcessToSpace, middle - start);
811 heap_->RecordTime(kIterateWeaks, end - middle); 815 heap_->RecordTime(kIterateWeaks, end - middle);
812 stats_history_.Add( 816 stats_history_.Add(
813 ScavengeStats(start, end, 817 ScavengeStats(start, end,
814 usage_before, GetCurrentUsage(), 818 usage_before, GetCurrentUsage(),
815 promo_candidate_words, 819 promo_candidate_words,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 } 875 }
872 876
873 877
874 void Scavenger::FreeExternal(intptr_t size) { 878 void Scavenger::FreeExternal(intptr_t size) {
875 ASSERT(size >= 0); 879 ASSERT(size >= 0);
876 external_size_ -= size; 880 external_size_ -= size;
877 ASSERT(external_size_ >= 0); 881 ASSERT(external_size_ >= 0);
878 } 882 }
879 883
880 } // namespace dart 884 } // namespace dart
OLDNEW
« runtime/vm/raw_object.h ('K') | « runtime/vm/scavenger.h ('k') | runtime/vm/snapshot.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698