Commit ba968622 authored by hpayer's avatar hpayer Committed by Commit bot

Synchronize on concurrent store buffer entries.

BUG=chromium:524425
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#30383}
parent 2188bdaf
...@@ -47,6 +47,7 @@ MarkCompactCollector::MarkCompactCollector(Heap* heap) ...@@ -47,6 +47,7 @@ MarkCompactCollector::MarkCompactCollector(Heap* heap)
compacting_(false), compacting_(false),
was_marked_incrementally_(false), was_marked_incrementally_(false),
sweeping_in_progress_(false), sweeping_in_progress_(false),
parallel_compaction_in_progress_(false),
pending_sweeper_jobs_semaphore_(0), pending_sweeper_jobs_semaphore_(0),
pending_compaction_jobs_semaphore_(0), pending_compaction_jobs_semaphore_(0),
evacuation_(false), evacuation_(false),
...@@ -2690,7 +2691,11 @@ void MarkCompactCollector::AbortWeakCells() { ...@@ -2690,7 +2691,11 @@ void MarkCompactCollector::AbortWeakCells() {
void MarkCompactCollector::RecordMigratedSlot(Object* value, Address slot) { void MarkCompactCollector::RecordMigratedSlot(Object* value, Address slot) {
if (heap_->InNewSpace(value)) { if (heap_->InNewSpace(value)) {
heap_->store_buffer()->Mark(slot); if (parallel_compaction_in_progress_) {
heap_->store_buffer()->MarkSynchronized(slot);
} else {
heap_->store_buffer()->Mark(slot);
}
} else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) { } else if (value->IsHeapObject() && IsOnEvacuationCandidate(value)) {
SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_, SlotsBuffer::AddTo(&slots_buffer_allocator_, &migration_slots_buffer_,
reinterpret_cast<Object**>(slot), reinterpret_cast<Object**>(slot),
...@@ -3313,11 +3318,18 @@ void MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) { ...@@ -3313,11 +3318,18 @@ void MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) {
void MarkCompactCollector::EvacuatePagesInParallel() { void MarkCompactCollector::EvacuatePagesInParallel() {
parallel_compaction_in_progress_ = true;
V8::GetCurrentPlatform()->CallOnBackgroundThread( V8::GetCurrentPlatform()->CallOnBackgroundThread(
new CompactionTask(heap()), v8::Platform::kShortRunningTask); new CompactionTask(heap()), v8::Platform::kShortRunningTask);
} }
void MarkCompactCollector::WaitUntilCompactionCompleted() {
pending_compaction_jobs_semaphore_.Wait();
parallel_compaction_in_progress_ = false;
}
void MarkCompactCollector::EvacuatePages() { void MarkCompactCollector::EvacuatePages() {
int npages = evacuation_candidates_.length(); int npages = evacuation_candidates_.length();
int abandoned_pages = 0; int abandoned_pages = 0;
...@@ -3626,7 +3638,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { ...@@ -3626,7 +3638,7 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
EvacuationScope evacuation_scope(this); EvacuationScope evacuation_scope(this);
if (FLAG_parallel_compaction) { if (FLAG_parallel_compaction) {
EvacuatePagesInParallel(); EvacuatePagesInParallel();
pending_compaction_jobs_semaphore_.Wait(); WaitUntilCompactionCompleted();
} else { } else {
EvacuatePages(); EvacuatePages();
} }
......
...@@ -707,6 +707,9 @@ class MarkCompactCollector { ...@@ -707,6 +707,9 @@ class MarkCompactCollector {
// True if concurrent or parallel sweeping is currently in progress. // True if concurrent or parallel sweeping is currently in progress.
bool sweeping_in_progress_; bool sweeping_in_progress_;
// True if parallel compaction is currently in progress.
bool parallel_compaction_in_progress_;
// Synchronize sweeper threads. // Synchronize sweeper threads.
base::Semaphore pending_sweeper_jobs_semaphore_; base::Semaphore pending_sweeper_jobs_semaphore_;
...@@ -873,6 +876,8 @@ class MarkCompactCollector { ...@@ -873,6 +876,8 @@ class MarkCompactCollector {
void EvacuatePagesInParallel(); void EvacuatePagesInParallel();
void WaitUntilCompactionCompleted();
void EvacuateNewSpaceAndCandidates(); void EvacuateNewSpaceAndCandidates();
void ReleaseEvacuationCandidates(); void ReleaseEvacuationCandidates();
......
...@@ -26,6 +26,12 @@ void StoreBuffer::Mark(Address addr) { ...@@ -26,6 +26,12 @@ void StoreBuffer::Mark(Address addr) {
} }
inline void StoreBuffer::MarkSynchronized(Address addr) {
base::LockGuard<base::Mutex> lock_guard(&mutex_);
Mark(addr);
}
void StoreBuffer::EnterDirectlyIntoStoreBuffer(Address addr) { void StoreBuffer::EnterDirectlyIntoStoreBuffer(Address addr) {
if (store_buffer_rebuilding_enabled_) { if (store_buffer_rebuilding_enabled_) {
SLOW_DCHECK(!heap_->code_space()->Contains(addr) && SLOW_DCHECK(!heap_->code_space()->Contains(addr) &&
......
...@@ -33,9 +33,13 @@ class StoreBuffer { ...@@ -33,9 +33,13 @@ class StoreBuffer {
void SetUp(); void SetUp();
void TearDown(); void TearDown();
// This is used by the mutator to enter addresses into the store buffer. // This is used to add addresses to the store buffer non-concurrently.
inline void Mark(Address addr); inline void Mark(Address addr);
// This is used to add addresses to the store buffer when multiple threads
// may operate on the store buffer.
inline void MarkSynchronized(Address addr);
// This is used by the heap traversal to enter the addresses into the store // This is used by the heap traversal to enter the addresses into the store
// buffer that should still be in the store buffer after GC. It enters // buffer that should still be in the store buffer after GC. It enters
// addresses directly into the old buffer because the GC starts by wiping the // addresses directly into the old buffer because the GC starts by wiping the
...@@ -129,6 +133,9 @@ class StoreBuffer { ...@@ -129,6 +133,9 @@ class StoreBuffer {
uintptr_t* hash_set_2_; uintptr_t* hash_set_2_;
bool hash_sets_are_empty_; bool hash_sets_are_empty_;
// Used for synchronization of concurrent store buffer access.
base::Mutex mutex_;
void ClearFilteringHashSets(); void ClearFilteringHashSets();
bool SpaceAvailable(intptr_t space_needed); bool SpaceAvailable(intptr_t space_needed);
......
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