Commit 265e87e5 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Compiler] Seperate AttachOuterScopeInfo out of DeclarationScope::Analyze

Splits out AttachOuterScopeInfo from DeclarationScope::Analyze and attaches
the outer scope info after parsing has completed (when parsing on the main
thread, which is the only time we have an outer scope info) instead of
during Compiler::Analyse().

BUG=v8:5203

TBR=yangguo@chromium.org

Change-Id: Idd8d2409fb20f09a9f6bbf5cff7e6edcf90077d7
Reviewed-on: https://chromium-review.googlesource.com/605889
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47243}
parent ef0e8359
......@@ -622,32 +622,34 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
}
}
void DeclarationScope::Analyze(ParseInfo* info, Isolate* isolate) {
RuntimeCallTimerScope runtimeTimer(isolate,
&RuntimeCallStats::CompileScopeAnalysis);
DCHECK(info->literal() != NULL);
DeclarationScope* scope = info->literal()->scope();
DCHECK(scope->scope_info_.is_null());
void DeclarationScope::AttachOuterScopeInfo(ParseInfo* info, Isolate* isolate) {
DCHECK(scope_info_.is_null());
Handle<ScopeInfo> outer_scope_info;
if (info->maybe_outer_scope_info().ToHandle(&outer_scope_info)) {
// If we have a scope info we will potentially need to lookup variable names
// on the scope info as internalized strings, so make sure ast_value_factory
// is internalized.
info->ast_value_factory()->Internalize(isolate);
if (scope->outer_scope()) {
if (outer_scope()) {
DeclarationScope* script_scope = new (info->zone())
DeclarationScope(info->zone(), info->ast_value_factory());
info->set_script_scope(script_scope);
scope->ReplaceOuterScope(Scope::DeserializeScopeChain(
ReplaceOuterScope(Scope::DeserializeScopeChain(
info->zone(), *outer_scope_info, script_scope,
info->ast_value_factory(),
Scope::DeserializationMode::kIncludingVariables));
} else {
DCHECK_EQ(outer_scope_info->scope_type(), SCRIPT_SCOPE);
scope->SetScriptScopeInfo(outer_scope_info);
SetScriptScopeInfo(outer_scope_info);
}
}
}
void DeclarationScope::Analyze(ParseInfo* info) {
RuntimeCallTimerScope runtimeTimer(info->runtime_call_stats(),
&RuntimeCallStats::CompileScopeAnalysis);
DCHECK(info->literal() != NULL);
DeclarationScope* scope = info->literal()->scope();
if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
AstNodeFactory factory(info->ast_value_factory(), info->zone());
......
......@@ -858,10 +858,14 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
return sloppy_block_function_map_;
}
// Replaces the outer scope with the outer_scope_info in |info| if there is
// one.
void AttachOuterScopeInfo(ParseInfo* info, Isolate* isolate);
// Compute top scope and allocate variables. For lazy compilation the top
// scope only contains the single lazily compiled function, so this
// doesn't re-allocate variables repeatedly.
static void Analyze(ParseInfo* info, Isolate* isolate);
static void Analyze(ParseInfo* info);
// To be called during parsing. Do just enough scope analysis that we can
// discard the Scope contents for lazily compiled functions. In particular,
......
......@@ -365,22 +365,25 @@ void UnoptimizedCompileJob::FinalizeParsingOnMainThread(Isolate* isolate) {
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) {
parser_->ReportErrors(isolate, script);
status_ = Status::kFailed;
} else {
parse_info_->literal()->scope()->AttachOuterScopeInfo(parse_info_.get(),
isolate);
status_ = Status::kReadyToAnalyze;
}
parser_->UpdateStatistics(isolate, script);
parse_info_->UpdateStatisticsAfterBackgroundParse(isolate);
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);
}
parser_->HandleSourceURLComments(isolate, script);
parse_info_->set_character_stream(nullptr);
......@@ -399,7 +402,7 @@ void UnoptimizedCompileJob::AnalyzeOnMainThread(Isolate* isolate) {
PrintF("UnoptimizedCompileJob[%p]: Analyzing\n", static_cast<void*>(this));
}
if (Compiler::Analyze(parse_info_.get(), isolate)) {
if (Compiler::Analyze(parse_info_.get())) {
status_ = Status::kAnalyzed;
} else {
status_ = Status::kFailed;
......
......@@ -456,7 +456,7 @@ Handle<SharedFunctionInfo> CompileUnoptimizedCode(
DCHECK(AllowCompilation::IsAllowed(isolate));
Compiler::EagerInnerFunctionLiterals inner_literals;
if (!Compiler::Analyze(parse_info, isolate, &inner_literals)) {
if (!Compiler::Analyze(parse_info, &inner_literals)) {
if (!isolate->has_pending_exception()) isolate->StackOverflow();
return Handle<SharedFunctionInfo>::null();
}
......@@ -1034,13 +1034,13 @@ Handle<SharedFunctionInfo> CompileToplevel(
// ----------------------------------------------------------------------------
// Implementation of Compiler
bool Compiler::Analyze(ParseInfo* parse_info, Isolate* isolate,
bool Compiler::Analyze(ParseInfo* parse_info,
EagerInnerFunctionLiterals* eager_literals) {
DCHECK_NOT_NULL(parse_info->literal());
RuntimeCallTimerScope runtimeTimer(isolate,
RuntimeCallTimerScope runtimeTimer(parse_info->runtime_call_stats(),
&RuntimeCallStats::CompileAnalyse);
if (!Rewriter::Rewrite(parse_info)) return false;
DeclarationScope::Analyze(parse_info, isolate);
DeclarationScope::Analyze(parse_info);
if (!Renumber(parse_info, eager_literals)) return false;
return true;
}
......@@ -1051,7 +1051,7 @@ bool Compiler::ParseAndAnalyze(ParseInfo* parse_info,
if (!parsing::ParseAny(parse_info, shared_info, isolate)) {
return false;
}
return Compiler::Analyze(parse_info, isolate);
return Compiler::Analyze(parse_info);
}
bool Compiler::Compile(Handle<JSFunction> function, ClearExceptionFlag flag) {
......
......@@ -73,7 +73,7 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
Isolate* isolate);
// Rewrite, analyze scopes, and renumber. If |eager_literals| is non-null, it
// is appended with inner function literals which should be eagerly compiled.
static bool Analyze(ParseInfo* parse_info, Isolate* isolate,
static bool Analyze(ParseInfo* parse_info,
EagerInnerFunctionLiterals* eager_literals = nullptr);
// Ensures that bytecode is generated, calls ParseAndAnalyze internally.
static bool EnsureBytecode(ParseInfo* parse_info, Isolate* isolate,
......
......@@ -122,7 +122,7 @@ void ScopeIterator::TryParseAndRetrieveScopes(ScopeIterator::Option option) {
CollectNonLocals(info.get(), scope);
}
if (!ignore_nested_scopes) {
DeclarationScope::Analyze(info.get(), isolate_);
DeclarationScope::Analyze(info.get());
DeclarationScope::AllocateScopeInfos(info.get(), isolate_,
AnalyzeMode::kDebugger);
RetrieveScopeChain(scope);
......
......@@ -31,6 +31,7 @@ bool ParseProgram(ParseInfo* info, Isolate* isolate) {
if (result == nullptr) {
parser.ReportErrors(isolate, info->script());
} else {
result->scope()->AttachOuterScopeInfo(info, isolate);
info->set_language_mode(info->literal()->language_mode());
}
parser.UpdateStatistics(isolate, info->script());
......@@ -53,6 +54,8 @@ bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
info->set_literal(result);
if (result == nullptr) {
parser.ReportErrors(isolate, info->script());
} else {
result->scope()->AttachOuterScopeInfo(info, isolate);
}
parser.UpdateStatistics(isolate, info->script());
return (result != nullptr);
......
......@@ -42,7 +42,7 @@ struct TestHelper : public HandleAndZoneScope {
info.isolate()));
info.set_literal(parse_info.literal());
CHECK(Rewriter::Rewrite(&parse_info));
DeclarationScope::Analyze(&parse_info, info.isolate());
DeclarationScope::Analyze(&parse_info);
DeclarationScope* scope = info.literal()->scope();
AstValueFactory* factory = parse_info.ast_value_factory();
......
......@@ -693,7 +693,7 @@ TEST(PreParserScopeAnalysis) {
eager_normal.set_allow_lazy_parsing(false);
CHECK(i::parsing::ParseProgram(&eager_normal, isolate));
CHECK(i::Compiler::Analyze(&eager_normal, isolate));
CHECK(i::Compiler::Analyze(&eager_normal));
// Compare the allocation of the variables in two cases: 1) normal scope
// allocation 2) allocation based on the preparse data.
......
......@@ -835,7 +835,7 @@ TEST(ScopeUsesArgumentsSuperThis) {
CHECK(i::parsing::ParseProgram(&info, isolate));
CHECK(i::Rewriter::Rewrite(&info));
info.ast_value_factory()->Internalize(isolate);
i::DeclarationScope::Analyze(&info, isolate);
i::DeclarationScope::Analyze(&info);
i::DeclarationScope::AllocateScopeInfos(&info, isolate,
i::AnalyzeMode::kRegular);
CHECK(info.literal() != NULL);
......@@ -3375,7 +3375,7 @@ TEST(InnerAssignment) {
info->set_allow_lazy_parsing(false);
CHECK(i::parsing::ParseProgram(info.get(), isolate));
}
CHECK(i::Compiler::Analyze(info.get(), isolate));
CHECK(i::Compiler::Analyze(info.get()));
CHECK(info->literal() != NULL);
i::Scope* scope = info->literal()->scope();
......@@ -3479,7 +3479,7 @@ TEST(MaybeAssignedParameters) {
info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(shared));
info->set_allow_lazy_parsing(allow_lazy);
CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
CHECK(i::Compiler::Analyze(info.get(), isolate));
CHECK(i::Compiler::Analyze(info.get()));
CHECK_NOT_NULL(info->literal());
i::Scope* scope = info->literal()->scope();
......@@ -3518,7 +3518,7 @@ static void TestMaybeAssigned(Input input, const char* variable, bool module,
info->set_allow_lazy_parsing(allow_lazy_parsing);
CHECK(i::parsing::ParseProgram(info.get(), isolate));
CHECK(i::Compiler::Analyze(info.get(), isolate));
CHECK(i::Compiler::Analyze(info.get()));
CHECK_NOT_NULL(info->literal());
i::Scope* scope = info->literal()->scope();
......@@ -6726,7 +6726,7 @@ TEST(ModuleParsingInternals) {
i::ParseInfo info(script);
info.set_module();
CHECK(i::parsing::ParseProgram(&info, isolate));
CHECK(i::Compiler::Analyze(&info, isolate));
CHECK(i::Compiler::Analyze(&info));
i::FunctionLiteral* func = info.literal();
i::ModuleScope* module_scope = func->scope()->AsModuleScope();
i::Scope* outer_scope = module_scope->outer_scope();
......@@ -9695,7 +9695,7 @@ TEST(NoPessimisticContextAllocation) {
i::ParseInfo info(script);
CHECK(i::parsing::ParseProgram(&info, isolate));
CHECK(i::Compiler::Analyze(&info, isolate));
CHECK(i::Compiler::Analyze(&info));
CHECK(info.literal() != NULL);
i::Scope* scope = info.literal()->scope()->inner_scope();
......@@ -10270,7 +10270,7 @@ TEST(LexicalLoopVariable) {
info.set_allow_lazy_parsing(false);
CHECK(i::parsing::ParseProgram(&info, isolate));
CHECK(i::Rewriter::Rewrite(&info));
i::DeclarationScope::Analyze(&info, isolate);
i::DeclarationScope::Analyze(&info);
i::DeclarationScope::AllocateScopeInfos(&info, isolate,
i::AnalyzeMode::kRegular);
CHECK(info.literal() != NULL);
......
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