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

[heap] Refactor updating of marking deque after scavenge.

This introduces MarkingDeque::Update function that accepts a callback
and updates marking deque elements using the callback.

BUG=chromium:694255

Review-Url: https://codereview.chromium.org/2854063002
Cr-Commit-Position: refs/heads/master@{#45032}
parent 259f061f
......@@ -763,51 +763,42 @@ void IncrementalMarking::FinalizeIncrementally() {
void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
if (!IsMarking()) return;
int current = marking_deque()->bottom();
int mask = marking_deque()->mask();
int limit = marking_deque()->top();
HeapObject** array = marking_deque()->array();
int new_top = current;
Map* filler_map = heap_->one_pointer_filler_map();
while (current != limit) {
HeapObject* obj = array[current];
marking_deque()->Update([this, filler_map](HeapObject* obj) -> HeapObject* {
DCHECK(obj->IsHeapObject());
current = ((current + 1) & mask);
// Only pointers to from space have to be updated.
if (heap_->InFromSpace(obj)) {
MapWord map_word = obj->map_word();
// There may be objects on the marking deque that do not exist anymore,
// e.g. left trimmed objects or objects from the root set (frames).
// If these object are dead at scavenging time, their marking deque
// entries will not point to forwarding addresses. Hence, we can discard
// them.
if (map_word.IsForwardingAddress()) {
HeapObject* dest = map_word.ToForwardingAddress();
if (ObjectMarking::IsBlack(dest, marking_state(dest))) continue;
array[new_top] = dest;
new_top = ((new_top + 1) & mask);
DCHECK(new_top != marking_deque()->bottom());
DCHECK(ObjectMarking::IsGrey(obj, marking_state(obj)) ||
(obj->IsFiller() &&
ObjectMarking::IsWhite(obj, marking_state(obj))));
if (!map_word.IsForwardingAddress()) {
// There may be objects on the marking deque that do not exist anymore,
// e.g. left trimmed objects or objects from the root set (frames).
// If these object are dead at scavenging time, their marking deque
// entries will not point to forwarding addresses. Hence, we can discard
// them.
return nullptr;
}
} else if (obj->map() != filler_map) {
// Skip one word filler objects that appear on the
// stack when we perform in place array shift.
array[new_top] = obj;
new_top = ((new_top + 1) & mask);
DCHECK(new_top != marking_deque()->bottom());
HeapObject* dest = map_word.ToForwardingAddress();
if (ObjectMarking::IsBlack(dest, marking_state(dest))) {
// The object is already processed by the marker.
return nullptr;
}
DCHECK(
ObjectMarking::IsGrey(obj, marking_state(obj)) ||
(obj->IsFiller() && ObjectMarking::IsWhite(obj, marking_state(obj))));
return dest;
} else {
DCHECK(ObjectMarking::IsGrey(obj, marking_state(obj)) ||
(obj->IsFiller() &&
ObjectMarking::IsWhite(obj, marking_state(obj))) ||
(MemoryChunk::FromAddress(obj->address())
->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) &&
ObjectMarking::IsBlack(obj, marking_state(obj))));
// Skip one word filler objects that appear on the
// stack when we perform in place array shift.
return (obj->map() == filler_map) ? nullptr : obj;
}
}
marking_deque()->set_top(new_top);
});
}
......
......@@ -95,11 +95,26 @@ class SequentialMarkingDeque {
}
}
HeapObject** array() { return array_; }
int bottom() { return bottom_; }
// Calls the specified callback on each element of the deque and replaces
// the element with the result of the callback. If the callback returns
// nullptr then the element is removed from the deque.
// The callback must accept HeapObject* and return HeapObject*.
template <typename Callback>
void Update(Callback callback) {
int i = bottom_;
int new_top = bottom_;
while (i != top_) {
HeapObject* object = callback(array_[i]);
if (object) {
array_[new_top] = object;
new_top = (new_top + 1) & mask_;
}
i = (i + 1) & mask_;
}
top_ = new_top;
}
int top() { return top_; }
int mask() { return mask_; }
void set_top(int top) { top_ = top; }
private:
// This task uncommits the marking_deque backing store if
......
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