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

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

Powered by Google App Engine
This is Rietveld 408576698