diff options
Diffstat (limited to 'deps/v8/src/compiler-dispatcher/unoptimized-compile-job.cc')
-rw-r--r-- | deps/v8/src/compiler-dispatcher/unoptimized-compile-job.cc | 278 |
1 files changed, 88 insertions, 190 deletions
diff --git a/deps/v8/src/compiler-dispatcher/unoptimized-compile-job.cc b/deps/v8/src/compiler-dispatcher/unoptimized-compile-job.cc index ca7e12e402..74b2352bd8 100644 --- a/deps/v8/src/compiler-dispatcher/unoptimized-compile-job.cc +++ b/deps/v8/src/compiler-dispatcher/unoptimized-compile-job.cc @@ -11,6 +11,7 @@ #include "src/compiler.h" #include "src/flags.h" #include "src/global-handles.h" +#include "src/interpreter/interpreter.h" #include "src/isolate.h" #include "src/objects-inl.h" #include "src/parsing/parse-info.h" @@ -66,14 +67,18 @@ UnoptimizedCompileJob::UnoptimizedCompileJob(Isolate* isolate, CompilerDispatcherTracer* tracer, Handle<SharedFunctionInfo> shared, size_t max_stack_size) - : status_(Status::kInitial), + : CompilerDispatcherJob(Type::kUnoptimizedCompile), main_thread_id_(isolate->thread_id().ToInteger()), tracer_(tracer), + allocator_(isolate->allocator()), context_(isolate->global_handles()->Create(isolate->context())), shared_(isolate->global_handles()->Create(*shared)), max_stack_size_(max_stack_size), trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) { DCHECK(!shared_->is_toplevel()); + // TODO(rmcilroy): Handle functions with non-empty outer scope info. + DCHECK(shared_->outer_scope_info()->IsTheHole(isolate) || + ScopeInfo::cast(shared_->outer_scope_info())->length() == 0); HandleScope scope(isolate); Handle<Script> script(Script::cast(shared_->script()), isolate); Handle<String> source(String::cast(script->source()), isolate); @@ -85,8 +90,7 @@ UnoptimizedCompileJob::UnoptimizedCompileJob(Isolate* isolate, } UnoptimizedCompileJob::~UnoptimizedCompileJob() { - DCHECK(status_ == Status::kInitial || - status_ == Status::kDone); + DCHECK(status() == Status::kInitial || status() == Status::kDone); if (!shared_.is_null()) { DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_); i::GlobalHandles::Destroy(Handle<Object>::cast(shared_).location()); @@ -102,71 +106,17 @@ bool UnoptimizedCompileJob::IsAssociatedWith( return *shared_ == *shared; } -void UnoptimizedCompileJob::StepNextOnMainThread(Isolate* isolate) { - DCHECK_EQ(isolate->thread_id().ToInteger(), main_thread_id_); - - // Ensure we are in the correct context for the job. - SaveContext save(isolate); - if (has_context()) { - isolate->set_context(context()); - } else { - // Phases which can run off the main thread by definition can't execute any - // JS code, and so we don't need to enter their context. - DCHECK(CanStepNextOnAnyThread()); - } - - switch (status()) { - case Status::kInitial: - return PrepareToParseOnMainThread(isolate); - - case Status::kReadyToParse: - return Parse(); - - case Status::kParsed: - return FinalizeParsingOnMainThread(isolate); - - case Status::kReadyToAnalyze: - return AnalyzeOnMainThread(isolate); - - case Status::kAnalyzed: - return PrepareToCompileOnMainThread(isolate); - - case Status::kReadyToCompile: - return Compile(); - - case Status::kCompiled: - return FinalizeCompilingOnMainThread(isolate); - - case Status::kFailed: - case Status::kDone: - return; - } - UNREACHABLE(); -} - -void UnoptimizedCompileJob::StepNextOnBackgroundThread() { - DCHECK(CanStepNextOnAnyThread()); - switch (status()) { - case Status::kReadyToParse: - return Parse(); - - case Status::kReadyToCompile: - return Compile(); - - default: - UNREACHABLE(); - } -} - -void UnoptimizedCompileJob::PrepareToParseOnMainThread(Isolate* isolate) { +void UnoptimizedCompileJob::PrepareOnMainThread(Isolate* isolate) { DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_); DCHECK_EQ(isolate->thread_id().ToInteger(), main_thread_id_); - DCHECK(status() == Status::kInitial); - COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToParse); + DCHECK_EQ(status(), Status::kInitial); + COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepare); + if (trace_compiler_dispatcher_jobs_) { PrintF("UnoptimizedCompileJob[%p]: Preparing to parse\n", static_cast<void*>(this)); } + HandleScope scope(isolate); unicode_cache_.reset(new UnicodeCache()); Handle<Script> script(Script::cast(shared_->script()), isolate); @@ -266,142 +216,76 @@ void UnoptimizedCompileJob::PrepareToParseOnMainThread(Isolate* isolate) { Handle<String> name(shared_->name()); parse_info_->set_function_name( parse_info_->ast_value_factory()->GetString(name)); - status_ = Status::kReadyToParse; + set_status(Status::kPrepared); } -void UnoptimizedCompileJob::Parse() { - DCHECK(status() == Status::kReadyToParse); +void UnoptimizedCompileJob::Compile(bool on_background_thread) { + DCHECK_EQ(status(), Status::kPrepared); COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM( - tracer_, kParse, + tracer_, kCompile, parse_info_->end_position() - parse_info_->start_position()); if (trace_compiler_dispatcher_jobs_) { - PrintF("UnoptimizedCompileJob[%p]: Parsing\n", static_cast<void*>(this)); + PrintF("UnoptimizedCompileJob[%p]: Compiling\n", static_cast<void*>(this)); } DisallowHeapAllocation no_allocation; DisallowHandleAllocation no_handles; DisallowHandleDereference no_deref; + parse_info_->set_on_background_thread(on_background_thread); uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB; - parser_->set_stack_limit(stack_limit); + parse_info_->set_stack_limit(stack_limit); parser_->ParseOnBackground(parse_info_.get()); - status_ = Status::kParsed; -} - -void UnoptimizedCompileJob::FinalizeParsingOnMainThread(Isolate* isolate) { - DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_); - DCHECK_EQ(isolate->thread_id().ToInteger(), main_thread_id_); - DCHECK(status() == Status::kParsed); - COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalizeParsing); - if (trace_compiler_dispatcher_jobs_) { - PrintF("UnoptimizedCompileJob[%p]: Finalizing parsing\n", - static_cast<void*>(this)); - } - - if (!source_.is_null()) { - i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location()); - source_ = Handle<String>::null(); - } - if (!wrapper_.is_null()) { - i::GlobalHandles::Destroy(Handle<Object>::cast(wrapper_).location()); - wrapper_ = Handle<String>::null(); - } - - Handle<Script> script(Script::cast(shared_->script()), isolate); - parse_info_->set_script(script); - - 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); - } if (parse_info_->literal() == nullptr) { - parser_->ReportErrors(isolate, script); - status_ = Status::kFailed; - } else { - parse_info_->literal()->scope()->AttachOuterScopeInfo(parse_info_.get(), - isolate); - status_ = Status::kReadyToAnalyze; - } - parser_->UpdateStatistics(isolate, script); - parse_info_->UpdateStatisticsAfterBackgroundParse(isolate); - - parser_->HandleSourceURLComments(isolate, script); - - parse_info_->set_unicode_cache(nullptr); - parser_.reset(); - unicode_cache_.reset(); -} - -void UnoptimizedCompileJob::AnalyzeOnMainThread(Isolate* isolate) { - DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_); - DCHECK_EQ(isolate->thread_id().ToInteger(), main_thread_id_); - DCHECK(status() == Status::kReadyToAnalyze); - COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kAnalyze); - if (trace_compiler_dispatcher_jobs_) { - PrintF("UnoptimizedCompileJob[%p]: Analyzing\n", static_cast<void*>(this)); + // Parser sets error in pending error handler. + set_status(Status::kHasErrorsToReport); + return; } - if (Compiler::Analyze(parse_info_.get())) { - status_ = Status::kAnalyzed; - } else { - status_ = Status::kFailed; - if (!isolate->has_pending_exception()) isolate->StackOverflow(); + if (!Compiler::Analyze(parse_info_.get())) { + parse_info_->pending_error_handler()->set_stack_overflow(); + set_status(Status::kHasErrorsToReport); + return; } -} -void UnoptimizedCompileJob::PrepareToCompileOnMainThread(Isolate* isolate) { - DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_); - DCHECK_EQ(isolate->thread_id().ToInteger(), main_thread_id_); - DCHECK(status() == Status::kAnalyzed); - COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToCompile); + compilation_job_.reset(interpreter::Interpreter::NewCompilationJob( + parse_info_.get(), parse_info_->literal(), allocator_)); - compilation_job_.reset( - Compiler::PrepareUnoptimizedCompilationJob(parse_info_.get(), isolate)); if (!compilation_job_.get()) { - if (!isolate->has_pending_exception()) isolate->StackOverflow(); - status_ = Status::kFailed; + parse_info_->pending_error_handler()->set_stack_overflow(); + set_status(Status::kHasErrorsToReport); return; } - CHECK(compilation_job_->can_execute_on_background_thread()); - status_ = Status::kReadyToCompile; -} - -void UnoptimizedCompileJob::Compile() { - DCHECK(status() == Status::kReadyToCompile); - COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kCompile); - if (trace_compiler_dispatcher_jobs_) { - PrintF("UnoptimizedCompileJob[%p]: Compiling\n", static_cast<void*>(this)); + if (compilation_job_->ExecuteJob() != CompilationJob::SUCCEEDED) { + parse_info_->pending_error_handler()->set_stack_overflow(); + set_status(Status::kHasErrorsToReport); + return; } - // Disallowing of handle dereference and heap access dealt with in - // CompilationJob::ExecuteJob. - - uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB; - compilation_job_->set_stack_limit(stack_limit); - - CompilationJob::Status status = compilation_job_->ExecuteJob(); - USE(status); - - // Always transition to kCompiled - errors will be reported by - // FinalizeCompilingOnMainThread. - status_ = Status::kCompiled; + set_status(Status::kCompiled); } -void UnoptimizedCompileJob::FinalizeCompilingOnMainThread(Isolate* isolate) { +void UnoptimizedCompileJob::FinalizeOnMainThread(Isolate* isolate) { DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_); DCHECK_EQ(isolate->thread_id().ToInteger(), main_thread_id_); - DCHECK(status() == Status::kCompiled); - COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalizeCompiling); + DCHECK_EQ(status(), Status::kCompiled); + DCHECK_NOT_NULL(parse_info_->literal()); + DCHECK_NOT_NULL(compilation_job_.get()); + COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalize); if (trace_compiler_dispatcher_jobs_) { PrintF("UnoptimizedCompileJob[%p]: Finalizing compiling\n", static_cast<void*>(this)); } + Handle<Script> script(Script::cast(shared_->script()), isolate); + parse_info_->set_script(script); + parser_->UpdateStatistics(isolate, script); + parse_info_->UpdateBackgroundParseStatisticsOnMainThread(isolate); + parser_->HandleSourceURLComments(isolate, script); + { HandleScope scope(isolate); // Internalize ast values onto the heap. @@ -411,24 +295,44 @@ void UnoptimizedCompileJob::FinalizeCompilingOnMainThread(Isolate* isolate) { AnalyzeMode::kRegular); compilation_job_->compilation_info()->set_shared_info(shared_); if (compilation_job_->state() == CompilationJob::State::kFailed || - !Compiler::FinalizeCompilationJob(compilation_job_.release())) { + !Compiler::FinalizeCompilationJob(compilation_job_.release(), + isolate)) { if (!isolate->has_pending_exception()) isolate->StackOverflow(); - status_ = Status::kFailed; + set_status(Status::kFailed); return; } } - compilation_job_.reset(); - parse_info_.reset(); - - status_ = Status::kDone; + ResetDataOnMainThread(isolate); + set_status(Status::kDone); } -void UnoptimizedCompileJob::ResetOnMainThread(Isolate* isolate) { +void UnoptimizedCompileJob::ReportErrorsOnMainThread(Isolate* isolate) { + DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_); + DCHECK_EQ(isolate->thread_id().ToInteger(), main_thread_id_); + DCHECK_EQ(status(), Status::kHasErrorsToReport); + if (trace_compiler_dispatcher_jobs_) { - PrintF("UnoptimizedCompileJob[%p]: Resetting\n", static_cast<void*>(this)); + PrintF("UnoptimizedCompileJob[%p]: Reporting Errors\n", + static_cast<void*>(this)); } + // Ensure we report errors in the correct context for the job. + SaveContext save(isolate); + isolate->set_context(context()); + + Handle<Script> script(Script::cast(shared_->script()), isolate); + parse_info_->pending_error_handler()->ReportErrors( + isolate, script, parse_info_->ast_value_factory()); + + ResetDataOnMainThread(isolate); + set_status(Status::kFailed); +} + +void UnoptimizedCompileJob::ResetDataOnMainThread(Isolate* isolate) { + DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_); + DCHECK_EQ(isolate->thread_id().ToInteger(), main_thread_id_); + compilation_job_.reset(); parser_.reset(); unicode_cache_.reset(); @@ -446,34 +350,28 @@ void UnoptimizedCompileJob::ResetOnMainThread(Isolate* isolate) { i::GlobalHandles::Destroy(Handle<Object>::cast(wrapper_).location()); wrapper_ = Handle<String>::null(); } +} + +void UnoptimizedCompileJob::ResetOnMainThread(Isolate* isolate) { + if (trace_compiler_dispatcher_jobs_) { + PrintF("UnoptimizedCompileJob[%p]: Resetting\n", static_cast<void*>(this)); + } - status_ = Status::kInitial; + ResetDataOnMainThread(isolate); + set_status(Status::kInitial); } double UnoptimizedCompileJob::EstimateRuntimeOfNextStepInMs() const { switch (status()) { case Status::kInitial: - return tracer_->EstimatePrepareToParseInMs(); - - case Status::kReadyToParse: - return tracer_->EstimateParseInMs(parse_info_->end_position() - - parse_info_->start_position()); - - case Status::kParsed: - return tracer_->EstimateFinalizeParsingInMs(); - - case Status::kReadyToAnalyze: - return tracer_->EstimateAnalyzeInMs(); - - case Status::kAnalyzed: - return tracer_->EstimatePrepareToCompileInMs(); - - case Status::kReadyToCompile: - return tracer_->EstimateCompileInMs(); - + return tracer_->EstimatePrepareInMs(); + case Status::kPrepared: + return tracer_->EstimateCompileInMs(parse_info_->end_position() - + parse_info_->start_position()); case Status::kCompiled: - return tracer_->EstimateFinalizeCompilingInMs(); + return tracer_->EstimateFinalizeInMs(); + case Status::kHasErrorsToReport: case Status::kFailed: case Status::kDone: return 0.0; |