2016-07-22 12:19:50 +00:00
|
|
|
// Copyright 2016 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
2016-08-05 13:18:42 +00:00
|
|
|
#include "include/v8.h"
|
|
|
|
#include "src/api.h"
|
2016-09-05 11:54:00 +00:00
|
|
|
#include "src/ast/ast.h"
|
2016-08-05 13:18:42 +00:00
|
|
|
#include "src/ast/scopes.h"
|
2016-09-06 13:34:31 +00:00
|
|
|
#include "src/base/platform/semaphore.h"
|
2016-07-22 12:19:50 +00:00
|
|
|
#include "src/compiler-dispatcher/compiler-dispatcher-job.h"
|
2016-12-12 15:35:41 +00:00
|
|
|
#include "src/compiler-dispatcher/compiler-dispatcher-tracer.h"
|
2016-07-29 10:05:57 +00:00
|
|
|
#include "src/flags.h"
|
2016-07-22 12:19:50 +00:00
|
|
|
#include "src/isolate-inl.h"
|
2016-08-22 11:33:30 +00:00
|
|
|
#include "src/parsing/parse-info.h"
|
2016-09-06 13:34:31 +00:00
|
|
|
#include "src/v8.h"
|
2017-04-18 14:01:12 +00:00
|
|
|
#include "test/unittests/test-helpers.h"
|
2016-07-22 12:19:50 +00:00
|
|
|
#include "test/unittests/test-utils.h"
|
|
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
class CompilerDispatcherJobTest : public TestWithContext {
|
2016-12-12 15:35:41 +00:00
|
|
|
public:
|
2017-07-27 11:49:37 +00:00
|
|
|
CompilerDispatcherJobTest() : tracer_(i_isolate()) {}
|
|
|
|
~CompilerDispatcherJobTest() override {}
|
2016-12-12 15:35:41 +00:00
|
|
|
|
|
|
|
CompilerDispatcherTracer* tracer() { return &tracer_; }
|
|
|
|
|
2016-09-06 13:34:31 +00:00
|
|
|
static void SetUpTestCase() {
|
2017-03-14 13:33:13 +00:00
|
|
|
CHECK_NULL(save_flags_);
|
|
|
|
save_flags_ = new SaveFlags();
|
2017-07-13 12:27:47 +00:00
|
|
|
FLAG_stress_fullcodegen = false;
|
2016-09-06 13:34:31 +00:00
|
|
|
TestWithContext::SetUpTestCase();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void TearDownTestCase() {
|
|
|
|
TestWithContext::TearDownTestCase();
|
2017-03-14 13:33:13 +00:00
|
|
|
CHECK_NOT_NULL(save_flags_);
|
|
|
|
delete save_flags_;
|
|
|
|
save_flags_ = nullptr;
|
2016-09-06 13:34:31 +00:00
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
static CompileJobStatus GetStatus(CompilerDispatcherJob* job) {
|
2017-07-04 08:55:45 +00:00
|
|
|
return job->status();
|
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
static CompileJobStatus GetStatus(
|
|
|
|
const std::unique_ptr<CompilerDispatcherJob>& job) {
|
2017-07-04 08:55:45 +00:00
|
|
|
return GetStatus(job.get());
|
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
static Variable* LookupVariableByName(CompilerDispatcherJob* job,
|
2017-07-04 08:55:45 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-09-06 13:34:31 +00:00
|
|
|
private:
|
2017-01-16 10:49:16 +00:00
|
|
|
CompilerDispatcherTracer tracer_;
|
2017-03-14 13:33:13 +00:00
|
|
|
static SaveFlags* save_flags_;
|
2017-01-16 10:49:16 +00:00
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(CompilerDispatcherJobTest);
|
2016-09-06 13:34:31 +00:00
|
|
|
};
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
SaveFlags* CompilerDispatcherJobTest::save_flags_ = nullptr;
|
2016-09-06 13:34:31 +00:00
|
|
|
|
2016-07-29 10:05:57 +00:00
|
|
|
namespace {
|
|
|
|
|
2016-08-05 13:18:42 +00:00
|
|
|
const char test_script[] = "(x) { x*x; }";
|
2016-08-03 13:30:23 +00:00
|
|
|
|
2016-07-29 10:05:57 +00:00
|
|
|
} // namespace
|
|
|
|
|
2017-07-04 08:55:45 +00:00
|
|
|
#define ASSERT_JOB_STATUS(STATUS, JOB) ASSERT_EQ(STATUS, GetStatus(JOB))
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, Construct) {
|
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2017-04-06 13:59:07 +00:00
|
|
|
i_isolate(), tracer(),
|
|
|
|
test::CreateSharedFunctionInfo(i_isolate(), nullptr), FLAG_stack_size));
|
2016-07-29 10:05:57 +00:00
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, ConstructWithoutSFI) {
|
2017-04-06 13:59:07 +00:00
|
|
|
std::unique_ptr<test::FinishCallback> callback(new test::FinishCallback());
|
|
|
|
std::unique_ptr<test::ScriptResource> resource(
|
|
|
|
new test::ScriptResource(test_script, strlen(test_script)));
|
2017-07-27 11:49:37 +00:00
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2017-04-06 13:59:07 +00:00
|
|
|
tracer(), FLAG_stack_size,
|
|
|
|
test::CreateSource(i_isolate(), resource.get()), 0,
|
2017-04-06 11:58:38 +00:00
|
|
|
static_cast<int>(resource->length()), SLOPPY, 1, false, false, false,
|
2017-04-19 19:20:10 +00:00
|
|
|
i_isolate()->heap()->HashSeed(), i_isolate()->allocator(),
|
2017-04-06 11:58:38 +00:00
|
|
|
ScriptCompiler::kNoCompileOptions, i_isolate()->ast_string_constants(),
|
|
|
|
callback.get()));
|
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, StateTransitions) {
|
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2017-04-06 13:59:07 +00:00
|
|
|
i_isolate(), tracer(),
|
|
|
|
test::CreateSharedFunctionInfo(i_isolate(), nullptr), FLAG_stack_size));
|
2016-07-28 07:46:15 +00:00
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kInitial, job);
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kReadyToParse, job);
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kParsed, job);
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kReadyToAnalyze, job);
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kAnalyzed, job);
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kReadyToCompile, job);
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kCompiled, job);
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kDone, job);
|
2016-08-01 11:27:58 +00:00
|
|
|
job->ResetOnMainThread();
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kInitial, job);
|
2016-08-01 11:27:58 +00:00
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, StateTransitionsParseWithCallback) {
|
2017-04-06 13:59:07 +00:00
|
|
|
std::unique_ptr<test::FinishCallback> callback(new test::FinishCallback());
|
|
|
|
std::unique_ptr<test::ScriptResource> resource(
|
|
|
|
new test::ScriptResource(test_script, strlen(test_script)));
|
2017-07-27 11:49:37 +00:00
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2017-04-06 13:59:07 +00:00
|
|
|
tracer(), FLAG_stack_size,
|
|
|
|
test::CreateSource(i_isolate(), resource.get()), 0,
|
2017-04-06 11:58:38 +00:00
|
|
|
static_cast<int>(resource->length()), SLOPPY, 1, false, false, false,
|
2017-04-19 19:20:10 +00:00
|
|
|
i_isolate()->heap()->HashSeed(), i_isolate()->allocator(),
|
2017-04-06 11:58:38 +00:00
|
|
|
ScriptCompiler::kNoCompileOptions, i_isolate()->ast_string_constants(),
|
|
|
|
callback.get()));
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kReadyToParse, job);
|
|
|
|
job->StepNextOnMainThread();
|
2017-07-04 08:55:45 +00:00
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kDone, job);
|
2017-04-06 11:58:38 +00:00
|
|
|
job->ResetOnMainThread();
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kInitial, job);
|
2017-04-06 11:58:38 +00:00
|
|
|
ASSERT_TRUE(callback->result() != nullptr);
|
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, SyntaxError) {
|
2017-04-06 13:59:07 +00:00
|
|
|
test::ScriptResource script("^^^", strlen("^^^"));
|
2017-07-27 11:49:37 +00:00
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2017-04-06 13:59:07 +00:00
|
|
|
i_isolate(), tracer(),
|
|
|
|
test::CreateSharedFunctionInfo(i_isolate(), &script), FLAG_stack_size));
|
2016-08-01 11:27:58 +00:00
|
|
|
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_TRUE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kFailed, job);
|
2016-08-01 11:27:58 +00:00
|
|
|
ASSERT_TRUE(i_isolate()->has_pending_exception());
|
2016-08-23 12:10:39 +00:00
|
|
|
|
2016-08-05 13:18:42 +00:00
|
|
|
i_isolate()->clear_pending_exception();
|
2016-08-23 12:10:39 +00:00
|
|
|
|
|
|
|
job->ResetOnMainThread();
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kInitial, job);
|
2016-08-05 13:18:42 +00:00
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, ScopeChain) {
|
2016-08-05 13:18:42 +00:00
|
|
|
const char script[] =
|
2016-09-20 12:07:52 +00:00
|
|
|
"function g() { var y = 1; function f(x) { return x * y }; return f; } "
|
2016-08-05 13:18:42 +00:00
|
|
|
"g();";
|
2017-04-06 13:59:07 +00:00
|
|
|
Handle<JSFunction> f =
|
|
|
|
Handle<JSFunction>::cast(test::RunJS(isolate(), script));
|
2016-08-05 13:18:42 +00:00
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2016-12-12 15:35:41 +00:00
|
|
|
i_isolate(), tracer(), handle(f->shared()), FLAG_stack_size));
|
2016-08-05 13:18:42 +00:00
|
|
|
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kReadyToCompile, job);
|
2017-07-04 08:55:45 +00:00
|
|
|
|
|
|
|
Variable* var = LookupVariableByName(job.get(), "x");
|
2016-08-05 13:18:42 +00:00
|
|
|
ASSERT_TRUE(var);
|
2016-09-15 16:41:03 +00:00
|
|
|
ASSERT_TRUE(var->IsParameter());
|
2016-08-05 13:18:42 +00:00
|
|
|
|
2017-07-04 08:55:45 +00:00
|
|
|
var = LookupVariableByName(job.get(), "y");
|
2016-08-05 13:18:42 +00:00
|
|
|
ASSERT_TRUE(var);
|
|
|
|
ASSERT_TRUE(var->IsContextSlot());
|
|
|
|
|
|
|
|
job->ResetOnMainThread();
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kInitial, job);
|
2016-07-28 07:46:15 +00:00
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, CompileAndRun) {
|
2016-08-25 10:24:53 +00:00
|
|
|
const char script[] =
|
|
|
|
"function g() {\n"
|
|
|
|
" f = function(a) {\n"
|
|
|
|
" for (var i = 0; i < 3; i++) { a += 20; }\n"
|
|
|
|
" return a;\n"
|
|
|
|
" }\n"
|
|
|
|
" return f;\n"
|
|
|
|
"}\n"
|
|
|
|
"g();";
|
2017-04-06 13:59:07 +00:00
|
|
|
Handle<JSFunction> f =
|
|
|
|
Handle<JSFunction>::cast(test::RunJS(isolate(), script));
|
2017-07-27 11:49:37 +00:00
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2016-12-12 15:35:41 +00:00
|
|
|
i_isolate(), tracer(), handle(f->shared()), FLAG_stack_size));
|
2016-08-25 10:24:53 +00:00
|
|
|
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kDone, job);
|
2016-08-25 10:24:53 +00:00
|
|
|
|
2017-04-06 13:59:07 +00:00
|
|
|
Smi* value = Smi::cast(*test::RunJS(isolate(), "f(100);"));
|
2016-08-25 10:24:53 +00:00
|
|
|
ASSERT_TRUE(value == Smi::FromInt(160));
|
|
|
|
|
|
|
|
job->ResetOnMainThread();
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kInitial, job);
|
2016-08-25 10:24:53 +00:00
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, CompileFailureToAnalyse) {
|
2016-08-25 10:24:53 +00:00
|
|
|
std::string raw_script("() { var a = ");
|
|
|
|
for (int i = 0; i < 100000; i++) {
|
|
|
|
raw_script += "'x' + ";
|
|
|
|
}
|
|
|
|
raw_script += " 'x'; }";
|
2017-04-06 13:59:07 +00:00
|
|
|
test::ScriptResource script(raw_script.c_str(), strlen(raw_script.c_str()));
|
2017-07-27 11:49:37 +00:00
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2017-04-06 13:59:07 +00:00
|
|
|
i_isolate(), tracer(),
|
|
|
|
test::CreateSharedFunctionInfo(i_isolate(), &script), 100));
|
2016-08-25 10:24:53 +00:00
|
|
|
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_TRUE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kFailed, job);
|
2016-08-25 10:24:53 +00:00
|
|
|
ASSERT_TRUE(i_isolate()->has_pending_exception());
|
|
|
|
|
|
|
|
i_isolate()->clear_pending_exception();
|
|
|
|
job->ResetOnMainThread();
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kInitial, job);
|
2016-08-25 10:24:53 +00:00
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, CompileFailureToFinalize) {
|
2016-08-25 10:24:53 +00:00
|
|
|
std::string raw_script("() { var a = ");
|
2016-08-25 13:57:23 +00:00
|
|
|
for (int i = 0; i < 1000; i++) {
|
2016-08-25 10:24:53 +00:00
|
|
|
raw_script += "'x' + ";
|
|
|
|
}
|
|
|
|
raw_script += " 'x'; }";
|
2017-04-06 13:59:07 +00:00
|
|
|
test::ScriptResource script(raw_script.c_str(), strlen(raw_script.c_str()));
|
2017-07-27 11:49:37 +00:00
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2017-04-06 13:59:07 +00:00
|
|
|
i_isolate(), tracer(),
|
|
|
|
test::CreateSharedFunctionInfo(i_isolate(), &script), 50));
|
2016-08-25 10:24:53 +00:00
|
|
|
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_TRUE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kFailed, job);
|
2016-08-25 10:24:53 +00:00
|
|
|
ASSERT_TRUE(i_isolate()->has_pending_exception());
|
|
|
|
|
|
|
|
i_isolate()->clear_pending_exception();
|
|
|
|
job->ResetOnMainThread();
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kInitial, job);
|
2016-08-25 10:24:53 +00:00
|
|
|
}
|
|
|
|
|
2016-09-06 13:34:31 +00:00
|
|
|
class CompileTask : public Task {
|
|
|
|
public:
|
2017-07-27 11:49:37 +00:00
|
|
|
CompileTask(CompilerDispatcherJob* job, base::Semaphore* semaphore)
|
2016-09-06 13:34:31 +00:00
|
|
|
: job_(job), semaphore_(semaphore) {}
|
|
|
|
~CompileTask() override {}
|
|
|
|
|
|
|
|
void Run() override {
|
2017-07-04 08:55:45 +00:00
|
|
|
job_->StepNextOnBackgroundThread();
|
|
|
|
ASSERT_FALSE(job_->IsFailed());
|
2016-09-06 13:34:31 +00:00
|
|
|
semaphore_->Signal();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2017-07-27 11:49:37 +00:00
|
|
|
CompilerDispatcherJob* job_;
|
2016-09-06 13:34:31 +00:00
|
|
|
base::Semaphore* semaphore_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(CompileTask);
|
|
|
|
};
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, CompileOnBackgroundThread) {
|
2016-09-06 13:34:31 +00:00
|
|
|
const char* raw_script =
|
|
|
|
"(a, b) {\n"
|
|
|
|
" var c = a + b;\n"
|
|
|
|
" function bar() { return b }\n"
|
|
|
|
" var d = { foo: 100, bar : bar() }\n"
|
|
|
|
" return bar;"
|
|
|
|
"}";
|
2017-04-06 13:59:07 +00:00
|
|
|
test::ScriptResource script(raw_script, strlen(raw_script));
|
2017-07-27 11:49:37 +00:00
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2017-04-06 13:59:07 +00:00
|
|
|
i_isolate(), tracer(),
|
|
|
|
test::CreateSharedFunctionInfo(i_isolate(), &script), 100));
|
2016-09-06 13:34:31 +00:00
|
|
|
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2016-09-06 13:34:31 +00:00
|
|
|
|
|
|
|
base::Semaphore semaphore(0);
|
|
|
|
CompileTask* background_task = new CompileTask(job.get(), &semaphore);
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kReadyToCompile, job);
|
2016-09-06 13:34:31 +00:00
|
|
|
V8::GetCurrentPlatform()->CallOnBackgroundThread(background_task,
|
|
|
|
Platform::kShortRunningTask);
|
|
|
|
semaphore.Wait();
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kDone, job);
|
2016-09-06 13:34:31 +00:00
|
|
|
|
|
|
|
job->ResetOnMainThread();
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kInitial, job);
|
2016-09-06 13:34:31 +00:00
|
|
|
}
|
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
TEST_F(CompilerDispatcherJobTest, LazyInnerFunctions) {
|
2016-12-16 12:38:17 +00:00
|
|
|
const char script[] =
|
|
|
|
"function g() {\n"
|
|
|
|
" f = function() {\n"
|
|
|
|
" e = (function() { return 42; });\n"
|
|
|
|
" return e;\n"
|
|
|
|
" };\n"
|
|
|
|
" return f;\n"
|
|
|
|
"}\n"
|
|
|
|
"g();";
|
2017-04-06 13:59:07 +00:00
|
|
|
Handle<JSFunction> f =
|
|
|
|
Handle<JSFunction>::cast(test::RunJS(isolate(), script));
|
2016-12-16 12:38:17 +00:00
|
|
|
|
2017-07-27 11:49:37 +00:00
|
|
|
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
|
2016-12-16 12:38:17 +00:00
|
|
|
i_isolate(), tracer(), handle(f->shared()), FLAG_stack_size));
|
|
|
|
|
2017-07-04 08:55:45 +00:00
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
|
|
|
job->StepNextOnMainThread();
|
|
|
|
ASSERT_FALSE(job->IsFailed());
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kDone, job);
|
2016-12-16 12:38:17 +00:00
|
|
|
|
2017-04-06 13:59:07 +00:00
|
|
|
Handle<JSFunction> e =
|
|
|
|
Handle<JSFunction>::cast(test::RunJS(isolate(), "f();"));
|
2016-12-16 12:38:17 +00:00
|
|
|
|
|
|
|
ASSERT_FALSE(e->shared()->HasBaselineCode());
|
|
|
|
|
|
|
|
job->ResetOnMainThread();
|
2017-07-27 11:49:37 +00:00
|
|
|
ASSERT_JOB_STATUS(CompileJobStatus::kInitial, job);
|
2016-12-16 12:38:17 +00:00
|
|
|
}
|
|
|
|
|
2016-07-22 12:19:50 +00:00
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|