Index: src/mark-compact.cc |
diff --git a/src/mark-compact.cc b/src/mark-compact.cc |
index 51b1008b6babb1f5a39718eb1c76555b2817f1b2..ab5e9366dd0e2701ca82febb38dd61a5700def51 100644 |
--- a/src/mark-compact.cc |
+++ b/src/mark-compact.cc |
@@ -1989,6 +1989,81 @@ static void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque, |
} |
+int MarkCompactCollector::DiscoverAndPromoteBlackObjectsOnPage( |
+ NewSpace* new_space, |
+ NewSpacePage* p) { |
+ ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); |
+ ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); |
+ ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); |
+ ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); |
+ |
+ MarkBit::CellType* cells = p->markbits()->cells(); |
+ int survivors_size = 0; |
+ |
+ int last_cell_index = |
+ Bitmap::IndexToCell( |
+ Bitmap::CellAlignIndex( |
+ p->AddressToMarkbitIndex(p->area_end()))); |
+ |
+ Address cell_base = p->area_start(); |
+ int cell_index = Bitmap::IndexToCell( |
+ Bitmap::CellAlignIndex( |
+ p->AddressToMarkbitIndex(cell_base))); |
+ |
+ for (; |
+ cell_index < last_cell_index; |
+ cell_index++, cell_base += 32 * kPointerSize) { |
+ ASSERT(static_cast<unsigned>(cell_index) == |
+ Bitmap::IndexToCell( |
+ Bitmap::CellAlignIndex( |
+ p->AddressToMarkbitIndex(cell_base)))); |
+ |
+ MarkBit::CellType current_cell = cells[cell_index]; |
+ if (current_cell == 0) continue; |
+ |
+ int offset = 0; |
+ while (current_cell != 0) { |
+ int trailing_zeros = CompilerIntrinsics::CountTrailingZeros(current_cell); |
+ current_cell >>= trailing_zeros; |
+ offset += trailing_zeros; |
+ Address address = cell_base + offset * kPointerSize; |
+ HeapObject* object = HeapObject::FromAddress(address); |
+ |
+ int size = object->Size(); |
+ survivors_size += size; |
+ |
+ offset++; |
+ current_cell >>= 1; |
+ // Aggressively promote young survivors to the old space. |
+ if (TryPromoteObject(object, size)) { |
+ continue; |
+ } |
+ |
+ // Promotion failed. Just migrate object to another semispace. |
+ MaybeObject* allocation = new_space->AllocateRaw(size); |
+ if (allocation->IsFailure()) { |
+ if (!new_space->AddFreshPage()) { |
+ // Shouldn't happen. We are sweeping linearly, and to-space |
+ // has the same number of pages as from-space, so there is |
+ // always room. |
+ UNREACHABLE(); |
+ } |
+ allocation = new_space->AllocateRaw(size); |
+ ASSERT(!allocation->IsFailure()); |
+ } |
+ Object* target = allocation->ToObjectUnchecked(); |
+ |
+ MigrateObject(HeapObject::cast(target)->address(), |
+ object->address(), |
+ size, |
+ NEW_SPACE); |
+ } |
+ cells[cell_index] = 0; |
+ } |
+ return survivors_size; |
+} |
+ |
+ |
static void DiscoverGreyObjectsInSpace(Heap* heap, |
MarkingDeque* marking_deque, |
PagedSpace* space) { |
@@ -2895,42 +2970,10 @@ void MarkCompactCollector::EvacuateNewSpace() { |
// migrate live objects and write forwarding addresses. This stage puts |
// new entries in the store buffer and may cause some pages to be marked |
// scan-on-scavenge. |
- SemiSpaceIterator from_it(from_bottom, from_top); |
- for (HeapObject* object = from_it.Next(); |
- object != NULL; |
- object = from_it.Next()) { |
- MarkBit mark_bit = Marking::MarkBitFrom(object); |
- if (mark_bit.Get()) { |
- mark_bit.Clear(); |
- // Don't bother decrementing live bytes count. We'll discard the |
- // entire page at the end. |
- int size = object->Size(); |
- survivors_size += size; |
- |
- // Aggressively promote young survivors to the old space. |
- if (TryPromoteObject(object, size)) { |
- continue; |
- } |
- |
- // Promotion failed. Just migrate object to another semispace. |
- MaybeObject* allocation = new_space->AllocateRaw(size); |
- if (allocation->IsFailure()) { |
- if (!new_space->AddFreshPage()) { |
- // Shouldn't happen. We are sweeping linearly, and to-space |
- // has the same number of pages as from-space, so there is |
- // always room. |
- UNREACHABLE(); |
- } |
- allocation = new_space->AllocateRaw(size); |
- ASSERT(!allocation->IsFailure()); |
- } |
- Object* target = allocation->ToObjectUnchecked(); |
- |
- MigrateObject(HeapObject::cast(target)->address(), |
- object->address(), |
- size, |
- NEW_SPACE); |
- } |
+ NewSpacePageIterator it(from_bottom, from_top); |
+ while (it.has_next()) { |
+ NewSpacePage* p = it.next(); |
+ survivors_size += DiscoverAndPromoteBlackObjectsOnPage(new_space, p); |
} |
heap_->IncrementYoungSurvivorsCounter(survivors_size); |