Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index 961f5b38329a1266c5b231446f63d04cac6ad0a2..06d19cad8db442937f580ad4f228ab8d0be500ac 100644 |
--- a/src/heap/mark-compact.cc |
+++ b/src/heap/mark-compact.cc |
@@ -1857,14 +1857,20 @@ int MarkCompactCollector::DiscoverAndEvacuateBlackObjectsOnPage( |
Address address = cell_base + offset * kPointerSize; |
HeapObject* object = HeapObject::FromAddress(address); |
+ offset++; |
+ current_cell >>= 1; |
+ |
+ MapWord map_word = object->map_word(); |
+ if (map_word.IsForwardingAddress()) { |
+ printf("forwarded object found %p\n", address); |
+ continue; |
+ } |
+ |
int size = object->Size(); |
survivors_size += size; |
Heap::UpdateAllocationSiteFeedback(object, Heap::RECORD_SCRATCHPAD_SLOT); |
- offset++; |
- current_cell >>= 1; |
- |
// TODO(hpayer): Refactor EvacuateObject and call this function instead. |
if (heap()->ShouldBePromoted(object->address(), size) && |
TryPromoteObject(object, size)) { |
@@ -2940,6 +2946,32 @@ static void UpdatePointer(HeapObject** address, HeapObject* object) { |
} |
+static void PromoteObjectReferencedFromStoreBuffer(HeapObject** address, |
+ HeapObject* object) { |
+ Heap* heap = object->GetIsolate()->heap(); |
+ DCHECK(heap->InFromSpace(object)); |
+ |
+ // We use the first word (where the map pointer usually is) of a heap |
+ // object to record the forwarding pointer. A forwarding pointer can |
+ // point to an old space, the code space, or the to space of the new |
+ // generation. |
+ MapWord first_word = object->map_word(); |
+ |
+ // If the first word is a forwarding address, the object has already been |
+ // promoted to the old generation. There must have been a duplicate store |
+ // buffer entry. |
+ if (first_word.IsForwardingAddress()) { |
+ DCHECK(!heap->InNewSpace(first_word.ToForwardingAddress())); |
+ return; |
+ } |
+ |
+ if (!heap->mark_compact_collector()->TryPromoteObject(object, |
+ object->Size())) { |
+ V8::FatalProcessOutOfMemory("Store buffer promotion"); |
+ } |
+} |
+ |
+ |
static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, |
Object** p) { |
MapWord map_word = HeapObject::cast(*p)->map_word(); |
@@ -2991,6 +3023,13 @@ void MarkCompactCollector::EvacuateNewSpace() { |
int survivors_size = 0; |
+ { |
+ StoreBufferRebuildScope scope(heap_, heap_->store_buffer(), |
+ &Heap::ScavengeStoreBufferCallback); |
+ heap_->store_buffer()->IteratePointersToNewSpace( |
+ &PromoteObjectReferencedFromStoreBuffer); |
+ } |
+ |
// First pass: traverse all objects in inactive semispace, remove marks, |
// migrate live objects and write forwarding addresses. This stage puts |
// new entries in the store buffer and may cause some pages to be marked |
@@ -3401,6 +3440,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { |
Heap::RelocationLock relocation_lock(heap()); |
bool code_slots_filtering_required; |
+ |
{ |
GCTracer::Scope gc_scope(heap()->tracer(), |
GCTracer::Scope::MC_SWEEP_NEWSPACE); |