Chromium Code Reviews| Index: src/heap/mark-compact.cc |
| diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
| index 5be69a10d1fcddc6cfba672954111ef8d672784c..62a3a3f10bdf48eeee226ec823b56410a243af3b 100644 |
| --- a/src/heap/mark-compact.cc |
| +++ b/src/heap/mark-compact.cc |
| @@ -2872,128 +2872,6 @@ static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, |
| return String::cast(*p); |
| } |
| -bool MarkCompactCollector::IsSlotInBlackObject(MemoryChunk* p, Address slot) { |
|
Michael Lippautz
2016/10/20 16:28:24
I would like to express my deepest gratitude for d
Hannes Payer (out of office)
2016/10/21 07:13:29
Drinks are on you :D
|
| - Space* owner = p->owner(); |
| - DCHECK(owner != heap_->lo_space() && owner != nullptr); |
| - USE(owner); |
| - |
| - // We may be part of a black area. |
| - if (Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(slot))) { |
| - return true; |
| - } |
| - |
| - uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); |
| - unsigned int cell_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; |
| - MarkBit::CellType index_mask = 1u << Bitmap::IndexInCell(mark_bit_index); |
| - MarkBit::CellType* cells = p->markbits()->cells(); |
| - Address base_address = p->area_start(); |
| - unsigned int base_address_cell_index = Bitmap::IndexToCell( |
| - Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(base_address))); |
| - |
| - // Check if the slot points to the start of an object. This can happen e.g. |
| - // when we left trim a fixed array. Such slots are invalid and we can remove |
| - // them. |
| - if (index_mask > 1) { |
| - if ((cells[cell_index] & index_mask) != 0 && |
| - (cells[cell_index] & (index_mask >> 1)) == 0) { |
| - return false; |
| - } |
| - } else { |
| - // Left trimming moves the mark bits so we cannot be in the very first cell. |
| - DCHECK(cell_index != base_address_cell_index); |
| - if ((cells[cell_index] & index_mask) != 0 && |
| - (cells[cell_index - 1] & (1u << Bitmap::kBitIndexMask)) == 0) { |
| - return false; |
| - } |
| - } |
| - |
| - // Check if the object is in the current cell. |
| - MarkBit::CellType slot_mask; |
| - if ((cells[cell_index] == 0) || |
| - (base::bits::CountTrailingZeros32(cells[cell_index]) > |
| - base::bits::CountTrailingZeros32(cells[cell_index] | index_mask))) { |
| - // If we are already in the first cell, there is no live object. |
| - if (cell_index == base_address_cell_index) return false; |
| - |
| - // If not, find a cell in a preceding cell slot that has a mark bit set. |
| - do { |
| - cell_index--; |
| - } while (cell_index > base_address_cell_index && cells[cell_index] == 0); |
| - |
| - // The slot must be in a dead object if there are no preceding cells that |
| - // have mark bits set. |
| - if (cells[cell_index] == 0) { |
| - return false; |
| - } |
| - |
| - // The object is in a preceding cell. Set the mask to find any object. |
| - slot_mask = ~0u; |
| - } else { |
| - // We are interested in object mark bits right before the slot. |
| - slot_mask = index_mask + (index_mask - 1); |
| - } |
| - |
| - MarkBit::CellType current_cell = cells[cell_index]; |
| - CHECK(current_cell != 0); |
| - |
| - // Find the last live object in the cell. |
| - unsigned int leading_zeros = |
| - base::bits::CountLeadingZeros32(current_cell & slot_mask); |
| - CHECK(leading_zeros != Bitmap::kBitsPerCell); |
| - int offset = static_cast<int>(Bitmap::kBitIndexMask - leading_zeros) - 1; |
| - |
| - base_address += (cell_index - base_address_cell_index) * |
| - Bitmap::kBitsPerCell * kPointerSize; |
| - Address address = base_address + offset * kPointerSize; |
| - |
| - // If the found mark bit is part of a black area, the slot cannot be part |
| - // of a live object since it is not marked. |
| - if (p->IsBlackAreaEndMarker(address + kPointerSize)) return false; |
| - |
| - HeapObject* object = HeapObject::FromAddress(address); |
| - CHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object))); |
| - CHECK(object->address() < reinterpret_cast<Address>(slot)); |
| - if ((object->address() + kPointerSize) <= slot && |
| - (object->address() + object->Size()) > slot) { |
| - // If the slot is within the last found object in the cell, the slot is |
| - // in a live object. |
| - // Slots pointing to the first word of an object are invalid and removed. |
| - // This can happen when we move the object header while left trimming. |
| - return true; |
| - } |
| - return false; |
| -} |
| - |
| -HeapObject* MarkCompactCollector::FindBlackObjectBySlotSlow(Address slot) { |
| - Page* p = Page::FromAddress(slot); |
| - Space* owner = p->owner(); |
| - if (owner == heap_->lo_space() || owner == nullptr) { |
| - Object* large_object = heap_->lo_space()->FindObject(slot); |
| - // This object has to exist, otherwise we would not have recorded a slot |
| - // for it. |
| - CHECK(large_object->IsHeapObject()); |
| - HeapObject* large_heap_object = HeapObject::cast(large_object); |
| - |
| - if (IsMarked(large_heap_object)) { |
| - return large_heap_object; |
| - } |
| - return nullptr; |
| - } |
| - |
| - LiveObjectIterator<kBlackObjects> it(p); |
| - HeapObject* object = nullptr; |
| - while ((object = it.Next()) != nullptr) { |
| - int size = object->Size(); |
| - if (object->address() > slot) return nullptr; |
| - if (object->address() <= slot && slot < (object->address() + size)) { |
| - return object; |
| - } |
| - } |
| - |
| - return nullptr; |
| -} |
| - |
| - |
| void MarkCompactCollector::EvacuateNewSpacePrologue() { |
| NewSpace* new_space = heap()->new_space(); |
| // Append the list of new space pages to be processed. |
| @@ -3316,23 +3194,38 @@ class EvacuationWeakObjectRetainer : public WeakObjectRetainer { |
| } |
| }; |
| +MarkCompactCollector::Sweeper::ClearOldToNewSlotsMode |
| +MarkCompactCollector::Sweeper::GetClearOldToNewSlotsMode(Page* p) { |
| + AllocationSpace identity = p->owner()->identity(); |
| + if (p->old_to_new_slots() && |
| + (identity == OLD_SPACE || identity == MAP_SPACE)) { |
| + return MarkCompactCollector::Sweeper::CLEAR_REGULAR_SLOTS; |
| + } else if (p->typed_old_to_new_slots() && identity == CODE_SPACE) { |
| + return MarkCompactCollector::Sweeper::CLEAR_TYPED_SLOTS; |
| + } |
| + return MarkCompactCollector::Sweeper::DO_NOT_CLEAR; |
| +} |
| + |
| int MarkCompactCollector::Sweeper::RawSweep( |
| Page* p, FreeListRebuildingMode free_list_mode, |
| FreeSpaceTreatmentMode free_space_mode) { |
| Space* space = p->owner(); |
| - AllocationSpace identity = space->identity(); |
| DCHECK_NOT_NULL(space); |
| - DCHECK(free_list_mode == IGNORE_FREE_LIST || identity == OLD_SPACE || |
| - identity == CODE_SPACE || identity == MAP_SPACE); |
| + DCHECK(free_list_mode == IGNORE_FREE_LIST || space->identity() == OLD_SPACE || |
| + space->identity() == CODE_SPACE || space->identity() == MAP_SPACE); |
| DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone()); |
| + // If there are old-to-new slots in that page, we have to filter out slots |
| + // that are in dead memory which is freed by the sweeper. |
| + ClearOldToNewSlotsMode slots_clearing_mode = GetClearOldToNewSlotsMode(p); |
| + |
| + // The free ranges map is used for filtering typed slots. |
| + std::map<uint32_t, uint32_t> free_ranges; |
|
ulan
2016/10/20 15:48:19
Alternative solution was to have host_objects of t
Hannes Payer (out of office)
2016/10/21 07:13:29
Are you referring to the solution where you
1) tra
|
| + |
| // Before we sweep objects on the page, we free dead array buffers which |
| // requires valid mark bits. |
| ArrayBufferTracker::FreeDead(p); |
| - // We also release the black area markers here. |
| - p->ReleaseBlackAreaEndMarkerMap(); |
| - |
| Address free_start = p->area_start(); |
| DCHECK(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0); |
| @@ -3352,8 +3245,7 @@ int MarkCompactCollector::Sweeper::RawSweep( |
| LiveObjectIterator<kBlackObjects> it(p); |
| HeapObject* object = NULL; |
| - bool clear_slots = |
| - p->old_to_new_slots() && (identity == OLD_SPACE || identity == MAP_SPACE); |
| + |
| while ((object = it.Next()) != NULL) { |
| DCHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object))); |
| Address free_end = object->address(); |
| @@ -3372,9 +3264,13 @@ int MarkCompactCollector::Sweeper::RawSweep( |
| ClearRecordedSlots::kNo); |
| } |
| - if (clear_slots) { |
| + if (slots_clearing_mode == CLEAR_REGULAR_SLOTS) { |
| RememberedSet<OLD_TO_NEW>::RemoveRange(p, free_start, free_end, |
| SlotSet::KEEP_EMPTY_BUCKETS); |
| + } else if (slots_clearing_mode == CLEAR_TYPED_SLOTS) { |
| + free_ranges.insert(std::pair<uint32_t, uint32_t>( |
| + static_cast<uint32_t>(free_start - p->address()), |
| + static_cast<uint32_t>(free_end - p->address()))); |
| } |
| } |
| Map* map = object->synchronized_map(); |
| @@ -3406,9 +3302,14 @@ int MarkCompactCollector::Sweeper::RawSweep( |
| ClearRecordedSlots::kNo); |
| } |
| - if (clear_slots) { |
| + if (slots_clearing_mode == CLEAR_REGULAR_SLOTS) { |
| RememberedSet<OLD_TO_NEW>::RemoveRange(p, free_start, p->area_end(), |
| SlotSet::KEEP_EMPTY_BUCKETS); |
| + } else if (slots_clearing_mode == CLEAR_TYPED_SLOTS) { |
| + free_ranges.insert(std::pair<uint32_t, uint32_t>( |
| + static_cast<uint32_t>(free_start - p->address()), |
| + static_cast<uint32_t>(p->area_end() - p->address()))); |
| + p->typed_old_to_new_slots()->RemoveInvaldSlots(free_ranges); |
|
Michael Lippautz
2016/10/20 16:28:24
This call should go outside of the last if block a
Hannes Payer (out of office)
2016/10/21 07:13:29
Uh, good catch. Too many branches. Done
|
| } |
| } |
| @@ -3837,9 +3738,6 @@ int MarkCompactCollector::Sweeper::ParallelSweepPage(Page* page, |
| if (identity == NEW_SPACE) { |
| RawSweep(page, IGNORE_FREE_LIST, free_space_mode); |
| } else { |
| - if (identity == CODE_SPACE) { |
| - RememberedSet<OLD_TO_NEW>::ClearInvalidTypedSlots(heap_, page); |
| - } |
| max_freed = RawSweep(page, REBUILD_FREE_LIST, free_space_mode); |
| } |
| @@ -3907,7 +3805,6 @@ void MarkCompactCollector::StartSweepSpace(PagedSpace* space) { |
| if (p->IsEvacuationCandidate()) { |
| // Will be processed in EvacuateNewSpaceAndCandidates. |
| DCHECK(evacuation_candidates_.length() > 0); |
| - DCHECK(!p->HasBlackAreas()); |
| continue; |
| } |