Reviewers: danno,

Description:
Make the performance of the VM more predictable by not letting the hash seed
affect the order in which the local variables are processed in the compiler.

Please review this at https://chromiumcodereview.appspot.com/10870033/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/

Affected files:
  M     src/hashmap.h
  M     src/scopes.cc
  M     src/variables.h


Index: src/hashmap.h
===================================================================
--- src/hashmap.h       (revision 12363)
+++ src/hashmap.h       (working copy)
@@ -59,7 +59,8 @@
   struct Entry {
     void* key;
     void* value;
-    uint32_t hash;  // the full hash value for key
+    uint32_t hash;  // The full hash value for key
+    int order;  // If you never remove entries this is the insertion order.
   };

   // If an entry with matching key is found, Lookup()
@@ -140,6 +141,7 @@
     p->key = key;
     p->value = NULL;
     p->hash = hash;
+    p->order = occupancy_;
     occupancy_++;

     // Grow the map if we reached >= 80% occupancy.
@@ -297,7 +299,9 @@
   // Rehash all current entries.
   for (Entry* p = map; n > 0; p++) {
     if (p->key != NULL) {
-      Lookup(p->key, p->hash, true, allocator)->value = p->value;
+      Entry* entry = Lookup(p->key, p->hash, true, allocator);
+      entry->value = p->value;
+      entry->order = p->order;
       n--;
     }
   }
Index: src/scopes.cc
===================================================================
--- src/scopes.cc       (revision 12363)
+++ src/scopes.cc       (working copy)
@@ -594,6 +594,21 @@
 }


+class VarAndOrder {
+ public:
+  VarAndOrder(Variable* var, int order) : var_(var), order_(order) { }
+  Variable* var() const { return var_; }
+  int order() const { return order_; }
+  static int Compare(const VarAndOrder* a, const VarAndOrder* b) {
+    return a->order_ - b->order_;
+  }
+
+ private:
+  Variable* var_;
+  int order_;
+};
+
+
 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
ZoneList<Variable*>* context_locals) {
   ASSERT(stack_locals != NULL);
@@ -608,19 +623,27 @@
     }
   }

+  ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
+
   // Collect declared local variables.
   for (VariableMap::Entry* p = variables_.Start();
        p != NULL;
        p = variables_.Next(p)) {
     Variable* var = reinterpret_cast<Variable*>(p->value);
     if (var->is_used()) {
-      if (var->IsStackLocal()) {
-        stack_locals->Add(var, zone());
-      } else if (var->IsContextSlot()) {
-        context_locals->Add(var, zone());
-      }
+      vars.Add(VarAndOrder(var, p->order), zone());
     }
   }
+  vars.Sort(VarAndOrder::Compare);
+  int var_count = vars.length();
+  for (int i = 0; i < var_count; i++) {
+    Variable* var = vars[i].var();
+    if (var->IsStackLocal()) {
+      stack_locals->Add(var, zone());
+    } else if (var->IsContextSlot()) {
+      context_locals->Add(var, zone());
+    }
+  }
 }


@@ -1256,13 +1279,21 @@
     AllocateNonParameterLocal(temps_[i]);
   }

+  ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
+
   for (VariableMap::Entry* p = variables_.Start();
        p != NULL;
        p = variables_.Next(p)) {
     Variable* var = reinterpret_cast<Variable*>(p->value);
-    AllocateNonParameterLocal(var);
+    vars.Add(VarAndOrder(var, p->order), zone());
   }

+  vars.Sort(VarAndOrder::Compare);
+  int var_count = vars.length();
+  for (int i = 0; i < var_count; i++) {
+    AllocateNonParameterLocal(vars[i].var());
+  }
+
   // For now, function_ must be allocated at the very end.  If it gets
   // allocated in the context, it must be the last slot in the context,
   // because of the current ScopeInfo implementation (see
Index: src/variables.h
===================================================================
--- src/variables.h     (revision 12363)
+++ src/variables.h     (working copy)
@@ -55,7 +55,7 @@
     UNALLOCATED,

     // A slot in the parameter section on the stack.  index() is the
-    // parameter index, counting left-to-right.  The reciever is index -1;
+    // parameter index, counting left-to-right.  The receiver is index -1;
     // the first parameter is index 0.
     PARAMETER,



--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to