Commit ee41ee6b authored by ulan's avatar ulan Committed by Commit bot

[heap] Color object black on unsafe layout change.

This is a part of synchronization protocol with the concurrent marking.

BUG=chromium:694255

Review-Url: https://codereview.chromium.org/2872323002
Cr-Commit-Position: refs/heads/master@{#45262}
parent 7a88f729
......@@ -47,8 +47,6 @@ class ConcurrentMarkingDeque {
// deque. The concurrent thread can push to both deques.
bool Push(HeapObject* object, MarkingThread thread = MarkingThread::kMain,
TargetDeque target = TargetDeque::kShared) {
DCHECK_IMPLIES(thread == MarkingThread::kMain,
target == TargetDeque::kShared);
switch (target) {
case TargetDeque::kShared:
shared_deque_.Push(object);
......
......@@ -4274,7 +4274,7 @@ void Heap::RegisterDeserializedObjectsForBlackAllocation(
void Heap::NotifyObjectLayoutChange(HeapObject* object,
const DisallowHeapAllocation&) {
if (FLAG_incremental_marking && incremental_marking()->IsMarking()) {
incremental_marking()->WhiteToGreyAndPush(object);
incremental_marking()->MarkBlackAndPush(object);
}
#ifdef VERIFY_HEAP
DCHECK(pending_layout_change_object_ == nullptr);
......
......@@ -137,6 +137,20 @@ bool IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj) {
return false;
}
void IncrementalMarking::MarkBlackAndPush(HeapObject* obj) {
// Color the object black and push it into the bailout deque.
ObjectMarking::WhiteToGrey<kAtomicity>(obj, marking_state(obj));
if (ObjectMarking::GreyToBlack<kAtomicity>(obj, marking_state(obj))) {
#if V8_CONCURRENT_MARKING
marking_deque()->Push(obj, MarkingThread::kMain, TargetDeque::kBailout);
#else
if (!marking_deque()->Push(obj)) {
ObjectMarking::BlackToGrey<kAtomicity>(obj, marking_state(obj));
}
#endif
}
}
void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from,
HeapObject* to) {
DCHECK(MemoryChunk::FromAddress(from->address())->SweepingDone());
......@@ -813,13 +827,9 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
return nullptr;
}
HeapObject* dest = map_word.ToForwardingAddress();
if (ObjectMarking::IsBlack<kAtomicity>(dest, marking_state(dest))) {
// The object is already processed by the marker.
return nullptr;
}
DCHECK(ObjectMarking::IsGrey<kAtomicity>(obj, marking_state(obj)) ||
(obj->IsFiller() &&
ObjectMarking::IsWhite<kAtomicity>(obj, marking_state(obj))));
DCHECK_IMPLIES(
ObjectMarking::IsWhite<kAtomicity>(obj, marking_state(obj)),
obj->IsFiller());
return dest;
} else if (heap_->InToSpace(obj)) {
// The object may be on a page that was moved in new space.
......@@ -838,12 +848,9 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
? obj
: nullptr;
}
DCHECK(ObjectMarking::IsGrey<kAtomicity>(obj, marking_state(obj)) ||
(obj->IsFiller() &&
ObjectMarking::IsWhite<kAtomicity>(obj, marking_state(obj))) ||
(MemoryChunk::FromAddress(obj->address())
->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) &&
ObjectMarking::IsBlack<kAtomicity>(obj, marking_state(obj))));
DCHECK_IMPLIES(
ObjectMarking::IsWhite<kAtomicity>(obj, marking_state(obj)),
obj->IsFiller());
// Skip one word filler objects that appear on the
// stack when we perform in place array shift.
return (obj->map() == filler_map) ? nullptr : obj;
......@@ -858,20 +865,20 @@ bool IncrementalMarking::IsFixedArrayWithProgressBar(HeapObject* obj) {
}
void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) {
#if ENABLE_SLOW_DCHECKS
MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj, marking_state(obj));
MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
SLOW_DCHECK(Marking::IsGrey<kAtomicity>(mark_bit) ||
(chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) &&
Marking::IsBlack<kAtomicity>(mark_bit)));
#endif
if (ObjectMarking::GreyToBlack<kAtomicity>(obj, marking_state(obj))) {
WhiteToGreyAndPush(map);
IncrementalMarkingMarkingVisitor::IterateBody(map, obj);
} else if (IsFixedArrayWithProgressBar(obj)) {
DCHECK(ObjectMarking::IsBlack<kAtomicity>(obj, marking_state(obj)));
IncrementalMarkingMarkingVisitor::VisitFixedArrayIncremental(map, obj);
}
DCHECK(Marking::IsGrey<kAtomicity>(mark_bit) ||
Marking::IsBlack<kAtomicity>(mark_bit));
USE(mark_bit);
// The object can already be black in two cases:
// 1. The object is a fixed array with the progress bar.
// 2. The object is a JSObject that was colored black before
// unsafe layout change.
if (!ObjectMarking::GreyToBlack<kAtomicity>(obj, marking_state(obj))) {
DCHECK(IsFixedArrayWithProgressBar(obj) || obj->IsJSObject());
}
DCHECK(ObjectMarking::IsBlack<kAtomicity>(obj, marking_state(obj)));
WhiteToGreyAndPush(map);
IncrementalMarkingMarkingVisitor::IterateBody(map, obj);
}
intptr_t IncrementalMarking::ProcessMarkingDeque(
......
......@@ -223,6 +223,11 @@ class V8_EXPORT_PRIVATE IncrementalMarking {
// from white to grey.
bool WhiteToGreyAndPush(HeapObject* obj);
// This function is used to color the object black before it undergoes an
// unsafe layout change. This is a part of synchronization protocol with
// the concurrent marker.
void MarkBlackAndPush(HeapObject* obj);
inline void SetOldSpacePageFlags(MemoryChunk* chunk) {
SetOldSpacePageFlags(chunk, IsMarking(), IsCompacting());
}
......
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