Commit d454e6cc authored by verwaest's avatar verwaest Committed by Commit bot

Shuffle fields around in Scope to save more zone memory

This makes the debug-only scope-name actually debug-only-allocated, replaces num_vars_ usages by variables_.occupancy, and shuffles fields around in the scope class for better packing.

This reduces sizeof(i::Scope) from 360 to 328 bytes on x64.

BUG=v8:5209

Review-Url: https://codereview.chromium.org/2201763004
Cr-Commit-Position: refs/heads/master@{#38210}
parent 9ee6ca75
...@@ -84,8 +84,6 @@ void SloppyBlockFunctionMap::Declare(const AstRawString* name, ...@@ -84,8 +84,6 @@ void SloppyBlockFunctionMap::Declare(const AstRawString* name,
Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
FunctionKind function_kind) FunctionKind function_kind)
: outer_scope_(outer_scope), : outer_scope_(outer_scope),
scope_type_(scope_type),
function_kind_(function_kind),
variables_(zone), variables_(zone),
temps_(4, zone), temps_(4, zone),
params_(4, zone), params_(4, zone),
...@@ -94,6 +92,8 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, ...@@ -94,6 +92,8 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
ModuleDescriptor(zone) ModuleDescriptor(zone)
: NULL), : NULL),
sloppy_block_function_map_(zone), sloppy_block_function_map_(zone),
scope_type_(scope_type),
function_kind_(function_kind),
already_resolved_(false) { already_resolved_(false) {
SetDefaults(); SetDefaults();
if (outer_scope == nullptr) { if (outer_scope == nullptr) {
...@@ -115,15 +115,15 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, ...@@ -115,15 +115,15 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type,
Handle<ScopeInfo> scope_info) Handle<ScopeInfo> scope_info)
: outer_scope_(nullptr), : outer_scope_(nullptr),
scope_type_(scope_type),
function_kind_(scope_info.is_null() ? kNormalFunction
: scope_info->function_kind()),
variables_(zone), variables_(zone),
temps_(4, zone), temps_(4, zone),
params_(4, zone), params_(4, zone),
decls_(4, zone), decls_(4, zone),
module_descriptor_(nullptr), module_descriptor_(nullptr),
sloppy_block_function_map_(zone), sloppy_block_function_map_(zone),
scope_type_(scope_type),
function_kind_(scope_info.is_null() ? kNormalFunction
: scope_info->function_kind()),
already_resolved_(true), already_resolved_(true),
scope_info_(scope_info) { scope_info_(scope_info) {
SetDefaults(); SetDefaults();
...@@ -142,18 +142,17 @@ Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, ...@@ -142,18 +142,17 @@ Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type,
Scope::Scope(Zone* zone, Scope* inner_scope, Scope::Scope(Zone* zone, Scope* inner_scope,
const AstRawString* catch_variable_name) const AstRawString* catch_variable_name)
: outer_scope_(nullptr), : outer_scope_(nullptr),
scope_type_(CATCH_SCOPE),
function_kind_(kNormalFunction),
variables_(zone), variables_(zone),
temps_(0, zone), temps_(0, zone),
params_(0, zone), params_(0, zone),
decls_(0, zone), decls_(0, zone),
module_descriptor_(nullptr), module_descriptor_(nullptr),
sloppy_block_function_map_(zone), sloppy_block_function_map_(zone),
scope_type_(CATCH_SCOPE),
function_kind_(kNormalFunction),
already_resolved_(true) { already_resolved_(true) {
SetDefaults(); SetDefaults();
AddInnerScope(inner_scope); AddInnerScope(inner_scope);
++num_var_;
num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
Variable* variable = variables_.Declare(this, Variable* variable = variables_.Declare(this,
catch_variable_name, catch_variable_name,
...@@ -170,7 +169,9 @@ void Scope::SetDefaults() { ...@@ -170,7 +169,9 @@ void Scope::SetDefaults() {
inner_scope_ = nullptr; inner_scope_ = nullptr;
sibling_ = nullptr; sibling_ = nullptr;
unresolved_ = nullptr; unresolved_ = nullptr;
#ifdef DEBUG
scope_name_ = nullptr; scope_name_ = nullptr;
#endif
dynamics_ = nullptr; dynamics_ = nullptr;
receiver_ = nullptr; receiver_ = nullptr;
new_target_ = nullptr; new_target_ = nullptr;
...@@ -189,7 +190,6 @@ void Scope::SetDefaults() { ...@@ -189,7 +190,6 @@ void Scope::SetDefaults() {
scope_nonlinear_ = false; scope_nonlinear_ = false;
force_eager_compilation_ = false; force_eager_compilation_ = false;
force_context_allocation_ = false; force_context_allocation_ = false;
num_var_ = 0;
num_stack_slots_ = 0; num_stack_slots_ = 0;
num_heap_slots_ = 0; num_heap_slots_ = 0;
num_global_slots_ = 0; num_global_slots_ = 0;
...@@ -327,7 +327,8 @@ Scope* Scope::FinalizeBlockScope() { ...@@ -327,7 +327,8 @@ Scope* Scope::FinalizeBlockScope() {
DCHECK(temps_.is_empty()); DCHECK(temps_.is_empty());
DCHECK(params_.is_empty()); DCHECK(params_.is_empty());
if (num_var() > 0 || (is_declaration_scope() && calls_sloppy_eval())) { if (variables_.occupancy() > 0 ||
(is_declaration_scope() && calls_sloppy_eval())) {
return this; return this;
} }
...@@ -562,7 +563,6 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, ...@@ -562,7 +563,6 @@ Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
// introduced during variable allocation, and TEMPORARY variables are // introduced during variable allocation, and TEMPORARY variables are
// allocated via NewTemporary(). // allocated via NewTemporary().
DCHECK(IsDeclaredVariableMode(mode)); DCHECK(IsDeclaredVariableMode(mode));
++num_var_;
return variables_.Declare(this, name, mode, kind, init_flag, return variables_.Declare(this, name, mode, kind, init_flag,
maybe_assigned_flag); maybe_assigned_flag);
} }
......
...@@ -118,10 +118,12 @@ class Scope: public ZoneObject { ...@@ -118,10 +118,12 @@ class Scope: public ZoneObject {
Context* context, Scope* script_scope, Context* context, Scope* script_scope,
AstValueFactory* ast_value_factory); AstValueFactory* ast_value_factory);
#ifdef DEBUG
// The scope name is only used for printing/debugging. // The scope name is only used for printing/debugging.
void SetScopeName(const AstRawString* scope_name) { void SetScopeName(const AstRawString* scope_name) {
scope_name_ = scope_name; scope_name_ = scope_name;
} }
#endif
void DeclareThis(AstValueFactory* ast_value_factory); void DeclareThis(AstValueFactory* ast_value_factory);
void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory); void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory);
...@@ -519,7 +521,7 @@ class Scope: public ZoneObject { ...@@ -519,7 +521,7 @@ class Scope: public ZoneObject {
const AstRawString* catch_variable_name() const { const AstRawString* catch_variable_name() const {
DCHECK(is_catch_scope()); DCHECK(is_catch_scope());
DCHECK(num_var() == 1); DCHECK_EQ(1, num_var());
return static_cast<AstRawString*>(variables_.Start()->key); return static_cast<AstRawString*>(variables_.Start()->key);
} }
...@@ -533,9 +535,6 @@ class Scope: public ZoneObject { ...@@ -533,9 +535,6 @@ class Scope: public ZoneObject {
ZoneList<Variable*>* context_locals, ZoneList<Variable*>* context_locals,
ZoneList<Variable*>* context_globals); ZoneList<Variable*>* context_globals);
// Current number of var locals.
int num_var() const { return num_var_; }
// Result of variable allocation. // Result of variable allocation.
int num_stack_slots() const { return num_stack_slots_; } int num_stack_slots() const { return num_stack_slots_; }
int num_heap_slots() const { return num_heap_slots_; } int num_heap_slots() const { return num_heap_slots_; }
...@@ -604,6 +603,8 @@ class Scope: public ZoneObject { ...@@ -604,6 +603,8 @@ class Scope: public ZoneObject {
return params_.Contains(variables_.Lookup(name)); return params_.Contains(variables_.Lookup(name));
} }
int num_var() const { return variables_.occupancy(); }
SloppyBlockFunctionMap* sloppy_block_function_map() { SloppyBlockFunctionMap* sloppy_block_function_map() {
return &sloppy_block_function_map_; return &sloppy_block_function_map_;
} }
...@@ -626,13 +627,10 @@ class Scope: public ZoneObject { ...@@ -626,13 +627,10 @@ class Scope: public ZoneObject {
Scope* inner_scope_; // an inner scope of this scope Scope* inner_scope_; // an inner scope of this scope
Scope* sibling_; // a sibling inner scope of the outer scope of this scope. Scope* sibling_; // a sibling inner scope of the outer scope of this scope.
// The scope type.
const ScopeType scope_type_;
// If the scope is a function scope, this is the function kind.
const FunctionKind function_kind_;
// Debugging support. // Debugging support.
#ifdef DEBUG
const AstRawString* scope_name_; const AstRawString* scope_name_;
#endif
// The variables declared in this scope: // The variables declared in this scope:
// //
...@@ -669,45 +667,51 @@ class Scope: public ZoneObject { ...@@ -669,45 +667,51 @@ class Scope: public ZoneObject {
// Map of function names to lists of functions defined in sloppy blocks // Map of function names to lists of functions defined in sloppy blocks
SloppyBlockFunctionMap sloppy_block_function_map_; SloppyBlockFunctionMap sloppy_block_function_map_;
// The scope type.
const ScopeType scope_type_;
// If the scope is a function scope, this is the function kind.
const FunctionKind function_kind_;
// Scope-specific information computed during parsing. // Scope-specific information computed during parsing.
// //
// The language mode of this scope.
STATIC_ASSERT(LANGUAGE_END == 3);
LanguageMode language_mode_ : 2;
// This scope is inside a 'with' of some outer scope. // This scope is inside a 'with' of some outer scope.
bool scope_inside_with_; bool scope_inside_with_ : 1;
// This scope or a nested catch scope or with scope contain an 'eval' call. At // This scope or a nested catch scope or with scope contain an 'eval' call. At
// the 'eval' call site this scope is the declaration scope. // the 'eval' call site this scope is the declaration scope.
bool scope_calls_eval_; bool scope_calls_eval_ : 1;
// This scope uses "super" property ('super.foo'). // This scope uses "super" property ('super.foo').
bool scope_uses_super_property_; bool scope_uses_super_property_ : 1;
// This scope has a parameter called "arguments". // This scope has a parameter called "arguments".
bool has_arguments_parameter_; bool has_arguments_parameter_ : 1;
// This scope contains an "use asm" annotation. // This scope contains an "use asm" annotation.
bool asm_module_; 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_; bool asm_function_ : 1;
// This scope's declarations might not be executed in order (e.g., switch). // This scope's declarations might not be executed in order (e.g., switch).
bool scope_nonlinear_; bool scope_nonlinear_ : 1;
// The language mode of this scope. bool is_hidden_ : 1;
LanguageMode language_mode_; bool has_simple_parameters_ : 1;
// Source positions.
int start_position_;
int end_position_;
bool is_hidden_;
// Computed via PropagateScopeInfo. // Computed via PropagateScopeInfo.
bool outer_scope_calls_sloppy_eval_; bool outer_scope_calls_sloppy_eval_ : 1;
bool inner_scope_calls_eval_; bool inner_scope_calls_eval_ : 1;
bool force_eager_compilation_; bool force_eager_compilation_ : 1;
bool force_context_allocation_; bool force_context_allocation_ : 1;
// True if it doesn't need scope resolution (e.g., if the scope was // True if it doesn't need scope resolution (e.g., if the scope was
// constructed based on a serialized scope info or a catch context). // constructed based on a serialized scope info or a catch context).
bool already_resolved_; bool already_resolved_ : 1;
bool already_resolved() { return already_resolved_; }
// True if it holds 'var' declarations. // True if it holds 'var' declarations.
bool is_declaration_scope_; bool is_declaration_scope_ : 1;
// Computed as variables are declared. // Source positions.
int num_var_; int start_position_;
int end_position_;
// Computed via AllocateVariables; function, block and catch scopes only. // Computed via AllocateVariables; function, block and catch scopes only.
int num_stack_slots_; int num_stack_slots_;
...@@ -716,13 +720,11 @@ class Scope: public ZoneObject { ...@@ -716,13 +720,11 @@ class Scope: public ZoneObject {
// Info about the parameter list of a function. // Info about the parameter list of a function.
int arity_; int arity_;
bool has_simple_parameters_;
Variable* rest_parameter_;
int rest_index_; int rest_index_;
Variable* rest_parameter_;
// Serialized scope info support. // Serialized scope info support.
Handle<ScopeInfo> scope_info_; Handle<ScopeInfo> scope_info_;
bool already_resolved() { return already_resolved_; }
// Create a non-local variable with a given name. // Create a non-local variable with a given name.
// These variables are looked up dynamically at runtime. // These variables are looked up dynamically at runtime.
......
...@@ -1013,7 +1013,7 @@ enum MinusZeroMode { ...@@ -1013,7 +1013,7 @@ enum MinusZeroMode {
enum Signedness { kSigned, kUnsigned }; enum Signedness { kSigned, kUnsigned };
enum FunctionKind { enum FunctionKind : uint16_t {
kNormalFunction = 0, kNormalFunction = 0,
kArrowFunction = 1 << 0, kArrowFunction = 1 << 0,
kGeneratorFunction = 1 << 1, kGeneratorFunction = 1 << 1,
......
...@@ -4298,7 +4298,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -4298,7 +4298,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// Parse function. // Parse function.
{ {
FunctionState function_state(&function_state_, &scope_state_, scope, kind); FunctionState function_state(&function_state_, &scope_state_, scope, kind);
#ifdef DEBUG
this->scope()->SetScopeName(function_name); this->scope()->SetScopeName(function_name);
#endif
ExpressionClassifier formals_classifier(this, &duplicate_finder); ExpressionClassifier formals_classifier(this, &duplicate_finder);
eager_compile_hint = function_state_->this_function_is_parenthesized() eager_compile_hint = function_state_->this_function_is_parenthesized()
...@@ -5010,7 +5012,9 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier, ...@@ -5010,7 +5012,9 @@ Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier,
BlockState block_state(&scope_state_); BlockState block_state(&scope_state_);
RaiseLanguageMode(STRICT); RaiseLanguageMode(STRICT);
#ifdef DEBUG
scope()->SetScopeName(name); scope()->SetScopeName(name);
#endif
VariableProxy* proxy = nullptr; VariableProxy* proxy = nullptr;
if (name != nullptr) { if (name != nullptr) {
......
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