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

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 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()) {
turnidge 2012/08/16 23:31:46 Comment here and in similar point in other file --
126 std::pair<DelaySet::iterator, DelaySet::iterator> ret;
127 ret = delay_set_.equal_range(raw_obj);
128 for (DelaySet::iterator it = ret.first; it != ret.second; ++it) {
129 it->second->VisitPointers(this);
130 }
131 delay_set_.erase(ret.first, ret.second);
132 raw_obj->ClearWatchedBit();
133 }
103 intptr_t size = raw_obj->Size(); 134 intptr_t size = raw_obj->Size();
104 // Check whether object should be promoted. 135 // Check whether object should be promoted.
105 if (scavenger_->survivor_end_ <= raw_addr) { 136 if (scavenger_->survivor_end_ <= raw_addr) {
106 // Not a survivor of a previous scavenge. Just copy the object into the 137 // Not a survivor of a previous scavenge. Just copy the object into the
107 // to space. 138 // to space.
108 new_addr = scavenger_->TryAllocate(size); 139 new_addr = scavenger_->TryAllocate(size);
109 } else { 140 } else {
110 // TODO(iposva): Experiment with less aggressive promotion. For example 141 // TODO(iposva): Experiment with less aggressive promotion. For example
111 // a coin toss determines if an object is promoted or whether it should 142 // a coin toss determines if an object is promoted or whether it should
112 // survive in this generation. 143 // survive in this generation.
(...skipping 26 matching lines...) Expand all
139 *p = new_obj; 170 *p = new_obj;
140 // Update the store buffer as needed. 171 // Update the store buffer as needed.
141 if (visiting_old_pointers_) { 172 if (visiting_old_pointers_) {
142 UpdateStoreBuffer(p, new_obj); 173 UpdateStoreBuffer(p, new_obj);
143 } 174 }
144 } 175 }
145 176
146 Scavenger* scavenger_; 177 Scavenger* scavenger_;
147 Heap* heap_; 178 Heap* heap_;
148 Heap* vm_heap_; 179 Heap* vm_heap_;
180 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet;
181 DelaySet delay_set_;
149 182
150 bool visiting_old_pointers_; 183 bool visiting_old_pointers_;
151 184
152 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); 185 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor);
153 }; 186 };
154 187
155 188
156 class ScavengerWeakVisitor : public HandleVisitor { 189 class ScavengerWeakVisitor : public HandleVisitor {
157 public: 190 public:
158 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) { 191 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) {
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 isolate->VisitWeakPersistentHandles(visitor, 465 isolate->VisitWeakPersistentHandles(visitor,
433 visit_prologue_weak_persistent_handles); 466 visit_prologue_weak_persistent_handles);
434 } 467 }
435 468
436 469
437 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) { 470 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) {
438 // Iterate until all work has been drained. 471 // Iterate until all work has been drained.
439 while ((resolved_top_ < top_) || PromotedStackHasMore()) { 472 while ((resolved_top_ < top_) || PromotedStackHasMore()) {
440 while (resolved_top_ < top_) { 473 while (resolved_top_ < top_) {
441 RawObject* raw_obj = RawObject::FromAddr(resolved_top_); 474 RawObject* raw_obj = RawObject::FromAddr(resolved_top_);
442 resolved_top_ += raw_obj->VisitPointers(visitor); 475 intptr_t class_id = raw_obj->GetClassId();
476 if (class_id != kWeakPropertyCid) {
477 resolved_top_ += raw_obj->VisitPointers(visitor);
478 } else {
479 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj);
480 resolved_top_ += ProcessWeakProperty(raw_weak, visitor);
481 }
443 } 482 }
444 visitor->VisitingOldPointers(true); 483 visitor->VisitingOldPointers(true);
445 while (PromotedStackHasMore()) { 484 while (PromotedStackHasMore()) {
446 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack()); 485 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack());
447 // Resolve or copy all objects referred to by the current object. This 486 // 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 487 // can potentially push more objects on this stack as well as add more
449 // objects to be resolved in the to space. 488 // objects to be resolved in the to space.
450 raw_object->VisitPointers(visitor); 489 raw_object->VisitPointers(visitor);
451 } 490 }
452 visitor->VisitingOldPointers(false); 491 visitor->VisitingOldPointers(false);
453 } 492 }
454 } 493 }
455 494
456 495
496 uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak,
497 ScavengerVisitor* visitor) {
498 // The fate of the weak property is determined by its key.
499 RawObject* raw_key = raw_weak->ptr()->key_;
500 uword raw_addr = RawObject::ToAddr(raw_key);
501 uword header = *reinterpret_cast<uword*>(raw_addr);
502 if (!IsForwarding(header)) {
503 // Key is white. Delay the weak property.
504 visitor->DelayWeakProperty(raw_weak);
505 return raw_weak->Size();
506 } else {
507 // Key is gray or black. Make the weak property black.
508 return raw_weak->VisitPointers(visitor);
509 }
510 }
511
512
457 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { 513 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
458 uword cur = FirstObjectStart(); 514 uword cur = FirstObjectStart();
459 while (cur < top_) { 515 while (cur < top_) {
460 RawObject* raw_obj = RawObject::FromAddr(cur); 516 RawObject* raw_obj = RawObject::FromAddr(cur);
461 cur += raw_obj->VisitPointers(visitor); 517 cur += raw_obj->VisitPointers(visitor);
462 } 518 }
463 } 519 }
464 520
465 521
466 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { 522 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"); 556 Timer timer(FLAG_verbose_gc, "Scavenge");
501 timer.Start(); 557 timer.Start();
502 // Setup the visitor and run a scavenge. 558 // Setup the visitor and run a scavenge.
503 ScavengerVisitor visitor(isolate, this); 559 ScavengerVisitor visitor(isolate, this);
504 Prologue(isolate, invoke_api_callbacks); 560 Prologue(isolate, invoke_api_callbacks);
505 IterateRoots(isolate, &visitor, !invoke_api_callbacks); 561 IterateRoots(isolate, &visitor, !invoke_api_callbacks);
506 ProcessToSpace(&visitor); 562 ProcessToSpace(&visitor);
507 IterateWeakReferences(isolate, &visitor); 563 IterateWeakReferences(isolate, &visitor);
508 ScavengerWeakVisitor weak_visitor(this); 564 ScavengerWeakVisitor weak_visitor(this);
509 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); 565 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks);
566 visitor.Finalize();
510 Epilogue(isolate, invoke_api_callbacks); 567 Epilogue(isolate, invoke_api_callbacks);
511 timer.Stop(); 568 timer.Stop();
512 if (FLAG_verbose_gc) { 569 if (FLAG_verbose_gc) {
513 OS::PrintErr("Scavenge[%d]: %dus\n", count_, timer.TotalElapsedTime()); 570 OS::PrintErr("Scavenge[%d]: %dus\n", count_, timer.TotalElapsedTime());
514 } 571 }
515 572
516 if (FLAG_verify_after_gc) { 573 if (FLAG_verify_after_gc) {
517 OS::PrintErr("Verifying after Scavenge..."); 574 OS::PrintErr("Verifying after Scavenge...");
518 heap_->Verify(); 575 heap_->Verify();
519 OS::PrintErr(" done.\n"); 576 OS::PrintErr(" done.\n");
520 } 577 }
521 578
522 count_++; 579 count_++;
523 // Done scavenging. Reset the marker. 580 // Done scavenging. Reset the marker.
524 ASSERT(scavenging_); 581 ASSERT(scavenging_);
525 scavenging_ = false; 582 scavenging_ = false;
526 } 583 }
527 584
528 585
529 void Scavenger::WriteProtect(bool read_only) { 586 void Scavenger::WriteProtect(bool read_only) {
530 space_->Protect( 587 space_->Protect(
531 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); 588 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite);
532 } 589 }
533 590
534 } // namespace dart 591 } // 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