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

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, 10 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
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index f23918cbfe1f9c9da1e294839b634f93c17e6cf2..14683babe56274e3e1d5852a9d9ea343f5a56a40 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -144,7 +144,9 @@ 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)) {
+ VerifyMarking(space->heap(), p->area_start(), p->area_end());
+ }
ulan 2016/02/10 10:27:39 It would be great to verify coloring invariant for
Hannes Payer (out of office) 2016/02/11 18:18:07 Done.
}
}
@@ -448,7 +450,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);
+ }
}
}
@@ -471,8 +477,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);
+ }
}
}
@@ -581,7 +591,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
@@ -690,6 +702,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;
if (p->IsFlagSet(Page::POPULAR_PAGE)) {
// This page had slots buffer overflow on previous GC, skip it.
p->ClearFlag(Page::POPULAR_PAGE);
@@ -1733,8 +1746,10 @@ void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) {
PageIterator it(space);
while (it.has_next()) {
Page* p = it.next();
- DiscoverGreyObjectsOnPage(p);
- if (marking_deque()->IsFull()) return;
+ if (!p->IsFlagSet(Page::BLACK_PAGE)) {
+ DiscoverGreyObjectsOnPage(p);
+ if (marking_deque()->IsFull()) return;
+ }
}
}
@@ -2913,6 +2928,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);
@@ -2993,7 +3014,6 @@ bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot,
bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) {
- // This function does not support large objects right now.
Space* owner = p->owner();
if (owner == heap_->lo_space() || owner == NULL) {
Object* large_object = heap_->lo_space()->FindObject(slot);
@@ -3007,6 +3027,8 @@ bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) {
return false;
}
+ if (p->IsFlagSet(Page::BLACK_PAGE)) return true;
+
LiveObjectIterator<kBlackObjects> it(p);
HeapObject* object = NULL;
while ((object = it.Next()) != NULL) {
@@ -3022,15 +3044,21 @@ bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, 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);
}
@@ -3433,6 +3461,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));
@@ -3889,6 +3918,16 @@ void MarkCompactCollector::StartSweepSpace(PagedSpace* space) {
Page* p = it.next();
DCHECK(p->SweepingDone());
+ // 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::RESCAN_ON_EVACUATION) ||
p->IsEvacuationCandidate()) {
// Will be processed in EvacuateNewSpaceAndCandidates.

Powered by Google App Engine
This is Rietveld 408576698