[Compiler] Simplify UnoptimizedCompileJob
Simplifies the unoptimized compile job to have only three steps, the on-main-thread prepare step, the off-thread compile step and the on-main-thread finalization step. As part of this change, the compiler dispatcher no longer supports functions with outer scopeinfo's, since these need to be analysed on the main thread. BUG=v8:5203 Change-Id: Ifb378ef81bd47b6f6d4037a3b8acf88660896c4e Reviewed-on: https://chromium-review.googlesource.com/774558 Commit-Queue: Ross McIlroy <rmcilroy@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/master@{#49413}
This commit is contained in:
parent
473fb7d6af
commit
8ff0ca1b1c
@ -30,26 +30,14 @@ CompilerDispatcherTracer::Scope::Scope(CompilerDispatcherTracer* tracer,
|
||||
CompilerDispatcherTracer::Scope::~Scope() {
|
||||
double elapsed = MonotonicallyIncreasingTimeInMs() - start_time_;
|
||||
switch (scope_id_) {
|
||||
case ScopeID::kPrepareToParse:
|
||||
tracer_->RecordPrepareToParse(elapsed);
|
||||
break;
|
||||
case ScopeID::kParse:
|
||||
tracer_->RecordParse(elapsed, num_);
|
||||
break;
|
||||
case ScopeID::kFinalizeParsing:
|
||||
tracer_->RecordFinalizeParsing(elapsed);
|
||||
break;
|
||||
case ScopeID::kAnalyze:
|
||||
tracer_->RecordAnalyze(elapsed);
|
||||
break;
|
||||
case ScopeID::kPrepareToCompile:
|
||||
tracer_->RecordPrepareToCompile(elapsed);
|
||||
case ScopeID::kPrepare:
|
||||
tracer_->RecordPrepare(elapsed);
|
||||
break;
|
||||
case ScopeID::kCompile:
|
||||
tracer_->RecordCompile(elapsed);
|
||||
tracer_->RecordCompile(elapsed, num_);
|
||||
break;
|
||||
case ScopeID::kFinalizeCompiling:
|
||||
tracer_->RecordFinalizeCompiling(elapsed);
|
||||
case ScopeID::kFinalize:
|
||||
tracer_->RecordFinalize(elapsed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -57,20 +45,12 @@ CompilerDispatcherTracer::Scope::~Scope() {
|
||||
// static
|
||||
const char* CompilerDispatcherTracer::Scope::Name(ScopeID scope_id) {
|
||||
switch (scope_id) {
|
||||
case ScopeID::kPrepareToParse:
|
||||
return "V8.BackgroundCompile_PrepareToParse";
|
||||
case ScopeID::kParse:
|
||||
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::kPrepare:
|
||||
return "V8.BackgroundCompile_Prepare";
|
||||
case ScopeID::kCompile:
|
||||
return "V8.BackgroundCompile_Compile";
|
||||
case ScopeID::kFinalizeCompiling:
|
||||
return "V8.BackgroundCompile_FinalizeCompiling";
|
||||
case ScopeID::kFinalize:
|
||||
return "V8.BackgroundCompile_Finalize";
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -85,87 +65,44 @@ CompilerDispatcherTracer::CompilerDispatcherTracer(Isolate* isolate)
|
||||
|
||||
CompilerDispatcherTracer::~CompilerDispatcherTracer() {}
|
||||
|
||||
void CompilerDispatcherTracer::RecordPrepareToParse(double duration_ms) {
|
||||
void CompilerDispatcherTracer::RecordPrepare(double duration_ms) {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
prepare_parse_events_.Push(duration_ms);
|
||||
prepare_events_.Push(duration_ms);
|
||||
}
|
||||
|
||||
void CompilerDispatcherTracer::RecordParse(double duration_ms,
|
||||
size_t source_length) {
|
||||
void CompilerDispatcherTracer::RecordCompile(double duration_ms,
|
||||
size_t source_length) {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
parse_events_.Push(std::make_pair(source_length, duration_ms));
|
||||
compile_events_.Push(std::make_pair(source_length, duration_ms));
|
||||
}
|
||||
|
||||
void CompilerDispatcherTracer::RecordFinalizeParsing(double duration_ms) {
|
||||
void CompilerDispatcherTracer::RecordFinalize(double duration_ms) {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
finalize_parsing_events_.Push(duration_ms);
|
||||
finalize_events_.Push(duration_ms);
|
||||
}
|
||||
|
||||
void CompilerDispatcherTracer::RecordAnalyze(double duration_ms) {
|
||||
double CompilerDispatcherTracer::EstimatePrepareInMs() const {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
analyze_events_.Push(duration_ms);
|
||||
return Average(prepare_events_);
|
||||
}
|
||||
|
||||
void CompilerDispatcherTracer::RecordPrepareToCompile(double duration_ms) {
|
||||
double CompilerDispatcherTracer::EstimateCompileInMs(
|
||||
size_t source_length) const {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
prepare_compile_events_.Push(duration_ms);
|
||||
return Estimate(compile_events_, source_length);
|
||||
}
|
||||
|
||||
void CompilerDispatcherTracer::RecordCompile(double duration_ms) {
|
||||
double CompilerDispatcherTracer::EstimateFinalizeInMs() const {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
compile_events_.Push(duration_ms);
|
||||
}
|
||||
|
||||
void CompilerDispatcherTracer::RecordFinalizeCompiling(double duration_ms) {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
finalize_compiling_events_.Push(duration_ms);
|
||||
}
|
||||
|
||||
double CompilerDispatcherTracer::EstimatePrepareToParseInMs() const {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
return Average(prepare_parse_events_);
|
||||
}
|
||||
|
||||
double CompilerDispatcherTracer::EstimateParseInMs(size_t source_length) const {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
return Estimate(parse_events_, source_length);
|
||||
}
|
||||
|
||||
double CompilerDispatcherTracer::EstimateFinalizeParsingInMs() const {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
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_);
|
||||
}
|
||||
|
||||
double CompilerDispatcherTracer::EstimateCompileInMs() const {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
return Average(compile_events_);
|
||||
}
|
||||
|
||||
double CompilerDispatcherTracer::EstimateFinalizeCompilingInMs() const {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
return Average(finalize_compiling_events_);
|
||||
return Average(finalize_events_);
|
||||
}
|
||||
|
||||
void CompilerDispatcherTracer::DumpStatistics() const {
|
||||
PrintF(
|
||||
"CompilerDispatcherTracer: "
|
||||
"prepare_parsing=%.2lfms parsing=%.2lfms/kb finalize_parsing=%.2lfms "
|
||||
"analyze=%.2lfms prepare_compiling=%.2lfms compiling=%.2lfms/kb "
|
||||
"finalize_compiling=%.2lfms\n",
|
||||
EstimatePrepareToParseInMs(), EstimateParseInMs(1 * KB),
|
||||
EstimateFinalizeParsingInMs(), EstimateAnalyzeInMs(),
|
||||
EstimatePrepareToCompileInMs(), EstimateCompileInMs(),
|
||||
EstimateFinalizeCompilingInMs());
|
||||
"prepare=%.2lfms compiling=%.2lfms/kb finalize=%.2lfms\n",
|
||||
EstimatePrepareInMs(), EstimateCompileInMs(1 * KB),
|
||||
EstimateFinalizeInMs());
|
||||
}
|
||||
|
||||
double CompilerDispatcherTracer::Average(
|
||||
|
@ -31,15 +31,7 @@ class RuntimeCallStats;
|
||||
|
||||
class V8_EXPORT_PRIVATE CompilerDispatcherTracer {
|
||||
public:
|
||||
enum class ScopeID {
|
||||
kPrepareToParse,
|
||||
kParse,
|
||||
kFinalizeParsing,
|
||||
kAnalyze,
|
||||
kPrepareToCompile,
|
||||
kCompile,
|
||||
kFinalizeCompiling
|
||||
};
|
||||
enum class ScopeID { kPrepare, kCompile, kFinalize };
|
||||
|
||||
class Scope {
|
||||
public:
|
||||
@ -60,21 +52,13 @@ class V8_EXPORT_PRIVATE CompilerDispatcherTracer {
|
||||
explicit CompilerDispatcherTracer(Isolate* isolate);
|
||||
~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);
|
||||
void RecordFinalizeCompiling(double duration_ms);
|
||||
void RecordPrepare(double duration_ms);
|
||||
void RecordCompile(double duration_ms, size_t source_length);
|
||||
void RecordFinalize(double duration_ms);
|
||||
|
||||
double EstimatePrepareToParseInMs() const;
|
||||
double EstimateParseInMs(size_t source_length) const;
|
||||
double EstimateFinalizeParsingInMs() const;
|
||||
double EstimateAnalyzeInMs() const;
|
||||
double EstimatePrepareToCompileInMs() const;
|
||||
double EstimateCompileInMs() const;
|
||||
double EstimateFinalizeCompilingInMs() const;
|
||||
double EstimatePrepareInMs() const;
|
||||
double EstimateCompileInMs(size_t source_length) const;
|
||||
double EstimateFinalizeInMs() const;
|
||||
|
||||
void DumpStatistics() const;
|
||||
|
||||
@ -84,13 +68,9 @@ class V8_EXPORT_PRIVATE CompilerDispatcherTracer {
|
||||
const base::RingBuffer<std::pair<size_t, double>>& buffer, size_t num);
|
||||
|
||||
mutable base::Mutex mutex_;
|
||||
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<double> compile_events_;
|
||||
base::RingBuffer<double> finalize_compiling_events_;
|
||||
base::RingBuffer<double> prepare_events_;
|
||||
base::RingBuffer<std::pair<size_t, double>> compile_events_;
|
||||
base::RingBuffer<double> finalize_events_;
|
||||
|
||||
RuntimeCallStats* runtime_call_stats_;
|
||||
|
||||
|
@ -70,11 +70,15 @@ UnoptimizedCompileJob::UnoptimizedCompileJob(Isolate* isolate,
|
||||
: status_(Status::kInitial),
|
||||
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);
|
||||
@ -118,25 +122,16 @@ void UnoptimizedCompileJob::StepNextOnMainThread(Isolate* isolate) {
|
||||
|
||||
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);
|
||||
return PrepareOnMainThread(isolate);
|
||||
|
||||
case Status::kReadyToCompile:
|
||||
return Compile();
|
||||
return Compile(false);
|
||||
|
||||
case Status::kCompiled:
|
||||
return FinalizeCompilingOnMainThread(isolate);
|
||||
return FinalizeOnMainThread(isolate);
|
||||
|
||||
case Status::kReportErrors:
|
||||
return ReportErrorsOnMainThread(isolate);
|
||||
|
||||
case Status::kFailed:
|
||||
case Status::kDone:
|
||||
@ -148,26 +143,25 @@ void UnoptimizedCompileJob::StepNextOnMainThread(Isolate* isolate) {
|
||||
void UnoptimizedCompileJob::StepNextOnBackgroundThread() {
|
||||
DCHECK(CanStepNextOnAnyThread());
|
||||
switch (status()) {
|
||||
case Status::kReadyToParse:
|
||||
return Parse();
|
||||
|
||||
case Status::kReadyToCompile:
|
||||
return Compile();
|
||||
return Compile(true);
|
||||
|
||||
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_EQ(status(), Status::kInitial);
|
||||
COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToParse);
|
||||
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);
|
||||
@ -267,143 +261,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;
|
||||
status_ = Status::kReadyToCompile;
|
||||
}
|
||||
|
||||
void UnoptimizedCompileJob::Parse() {
|
||||
DCHECK_EQ(status(), Status::kReadyToParse);
|
||||
void UnoptimizedCompileJob::Compile(bool on_background_thread) {
|
||||
DCHECK_EQ(status(), Status::kReadyToCompile);
|
||||
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_EQ(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) {
|
||||
parse_info_->pending_error_handler()->ReportErrors(
|
||||
isolate, script, parse_info_->ast_value_factory());
|
||||
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_EQ(status(), Status::kReadyToAnalyze);
|
||||
COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kAnalyze);
|
||||
if (trace_compiler_dispatcher_jobs_) {
|
||||
PrintF("UnoptimizedCompileJob[%p]: Analyzing\n", static_cast<void*>(this));
|
||||
}
|
||||
|
||||
if (Compiler::Analyze(parse_info_.get())) {
|
||||
status_ = Status::kAnalyzed;
|
||||
} else {
|
||||
status_ = Status::kFailed;
|
||||
if (!isolate->has_pending_exception()) isolate->StackOverflow();
|
||||
}
|
||||
}
|
||||
|
||||
void UnoptimizedCompileJob::PrepareToCompileOnMainThread(Isolate* isolate) {
|
||||
DCHECK_EQ(ThreadId::Current().ToInteger(), main_thread_id_);
|
||||
DCHECK_EQ(isolate->thread_id().ToInteger(), main_thread_id_);
|
||||
DCHECK_EQ(status(), Status::kAnalyzed);
|
||||
COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToCompile);
|
||||
|
||||
compilation_job_.reset(interpreter::Interpreter::NewCompilationJob(
|
||||
parse_info_.get(), parse_info_->literal(), isolate->allocator()));
|
||||
|
||||
if (!compilation_job_.get()) {
|
||||
if (!isolate->has_pending_exception()) isolate->StackOverflow();
|
||||
status_ = Status::kFailed;
|
||||
// Parser sets error in pending error handler.
|
||||
status_ = Status::kReportErrors;
|
||||
return;
|
||||
}
|
||||
|
||||
status_ = Status::kReadyToCompile;
|
||||
}
|
||||
|
||||
void UnoptimizedCompileJob::Compile() {
|
||||
DCHECK_EQ(status(), Status::kReadyToCompile);
|
||||
COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kCompile);
|
||||
if (trace_compiler_dispatcher_jobs_) {
|
||||
PrintF("UnoptimizedCompileJob[%p]: Compiling\n", static_cast<void*>(this));
|
||||
if (!Compiler::Analyze(parse_info_.get())) {
|
||||
parse_info_->pending_error_handler()->set_stack_overflow();
|
||||
status_ = Status::kReportErrors;
|
||||
return;
|
||||
}
|
||||
|
||||
// Disallowing of handle dereference and heap access dealt with in
|
||||
// CompilationJob::ExecuteJob.
|
||||
compilation_job_.reset(interpreter::Interpreter::NewCompilationJob(
|
||||
parse_info_.get(), parse_info_->literal(), allocator_));
|
||||
|
||||
uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB;
|
||||
compilation_job_->set_stack_limit(stack_limit);
|
||||
if (!compilation_job_.get()) {
|
||||
parse_info_->pending_error_handler()->set_stack_overflow();
|
||||
status_ = Status::kReportErrors;
|
||||
return;
|
||||
}
|
||||
|
||||
CompilationJob::Status status = compilation_job_->ExecuteJob();
|
||||
USE(status);
|
||||
if (compilation_job_->ExecuteJob() != CompilationJob::SUCCEEDED) {
|
||||
parse_info_->pending_error_handler()->set_stack_overflow();
|
||||
status_ = Status::kReportErrors;
|
||||
return;
|
||||
}
|
||||
|
||||
// Always transition to kCompiled - errors will be reported by
|
||||
// FinalizeCompilingOnMainThread.
|
||||
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_EQ(status(), Status::kCompiled);
|
||||
COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalizeCompiling);
|
||||
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_->UpdateStatisticsAfterBackgroundParse(isolate);
|
||||
parser_->HandleSourceURLComments(isolate, script);
|
||||
|
||||
{
|
||||
HandleScope scope(isolate);
|
||||
// Internalize ast values onto the heap.
|
||||
@ -421,17 +348,32 @@ void UnoptimizedCompileJob::FinalizeCompilingOnMainThread(Isolate* isolate) {
|
||||
}
|
||||
}
|
||||
|
||||
compilation_job_.reset();
|
||||
parse_info_.reset();
|
||||
|
||||
ResetDataOnMainThread(isolate);
|
||||
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::kReportErrors);
|
||||
|
||||
if (trace_compiler_dispatcher_jobs_) {
|
||||
PrintF("UnoptimizedCompileJob[%p]: Resetting\n", static_cast<void*>(this));
|
||||
PrintF("UnoptimizedCompileJob[%p]: Reporting Errors\n",
|
||||
static_cast<void*>(this));
|
||||
}
|
||||
|
||||
Handle<Script> script(Script::cast(shared_->script()), isolate);
|
||||
parse_info_->pending_error_handler()->ReportErrors(
|
||||
isolate, script, parse_info_->ast_value_factory());
|
||||
|
||||
ResetDataOnMainThread(isolate);
|
||||
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();
|
||||
@ -449,34 +391,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));
|
||||
}
|
||||
|
||||
ResetDataOnMainThread(isolate);
|
||||
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();
|
||||
|
||||
return tracer_->EstimatePrepareInMs();
|
||||
case Status::kReadyToCompile:
|
||||
return tracer_->EstimateCompileInMs();
|
||||
|
||||
return tracer_->EstimateCompileInMs(parse_info_->end_position() -
|
||||
parse_info_->start_position());
|
||||
case Status::kCompiled:
|
||||
return tracer_->EstimateFinalizeCompilingInMs();
|
||||
return tracer_->EstimateFinalizeInMs();
|
||||
|
||||
case Status::kReportErrors:
|
||||
case Status::kFailed:
|
||||
case Status::kDone:
|
||||
return 0.0;
|
||||
|
@ -34,12 +34,9 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
|
||||
public:
|
||||
enum class Status {
|
||||
kInitial,
|
||||
kReadyToParse,
|
||||
kParsed,
|
||||
kReadyToAnalyze,
|
||||
kAnalyzed,
|
||||
kReadyToCompile,
|
||||
kCompiled,
|
||||
kReportErrors,
|
||||
kDone,
|
||||
kFailed,
|
||||
};
|
||||
@ -68,8 +65,7 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
|
||||
// StepNextOnMainThread and StepNextOnBackgroundThread could be used for the
|
||||
// next step.
|
||||
bool CanStepNextOnAnyThread() override {
|
||||
return status() == Status::kReadyToParse ||
|
||||
status() == Status::kReadyToCompile;
|
||||
return status() == Status::kReadyToCompile;
|
||||
}
|
||||
|
||||
// Step the job forward by one state on the main thread.
|
||||
@ -98,6 +94,7 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
|
||||
Status status_;
|
||||
int main_thread_id_;
|
||||
CompilerDispatcherTracer* tracer_;
|
||||
AccountingAllocator* allocator_;
|
||||
Handle<Context> context_; // Global handle.
|
||||
Handle<SharedFunctionInfo> shared_; // Global handle.
|
||||
Handle<String> source_; // Global handle.
|
||||
@ -115,26 +112,20 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileJob : public CompilerDispatcherJob {
|
||||
|
||||
bool trace_compiler_dispatcher_jobs_;
|
||||
|
||||
// Transition from kInitial to kReadyToParse.
|
||||
void PrepareToParseOnMainThread(Isolate* isolate);
|
||||
// Transition from kInitial to kReadyToCompile
|
||||
void PrepareOnMainThread(Isolate* isolate);
|
||||
|
||||
// Transition from kReadyToParse to kParsed.
|
||||
void Parse();
|
||||
|
||||
// Transition from kParsed to kReadyToAnalyze (or kFailed).
|
||||
void FinalizeParsingOnMainThread(Isolate* isolate);
|
||||
|
||||
// Transition from kReadyToAnalyze to kAnalyzed (or kFailed).
|
||||
void AnalyzeOnMainThread(Isolate* isolate);
|
||||
|
||||
// Transition from kAnalyzed to kReadyToCompile (or kFailed).
|
||||
void PrepareToCompileOnMainThread(Isolate* isolate);
|
||||
|
||||
// Transition from kReadyToCompile to kCompiled.
|
||||
void Compile();
|
||||
// Transition from kReadyToCompile to kCompiled (or kReportErrors).
|
||||
void Compile(bool on_background_thread);
|
||||
|
||||
// Transition from kCompiled to kDone (or kFailed).
|
||||
void FinalizeCompilingOnMainThread(Isolate* isolate);
|
||||
void FinalizeOnMainThread(Isolate* isolate);
|
||||
|
||||
// Transition from kReportErrors to kFailed.
|
||||
void ReportErrorsOnMainThread(Isolate* isolate);
|
||||
|
||||
// Free all resources.
|
||||
void ResetDataOnMainThread(Isolate* isolate);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(UnoptimizedCompileJob);
|
||||
};
|
||||
|
@ -11,40 +11,36 @@ namespace internal {
|
||||
TEST(CompilerDispatcherTracerTest, EstimateWithoutSamples) {
|
||||
CompilerDispatcherTracer tracer(nullptr);
|
||||
|
||||
EXPECT_EQ(0.0, tracer.EstimatePrepareToParseInMs());
|
||||
EXPECT_EQ(1.0, tracer.EstimateParseInMs(0));
|
||||
EXPECT_EQ(1.0, tracer.EstimateParseInMs(42));
|
||||
EXPECT_EQ(0.0, tracer.EstimateFinalizeParsingInMs());
|
||||
EXPECT_EQ(0.0, tracer.EstimatePrepareToCompileInMs());
|
||||
EXPECT_EQ(0.0, tracer.EstimateCompileInMs());
|
||||
EXPECT_EQ(0.0, tracer.EstimateCompileInMs());
|
||||
EXPECT_EQ(0.0, tracer.EstimateFinalizeCompilingInMs());
|
||||
EXPECT_EQ(0.0, tracer.EstimatePrepareInMs());
|
||||
EXPECT_EQ(1.0, tracer.EstimateCompileInMs(1));
|
||||
EXPECT_EQ(1.0, tracer.EstimateCompileInMs(42));
|
||||
EXPECT_EQ(0.0, tracer.EstimateFinalizeInMs());
|
||||
}
|
||||
|
||||
TEST(CompilerDispatcherTracerTest, Average) {
|
||||
CompilerDispatcherTracer tracer(nullptr);
|
||||
|
||||
EXPECT_EQ(0.0, tracer.EstimatePrepareToParseInMs());
|
||||
EXPECT_EQ(0.0, tracer.EstimatePrepareInMs());
|
||||
|
||||
tracer.RecordPrepareToParse(1.0);
|
||||
tracer.RecordPrepareToParse(2.0);
|
||||
tracer.RecordPrepareToParse(3.0);
|
||||
tracer.RecordPrepare(1.0);
|
||||
tracer.RecordPrepare(2.0);
|
||||
tracer.RecordPrepare(3.0);
|
||||
|
||||
EXPECT_EQ((1.0 + 2.0 + 3.0) / 3, tracer.EstimatePrepareToParseInMs());
|
||||
EXPECT_EQ((1.0 + 2.0 + 3.0) / 3, tracer.EstimatePrepareInMs());
|
||||
}
|
||||
|
||||
TEST(CompilerDispatcherTracerTest, SizeBasedAverage) {
|
||||
CompilerDispatcherTracer tracer(nullptr);
|
||||
|
||||
EXPECT_EQ(1.0, tracer.EstimateParseInMs(100));
|
||||
EXPECT_EQ(1.0, tracer.EstimateCompileInMs(100));
|
||||
|
||||
// All three samples parse 100 units/ms.
|
||||
tracer.RecordParse(1.0, 100);
|
||||
tracer.RecordParse(2.0, 200);
|
||||
tracer.RecordParse(3.0, 300);
|
||||
tracer.RecordCompile(1.0, 100);
|
||||
tracer.RecordCompile(2.0, 200);
|
||||
tracer.RecordCompile(3.0, 300);
|
||||
|
||||
EXPECT_EQ(1.0, tracer.EstimateParseInMs(100));
|
||||
EXPECT_EQ(5.0, tracer.EstimateParseInMs(500));
|
||||
EXPECT_EQ(1.0, tracer.EstimateCompileInMs(100));
|
||||
EXPECT_EQ(5.0, tracer.EstimateCompileInMs(500));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
@ -31,9 +31,8 @@
|
||||
#define STR(x) _STR(x)
|
||||
#define _SCRIPT(fn, a, b, c) a fn b fn c
|
||||
#define SCRIPT(a, b, c) _SCRIPT("f" STR(__LINE__), a, b, c)
|
||||
#define TEST_SCRIPT() \
|
||||
SCRIPT("function g() { var y = 1; function ", \
|
||||
"(x) { return x * y }; return ", "; } g();")
|
||||
#define TEST_SCRIPT() \
|
||||
"function f" STR(__LINE__) "(x, y) { return x * y }; f" STR(__LINE__) ";"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -335,9 +334,8 @@ TEST_F(CompilerDispatcherTest, FinishAllNow) {
|
||||
std::stringstream ss;
|
||||
ss << 'f' << STR(__LINE__) << '_' << i;
|
||||
std::string func_name = ss.str();
|
||||
std::string script("function g() { function " + func_name +
|
||||
"(x) { var a = 'x'; }; return " + func_name +
|
||||
"; } g();");
|
||||
std::string script("function f" + func_name + "(x, y) { return x * y }; f" +
|
||||
func_name + ";");
|
||||
f[i] = RunJS<JSFunction>(script.c_str());
|
||||
shared[i] = Handle<SharedFunctionInfo>(f[i]->shared(), i_isolate());
|
||||
ASSERT_FALSE(shared[i]->is_compiled());
|
||||
@ -400,7 +398,7 @@ TEST_F(CompilerDispatcherTest, IdleTaskSmallIdleTime) {
|
||||
// The job should be still scheduled for the main thread, but ready for
|
||||
// parsing.
|
||||
ASSERT_EQ(dispatcher.jobs_.size(), 1u);
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToParse,
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToCompile,
|
||||
GetUnoptimizedJobStatus(dispatcher.jobs_.begin()->second));
|
||||
|
||||
// Now grant a lot of idle time and freeze time.
|
||||
@ -416,12 +414,12 @@ TEST_F(CompilerDispatcherTest, IdleTaskException) {
|
||||
CompilerDispatcher dispatcher(i_isolate(), &platform, 50);
|
||||
|
||||
std::string func_name("f" STR(__LINE__));
|
||||
std::string script("function g() { function " + func_name + "(x) { var a = ");
|
||||
std::string script("function " + func_name + "(x) { var a = ");
|
||||
for (int i = 0; i < 500; i++) {
|
||||
// Alternate + and - to avoid n-ary operation nodes.
|
||||
script += "'x' + 'x' - ";
|
||||
}
|
||||
script += " 'x'; }; return " + func_name + "; } g();";
|
||||
script += " 'x'; }; " + func_name + ";";
|
||||
Handle<JSFunction> f = RunJS<JSFunction>(script.c_str());
|
||||
Handle<SharedFunctionInfo> shared(f->shared(), i_isolate());
|
||||
|
||||
@ -456,7 +454,7 @@ TEST_F(CompilerDispatcherTest, CompileOnBackgroundThread) {
|
||||
|
||||
// Make compiling super expensive, and advance job as much as possible on the
|
||||
// foreground thread.
|
||||
dispatcher.tracer_->RecordCompile(50000.0);
|
||||
dispatcher.tracer_->RecordCompile(50000.0, 1);
|
||||
platform.RunIdleTask(10.0, 0.0);
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToCompile,
|
||||
GetUnoptimizedJobStatus(dispatcher.jobs_.begin()->second));
|
||||
@ -499,7 +497,7 @@ TEST_F(CompilerDispatcherTest, FinishNowWithBackgroundTask) {
|
||||
|
||||
// Make compiling super expensive, and advance job as much as possible on the
|
||||
// foreground thread.
|
||||
dispatcher.tracer_->RecordCompile(50000.0);
|
||||
dispatcher.tracer_->RecordCompile(50000.0, 1);
|
||||
platform.RunIdleTask(10.0, 0.0);
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToCompile,
|
||||
GetUnoptimizedJobStatus(dispatcher.jobs_.begin()->second));
|
||||
@ -552,12 +550,12 @@ TEST_F(CompilerDispatcherTest, FinishNowException) {
|
||||
CompilerDispatcher dispatcher(i_isolate(), &platform, 50);
|
||||
|
||||
std::string func_name("f" STR(__LINE__));
|
||||
std::string script("function g() { function " + func_name + "(x) { var a = ");
|
||||
std::string script("function " + func_name + "(x) { var a = ");
|
||||
for (int i = 0; i < 500; i++) {
|
||||
// Alternate + and - to avoid n-ary operation nodes.
|
||||
script += "'x' + 'x' - ";
|
||||
}
|
||||
script += " 'x'; }; return " + func_name + "; } g();";
|
||||
script += " 'x'; }; " + func_name + ";";
|
||||
Handle<JSFunction> f = RunJS<JSFunction>(script.c_str());
|
||||
Handle<SharedFunctionInfo> shared(f->shared(), i_isolate());
|
||||
|
||||
@ -593,7 +591,7 @@ TEST_F(CompilerDispatcherTest, AsyncAbortAllPendingBackgroundTask) {
|
||||
|
||||
// Make compiling super expensive, and advance job as much as possible on the
|
||||
// foreground thread.
|
||||
dispatcher.tracer_->RecordCompile(50000.0);
|
||||
dispatcher.tracer_->RecordCompile(50000.0, 1);
|
||||
platform.RunIdleTask(10.0, 0.0);
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToCompile,
|
||||
GetUnoptimizedJobStatus(dispatcher.jobs_.begin()->second));
|
||||
@ -639,7 +637,7 @@ TEST_F(CompilerDispatcherTest, AsyncAbortAllRunningBackgroundTask) {
|
||||
|
||||
// Make compiling super expensive, and advance job as much as possible on the
|
||||
// foreground thread.
|
||||
dispatcher.tracer_->RecordCompile(50000.0);
|
||||
dispatcher.tracer_->RecordCompile(50000.0, 1);
|
||||
platform.RunIdleTask(10.0, 0.0);
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToCompile,
|
||||
GetUnoptimizedJobStatus(dispatcher.jobs_.begin()->second));
|
||||
@ -715,7 +713,7 @@ TEST_F(CompilerDispatcherTest, FinishNowDuringAbortAll) {
|
||||
|
||||
// Make compiling super expensive, and advance job as much as possible on the
|
||||
// foreground thread.
|
||||
dispatcher.tracer_->RecordCompile(50000.0);
|
||||
dispatcher.tracer_->RecordCompile(50000.0, 1);
|
||||
platform.RunIdleTask(10.0, 0.0);
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToCompile,
|
||||
GetUnoptimizedJobStatus(dispatcher.jobs_.begin()->second));
|
||||
@ -884,7 +882,7 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStep) {
|
||||
ASSERT_TRUE(dispatcher.EnqueueAndStep(shared));
|
||||
ASSERT_TRUE(dispatcher.IsEnqueued(shared));
|
||||
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToParse,
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToCompile,
|
||||
GetUnoptimizedJobStatus(dispatcher.jobs_.begin()->second));
|
||||
|
||||
ASSERT_TRUE(platform.IdleTaskPending());
|
||||
@ -898,7 +896,7 @@ TEST_F(CompilerDispatcherTest, CompileLazyFinishesDispatcherJob) {
|
||||
// enqueued functions.
|
||||
CompilerDispatcher* dispatcher = i_isolate()->compiler_dispatcher();
|
||||
|
||||
const char script[] = TEST_SCRIPT();
|
||||
const char script[] = "function lazy() { return 42; }; lazy;";
|
||||
Handle<JSFunction> f = RunJS<JSFunction>(script);
|
||||
Handle<SharedFunctionInfo> shared(f->shared(), i_isolate());
|
||||
|
||||
@ -909,7 +907,7 @@ TEST_F(CompilerDispatcherTest, CompileLazyFinishesDispatcherJob) {
|
||||
|
||||
// Now force the function to run and ensure CompileLazy finished and dequeues
|
||||
// it from the dispatcher.
|
||||
RunJS("g()();");
|
||||
RunJS("lazy();");
|
||||
ASSERT_TRUE(shared->is_compiled());
|
||||
ASSERT_FALSE(dispatcher->IsEnqueued(shared));
|
||||
}
|
||||
@ -950,12 +948,12 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStepTwice) {
|
||||
ASSERT_FALSE(dispatcher.IsEnqueued(shared));
|
||||
ASSERT_TRUE(dispatcher.EnqueueAndStep(shared));
|
||||
ASSERT_TRUE(dispatcher.IsEnqueued(shared));
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToParse,
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToCompile,
|
||||
GetUnoptimizedJobStatus(dispatcher.jobs_.begin()->second));
|
||||
|
||||
// EnqueueAndStep of the same function again (shouldn't step the job.
|
||||
ASSERT_TRUE(dispatcher.EnqueueAndStep(shared));
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToParse,
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToCompile,
|
||||
GetUnoptimizedJobStatus(dispatcher.jobs_.begin()->second));
|
||||
|
||||
ASSERT_TRUE(platform.IdleTaskPending());
|
||||
@ -988,7 +986,7 @@ TEST_F(CompilerDispatcherTest, CompileMultipleOnBackgroundThread) {
|
||||
|
||||
// Make compiling super expensive, and advance job as much as possible on the
|
||||
// foreground thread.
|
||||
dispatcher.tracer_->RecordCompile(50000.0);
|
||||
dispatcher.tracer_->RecordCompile(50000.0, 1);
|
||||
platform.RunIdleTask(10.0, 0.0);
|
||||
ASSERT_EQ(dispatcher.jobs_.size(), 2u);
|
||||
ASSERT_EQ(UnoptimizedCompileJob::Status::kReadyToCompile,
|
||||
@ -1023,5 +1021,11 @@ TEST_F(CompilerDispatcherTest, CompileMultipleOnBackgroundThread) {
|
||||
ASSERT_FALSE(platform.IdleTaskPending());
|
||||
}
|
||||
|
||||
#undef _STR
|
||||
#undef STR
|
||||
#undef _SCRIPT
|
||||
#undef SCRIPT
|
||||
#undef TEST_SCRIPT
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -84,18 +84,6 @@ TEST_F(UnoptimizedCompileJobTest, StateTransitions) {
|
||||
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kInitial, job);
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kReadyToParse, job);
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kParsed, job);
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kReadyToAnalyze, job);
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kAnalyzed, job);
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kReadyToCompile, job);
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
@ -128,39 +116,6 @@ TEST_F(UnoptimizedCompileJobTest, SyntaxError) {
|
||||
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kInitial, job);
|
||||
}
|
||||
|
||||
TEST_F(UnoptimizedCompileJobTest, ScopeChain) {
|
||||
const char script[] =
|
||||
"function g() { var y = 1; function f(x) { return x * y }; return f; } "
|
||||
"g();";
|
||||
Handle<JSFunction> f = RunJS<JSFunction>(script);
|
||||
|
||||
std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob(
|
||||
isolate(), tracer(), handle(f->shared()), FLAG_stack_size));
|
||||
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kReadyToCompile, job);
|
||||
|
||||
Variable* var = LookupVariableByName(job.get(), "x");
|
||||
ASSERT_TRUE(var);
|
||||
ASSERT_TRUE(var->IsParameter());
|
||||
|
||||
var = LookupVariableByName(job.get(), "y");
|
||||
ASSERT_TRUE(var);
|
||||
ASSERT_TRUE(var->IsContextSlot());
|
||||
|
||||
job->ResetOnMainThread(isolate());
|
||||
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kInitial, job);
|
||||
}
|
||||
|
||||
TEST_F(UnoptimizedCompileJobTest, CompileAndRun) {
|
||||
const char script[] =
|
||||
"function g() {\n"
|
||||
@ -175,14 +130,6 @@ TEST_F(UnoptimizedCompileJobTest, CompileAndRun) {
|
||||
std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob(
|
||||
isolate(), tracer(), handle(f->shared()), FLAG_stack_size));
|
||||
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
@ -218,8 +165,6 @@ TEST_F(UnoptimizedCompileJobTest, CompileFailureToAnalyse) {
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_TRUE(job->IsFailed());
|
||||
ASSERT_JOB_STATUS(UnoptimizedCompileJob::Status::kFailed, job);
|
||||
ASSERT_TRUE(isolate()->has_pending_exception());
|
||||
@ -241,14 +186,6 @@ TEST_F(UnoptimizedCompileJobTest, CompileFailureToFinalize) {
|
||||
isolate(), tracer(), test::CreateSharedFunctionInfo(isolate(), &script),
|
||||
50));
|
||||
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
@ -296,14 +233,6 @@ TEST_F(UnoptimizedCompileJobTest, CompileOnBackgroundThread) {
|
||||
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
|
||||
base::Semaphore semaphore(0);
|
||||
CompileTask* background_task = new CompileTask(job.get(), &semaphore);
|
||||
@ -321,27 +250,16 @@ TEST_F(UnoptimizedCompileJobTest, CompileOnBackgroundThread) {
|
||||
|
||||
TEST_F(UnoptimizedCompileJobTest, LazyInnerFunctions) {
|
||||
const char script[] =
|
||||
"function g() {\n"
|
||||
" f = function() {\n"
|
||||
" e = (function() { return 42; });\n"
|
||||
" return e;\n"
|
||||
" };\n"
|
||||
" return f;\n"
|
||||
"}\n"
|
||||
"g();";
|
||||
"f = function() {\n"
|
||||
" e = (function() { return 42; });\n"
|
||||
" return e;\n"
|
||||
"};\n"
|
||||
"f;";
|
||||
Handle<JSFunction> f = RunJS<JSFunction>(script);
|
||||
|
||||
std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob(
|
||||
isolate(), tracer(), handle(f->shared()), FLAG_stack_size));
|
||||
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
ASSERT_FALSE(job->IsFailed());
|
||||
job->StepNextOnMainThread(isolate());
|
||||
|
Loading…
Reference in New Issue
Block a user