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

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

Powered by Google App Engine
This is Rietveld 408576698