Commit 6e9e2e58 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

[heap] Move SweeperTask to CancelableTask

This mitigates the problem of blocking on the main thread when the
platform is unable to execute background tasks in a timely manner.

Bug: v8:6655
Change-Id: Icdaae744ee73146b86b9a28c8035138746721971
Reviewed-on: https://chromium-review.googlesource.com/595467
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47036}
parent 828e0e35
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/base/atomicops.h" #include "src/base/atomicops.h"
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/base/sys-info.h" #include "src/base/sys-info.h"
#include "src/cancelable-task.h"
#include "src/code-stubs.h" #include "src/code-stubs.h"
#include "src/compilation-cache.h" #include "src/compilation-cache.h"
#include "src/deoptimizer.h" #include "src/deoptimizer.h"
...@@ -621,12 +622,14 @@ void MarkCompactCollector::ClearMarkbits() { ...@@ -621,12 +622,14 @@ void MarkCompactCollector::ClearMarkbits() {
heap_->lo_space()->ClearMarkingStateOfLiveObjects(); heap_->lo_space()->ClearMarkingStateOfLiveObjects();
} }
class MarkCompactCollector::Sweeper::SweeperTask : public v8::Task { class MarkCompactCollector::Sweeper::SweeperTask final : public CancelableTask {
public: public:
SweeperTask(Sweeper* sweeper, base::Semaphore* pending_sweeper_tasks, SweeperTask(Isolate* isolate, Sweeper* sweeper,
base::Semaphore* pending_sweeper_tasks,
base::AtomicNumber<intptr_t>* num_sweeping_tasks, base::AtomicNumber<intptr_t>* num_sweeping_tasks,
AllocationSpace space_to_start) AllocationSpace space_to_start)
: sweeper_(sweeper), : CancelableTask(isolate),
sweeper_(sweeper),
pending_sweeper_tasks_(pending_sweeper_tasks), pending_sweeper_tasks_(pending_sweeper_tasks),
num_sweeping_tasks_(num_sweeping_tasks), num_sweeping_tasks_(num_sweeping_tasks),
space_to_start_(space_to_start) {} space_to_start_(space_to_start) {}
...@@ -634,8 +637,7 @@ class MarkCompactCollector::Sweeper::SweeperTask : public v8::Task { ...@@ -634,8 +637,7 @@ class MarkCompactCollector::Sweeper::SweeperTask : public v8::Task {
virtual ~SweeperTask() {} virtual ~SweeperTask() {}
private: private:
// v8::Task overrides. void RunInternal() final {
void Run() override {
DCHECK_GE(space_to_start_, FIRST_SPACE); DCHECK_GE(space_to_start_, FIRST_SPACE);
DCHECK_LE(space_to_start_, LAST_PAGED_SPACE); DCHECK_LE(space_to_start_, LAST_PAGED_SPACE);
const int offset = space_to_start_ - FIRST_SPACE; const int offset = space_to_start_ - FIRST_SPACE;
...@@ -650,9 +652,9 @@ class MarkCompactCollector::Sweeper::SweeperTask : public v8::Task { ...@@ -650,9 +652,9 @@ class MarkCompactCollector::Sweeper::SweeperTask : public v8::Task {
pending_sweeper_tasks_->Signal(); pending_sweeper_tasks_->Signal();
} }
Sweeper* sweeper_; Sweeper* const sweeper_;
base::Semaphore* pending_sweeper_tasks_; base::Semaphore* const pending_sweeper_tasks_;
base::AtomicNumber<intptr_t>* num_sweeping_tasks_; base::AtomicNumber<intptr_t>* const num_sweeping_tasks_;
AllocationSpace space_to_start_; AllocationSpace space_to_start_;
DISALLOW_COPY_AND_ASSIGN(SweeperTask); DISALLOW_COPY_AND_ASSIGN(SweeperTask);
...@@ -670,15 +672,19 @@ void MarkCompactCollector::Sweeper::StartSweeping() { ...@@ -670,15 +672,19 @@ void MarkCompactCollector::Sweeper::StartSweeping() {
} }
void MarkCompactCollector::Sweeper::StartSweeperTasks() { void MarkCompactCollector::Sweeper::StartSweeperTasks() {
DCHECK_EQ(0, num_tasks_);
DCHECK_EQ(0, num_sweeping_tasks_.Value());
if (FLAG_concurrent_sweeping && sweeping_in_progress_) { if (FLAG_concurrent_sweeping && sweeping_in_progress_) {
ForAllSweepingSpaces([this](AllocationSpace space) { ForAllSweepingSpaces([this](AllocationSpace space) {
if (space == NEW_SPACE) return; if (space == NEW_SPACE) return;
num_sweeping_tasks_.Increment(1); num_sweeping_tasks_.Increment(1);
semaphore_counter_++; SweeperTask* task = new SweeperTask(heap_->isolate(), this,
&pending_sweeper_tasks_semaphore_,
&num_sweeping_tasks_, space);
DCHECK_LT(num_tasks_, kMaxSweeperTasks);
task_ids_[num_tasks_++] = task->id();
V8::GetCurrentPlatform()->CallOnBackgroundThread( V8::GetCurrentPlatform()->CallOnBackgroundThread(
new SweeperTask(this, &pending_sweeper_tasks_semaphore_, task, v8::Platform::kShortRunningTask);
&num_sweeping_tasks_, space),
v8::Platform::kShortRunningTask);
}); });
} }
} }
...@@ -723,10 +729,14 @@ void MarkCompactCollector::Sweeper::EnsureCompleted() { ...@@ -723,10 +729,14 @@ void MarkCompactCollector::Sweeper::EnsureCompleted() {
[this](AllocationSpace space) { ParallelSweepSpace(space, 0); }); [this](AllocationSpace space) { ParallelSweepSpace(space, 0); });
if (FLAG_concurrent_sweeping) { if (FLAG_concurrent_sweeping) {
while (semaphore_counter_ > 0) { for (int i = 0; i < num_tasks_; i++) {
pending_sweeper_tasks_semaphore_.Wait(); if (heap_->isolate()->cancelable_task_manager()->TryAbort(task_ids_[i]) !=
semaphore_counter_--; CancelableTaskManager::kTaskAborted) {
pending_sweeper_tasks_semaphore_.Wait();
}
} }
num_tasks_ = 0;
num_sweeping_tasks_.SetValue(0);
} }
ForAllSweepingSpaces([this](AllocationSpace space) { ForAllSweepingSpaces([this](AllocationSpace space) {
......
...@@ -493,8 +493,6 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -493,8 +493,6 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
class Sweeper { class Sweeper {
public: public:
class SweeperTask;
enum FreeListRebuildingMode { REBUILD_FREE_LIST, IGNORE_FREE_LIST }; enum FreeListRebuildingMode { REBUILD_FREE_LIST, IGNORE_FREE_LIST };
enum ClearOldToNewSlotsMode { enum ClearOldToNewSlotsMode {
DO_NOT_CLEAR, DO_NOT_CLEAR,
...@@ -510,8 +508,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -510,8 +508,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
explicit Sweeper(Heap* heap) explicit Sweeper(Heap* heap)
: heap_(heap), : heap_(heap),
num_tasks_(0),
pending_sweeper_tasks_semaphore_(0), pending_sweeper_tasks_semaphore_(0),
semaphore_counter_(0),
sweeping_in_progress_(false), sweeping_in_progress_(false),
num_sweeping_tasks_(0) {} num_sweeping_tasks_(0) {}
...@@ -537,7 +535,10 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -537,7 +535,10 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
Page* GetSweptPageSafe(PagedSpace* space); Page* GetSweptPageSafe(PagedSpace* space);
private: private:
class SweeperTask;
static const int kAllocationSpaces = LAST_PAGED_SPACE + 1; static const int kAllocationSpaces = LAST_PAGED_SPACE + 1;
static const int kMaxSweeperTasks = kAllocationSpaces;
template <typename Callback> template <typename Callback>
void ForAllSweepingSpaces(Callback callback) { void ForAllSweepingSpaces(Callback callback) {
...@@ -550,10 +551,10 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { ...@@ -550,10 +551,10 @@ class MarkCompactCollector final : public MarkCompactCollectorBase {
void PrepareToBeSweptPage(AllocationSpace space, Page* page); void PrepareToBeSweptPage(AllocationSpace space, Page* page);
Heap* heap_; Heap* const heap_;
int num_tasks_;
uint32_t task_ids_[kMaxSweeperTasks];
base::Semaphore pending_sweeper_tasks_semaphore_; base::Semaphore pending_sweeper_tasks_semaphore_;
// Counter is only used for waiting on the semaphore.
intptr_t semaphore_counter_;
base::Mutex mutex_; base::Mutex mutex_;
SweptList swept_list_[kAllocationSpaces]; SweptList swept_list_[kAllocationSpaces];
SweepingList sweeping_list_[kAllocationSpaces]; SweepingList sweeping_list_[kAllocationSpaces];
......
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