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