Commit 2ba5c10d authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[scope] Use contains_asm_module_ bit to bypass recursive checks

Parser::MaybeResetCharacterStream calls Scope::ContainsAsmModule which
recursively checks whether a Scope is an asm module or any of its
sub-scopes. This is sub-optimal for deeply nested scopes and many
functions which do not contain any asm modules.

Drive-by-fix:
- rename Scope::asm_module to Scope::is_asm_module


Change-Id: I922270c608b54c6525f0672ead4aca90f57a6551
Reviewed-on: https://chromium-review.googlesource.com/c/1360636Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58288}
parent 7520a0fa
......@@ -285,7 +285,7 @@ Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
void DeclarationScope::SetDefaults() {
is_declaration_scope_ = true;
has_simple_parameters_ = true;
asm_module_ = false;
is_asm_module_ = false;
force_eager_compilation_ = false;
has_arguments_parameter_ = false;
scope_uses_super_property_ = false;
......@@ -354,12 +354,10 @@ void DeclarationScope::set_should_eager_compile() {
should_eager_compile_ = !was_lazily_parsed_;
}
void DeclarationScope::set_asm_module() {
asm_module_ = true;
}
void DeclarationScope::set_is_asm_module() { is_asm_module_ = true; }
bool Scope::IsAsmModule() const {
return is_function_scope() && AsDeclarationScope()->asm_module();
return is_function_scope() && AsDeclarationScope()->is_asm_module();
}
bool Scope::ContainsAsmModule() const {
......@@ -409,8 +407,9 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
} else if (scope_info->scope_type() == FUNCTION_SCOPE) {
outer_scope = new (zone)
DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
if (scope_info->IsAsmModule())
outer_scope->AsDeclarationScope()->set_asm_module();
if (scope_info->IsAsmModule()) {
outer_scope->AsDeclarationScope()->set_is_asm_module();
}
} else if (scope_info->scope_type() == EVAL_SCOPE) {
outer_scope = new (zone)
DeclarationScope(zone, EVAL_SCOPE, handle(scope_info, isolate));
......
......@@ -814,8 +814,8 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
scope_info_ = scope_info;
}
bool asm_module() const { return asm_module_; }
void set_asm_module();
bool is_asm_module() const { return is_asm_module_; }
void set_is_asm_module();
bool should_ban_arguments() const {
return IsClassMembersInitializerFunction(function_kind());
......@@ -1065,7 +1065,7 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
bool has_simple_parameters_ : 1;
// This scope contains an "use asm" annotation.
bool asm_module_ : 1;
bool is_asm_module_ : 1;
bool force_eager_compilation_ : 1;
// This function scope has a rest parameter.
bool has_rest_ : 1;
......
......@@ -1381,8 +1381,9 @@ static inline Handle<Object> MakeEntryPair(Isolate* isolate, Handle<Object> key,
PACKED_ELEMENTS, 2);
}
bool ScopeInfo::IsAsmModule() const { return AsmModuleField::decode(Flags()); }
bool ScopeInfo::IsAsmModule() const {
return IsAsmModuleField::decode(Flags());
}
bool ScopeInfo::HasSimpleParameters() const {
return HasSimpleParametersField::decode(Flags());
......
......@@ -152,12 +152,12 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
bool has_simple_parameters = false;
bool asm_module = false;
bool is_asm_module = false;
bool calls_sloppy_eval = false;
if (scope->is_function_scope()) {
DeclarationScope* function_scope = scope->AsDeclarationScope();
has_simple_parameters = function_scope->has_simple_parameters();
asm_module = function_scope->asm_module();
is_asm_module = function_scope->is_asm_module();
}
FunctionKind function_kind = kNormalFunction;
if (scope->is_declaration_scope()) {
......@@ -175,7 +175,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
HasNewTargetField::encode(has_new_target) |
FunctionVariableField::encode(function_name_info) |
HasInferredFunctionNameField::encode(has_inferred_function_name) |
AsmModuleField::encode(asm_module) |
IsAsmModuleField::encode(is_asm_module) |
HasSimpleParametersField::encode(has_simple_parameters) |
FunctionKindField::encode(function_kind) |
HasOuterScopeInfoField::encode(has_outer_scope_info) |
......@@ -331,7 +331,7 @@ Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
LanguageModeField::encode(LanguageMode::kSloppy) |
DeclarationScopeField::encode(false) |
ReceiverVariableField::encode(NONE) | HasNewTargetField::encode(false) |
FunctionVariableField::encode(NONE) | AsmModuleField::encode(false) |
FunctionVariableField::encode(NONE) | IsAsmModuleField::encode(false) |
HasSimpleParametersField::encode(true) |
FunctionKindField::encode(kNormalFunction) |
HasOuterScopeInfoField::encode(has_outer_scope_info) |
......@@ -395,7 +395,7 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate,
HasNewTargetField::encode(false) |
FunctionVariableField::encode(is_empty_function ? UNUSED : NONE) |
HasInferredFunctionNameField::encode(has_inferred_function_name) |
AsmModuleField::encode(false) | HasSimpleParametersField::encode(true) |
IsAsmModuleField::encode(false) | HasSimpleParametersField::encode(true) |
FunctionKindField::encode(FunctionKind::kNormalFunction) |
HasOuterScopeInfoField::encode(false) |
IsDebugEvaluateScopeField::encode(false);
......
......@@ -232,10 +232,10 @@ class ScopeInfo : public FixedArray {
// function name.
class HasInferredFunctionNameField
: public BitField<bool, FunctionVariableField::kNext, 1> {};
class AsmModuleField
class IsAsmModuleField
: public BitField<bool, HasInferredFunctionNameField::kNext, 1> {};
class HasSimpleParametersField
: public BitField<bool, AsmModuleField::kNext, 1> {};
: public BitField<bool, IsAsmModuleField::kNext, 1> {};
class FunctionKindField
: public BitField<FunctionKind, HasSimpleParametersField::kNext, 5> {};
class HasOuterScopeInfoField
......
......@@ -81,6 +81,8 @@ class V8_EXPORT_PRIVATE ParseInfo {
FLAG_ACCESSOR(kCollectTypeProfile, collect_type_profile,
set_collect_type_profile)
FLAG_ACCESSOR(kIsAsmWasmBroken, is_asm_wasm_broken, set_asm_wasm_broken)
FLAG_ACCESSOR(kContainsAsmModule, contains_asm_module,
set_contains_asm_module)
FLAG_ACCESSOR(kBlockCoverageEnabled, block_coverage_enabled,
set_block_coverage_enabled)
FLAG_ACCESSOR(kOnBackgroundThread, on_background_thread,
......@@ -278,6 +280,7 @@ class V8_EXPORT_PRIVATE ParseInfo {
kAllowEvalCache = 1 << 15,
kIsDeclaration = 1 << 16,
kRequiresInstanceMembersInitializer = 1 << 17,
kContainsAsmModule = 1 << 18,
};
//------------- Inputs to parsing and scope analysis -----------------------
......
......@@ -454,10 +454,11 @@ namespace {
void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) {
// Don't reset the character stream if there is an asm.js module since it will
// be used again by the asm-parser.
if (!FLAG_stress_validate_asm &&
(literal == nullptr || !literal->scope()->ContainsAsmModule())) {
info->ResetCharacterStream();
if (info->contains_asm_module()) {
if (FLAG_stress_validate_asm) return;
if (literal != nullptr && literal->scope()->ContainsAsmModule()) return;
}
info->ResetCharacterStream();
}
} // namespace
......@@ -3476,7 +3477,8 @@ void Parser::SetAsmModule() {
// incremented after parsing is done.
++use_counts_[v8::Isolate::kUseAsm];
DCHECK(scope()->is_declaration_scope());
scope()->AsDeclarationScope()->set_asm_module();
scope()->AsDeclarationScope()->set_is_asm_module();
info_->set_contains_asm_module(true);
}
Expression* Parser::ExpressionListToExpression(
......
......@@ -4042,7 +4042,7 @@ TEST(AsmModuleFlag) {
// The asm.js module should be marked as such.
i::Scope* s = DeserializeFunctionScope(isolate, &zone, m, "f");
CHECK(s->IsAsmModule() && s->AsDeclarationScope()->asm_module());
CHECK(s->IsAsmModule() && s->AsDeclarationScope()->is_asm_module());
}
......
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