Commit 6ed87bfb authored by verwaest's avatar verwaest Committed by Commit bot

Always immediately propagate flags outwards rather than relying on PropagateScopeInfo

- Now "inner_scope_uses_eval_" is also set of scopes that call eval themselves.
- AllowLazyParsing doesn't check force_eager_compilation_ anymore.
- Both inner_scope_uses_eval_ and force_eager_compilation_ are propagated
  outwards immediately when set.

BUG=v8:5209

Review-Url: https://codereview.chromium.org/2269603002
Cr-Commit-Position: refs/heads/master@{#38797}
parent 2d46ef23
......@@ -135,7 +135,7 @@ Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type,
if (scope_type == WITH_SCOPE) {
DCHECK(scope_info.is_null());
} else {
scope_calls_eval_ = scope_info->CallsEval();
if (scope_info->CallsEval()) RecordEvalCall();
set_language_mode(scope_info->language_mode());
num_heap_slots_ = scope_info->ContextLength();
}
......@@ -178,6 +178,7 @@ void DeclarationScope::SetDefaults() {
has_simple_parameters_ = true;
asm_module_ = false;
asm_function_ = false;
force_eager_compilation_ = false;
has_arguments_parameter_ = false;
receiver_ = nullptr;
new_target_ = nullptr;
......@@ -215,7 +216,6 @@ void Scope::SetDefaults() {
is_debug_evaluate_scope_ = false;
inner_scope_calls_eval_ = false;
force_eager_compilation_ = false;
force_context_allocation_ = false;
is_declaration_scope_ = false;
......@@ -877,17 +877,17 @@ bool Scope::AllowsLazyParsing() const {
// If we are inside a block scope, we must parse eagerly to find out how
// to allocate variables on the block scope. At this point, declarations may
// not have yet been parsed.
for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) {
if (scope->is_block_scope()) return false;
for (const Scope* s = this; s != nullptr; s = s->outer_scope_) {
if (s->is_block_scope()) return false;
}
return AllowsLazyCompilation();
return true;
}
bool DeclarationScope::AllowsLazyCompilation() const {
return !force_eager_compilation_;
}
bool Scope::AllowsLazyCompilation() const { return !force_eager_compilation_; }
bool Scope::AllowsLazyCompilationWithoutContext() const {
bool DeclarationScope::AllowsLazyCompilationWithoutContext() const {
if (force_eager_compilation_) return false;
// Disallow lazy compilation without context if any outer scope needs a
// context.
......@@ -1468,12 +1468,6 @@ VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
void Scope::PropagateScopeInfo() {
for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) {
inner->PropagateScopeInfo();
if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) {
inner_scope_calls_eval_ = true;
}
if (inner->force_eager_compilation_) {
force_eager_compilation_ = true;
}
if (IsAsmModule() && inner->is_function_scope()) {
inner->AsDeclarationScope()->set_asm_function();
}
......@@ -1487,10 +1481,9 @@ bool Scope::MustAllocate(Variable* var) {
// via an eval() call. This is only possible if the variable has a
// visible name.
if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
(scope_calls_eval_ || inner_scope_calls_eval_ || is_catch_scope() ||
is_script_scope())) {
(inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
var->set_is_used();
if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned();
if (inner_scope_calls_eval_) var->set_maybe_assigned();
}
DCHECK(!var->has_forced_context_allocation() || var->is_used());
// Global variables do not need to be allocated.
......@@ -1512,8 +1505,7 @@ bool Scope::MustAllocateInContext(Variable* var) {
if (var->mode() == TEMPORARY) return false;
if (is_catch_scope()) return true;
if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true;
return var->has_forced_context_allocation() || scope_calls_eval_ ||
inner_scope_calls_eval_;
return var->has_forced_context_allocation() || inner_scope_calls_eval_;
}
......
......@@ -221,8 +221,14 @@ class Scope: public ZoneObject {
// ---------------------------------------------------------------------------
// Scope-specific info.
// Inform the scope that the corresponding code contains an eval call.
void RecordEvalCall() { scope_calls_eval_ = true; }
// Inform the scope and outer scopes that the corresponding code contains an
// eval call.
void RecordEvalCall() {
scope_calls_eval_ = true;
for (Scope* scope = this; scope != nullptr; scope = scope->outer_scope()) {
scope->inner_scope_calls_eval_ = true;
}
}
// Inform the scope that the corresponding code uses "super".
void RecordSuperPropertyUsage() { scope_uses_super_property_ = true; }
......@@ -367,18 +373,9 @@ class Scope: public ZoneObject {
int ContextLocalCount() const;
int ContextGlobalCount() const;
// Make sure this scope and all outer scopes are eagerly compiled.
void ForceEagerCompilation() { force_eager_compilation_ = true; }
// Determine if we can parse a function literal in this scope lazily.
bool AllowsLazyParsing() const;
// Determine if we can use lazy compilation for this scope.
bool AllowsLazyCompilation() const;
// Determine if we can use lazy compilation for this scope without a context.
bool AllowsLazyCompilationWithoutContext() const;
// The number of contexts between this and scope; zero if this == scope.
int ContextChainLength(Scope* scope) const;
......@@ -510,9 +507,7 @@ class Scope: public ZoneObject {
// Temporary workaround that allows masking of 'this' in debug-evalute scopes.
bool is_debug_evaluate_scope_ : 1;
// Computed via PropagateScopeInfo.
bool inner_scope_calls_eval_ : 1;
bool force_eager_compilation_ : 1;
bool force_context_allocation_ : 1;
// True if it holds 'var' declarations.
......@@ -662,8 +657,7 @@ class DeclarationScope : public Scope {
bool NeedsHomeObject() const {
return scope_uses_super_property_ ||
((scope_calls_eval_ || inner_scope_calls_eval_) &&
(IsConciseMethod(function_kind()) ||
(inner_scope_calls_eval_ && (IsConciseMethod(function_kind()) ||
IsAccessorFunction(function_kind()) ||
IsClassConstructor(function_kind())));
}
......@@ -832,6 +826,21 @@ class DeclarationScope : public Scope {
Handle<StringSet> CollectNonLocals(ParseInfo* info,
Handle<StringSet> non_locals);
// Determine if we can use lazy compilation for this scope.
bool AllowsLazyCompilation() const;
// Determine if we can use lazy compilation for this scope without a context.
bool AllowsLazyCompilationWithoutContext() const;
// Make sure this closure and all outer closures are eagerly compiled.
void ForceEagerCompilation() {
DCHECK_EQ(this, GetClosureScope());
for (DeclarationScope* s = this; !s->is_script_scope();
s = s->outer_scope()->GetClosureScope()) {
s->force_eager_compilation_ = true;
}
}
#ifdef DEBUG
void PrintParameters();
#endif
......@@ -853,6 +862,7 @@ class DeclarationScope : public Scope {
bool asm_module_ : 1;
// This scope's outer context is an asm module.
bool asm_function_ : 1;
bool force_eager_compilation_ : 1;
// This scope has a parameter called "arguments".
bool has_arguments_parameter_ : 1;
......
......@@ -3460,8 +3460,9 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
if (peek() == Token::LBRACE) {
// Multiple statement body
Consume(Token::LBRACE);
bool is_lazily_parsed =
(mode() == PARSE_LAZILY && scope()->AllowsLazyParsing());
DCHECK_EQ(scope(), formal_parameters.scope);
bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
formal_parameters.scope->AllowsLazyParsing());
if (is_lazily_parsed) {
body = this->NewStatementList(0, zone());
this->SkipLazyFunctionBody(&materialized_literal_count,
......
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