| 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 |