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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 intptr_t bytes_promoted() const { return bytes_promoted_; } | 114 intptr_t bytes_promoted() const { return bytes_promoted_; } |
115 | 115 |
116 private: | 116 private: |
117 void UpdateStoreBuffer(RawObject** p, RawObject* obj) { | 117 void UpdateStoreBuffer(RawObject** p, RawObject* obj) { |
118 uword ptr = reinterpret_cast<uword>(p); | 118 uword ptr = reinterpret_cast<uword>(p); |
119 ASSERT(obj->IsHeapObject()); | 119 ASSERT(obj->IsHeapObject()); |
120 ASSERT(!scavenger_->Contains(ptr)); | 120 ASSERT(!scavenger_->Contains(ptr)); |
121 ASSERT(!heap_->CodeContains(ptr)); | 121 ASSERT(!heap_->CodeContains(ptr)); |
122 ASSERT(heap_->Contains(ptr)); | 122 ASSERT(heap_->Contains(ptr)); |
123 // If the newly written object is not a new object, drop it immediately. | 123 // If the newly written object is not a new object, drop it immediately. |
124 if (!obj->IsNewObject()) return; | 124 if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) { |
125 isolate()->store_buffer()->AddPointer( | 125 return; |
126 reinterpret_cast<uword>(visiting_old_object_)); | 126 } |
| 127 visiting_old_object_->SetRememberedBit(); |
| 128 isolate()->store_buffer()->AddObjectGC(visiting_old_object_); |
127 } | 129 } |
128 | 130 |
129 void ScavengePointer(RawObject** p) { | 131 void ScavengePointer(RawObject** p) { |
130 // ScavengePointer cannot be called recursively. | 132 // ScavengePointer cannot be called recursively. |
131 #ifdef DEBUG | 133 #ifdef DEBUG |
132 ASSERT(!in_scavenge_pointer_); | 134 ASSERT(!in_scavenge_pointer_); |
133 BoolScope bs(&in_scavenge_pointer_, true); | 135 BoolScope bs(&in_scavenge_pointer_, true); |
134 #endif | 136 #endif |
135 | 137 |
136 RawObject* raw_obj = *p; | 138 RawObject* raw_obj = *p; |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 memset(from_->pointer(), 0xf3, from_->size()); | 369 memset(from_->pointer(), 0xf3, from_->size()); |
368 #endif // defined(DEBUG) | 370 #endif // defined(DEBUG) |
369 if (invoke_api_callbacks) { | 371 if (invoke_api_callbacks) { |
370 isolate->gc_epilogue_callbacks().Invoke(); | 372 isolate->gc_epilogue_callbacks().Invoke(); |
371 } | 373 } |
372 } | 374 } |
373 | 375 |
374 | 376 |
375 void Scavenger::IterateStoreBuffers(Isolate* isolate, | 377 void Scavenger::IterateStoreBuffers(Isolate* isolate, |
376 ScavengerVisitor* visitor) { | 378 ScavengerVisitor* visitor) { |
377 // Drain store buffer block into store buffer to deduplicate it. It might be | 379 StoreBuffer* buffer = isolate->store_buffer(); |
378 // full of large objects repeated multiple times. | 380 heap_->RecordData(kStoreBufferBlockEntries, buffer->Count()); |
379 // Use DrainBlock directly instead of ProcessBlock because we are in the | |
380 // middle of a scavenge cycle and thus do not care if we are temporary | |
381 // running over the max number of deduplication sets. | |
382 StoreBufferBlock* block = isolate->store_buffer_block(); | |
383 heap_->RecordData(kStoreBufferBlockEntries, block->Count()); | |
384 isolate->store_buffer()->DrainBlock(block); | |
385 | 381 |
386 // Iterating through the store buffers. | 382 // Iterating through the store buffers. |
387 // Grab the deduplication sets out of the store buffer. | 383 // Grab the deduplication sets out of the store buffer. |
388 StoreBuffer::DedupSet* pending = isolate->store_buffer()->DedupSets(); | 384 StoreBufferBlock* pending = isolate->store_buffer()->Blocks(); |
389 intptr_t entries = 0; | 385 intptr_t entries = 0; |
390 while (pending != NULL) { | 386 while (pending != NULL) { |
391 StoreBuffer::DedupSet* next = pending->next(); | 387 StoreBufferBlock* next = pending->next(); |
392 HashSet* set = pending->set(); | 388 intptr_t count = pending->Count(); |
393 intptr_t count = set->Count(); | |
394 intptr_t size = set->Size(); | |
395 intptr_t handled = 0; | |
396 entries += count; | 389 entries += count; |
397 for (intptr_t i = 0; i < size; i++) { | 390 for (intptr_t i = 0; i < count; i++) { |
398 RawObject* raw_object = reinterpret_cast<RawObject*>(set->At(i)); | 391 RawObject* raw_object = pending->At(i); |
399 if (raw_object != NULL) { | 392 ASSERT(raw_object->IsRemembered()); |
400 visitor->VisitingOldObject(raw_object); | 393 raw_object->ClearRememberedBit(); |
401 raw_object->VisitPointers(visitor); | 394 visitor->VisitingOldObject(raw_object); |
402 handled++; | 395 raw_object->VisitPointers(visitor); |
403 if (handled == count) { | |
404 break; | |
405 } | |
406 } | |
407 } | 396 } |
408 delete pending; | 397 delete pending; |
409 pending = next; | 398 pending = next; |
410 } | 399 } |
411 heap_->RecordData(kStoreBufferEntries, entries); | 400 heap_->RecordData(kStoreBufferEntries, entries); |
412 // Done iterating through old objects remembered in the store buffers. | 401 // Done iterating through old objects remembered in the store buffers. |
413 visitor->VisitingOldObject(NULL); | 402 visitor->VisitingOldObject(NULL); |
414 } | 403 } |
415 | 404 |
416 | 405 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); | 516 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); |
528 resolved_top_ += ProcessWeakProperty(raw_weak, visitor); | 517 resolved_top_ += ProcessWeakProperty(raw_weak, visitor); |
529 } | 518 } |
530 } | 519 } |
531 { | 520 { |
532 while (PromotedStackHasMore()) { | 521 while (PromotedStackHasMore()) { |
533 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack()); | 522 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack()); |
534 // Resolve or copy all objects referred to by the current object. This | 523 // Resolve or copy all objects referred to by the current object. This |
535 // can potentially push more objects on this stack as well as add more | 524 // can potentially push more objects on this stack as well as add more |
536 // objects to be resolved in the to space. | 525 // objects to be resolved in the to space. |
| 526 ASSERT(!raw_object->IsRemembered()); |
537 visitor->VisitingOldObject(raw_object); | 527 visitor->VisitingOldObject(raw_object); |
538 raw_object->VisitPointers(visitor); | 528 raw_object->VisitPointers(visitor); |
539 } | 529 } |
540 visitor->VisitingOldObject(NULL); | 530 visitor->VisitingOldObject(NULL); |
541 } | 531 } |
542 while (!delayed_weak_stack->is_empty()) { | 532 while (!delayed_weak_stack->is_empty()) { |
543 // Pop the delayed weak object from the stack and visit its pointers. | 533 // Pop the delayed weak object from the stack and visit its pointers. |
544 RawObject* weak_property = delayed_weak_stack->RemoveLast(); | 534 RawObject* weak_property = delayed_weak_stack->RemoveLast(); |
545 weak_property->VisitPointers(visitor); | 535 weak_property->VisitPointers(visitor); |
546 } | 536 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 PeerTable::iterator it = peer_table_.find(raw_obj); | 662 PeerTable::iterator it = peer_table_.find(raw_obj); |
673 return (it == peer_table_.end()) ? NULL : it->second; | 663 return (it == peer_table_.end()) ? NULL : it->second; |
674 } | 664 } |
675 | 665 |
676 | 666 |
677 int64_t Scavenger::PeerCount() const { | 667 int64_t Scavenger::PeerCount() const { |
678 return static_cast<int64_t>(peer_table_.size()); | 668 return static_cast<int64_t>(peer_table_.size()); |
679 } | 669 } |
680 | 670 |
681 } // namespace dart | 671 } // namespace dart |
OLD | NEW |