OLD | NEW |
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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 private: | 73 private: |
74 bool* _addr; | 74 bool* _addr; |
75 bool _value; | 75 bool _value; |
76 }; | 76 }; |
77 | 77 |
78 | 78 |
79 class ScavengerVisitor : public ObjectPointerVisitor { | 79 class ScavengerVisitor : public ObjectPointerVisitor { |
80 public: | 80 public: |
81 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger) | 81 explicit ScavengerVisitor(Isolate* isolate, Scavenger* scavenger) |
82 : ObjectPointerVisitor(isolate), | 82 : ObjectPointerVisitor(isolate), |
| 83 thread_(Thread::Current()), |
83 scavenger_(scavenger), | 84 scavenger_(scavenger), |
84 from_start_(scavenger_->from_->start()), | 85 from_start_(scavenger_->from_->start()), |
85 from_size_(scavenger_->from_->end() - scavenger_->from_->start()), | 86 from_size_(scavenger_->from_->end() - scavenger_->from_->start()), |
86 heap_(scavenger->heap_), | 87 heap_(scavenger->heap_), |
87 vm_heap_(Dart::vm_isolate()->heap()), | 88 vm_heap_(Dart::vm_isolate()->heap()), |
88 page_space_(scavenger->heap_->old_space()), | 89 page_space_(scavenger->heap_->old_space()), |
89 delayed_weak_stack_(), | 90 delayed_weak_stack_(), |
90 bytes_promoted_(0), | 91 bytes_promoted_(0), |
91 visiting_old_object_(NULL), | 92 visiting_old_object_(NULL), |
92 in_scavenge_pointer_(false) { } | 93 in_scavenge_pointer_(false) { } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 uword ptr = reinterpret_cast<uword>(p); | 133 uword ptr = reinterpret_cast<uword>(p); |
133 ASSERT(obj->IsHeapObject()); | 134 ASSERT(obj->IsHeapObject()); |
134 ASSERT(!scavenger_->Contains(ptr)); | 135 ASSERT(!scavenger_->Contains(ptr)); |
135 ASSERT(!heap_->CodeContains(ptr)); | 136 ASSERT(!heap_->CodeContains(ptr)); |
136 ASSERT(heap_->Contains(ptr)); | 137 ASSERT(heap_->Contains(ptr)); |
137 // If the newly written object is not a new object, drop it immediately. | 138 // If the newly written object is not a new object, drop it immediately. |
138 if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) { | 139 if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) { |
139 return; | 140 return; |
140 } | 141 } |
141 visiting_old_object_->SetRememberedBit(); | 142 visiting_old_object_->SetRememberedBit(); |
142 isolate()->store_buffer()->AddObjectGC(visiting_old_object_); | 143 thread_->StoreBufferAddObjectGC(visiting_old_object_); |
143 } | 144 } |
144 | 145 |
145 void ScavengePointer(RawObject** p) { | 146 void ScavengePointer(RawObject** p) { |
146 // ScavengePointer cannot be called recursively. | 147 // ScavengePointer cannot be called recursively. |
147 #ifdef DEBUG | 148 #ifdef DEBUG |
148 ASSERT(!in_scavenge_pointer_); | 149 ASSERT(!in_scavenge_pointer_); |
149 BoolScope bs(&in_scavenge_pointer_, true); | 150 BoolScope bs(&in_scavenge_pointer_, true); |
150 #endif | 151 #endif |
151 | 152 |
152 RawObject* raw_obj = *p; | 153 RawObject* raw_obj = *p; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 // Update the reference. | 233 // Update the reference. |
233 RawObject* new_obj = RawObject::FromAddr(new_addr); | 234 RawObject* new_obj = RawObject::FromAddr(new_addr); |
234 *p = new_obj; | 235 *p = new_obj; |
235 // Update the store buffer as needed. | 236 // Update the store buffer as needed. |
236 if (visiting_old_object_ != NULL) { | 237 if (visiting_old_object_ != NULL) { |
237 VerifiedMemory::Accept(reinterpret_cast<uword>(p), sizeof(*p)); | 238 VerifiedMemory::Accept(reinterpret_cast<uword>(p), sizeof(*p)); |
238 UpdateStoreBuffer(p, new_obj); | 239 UpdateStoreBuffer(p, new_obj); |
239 } | 240 } |
240 } | 241 } |
241 | 242 |
| 243 Thread* thread_; |
242 Scavenger* scavenger_; | 244 Scavenger* scavenger_; |
243 uword from_start_; | 245 uword from_start_; |
244 uword from_size_; | 246 uword from_size_; |
245 Heap* heap_; | 247 Heap* heap_; |
246 Heap* vm_heap_; | 248 Heap* vm_heap_; |
247 PageSpace* page_space_; | 249 PageSpace* page_space_; |
248 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; | 250 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; |
249 DelaySet delay_set_; | 251 DelaySet delay_set_; |
250 GrowableArray<RawObject*> delayed_weak_stack_; | 252 GrowableArray<RawObject*> delayed_weak_stack_; |
251 // TODO(cshapiro): use this value to compute survival statistics for | 253 // TODO(cshapiro): use this value to compute survival statistics for |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 } else { | 451 } else { |
450 return old_size_in_words; | 452 return old_size_in_words; |
451 } | 453 } |
452 } | 454 } |
453 | 455 |
454 | 456 |
455 void Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) { | 457 void Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) { |
456 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) { | 458 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) { |
457 (isolate->gc_prologue_callback())(); | 459 (isolate->gc_prologue_callback())(); |
458 } | 460 } |
| 461 Thread::PrepareForGC(); |
459 // Flip the two semi-spaces so that to_ is always the space for allocating | 462 // Flip the two semi-spaces so that to_ is always the space for allocating |
460 // objects. | 463 // objects. |
461 from_ = to_; | 464 from_ = to_; |
462 to_ = SemiSpace::New(NewSizeInWords(from_->size_in_words())); | 465 to_ = SemiSpace::New(NewSizeInWords(from_->size_in_words())); |
463 if (to_ == NULL) { | 466 if (to_ == NULL) { |
464 // TODO(koda): We could try to recover (collect old space, wait for another | 467 // TODO(koda): We could try to recover (collect old space, wait for another |
465 // isolate to finish scavenge, etc.). | 468 // isolate to finish scavenge, etc.). |
466 FATAL("Out of memory.\n"); | 469 FATAL("Out of memory.\n"); |
467 } | 470 } |
468 top_ = FirstObjectStart(); | 471 top_ = FirstObjectStart(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 from_->Delete(); | 509 from_->Delete(); |
507 from_ = NULL; | 510 from_ = NULL; |
508 if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) { | 511 if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) { |
509 (isolate->gc_epilogue_callback())(); | 512 (isolate->gc_epilogue_callback())(); |
510 } | 513 } |
511 } | 514 } |
512 | 515 |
513 | 516 |
514 void Scavenger::IterateStoreBuffers(Isolate* isolate, | 517 void Scavenger::IterateStoreBuffers(Isolate* isolate, |
515 ScavengerVisitor* visitor) { | 518 ScavengerVisitor* visitor) { |
516 StoreBuffer* buffer = isolate->store_buffer(); | |
517 heap_->RecordData(kStoreBufferEntries, buffer->Count()); | |
518 | |
519 // Iterating through the store buffers. | 519 // Iterating through the store buffers. |
520 // Grab the deduplication sets out of the store buffer. | 520 // Grab the deduplication sets out of the isolate's consolidated store buffer. |
521 StoreBufferBlock* pending = isolate->store_buffer()->Blocks(); | 521 StoreBufferBlock* pending = isolate->store_buffer()->Blocks(); |
| 522 intptr_t total_count = 0; |
522 while (pending != NULL) { | 523 while (pending != NULL) { |
523 StoreBufferBlock* next = pending->next(); | 524 StoreBufferBlock* next = pending->next(); |
524 // Generated code appends to store buffers; tell MemorySanitizer. | 525 // Generated code appends to store buffers; tell MemorySanitizer. |
525 MSAN_UNPOISON(pending, sizeof(*pending)); | 526 MSAN_UNPOISON(pending, sizeof(*pending)); |
526 intptr_t count = pending->Count(); | 527 intptr_t count = pending->Count(); |
| 528 total_count += count; |
527 for (intptr_t i = 0; i < count; i++) { | 529 for (intptr_t i = 0; i < count; i++) { |
528 RawObject* raw_object = pending->At(i); | 530 RawObject* raw_object = pending->At(i); |
529 ASSERT(raw_object->IsRemembered()); | 531 ASSERT(raw_object->IsRemembered()); |
530 raw_object->ClearRememberedBit(); | 532 raw_object->ClearRememberedBit(); |
531 visitor->VisitingOldObject(raw_object); | 533 visitor->VisitingOldObject(raw_object); |
532 raw_object->VisitPointers(visitor); | 534 raw_object->VisitPointers(visitor); |
533 } | 535 } |
534 delete pending; | 536 delete pending; |
535 pending = next; | 537 pending = next; |
536 } | 538 } |
| 539 heap_->RecordData(kStoreBufferEntries, total_count); |
537 heap_->RecordData(kDataUnused1, 0); | 540 heap_->RecordData(kDataUnused1, 0); |
538 heap_->RecordData(kDataUnused2, 0); | 541 heap_->RecordData(kDataUnused2, 0); |
539 // Done iterating through old objects remembered in the store buffers. | 542 // Done iterating through old objects remembered in the store buffers. |
540 visitor->VisitingOldObject(NULL); | 543 visitor->VisitingOldObject(NULL); |
541 } | 544 } |
542 | 545 |
543 | 546 |
544 void Scavenger::IterateObjectIdTable(Isolate* isolate, | 547 void Scavenger::IterateObjectIdTable(Isolate* isolate, |
545 ScavengerVisitor* visitor) { | 548 ScavengerVisitor* visitor) { |
546 ObjectIdRing* ring = isolate->object_id_ring(); | 549 ObjectIdRing* ring = isolate->object_id_ring(); |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 } | 902 } |
900 | 903 |
901 | 904 |
902 void Scavenger::FreeExternal(intptr_t size) { | 905 void Scavenger::FreeExternal(intptr_t size) { |
903 ASSERT(size >= 0); | 906 ASSERT(size >= 0); |
904 external_size_ -= size; | 907 external_size_ -= size; |
905 ASSERT(external_size_ >= 0); | 908 ASSERT(external_size_ >= 0); |
906 } | 909 } |
907 | 910 |
908 } // namespace dart | 911 } // namespace dart |
OLD | NEW |