Commit 912577a3 authored by jochen's avatar jochen Committed by Commit bot

Reland "Hook up compiler dispatcher jobs to lazy parser."

Original issue description:
> The lazy parser actually parses eagerly. It's called lazy because it
> parses functions that were previously lazy parsed. D'uh.
>
> BUG=v8:5215
> R=marja@chromium.org
>
> Review-Url: https://codereview.chromium.org/2220463002
> Cr-Commit-Position: refs/heads/master@{#38375}

BUG=v8:5215
TBR=marja@chromium.org

Review-Url: https://codereview.chromium.org/2218033003
Cr-Commit-Position: refs/heads/master@{#38387}
parent 682a8f71
...@@ -46,6 +46,8 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() { ...@@ -46,6 +46,8 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() {
zone_.reset(new Zone(isolate_->allocator())); zone_.reset(new Zone(isolate_->allocator()));
Handle<SharedFunctionInfo> shared(function_->shared(), isolate_); Handle<SharedFunctionInfo> shared(function_->shared(), isolate_);
Handle<Script> script(Script::cast(shared->script()), isolate_); Handle<Script> script(Script::cast(shared->script()), isolate_);
DCHECK(script->type() != Script::TYPE_NATIVE);
Handle<String> source(String::cast(script->source()), isolate_); Handle<String> source(String::cast(script->source()), isolate_);
if (source->IsExternalTwoByteString()) { if (source->IsExternalTwoByteString()) {
character_stream_.reset(new ExternalTwoByteStringUtf16CharacterStream( character_stream_.reset(new ExternalTwoByteStringUtf16CharacterStream(
...@@ -66,12 +68,24 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() { ...@@ -66,12 +68,24 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() {
parse_info_.reset(new ParseInfo(zone_.get())); parse_info_.reset(new ParseInfo(zone_.get()));
parse_info_->set_isolate(isolate_); parse_info_->set_isolate(isolate_);
parse_info_->set_character_stream(character_stream_.get()); parse_info_->set_character_stream(character_stream_.get());
parse_info_->set_lazy();
parse_info_->set_hash_seed(isolate_->heap()->HashSeed()); parse_info_->set_hash_seed(isolate_->heap()->HashSeed());
parse_info_->set_is_named_expression(shared->is_named_expression());
parse_info_->set_calls_eval(shared->scope_info()->CallsEval());
parse_info_->set_compiler_hints(shared->compiler_hints());
parse_info_->set_start_position(shared->start_position());
parse_info_->set_end_position(shared->end_position());
parse_info_->set_unicode_cache(unicode_cache_.get()); parse_info_->set_unicode_cache(unicode_cache_.get());
parse_info_->set_language_mode(shared->language_mode());
parser_.reset(new Parser(parse_info_.get())); parser_.reset(new Parser(parse_info_.get()));
parser_->DeserializeScopeChain( parser_->DeserializeScopeChain(
parse_info_.get(), handle(function_->context(), isolate_), parse_info_.get(), handle(function_->context(), isolate_),
Scope::DeserializationMode::kDeserializeOffHeap); Scope::DeserializationMode::kDeserializeOffHeap);
Handle<String> name(String::cast(shared->name()));
parse_info_->set_function_name(
parse_info_->ast_value_factory()->GetString(name));
status_ = CompileJobStatus::kReadyToParse; status_ = CompileJobStatus::kReadyToParse;
} }
......
...@@ -58,6 +58,7 @@ ParseInfo::ParseInfo(Zone* zone) ...@@ -58,6 +58,7 @@ ParseInfo::ParseInfo(Zone* zone)
isolate_(nullptr), isolate_(nullptr),
cached_data_(nullptr), cached_data_(nullptr),
ast_value_factory_(nullptr), ast_value_factory_(nullptr),
function_name_(nullptr),
literal_(nullptr), literal_(nullptr),
scope_(nullptr) {} scope_(nullptr) {}
...@@ -1117,8 +1118,8 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) { ...@@ -1117,8 +1118,8 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) {
source, shared_info->start_position(), shared_info->end_position())); source, shared_info->start_position(), shared_info->end_position()));
} }
Handle<String> name(String::cast(shared_info->name())); Handle<String> name(String::cast(shared_info->name()));
result = DoParseLazy(isolate, info, ast_value_factory()->GetString(name), result =
stream.get()); DoParseLazy(info, ast_value_factory()->GetString(name), stream.get());
if (result != nullptr) { if (result != nullptr) {
Handle<String> inferred_name(shared_info->inferred_name()); Handle<String> inferred_name(shared_info->inferred_name());
result->set_inferred_name(inferred_name); result->set_inferred_name(inferred_name);
...@@ -1145,7 +1146,7 @@ static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) { ...@@ -1145,7 +1146,7 @@ static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
return FunctionLiteral::kAnonymousExpression; return FunctionLiteral::kAnonymousExpression;
} }
FunctionLiteral* Parser::DoParseLazy(Isolate* isolate, ParseInfo* info, FunctionLiteral* Parser::DoParseLazy(ParseInfo* info,
const AstRawString* raw_name, const AstRawString* raw_name,
Utf16CharacterStream* source) { Utf16CharacterStream* source) {
scanner_.Initialize(source); scanner_.Initialize(source);
...@@ -5513,7 +5514,6 @@ void Parser::ParseOnBackground(ParseInfo* info) { ...@@ -5513,7 +5514,6 @@ void Parser::ParseOnBackground(ParseInfo* info) {
DCHECK(info->literal() == NULL); DCHECK(info->literal() == NULL);
FunctionLiteral* result = NULL; FunctionLiteral* result = NULL;
fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
CompleteParserRecorder recorder; CompleteParserRecorder recorder;
if (produce_cached_parse_data()) log_ = &recorder; if (produce_cached_parse_data()) log_ = &recorder;
...@@ -5529,7 +5529,6 @@ void Parser::ParseOnBackground(ParseInfo* info) { ...@@ -5529,7 +5529,6 @@ void Parser::ParseOnBackground(ParseInfo* info) {
info->source_stream_encoding())); info->source_stream_encoding()));
stream_ptr = stream.get(); stream_ptr = stream.get();
} }
scanner_.Initialize(stream_ptr);
DCHECK(info->context().is_null() || info->context()->IsNativeContext()); DCHECK(info->context().is_null() || info->context()->IsNativeContext());
DCHECK(original_scope_); DCHECK(original_scope_);
...@@ -5540,7 +5539,13 @@ void Parser::ParseOnBackground(ParseInfo* info) { ...@@ -5540,7 +5539,13 @@ void Parser::ParseOnBackground(ParseInfo* info) {
// don't). We work around this by storing all the scopes which need their end // don't). We work around this by storing all the scopes which need their end
// position set at the end of the script (the top scope and possible eval // position set at the end of the script (the top scope and possible eval
// scopes) and set their end position after we know the script length. // scopes) and set their end position after we know the script length.
if (info->is_lazy()) {
result = DoParseLazy(info, info->function_name(), stream_ptr);
} else {
fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
scanner_.Initialize(stream_ptr);
result = DoParseProgram(info); result = DoParseProgram(info);
}
info->set_literal(result); info->set_literal(result);
......
...@@ -112,6 +112,11 @@ class ParseInfo { ...@@ -112,6 +112,11 @@ class ParseInfo {
ast_value_factory_ = ast_value_factory; ast_value_factory_ = ast_value_factory;
} }
const AstRawString* function_name() const { return function_name_; }
void set_function_name(const AstRawString* function_name) {
function_name_ = function_name;
}
FunctionLiteral* literal() { return literal_; } FunctionLiteral* literal() { return literal_; }
void set_literal(FunctionLiteral* literal) { literal_ = literal; } void set_literal(FunctionLiteral* literal) { literal_ = literal; }
...@@ -225,6 +230,7 @@ class ParseInfo { ...@@ -225,6 +230,7 @@ class ParseInfo {
//----------- Inputs+Outputs of parsing and scope analysis ----------------- //----------- Inputs+Outputs of parsing and scope analysis -----------------
ScriptData** cached_data_; // used if available, populated if requested. ScriptData** cached_data_; // used if available, populated if requested.
AstValueFactory* ast_value_factory_; // used if available, otherwise new. AstValueFactory* ast_value_factory_; // used if available, otherwise new.
const AstRawString* function_name_;
//----------- Outputs of parsing and scope analysis ------------------------ //----------- Outputs of parsing and scope analysis ------------------------
FunctionLiteral* literal_; // produced by full parser. FunctionLiteral* literal_; // produced by full parser.
...@@ -776,8 +782,7 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -776,8 +782,7 @@ class Parser : public ParserBase<ParserTraits> {
FunctionLiteral* ParseProgram(Isolate* isolate, ParseInfo* info); FunctionLiteral* ParseProgram(Isolate* isolate, ParseInfo* info);
FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info); FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info);
FunctionLiteral* DoParseLazy(Isolate* isolate, ParseInfo* info, FunctionLiteral* DoParseLazy(ParseInfo* info, const AstRawString* raw_name,
const AstRawString* raw_name,
Utf16CharacterStream* source); Utf16CharacterStream* source);
// Called by ParseProgram after setting up the scanner. // Called by ParseProgram after setting up the scanner.
......
...@@ -4,9 +4,13 @@ ...@@ -4,9 +4,13 @@
#include <memory> #include <memory>
#include "include/v8.h"
#include "src/api.h"
#include "src/ast/scopes.h"
#include "src/compiler-dispatcher/compiler-dispatcher-job.h" #include "src/compiler-dispatcher/compiler-dispatcher-job.h"
#include "src/flags.h" #include "src/flags.h"
#include "src/isolate-inl.h" #include "src/isolate-inl.h"
#include "src/parsing/parser.h"
#include "test/unittests/test-utils.h" #include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -17,7 +21,7 @@ typedef TestWithContext CompilerDispatcherJobTest; ...@@ -17,7 +21,7 @@ typedef TestWithContext CompilerDispatcherJobTest;
namespace { namespace {
const char test_script[] = "x*x"; const char test_script[] = "(x) { x*x; }";
class ScriptResource : public v8::String::ExternalOneByteStringResource { class ScriptResource : public v8::String::ExternalOneByteStringResource {
public: public:
...@@ -108,6 +112,44 @@ TEST_F(CompilerDispatcherJobTest, SyntaxError) { ...@@ -108,6 +112,44 @@ TEST_F(CompilerDispatcherJobTest, SyntaxError) {
job->ReportErrorsOnMainThread(); job->ReportErrorsOnMainThread();
ASSERT_TRUE(job->status() == CompileJobStatus::kDone); ASSERT_TRUE(job->status() == CompileJobStatus::kDone);
ASSERT_TRUE(i_isolate()->has_pending_exception()); ASSERT_TRUE(i_isolate()->has_pending_exception());
i_isolate()->clear_pending_exception();
}
TEST_F(CompilerDispatcherJobTest, ScopeChain) {
const char script[] =
"function g() { var g = 1; function f(x) { return x * g }; return f; } "
"g();";
Handle<JSFunction> f = Handle<JSFunction>::cast(Utils::OpenHandle(
*v8::Script::Compile(isolate()->GetCurrentContext(),
v8::String::NewFromUtf8(isolate(), script,
v8::NewStringType::kNormal)
.ToLocalChecked())
.ToLocalChecked()
->Run(isolate()->GetCurrentContext())
.ToLocalChecked()));
std::unique_ptr<CompilerDispatcherJob> job(
new CompilerDispatcherJob(i_isolate(), f, FLAG_stack_size));
job->PrepareToParseOnMainThread();
job->Parse();
job->FinalizeParsingOnMainThread();
ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToCompile);
const AstRawString* var_x =
job->parse_info_->ast_value_factory()->GetOneByteString("x");
Variable* var = job->parse_info_->literal()->scope()->Lookup(var_x);
ASSERT_TRUE(var);
ASSERT_TRUE(var->IsUnallocated());
const AstRawString* var_g =
job->parse_info_->ast_value_factory()->GetOneByteString("g");
var = job->parse_info_->literal()->scope()->Lookup(var_g);
ASSERT_TRUE(var);
ASSERT_TRUE(var->IsContextSlot());
job->ResetOnMainThread();
ASSERT_TRUE(job->status() == CompileJobStatus::kInitial);
} }
} // namespace internal } // namespace internal
......
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