Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(918)

Unified Diff: src/heap/mark-compact.cc

Issue 2440683002: [heap] Move typed slot filtering logic into sweeper. (Closed)
Patch Set: fix test Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/remembered-set.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index 5be69a10d1fcddc6cfba672954111ef8d672784c..69d783417e0cf6db53035bc975803ccaa267fe9d 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) {
- 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;
+
// 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,12 +3302,21 @@ 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())));
}
}
+ // Clear invalid typed slots after collection all free ranges.
+ if (slots_clearing_mode == CLEAR_TYPED_SLOTS) {
+ p->typed_old_to_new_slots()->RemoveInvaldSlots(free_ranges);
+ }
+
// Clear the mark bits of that page and reset live bytes count.
p->ClearLiveness();
@@ -3837,9 +3742,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 +3809,6 @@ void MarkCompactCollector::StartSweepSpace(PagedSpace* space) {
if (p->IsEvacuationCandidate()) {
// Will be processed in EvacuateNewSpaceAndCandidates.
DCHECK(evacuation_candidates_.length() > 0);
- DCHECK(!p->HasBlackAreas());
continue;
}
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/remembered-set.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698