Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index b4fafec10939aea23ddd4bc2aada41fee52eced9..f75f323c45a2bbf22794118b0838d5aa3b0e4234 100644 |
--- a/src/heap/mark-compact.cc |
+++ b/src/heap/mark-compact.cc |
@@ -287,60 +287,6 @@ |
} |
-void MarkCompactCollector::ClearInvalidSlotsBufferEntries(PagedSpace* space) { |
- PageIterator it(space); |
- while (it.has_next()) { |
- Page* p = it.next(); |
- SlotsBuffer::RemoveInvalidSlots(heap_, p->slots_buffer()); |
- } |
-} |
- |
- |
-void MarkCompactCollector::ClearInvalidStoreAndSlotsBufferEntries() { |
- heap_->store_buffer()->ClearInvalidStoreBufferEntries(); |
- |
- ClearInvalidSlotsBufferEntries(heap_->old_pointer_space()); |
- ClearInvalidSlotsBufferEntries(heap_->old_data_space()); |
- ClearInvalidSlotsBufferEntries(heap_->code_space()); |
- ClearInvalidSlotsBufferEntries(heap_->cell_space()); |
- ClearInvalidSlotsBufferEntries(heap_->map_space()); |
- |
- LargeObjectIterator it(heap_->lo_space()); |
- for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
- MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); |
- SlotsBuffer::RemoveInvalidSlots(heap_, chunk->slots_buffer()); |
- } |
-} |
- |
- |
-#ifdef VERIFY_HEAP |
-static void VerifyValidSlotsBufferEntries(Heap* heap, PagedSpace* space) { |
- PageIterator it(space); |
- while (it.has_next()) { |
- Page* p = it.next(); |
- SlotsBuffer::VerifySlots(heap, p->slots_buffer()); |
- } |
-} |
- |
- |
-static void VerifyValidStoreAndSlotsBufferEntries(Heap* heap) { |
- heap->store_buffer()->VerifyValidStoreBufferEntries(); |
- |
- VerifyValidSlotsBufferEntries(heap, heap->old_pointer_space()); |
- VerifyValidSlotsBufferEntries(heap, heap->old_data_space()); |
- VerifyValidSlotsBufferEntries(heap, heap->code_space()); |
- VerifyValidSlotsBufferEntries(heap, heap->cell_space()); |
- VerifyValidSlotsBufferEntries(heap, heap->map_space()); |
- |
- LargeObjectIterator it(heap->lo_space()); |
- for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
- MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); |
- SlotsBuffer::VerifySlots(heap, chunk->slots_buffer()); |
- } |
-} |
-#endif |
- |
- |
void MarkCompactCollector::CollectGarbage() { |
// Make sure that Prepare() has been called. The individual steps below will |
// update the state as they proceed. |
@@ -366,11 +312,11 @@ |
} |
#endif |
- ClearInvalidStoreAndSlotsBufferEntries(); |
+ heap_->store_buffer()->ClearInvalidStoreBufferEntries(); |
#ifdef VERIFY_HEAP |
if (FLAG_verify_heap) { |
- VerifyValidStoreAndSlotsBufferEntries(heap_); |
+ heap_->store_buffer()->VerifyValidStoreBufferEntries(); |
} |
#endif |
@@ -777,7 +723,6 @@ |
int count = 0; |
int fragmentation = 0; |
- int page_number = 0; |
Candidate* least = NULL; |
PageIterator it(space); |
@@ -792,16 +737,9 @@ |
CHECK(p->slots_buffer() == NULL); |
if (FLAG_stress_compaction) { |
- if (FLAG_manual_evacuation_candidates_selection) { |
- if (p->IsFlagSet(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING)) { |
- p->ClearFlag(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); |
- fragmentation = 1; |
- } |
- } else { |
- unsigned int counter = space->heap()->ms_count(); |
- if ((counter & 1) == (page_number & 1)) fragmentation = 1; |
- page_number++; |
- } |
+ unsigned int counter = space->heap()->ms_count(); |
+ uintptr_t page_number = reinterpret_cast<uintptr_t>(p) >> kPageSizeBits; |
+ if ((counter & 1) == (page_number & 1)) fragmentation = 1; |
} else if (mode == REDUCE_MEMORY_FOOTPRINT && !FLAG_always_compact) { |
// Don't try to release too many pages. |
if (estimated_release >= over_reserved) { |
@@ -3097,14 +3035,10 @@ |
} |
-bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot, |
- HeapObject** out_object) { |
+bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot) { |
// This function does not support large objects right now. |
Space* owner = p->owner(); |
- if (owner == heap_->lo_space() || owner == NULL) { |
- *out_object = NULL; |
- return true; |
- } |
+ if (owner == heap_->lo_space() || owner == NULL) return true; |
uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); |
unsigned int start_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; |
@@ -3158,7 +3092,6 @@ |
(object->address() + object->Size()) > slot) { |
// If the slot is within the last found object in the cell, the slot is |
// in a live object. |
- *out_object = object; |
return true; |
} |
return false; |
@@ -3200,38 +3133,28 @@ |
} |
-bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { |
- HeapObject* object = NULL; |
+bool MarkCompactCollector::IsSlotInLiveObject(HeapObject** address, |
+ HeapObject* object) { |
+ // If the target object is not black, the source slot must be part |
+ // of a non-black (dead) object. |
+ if (!Marking::IsBlack(Marking::MarkBitFrom(object))) { |
+ return false; |
+ } |
+ |
// The target object is black but we don't know if the source slot is black. |
// The source object could have died and the slot could be part of a free |
// space. Find out based on mark bits if the slot is part of a live object. |
- if (!IsSlotInBlackObject(Page::FromAddress(slot), slot, &object)) { |
+ if (!IsSlotInBlackObject( |
+ Page::FromAddress(reinterpret_cast<Address>(address)), |
+ reinterpret_cast<Address>(address))) { |
return false; |
} |
-#if V8_DOUBLE_FIELDS_UNBOXING |
- // |object| is NULL only when the slot belongs to large object space. |
- DCHECK(object != NULL || |
- Page::FromAnyPointerAddress(heap_, slot)->owner() == |
- heap_->lo_space()); |
- // We don't need to check large objects' layout descriptor since it can't |
- // contain in-object fields anyway. |
- if (object != NULL) { |
- // Filter out slots that happens to point to unboxed double fields. |
- LayoutDescriptorHelper helper(object->map()); |
- bool has_only_tagged_fields = helper.all_fields_tagged(); |
- if (!has_only_tagged_fields && |
- !helper.IsTagged(static_cast<int>(slot - object->address()))) { |
- return false; |
- } |
- } |
-#endif |
- |
return true; |
} |
-void MarkCompactCollector::VerifyIsSlotInLiveObject(Address slot, |
+void MarkCompactCollector::VerifyIsSlotInLiveObject(HeapObject** address, |
HeapObject* object) { |
// The target object has to be black. |
CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
@@ -3239,7 +3162,9 @@ |
// The target object is black but we don't know if the source slot is black. |
// The source object could have died and the slot could be part of a free |
// space. Use the mark bit iterator to find out about liveness of the slot. |
- CHECK(IsSlotInBlackObjectSlow(Page::FromAddress(slot), slot)); |
+ CHECK(IsSlotInBlackObjectSlow( |
+ Page::FromAddress(reinterpret_cast<Address>(address)), |
+ reinterpret_cast<Address>(address))); |
} |
@@ -4558,66 +4483,6 @@ |
} |
-static Object* g_smi_slot = NULL; |
- |
- |
-void SlotsBuffer::RemoveInvalidSlots(Heap* heap, SlotsBuffer* buffer) { |
- DCHECK_EQ(Smi::FromInt(0), g_smi_slot); |
- |
- // Remove entries by replacing them with a dummy slot containing a smi. |
- const ObjectSlot kRemovedEntry = &g_smi_slot; |
- |
- while (buffer != NULL) { |
- SlotsBuffer::ObjectSlot* slots = buffer->slots_; |
- intptr_t slots_count = buffer->idx_; |
- |
- for (int slot_idx = 0; slot_idx < slots_count; ++slot_idx) { |
- ObjectSlot slot = slots[slot_idx]; |
- if (!IsTypedSlot(slot)) { |
- Object* object = *slot; |
- if (object->IsHeapObject()) { |
- if (heap->InNewSpace(object) || |
- !heap->mark_compact_collector()->IsSlotInLiveObject( |
- reinterpret_cast<Address>(slot))) { |
- slots[slot_idx] = kRemovedEntry; |
- } |
- } |
- } else { |
- ++slot_idx; |
- DCHECK(slot_idx < slots_count); |
- } |
- } |
- buffer = buffer->next(); |
- } |
-} |
- |
- |
-void SlotsBuffer::VerifySlots(Heap* heap, SlotsBuffer* buffer) { |
- DCHECK_EQ(Smi::FromInt(0), g_smi_slot); |
- |
- while (buffer != NULL) { |
- SlotsBuffer::ObjectSlot* slots = buffer->slots_; |
- intptr_t slots_count = buffer->idx_; |
- |
- for (int slot_idx = 0; slot_idx < slots_count; ++slot_idx) { |
- ObjectSlot slot = slots[slot_idx]; |
- if (!IsTypedSlot(slot)) { |
- Object* object = *slot; |
- if (object->IsHeapObject()) { |
- CHECK(!heap->InNewSpace(object)); |
- CHECK(heap->mark_compact_collector()->IsSlotInLiveObject( |
- reinterpret_cast<Address>(slot))); |
- } |
- } else { |
- ++slot_idx; |
- DCHECK(slot_idx < slots_count); |
- } |
- } |
- buffer = buffer->next(); |
- } |
-} |
- |
- |
static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { |
if (RelocInfo::IsCodeTarget(rmode)) { |
return SlotsBuffer::CODE_TARGET_SLOT; |