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

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

Issue 1420423009: [heap] Black allocation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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/mark-compact-inl.h » ('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 ea0b75daa1a430bb055adcb4272a644fad31e96d..2c998c8817a090478f0e209881aaad04efde6e61 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -119,6 +119,15 @@ static void VerifyMarking(Heap* heap, Address bottom, Address top) {
}
}
+static void VerifyMarkingBlackPage(Heap* heap, Page* page) {
+ CHECK(page->IsFlagSet(Page::BLACK_PAGE));
+ VerifyMarkingVisitor visitor(heap);
+ HeapObjectIterator it(page);
+ for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
+ CHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
+ object->Iterate(&visitor);
+ }
+}
static void VerifyMarking(NewSpace* space) {
Address end = space->top();
@@ -141,7 +150,11 @@ static void VerifyMarking(PagedSpace* space) {
while (it.has_next()) {
Page* p = it.next();
- VerifyMarking(space->heap(), p->area_start(), p->area_end());
+ if (p->IsFlagSet(Page::BLACK_PAGE)) {
+ VerifyMarkingBlackPage(space->heap(), p);
+ } else {
+ VerifyMarking(space->heap(), p->area_start(), p->area_end());
+ }
}
}
@@ -414,7 +427,11 @@ static void ClearMarkbitsInPagedSpace(PagedSpace* space) {
PageIterator it(space);
while (it.has_next()) {
- Bitmap::Clear(it.next());
+ Page* p = it.next();
+ Bitmap::Clear(p);
+ if (p->IsFlagSet(Page::BLACK_PAGE)) {
+ p->ClearFlag(Page::BLACK_PAGE);
+ }
}
}
@@ -437,8 +454,12 @@ void MarkCompactCollector::ClearMarkbits() {
LargeObjectIterator it(heap_->lo_space());
for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
Marking::MarkWhite(Marking::MarkBitFrom(obj));
- Page::FromAddress(obj->address())->ResetProgressBar();
- Page::FromAddress(obj->address())->ResetLiveBytes();
+ MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
+ chunk->ResetProgressBar();
+ chunk->ResetLiveBytes();
+ if (chunk->IsFlagSet(Page::BLACK_PAGE)) {
+ chunk->ClearFlag(Page::BLACK_PAGE);
+ }
}
}
@@ -555,7 +576,9 @@ void Marking::TransferMark(Heap* heap, Address old_start, Address new_start) {
DCHECK(MemoryChunk::FromAddress(old_start) ==
MemoryChunk::FromAddress(new_start));
- if (!heap->incremental_marking()->IsMarking()) return;
+ if (!heap->incremental_marking()->IsMarking() ||
+ Page::FromAddress(old_start)->IsFlagSet(Page::BLACK_PAGE))
+ return;
// If the mark doesn't move, we don't check the color of the object.
// It doesn't matter whether the object is black, since it hasn't changed
@@ -664,6 +687,7 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
while (it.has_next()) {
Page* p = it.next();
if (p->NeverEvacuate()) continue;
+ if (p->IsFlagSet(Page::BLACK_PAGE)) continue;
// Invariant: Evacuation candidates are just created when marking is
// started. This means that sweeping has finished. Furthermore, at the end
// of a GC all evacuation candidates are cleared and their slot buffers are
@@ -1467,10 +1491,11 @@ void MarkCompactCollector::DiscoverGreyObjectsWithIterator(T* it) {
}
}
-
+template <LiveObjectIterationMode T>
void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) {
DCHECK(!marking_deque()->IsFull());
- LiveObjectIterator<kGreyObjects> it(p);
+ DCHECK(T == kGreyObjects || T == kGreyObjectsOnBlackPage);
+ LiveObjectIterator<T> it(p);
HeapObject* object = NULL;
while ((object = it.Next()) != NULL) {
MarkBit markbit = Marking::MarkBitFrom(object);
@@ -1704,7 +1729,11 @@ void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) {
PageIterator it(space);
while (it.has_next()) {
Page* p = it.next();
- DiscoverGreyObjectsOnPage(p);
+ if (p->IsFlagSet(Page::BLACK_PAGE)) {
+ DiscoverGreyObjectsOnPage<kGreyObjectsOnBlackPage>(p);
+ } else {
+ DiscoverGreyObjectsOnPage<kGreyObjects>(p);
+ }
if (marking_deque()->IsFull()) return;
}
}
@@ -1715,7 +1744,7 @@ void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() {
NewSpacePageIterator it(space->bottom(), space->top());
while (it.has_next()) {
NewSpacePage* page = it.next();
- DiscoverGreyObjectsOnPage(page);
+ DiscoverGreyObjectsOnPage<kGreyObjects>(page);
if (marking_deque()->IsFull()) return;
}
}
@@ -2805,6 +2834,12 @@ bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot,
return false;
}
+ // If we are on a black page, we cannot find the actual object start
+ // easiliy. We just return true but do not set the out_object.
+ if (p->IsFlagSet(Page::BLACK_PAGE)) {
+ 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);
@@ -2885,7 +2920,6 @@ bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot,
HeapObject* MarkCompactCollector::FindBlackObjectBySlotSlow(Address slot) {
Page* p = Page::FromAddress(slot);
- // This function does not support large objects right now.
Space* owner = p->owner();
if (owner == heap_->lo_space() || owner == nullptr) {
Object* large_object = heap_->lo_space()->FindObject(slot);
@@ -2900,13 +2934,25 @@ HeapObject* MarkCompactCollector::FindBlackObjectBySlotSlow(Address slot) {
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;
+ if (p->IsFlagSet(Page::BLACK_PAGE)) {
+ HeapObjectIterator 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;
+ }
+ }
+ } else {
+ 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;
@@ -2914,15 +2960,21 @@ HeapObject* MarkCompactCollector::FindBlackObjectBySlotSlow(Address slot) {
bool MarkCompactCollector::IsSlotInLiveObject(Address slot) {
- HeapObject* object = NULL;
// 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)) {
+ Page* page = Page::FromAddress(slot);
+ HeapObject* object = NULL;
+ if (!IsSlotInBlackObject(page, slot, &object)) {
return false;
}
- DCHECK(object != NULL);
+ // If the slot is on a black page, the object will be live.
+ DCHECK(object != NULL || page->IsFlagSet(Page::BLACK_PAGE));
+ if (page->IsFlagSet(Page::BLACK_PAGE)) {
+ return true;
+ }
+
int offset = static_cast<int>(slot - object->address());
return object->IsValidSlot(offset);
}
@@ -3226,6 +3278,7 @@ template <SweepingMode sweeping_mode,
static int Sweep(PagedSpace* space, FreeList* free_list, Page* p,
ObjectVisitor* v) {
DCHECK(!p->IsEvacuationCandidate() && !p->SweepingDone());
+ DCHECK(!p->IsFlagSet(Page::BLACK_PAGE));
DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST,
space->identity() == CODE_SPACE);
DCHECK((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST));
@@ -3698,6 +3751,16 @@ void MarkCompactCollector::StartSweepSpace(PagedSpace* space) {
continue;
}
+ // We can not sweep black pages, since all mark bits are set for these
+ // pages.
+ if (p->IsFlagSet(Page::BLACK_PAGE)) {
+ Bitmap::Clear(p);
+ p->concurrent_sweeping_state().SetValue(Page::kSweepingDone);
+ p->ClearFlag(Page::BLACK_PAGE);
+ // TODO(hpayer): Free unused memory of last black page.
+ continue;
+ }
+
if (p->IsFlagSet(Page::NEVER_ALLOCATE_ON_PAGE)) {
// We need to sweep the page to get it into an iterable state again. Note
// that this adds unusable memory into the free list that is later on
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698