summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler-dispatcher/unoptimized-compile-job.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler-dispatcher/unoptimized-compile-job.cc')
-rw-r--r--deps/v8/src/compiler-dispatcher/unoptimized-compile-job.cc278
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;