| Index: src/compiler-dispatcher/compiler-dispatcher.cc
|
| diff --git a/src/compiler-dispatcher/compiler-dispatcher.cc b/src/compiler-dispatcher/compiler-dispatcher.cc
|
| index ba5154e0112591bae737245c87cf08e756c65a39..888516e31aaacc4e15f72bb0ebcc7e50eefb27c2 100644
|
| --- a/src/compiler-dispatcher/compiler-dispatcher.cc
|
| +++ b/src/compiler-dispatcher/compiler-dispatcher.cc
|
| @@ -93,6 +93,32 @@ void DoNextStepOnBackgroundThread(CompilerDispatcherJob* job) {
|
| // we'll get all of it so try to be a conservative.
|
| const double kMaxIdleTimeToExpectInMs = 40;
|
|
|
| +class MemoryPressureTask : public CancelableTask {
|
| + public:
|
| + MemoryPressureTask(Isolate* isolate, CancelableTaskManager* task_manager,
|
| + CompilerDispatcher* dispatcher);
|
| + ~MemoryPressureTask() override;
|
| +
|
| + // CancelableTask implementation.
|
| + void RunInternal() override;
|
| +
|
| + private:
|
| + CompilerDispatcher* dispatcher_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MemoryPressureTask);
|
| +};
|
| +
|
| +MemoryPressureTask::MemoryPressureTask(Isolate* isolate,
|
| + CancelableTaskManager* task_manager,
|
| + CompilerDispatcher* dispatcher)
|
| + : CancelableTask(isolate, task_manager), dispatcher_(dispatcher) {}
|
| +
|
| +MemoryPressureTask::~MemoryPressureTask() {}
|
| +
|
| +void MemoryPressureTask::RunInternal() {
|
| + dispatcher_->AbortAll(CompilerDispatcher::BlockingBehavior::kDontBlock);
|
| +}
|
| +
|
| } // namespace
|
|
|
| class CompilerDispatcher::AbortTask : public CancelableTask {
|
| @@ -180,6 +206,7 @@ CompilerDispatcher::CompilerDispatcher(Isolate* isolate, Platform* platform,
|
| max_stack_size_(max_stack_size),
|
| tracer_(new CompilerDispatcherTracer(isolate_)),
|
| task_manager_(new CancelableTaskManager()),
|
| + memory_pressure_level_(MemoryPressureLevel::kNone),
|
| abort_(false),
|
| idle_task_scheduled_(false),
|
| num_scheduled_background_tasks_(0),
|
| @@ -196,6 +223,10 @@ CompilerDispatcher::~CompilerDispatcher() {
|
| bool CompilerDispatcher::Enqueue(Handle<SharedFunctionInfo> function) {
|
| if (!IsEnabled()) return false;
|
|
|
| + if (memory_pressure_level_.Value() != MemoryPressureLevel::kNone) {
|
| + return false;
|
| + }
|
| +
|
| {
|
| base::LockGuard<base::Mutex> lock(&mutex_);
|
| if (abort_) return false;
|
| @@ -319,6 +350,34 @@ void CompilerDispatcher::AbortInactiveJobs() {
|
| }
|
| }
|
|
|
| +void CompilerDispatcher::MemoryPressureNotification(
|
| + v8::MemoryPressureLevel level, bool is_isolate_locked) {
|
| + MemoryPressureLevel previous = memory_pressure_level_.Value();
|
| + memory_pressure_level_.SetValue(level);
|
| + // If we're already under pressure, we haven't accepted new tasks meanwhile
|
| + // and can just return. If we're no longer under pressure, we're also done.
|
| + if (previous != MemoryPressureLevel::kNone ||
|
| + level == MemoryPressureLevel::kNone) {
|
| + return;
|
| + }
|
| + if (is_isolate_locked) {
|
| + AbortAll(BlockingBehavior::kDontBlock);
|
| + } else {
|
| + {
|
| + base::LockGuard<base::Mutex> lock(&mutex_);
|
| + if (abort_) return;
|
| + // By going into abort mode here, and clearing the
|
| + // pending_background_jobs_, we at keep existing background jobs from
|
| + // picking up more work before the MemoryPressureTask gets executed.
|
| + abort_ = true;
|
| + pending_background_jobs_.clear();
|
| + }
|
| + platform_->CallOnForegroundThread(
|
| + reinterpret_cast<v8::Isolate*>(isolate_),
|
| + new MemoryPressureTask(isolate_, task_manager_.get(), this));
|
| + }
|
| +}
|
| +
|
| CompilerDispatcher::JobMap::const_iterator CompilerDispatcher::GetJobFor(
|
| Handle<SharedFunctionInfo> shared) const {
|
| if (!shared->script()->IsScript()) return jobs_.end();
|
|
|