Revision: 12370
Author:   [email protected]
Date:     Thu Aug 23 01:15:38 2012
Log: 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.
Review URL: https://chromiumcodereview.appspot.com/10870033
http://code.google.com/p/v8/source/detail?r=12370

Modified:
 /branches/bleeding_edge/src/hashmap.h
 /branches/bleeding_edge/src/scopes.cc
 /branches/bleeding_edge/src/variables.h

=======================================
--- /branches/bleeding_edge/src/hashmap.h       Mon Jun 11 05:42:31 2012
+++ /branches/bleeding_edge/src/hashmap.h       Thu Aug 23 01:15:38 2012
@@ -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--;
     }
   }
=======================================
--- /branches/bleeding_edge/src/scopes.cc       Fri Aug 17 02:03:08 2012
+++ /branches/bleeding_edge/src/scopes.cc       Thu Aug 23 01:15:38 2012
@@ -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);
@@ -607,6 +622,8 @@
       stack_locals->Add(var, zone());
     }
   }
+
+  ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());

   // Collect declared local variables.
   for (VariableMap::Entry* p = variables_.Start();
@@ -614,11 +631,17 @@
        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());
     }
   }
 }
@@ -1255,12 +1278,20 @@
   for (int i = 0; i < temps_.length(); i++) {
     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
=======================================
--- /branches/bleeding_edge/src/variables.h     Thu Mar  8 05:03:07 2012
+++ /branches/bleeding_edge/src/variables.h     Thu Aug 23 01:15:38 2012
@@ -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