HELLO·Android
系统源代码
IT资讯
技术文章
我的收藏
注册
登录
-
我收藏的文章
创建代码块
我的代码块
我的账号
Pie
|
9.0.0_r8
下载
查看原文件
收藏
根目录
external
v8
src
compiler-dispatcher
compiler-dispatcher.cc
// Copyright 2016 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/compiler-dispatcher/compiler-dispatcher.h" #include "include/v8-platform.h" #include "include/v8.h" #include "src/base/platform/time.h" #include "src/cancelable-task.h" #include "src/compilation-info.h" #include "src/compiler-dispatcher/compiler-dispatcher-job.h" #include "src/compiler-dispatcher/compiler-dispatcher-tracer.h" #include "src/flags.h" #include "src/objects-inl.h" namespace v8 { namespace internal { namespace { enum class ExceptionHandling { kSwallow, kThrow }; bool DoNextStepOnMainThread(Isolate* isolate, CompilerDispatcherJob* job, ExceptionHandling exception_handling) { DCHECK(ThreadId::Current().Equals(isolate->thread_id())); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompilerDispatcherForgroundStep"); // Ensure we are in the correct context for the job. SaveContext save(isolate); isolate->set_context(job->context()); switch (job->status()) { case CompileJobStatus::kInitial: job->PrepareToParseOnMainThread(); break; case CompileJobStatus::kReadyToParse: job->Parse(); break; case CompileJobStatus::kParsed: job->FinalizeParsingOnMainThread(); break; case CompileJobStatus::kReadyToAnalyze: job->AnalyzeOnMainThread(); break; case CompileJobStatus::kAnalyzed: job->PrepareToCompileOnMainThread(); break; case CompileJobStatus::kReadyToCompile: job->Compile(); break; case CompileJobStatus::kCompiled: job->FinalizeCompilingOnMainThread(); break; case CompileJobStatus::kFailed: case CompileJobStatus::kDone: break; } DCHECK_EQ(job->status() == CompileJobStatus::kFailed, isolate->has_pending_exception()); if (job->status() == CompileJobStatus::kFailed && exception_handling == ExceptionHandling::kSwallow) { isolate->clear_pending_exception(); } return job->status() != CompileJobStatus::kFailed; } bool IsFinished(CompilerDispatcherJob* job) { return job->status() == CompileJobStatus::kDone || job->status() == CompileJobStatus::kFailed; } bool CanRunOnAnyThread(CompilerDispatcherJob* job) { return job->status() == CompileJobStatus::kReadyToParse || job->status() == CompileJobStatus::kReadyToCompile; } void DoNextStepOnBackgroundThread(CompilerDispatcherJob* job) { DCHECK(CanRunOnAnyThread(job)); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompilerDispatcherBackgroundStep"); switch (job->status()) { case CompileJobStatus::kReadyToParse: job->Parse(); break; case CompileJobStatus::kReadyToCompile: job->Compile(); break; default: UNREACHABLE(); } } // Theoretically we get 50ms of idle time max, however it's unlikely that // 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 { public: AbortTask(Isolate* isolate, CancelableTaskManager* task_manager, CompilerDispatcher* dispatcher); ~AbortTask() override; // CancelableTask implementation. void RunInternal() override; private: CompilerDispatcher* dispatcher_; DISALLOW_COPY_AND_ASSIGN(AbortTask); }; CompilerDispatcher::AbortTask::AbortTask(Isolate* isolate, CancelableTaskManager* task_manager, CompilerDispatcher* dispatcher) : CancelableTask(isolate, task_manager), dispatcher_(dispatcher) {} CompilerDispatcher::AbortTask::~AbortTask() {} void CompilerDispatcher::AbortTask::RunInternal() { dispatcher_->AbortInactiveJobs(); } class CompilerDispatcher::BackgroundTask : public CancelableTask { public: BackgroundTask(Isolate* isolate, CancelableTaskManager* task_manager, CompilerDispatcher* dispatcher); ~BackgroundTask() override; // CancelableTask implementation. void RunInternal() override; private: CompilerDispatcher* dispatcher_; DISALLOW_COPY_AND_ASSIGN(BackgroundTask); }; CompilerDispatcher::BackgroundTask::BackgroundTask( Isolate* isolate, CancelableTaskManager* task_manager, CompilerDispatcher* dispatcher) : CancelableTask(isolate, task_manager), dispatcher_(dispatcher) {} CompilerDispatcher::BackgroundTask::~BackgroundTask() {} void CompilerDispatcher::BackgroundTask::RunInternal() { dispatcher_->DoBackgroundWork(); } class CompilerDispatcher::IdleTask : public CancelableIdleTask { public: IdleTask(Isolate* isolate, CancelableTaskManager* task_manager, CompilerDispatcher* dispatcher); ~IdleTask() override; // CancelableIdleTask implementation. void RunInternal(double deadline_in_seconds) override; private: CompilerDispatcher* dispatcher_; DISALLOW_COPY_AND_ASSIGN(IdleTask); }; CompilerDispatcher::IdleTask::IdleTask(Isolate* isolate, CancelableTaskManager* task_manager, CompilerDispatcher* dispatcher) : CancelableIdleTask(isolate, task_manager), dispatcher_(dispatcher) {} CompilerDispatcher::IdleTask::~IdleTask() {} void CompilerDispatcher::IdleTask::RunInternal(double deadline_in_seconds) { dispatcher_->DoIdleWork(deadline_in_seconds); } CompilerDispatcher::CompilerDispatcher(Isolate* isolate, Platform* platform, size_t max_stack_size) : isolate_(isolate), platform_(platform), max_stack_size_(max_stack_size), trace_compiler_dispatcher_(FLAG_trace_compiler_dispatcher), tracer_(new CompilerDispatcherTracer(isolate_)), task_manager_(new CancelableTaskManager()), memory_pressure_level_(MemoryPressureLevel::kNone), abort_(false), idle_task_scheduled_(false), num_scheduled_background_tasks_(0), main_thread_blocking_on_job_(nullptr), block_for_testing_(false), semaphore_for_testing_(0) { if (trace_compiler_dispatcher_ && !IsEnabled()) { PrintF("CompilerDispatcher: dispatcher is disabled\n"); } } CompilerDispatcher::~CompilerDispatcher() { // To avoid crashing in unit tests due to unfished jobs. AbortAll(BlockingBehavior::kBlock); task_manager_->CancelAndWait(); } bool CompilerDispatcher::CanEnqueue(Handle
function) { if (!IsEnabled()) return false; DCHECK(FLAG_ignition); if (memory_pressure_level_.Value() != MemoryPressureLevel::kNone) { return false; } { base::LockGuard
lock(&mutex_); if (abort_) return false; } // We only handle functions (no eval / top-level code / wasm) that are // attached to a script. if (!function->script()->IsScript() || function->is_toplevel() || function->asm_function() || function->native()) { return false; } return true; } bool CompilerDispatcher::Enqueue(Handle
function) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompilerDispatcherEnqueue"); if (!CanEnqueue(function)) return false; if (IsEnqueued(function)) return true; if (trace_compiler_dispatcher_) { PrintF("CompilerDispatcher: enqueuing "); function->ShortPrint(); PrintF(" for parse and compile\n"); } std::unique_ptr
job(new CompilerDispatcherJob( isolate_, tracer_.get(), function, max_stack_size_)); std::pair
key(Script::cast(function->script())->id(), function->function_literal_id()); jobs_.insert(std::make_pair(key, std::move(job))); ScheduleIdleTaskIfNeeded(); return true; } bool CompilerDispatcher::EnqueueAndStep(Handle
function) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompilerDispatcherEnqueueAndStep"); if (IsEnqueued(function)) return true; if (!Enqueue(function)) return false; if (trace_compiler_dispatcher_) { PrintF("CompilerDispatcher: stepping "); function->ShortPrint(); PrintF("\n"); } JobMap::const_iterator job = GetJobFor(function); DoNextStepOnMainThread(isolate_, job->second.get(), ExceptionHandling::kSwallow); ConsiderJobForBackgroundProcessing(job->second.get()); return true; } bool CompilerDispatcher::Enqueue( Handle
登录后可以享受更多权益
您还没有登录,登录后您可以:
收藏Android系统代码
收藏喜欢的文章
多个平台共享账号
去登录
首次使用?从这里
注册