Commit 493c894a authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Compiler] Remove CompilerDispatcherJob and use BackgroundCompileTask directly

Simplify the logic in the CompilerDispatcher to use BackgroundCompileTasks
directly, rather than having a (now unecessary) CompilerDispatcherJob
abstraction. In the process, the CompilerDispatcherTracer is removed, and the
idle task logic is simplified finalize already compiled jobs until the
idle task deadline.

BUG=v8:8238, v8:8041

Change-Id: I1ea2366f959b6951de222d62fde80725b3cc70ff
Reviewed-on: https://chromium-review.googlesource.com/c/1260123
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56473}
parent e3a42cfd
...@@ -1669,16 +1669,10 @@ v8_source_set("v8_base") { ...@@ -1669,16 +1669,10 @@ v8_source_set("v8_base") {
"src/compilation-cache.h", "src/compilation-cache.h",
"src/compilation-statistics.cc", "src/compilation-statistics.cc",
"src/compilation-statistics.h", "src/compilation-statistics.h",
"src/compiler-dispatcher/compiler-dispatcher-job.cc",
"src/compiler-dispatcher/compiler-dispatcher-job.h",
"src/compiler-dispatcher/compiler-dispatcher-tracer.cc",
"src/compiler-dispatcher/compiler-dispatcher-tracer.h",
"src/compiler-dispatcher/compiler-dispatcher.cc", "src/compiler-dispatcher/compiler-dispatcher.cc",
"src/compiler-dispatcher/compiler-dispatcher.h", "src/compiler-dispatcher/compiler-dispatcher.h",
"src/compiler-dispatcher/optimizing-compile-dispatcher.cc", "src/compiler-dispatcher/optimizing-compile-dispatcher.cc",
"src/compiler-dispatcher/optimizing-compile-dispatcher.h", "src/compiler-dispatcher/optimizing-compile-dispatcher.h",
"src/compiler-dispatcher/unoptimized-compile-job.cc",
"src/compiler-dispatcher/unoptimized-compile-job.h",
"src/compiler.cc", "src/compiler.cc",
"src/compiler.h", "src/compiler.h",
"src/compiler/access-builder.cc", "src/compiler/access-builder.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-job.h"
#include "src/compiler-dispatcher/unoptimized-compile-job.h"
namespace v8 {
namespace internal {
const UnoptimizedCompileJob* CompilerDispatcherJob::AsUnoptimizedCompileJob()
const {
DCHECK_EQ(type(), Type::kUnoptimizedCompile);
return static_cast<const UnoptimizedCompileJob*>(this);
}
} // namespace internal
} // namespace v8
// 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.
#ifndef V8_COMPILER_DISPATCHER_COMPILER_DISPATCHER_JOB_H_
#define V8_COMPILER_DISPATCHER_COMPILER_DISPATCHER_JOB_H_
#include "src/contexts.h"
#include "src/handles.h"
namespace v8 {
namespace internal {
class SharedFunctionInfo;
class UnoptimizedCompileJob;
class V8_EXPORT_PRIVATE CompilerDispatcherJob {
public:
enum class Type { kUnoptimizedCompile };
enum class Status {
kInitial,
kReadyToFinalize,
kDone,
kFailed,
};
CompilerDispatcherJob(Type type) : type_(type), status_(Status::kInitial) {}
virtual ~CompilerDispatcherJob() = default;
Type type() const { return type_; }
// Returns the current status of the compile
Status status() const { return status_; }
// Returns true if this CompilerDispatcherJob has finished (either with a
// success or a failure).
bool IsFinished() const {
return status() == Status::kDone || status() == Status::kFailed;
}
// Returns true if this CompilerDispatcherJob has failed.
bool IsFailed() const { return status() == Status::kFailed; }
// Return true if the next step can be run on any thread.
bool NextStepCanRunOnAnyThread() const {
return status() == Status::kInitial;
}
// Casts to implementations.
const UnoptimizedCompileJob* AsUnoptimizedCompileJob() const;
// Transition from kInitial to kReadyToFinalize.
virtual void Compile(bool on_background_thread) = 0;
// Transition from kReadyToFinalize to kDone (or kFailed). Must only be
// invoked on the main thread.
virtual void FinalizeOnMainThread(Isolate* isolate,
Handle<SharedFunctionInfo> shared) = 0;
// Free all resources. Must only be invoked on the main thread.
virtual void ResetOnMainThread(Isolate* isolate) = 0;
// Estimate how long the next step will take using the tracer.
virtual double EstimateRuntimeOfNextStepInMs() const = 0;
protected:
void set_status(Status status) { status_ = status; }
private:
Type type_;
Status status_;
};
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_DISPATCHER_COMPILER_DISPATCHER_JOB_H_
// 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-tracer.h"
#include "src/isolate.h"
#include "src/utils.h"
namespace v8 {
namespace internal {
namespace {
double MonotonicallyIncreasingTimeInMs() {
return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
static_cast<double>(base::Time::kMillisecondsPerSecond);
}
const double kEstimatedRuntimeWithoutData = 1.0;
} // namespace
CompilerDispatcherTracer::Scope::Scope(CompilerDispatcherTracer* tracer,
ScopeID scope_id, size_t num)
: tracer_(tracer), scope_id_(scope_id), num_(num) {
start_time_ = MonotonicallyIncreasingTimeInMs();
}
CompilerDispatcherTracer::Scope::~Scope() {
double elapsed = MonotonicallyIncreasingTimeInMs() - start_time_;
switch (scope_id_) {
case ScopeID::kPrepare:
tracer_->RecordPrepare(elapsed);
break;
case ScopeID::kCompile:
tracer_->RecordCompile(elapsed, num_);
break;
case ScopeID::kFinalize:
tracer_->RecordFinalize(elapsed);
break;
}
}
// static
const char* CompilerDispatcherTracer::Scope::Name(ScopeID scope_id) {
switch (scope_id) {
case ScopeID::kPrepare:
return "V8.BackgroundCompile_Prepare";
case ScopeID::kCompile:
return "V8.BackgroundCompile_Compile";
case ScopeID::kFinalize:
return "V8.BackgroundCompile_Finalize";
}
UNREACHABLE();
}
CompilerDispatcherTracer::CompilerDispatcherTracer(Isolate* isolate)
: runtime_call_stats_(nullptr) {
// isolate might be nullptr during unittests.
if (isolate) {
runtime_call_stats_ = isolate->counters()->runtime_call_stats();
}
}
CompilerDispatcherTracer::~CompilerDispatcherTracer() = default;
void CompilerDispatcherTracer::RecordPrepare(double duration_ms) {
base::LockGuard<base::Mutex> lock(&mutex_);
prepare_events_.Push(duration_ms);
}
void CompilerDispatcherTracer::RecordCompile(double duration_ms,
size_t source_length) {
base::LockGuard<base::Mutex> lock(&mutex_);
compile_events_.Push(std::make_pair(source_length, duration_ms));
}
void CompilerDispatcherTracer::RecordFinalize(double duration_ms) {
base::LockGuard<base::Mutex> lock(&mutex_);
finalize_events_.Push(duration_ms);
}
double CompilerDispatcherTracer::EstimatePrepareInMs() const {
base::LockGuard<base::Mutex> lock(&mutex_);
return Average(prepare_events_);
}
double CompilerDispatcherTracer::EstimateCompileInMs(
size_t source_length) const {
base::LockGuard<base::Mutex> lock(&mutex_);
return Estimate(compile_events_, source_length);
}
double CompilerDispatcherTracer::EstimateFinalizeInMs() const {
base::LockGuard<base::Mutex> lock(&mutex_);
return Average(finalize_events_);
}
void CompilerDispatcherTracer::DumpStatistics() const {
PrintF(
"CompilerDispatcherTracer: "
"prepare=%.2lfms compiling=%.2lfms/kb finalize=%.2lfms\n",
EstimatePrepareInMs(), EstimateCompileInMs(1 * KB),
EstimateFinalizeInMs());
}
double CompilerDispatcherTracer::Average(
const base::RingBuffer<double>& buffer) {
if (buffer.Count() == 0) return 0.0;
double sum = buffer.Sum([](double a, double b) { return a + b; }, 0.0);
return sum / buffer.Count();
}
double CompilerDispatcherTracer::Estimate(
const base::RingBuffer<std::pair<size_t, double>>& buffer, size_t num) {
if (buffer.Count() == 0) return kEstimatedRuntimeWithoutData;
std::pair<size_t, double> sum = buffer.Sum(
[](std::pair<size_t, double> a, std::pair<size_t, double> b) {
return std::make_pair(a.first + b.first, a.second + b.second);
},
std::make_pair(0, 0.0));
return num * (sum.second / sum.first);
}
} // namespace internal
} // namespace v8
// 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.
#ifndef V8_COMPILER_DISPATCHER_COMPILER_DISPATCHER_TRACER_H_
#define V8_COMPILER_DISPATCHER_COMPILER_DISPATCHER_TRACER_H_
#include <utility>
#include "src/base/macros.h"
#include "src/base/platform/mutex.h"
#include "src/base/ring-buffer.h"
#include "src/counters.h"
#include "src/globals.h"
namespace v8 {
namespace internal {
class Isolate;
class RuntimeCallStats;
#define COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM(tracer, scope_id, num) \
CompilerDispatcherTracer::ScopeID tracer_scope_id( \
CompilerDispatcherTracer::ScopeID::scope_id); \
CompilerDispatcherTracer::Scope trace_scope(tracer, tracer_scope_id, num); \
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), \
CompilerDispatcherTracer::Scope::Name(tracer_scope_id))
#define COMPILER_DISPATCHER_TRACE_SCOPE(tracer, scope_id) \
COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM(tracer, scope_id, 0)
class V8_EXPORT_PRIVATE CompilerDispatcherTracer {
public:
enum class ScopeID { kPrepare, kCompile, kFinalize };
class Scope {
public:
Scope(CompilerDispatcherTracer* tracer, ScopeID scope_id, size_t num = 0);
~Scope();
static const char* Name(ScopeID scoped_id);
private:
CompilerDispatcherTracer* tracer_;
ScopeID scope_id_;
size_t num_;
double start_time_;
DISALLOW_COPY_AND_ASSIGN(Scope);
};
explicit CompilerDispatcherTracer(Isolate* isolate);
~CompilerDispatcherTracer();
void RecordPrepare(double duration_ms);
void RecordCompile(double duration_ms, size_t source_length);
void RecordFinalize(double duration_ms);
double EstimatePrepareInMs() const;
double EstimateCompileInMs(size_t source_length) const;
double EstimateFinalizeInMs() const;
void DumpStatistics() const;
private:
static double Average(const base::RingBuffer<double>& buffer);
static double Estimate(
const base::RingBuffer<std::pair<size_t, double>>& buffer, size_t num);
mutable base::Mutex mutex_;
base::RingBuffer<double> prepare_events_;
base::RingBuffer<std::pair<size_t, double>> compile_events_;
base::RingBuffer<double> finalize_events_;
RuntimeCallStats* runtime_call_stats_;
DISALLOW_COPY_AND_ASSIGN(CompilerDispatcherTracer);
};
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_DISPATCHER_COMPILER_DISPATCHER_TRACER_H_
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "src/base/platform/semaphore.h" #include "src/base/platform/semaphore.h"
#include "src/globals.h" #include "src/globals.h"
#include "src/identity-map.h" #include "src/identity-map.h"
#include "src/maybe-handles.h"
#include "testing/gtest/include/gtest/gtest_prod.h" // nogncheck #include "testing/gtest/include/gtest/gtest_prod.h" // nogncheck
namespace v8 { namespace v8 {
...@@ -30,8 +31,8 @@ namespace internal { ...@@ -30,8 +31,8 @@ namespace internal {
class AstRawString; class AstRawString;
class AstValueFactory; class AstValueFactory;
class BackgroundCompileTask;
class CancelableTaskManager; class CancelableTaskManager;
class CompilerDispatcherJob;
class UnoptimizedCompileJob; class UnoptimizedCompileJob;
class CompilerDispatcherTracer; class CompilerDispatcherTracer;
class DeferredHandles; class DeferredHandles;
...@@ -111,43 +112,51 @@ class V8_EXPORT_PRIVATE CompilerDispatcher { ...@@ -111,43 +112,51 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
bool is_isolate_locked); bool is_isolate_locked);
private: private:
FRIEND_TEST(CompilerDispatcherTest, EnqueueJob); FRIEND_TEST(CompilerDispatcherTest, IdleTaskNoIdleTime);
FRIEND_TEST(CompilerDispatcherTest, EnqueueWithoutSFI);
FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStep);
FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStepWithoutSFI);
FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStepTwice);
FRIEND_TEST(CompilerDispatcherTest, EnqueueParsed);
FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStepParsed);
FRIEND_TEST(CompilerDispatcherTest, IdleTaskSmallIdleTime); FRIEND_TEST(CompilerDispatcherTest, IdleTaskSmallIdleTime);
FRIEND_TEST(CompilerDispatcherTest, CompileOnBackgroundThread);
FRIEND_TEST(CompilerDispatcherTest, FinishNowWithWorkerTask); FRIEND_TEST(CompilerDispatcherTest, FinishNowWithWorkerTask);
FRIEND_TEST(CompilerDispatcherTest, AsyncAbortAllPendingWorkerTask); FRIEND_TEST(CompilerDispatcherTest, AsyncAbortAllPendingWorkerTask);
FRIEND_TEST(CompilerDispatcherTest, AsyncAbortAllRunningWorkerTask); FRIEND_TEST(CompilerDispatcherTest, AsyncAbortAllRunningWorkerTask);
FRIEND_TEST(CompilerDispatcherTest, FinishNowDuringAbortAll); FRIEND_TEST(CompilerDispatcherTest, FinishNowDuringAbortAll);
FRIEND_TEST(CompilerDispatcherTest, CompileMultipleOnBackgroundThread); FRIEND_TEST(CompilerDispatcherTest, CompileMultipleOnBackgroundThread);
typedef std::map<JobId, std::unique_ptr<CompilerDispatcherJob>> JobMap;
typedef std::map<JobId, Handle<SharedFunctionInfo>> JobIdToSharedMap;
typedef IdentityMap<JobId, FreeStoreAllocationPolicy> SharedToJobIdMap;
class AbortTask; class AbortTask;
class WorkerTask; class WorkerTask;
class IdleTask; class IdleTask;
struct Job {
explicit Job(BackgroundCompileTask* task_arg);
~Job();
bool IsReadyToFinalize(const base::LockGuard<base::Mutex>&) {
return has_run && !function.is_null();
}
bool IsReadyToFinalize(base::Mutex* mutex) {
base::LockGuard<base::Mutex> lock(mutex);
return IsReadyToFinalize(lock);
}
std::unique_ptr<BackgroundCompileTask> task;
MaybeHandle<SharedFunctionInfo> function;
bool has_run;
};
typedef std::map<JobId, std::unique_ptr<Job>> JobMap;
typedef IdentityMap<JobId, FreeStoreAllocationPolicy> SharedToJobIdMap;
bool CanEnqueue(); bool CanEnqueue();
void WaitForJobIfRunningOnBackground(CompilerDispatcherJob* job); void WaitForJobIfRunningOnBackground(Job* job);
void AbortInactiveJobs(); void AbortInactiveJobs();
JobMap::const_iterator GetJobFor(Handle<SharedFunctionInfo> shared) const; JobMap::const_iterator GetJobFor(Handle<SharedFunctionInfo> shared) const;
void ConsiderJobForBackgroundProcessing(CompilerDispatcherJob* job);
void ScheduleMoreWorkerTasksIfNeeded(); void ScheduleMoreWorkerTasksIfNeeded();
void ScheduleIdleTaskFromAnyThread(); void ScheduleIdleTaskFromAnyThread();
void ScheduleIdleTaskIfNeeded(); void ScheduleIdleTaskIfNeeded();
void ScheduleAbortTask(); void ScheduleAbortTask();
void DoBackgroundWork(); void DoBackgroundWork();
void DoIdleWork(double deadline_in_seconds); void DoIdleWork(double deadline_in_seconds);
// Returns job if not removed otherwise iterator following the removed job.
JobMap::const_iterator RemoveIfFinished(JobMap::const_iterator job);
// Returns iterator to the inserted job. // Returns iterator to the inserted job.
JobMap::const_iterator InsertJob(std::unique_ptr<CompilerDispatcherJob> job); JobMap::const_iterator InsertJob(std::unique_ptr<Job> job);
// Returns iterator following the removed job. // Returns iterator following the removed job.
JobMap::const_iterator RemoveJob(JobMap::const_iterator job); JobMap::const_iterator RemoveJob(JobMap::const_iterator job);
...@@ -162,8 +171,6 @@ class V8_EXPORT_PRIVATE CompilerDispatcher { ...@@ -162,8 +171,6 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
// Copy of FLAG_trace_compiler_dispatcher to allow for access from any thread. // Copy of FLAG_trace_compiler_dispatcher to allow for access from any thread.
bool trace_compiler_dispatcher_; bool trace_compiler_dispatcher_;
std::unique_ptr<CompilerDispatcherTracer> tracer_;
std::unique_ptr<CancelableTaskManager> task_manager_; std::unique_ptr<CancelableTaskManager> task_manager_;
// Id for next job to be added // Id for next job to be added
...@@ -172,9 +179,6 @@ class V8_EXPORT_PRIVATE CompilerDispatcher { ...@@ -172,9 +179,6 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
// Mapping from job_id to job. // Mapping from job_id to job.
JobMap jobs_; JobMap jobs_;
// Mapping from job_id to SharedFunctionInfo.
JobIdToSharedMap job_id_to_shared_;
// Mapping from SharedFunctionInfo to the corresponding unoptimized // Mapping from SharedFunctionInfo to the corresponding unoptimized
// compilation's JobId; // compilation's JobId;
SharedToJobIdMap shared_to_unoptimized_job_id_; SharedToJobIdMap shared_to_unoptimized_job_id_;
...@@ -193,16 +197,15 @@ class V8_EXPORT_PRIVATE CompilerDispatcher { ...@@ -193,16 +197,15 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
// Number of scheduled or running WorkerTask objects. // Number of scheduled or running WorkerTask objects.
int num_worker_tasks_; int num_worker_tasks_;
// The set of CompilerDispatcherJobs that can be advanced on any thread. // The set of jobs that can be run on a background thread.
std::unordered_set<CompilerDispatcherJob*> pending_background_jobs_; std::unordered_set<Job*> pending_background_jobs_;
// The set of CompilerDispatcherJobs currently processed on background // The set of jobs currently being run on background threads.
// threads. std::unordered_set<Job*> running_background_jobs_;
std::unordered_set<CompilerDispatcherJob*> running_background_jobs_;
// If not nullptr, then the main thread waits for the task processing // If not nullptr, then the main thread waits for the task processing
// this job, and blocks on the ConditionVariable main_thread_blocking_signal_. // this job, and blocks on the ConditionVariable main_thread_blocking_signal_.
CompilerDispatcherJob* main_thread_blocking_on_job_; Job* main_thread_blocking_on_job_;
base::ConditionVariable main_thread_blocking_signal_; base::ConditionVariable main_thread_blocking_signal_;
// Test support. // Test support.
......
// 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/unoptimized-compile-job.h"
#include "src/assert-scope.h"
#include "src/compiler-dispatcher/compiler-dispatcher-tracer.h"
#include "src/compiler.h"
#include "src/flags.h"
#include "src/interpreter/interpreter.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/parser.h"
#include "src/parsing/scanner-character-streams.h"
#include "src/unicode-cache.h"
#include "src/unoptimized-compilation-info.h"
#include "src/utils.h"
namespace v8 {
namespace internal {
UnoptimizedCompileJob::UnoptimizedCompileJob(
CompilerDispatcherTracer* tracer, AccountingAllocator* allocator,
const ParseInfo* outer_parse_info, const AstRawString* function_name,
const FunctionLiteral* function_literal,
WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
TimedHistogram* timer, size_t max_stack_size)
: CompilerDispatcherJob(Type::kUnoptimizedCompile),
tracer_(tracer),
task_(new BackgroundCompileTask(allocator, outer_parse_info,
function_name, function_literal,
worker_thread_runtime_stats, timer,
static_cast<int>(max_stack_size))) {}
UnoptimizedCompileJob::~UnoptimizedCompileJob() {
DCHECK(status() == Status::kInitial || status() == Status::kDone);
}
void UnoptimizedCompileJob::Compile(bool on_background_thread) {
DCHECK_EQ(status(), Status::kInitial);
COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM(
tracer_, kCompile,
task_->info()->end_position() - task_->info()->start_position());
task_->Run();
set_status(Status::kReadyToFinalize);
}
void UnoptimizedCompileJob::FinalizeOnMainThread(
Isolate* isolate, Handle<SharedFunctionInfo> shared) {
DCHECK_EQ(ThreadId::Current().ToInteger(), isolate->thread_id().ToInteger());
DCHECK_EQ(status(), Status::kReadyToFinalize);
COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalize);
bool succeeded = Compiler::FinalizeBackgroundCompileTask(
task_.get(), shared, isolate, Compiler::KEEP_EXCEPTION);
ResetDataOnMainThread(isolate);
set_status(succeeded ? Status::kDone : Status::kFailed);
}
void UnoptimizedCompileJob::ResetDataOnMainThread(Isolate* isolate) {
DCHECK_EQ(ThreadId::Current().ToInteger(), isolate->thread_id().ToInteger());
task_.reset();
}
void UnoptimizedCompileJob::ResetOnMainThread(Isolate* isolate) {
ResetDataOnMainThread(isolate);
set_status(Status::kInitial);
}
double UnoptimizedCompileJob::EstimateRuntimeOfNextStepInMs() const {
switch (status()) {
case Status::kInitial:
return tracer_->EstimateCompileInMs(task_->info()->end_position() -
task_->info()->start_position());
case Status::kReadyToFinalize:
// TODO(rmcilroy): Pass size of bytecode to tracer to get better estimate.
return tracer_->EstimateFinalizeInMs();
case Status::kFailed:
case Status::kDone:
return 0.0;
}
UNREACHABLE();
}
} // namespace internal
} // namespace v8
// 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.
#ifndef V8_COMPILER_DISPATCHER_UNOPTIMIZED_COMPILE_JOB_H_
#define V8_COMPILER_DISPATCHER_UNOPTIMIZED_COMPILE_JOB_H_
#include <memory>
#include "include/v8.h"
#include "src/base/macros.h"
#include "src/compiler-dispatcher/compiler-dispatcher-job.h"
#include "src/globals.h"
namespace v8 {
namespace internal {
class AccountingAllocator;
class AstRawString;
class AstValueFactory;
class AstStringConstants;
class BackgroundCompileTask;
class CompilerDispatcherTracer;
class DeferredHandles;
class FunctionLiteral;
class Isolate;
class ParseInfo;
class Parser;
class SharedFunctionInfo;
class String;
class TimedHistogram;
class UnicodeCache;
class UnoptimizedCompilationJob;
class WorkerThreadRuntimeCallStats;
// TODO(rmcilroy): Remove this class entirely and just have CompilerDispatcher
// manage BackgroundCompileTasks.
class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
public:
// Creates a UnoptimizedCompileJob in the initial state.
UnoptimizedCompileJob(
CompilerDispatcherTracer* tracer, AccountingAllocator* allocator,
const ParseInfo* outer_parse_info, const AstRawString* function_name,
const FunctionLiteral* function_literal,
WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
TimedHistogram* timer, size_t max_stack_size);
~UnoptimizedCompileJob() override;
// CompilerDispatcherJob implementation.
void Compile(bool on_background_thread) override;
void FinalizeOnMainThread(Isolate* isolate,
Handle<SharedFunctionInfo> shared) override;
void ResetOnMainThread(Isolate* isolate) override;
double EstimateRuntimeOfNextStepInMs() const override;
private:
friend class CompilerDispatcherTest;
friend class UnoptimizedCompileJobTest;
void ResetDataOnMainThread(Isolate* isolate);
CompilerDispatcherTracer* tracer_;
std::unique_ptr<BackgroundCompileTask> task_;
DISALLOW_COPY_AND_ASSIGN(UnoptimizedCompileJob);
};
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_DISPATCHER_UNOPTIMIZED_COMPILE_JOB_H_
...@@ -945,6 +945,8 @@ BackgroundCompileTask::BackgroundCompileTask( ...@@ -945,6 +945,8 @@ BackgroundCompileTask::BackgroundCompileTask(
} }
} }
BackgroundCompileTask::~BackgroundCompileTask() = default;
namespace { namespace {
// A scope object that ensures a parse info's runtime call stats, stack limit // A scope object that ensures a parse info's runtime call stats, stack limit
......
...@@ -316,13 +316,14 @@ class OptimizedCompilationJob : public CompilationJob { ...@@ -316,13 +316,14 @@ class OptimizedCompilationJob : public CompilationJob {
const char* compiler_name_; const char* compiler_name_;
}; };
class BackgroundCompileTask { class V8_EXPORT_PRIVATE BackgroundCompileTask {
public: public:
// Creates a new task that when run will parse and compile the streamed // Creates a new task that when run will parse and compile the streamed
// script associated with |data| and can be finalized with // script associated with |data| and can be finalized with
// Compiler::GetSharedFunctionInfoForStreamedScript. // Compiler::GetSharedFunctionInfoForStreamedScript.
// Note: does not take ownership of |data|. // Note: does not take ownership of |data|.
BackgroundCompileTask(ScriptStreamingData* data, Isolate* isolate); BackgroundCompileTask(ScriptStreamingData* data, Isolate* isolate);
~BackgroundCompileTask();
// Creates a new task that when run will parse and compile the // Creates a new task that when run will parse and compile the
// |function_literal| and can be finalized with // |function_literal| and can be finalized with
......
...@@ -55,6 +55,7 @@ v8_source_set("unittests_sources") { ...@@ -55,6 +55,7 @@ v8_source_set("unittests_sources") {
"asmjs/asm-scanner-unittest.cc", "asmjs/asm-scanner-unittest.cc",
"asmjs/asm-types-unittest.cc", "asmjs/asm-types-unittest.cc",
"asmjs/switch-logic-unittest.cc", "asmjs/switch-logic-unittest.cc",
"background-compile-task-unittest.cc",
"base/address-region-unittest.cc", "base/address-region-unittest.cc",
"base/atomic-utils-unittest.cc", "base/atomic-utils-unittest.cc",
"base/bits-unittest.cc", "base/bits-unittest.cc",
...@@ -83,10 +84,8 @@ v8_source_set("unittests_sources") { ...@@ -83,10 +84,8 @@ v8_source_set("unittests_sources") {
"char-predicates-unittest.cc", "char-predicates-unittest.cc",
"code-stub-assembler-unittest.cc", "code-stub-assembler-unittest.cc",
"code-stub-assembler-unittest.h", "code-stub-assembler-unittest.h",
"compiler-dispatcher/compiler-dispatcher-tracer-unittest.cc",
"compiler-dispatcher/compiler-dispatcher-unittest.cc", "compiler-dispatcher/compiler-dispatcher-unittest.cc",
"compiler-dispatcher/optimizing-compile-dispatcher-unittest.cc", "compiler-dispatcher/optimizing-compile-dispatcher-unittest.cc",
"compiler-dispatcher/unoptimized-compile-job-unittest.cc",
"compiler/branch-elimination-unittest.cc", "compiler/branch-elimination-unittest.cc",
"compiler/bytecode-analysis-unittest.cc", "compiler/bytecode-analysis-unittest.cc",
"compiler/checkpoint-elimination-unittest.cc", "compiler/checkpoint-elimination-unittest.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-tracer.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
TEST(CompilerDispatcherTracerTest, EstimateWithoutSamples) {
CompilerDispatcherTracer tracer(nullptr);
EXPECT_EQ(0.0, tracer.EstimatePrepareInMs());
EXPECT_EQ(1.0, tracer.EstimateCompileInMs(1));
EXPECT_EQ(1.0, tracer.EstimateCompileInMs(42));
EXPECT_EQ(0.0, tracer.EstimateFinalizeInMs());
}
TEST(CompilerDispatcherTracerTest, Average) {
CompilerDispatcherTracer tracer(nullptr);
EXPECT_EQ(0.0, tracer.EstimatePrepareInMs());
tracer.RecordPrepare(1.0);
tracer.RecordPrepare(2.0);
tracer.RecordPrepare(3.0);
EXPECT_EQ((1.0 + 2.0 + 3.0) / 3, tracer.EstimatePrepareInMs());
}
TEST(CompilerDispatcherTracerTest, SizeBasedAverage) {
CompilerDispatcherTracer tracer(nullptr);
EXPECT_EQ(1.0, tracer.EstimateCompileInMs(100));
// All three samples parse 100 units/ms.
tracer.RecordCompile(1.0, 100);
tracer.RecordCompile(2.0, 200);
tracer.RecordCompile(3.0, 300);
EXPECT_EQ(1.0, tracer.EstimateCompileInMs(100));
EXPECT_EQ(5.0, tracer.EstimateCompileInMs(500));
}
} // namespace internal
} // namespace v8
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <memory> #include <memory>
#include "include/v8.h" #include "include/v8.h"
#include "src/compiler-dispatcher/compiler-dispatcher-job.h"
#include "src/parsing/parse-info.h" #include "src/parsing/parse-info.h"
namespace v8 { namespace v8 {
......
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