| Index: runtime/vm/scavenger.cc
|
| ===================================================================
|
| --- runtime/vm/scavenger.cc (revision 22392)
|
| +++ runtime/vm/scavenger.cc (working copy)
|
| @@ -121,9 +121,11 @@
|
| ASSERT(!heap_->CodeContains(ptr));
|
| ASSERT(heap_->Contains(ptr));
|
| // If the newly written object is not a new object, drop it immediately.
|
| - if (!obj->IsNewObject()) return;
|
| - isolate()->store_buffer()->AddPointer(
|
| - reinterpret_cast<uword>(visiting_old_object_));
|
| + if (!obj->IsNewObject() || visiting_old_object_->IsRemembered()) {
|
| + return;
|
| + }
|
| + visiting_old_object_->SetRememberedBit();
|
| + isolate()->store_buffer()->AddObjectGC(visiting_old_object_);
|
| }
|
|
|
| void ScavengePointer(RawObject** p) {
|
| @@ -374,36 +376,23 @@
|
|
|
| void Scavenger::IterateStoreBuffers(Isolate* isolate,
|
| ScavengerVisitor* visitor) {
|
| - // Drain store buffer block into store buffer to deduplicate it. It might be
|
| - // full of large objects repeated multiple times.
|
| - // Use DrainBlock directly instead of ProcessBlock because we are in the
|
| - // middle of a scavenge cycle and thus do not care if we are temporary
|
| - // running over the max number of deduplication sets.
|
| - StoreBufferBlock* block = isolate->store_buffer_block();
|
| - heap_->RecordData(kStoreBufferBlockEntries, block->Count());
|
| - isolate->store_buffer()->DrainBlock(block);
|
| + StoreBuffer* buffer = isolate->store_buffer();
|
| + heap_->RecordData(kStoreBufferBlockEntries, buffer->Count());
|
|
|
| // Iterating through the store buffers.
|
| // Grab the deduplication sets out of the store buffer.
|
| - StoreBuffer::DedupSet* pending = isolate->store_buffer()->DedupSets();
|
| + StoreBufferBlock* pending = isolate->store_buffer()->Blocks();
|
| intptr_t entries = 0;
|
| while (pending != NULL) {
|
| - StoreBuffer::DedupSet* next = pending->next();
|
| - HashSet* set = pending->set();
|
| - intptr_t count = set->Count();
|
| - intptr_t size = set->Size();
|
| - intptr_t handled = 0;
|
| + StoreBufferBlock* next = pending->next();
|
| + intptr_t count = pending->Count();
|
| entries += count;
|
| - for (intptr_t i = 0; i < size; i++) {
|
| - RawObject* raw_object = reinterpret_cast<RawObject*>(set->At(i));
|
| - if (raw_object != NULL) {
|
| - visitor->VisitingOldObject(raw_object);
|
| - raw_object->VisitPointers(visitor);
|
| - handled++;
|
| - if (handled == count) {
|
| - break;
|
| - }
|
| - }
|
| + for (intptr_t i = 0; i < count; i++) {
|
| + RawObject* raw_object = pending->At(i);
|
| + ASSERT(raw_object->IsRemembered());
|
| + raw_object->ClearRememberedBit();
|
| + visitor->VisitingOldObject(raw_object);
|
| + raw_object->VisitPointers(visitor);
|
| }
|
| delete pending;
|
| pending = next;
|
| @@ -534,6 +523,7 @@
|
| // Resolve or copy all objects referred to by the current object. This
|
| // can potentially push more objects on this stack as well as add more
|
| // objects to be resolved in the to space.
|
| + ASSERT(!raw_object->IsRemembered());
|
| visitor->VisitingOldObject(raw_object);
|
| raw_object->VisitPointers(visitor);
|
| }
|
|
|