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

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

Issue 13406004: - Remember objects (not addresses) in the old generation containing new pointers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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 <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 class ScavengerVisitor : public ObjectPointerVisitor { 68 class ScavengerVisitor : public ObjectPointerVisitor {
69 public: 69 public:
70 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger) 70 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger)
71 : ObjectPointerVisitor(isolate), 71 : ObjectPointerVisitor(isolate),
72 scavenger_(scavenger), 72 scavenger_(scavenger),
73 heap_(scavenger->heap_), 73 heap_(scavenger->heap_),
74 vm_heap_(Dart::vm_isolate()->heap()), 74 vm_heap_(Dart::vm_isolate()->heap()),
75 delayed_weak_stack_(), 75 delayed_weak_stack_(),
76 growth_policy_(PageSpace::kControlGrowth), 76 growth_policy_(PageSpace::kControlGrowth),
77 bytes_promoted_(0), 77 bytes_promoted_(0),
78 #ifdef DEBUG 78 visiting_old_object_(NULL),
79 in_scavenge_pointer_(false), 79 in_scavenge_pointer_(false) { }
80 #endif
81 visiting_old_pointers_(false) { }
82 80
83 void VisitPointers(RawObject** first, RawObject** last) { 81 void VisitPointers(RawObject** first, RawObject** last) {
84 for (RawObject** current = first; current <= last; current++) { 82 for (RawObject** current = first; current <= last; current++) {
85 ScavengePointer(current); 83 ScavengePointer(current);
86 } 84 }
87 } 85 }
88 86
89 GrowableArray<RawObject*>* DelayedWeakStack() { 87 GrowableArray<RawObject*>* DelayedWeakStack() {
90 return &delayed_weak_stack_; 88 return &delayed_weak_stack_;
91 } 89 }
92 90
93 bool* VisitingOldPointersAddr() { return &visiting_old_pointers_; } 91 void VisitingOldObject(RawObject* obj) {
92 ASSERT((obj == NULL) || obj->IsOldObject());
93 visiting_old_object_ = obj;
94 }
94 95
95 void DelayWeakProperty(RawWeakProperty* raw_weak) { 96 void DelayWeakProperty(RawWeakProperty* raw_weak) {
96 RawObject* raw_key = raw_weak->ptr()->key_; 97 RawObject* raw_key = raw_weak->ptr()->key_;
97 DelaySet::iterator it = delay_set_.find(raw_key); 98 DelaySet::iterator it = delay_set_.find(raw_key);
98 if (it != delay_set_.end()) { 99 if (it != delay_set_.end()) {
99 ASSERT(raw_key->IsWatched()); 100 ASSERT(raw_key->IsWatched());
100 } else { 101 } else {
101 ASSERT(!raw_key->IsWatched()); 102 ASSERT(!raw_key->IsWatched());
102 raw_key->SetWatchedBit(); 103 raw_key->SetWatchedBit();
103 } 104 }
(...skipping 11 matching lines...) Expand all
115 116
116 private: 117 private:
117 void UpdateStoreBuffer(RawObject** p, RawObject* obj) { 118 void UpdateStoreBuffer(RawObject** p, RawObject* obj) {
118 uword ptr = reinterpret_cast<uword>(p); 119 uword ptr = reinterpret_cast<uword>(p);
119 ASSERT(obj->IsHeapObject()); 120 ASSERT(obj->IsHeapObject());
120 ASSERT(!scavenger_->Contains(ptr)); 121 ASSERT(!scavenger_->Contains(ptr));
121 ASSERT(!heap_->CodeContains(ptr)); 122 ASSERT(!heap_->CodeContains(ptr));
122 ASSERT(heap_->Contains(ptr)); 123 ASSERT(heap_->Contains(ptr));
123 // If the newly written object is not a new object, drop it immediately. 124 // If the newly written object is not a new object, drop it immediately.
124 if (!obj->IsNewObject()) return; 125 if (!obj->IsNewObject()) return;
125 isolate()->store_buffer()->AddPointer(ptr); 126 isolate()->store_buffer()->AddPointer(
127 reinterpret_cast<uword>(visiting_old_object_));
126 } 128 }
127 129
128 void ScavengePointer(RawObject** p) { 130 void ScavengePointer(RawObject** p) {
129 // ScavengePointer cannot be called recursively. 131 // ScavengePointer cannot be called recursively.
130 #ifdef DEBUG 132 #ifdef DEBUG
131 ASSERT(!in_scavenge_pointer_); 133 ASSERT(!in_scavenge_pointer_);
132 BoolScope bs(&in_scavenge_pointer_, true); 134 BoolScope bs(&in_scavenge_pointer_, true);
133 #endif 135 #endif
134 136
135 RawObject* raw_obj = *p; 137 RawObject* raw_obj = *p;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 memmove(reinterpret_cast<void*>(new_addr), 234 memmove(reinterpret_cast<void*>(new_addr),
233 reinterpret_cast<void*>(raw_addr), 235 reinterpret_cast<void*>(raw_addr),
234 size); 236 size);
235 // Remember forwarding address. 237 // Remember forwarding address.
236 ForwardTo(raw_addr, new_addr); 238 ForwardTo(raw_addr, new_addr);
237 } 239 }
238 // Update the reference. 240 // Update the reference.
239 RawObject* new_obj = RawObject::FromAddr(new_addr); 241 RawObject* new_obj = RawObject::FromAddr(new_addr);
240 *p = new_obj; 242 *p = new_obj;
241 // Update the store buffer as needed. 243 // Update the store buffer as needed.
242 if (visiting_old_pointers_) { 244 if (visiting_old_object_ != NULL) {
243 UpdateStoreBuffer(p, new_obj); 245 UpdateStoreBuffer(p, new_obj);
244 } 246 }
245 } 247 }
246 248
247 Scavenger* scavenger_; 249 Scavenger* scavenger_;
248 Heap* heap_; 250 Heap* heap_;
249 Heap* vm_heap_; 251 Heap* vm_heap_;
250 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; 252 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet;
251 DelaySet delay_set_; 253 DelaySet delay_set_;
252 GrowableArray<RawObject*> delayed_weak_stack_; 254 GrowableArray<RawObject*> delayed_weak_stack_;
253 PageSpace::GrowthPolicy growth_policy_; 255 PageSpace::GrowthPolicy growth_policy_;
254 // TODO(cshapiro): use this value to compute survival statistics for 256 // TODO(cshapiro): use this value to compute survival statistics for
255 // new space growth policy. 257 // new space growth policy.
256 intptr_t bytes_promoted_; 258 intptr_t bytes_promoted_;
257 259 RawObject* visiting_old_object_;
258 #ifdef DEBUG
259 bool in_scavenge_pointer_; 260 bool in_scavenge_pointer_;
260 #endif
261 bool visiting_old_pointers_;
262 261
263 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); 262 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor);
264 }; 263 };
265 264
266 265
267 class ScavengerWeakVisitor : public HandleVisitor { 266 class ScavengerWeakVisitor : public HandleVisitor {
268 public: 267 public:
269 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) { 268 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) {
270 } 269 }
271 270
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 #endif // defined(DEBUG) 385 #endif // defined(DEBUG)
387 if (invoke_api_callbacks) { 386 if (invoke_api_callbacks) {
388 isolate->gc_epilogue_callbacks().Invoke(); 387 isolate->gc_epilogue_callbacks().Invoke();
389 } 388 }
390 } 389 }
391 390
392 391
393 void Scavenger::IterateStoreBuffers(Isolate* isolate, 392 void Scavenger::IterateStoreBuffers(Isolate* isolate,
394 ScavengerVisitor* visitor) { 393 ScavengerVisitor* visitor) {
395 // Iterating through the store buffers. 394 // Iterating through the store buffers.
396 BoolScope bs(visitor->VisitingOldPointersAddr(), true);
397 // Grab the deduplication sets out of the store buffer. 395 // Grab the deduplication sets out of the store buffer.
398 StoreBuffer::DedupSet* pending = isolate->store_buffer()->DedupSets(); 396 StoreBuffer::DedupSet* pending = isolate->store_buffer()->DedupSets();
399 intptr_t entries = 0; 397 intptr_t entries = 0;
400 intptr_t duplicates = 0;
401 while (pending != NULL) { 398 while (pending != NULL) {
402 StoreBuffer::DedupSet* next = pending->next(); 399 StoreBuffer::DedupSet* next = pending->next();
403 HashSet* set = pending->set(); 400 HashSet* set = pending->set();
404 intptr_t count = set->Count(); 401 intptr_t count = set->Count();
405 intptr_t size = set->Size(); 402 intptr_t size = set->Size();
406 intptr_t handled = 0; 403 intptr_t handled = 0;
407 entries += count; 404 entries += count;
408 for (intptr_t i = 0; i < size; i++) { 405 for (intptr_t i = 0; i < size; i++) {
409 RawObject** pointer = reinterpret_cast<RawObject**>(set->At(i)); 406 RawObject* raw_object = reinterpret_cast<RawObject*>(set->At(i));
410 if (pointer != NULL) { 407 if (raw_object != NULL) {
411 RawObject* value = *pointer; 408 visitor->VisitingOldObject(raw_object);
412 // Skip entries that have been overwritten with Smis. 409 raw_object->VisitPointers(visitor);
413 if (value->IsHeapObject()) {
414 if (from_->Contains(RawObject::ToAddr(value))) {
415 visitor->VisitPointer(pointer);
416 } else {
417 duplicates++;
418 }
419 }
420 handled++; 410 handled++;
421 if (handled == count) { 411 if (handled == count) {
422 break; 412 break;
423 } 413 }
424 } 414 }
425 } 415 }
426 delete pending; 416 delete pending;
427 pending = next; 417 pending = next;
428 } 418 }
429 heap_->RecordData(kStoreBufferEntries, entries); 419 heap_->RecordData(kStoreBufferEntries, entries);
430 heap_->RecordData(kStoreBufferDuplicates, duplicates);
431 StoreBufferBlock* block = isolate->store_buffer_block(); 420 StoreBufferBlock* block = isolate->store_buffer_block();
432 entries = block->Count(); 421 entries = block->Count();
433 duplicates = 0;
434 for (intptr_t i = 0; i < entries; i++) { 422 for (intptr_t i = 0; i < entries; i++) {
435 RawObject** pointer = reinterpret_cast<RawObject**>(block->At(i)); 423 RawObject* raw_object = reinterpret_cast<RawObject*>(block->At(i));
436 RawObject* value = *pointer; 424 ASSERT(raw_object->IsHeapObject());
437 if (value->IsHeapObject()) { 425 visitor->VisitingOldObject(raw_object);
438 if (from_->Contains(RawObject::ToAddr(value))) { 426 raw_object->VisitPointers(visitor);
439 visitor->VisitPointer(pointer);
440 } else {
441 duplicates++;
442 }
443 }
444 } 427 }
445 block->Reset(); 428 block->Reset();
446 heap_->RecordData(kStoreBufferBlockEntries, entries); 429 heap_->RecordData(kStoreBufferBlockEntries, entries);
447 heap_->RecordData(kStoreBufferBlockDuplicates, duplicates); 430 // Done iterating through old objects remembered in the store buffers.
431 visitor->VisitingOldObject(NULL);
448 } 432 }
449 433
450 434
451 void Scavenger::IterateRoots(Isolate* isolate, 435 void Scavenger::IterateRoots(Isolate* isolate,
452 ScavengerVisitor* visitor, 436 ScavengerVisitor* visitor,
453 bool visit_prologue_weak_persistent_handles) { 437 bool visit_prologue_weak_persistent_handles) {
454 int64_t start = OS::GetCurrentTimeMicros(); 438 int64_t start = OS::GetCurrentTimeMicros();
455 isolate->VisitObjectPointers(visitor, 439 isolate->VisitObjectPointers(visitor,
456 visit_prologue_weak_persistent_handles, 440 visit_prologue_weak_persistent_handles,
457 StackFrameIterator::kDontValidateFrames); 441 StackFrameIterator::kDontValidateFrames);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 RawObject* raw_obj = RawObject::FromAddr(resolved_top_); 540 RawObject* raw_obj = RawObject::FromAddr(resolved_top_);
557 intptr_t class_id = raw_obj->GetClassId(); 541 intptr_t class_id = raw_obj->GetClassId();
558 if (class_id != kWeakPropertyCid) { 542 if (class_id != kWeakPropertyCid) {
559 resolved_top_ += raw_obj->VisitPointers(visitor); 543 resolved_top_ += raw_obj->VisitPointers(visitor);
560 } else { 544 } else {
561 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); 545 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj);
562 resolved_top_ += ProcessWeakProperty(raw_weak, visitor); 546 resolved_top_ += ProcessWeakProperty(raw_weak, visitor);
563 } 547 }
564 } 548 }
565 { 549 {
566 BoolScope bs(visitor->VisitingOldPointersAddr(), true);
567 while (PromotedStackHasMore()) { 550 while (PromotedStackHasMore()) {
568 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack()); 551 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack());
569 // Resolve or copy all objects referred to by the current object. This 552 // Resolve or copy all objects referred to by the current object. This
570 // can potentially push more objects on this stack as well as add more 553 // can potentially push more objects on this stack as well as add more
571 // objects to be resolved in the to space. 554 // objects to be resolved in the to space.
555 visitor->VisitingOldObject(raw_object);
572 raw_object->VisitPointers(visitor); 556 raw_object->VisitPointers(visitor);
573 } 557 }
558 visitor->VisitingOldObject(NULL);
574 } 559 }
575 while (!delayed_weak_stack->is_empty()) { 560 while (!delayed_weak_stack->is_empty()) {
576 // Pop the delayed weak object from the stack and visit its pointers. 561 // Pop the delayed weak object from the stack and visit its pointers.
577 RawObject* weak_property = delayed_weak_stack->RemoveLast(); 562 RawObject* weak_property = delayed_weak_stack->RemoveLast();
578 weak_property->VisitPointers(visitor); 563 weak_property->VisitPointers(visitor);
579 } 564 }
580 } 565 }
581 } 566 }
582 567
583 568
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 PeerTable::iterator it = peer_table_.find(raw_obj); 697 PeerTable::iterator it = peer_table_.find(raw_obj);
713 return (it == peer_table_.end()) ? NULL : it->second; 698 return (it == peer_table_.end()) ? NULL : it->second;
714 } 699 }
715 700
716 701
717 int64_t Scavenger::PeerCount() const { 702 int64_t Scavenger::PeerCount() const {
718 return static_cast<int64_t>(peer_table_.size()); 703 return static_cast<int64_t>(peer_table_.size());
719 } 704 }
720 705
721 } // namespace dart 706 } // namespace dart
OLDNEW
« runtime/vm/object.cc ('K') | « runtime/vm/scavenger.h ('k') | runtime/vm/store_buffer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698