Commit 2bed5a29 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Handle object creation data races in concurrent marking.

Black allocation is switched on at the start of incremental marking
if concurrent marking is enabled.

New space objects in the allocation area are handled by the main thread.

BUG=chromium:694255

Change-Id: I694affe11b95f51e2fe79563b2b048aaef982c03
Reviewed-on: https://chromium-review.googlesource.com/518862
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45626}
parent 6f69e3ce
......@@ -255,7 +255,14 @@ void ConcurrentMarking::Run() {
HeapObject* object;
while ((object = deque_->Pop(MarkingThread::kConcurrent)) != nullptr) {
base::LockGuard<base::Mutex> guard(relocation_mutex);
bytes_marked += visitor_->Visit(object);
Address new_space_top = heap_->new_space()->original_top();
Address new_space_limit = heap_->new_space()->original_limit();
Address addr = object->address();
if (new_space_top <= addr && addr < new_space_limit) {
deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kBailout);
} else {
bytes_marked += visitor_->Visit(object);
}
}
}
if (FLAG_trace_concurrent_marking) {
......
......@@ -583,6 +583,10 @@ void IncrementalMarking::StartMarking() {
heap_->CompletelyClearInstanceofCache();
heap_->isolate()->compilation_cache()->MarkCompactPrologue();
if (FLAG_concurrent_marking && !black_allocation_) {
StartBlackAllocation();
}
// Mark strong roots grey.
IncrementalMarkingRootMarkingVisitor visitor(this);
heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
......
......@@ -1785,6 +1785,8 @@ LocalAllocationBuffer& LocalAllocationBuffer::operator=(
void NewSpace::UpdateAllocationInfo() {
MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
allocation_info_.Reset(to_space_.page_low(), to_space_.page_high());
original_top_.SetValue(top());
original_limit_.SetValue(limit());
UpdateInlineAllocationLimit(0);
DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
}
......
......@@ -1545,22 +1545,14 @@ class V8_EXPORT_PRIVATE HeapObjectIterator : public ObjectIterator {
// space.
class AllocationInfo {
public:
AllocationInfo() : original_top_(nullptr), top_(nullptr), limit_(nullptr) {}
AllocationInfo(Address top, Address limit)
: original_top_(top), top_(top), limit_(limit) {}
AllocationInfo() : top_(nullptr), limit_(nullptr) {}
AllocationInfo(Address top, Address limit) : top_(top), limit_(limit) {}
void Reset(Address top, Address limit) {
original_top_ = top;
set_top(top);
set_limit(limit);
}
Address original_top() {
SLOW_DCHECK(top_ == NULL ||
(reinterpret_cast<intptr_t>(top_) & kHeapObjectTagMask) == 0);
return original_top_;
}
INLINE(void set_top(Address top)) {
SLOW_DCHECK(top == NULL ||
(reinterpret_cast<intptr_t>(top) & kHeapObjectTagMask) == 0);
......@@ -1594,8 +1586,6 @@ class AllocationInfo {
#endif
private:
// The original top address when the allocation info was initialized.
Address original_top_;
// Current allocation top.
Address top_;
// Current allocation limit.
......@@ -2443,10 +2433,10 @@ class NewSpace : public Space {
explicit NewSpace(Heap* heap)
: Space(heap, NEW_SPACE, NOT_EXECUTABLE),
top_on_previous_step_(0),
to_space_(heap, kToSpace),
from_space_(heap, kFromSpace),
reservation_(),
top_on_previous_step_(0),
allocated_histogram_(nullptr),
promoted_histogram_(nullptr) {}
......@@ -2580,6 +2570,10 @@ class NewSpace : public Space {
return allocation_info_.limit();
}
Address original_top() { return original_top_.Value(); }
Address original_limit() { return original_limit_.Value(); }
// Return the address of the first object in the active semispace.
Address bottom() { return to_space_.space_start(); }
......@@ -2710,16 +2704,20 @@ class NewSpace : public Space {
base::Mutex mutex_;
// Allocation pointer and limit for normal allocation and allocation during
// mark-compact collection.
AllocationInfo allocation_info_;
Address top_on_previous_step_;
// The top and the limit at the time of setting the allocation info.
// These values can be accessed by background tasks.
base::AtomicValue<Address> original_top_;
base::AtomicValue<Address> original_limit_;
// The semispaces.
SemiSpace to_space_;
SemiSpace from_space_;
base::VirtualMemory reservation_;
// Allocation pointer and limit for normal allocation and allocation during
// mark-compact collection.
AllocationInfo allocation_info_;
Address top_on_previous_step_;
HistogramInfo* allocated_histogram_;
HistogramInfo* promoted_histogram_;
......
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