Commit 7deb6821 authored by Wiktor Garbacz's avatar Wiktor Garbacz Committed by Commit Bot

[compiler-dispatcher] Enqueue jobs without SFI.

This a step towards using CompilerDispatcher in parallel
parsing.

BUG=v8:6093

Change-Id: I7c0dc0a5f5b25652a8aa98c94b1e069c1f081a5b
Reviewed-on: https://chromium-review.googlesource.com/473106Reviewed-by: 's avatarJochen Eisinger <jochen@chromium.org>
Commit-Queue: Wiktor Garbacz <wiktorg@google.com>
Cr-Commit-Position: refs/heads/master@{#44570}
parent f956279e
......@@ -68,7 +68,7 @@ CompilerDispatcherJob::CompilerDispatcherJob(
bool module, bool is_named_expression, bool calls_eval, uint32_t hash_seed,
AccountingAllocator* zone_allocator, int compiler_hints,
const AstStringConstants* ast_string_constants,
FinishCallback* finish_callback)
CompileJobFinishCallback* finish_callback)
: status_(CompileJobStatus::kReadyToParse),
isolate_(nullptr),
tracer_(tracer),
......
......@@ -43,14 +43,14 @@ enum class CompileJobStatus {
kDone,
};
class V8_EXPORT_PRIVATE CompilerDispatcherJob {
class CompileJobFinishCallback {
public:
class FinishCallback {
public:
virtual ~FinishCallback() {}
virtual void ParseFinished(std::unique_ptr<ParseInfo> parse_info) = 0;
};
virtual ~CompileJobFinishCallback() {}
virtual void ParseFinished(std::unique_ptr<ParseInfo> parse_info) = 0;
};
class V8_EXPORT_PRIVATE CompilerDispatcherJob {
public:
// Creates a CompilerDispatcherJob in the initial state.
CompilerDispatcherJob(Isolate* isolate, CompilerDispatcherTracer* tracer,
Handle<SharedFunctionInfo> shared,
......@@ -65,7 +65,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob {
uint32_t hash_seed, AccountingAllocator* zone_allocator,
int compiler_hints,
const AstStringConstants* ast_string_constants,
FinishCallback* finish_callback);
CompileJobFinishCallback* finish_callback);
// Creates a CompilerDispatcherJob in the analyzed state.
CompilerDispatcherJob(Isolate* isolate, CompilerDispatcherTracer* tracer,
Handle<Script> script,
......@@ -79,6 +79,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob {
CompileJobStatus status() const { return status_; }
bool has_context() const { return !context_.is_null(); }
Context* context() { return *context_; }
Handle<SharedFunctionInfo> shared() const { return shared_; }
......@@ -135,7 +136,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcherJob {
Handle<String> wrapper_; // Global handle.
std::unique_ptr<v8::String::ExternalStringResourceBase> source_wrapper_;
size_t max_stack_size_;
FinishCallback* finish_callback_ = nullptr;
CompileJobFinishCallback* finish_callback_ = nullptr;
// Members required for parsing.
std::unique_ptr<UnicodeCache> unicode_cache_;
......
......@@ -28,6 +28,7 @@ enum class MemoryPressureLevel;
namespace internal {
class CancelableTaskManager;
class CompileJobFinishCallback;
class CompilerDispatcherJob;
class CompilerDispatcherTracer;
class DeferredHandles;
......@@ -81,6 +82,13 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
// Enqueue a job for parse and compile. Returns true if a job was enqueued.
bool Enqueue(Handle<SharedFunctionInfo> function);
// Enqueue a job for initial parse. Returns true if a job was enqueued.
bool Enqueue(Handle<String> source, int start_pos, int end_position,
LanguageMode language_mode, int function_literal_id, bool native,
bool module, bool is_named_expression, bool calls_eval,
int compiler_hints, CompileJobFinishCallback* finish_callback,
JobId* job_id);
// Like Enqueue, but also advances the job so that it can potentially
// continue running on a background thread (if at all possible). Returns
// true if the job was enqueued.
......@@ -122,7 +130,9 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
private:
FRIEND_TEST(CompilerDispatcherTest, EnqueueJob);
FRIEND_TEST(CompilerDispatcherTest, EnqueueWithoutSFI);
FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStep);
FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStepWithoutSFI);
FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStepTwice);
FRIEND_TEST(CompilerDispatcherTest, EnqueueParsed);
FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStepParsed);
......@@ -142,6 +152,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
void WaitForJobIfRunningOnBackground(CompilerDispatcherJob* job);
void AbortInactiveJobs();
bool CanEnqueue();
bool CanEnqueue(Handle<SharedFunctionInfo> function);
JobMap::const_iterator GetJobFor(Handle<SharedFunctionInfo> shared) const;
void ConsiderJobForBackgroundProcessing(CompilerDispatcherJob* job);
......@@ -152,6 +163,11 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
void DoBackgroundWork();
void DoIdleWork(double deadline_in_seconds);
JobId Enqueue(std::unique_ptr<CompilerDispatcherJob> job);
JobId EnqueueAndStep(std::unique_ptr<CompilerDispatcherJob> job);
// Returns job if not removed otherwise iterator following the removed job.
JobMap::const_iterator RemoveIfFinished(JobMap::const_iterator job);
// Returns iterator following the removed job.
JobMap::const_iterator RemoveJob(JobMap::const_iterator job);
Isolate* isolate_;
Platform* platform_;
......
......@@ -4,14 +4,16 @@
#include "test/unittests/compiler-dispatcher/compiler-dispatcher-helper.h"
#include <memory>
#include "include/v8.h"
#include "src/api.h"
#include "src/handles.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/objects.h"
namespace v8 {
namespace internal {
namespace test {
Handle<Object> RunJS(v8::Isolate* isolate, const char* script) {
return Utils::OpenHandle(
......@@ -24,5 +26,35 @@ Handle<Object> RunJS(v8::Isolate* isolate, const char* script) {
.ToLocalChecked());
}
Handle<String> CreateSource(Isolate* isolate,
ExternalOneByteString::Resource* maybe_resource) {
static const char test_script[] = "(x) { x*x; }";
if (maybe_resource) {
return isolate->factory()
->NewExternalStringFromOneByte(maybe_resource)
.ToHandleChecked();
}
return isolate->factory()->NewStringFromAsciiChecked(test_script);
}
Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
Isolate* isolate,
v8::String::ExternalOneByteStringResource* maybe_resource) {
HandleScope scope(isolate);
Handle<String> source = CreateSource(isolate, maybe_resource);
Handle<Script> script = isolate->factory()->NewScript(source);
Handle<FixedArray> infos = isolate->factory()->NewFixedArray(3);
script->set_shared_function_infos(*infos);
Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
isolate->factory()->NewStringFromAsciiChecked("f"),
isolate->builtins()->CompileLazy(), false);
shared->set_end_position(source->length());
shared->set_outer_scope_info(ScopeInfo::Empty(isolate));
shared->set_function_literal_id(1);
SharedFunctionInfo::SetScript(shared, script);
return scope.CloseAndEscape(shared);
}
} // namespace test
} // namespace internal
} // namespace v8
......@@ -5,6 +5,12 @@
#ifndef V8_UNITTESTS_COMPILER_DISPATCHER_COMPILER_DISPATCHER_HELPER_H_
#define V8_UNITTESTS_COMPILER_DISPATCHER_COMPILER_DISPATCHER_HELPER_H_
#include <memory>
#include "include/v8.h"
#include "src/compiler-dispatcher/compiler-dispatcher-job.h"
#include "src/parsing/parse-info.h"
namespace v8 {
class Isolate;
......@@ -14,9 +20,46 @@ namespace internal {
class Object;
template <typename T>
class Handle;
class Isolate;
namespace test {
class ScriptResource : public v8::String::ExternalOneByteStringResource {
public:
ScriptResource(const char* data, size_t length)
: data_(data), length_(length) {}
~ScriptResource() override = default;
const char* data() const override { return data_; }
size_t length() const override { return length_; }
private:
const char* data_;
size_t length_;
DISALLOW_COPY_AND_ASSIGN(ScriptResource);
};
class FinishCallback : public CompileJobFinishCallback {
public:
void ParseFinished(std::unique_ptr<ParseInfo> result) override {
result_ = std::move(result);
}
ParseInfo* result() const { return result_.get(); }
private:
std::unique_ptr<ParseInfo> result_;
};
Handle<Object> RunJS(v8::Isolate* isolate, const char* script);
Handle<String> CreateSource(
Isolate* isolate,
v8::String::ExternalOneByteStringResource* maybe_resource);
Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
Isolate* isolate,
v8::String::ExternalOneByteStringResource* maybe_resource);
} // namespace test
} // namespace internal
} // namespace v8
......
......@@ -56,74 +56,21 @@ namespace {
const char test_script[] = "(x) { x*x; }";
class ScriptResource : public v8::String::ExternalOneByteStringResource {
public:
ScriptResource(const char* data, size_t length)
: data_(data), length_(length) {}
~ScriptResource() override = default;
const char* data() const override { return data_; }
size_t length() const override { return length_; }
private:
const char* data_;
size_t length_;
DISALLOW_COPY_AND_ASSIGN(ScriptResource);
};
Handle<String> CreateSource(Isolate* isolate,
ExternalOneByteString::Resource* maybe_resource) {
if (maybe_resource) {
return isolate->factory()
->NewExternalStringFromOneByte(maybe_resource)
.ToHandleChecked();
}
return isolate->factory()->NewStringFromAsciiChecked(test_script);
}
Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
Isolate* isolate, ExternalOneByteString::Resource* maybe_resource) {
HandleScope scope(isolate);
Handle<String> source = CreateSource(isolate, maybe_resource);
Handle<Script> script = isolate->factory()->NewScript(source);
Handle<FixedArray> infos = isolate->factory()->NewFixedArray(3);
script->set_shared_function_infos(*infos);
Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo(
isolate->factory()->NewStringFromAsciiChecked("f"),
isolate->builtins()->CompileLazy(), false);
shared->set_end_position(source->length());
shared->set_outer_scope_info(ScopeInfo::Empty(isolate));
shared->set_function_literal_id(1);
SharedFunctionInfo::SetScript(shared, script);
return scope.CloseAndEscape(shared);
}
class FinishCallback : public CompilerDispatcherJob::FinishCallback {
public:
void ParseFinished(std::unique_ptr<ParseInfo> result) override {
result_ = std::move(result);
}
ParseInfo* result() const { return result_.get(); }
private:
std::unique_ptr<ParseInfo> result_;
};
} // namespace
TEST_F(CompilerDispatcherJobTest, Construct) {
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
i_isolate(), tracer(), CreateSharedFunctionInfo(i_isolate(), nullptr),
FLAG_stack_size));
i_isolate(), tracer(),
test::CreateSharedFunctionInfo(i_isolate(), nullptr), FLAG_stack_size));
}
TEST_F(CompilerDispatcherJobTest, ConstructWithoutSFI) {
std::unique_ptr<FinishCallback> callback(new FinishCallback());
std::unique_ptr<ScriptResource> resource(
new ScriptResource(test_script, strlen(test_script)));
std::unique_ptr<test::FinishCallback> callback(new test::FinishCallback());
std::unique_ptr<test::ScriptResource> resource(
new test::ScriptResource(test_script, strlen(test_script)));
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
tracer(), FLAG_stack_size, CreateSource(i_isolate(), resource.get()), 0,
tracer(), FLAG_stack_size,
test::CreateSource(i_isolate(), resource.get()), 0,
static_cast<int>(resource->length()), SLOPPY, 1, false, false, false,
false, i_isolate()->heap()->HashSeed(), i_isolate()->allocator(),
ScriptCompiler::kNoCompileOptions, i_isolate()->ast_string_constants(),
......@@ -132,8 +79,8 @@ TEST_F(CompilerDispatcherJobTest, ConstructWithoutSFI) {
TEST_F(CompilerDispatcherJobTest, StateTransitions) {
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
i_isolate(), tracer(), CreateSharedFunctionInfo(i_isolate(), nullptr),
FLAG_stack_size));
i_isolate(), tracer(),
test::CreateSharedFunctionInfo(i_isolate(), nullptr), FLAG_stack_size));
ASSERT_TRUE(job->status() == CompileJobStatus::kInitial);
job->PrepareToParseOnMainThread();
......@@ -155,11 +102,12 @@ TEST_F(CompilerDispatcherJobTest, StateTransitions) {
}
TEST_F(CompilerDispatcherJobTest, StateTransitionsParseWithCallback) {
std::unique_ptr<FinishCallback> callback(new FinishCallback());
std::unique_ptr<ScriptResource> resource(
new ScriptResource(test_script, strlen(test_script)));
std::unique_ptr<test::FinishCallback> callback(new test::FinishCallback());
std::unique_ptr<test::ScriptResource> resource(
new test::ScriptResource(test_script, strlen(test_script)));
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
tracer(), FLAG_stack_size, CreateSource(i_isolate(), resource.get()), 0,
tracer(), FLAG_stack_size,
test::CreateSource(i_isolate(), resource.get()), 0,
static_cast<int>(resource->length()), SLOPPY, 1, false, false, false,
false, i_isolate()->heap()->HashSeed(), i_isolate()->allocator(),
ScriptCompiler::kNoCompileOptions, i_isolate()->ast_string_constants(),
......@@ -173,10 +121,10 @@ TEST_F(CompilerDispatcherJobTest, StateTransitionsParseWithCallback) {
}
TEST_F(CompilerDispatcherJobTest, SyntaxError) {
ScriptResource script("^^^", strlen("^^^"));
test::ScriptResource script("^^^", strlen("^^^"));
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
i_isolate(), tracer(), CreateSharedFunctionInfo(i_isolate(), &script),
FLAG_stack_size));
i_isolate(), tracer(),
test::CreateSharedFunctionInfo(i_isolate(), &script), FLAG_stack_size));
job->PrepareToParseOnMainThread();
job->Parse();
......@@ -194,7 +142,8 @@ TEST_F(CompilerDispatcherJobTest, ScopeChain) {
const char script[] =
"function g() { var y = 1; function f(x) { return x * y }; return f; } "
"g();";
Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script));
Handle<JSFunction> f =
Handle<JSFunction>::cast(test::RunJS(isolate(), script));
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
i_isolate(), tracer(), handle(f->shared()), FLAG_stack_size));
......@@ -232,7 +181,8 @@ TEST_F(CompilerDispatcherJobTest, CompileAndRun) {
" return f;\n"
"}\n"
"g();";
Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script));
Handle<JSFunction> f =
Handle<JSFunction>::cast(test::RunJS(isolate(), script));
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
i_isolate(), tracer(), handle(f->shared()), FLAG_stack_size));
......@@ -245,7 +195,7 @@ TEST_F(CompilerDispatcherJobTest, CompileAndRun) {
ASSERT_TRUE(job->FinalizeCompilingOnMainThread());
ASSERT_TRUE(job->status() == CompileJobStatus::kDone);
Smi* value = Smi::cast(*RunJS(isolate(), "f(100);"));
Smi* value = Smi::cast(*test::RunJS(isolate(), "f(100);"));
ASSERT_TRUE(value == Smi::FromInt(160));
job->ResetOnMainThread();
......@@ -258,10 +208,10 @@ TEST_F(CompilerDispatcherJobTest, CompileFailureToAnalyse) {
raw_script += "'x' + ";
}
raw_script += " 'x'; }";
ScriptResource script(raw_script.c_str(), strlen(raw_script.c_str()));
test::ScriptResource script(raw_script.c_str(), strlen(raw_script.c_str()));
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
i_isolate(), tracer(), CreateSharedFunctionInfo(i_isolate(), &script),
100));
i_isolate(), tracer(),
test::CreateSharedFunctionInfo(i_isolate(), &script), 100));
job->PrepareToParseOnMainThread();
job->Parse();
......@@ -281,10 +231,10 @@ TEST_F(CompilerDispatcherJobTest, CompileFailureToFinalize) {
raw_script += "'x' + ";
}
raw_script += " 'x'; }";
ScriptResource script(raw_script.c_str(), strlen(raw_script.c_str()));
test::ScriptResource script(raw_script.c_str(), strlen(raw_script.c_str()));
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
i_isolate(), tracer(), CreateSharedFunctionInfo(i_isolate(), &script),
50));
i_isolate(), tracer(),
test::CreateSharedFunctionInfo(i_isolate(), &script), 50));
job->PrepareToParseOnMainThread();
job->Parse();
......@@ -326,10 +276,10 @@ TEST_F(CompilerDispatcherJobTest, CompileOnBackgroundThread) {
" var d = { foo: 100, bar : bar() }\n"
" return bar;"
"}";
ScriptResource script(raw_script, strlen(raw_script));
test::ScriptResource script(raw_script, strlen(raw_script));
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
i_isolate(), tracer(), CreateSharedFunctionInfo(i_isolate(), &script),
100));
i_isolate(), tracer(),
test::CreateSharedFunctionInfo(i_isolate(), &script), 100));
job->PrepareToParseOnMainThread();
job->Parse();
......@@ -359,7 +309,8 @@ TEST_F(CompilerDispatcherJobTest, LazyInnerFunctions) {
" return f;\n"
"}\n"
"g();";
Handle<JSFunction> f = Handle<JSFunction>::cast(RunJS(isolate(), script));
Handle<JSFunction> f =
Handle<JSFunction>::cast(test::RunJS(isolate(), script));
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob(
i_isolate(), tracer(), handle(f->shared()), FLAG_stack_size));
......@@ -373,7 +324,8 @@ TEST_F(CompilerDispatcherJobTest, LazyInnerFunctions) {
ASSERT_TRUE(job->FinalizeCompilingOnMainThread());
ASSERT_TRUE(job->status() == CompileJobStatus::kDone);
Handle<JSFunction> e = Handle<JSFunction>::cast(RunJS(isolate(), "f();"));
Handle<JSFunction> e =
Handle<JSFunction>::cast(test::RunJS(isolate(), "f();"));
ASSERT_FALSE(e->shared()->HasBaselineCode());
......
......@@ -71,8 +71,8 @@ TEST_F(OptimizingCompileDispatcherTest, Construct) {
}
TEST_F(OptimizingCompileDispatcherTest, NonBlockingFlush) {
Handle<JSFunction> fun = Handle<JSFunction>::cast(
RunJS(isolate(), "function f() { function g() {}; return g;}; f();"));
Handle<JSFunction> fun = Handle<JSFunction>::cast(test::RunJS(
isolate(), "function f() { function g() {}; return g;}; f();"));
BlockingCompilationJob* job = new BlockingCompilationJob(i_isolate(), fun);
OptimizingCompileDispatcher dispatcher(i_isolate());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment