diff options
author | Michaël Zasso <targos@protonmail.com> | 2017-05-02 10:50:00 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2017-05-06 20:02:35 +0200 |
commit | 60d1aac8d225e844e68ae48e8f3d58802e635fbe (patch) | |
tree | 922f347dd054db18d88666fad7181e5a777f4022 /deps/v8/src/compiler-dispatcher | |
parent | 73d9c0f903ae371cd5011af64c3a6f69a1bda978 (diff) | |
download | node-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')
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(); |