Make the performance of the VM more predictable by not letting the hash seed
authorerik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 Aug 2012 08:15:38 +0000 (08:15 +0000)
committererik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 Aug 2012 08:15:38 +0000 (08:15 +0000)
affect the order in which the local variables are processed in the compiler.
Review URL: https://chromiumcodereview.appspot.com/10870033

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12370 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hashmap.h
src/scopes.cc
src/variables.h

index 6f76e9f..11f6ace 100644 (file)
@@ -59,7 +59,8 @@ class TemplateHashMapImpl {
   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 @@ TemplateHashMapImpl<AllocationPolicy>::Lookup(
     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 @@ void TemplateHashMapImpl<AllocationPolicy>::Resize(AllocationPolicy allocator) {
   // 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 6da9f49..32716cd 100644 (file)
@@ -594,6 +594,21 @@ VariableProxy* Scope::CheckAssignmentToConst() {
 }
 
 
+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,17 +623,25 @@ void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
     }
   }
 
+  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,11 +1279,19 @@ void Scope::AllocateNonParameterLocals() {
     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
index f49b6e1..e5aee2d 100644 (file)
@@ -55,7 +55,7 @@ class Variable: public ZoneObject {
     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,