summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler-dispatcher
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2017-05-02 10:50:00 +0200
committerMichaël Zasso <targos@protonmail.com>2017-05-06 20:02:35 +0200
commit60d1aac8d225e844e68ae48e8f3d58802e635fbe (patch)
tree922f347dd054db18d88666fad7181e5a777f4022 /deps/v8/src/compiler-dispatcher
parent73d9c0f903ae371cd5011af64c3a6f69a1bda978 (diff)
downloadnode-new-60d1aac8d225e844e68ae48e8f3d58802e635fbe.tar.gz
deps: update V8 to 5.8.283.38
PR-URL: https://github.com/nodejs/node/pull/12784 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com>
Diffstat (limited to 'deps/v8/src/compiler-dispatcher')
-rw-r--r--deps/v8/src/compiler-dispatcher/compiler-dispatcher-job.cc147
-rw-r--r--deps/v8/src/compiler-dispatcher/compiler-dispatcher-job.h35
-rw-r--r--deps/v8/src/compiler-dispatcher/compiler-dispatcher-tracer.cc24
-rw-r--r--deps/v8/src/compiler-dispatcher/compiler-dispatcher-tracer.h4
-rw-r--r--deps/v8/src/compiler-dispatcher/compiler-dispatcher.cc95
-rw-r--r--deps/v8/src/compiler-dispatcher/compiler-dispatcher.h32
-rw-r--r--deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc30
-rw-r--r--deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h5
8 files changed, 288 insertions, 84 deletions
diff --git a/deps/v8/src/compiler-dispatcher/compiler-dispatcher-job.cc b/deps/v8/src/compiler-dispatcher/compiler-dispatcher-job.cc
index fdb975a5e4..56d166f578 100644
--- a/deps/v8/src/compiler-dispatcher/compiler-dispatcher-job.cc
+++ b/deps/v8/src/compiler-dispatcher/compiler-dispatcher-job.cc
@@ -17,7 +17,6 @@
#include "src/parsing/scanner-character-streams.h"
#include "src/unicode-cache.h"
#include "src/utils.h"
-#include "src/zone/zone.h"
namespace v8 {
namespace internal {
@@ -66,20 +65,54 @@ CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate,
CompilerDispatcherTracer* tracer,
Handle<SharedFunctionInfo> shared,
size_t max_stack_size)
- : isolate_(isolate),
+ : status_(CompileJobStatus::kInitial),
+ isolate_(isolate),
tracer_(tracer),
+ context_(Handle<Context>::cast(
+ isolate_->global_handles()->Create(isolate->context()))),
shared_(Handle<SharedFunctionInfo>::cast(
isolate_->global_handles()->Create(*shared))),
max_stack_size_(max_stack_size),
trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
+ DCHECK(!shared_->is_toplevel());
HandleScope scope(isolate_);
- DCHECK(!shared_->outer_scope_info()->IsTheHole(isolate_));
Handle<Script> script(Script::cast(shared_->script()), isolate_);
Handle<String> source(String::cast(script->source()), isolate_);
if (trace_compiler_dispatcher_jobs_) {
PrintF("CompilerDispatcherJob[%p] created for ", static_cast<void*>(this));
shared_->ShortPrint();
- PrintF("\n");
+ PrintF(" in initial state.\n");
+ }
+}
+
+CompilerDispatcherJob::CompilerDispatcherJob(
+ Isolate* isolate, CompilerDispatcherTracer* tracer, Handle<Script> script,
+ Handle<SharedFunctionInfo> shared, FunctionLiteral* literal,
+ std::shared_ptr<Zone> parse_zone,
+ std::shared_ptr<DeferredHandles> parse_handles,
+ std::shared_ptr<DeferredHandles> compile_handles, size_t max_stack_size)
+ : status_(CompileJobStatus::kAnalyzed),
+ isolate_(isolate),
+ tracer_(tracer),
+ context_(Handle<Context>::cast(
+ isolate_->global_handles()->Create(isolate->context()))),
+ shared_(Handle<SharedFunctionInfo>::cast(
+ isolate_->global_handles()->Create(*shared))),
+ max_stack_size_(max_stack_size),
+ parse_info_(new ParseInfo(shared_)),
+ parse_zone_(parse_zone),
+ compile_info_(new CompilationInfo(parse_info_->zone(), parse_info_.get(),
+ Handle<JSFunction>::null())),
+ trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
+ parse_info_->set_literal(literal);
+ parse_info_->set_script(script);
+ parse_info_->set_deferred_handles(parse_handles);
+ compile_info_->set_deferred_handles(compile_handles);
+
+ if (trace_compiler_dispatcher_jobs_) {
+ PrintF("CompilerDispatcherJob[%p] created for ", static_cast<void*>(this));
+ shared_->ShortPrint();
+ PrintF(" in Analyzed state.\n");
}
}
@@ -88,6 +121,7 @@ CompilerDispatcherJob::~CompilerDispatcherJob() {
DCHECK(status_ == CompileJobStatus::kInitial ||
status_ == CompileJobStatus::kDone);
i::GlobalHandles::Destroy(Handle<Object>::cast(shared_).location());
+ i::GlobalHandles::Destroy(Handle<Object>::cast(context_).location());
}
bool CompilerDispatcherJob::IsAssociatedWith(
@@ -105,11 +139,11 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() {
}
HandleScope scope(isolate_);
unicode_cache_.reset(new UnicodeCache());
- zone_.reset(new Zone(isolate_->allocator(), ZONE_NAME));
Handle<Script> script(Script::cast(shared_->script()), isolate_);
DCHECK(script->type() != Script::TYPE_NATIVE);
Handle<String> source(String::cast(script->source()), isolate_);
+ parse_info_.reset(new ParseInfo(isolate_->allocator()));
if (source->IsExternalTwoByteString() || source->IsExternalOneByteString()) {
character_stream_.reset(ScannerStream::For(
source, shared_->start_position(), shared_->end_position()));
@@ -140,7 +174,7 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() {
offset = shared_->start_position();
int byte_len = length * (source->IsOneByteRepresentation() ? 1 : 2);
- data = zone_->New(byte_len);
+ data = parse_info_->zone()->New(byte_len);
DisallowHeapAllocation no_allocation;
String::FlatContent content = source->GetFlatContent();
@@ -178,7 +212,6 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() {
ScannerStream::For(wrapper_, shared_->start_position() - offset,
shared_->end_position() - offset));
}
- parse_info_.reset(new ParseInfo(zone_.get()));
parse_info_->set_isolate(isolate_);
parse_info_->set_character_stream(character_stream_.get());
parse_info_->set_hash_seed(isolate_->heap()->HashSeed());
@@ -191,12 +224,12 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() {
parse_info_->set_function_literal_id(shared_->function_literal_id());
parser_.reset(new Parser(parse_info_.get()));
- Handle<ScopeInfo> outer_scope_info(
- handle(ScopeInfo::cast(shared_->outer_scope_info())));
- parser_->DeserializeScopeChain(parse_info_.get(),
- outer_scope_info->length() > 0
- ? MaybeHandle<ScopeInfo>(outer_scope_info)
- : MaybeHandle<ScopeInfo>());
+ MaybeHandle<ScopeInfo> outer_scope_info;
+ if (!shared_->outer_scope_info()->IsTheHole(isolate_) &&
+ ScopeInfo::cast(shared_->outer_scope_info())->length() > 0) {
+ outer_scope_info = handle(ScopeInfo::cast(shared_->outer_scope_info()));
+ }
+ parser_->DeserializeScopeChain(parse_info_.get(), outer_scope_info);
Handle<String> name(String::cast(shared_->name()));
parse_info_->set_function_name(
@@ -249,27 +282,30 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
wrapper_ = Handle<String>::null();
}
+ Handle<Script> script(Script::cast(shared_->script()), isolate_);
+ parse_info_->set_script(script);
if (parse_info_->literal() == nullptr) {
+ parser_->ReportErrors(isolate_, script);
status_ = CompileJobStatus::kFailed;
} else {
- status_ = CompileJobStatus::kReadyToAnalyse;
+ status_ = CompileJobStatus::kReadyToAnalyze;
}
+ parser_->UpdateStatistics(isolate_, script);
DeferredHandleScope scope(isolate_);
{
- Handle<Script> script(Script::cast(shared_->script()), isolate_);
+ parse_info_->ReopenHandlesInNewHandleScope();
- parse_info_->set_script(script);
- Handle<ScopeInfo> outer_scope_info(
- handle(ScopeInfo::cast(shared_->outer_scope_info())));
- if (outer_scope_info->length() > 0) {
+ if (!shared_->outer_scope_info()->IsTheHole(isolate_) &&
+ ScopeInfo::cast(shared_->outer_scope_info())->length() > 0) {
+ Handle<ScopeInfo> outer_scope_info(
+ handle(ScopeInfo::cast(shared_->outer_scope_info())));
parse_info_->set_outer_scope_info(outer_scope_info);
}
parse_info_->set_shared_info(shared_);
- // Do the parsing tasks which need to be done on the main thread. This
- // will also handle parse errors.
- parser_->Internalize(isolate_, script, parse_info_->literal() == nullptr);
+ // Internalize ast values on the main thread.
+ parse_info_->ast_value_factory()->Internalize(isolate_);
parser_->HandleSourceURLComments(isolate_, script);
parse_info_->set_character_stream(nullptr);
@@ -278,30 +314,43 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
unicode_cache_.reset();
character_stream_.reset();
}
- handles_from_parsing_.reset(scope.Detach());
+ parse_info_->set_deferred_handles(scope.Detach());
return status_ != CompileJobStatus::kFailed;
}
-bool CompilerDispatcherJob::PrepareToCompileOnMainThread() {
+bool CompilerDispatcherJob::AnalyzeOnMainThread() {
DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
- DCHECK(status() == CompileJobStatus::kReadyToAnalyse);
- COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToCompile);
+ DCHECK(status() == CompileJobStatus::kReadyToAnalyze);
+ COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kAnalyze);
if (trace_compiler_dispatcher_jobs_) {
- PrintF("CompilerDispatcherJob[%p]: Preparing to compile\n",
- static_cast<void*>(this));
+ PrintF("CompilerDispatcherJob[%p]: Analyzing\n", static_cast<void*>(this));
}
- compile_info_.reset(
- new CompilationInfo(parse_info_.get(), Handle<JSFunction>::null()));
+ compile_info_.reset(new CompilationInfo(
+ parse_info_->zone(), parse_info_.get(), Handle<JSFunction>::null()));
DeferredHandleScope scope(isolate_);
- if (Compiler::Analyze(parse_info_.get())) {
- compile_job_.reset(
- Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get()));
+ {
+ if (Compiler::Analyze(parse_info_.get())) {
+ status_ = CompileJobStatus::kAnalyzed;
+ } else {
+ status_ = CompileJobStatus::kFailed;
+ if (!isolate_->has_pending_exception()) isolate_->StackOverflow();
+ }
}
compile_info_->set_deferred_handles(scope.Detach());
+ return status_ != CompileJobStatus::kFailed;
+}
+
+bool CompilerDispatcherJob::PrepareToCompileOnMainThread() {
+ DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
+ DCHECK(status() == CompileJobStatus::kAnalyzed);
+ COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToCompile);
+
+ compile_job_.reset(
+ Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get()));
if (!compile_job_.get()) {
if (!isolate_->has_pending_exception()) isolate_->StackOverflow();
status_ = CompileJobStatus::kFailed;
@@ -344,18 +393,20 @@ bool CompilerDispatcherJob::FinalizeCompilingOnMainThread() {
static_cast<void*>(this));
}
- if (compile_job_->state() == CompilationJob::State::kFailed ||
- !Compiler::FinalizeCompilationJob(compile_job_.release())) {
- if (!isolate_->has_pending_exception()) isolate_->StackOverflow();
- status_ = CompileJobStatus::kFailed;
- return false;
+ {
+ HandleScope scope(isolate_);
+ if (compile_job_->state() == CompilationJob::State::kFailed ||
+ !Compiler::FinalizeCompilationJob(compile_job_.release())) {
+ if (!isolate_->has_pending_exception()) isolate_->StackOverflow();
+ status_ = CompileJobStatus::kFailed;
+ return false;
+ }
}
- zone_.reset();
- parse_info_.reset();
- compile_info_.reset();
compile_job_.reset();
- handles_from_parsing_.reset();
+ compile_info_.reset();
+ parse_zone_.reset();
+ parse_info_.reset();
status_ = CompileJobStatus::kDone;
return true;
@@ -368,14 +419,13 @@ void CompilerDispatcherJob::ResetOnMainThread() {
PrintF("CompilerDispatcherJob[%p]: Resetting\n", static_cast<void*>(this));
}
+ compile_job_.reset();
+ compile_info_.reset();
+ parse_zone_.reset();
parser_.reset();
unicode_cache_.reset();
character_stream_.reset();
parse_info_.reset();
- handles_from_parsing_.reset();
- compile_info_.reset();
- compile_job_.reset();
- zone_.reset();
if (!source_.is_null()) {
i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location());
@@ -401,7 +451,10 @@ double CompilerDispatcherJob::EstimateRuntimeOfNextStepInMs() const {
case CompileJobStatus::kParsed:
return tracer_->EstimateFinalizeParsingInMs();
- case CompileJobStatus::kReadyToAnalyse:
+ case CompileJobStatus::kReadyToAnalyze:
+ return tracer_->EstimateAnalyzeInMs();
+
+ case CompileJobStatus::kAnalyzed:
return tracer_->EstimatePrepareToCompileInMs();
case CompileJobStatus::kReadyToCompile:
diff --git a/deps/v8/src/compiler-dispatcher/compiler-dispatcher-job.h b/deps/v8/src/compiler-dispatcher/compiler-dispatcher-job.h
index e0a2677f8e..aea484729e 100644
--- a/deps/v8/src/compiler-dispatcher/compiler-dispatcher-job.h
+++ b/deps/v8/src/compiler-dispatcher/compiler-dispatcher-job.h
@@ -16,9 +16,12 @@
namespace v8 {
namespace internal {
+class AstValueFactory;
class CompilerDispatcherTracer;
class CompilationInfo;
class CompilationJob;
+class DeferredHandles;
+class FunctionLiteral;
class Isolate;
class ParseInfo;
class Parser;
@@ -26,13 +29,13 @@ class SharedFunctionInfo;
class String;
class UnicodeCache;
class Utf16CharacterStream;
-class Zone;
enum class CompileJobStatus {
kInitial,
kReadyToParse,
kParsed,
- kReadyToAnalyse,
+ kReadyToAnalyze,
+ kAnalyzed,
kReadyToCompile,
kCompiled,
kFailed,
@@ -41,13 +44,25 @@ enum class CompileJobStatus {
class V8_EXPORT_PRIVATE CompilerDispatcherJob {
public:
+ // Creates a CompilerDispatcherJob in the initial state.
CompilerDispatcherJob(Isolate* isolate, CompilerDispatcherTracer* tracer,
Handle<SharedFunctionInfo> shared,
size_t max_stack_size);
+ // Creates a CompilerDispatcherJob in the analyzed state.
+ CompilerDispatcherJob(Isolate* isolate, CompilerDispatcherTracer* tracer,
+ Handle<Script> script,
+ Handle<SharedFunctionInfo> shared,
+ FunctionLiteral* literal,
+ std::shared_ptr<Zone> parse_zone,
+ std::shared_ptr<DeferredHandles> parse_handles,
+ std::shared_ptr<DeferredHandles> compile_handles,
+ size_t max_stack_size);
~CompilerDispatcherJob();
CompileJobStatus status() const { return status_; }
+ Context* context() { return *context_; }
+
// Returns true if this CompilerDispatcherJob was created for the given
// function.
bool IsAssociatedWith(Handle<SharedFunctionInfo> shared) const;
@@ -58,11 +73,15 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob {
// Transition from kReadyToParse to kParsed.
void Parse();
- // Transition from kParsed to kReadyToAnalyse (or kFailed). Returns false
+ // Transition from kParsed to kReadyToAnalyze (or kFailed). Returns false
// when transitioning to kFailed. In that case, an exception is pending.
bool FinalizeParsingOnMainThread();
- // Transition from kReadyToAnalyse to kReadyToCompile (or kFailed). Returns
+ // Transition from kReadyToAnalyze to kAnalyzed (or kFailed). Returns
+ // false when transitioning to kFailed. In that case, an exception is pending.
+ bool AnalyzeOnMainThread();
+
+ // Transition from kAnalyzed to kReadyToCompile (or kFailed). Returns
// false when transitioning to kFailed. In that case, an exception is pending.
bool PrepareToCompileOnMainThread();
@@ -86,9 +105,10 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob {
private:
FRIEND_TEST(CompilerDispatcherJobTest, ScopeChain);
- CompileJobStatus status_ = CompileJobStatus::kInitial;
+ CompileJobStatus status_;
Isolate* isolate_;
CompilerDispatcherTracer* tracer_;
+ Handle<Context> context_; // Global handle.
Handle<SharedFunctionInfo> shared_; // Global handle.
Handle<String> source_; // Global handle.
Handle<String> wrapper_; // Global handle.
@@ -97,11 +117,12 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob {
// Members required for parsing.
std::unique_ptr<UnicodeCache> unicode_cache_;
- std::unique_ptr<Zone> zone_;
std::unique_ptr<Utf16CharacterStream> character_stream_;
std::unique_ptr<ParseInfo> parse_info_;
std::unique_ptr<Parser> parser_;
- std::unique_ptr<DeferredHandles> handles_from_parsing_;
+
+ // Members required for compiling a parsed function.
+ std::shared_ptr<Zone> parse_zone_;
// Members required for compiling.
std::unique_ptr<CompilationInfo> compile_info_;
diff --git a/deps/v8/src/compiler-dispatcher/compiler-dispatcher-tracer.cc b/deps/v8/src/compiler-dispatcher/compiler-dispatcher-tracer.cc
index 0703e016e9..d98209b147 100644
--- a/deps/v8/src/compiler-dispatcher/compiler-dispatcher-tracer.cc
+++ b/deps/v8/src/compiler-dispatcher/compiler-dispatcher-tracer.cc
@@ -39,6 +39,9 @@ CompilerDispatcherTracer::Scope::~Scope() {
case ScopeID::kFinalizeParsing:
tracer_->RecordFinalizeParsing(elapsed);
break;
+ case ScopeID::kAnalyze:
+ tracer_->RecordAnalyze(elapsed);
+ break;
case ScopeID::kPrepareToCompile:
tracer_->RecordPrepareToCompile(elapsed);
break;
@@ -60,6 +63,8 @@ const char* CompilerDispatcherTracer::Scope::Name(ScopeID scope_id) {
return "V8.BackgroundCompile_Parse";
case ScopeID::kFinalizeParsing:
return "V8.BackgroundCompile_FinalizeParsing";
+ case ScopeID::kAnalyze:
+ return "V8.BackgroundCompile_Analyze";
case ScopeID::kPrepareToCompile:
return "V8.BackgroundCompile_PrepareToCompile";
case ScopeID::kCompile:
@@ -97,6 +102,11 @@ void CompilerDispatcherTracer::RecordFinalizeParsing(double duration_ms) {
finalize_parsing_events_.Push(duration_ms);
}
+void CompilerDispatcherTracer::RecordAnalyze(double duration_ms) {
+ base::LockGuard<base::Mutex> lock(&mutex_);
+ analyze_events_.Push(duration_ms);
+}
+
void CompilerDispatcherTracer::RecordPrepareToCompile(double duration_ms) {
base::LockGuard<base::Mutex> lock(&mutex_);
prepare_compile_events_.Push(duration_ms);
@@ -128,6 +138,11 @@ double CompilerDispatcherTracer::EstimateFinalizeParsingInMs() const {
return Average(finalize_parsing_events_);
}
+double CompilerDispatcherTracer::EstimateAnalyzeInMs() const {
+ base::LockGuard<base::Mutex> lock(&mutex_);
+ return Average(analyze_events_);
+}
+
double CompilerDispatcherTracer::EstimatePrepareToCompileInMs() const {
base::LockGuard<base::Mutex> lock(&mutex_);
return Average(prepare_compile_events_);
@@ -148,11 +163,12 @@ void CompilerDispatcherTracer::DumpStatistics() const {
PrintF(
"CompilerDispatcherTracer: "
"prepare_parsing=%.2lfms parsing=%.2lfms/kb finalize_parsing=%.2lfms "
- "prepare_compiling=%.2lfms compiling=%.2lfms/kb "
- "finalize_compilig=%.2lfms\n",
+ "analyze=%.2lfms prepare_compiling=%.2lfms compiling=%.2lfms/kb "
+ "finalize_compiling=%.2lfms\n",
EstimatePrepareToParseInMs(), EstimateParseInMs(1 * KB),
- EstimateFinalizeParsingInMs(), EstimatePrepareToCompileInMs(),
- EstimateCompileInMs(1 * KB), EstimateFinalizeCompilingInMs());
+ EstimateFinalizeParsingInMs(), EstimateAnalyzeInMs(),
+ EstimatePrepareToCompileInMs(), EstimateCompileInMs(1 * KB),
+ EstimateFinalizeCompilingInMs());
}
double CompilerDispatcherTracer::Average(
diff --git a/deps/v8/src/compiler-dispatcher/compiler-dispatcher-tracer.h b/deps/v8/src/compiler-dispatcher/compiler-dispatcher-tracer.h
index 3751d0da54..7bbd5d9d60 100644
--- a/deps/v8/src/compiler-dispatcher/compiler-dispatcher-tracer.h
+++ b/deps/v8/src/compiler-dispatcher/compiler-dispatcher-tracer.h
@@ -35,6 +35,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherTracer {
kPrepareToParse,
kParse,
kFinalizeParsing,
+ kAnalyze,
kPrepareToCompile,
kCompile,
kFinalizeCompiling
@@ -62,6 +63,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherTracer {
void RecordPrepareToParse(double duration_ms);
void RecordParse(double duration_ms, size_t source_length);
void RecordFinalizeParsing(double duration_ms);
+ void RecordAnalyze(double duration_ms);
void RecordPrepareToCompile(double duration_ms);
void RecordCompile(double duration_ms, size_t ast_size_in_bytes);
void RecordFinalizeCompiling(double duration_ms);
@@ -69,6 +71,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherTracer {
double EstimatePrepareToParseInMs() const;
double EstimateParseInMs(size_t source_length) const;
double EstimateFinalizeParsingInMs() const;
+ double EstimateAnalyzeInMs() const;
double EstimatePrepareToCompileInMs() const;
double EstimateCompileInMs(size_t ast_size_in_bytes) const;
double EstimateFinalizeCompilingInMs() const;
@@ -84,6 +87,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherTracer {
base::RingBuffer<double> prepare_parse_events_;
base::RingBuffer<std::pair<size_t, double>> parse_events_;
base::RingBuffer<double> finalize_parsing_events_;
+ base::RingBuffer<double> analyze_events_;
base::RingBuffer<double> prepare_compile_events_;
base::RingBuffer<std::pair<size_t, double>> compile_events_;
base::RingBuffer<double> finalize_compiling_events_;
diff --git a/deps/v8/src/compiler-dispatcher/compiler-dispatcher.cc b/deps/v8/src/compiler-dispatcher/compiler-dispatcher.cc
index 70edce9673..802142b883 100644
--- a/deps/v8/src/compiler-dispatcher/compiler-dispatcher.cc
+++ b/deps/v8/src/compiler-dispatcher/compiler-dispatcher.cc
@@ -8,6 +8,7 @@
#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"
@@ -23,6 +24,13 @@ 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();
@@ -36,7 +44,11 @@ bool DoNextStepOnMainThread(Isolate* isolate, CompilerDispatcherJob* job,
job->FinalizeParsingOnMainThread();
break;
- case CompileJobStatus::kReadyToAnalyse:
+ case CompileJobStatus::kReadyToAnalyze:
+ job->AnalyzeOnMainThread();
+ break;
+
+ case CompileJobStatus::kAnalyzed:
job->PrepareToCompileOnMainThread();
break;
@@ -74,6 +86,9 @@ bool CanRunOnAnyThread(CompilerDispatcherJob* job) {
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();
@@ -224,7 +239,7 @@ CompilerDispatcher::~CompilerDispatcher() {
task_manager_->CancelAndWait();
}
-bool CompilerDispatcher::Enqueue(Handle<SharedFunctionInfo> function) {
+bool CompilerDispatcher::CanEnqueue(Handle<SharedFunctionInfo> function) {
if (!IsEnabled()) return false;
DCHECK(FLAG_ignition);
@@ -245,12 +260,19 @@ bool CompilerDispatcher::Enqueue(Handle<SharedFunctionInfo> function) {
return false;
}
+ return true;
+}
+
+bool CompilerDispatcher::Enqueue(Handle<SharedFunctionInfo> 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("\n");
+ PrintF(" for parse and compile\n");
}
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
@@ -263,6 +285,9 @@ bool CompilerDispatcher::Enqueue(Handle<SharedFunctionInfo> function) {
}
bool CompilerDispatcher::EnqueueAndStep(Handle<SharedFunctionInfo> 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_) {
@@ -277,17 +302,71 @@ bool CompilerDispatcher::EnqueueAndStep(Handle<SharedFunctionInfo> function) {
return true;
}
-bool CompilerDispatcher::IsEnabled() const {
- v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_);
- return FLAG_compiler_dispatcher && platform_->IdleTasksEnabled(v8_isolate);
+bool CompilerDispatcher::Enqueue(
+ Handle<Script> script, Handle<SharedFunctionInfo> function,
+ FunctionLiteral* literal, std::shared_ptr<Zone> parse_zone,
+ std::shared_ptr<DeferredHandles> parse_handles,
+ std::shared_ptr<DeferredHandles> compile_handles) {
+ 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 compile\n");
+ }
+
+ std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
+ isolate_, tracer_.get(), script, function, literal, parse_zone,
+ parse_handles, compile_handles, max_stack_size_));
+ std::pair<int, int> 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<Script> script, Handle<SharedFunctionInfo> function,
+ FunctionLiteral* literal, std::shared_ptr<Zone> parse_zone,
+ std::shared_ptr<DeferredHandles> parse_handles,
+ std::shared_ptr<DeferredHandles> compile_handles) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
+ "V8.CompilerDispatcherEnqueueAndStep");
+ if (IsEnqueued(function)) return true;
+ if (!Enqueue(script, function, literal, parse_zone, parse_handles,
+ compile_handles)) {
+ 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::IsEnabled() const { return FLAG_compiler_dispatcher; }
+
bool CompilerDispatcher::IsEnqueued(Handle<SharedFunctionInfo> function) const {
+ if (jobs_.empty()) return false;
return GetJobFor(function) != jobs_.end();
}
void CompilerDispatcher::WaitForJobIfRunningOnBackground(
CompilerDispatcherJob* job) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
+ "V8.CompilerDispatcherWaitForBackgroundJob");
+ RuntimeCallTimerScope runtimeTimer(
+ isolate_, &RuntimeCallStats::CompileWaitForDispatcher);
+
base::LockGuard<base::Mutex> lock(&mutex_);
if (running_background_jobs_.find(job) == running_background_jobs_.end()) {
pending_background_jobs_.erase(job);
@@ -303,6 +382,8 @@ void CompilerDispatcher::WaitForJobIfRunningOnBackground(
}
bool CompilerDispatcher::FinishNow(Handle<SharedFunctionInfo> function) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
+ "V8.CompilerDispatcherFinishNow");
JobMap::const_iterator job = GetJobFor(function);
CHECK(job != jobs_.end());
@@ -479,6 +560,8 @@ void CompilerDispatcher::ConsiderJobForBackgroundProcessing(
}
void CompilerDispatcher::ScheduleMoreBackgroundTasksIfNeeded() {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
+ "V8.CompilerDispatcherScheduleMoreBackgroundTasksIfNeeded");
if (FLAG_single_threaded) return;
{
base::LockGuard<base::Mutex> lock(&mutex_);
diff --git a/deps/v8/src/compiler-dispatcher/compiler-dispatcher.h b/deps/v8/src/compiler-dispatcher/compiler-dispatcher.h
index 41d4c83d52..6347aa89d3 100644
--- a/deps/v8/src/compiler-dispatcher/compiler-dispatcher.h
+++ b/deps/v8/src/compiler-dispatcher/compiler-dispatcher.h
@@ -28,8 +28,11 @@ namespace internal {
class CancelableTaskManager;
class CompilerDispatcherJob;
class CompilerDispatcherTracer;
+class DeferredHandles;
+class FunctionLiteral;
class Isolate;
class SharedFunctionInfo;
+class Zone;
template <typename T>
class Handle;
@@ -68,7 +71,10 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
size_t max_stack_size);
~CompilerDispatcher();
- // Returns true if a job was enqueued.
+ // Returns true if the compiler dispatcher is enabled.
+ bool IsEnabled() const;
+
+ // Enqueue a job for parse and compile. Returns true if a job was enqueued.
bool Enqueue(Handle<SharedFunctionInfo> function);
// Like Enqueue, but also advances the job so that it can potentially
@@ -76,11 +82,28 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
// true if the job was enqueued.
bool EnqueueAndStep(Handle<SharedFunctionInfo> function);
+ // Enqueue a job for compilation. Function must have already been parsed and
+ // analyzed and be ready for compilation. Returns true if a job was enqueued.
+ bool Enqueue(Handle<Script> script, Handle<SharedFunctionInfo> function,
+ FunctionLiteral* literal, std::shared_ptr<Zone> parse_zone,
+ std::shared_ptr<DeferredHandles> parse_handles,
+ std::shared_ptr<DeferredHandles> compile_handles);
+
+ // Like Enqueue, but also advances the job so that it can potentially
+ // continue running on a background thread (if at all possible). Returns
+ // true if the job was enqueued.
+ bool EnqueueAndStep(Handle<Script> script,
+ Handle<SharedFunctionInfo> function,
+ FunctionLiteral* literal,
+ std::shared_ptr<Zone> parse_zone,
+ std::shared_ptr<DeferredHandles> parse_handles,
+ std::shared_ptr<DeferredHandles> compile_handles);
+
// Returns true if there is a pending job for the given function.
bool IsEnqueued(Handle<SharedFunctionInfo> function) const;
// Blocks until the given function is compiled (and does so as fast as
- // possible). Returns true if the compile job was succesful.
+ // possible). Returns true if the compile job was successful.
bool FinishNow(Handle<SharedFunctionInfo> function);
// Aborts a given job. Blocks if requested.
@@ -95,6 +118,9 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
private:
FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStep);
+ FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStepTwice);
+ FRIEND_TEST(CompilerDispatcherTest, EnqueueParsed);
+ FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStepParsed);
FRIEND_TEST(CompilerDispatcherTest, IdleTaskSmallIdleTime);
FRIEND_TEST(CompilerDispatcherTest, CompileOnBackgroundThread);
FRIEND_TEST(CompilerDispatcherTest, FinishNowWithBackgroundTask);
@@ -110,8 +136,8 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
class IdleTask;
void WaitForJobIfRunningOnBackground(CompilerDispatcherJob* job);
- bool IsEnabled() const;
void AbortInactiveJobs();
+ bool CanEnqueue(Handle<SharedFunctionInfo> function);
JobMap::const_iterator GetJobFor(Handle<SharedFunctionInfo> shared) const;
void ConsiderJobForBackgroundProcessing(CompilerDispatcherJob* job);
void ScheduleMoreBackgroundTasksIfNeeded();
diff --git a/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc b/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc
index 1169506384..04df928727 100644
--- a/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc
+++ b/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc
@@ -9,6 +9,7 @@
#include "src/compiler.h"
#include "src/full-codegen/full-codegen.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "src/tracing/trace-event.h"
#include "src/v8.h"
@@ -33,11 +34,11 @@ void DisposeCompilationJob(CompilationJob* job, bool restore_function_code) {
class OptimizingCompileDispatcher::CompileTask : public v8::Task {
public:
- explicit CompileTask(Isolate* isolate) : isolate_(isolate) {
- OptimizingCompileDispatcher* dispatcher =
- isolate_->optimizing_compile_dispatcher();
- base::LockGuard<base::Mutex> lock_guard(&dispatcher->ref_count_mutex_);
- ++dispatcher->ref_count_;
+ explicit CompileTask(Isolate* isolate,
+ OptimizingCompileDispatcher* dispatcher)
+ : isolate_(isolate), dispatcher_(dispatcher) {
+ base::LockGuard<base::Mutex> lock_guard(&dispatcher_->ref_count_mutex_);
+ ++dispatcher_->ref_count_;
}
virtual ~CompileTask() {}
@@ -49,30 +50,29 @@ class OptimizingCompileDispatcher::CompileTask : public v8::Task {
DisallowHandleAllocation no_handles;
DisallowHandleDereference no_deref;
- OptimizingCompileDispatcher* dispatcher =
- isolate_->optimizing_compile_dispatcher();
{
TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.RecompileConcurrent");
- if (dispatcher->recompilation_delay_ != 0) {
+ if (dispatcher_->recompilation_delay_ != 0) {
base::OS::Sleep(base::TimeDelta::FromMilliseconds(
- dispatcher->recompilation_delay_));
+ dispatcher_->recompilation_delay_));
}
- dispatcher->CompileNext(dispatcher->NextInput(true));
+ dispatcher_->CompileNext(dispatcher_->NextInput(true));
}
{
- base::LockGuard<base::Mutex> lock_guard(&dispatcher->ref_count_mutex_);
- if (--dispatcher->ref_count_ == 0) {
- dispatcher->ref_count_zero_.NotifyOne();
+ base::LockGuard<base::Mutex> lock_guard(&dispatcher_->ref_count_mutex_);
+ if (--dispatcher_->ref_count_ == 0) {
+ dispatcher_->ref_count_zero_.NotifyOne();
}
}
}
Isolate* isolate_;
+ OptimizingCompileDispatcher* dispatcher_;
DISALLOW_COPY_AND_ASSIGN(CompileTask);
};
@@ -222,14 +222,14 @@ void OptimizingCompileDispatcher::QueueForOptimization(CompilationJob* job) {
blocked_jobs_++;
} else {
V8::GetCurrentPlatform()->CallOnBackgroundThread(
- new CompileTask(isolate_), v8::Platform::kShortRunningTask);
+ new CompileTask(isolate_, this), v8::Platform::kShortRunningTask);
}
}
void OptimizingCompileDispatcher::Unblock() {
while (blocked_jobs_ > 0) {
V8::GetCurrentPlatform()->CallOnBackgroundThread(
- new CompileTask(isolate_), v8::Platform::kShortRunningTask);
+ new CompileTask(isolate_, this), v8::Platform::kShortRunningTask);
blocked_jobs_--;
}
}
diff --git a/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h b/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h
index 7e08161517..5a9486d177 100644
--- a/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h
+++ b/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h
@@ -12,6 +12,7 @@
#include "src/base/platform/mutex.h"
#include "src/base/platform/platform.h"
#include "src/flags.h"
+#include "src/globals.h"
#include "src/list.h"
namespace v8 {
@@ -20,7 +21,7 @@ namespace internal {
class CompilationJob;
class SharedFunctionInfo;
-class OptimizingCompileDispatcher {
+class V8_EXPORT_PRIVATE OptimizingCompileDispatcher {
public:
enum class BlockingBehavior { kBlock, kDontBlock };
@@ -38,9 +39,9 @@ class OptimizingCompileDispatcher {
~OptimizingCompileDispatcher();
- void Run();
void Stop();
void Flush(BlockingBehavior blocking_behavior);
+ // Takes ownership of |job|.
void QueueForOptimization(CompilationJob* job);
void Unblock();
void InstallOptimizedFunctions();