Commit 9b547628 authored by hpayer's avatar hpayer Committed by Commit bot

[heap] RecordWrites iterates black object to ensure marking progress.

RecordWrites is not performing black to grey transitions anymore. In a follow up CL I will clean-up the remaining sites where we do black to grey, e.g. when we overflow marking deque.

BUG=

Review URL: https://codereview.chromium.org/1823783003

Cr-Commit-Position: refs/heads/master@{#35031}
parent 2012e564
......@@ -1108,7 +1108,7 @@ void Heap::MoveElements(FixedArray* array, int dst_index, int src_index,
dst_objects[i]);
}
}
incremental_marking()->RecordWrites(array);
incremental_marking()->IterateBlackObject(array);
}
......@@ -4709,10 +4709,9 @@ void Heap::IteratePromotedObject(HeapObject* target, int size,
// regular visiting and IteratePromotedObjectPointers.
if (!was_marked_black) {
if (incremental_marking()->black_allocation()) {
Map* map = target->map();
IncrementalMarking::MarkObject(this, map);
IncrementalMarking::MarkObject(this, target->map());
incremental_marking()->IterateBlackObject(target);
}
incremental_marking()->IterateBlackObject(target);
}
}
......
......@@ -141,52 +141,6 @@ void IncrementalMarking::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo,
}
void IncrementalMarking::RecordWrites(HeapObject* obj) {
if (IsMarking()) {
MarkBit obj_bit = Marking::MarkBitFrom(obj);
if (Marking::IsBlack(obj_bit)) {
MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) {
chunk->set_progress_bar(0);
}
BlackToGreyAndUnshift(obj, obj_bit);
RestartIfNotMarking();
}
}
}
void IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj,
MarkBit mark_bit) {
DCHECK(Marking::MarkBitFrom(obj) == mark_bit);
DCHECK(obj->Size() >= 2 * kPointerSize);
DCHECK(IsMarking());
Marking::BlackToGrey(mark_bit);
int obj_size = obj->Size();
MemoryChunk::IncrementLiveBytesFromGC(obj, -obj_size);
bytes_scanned_ -= obj_size;
int64_t old_bytes_rescanned = bytes_rescanned_;
bytes_rescanned_ = old_bytes_rescanned + obj_size;
if ((bytes_rescanned_ >> 20) != (old_bytes_rescanned >> 20)) {
if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSizeOfObjects()) {
// If we have queued twice the heap size for rescanning then we are
// going around in circles, scanning the same objects again and again
// as the program mutates the heap faster than we can incrementally
// trace it. In this case we switch to non-incremental marking in
// order to finish off this marking phase.
if (FLAG_trace_incremental_marking) {
PrintIsolate(
heap()->isolate(),
"Hurrying incremental marking because of lack of progress\n");
}
marking_speed_ = kMaxMarkingSpeed;
}
}
heap_->mark_compact_collector()->marking_deque()->Unshift(obj);
}
void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) {
Marking::WhiteToGrey(mark_bit);
heap_->mark_compact_collector()->marking_deque()->Push(obj);
......@@ -323,8 +277,7 @@ class IncrementalMarkingMarkingVisitor
};
void IncrementalMarking::IterateBlackObject(HeapObject* object) {
if (black_allocation() &&
Page::FromAddress(object->address())->IsFlagSet(Page::BLACK_PAGE)) {
if (IsMarking() && Marking::IsBlack(Marking::MarkBitFrom(object))) {
IncrementalMarkingMarkingVisitor::IterateBody(object->map(), object);
}
}
......
......@@ -176,10 +176,6 @@ class IncrementalMarking {
void RecordCodeTargetPatch(Code* host, Address pc, HeapObject* value);
void RecordCodeTargetPatch(Address pc, HeapObject* value);
void RecordWrites(HeapObject* obj);
void BlackToGreyAndUnshift(HeapObject* obj, MarkBit mark_bit);
void WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit);
inline void SetOldSpacePageFlags(MemoryChunk* chunk) {
......
......@@ -143,21 +143,10 @@ template <LiveObjectIterationMode T>
HeapObject* LiveObjectIterator<T>::Next() {
while (!it_.Done()) {
HeapObject* object = nullptr;
if (T == kGreyObjectsOnBlackPage) {
// Black objects will have most of the mark bits set to 1. If we invert
// the mark bits, grey objects will be left but the mark bit is moved by
// one position. We can just substract one word from the found location
// to obtain the grey object.
current_cell_ = ~current_cell_;
}
while (current_cell_ != 0) {
uint32_t trailing_zeros = base::bits::CountTrailingZeros32(current_cell_);
Address addr = cell_base_ + trailing_zeros * kPointerSize;
if (T == kGreyObjectsOnBlackPage) {
addr -= kPointerSize;
}
// Clear the first bit of the found object..
current_cell_ &= ~(1u << trailing_zeros);
......@@ -179,14 +168,10 @@ HeapObject* LiveObjectIterator<T>::Next() {
object = HeapObject::FromAddress(addr);
} else if (T == kAllLiveObjects) {
object = HeapObject::FromAddress(addr);
} else if (T == kGreyObjectsOnBlackPage) {
object = HeapObject::FromAddress(addr);
}
if (T != kGreyObjectsOnBlackPage) {
// Clear the second bit of the found object.
current_cell_ &= ~second_bit_index;
}
// Clear the second bit of the found object.
current_cell_ &= ~second_bit_index;
// We found a live object.
if (object != nullptr) break;
......
......@@ -1010,7 +1010,7 @@ void CodeFlusher::ProcessSharedFunctionInfoCandidates() {
void CodeFlusher::EvictCandidate(SharedFunctionInfo* shared_info) {
// Make sure previous flushing decisions are revisited.
isolate_->heap()->incremental_marking()->RecordWrites(shared_info);
isolate_->heap()->incremental_marking()->IterateBlackObject(shared_info);
if (FLAG_trace_code_flushing) {
PrintF("[code-flushing abandons function-info: ");
......@@ -1046,8 +1046,9 @@ void CodeFlusher::EvictCandidate(JSFunction* function) {
Object* undefined = isolate_->heap()->undefined_value();
// Make sure previous flushing decisions are revisited.
isolate_->heap()->incremental_marking()->RecordWrites(function);
isolate_->heap()->incremental_marking()->RecordWrites(function->shared());
isolate_->heap()->incremental_marking()->IterateBlackObject(function);
isolate_->heap()->incremental_marking()->IterateBlackObject(
function->shared());
if (FLAG_trace_code_flushing) {
PrintF("[code-flushing abandons closure: ");
......@@ -1493,11 +1494,9 @@ void MarkCompactCollector::DiscoverGreyObjectsWithIterator(T* it) {
}
}
template <LiveObjectIterationMode T>
void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) {
DCHECK(!marking_deque()->IsFull());
DCHECK(T == kGreyObjects || T == kGreyObjectsOnBlackPage);
LiveObjectIterator<T> it(p);
LiveObjectIterator<kGreyObjects> it(p);
HeapObject* object = NULL;
while ((object = it.Next()) != NULL) {
MarkBit markbit = Marking::MarkBitFrom(object);
......@@ -1798,10 +1797,8 @@ void MarkCompactCollector::DiscoverGreyObjectsInSpace(PagedSpace* space) {
PageIterator it(space);
while (it.has_next()) {
Page* p = it.next();
if (p->IsFlagSet(Page::BLACK_PAGE)) {
DiscoverGreyObjectsOnPage<kGreyObjectsOnBlackPage>(p);
} else {
DiscoverGreyObjectsOnPage<kGreyObjects>(p);
if (!p->IsFlagSet(Page::BLACK_PAGE)) {
DiscoverGreyObjectsOnPage(p);
}
if (marking_deque()->IsFull()) return;
}
......@@ -1813,7 +1810,7 @@ void MarkCompactCollector::DiscoverGreyObjectsInNewSpace() {
NewSpacePageIterator it(space->bottom(), space->top());
while (it.has_next()) {
NewSpacePage* page = it.next();
DiscoverGreyObjectsOnPage<kGreyObjects>(page);
DiscoverGreyObjectsOnPage(page);
if (marking_deque()->IsFull()) return;
}
}
......
......@@ -370,7 +370,6 @@ class MarkBitCellIterator BASE_EMBEDDED {
enum LiveObjectIterationMode {
kBlackObjects,
kGreyObjects,
kGreyObjectsOnBlackPage,
kAllLiveObjects
};
......@@ -382,10 +381,8 @@ class LiveObjectIterator BASE_EMBEDDED {
it_(chunk_),
cell_base_(it_.CurrentCellBase()),
current_cell_(*it_.CurrentCell()) {
// Black pages can only be iterated with kGreyObjectsOnBlackPage mode.
if (T != kGreyObjectsOnBlackPage) {
DCHECK(!chunk->IsFlagSet(Page::BLACK_PAGE));
}
// Black pages can not be iterated.
DCHECK(!chunk->IsFlagSet(Page::BLACK_PAGE));
}
HeapObject* Next();
......@@ -709,7 +706,6 @@ class MarkCompactCollector {
// on various pages of the heap. Used by {RefillMarkingDeque} only.
template <class T>
void DiscoverGreyObjectsWithIterator(T* it);
template <LiveObjectIterationMode T>
void DiscoverGreyObjectsOnPage(MemoryChunk* p);
void DiscoverGreyObjectsInSpace(PagedSpace* space);
void DiscoverGreyObjectsInNewSpace();
......
......@@ -3199,7 +3199,7 @@ void Map::ReplaceDescriptors(DescriptorArray* new_descriptors,
}
DescriptorArray* to_replace = instance_descriptors();
GetHeap()->incremental_marking()->RecordWrites(to_replace);
GetHeap()->incremental_marking()->IterateBlackObject(to_replace);
Map* current = this;
while (current->instance_descriptors() == to_replace) {
Object* next = current->GetBackPointer();
......@@ -4573,7 +4573,7 @@ void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) {
}
// Replace descriptors by new_descriptors in all maps that share it.
map->GetHeap()->incremental_marking()->RecordWrites(*descriptors);
map->GetHeap()->incremental_marking()->IterateBlackObject(*descriptors);
Map* current = *map;
while (current->instance_descriptors() == *descriptors) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment