[stubs] Use a single slot for context globals.
authorbmeurer <bmeurer@chromium.org>
Tue, 28 Jul 2015 08:18:17 +0000 (01:18 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 28 Jul 2015 08:18:33 +0000 (08:18 +0000)
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}

13 files changed:
src/compiler/ast-graph-builder.cc
src/contexts.cc
src/full-codegen/arm/full-codegen-arm.cc
src/full-codegen/arm64/full-codegen-arm64.cc
src/full-codegen/ia32/full-codegen-ia32.cc
src/full-codegen/mips/full-codegen-mips.cc
src/full-codegen/mips64/full-codegen-mips64.cc
src/full-codegen/ppc/full-codegen-ppc.cc
src/full-codegen/x64/full-codegen-x64.cc
src/full-codegen/x87/full-codegen-x87.cc
src/hydrogen.cc
src/scopeinfo.cc
src/scopes.cc

index 7ccb8aa..a9a7678 100644 (file)
@@ -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) {
index 88f593f..31ce98c 100644 (file)
@@ -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);
     }
   }
index 705e2b7..16bd8bc 100644 (file)
@@ -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));
index 78681b4..40af62c 100644 (file)
@@ -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);
index bebd0fb..6652c92 100644 (file)
@@ -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));
index 35e6da2..47fe911 100644 (file)
@@ -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));
index 7b2cda3..89c5593 100644 (file)
@@ -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));
index 0654a9a..68a0dc0 100644 (file)
@@ -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));
index 1839d2c..894a64a 100644 (file)
@@ -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);
index 1e93fe1..8f40e05 100644 (file)
@@ -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));
index f652b31..2689e42 100644 (file)
@@ -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<HStoreGlobalViaContext>(
index c79a980..fda3b1b 100644 (file)
@@ -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<ScopeInfo> 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<ScopeInfo> 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);
 }
 
 
index bf580cf..1473b24 100644 (file)
@@ -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