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

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

Issue 10832199: Add a weak property type to the virtual machine. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: minor clean-up Created 8 years, 4 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 | Annotate | Revision Log
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 <map>
8
7 #include "vm/dart.h" 9 #include "vm/dart.h"
8 #include "vm/dart_api_state.h" 10 #include "vm/dart_api_state.h"
9 #include "vm/isolate.h" 11 #include "vm/isolate.h"
10 #include "vm/object.h" 12 #include "vm/object.h"
11 #include "vm/stack_frame.h" 13 #include "vm/stack_frame.h"
12 #include "vm/store_buffer.h" 14 #include "vm/store_buffer.h"
13 #include "vm/verifier.h" 15 #include "vm/verifier.h"
14 #include "vm/visitor.h" 16 #include "vm/visitor.h"
15 17
16 namespace dart { 18 namespace dart {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 visiting_old_pointers_(false) {} 58 visiting_old_pointers_(false) {}
57 59
58 void VisitPointers(RawObject** first, RawObject** last) { 60 void VisitPointers(RawObject** first, RawObject** last) {
59 for (RawObject** current = first; current <= last; current++) { 61 for (RawObject** current = first; current <= last; current++) {
60 ScavengePointer(current); 62 ScavengePointer(current);
61 } 63 }
62 } 64 }
63 65
64 void VisitingOldPointers(bool value) { visiting_old_pointers_ = value; } 66 void VisitingOldPointers(bool value) { visiting_old_pointers_ = value; }
65 67
68 void DelayWeakProperty(RawWeakProperty* raw_weak) {
turnidge 2012/08/09 18:34:34 It's a shame about the code duplication between he
cshapiro 2012/08/14 04:58:18 Most of the supporting methods are now gone. Can
69 RawObject* raw_key = raw_weak->ptr()->key_;
70 DelaySet::iterator it = delay_set_.find(raw_key);
71 if (it != delay_set_.end()) {
72 ASSERT(raw_key->IsWatched());
73 WeakProperty::Push(raw_weak, &it->second);
74 } else {
75 ASSERT(!raw_key->IsWatched());
76 raw_key->SetWatchedBit();
77 delay_set_[raw_key] = raw_weak;
78 }
79 }
80
81 void Finalize() {
82 DelaySet::iterator it = delay_set_.begin();
83 for (; it != delay_set_.end(); ++it) {
84 while (it->second != Object::null()) {
85 RawWeakProperty* head = WeakProperty::Pop(&it->second);
86 WeakProperty::Clear(head);
87 }
88 }
89 }
90
66 private: 91 private:
67 void UpdateStoreBuffer(RawObject** p, RawObject* obj) { 92 void UpdateStoreBuffer(RawObject** p, RawObject* obj) {
68 uword ptr = reinterpret_cast<uword>(p); 93 uword ptr = reinterpret_cast<uword>(p);
69 ASSERT(obj->IsHeapObject()); 94 ASSERT(obj->IsHeapObject());
70 ASSERT(!scavenger_->Contains(ptr)); 95 ASSERT(!scavenger_->Contains(ptr));
71 ASSERT(!heap_->CodeContains(ptr)); 96 ASSERT(!heap_->CodeContains(ptr));
72 ASSERT(heap_->Contains(ptr)); 97 ASSERT(heap_->Contains(ptr));
73 // If the newly written object is not a new object, drop it immediately. 98 // If the newly written object is not a new object, drop it immediately.
74 if (!obj->IsNewObject()) return; 99 if (!obj->IsNewObject()) return;
75 isolate()->store_buffer()->AddPointer(ptr); 100 isolate()->store_buffer()->AddPointer(ptr);
(...skipping 17 matching lines...) Expand all
93 } 118 }
94 119
95 // Read the header word of the object and determine if the object has 120 // Read the header word of the object and determine if the object has
96 // already been copied. 121 // already been copied.
97 uword header = *reinterpret_cast<uword*>(raw_addr); 122 uword header = *reinterpret_cast<uword*>(raw_addr);
98 uword new_addr = 0; 123 uword new_addr = 0;
99 if (IsForwarding(header)) { 124 if (IsForwarding(header)) {
100 // Get the new location of the object. 125 // Get the new location of the object.
101 new_addr = ForwardedAddr(header); 126 new_addr = ForwardedAddr(header);
102 } else { 127 } else {
128 if (raw_obj->IsWatched()) {
129 DelaySet::iterator it = delay_set_.find(raw_obj);
130 ASSERT(it != delay_set_.end());
131 RawWeakProperty* raw_weak = it->second;
132 while (raw_weak != WeakProperty::null()) {
turnidge 2012/08/09 18:34:34 Ditto comment in other file regarding "Pop".
cshapiro 2012/08/14 04:58:18 Yup. Done.
133 raw_weak->VisitPointers(this);
134 RawWeakProperty* next = raw_weak->ptr()->next_;
135 raw_weak->ptr()->next_ = WeakProperty::null();
136 raw_weak = next;
137 }
138 delay_set_.erase(it);
139 raw_obj->ClearWatchedBit();
140 }
103 intptr_t size = raw_obj->Size(); 141 intptr_t size = raw_obj->Size();
104 // Check whether object should be promoted. 142 // Check whether object should be promoted.
105 if (scavenger_->survivor_end_ <= raw_addr) { 143 if (scavenger_->survivor_end_ <= raw_addr) {
106 // Not a survivor of a previous scavenge. Just copy the object into the 144 // Not a survivor of a previous scavenge. Just copy the object into the
107 // to space. 145 // to space.
108 new_addr = scavenger_->TryAllocate(size); 146 new_addr = scavenger_->TryAllocate(size);
109 } else { 147 } else {
110 // TODO(iposva): Experiment with less aggressive promotion. For example 148 // TODO(iposva): Experiment with less aggressive promotion. For example
111 // a coin toss determines if an object is promoted or whether it should 149 // a coin toss determines if an object is promoted or whether it should
112 // survive in this generation. 150 // survive in this generation.
(...skipping 26 matching lines...) Expand all
139 *p = new_obj; 177 *p = new_obj;
140 // Update the store buffer as needed. 178 // Update the store buffer as needed.
141 if (visiting_old_pointers_) { 179 if (visiting_old_pointers_) {
142 UpdateStoreBuffer(p, new_obj); 180 UpdateStoreBuffer(p, new_obj);
143 } 181 }
144 } 182 }
145 183
146 Scavenger* scavenger_; 184 Scavenger* scavenger_;
147 Heap* heap_; 185 Heap* heap_;
148 Heap* vm_heap_; 186 Heap* vm_heap_;
187 typedef std::map<RawObject*, RawWeakProperty*> DelaySet;
188 DelaySet delay_set_;
149 189
150 bool visiting_old_pointers_; 190 bool visiting_old_pointers_;
151 191
152 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); 192 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor);
153 }; 193 };
154 194
155 195
156 class ScavengerWeakVisitor : public HandleVisitor { 196 class ScavengerWeakVisitor : public HandleVisitor {
157 public: 197 public:
158 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) { 198 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) {
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 isolate->VisitWeakPersistentHandles(visitor, 472 isolate->VisitWeakPersistentHandles(visitor,
433 visit_prologue_weak_persistent_handles); 473 visit_prologue_weak_persistent_handles);
434 } 474 }
435 475
436 476
437 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) { 477 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) {
438 // Iterate until all work has been drained. 478 // Iterate until all work has been drained.
439 while ((resolved_top_ < top_) || PromotedStackHasMore()) { 479 while ((resolved_top_ < top_) || PromotedStackHasMore()) {
440 while (resolved_top_ < top_) { 480 while (resolved_top_ < top_) {
441 RawObject* raw_obj = RawObject::FromAddr(resolved_top_); 481 RawObject* raw_obj = RawObject::FromAddr(resolved_top_);
442 resolved_top_ += raw_obj->VisitPointers(visitor); 482 intptr_t class_id = raw_obj->GetClassId();
483 if (class_id != kWeakProperty) {
484 resolved_top_ += raw_obj->VisitPointers(visitor);
485 } else {
486 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj);
487 resolved_top_ += ProcessWeakProperty(raw_weak, visitor);
488 }
443 } 489 }
444 visitor->VisitingOldPointers(true); 490 visitor->VisitingOldPointers(true);
445 while (PromotedStackHasMore()) { 491 while (PromotedStackHasMore()) {
446 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack()); 492 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack());
447 // Resolve or copy all objects referred to by the current object. This 493 // Resolve or copy all objects referred to by the current object. This
448 // can potentially push more objects on this stack as well as add more 494 // can potentially push more objects on this stack as well as add more
449 // objects to be resolved in the to space. 495 // objects to be resolved in the to space.
450 raw_object->VisitPointers(visitor); 496 raw_object->VisitPointers(visitor);
451 } 497 }
452 visitor->VisitingOldPointers(false); 498 visitor->VisitingOldPointers(false);
453 } 499 }
454 } 500 }
455 501
456 502
503 uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak,
504 ScavengerVisitor* visitor) {
505 // The fate of the weak property is determined by its key.
506 RawObject* raw_key = raw_weak->ptr()->key_;
507 uword raw_addr = RawObject::ToAddr(raw_key);
508 uword header = *reinterpret_cast<uword*>(raw_addr);
509 if (!IsForwarding(header)) {
510 // Key is white. Delay the weak property.
511 visitor->DelayWeakProperty(raw_weak);
512 return raw_weak->Size();
513 } else {
514 // Key is gray or black. Make the weak property black.
515 return raw_weak->VisitPointers(visitor);
516 }
517 }
518
519
457 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { 520 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
458 uword cur = FirstObjectStart(); 521 uword cur = FirstObjectStart();
459 while (cur < top_) { 522 while (cur < top_) {
460 RawObject* raw_obj = RawObject::FromAddr(cur); 523 RawObject* raw_obj = RawObject::FromAddr(cur);
461 cur += raw_obj->VisitPointers(visitor); 524 cur += raw_obj->VisitPointers(visitor);
462 } 525 }
463 } 526 }
464 527
465 528
466 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { 529 void Scavenger::VisitObjects(ObjectVisitor* visitor) const {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 Timer timer(FLAG_verbose_gc, "Scavenge"); 563 Timer timer(FLAG_verbose_gc, "Scavenge");
501 timer.Start(); 564 timer.Start();
502 // Setup the visitor and run a scavenge. 565 // Setup the visitor and run a scavenge.
503 ScavengerVisitor visitor(isolate, this); 566 ScavengerVisitor visitor(isolate, this);
504 Prologue(isolate, invoke_api_callbacks); 567 Prologue(isolate, invoke_api_callbacks);
505 IterateRoots(isolate, &visitor, !invoke_api_callbacks); 568 IterateRoots(isolate, &visitor, !invoke_api_callbacks);
506 ProcessToSpace(&visitor); 569 ProcessToSpace(&visitor);
507 IterateWeakReferences(isolate, &visitor); 570 IterateWeakReferences(isolate, &visitor);
508 ScavengerWeakVisitor weak_visitor(this); 571 ScavengerWeakVisitor weak_visitor(this);
509 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); 572 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks);
573 visitor.Finalize();
510 Epilogue(isolate, invoke_api_callbacks); 574 Epilogue(isolate, invoke_api_callbacks);
511 timer.Stop(); 575 timer.Stop();
512 if (FLAG_verbose_gc) { 576 if (FLAG_verbose_gc) {
513 OS::PrintErr("Scavenge[%d]: %dus\n", count_, timer.TotalElapsedTime()); 577 OS::PrintErr("Scavenge[%d]: %dus\n", count_, timer.TotalElapsedTime());
514 } 578 }
515 579
516 if (FLAG_verify_after_gc) { 580 if (FLAG_verify_after_gc) {
517 OS::PrintErr("Verifying after Scavenge..."); 581 OS::PrintErr("Verifying after Scavenge...");
518 heap_->Verify(); 582 heap_->Verify();
519 OS::PrintErr(" done.\n"); 583 OS::PrintErr(" done.\n");
520 } 584 }
521 585
522 count_++; 586 count_++;
523 // Done scavenging. Reset the marker. 587 // Done scavenging. Reset the marker.
524 ASSERT(scavenging_); 588 ASSERT(scavenging_);
525 scavenging_ = false; 589 scavenging_ = false;
526 } 590 }
527 591
528 592
529 void Scavenger::WriteProtect(bool read_only) { 593 void Scavenger::WriteProtect(bool read_only) {
530 space_->Protect( 594 space_->Protect(
531 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); 595 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite);
532 } 596 }
533 597
534 } // namespace dart 598 } // 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