diff options
Diffstat (limited to 'deps/v8/test/unittests/compiler-dispatcher/unoptimized-compile-job-unittest.cc')
-rw-r--r-- | deps/v8/test/unittests/compiler-dispatcher/unoptimized-compile-job-unittest.cc | 227 |
1 files changed, 135 insertions, 92 deletions
diff --git a/deps/v8/test/unittests/compiler-dispatcher/unoptimized-compile-job-unittest.cc b/deps/v8/test/unittests/compiler-dispatcher/unoptimized-compile-job-unittest.cc index 5a0e89326b..e3d4ae078b 100644 --- a/deps/v8/test/unittests/compiler-dispatcher/unoptimized-compile-job-unittest.cc +++ b/deps/v8/test/unittests/compiler-dispatcher/unoptimized-compile-job-unittest.cc @@ -16,6 +16,7 @@ #include "src/flags.h" #include "src/isolate-inl.h" #include "src/parsing/parse-info.h" +#include "src/parsing/preparsed-scope-data.h" #include "src/v8.h" #include "test/unittests/test-helpers.h" #include "test/unittests/test-utils.h" @@ -26,9 +27,11 @@ namespace internal { class UnoptimizedCompileJobTest : public TestWithNativeContext { public: - UnoptimizedCompileJobTest() : tracer_(isolate()) {} - ~UnoptimizedCompileJobTest() override {} + UnoptimizedCompileJobTest() + : tracer_(isolate()), allocator_(isolate()->allocator()) {} + ~UnoptimizedCompileJobTest() override = default; + AccountingAllocator* allocator() { return allocator_; } CompilerDispatcherTracer* tracer() { return &tracer_; } static void SetUpTestCase() { @@ -44,15 +47,43 @@ class UnoptimizedCompileJobTest : public TestWithNativeContext { save_flags_ = nullptr; } - static Variable* LookupVariableByName(UnoptimizedCompileJob* job, - const char* name) { - const AstRawString* name_raw_string = - job->parse_info_->ast_value_factory()->GetOneByteString(name); - return job->parse_info_->literal()->scope()->Lookup(name_raw_string); + UnoptimizedCompileJob* NewUnoptimizedCompileJob( + Isolate* isolate, Handle<SharedFunctionInfo> shared, + size_t stack_size = FLAG_stack_size) { + std::unique_ptr<ParseInfo> outer_parse_info = + test::OuterParseInfoForShared(isolate, shared); + AstValueFactory* ast_value_factory = + outer_parse_info->GetOrCreateAstValueFactory(); + AstNodeFactory ast_node_factory(ast_value_factory, + outer_parse_info->zone()); + + const AstRawString* function_name = + ast_value_factory->GetOneByteString("f"); + DeclarationScope* script_scope = new (outer_parse_info->zone()) + DeclarationScope(outer_parse_info->zone(), ast_value_factory); + DeclarationScope* function_scope = + new (outer_parse_info->zone()) DeclarationScope( + outer_parse_info->zone(), script_scope, FUNCTION_SCOPE); + function_scope->set_start_position(shared->StartPosition()); + function_scope->set_end_position(shared->EndPosition()); + const FunctionLiteral* function_literal = + ast_node_factory.NewFunctionLiteral( + function_name, function_scope, nullptr, -1, -1, -1, + FunctionLiteral::kNoDuplicateParameters, + FunctionLiteral::kAnonymousExpression, + FunctionLiteral::kShouldEagerCompile, shared->StartPosition(), true, + shared->FunctionLiteralId(isolate), nullptr); + + return new UnoptimizedCompileJob( + tracer(), allocator(), outer_parse_info.get(), function_name, + function_literal, + isolate->counters()->worker_thread_runtime_call_stats(), + isolate->counters()->compile_function_on_background(), FLAG_stack_size); } private: CompilerDispatcherTracer tracer_; + AccountingAllocator* allocator_; static SaveFlags* save_flags_; DISALLOW_COPY_AND_ASSIGN(UnoptimizedCompileJobTest); @@ -63,24 +94,25 @@ SaveFlags* UnoptimizedCompileJobTest::save_flags_ = nullptr; #define ASSERT_JOB_STATUS(STATUS, JOB) ASSERT_EQ(STATUS, JOB->status()) TEST_F(UnoptimizedCompileJobTest, Construct) { - std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob( - isolate(), tracer(), test::CreateSharedFunctionInfo(isolate(), nullptr), - FLAG_stack_size)); + Handle<SharedFunctionInfo> shared = + test::CreateSharedFunctionInfo(isolate(), nullptr); + ASSERT_FALSE(shared->is_compiled()); + std::unique_ptr<UnoptimizedCompileJob> job( + NewUnoptimizedCompileJob(isolate(), shared)); } TEST_F(UnoptimizedCompileJobTest, StateTransitions) { - std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob( - isolate(), tracer(), test::CreateSharedFunctionInfo(isolate(), nullptr), - FLAG_stack_size)); + Handle<SharedFunctionInfo> shared = + test::CreateSharedFunctionInfo(isolate(), nullptr); + ASSERT_FALSE(shared->is_compiled()); + std::unique_ptr<UnoptimizedCompileJob> job( + NewUnoptimizedCompileJob(isolate(), shared)); ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kInitial, job); - job->PrepareOnMainThread(isolate()); - ASSERT_FALSE(job->IsFailed()); - ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kPrepared, job); job->Compile(false); ASSERT_FALSE(job->IsFailed()); - ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kCompiled, job); - job->FinalizeOnMainThread(isolate()); + ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kReadyToFinalize, job); + job->FinalizeOnMainThread(isolate(), shared); ASSERT_FALSE(job->IsFailed()); ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kDone, job); job->ResetOnMainThread(isolate()); @@ -89,15 +121,16 @@ TEST_F(UnoptimizedCompileJobTest, StateTransitions) { TEST_F(UnoptimizedCompileJobTest, SyntaxError) { test::ScriptResource* script = new test::ScriptResource("^^^", strlen("^^^")); - std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob( - isolate(), tracer(), test::CreateSharedFunctionInfo(isolate(), script), - FLAG_stack_size)); + Handle<SharedFunctionInfo> shared = + test::CreateSharedFunctionInfo(isolate(), script); + std::unique_ptr<UnoptimizedCompileJob> job( + NewUnoptimizedCompileJob(isolate(), shared)); - job->PrepareOnMainThread(isolate()); - ASSERT_FALSE(job->IsFailed()); job->Compile(false); ASSERT_FALSE(job->IsFailed()); - job->ReportErrorsOnMainThread(isolate()); + ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kReadyToFinalize, job); + + job->FinalizeOnMainThread(isolate(), shared); ASSERT_TRUE(job->IsFailed()); ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kFailed, job); ASSERT_TRUE(isolate()->has_pending_exception()); @@ -109,7 +142,7 @@ TEST_F(UnoptimizedCompileJobTest, SyntaxError) { } TEST_F(UnoptimizedCompileJobTest, CompileAndRun) { - const char script[] = + const char raw_script[] = "function g() {\n" " f = function(a) {\n" " for (var i = 0; i < 3; i++) { a += 20; }\n" @@ -118,29 +151,28 @@ TEST_F(UnoptimizedCompileJobTest, CompileAndRun) { " return f;\n" "}\n" "g();"; + test::ScriptResource* script = + new test::ScriptResource(raw_script, strlen(raw_script)); Handle<JSFunction> f = RunJS<JSFunction>(script); - std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob( - isolate(), tracer(), handle(f->shared(), f->GetIsolate()), - FLAG_stack_size)); + Handle<SharedFunctionInfo> shared = handle(f->shared(), isolate()); + ASSERT_FALSE(shared->is_compiled()); + std::unique_ptr<UnoptimizedCompileJob> job( + NewUnoptimizedCompileJob(isolate(), shared)); - job->PrepareOnMainThread(isolate()); - ASSERT_FALSE(job->IsFailed()); job->Compile(false); - ASSERT_FALSE(job->IsFailed()); - job->FinalizeOnMainThread(isolate()); - ASSERT_FALSE(job->IsFailed()); + job->FinalizeOnMainThread(isolate(), shared); ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kDone, job); + ASSERT_TRUE(shared->is_compiled()); + job->ResetOnMainThread(isolate()); + ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kInitial, job); Smi* value = Smi::cast(*RunJS("f(100);")); ASSERT_TRUE(value == Smi::FromInt(160)); - - job->ResetOnMainThread(isolate()); - ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kInitial, job); } -TEST_F(UnoptimizedCompileJobTest, CompileFailureToAnalyse) { +TEST_F(UnoptimizedCompileJobTest, CompileFailure) { std::string raw_script("() { var a = "); - for (int i = 0; i < 500000; i++) { + for (int i = 0; i < 10000; i++) { // TODO(leszeks): Figure out a more "unit-test-y" way of forcing an analysis // failure than a binop stack overflow. @@ -150,42 +182,16 @@ TEST_F(UnoptimizedCompileJobTest, CompileFailureToAnalyse) { raw_script += " 'x'; }"; test::ScriptResource* script = new test::ScriptResource(raw_script.c_str(), strlen(raw_script.c_str())); - std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob( - isolate(), tracer(), test::CreateSharedFunctionInfo(isolate(), script), - 100)); + Handle<SharedFunctionInfo> shared = + test::CreateSharedFunctionInfo(isolate(), script); + std::unique_ptr<UnoptimizedCompileJob> job( + NewUnoptimizedCompileJob(isolate(), shared, 100)); - job->PrepareOnMainThread(isolate()); - ASSERT_FALSE(job->IsFailed()); job->Compile(false); ASSERT_FALSE(job->IsFailed()); - job->ReportErrorsOnMainThread(isolate()); - ASSERT_TRUE(job->IsFailed()); - ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kFailed, job); - ASSERT_TRUE(isolate()->has_pending_exception()); + ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kReadyToFinalize, job); - isolate()->clear_pending_exception(); - job->ResetOnMainThread(isolate()); - ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kInitial, job); -} - -TEST_F(UnoptimizedCompileJobTest, CompileFailureToFinalize) { - std::string raw_script("() { var a = "); - for (int i = 0; i < 500; i++) { - // Alternate + and - to avoid n-ary operation nodes. - raw_script += "'x' + 'x' - "; - } - raw_script += " 'x'; }"; - test::ScriptResource* script = - new test::ScriptResource(raw_script.c_str(), strlen(raw_script.c_str())); - std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob( - isolate(), tracer(), test::CreateSharedFunctionInfo(isolate(), script), - 50)); - - job->PrepareOnMainThread(isolate()); - ASSERT_FALSE(job->IsFailed()); - job->Compile(false); - ASSERT_FALSE(job->IsFailed()); - job->ReportErrorsOnMainThread(isolate()); + job->FinalizeOnMainThread(isolate(), shared); ASSERT_TRUE(job->IsFailed()); ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kFailed, job); ASSERT_TRUE(isolate()->has_pending_exception()); @@ -199,7 +205,7 @@ class CompileTask : public Task { public: CompileTask(UnoptimizedCompileJob* job, base::Semaphore* semaphore) : job_(job), semaphore_(semaphore) {} - ~CompileTask() override {} + ~CompileTask() override = default; void Run() override { job_->Compile(true); @@ -223,19 +229,18 @@ TEST_F(UnoptimizedCompileJobTest, CompileOnBackgroundThread) { "}"; test::ScriptResource* script = new test::ScriptResource(raw_script, strlen(raw_script)); - std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob( - isolate(), tracer(), test::CreateSharedFunctionInfo(isolate(), script), - 100)); - - job->PrepareOnMainThread(isolate()); - ASSERT_FALSE(job->IsFailed()); + Handle<SharedFunctionInfo> shared = + test::CreateSharedFunctionInfo(isolate(), script); + std::unique_ptr<UnoptimizedCompileJob> job( + NewUnoptimizedCompileJob(isolate(), shared)); base::Semaphore semaphore(0); auto background_task = base::make_unique<CompileTask>(job.get(), &semaphore); - ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kPrepared, job); + ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kInitial, job); + V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(background_task)); semaphore.Wait(); - job->FinalizeOnMainThread(isolate()); + job->FinalizeOnMainThread(isolate(), shared); ASSERT_FALSE(job->IsFailed()); ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kDone, job); @@ -243,26 +248,64 @@ TEST_F(UnoptimizedCompileJobTest, CompileOnBackgroundThread) { ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kInitial, job); } -TEST_F(UnoptimizedCompileJobTest, LazyInnerFunctions) { - const char script[] = - "f = function() {\n" - " e = (function() { return 42; });\n" - " return e;\n" - "};\n" - "f;"; +TEST_F(UnoptimizedCompileJobTest, EagerInnerFunctions) { + const char raw_script[] = + "function g() {\n" + " f = function() {\n" + " // Simulate an eager IIFE with brackets.\n " + " var e = (function () { return 42; });\n" + " return e;\n" + " }\n" + " return f;\n" + "}\n" + "g();"; + test::ScriptResource* script = + new test::ScriptResource(raw_script, strlen(raw_script)); Handle<JSFunction> f = RunJS<JSFunction>(script); + Handle<SharedFunctionInfo> shared = handle(f->shared(), isolate()); + ASSERT_FALSE(shared->is_compiled()); + std::unique_ptr<UnoptimizedCompileJob> job( + NewUnoptimizedCompileJob(isolate(), shared)); - std::unique_ptr<UnoptimizedCompileJob> job(new UnoptimizedCompileJob( - isolate(), tracer(), handle(f->shared(), f->GetIsolate()), - FLAG_stack_size)); - - job->PrepareOnMainThread(isolate()); + job->Compile(false); + ASSERT_FALSE(job->IsFailed()); + job->FinalizeOnMainThread(isolate(), shared); ASSERT_FALSE(job->IsFailed()); + ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kDone, job); + ASSERT_TRUE(shared->is_compiled()); + + Handle<JSFunction> e = RunJS<JSFunction>("f();"); + + ASSERT_TRUE(e->shared()->is_compiled()); + + job->ResetOnMainThread(isolate()); + ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kInitial, job); +} + +TEST_F(UnoptimizedCompileJobTest, LazyInnerFunctions) { + const char raw_script[] = + "function g() {\n" + " f = function() {\n" + " function e() { return 42; };\n" + " return e;\n" + " }\n" + " return f;\n" + "}\n" + "g();"; + test::ScriptResource* script = + new test::ScriptResource(raw_script, strlen(raw_script)); + Handle<JSFunction> f = RunJS<JSFunction>(script); + Handle<SharedFunctionInfo> shared = handle(f->shared(), isolate()); + ASSERT_FALSE(shared->is_compiled()); + std::unique_ptr<UnoptimizedCompileJob> job( + NewUnoptimizedCompileJob(isolate(), shared)); + job->Compile(false); ASSERT_FALSE(job->IsFailed()); - job->FinalizeOnMainThread(isolate()); + job->FinalizeOnMainThread(isolate(), shared); ASSERT_FALSE(job->IsFailed()); ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kDone, job); + ASSERT_TRUE(shared->is_compiled()); Handle<JSFunction> e = RunJS<JSFunction>("f();"); |