Commit 06f05ec2 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[parser] Skipping inner funcs: make more functions skippable.

- Enable aggressive lazy inner funcs (make non-declaration funcs lazy, ie let f =
  function() { ... } when --experimental-preparser-scope-analysis is on.
- Turn on variable tracking for lazy top level functions: this makes their inner
  functions skippable.
- Test fix for an testing bug uncovered by this work: when restoring the data
  for the relevant scope, don't assume it's the outermost scope for which we
  have data.
- Fix: if we abort lazy parsing a function, we shouldn't produce any data for
  it.

BUG=v8:5516

Change-Id: I0606fbabb5886dc57dbb53ab5f3fb894ff5d032e
Reviewed-on: https://chromium-review.googlesource.com/518165Reviewed-by: 's avatarDaniel Vogelheim <vogelheim@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45615}
parent 153514bd
...@@ -1530,8 +1530,10 @@ void DeclarationScope::AnalyzePartially( ...@@ -1530,8 +1530,10 @@ void DeclarationScope::AnalyzePartially(
PreParsedScopeData* preparsed_scope_data) { PreParsedScopeData* preparsed_scope_data) {
DCHECK(!force_eager_compilation_); DCHECK(!force_eager_compilation_);
VariableProxy* unresolved = nullptr; VariableProxy* unresolved = nullptr;
bool need_preparsed_scope_data = FLAG_experimental_preparser_scope_analysis &&
preparsed_scope_data->Producing();
if (!outer_scope_->is_script_scope()) { if (!outer_scope_->is_script_scope() || need_preparsed_scope_data) {
// Try to resolve unresolved variables for this Scope and migrate those // Try to resolve unresolved variables for this Scope and migrate those
// which cannot be resolved inside. It doesn't make sense to try to resolve // which cannot be resolved inside. It doesn't make sense to try to resolve
// them in the outer Scopes here, because they are incomplete. // them in the outer Scopes here, because they are incomplete.
...@@ -1549,8 +1551,7 @@ void DeclarationScope::AnalyzePartially( ...@@ -1549,8 +1551,7 @@ void DeclarationScope::AnalyzePartially(
arguments_ = nullptr; arguments_ = nullptr;
} }
if (FLAG_experimental_preparser_scope_analysis && if (need_preparsed_scope_data) {
preparsed_scope_data->Producing()) {
// Store the information needed for allocating the locals of this scope // Store the information needed for allocating the locals of this scope
// and its inner scopes. // and its inner scopes.
preparsed_scope_data->SaveData(this); preparsed_scope_data->SaveData(this);
......
...@@ -965,7 +965,8 @@ DEFINE_BOOL(aggressive_lazy_inner_functions, false, ...@@ -965,7 +965,8 @@ DEFINE_BOOL(aggressive_lazy_inner_functions, false,
DEFINE_IMPLICATION(aggressive_lazy_inner_functions, lazy_inner_functions) DEFINE_IMPLICATION(aggressive_lazy_inner_functions, lazy_inner_functions)
DEFINE_BOOL(experimental_preparser_scope_analysis, false, DEFINE_BOOL(experimental_preparser_scope_analysis, false,
"perform scope analysis for preparsed inner functions") "perform scope analysis for preparsed inner functions")
DEFINE_IMPLICATION(experimental_preparser_scope_analysis, lazy_inner_functions) DEFINE_IMPLICATION(experimental_preparser_scope_analysis,
aggressive_lazy_inner_functions)
// simulator-arm.cc, simulator-arm64.cc and simulator-mips.cc // simulator-arm.cc, simulator-arm64.cc and simulator-mips.cc
DEFINE_BOOL(trace_sim, false, "Trace simulator execution") DEFINE_BOOL(trace_sim, false, "Trace simulator execution")
......
...@@ -142,7 +142,7 @@ void PreParsedScopeData::RestoreData(Scope* scope, uint32_t* index_ptr) const { ...@@ -142,7 +142,7 @@ void PreParsedScopeData::RestoreData(Scope* scope, uint32_t* index_ptr) const {
DCHECK_EQ(data.uses_super_property, DCHECK_EQ(data.uses_super_property,
scope->AsDeclarationScope()->uses_super_property()); scope->AsDeclarationScope()->uses_super_property());
uint32_t index_from_data = 0; uint32_t index_from_data = 0;
FindFunctionData(scope->start_position(), &index_from_data); DCHECK(FindFunctionData(scope->start_position(), &index_from_data));
DCHECK_EQ(index_from_data, index); DCHECK_EQ(index_from_data, index);
} }
#endif #endif
......
...@@ -137,7 +137,8 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -137,7 +137,8 @@ PreParser::PreParseResult PreParser::PreParseFunction(
parsing_module_ = parsing_module; parsing_module_ = parsing_module;
use_counts_ = use_counts; use_counts_ = use_counts;
DCHECK(!track_unresolved_variables_); DCHECK(!track_unresolved_variables_);
track_unresolved_variables_ = is_inner_function; track_unresolved_variables_ =
is_inner_function || FLAG_experimental_preparser_scope_analysis;
#ifdef DEBUG #ifdef DEBUG
function_scope->set_is_being_lazily_parsed(true); function_scope->set_is_being_lazily_parsed(true);
#endif #endif
...@@ -213,7 +214,7 @@ PreParser::PreParseResult PreParser::PreParseFunction( ...@@ -213,7 +214,7 @@ PreParser::PreParseResult PreParser::PreParseFunction(
function_scope->DeclareArguments(ast_value_factory()); function_scope->DeclareArguments(ast_value_factory());
if (FLAG_experimental_preparser_scope_analysis && if (FLAG_experimental_preparser_scope_analysis &&
preparsed_scope_data_ != nullptr) { preparsed_scope_data_ != nullptr && result != kLazyParsingAborted) {
// We're not going to skip this function, but it might contain skippable // We're not going to skip this function, but it might contain skippable
// functions inside it. // functions inside it.
preparsed_scope_data_->AddFunction( preparsed_scope_data_->AddFunction(
......
...@@ -770,8 +770,8 @@ TEST(PreParserScopeAnalysis) { ...@@ -770,8 +770,8 @@ TEST(PreParserScopeAnalysis) {
CHECK_NULL(unallocated_scope->sibling()); CHECK_NULL(unallocated_scope->sibling());
CHECK(unallocated_scope->is_function_scope()); CHECK(unallocated_scope->is_function_scope());
uint32_t index = 0; lazy_info.preparsed_scope_data()->RestoreData(
lazy_info.preparsed_scope_data()->RestoreData(unallocated_scope, &index); unallocated_scope->AsDeclarationScope());
i::ScopeTestHelper::AllocateWithoutVariableResolution(unallocated_scope); i::ScopeTestHelper::AllocateWithoutVariableResolution(unallocated_scope);
i::ScopeTestHelper::CompareScopes( i::ScopeTestHelper::CompareScopes(
......
...@@ -35,3 +35,61 @@ ...@@ -35,3 +35,61 @@
lazy(9)(); lazy(9)();
assertEquals(19, result); assertEquals(19, result);
})(); })();
(function TestCtxtAllocatingNonSimpleParams1() {
var result = 0;
function lazy([other_param1, ctxt_alloc_param, other_param2]) {
function skip_me() {
result = ctxt_alloc_param;
}
return skip_me;
}
// Test that parameters and variables of the outer function get context
// allocated even if we skip the inner function.
lazy([30, 29, 28])();
assertEquals(29, result);
})();
(function TestCtxtAllocatingNonSimpleParams2() {
var result = 0;
function lazy({a: other_param1, b: ctxt_alloc_param, c: other_param2}) {
function skip_me() {
result = ctxt_alloc_param;
}
return skip_me;
}
// Test that parameters and variables of the outer function get context
// allocated even if we skip the inner function.
lazy({a: 31, b: 32, c: 33})();
assertEquals(32, result);
})();
(function TestCtxtAllocatingNonSimpleParams3() {
var result = 0;
function lazy(...ctxt_alloc_param) {
function skip_me() {
result = ctxt_alloc_param;
}
return skip_me;
}
// Test that parameters and variables of the outer function get context
// allocated even if we skip the inner function.
lazy(34, 35)();
assertEquals([34, 35], result);
})();
// Skippable top level functions.
let result = 0;
function lazy_top_level(ctxt_alloc_param) {
let ctxt_alloc_var = 24;
function skip_me() {
result = ctxt_alloc_param + ctxt_alloc_var;
}
skip_me();
}
lazy_top_level(10);
assertEquals(34, result);
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