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,9 +255,16 @@ void ConcurrentMarking::Run() { ...@@ -255,9 +255,16 @@ void ConcurrentMarking::Run() {
HeapObject* object; HeapObject* object;
while ((object = deque_->Pop(MarkingThread::kConcurrent)) != nullptr) { while ((object = deque_->Pop(MarkingThread::kConcurrent)) != nullptr) {
base::LockGuard<base::Mutex> guard(relocation_mutex); base::LockGuard<base::Mutex> guard(relocation_mutex);
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); bytes_marked += visitor_->Visit(object);
} }
} }
}
if (FLAG_trace_concurrent_marking) { if (FLAG_trace_concurrent_marking) {
heap_->isolate()->PrintWithTimestamp("concurrently marked %dKB in %.2fms\n", heap_->isolate()->PrintWithTimestamp("concurrently marked %dKB in %.2fms\n",
static_cast<int>(bytes_marked / KB), static_cast<int>(bytes_marked / KB),
......
...@@ -583,6 +583,10 @@ void IncrementalMarking::StartMarking() { ...@@ -583,6 +583,10 @@ void IncrementalMarking::StartMarking() {
heap_->CompletelyClearInstanceofCache(); heap_->CompletelyClearInstanceofCache();
heap_->isolate()->compilation_cache()->MarkCompactPrologue(); heap_->isolate()->compilation_cache()->MarkCompactPrologue();
if (FLAG_concurrent_marking && !black_allocation_) {
StartBlackAllocation();
}
// Mark strong roots grey. // Mark strong roots grey.
IncrementalMarkingRootMarkingVisitor visitor(this); IncrementalMarkingRootMarkingVisitor visitor(this);
heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
......
...@@ -1785,6 +1785,8 @@ LocalAllocationBuffer& LocalAllocationBuffer::operator=( ...@@ -1785,6 +1785,8 @@ LocalAllocationBuffer& LocalAllocationBuffer::operator=(
void NewSpace::UpdateAllocationInfo() { void NewSpace::UpdateAllocationInfo() {
MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
allocation_info_.Reset(to_space_.page_low(), to_space_.page_high()); allocation_info_.Reset(to_space_.page_low(), to_space_.page_high());
original_top_.SetValue(top());
original_limit_.SetValue(limit());
UpdateInlineAllocationLimit(0); UpdateInlineAllocationLimit(0);
DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
} }
......
...@@ -1545,22 +1545,14 @@ class V8_EXPORT_PRIVATE HeapObjectIterator : public ObjectIterator { ...@@ -1545,22 +1545,14 @@ class V8_EXPORT_PRIVATE HeapObjectIterator : public ObjectIterator {
// space. // space.
class AllocationInfo { class AllocationInfo {
public: public:
AllocationInfo() : original_top_(nullptr), top_(nullptr), limit_(nullptr) {} AllocationInfo() : top_(nullptr), limit_(nullptr) {}
AllocationInfo(Address top, Address limit) AllocationInfo(Address top, Address limit) : top_(top), limit_(limit) {}
: original_top_(top), top_(top), limit_(limit) {}
void Reset(Address top, Address limit) { void Reset(Address top, Address limit) {
original_top_ = top;
set_top(top); set_top(top);
set_limit(limit); 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)) { INLINE(void set_top(Address top)) {
SLOW_DCHECK(top == NULL || SLOW_DCHECK(top == NULL ||
(reinterpret_cast<intptr_t>(top) & kHeapObjectTagMask) == 0); (reinterpret_cast<intptr_t>(top) & kHeapObjectTagMask) == 0);
...@@ -1594,8 +1586,6 @@ class AllocationInfo { ...@@ -1594,8 +1586,6 @@ class AllocationInfo {
#endif #endif
private: private:
// The original top address when the allocation info was initialized.
Address original_top_;
// Current allocation top. // Current allocation top.
Address top_; Address top_;
// Current allocation limit. // Current allocation limit.
...@@ -2443,10 +2433,10 @@ class NewSpace : public Space { ...@@ -2443,10 +2433,10 @@ class NewSpace : public Space {
explicit NewSpace(Heap* heap) explicit NewSpace(Heap* heap)
: Space(heap, NEW_SPACE, NOT_EXECUTABLE), : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
top_on_previous_step_(0),
to_space_(heap, kToSpace), to_space_(heap, kToSpace),
from_space_(heap, kFromSpace), from_space_(heap, kFromSpace),
reservation_(), reservation_(),
top_on_previous_step_(0),
allocated_histogram_(nullptr), allocated_histogram_(nullptr),
promoted_histogram_(nullptr) {} promoted_histogram_(nullptr) {}
...@@ -2580,6 +2570,10 @@ class NewSpace : public Space { ...@@ -2580,6 +2570,10 @@ class NewSpace : public Space {
return allocation_info_.limit(); 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. // Return the address of the first object in the active semispace.
Address bottom() { return to_space_.space_start(); } Address bottom() { return to_space_.space_start(); }
...@@ -2710,16 +2704,20 @@ class NewSpace : public Space { ...@@ -2710,16 +2704,20 @@ class NewSpace : public Space {
base::Mutex mutex_; 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. // The semispaces.
SemiSpace to_space_; SemiSpace to_space_;
SemiSpace from_space_; SemiSpace from_space_;
base::VirtualMemory reservation_; 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* allocated_histogram_;
HistogramInfo* promoted_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