From 4eeafb8802aaf32dac03b91ec61e166f45b76f81 Mon Sep 17 00:00:00 2001 From: bmeurer Date: Tue, 28 Jul 2015 01:18:17 -0700 Subject: [PATCH] [stubs] Use a single slot for context globals. Don't use different read/write slots for context globals, but let them share the same slot, which reduces the number of initial misses, and also saves some memory for large scripts. R=yangguo@chromium.org Review URL: https://codereview.chromium.org/1258213002 Cr-Commit-Position: refs/heads/master@{#29889} --- src/compiler/ast-graph-builder.cc | 2 -- src/contexts.cc | 2 -- src/full-codegen/arm/full-codegen-arm.cc | 4 +--- src/full-codegen/arm64/full-codegen-arm64.cc | 4 +--- src/full-codegen/ia32/full-codegen-ia32.cc | 4 +--- src/full-codegen/mips/full-codegen-mips.cc | 4 +--- src/full-codegen/mips64/full-codegen-mips64.cc | 4 +--- src/full-codegen/ppc/full-codegen-ppc.cc | 4 +--- src/full-codegen/x64/full-codegen-x64.cc | 3 +-- src/full-codegen/x87/full-codegen-x87.cc | 4 +--- src/hydrogen.cc | 4 +--- src/scopeinfo.cc | 15 +++++---------- src/scopes.cc | 10 ++++------ 13 files changed, 18 insertions(+), 46 deletions(-) diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index 7ccb8aa..a9a7678 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -3334,7 +3334,6 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, int slot_index = -1; if (variable->index() > 0) { DCHECK(variable->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. slot_index = variable->index(); int depth = current_scope()->ContextChainLength(variable->scope()); if (depth > 0) { @@ -3485,7 +3484,6 @@ Node* AstGraphBuilder::BuildVariableAssignment( int slot_index = -1; if (variable->index() > 0) { DCHECK(variable->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. slot_index = variable->index(); int depth = current_scope()->ContextChainLength(variable->scope()); if (depth > 0) { diff --git a/src/contexts.cc b/src/contexts.cc index 88f593f..31ce98c 100644 --- a/src/contexts.cc +++ b/src/contexts.cc @@ -365,8 +365,6 @@ void Context::InitializeGlobalSlots() { int context_locals = scope_info->ContextLocalCount(); int index = Context::MIN_CONTEXT_SLOTS + context_locals; for (int i = 0; i < context_globals; i++) { - // Clear both read and write slots. - set(index++, empty_cell); set(index++, empty_cell); } } diff --git a/src/full-codegen/arm/full-codegen-arm.cc b/src/full-codegen/arm/full-codegen-arm.cc index 705e2b7..16bd8bc 100644 --- a/src/full-codegen/arm/full-codegen-arm.cc +++ b/src/full-codegen/arm/full-codegen-arm.cc @@ -1414,7 +1414,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, if (var->IsGlobalSlot()) { DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. const int slot = var->index(); const int depth = scope()->ContextChainLength(var->scope()); if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { @@ -2713,8 +2712,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, // Global var, const, or let. DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. - const int slot = var->index() + 1; + const int slot = var->index(); const int depth = scope()->ContextChainLength(var->scope()); if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); diff --git a/src/full-codegen/arm64/full-codegen-arm64.cc b/src/full-codegen/arm64/full-codegen-arm64.cc index 78681b4..40af62c 100644 --- a/src/full-codegen/arm64/full-codegen-arm64.cc +++ b/src/full-codegen/arm64/full-codegen-arm64.cc @@ -1397,7 +1397,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, if (var->IsGlobalSlot()) { DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { @@ -2399,8 +2398,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, // Global var, const, or let. DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. - int const slot = var->index() + 1; + int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { __ Mov(StoreGlobalViaContextDescriptor::SlotRegister(), slot); diff --git a/src/full-codegen/ia32/full-codegen-ia32.cc b/src/full-codegen/ia32/full-codegen-ia32.cc index bebd0fb..6652c92 100644 --- a/src/full-codegen/ia32/full-codegen-ia32.cc +++ b/src/full-codegen/ia32/full-codegen-ia32.cc @@ -1340,7 +1340,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, if (var->IsGlobalSlot()) { DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { @@ -2620,8 +2619,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, // Global var, const, or let. DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. - int const slot = var->index() + 1; + int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { __ Move(StoreGlobalViaContextDescriptor::SlotRegister(), Immediate(slot)); diff --git a/src/full-codegen/mips/full-codegen-mips.cc b/src/full-codegen/mips/full-codegen-mips.cc index 35e6da2..47fe911 100644 --- a/src/full-codegen/mips/full-codegen-mips.cc +++ b/src/full-codegen/mips/full-codegen-mips.cc @@ -1406,7 +1406,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, if (var->IsGlobalSlot()) { DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { @@ -2703,8 +2702,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, DCHECK(var->IsStaticGlobalObjectProperty()); DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0)); __ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register()); - // Each var occupies two slots in the context: for reads and writes. - int const slot = var->index() + 1; + int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { __ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); diff --git a/src/full-codegen/mips64/full-codegen-mips64.cc b/src/full-codegen/mips64/full-codegen-mips64.cc index 7b2cda3..89c5593 100644 --- a/src/full-codegen/mips64/full-codegen-mips64.cc +++ b/src/full-codegen/mips64/full-codegen-mips64.cc @@ -1402,7 +1402,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, if (var->IsGlobalSlot()) { DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { @@ -2700,8 +2699,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, DCHECK(var->IsStaticGlobalObjectProperty()); DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(a0)); __ mov(StoreGlobalViaContextDescriptor::ValueRegister(), result_register()); - // Each var occupies two slots in the context: for reads and writes. - int const slot = var->index() + 1; + int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { __ li(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); diff --git a/src/full-codegen/ppc/full-codegen-ppc.cc b/src/full-codegen/ppc/full-codegen-ppc.cc index 0654a9a..68a0dc0 100644 --- a/src/full-codegen/ppc/full-codegen-ppc.cc +++ b/src/full-codegen/ppc/full-codegen-ppc.cc @@ -1377,7 +1377,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, if (var->IsGlobalSlot()) { DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. const int slot = var->index(); const int depth = scope()->ContextChainLength(var->scope()); if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { @@ -2715,8 +2714,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, // Global var, const, or let. DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. - const int slot = var->index() + 1; + const int slot = var->index(); const int depth = scope()->ContextChainLength(var->scope()); if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { __ mov(StoreGlobalViaContextDescriptor::SlotRegister(), Operand(slot)); diff --git a/src/full-codegen/x64/full-codegen-x64.cc b/src/full-codegen/x64/full-codegen-x64.cc index 1839d2c..894a64a 100644 --- a/src/full-codegen/x64/full-codegen-x64.cc +++ b/src/full-codegen/x64/full-codegen-x64.cc @@ -2614,8 +2614,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, // Global var, const, or let. DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. - int const slot = var->index() + 1; + int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { __ Set(StoreGlobalViaContextDescriptor::SlotRegister(), slot); diff --git a/src/full-codegen/x87/full-codegen-x87.cc b/src/full-codegen/x87/full-codegen-x87.cc index 1e93fe1..8f40e05 100644 --- a/src/full-codegen/x87/full-codegen-x87.cc +++ b/src/full-codegen/x87/full-codegen-x87.cc @@ -1333,7 +1333,6 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, if (var->IsGlobalSlot()) { DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= LoadGlobalViaContextStub::kMaximumDepth) { @@ -2613,8 +2612,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, // Global var, const, or let. DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. - int const slot = var->index() + 1; + int const slot = var->index(); int const depth = scope()->ContextChainLength(var->scope()); if (depth <= StoreGlobalViaContextStub::kMaximumDepth) { __ Move(StoreGlobalViaContextDescriptor::SlotRegister(), Immediate(slot)); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index f652b31..2689e42 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -5564,7 +5564,6 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { } else if (variable->IsGlobalSlot()) { DCHECK(variable->index() > 0); DCHECK(variable->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. int slot_index = variable->index(); int depth = scope()->ContextChainLength(variable->scope()); @@ -6796,8 +6795,7 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( } else if (var->IsGlobalSlot()) { DCHECK(var->index() > 0); DCHECK(var->IsStaticGlobalObjectProperty()); - // Each var occupies two slots in the context: for reads and writes. - int slot_index = var->index() + 1; + int slot_index = var->index(); int depth = scope()->ContextChainLength(var->scope()); HStoreGlobalViaContext* instr = Add( diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc index c79a980..fda3b1b 100644 --- a/src/scopeinfo.cc +++ b/src/scopeinfo.cc @@ -340,7 +340,7 @@ int ScopeInfo::ContextLength() { scope_type() == MODULE_SCOPE; if (has_context) { - return Context::MIN_CONTEXT_SLOTS + context_locals + 2 * context_globals + + return Context::MIN_CONTEXT_SLOTS + context_locals + context_globals + (function_name_context_slot ? 1 : 0); } } @@ -553,7 +553,7 @@ int ScopeInfo::ContextSlotIndex(Handle scope_info, var -= scope_info->ContextLocalCount(); *location = VariableLocation::GLOBAL; result = Context::MIN_CONTEXT_SLOTS + - scope_info->ContextLocalCount() + 2 * var; + scope_info->ContextLocalCount() + var; } context_slot_cache->Update(scope_info, name, *mode, *location, @@ -573,15 +573,10 @@ int ScopeInfo::ContextSlotIndex(Handle scope_info, String* ScopeInfo::ContextSlotName(int slot_index) { - // TODO(bmeurer): Simplify this once we have only a single slot for both reads - // and writes to context globals; currently we have 2 slots per context - // global, and these are located after the common context slots (of which we - // always have Context::MIN_CONTEXT_SLOTS) and the context locals. - int const var = - slot_index - (Context::MIN_CONTEXT_SLOTS + ContextLocalCount()); + int const var = slot_index - Context::MIN_CONTEXT_SLOTS; DCHECK_LE(0, var); - DCHECK_LT(var, 2 * ContextGlobalCount()); - return ContextLocalName(ContextLocalCount() + var / 2); + DCHECK_LT(var, ContextLocalCount() + ContextGlobalCount()); + return ContextLocalName(var); } diff --git a/src/scopes.cc b/src/scopes.cc index bf580cf..1473b24 100644 --- a/src/scopes.cc +++ b/src/scopes.cc @@ -1470,11 +1470,8 @@ void Scope::AllocateDeclaredGlobal(Isolate* isolate, Variable* var) { if (var->IsStaticGlobalObjectProperty()) { DCHECK_EQ(-1, var->index()); DCHECK(var->name()->IsString()); - var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_); + var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_++); num_global_slots_++; - // Each global variable occupies two slots in the context: for reads - // and writes. - num_heap_slots_ += 2; } else { // There must be only DYNAMIC_GLOBAL in the script scope. DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); @@ -1600,11 +1597,12 @@ int Scope::ContextLocalCount() const { if (num_heap_slots() == 0) return 0; bool is_function_var_in_context = function_ != NULL && function_->proxy()->var()->IsContextSlot(); - return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - - 2 * num_global_slots() - (is_function_var_in_context ? 1 : 0); + return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - + (is_function_var_in_context ? 1 : 0); } int Scope::ContextGlobalCount() const { return num_global_slots(); } + } // namespace internal } // namespace v8 -- 2.7.4