Version 3.22.18

Add tool to visualize machine code/lithium.

Handle misaligned loads and stores in load elimination. Do not track misaligned loads and be conservative about invalidating misaligned stores. (issue 2934)

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@17310 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/hydrogen-load-elimination.cc b/src/hydrogen-load-elimination.cc
index f33ebe2..3337188 100644
--- a/src/hydrogen-load-elimination.cc
+++ b/src/hydrogen-load-elimination.cc
@@ -212,7 +212,7 @@
   // instruction is redundant. Otherwise, return {instr}.
   HValue* store(HStoreNamedField* instr) {
     int field = FieldOf(instr->access());
-    if (field < 0) return instr;
+    if (field < 0) return KillIfMisaligned(instr);
 
     HValue* object = instr->object()->ActualValue();
     HValue* value = instr->value();
@@ -250,6 +250,38 @@
     }
   }
 
+  // Kill all entries aliasing the given store.
+  void KillStore(HStoreNamedField* s) {
+    int field = FieldOf(s->access());
+    if (field >= 0) {
+      KillFieldInternal(s->object()->ActualValue(), field, s->value());
+    } else {
+      KillIfMisaligned(s);
+    }
+  }
+
+  // Kill multiple entries in the case of a misaligned store.
+  HValue* KillIfMisaligned(HStoreNamedField* instr) {
+    HObjectAccess access = instr->access();
+    if (access.IsInobject()) {
+      int offset = access.offset();
+      if ((offset % kPointerSize) != 0) {
+        // Kill the field containing the first word of the access.
+        HValue* object = instr->object()->ActualValue();
+        int field = offset / kPointerSize;
+        KillFieldInternal(object, field, NULL);
+
+        // Kill the next field in case of overlap.
+        int size = kPointerSize;
+        if (access.representation().IsByte()) size = 1;
+        else if (access.representation().IsInteger32()) size = 4;
+        int next_field = (offset + size - 1) / kPointerSize;
+        if (next_field != field) KillFieldInternal(object, next_field, NULL);
+      }
+    }
+    return instr;
+  }
+
   // Find an entry for the given object and field pair.
   HFieldApproximation* Find(HValue* object, int field) {
     // Search for a field approximation for this object.
@@ -347,7 +379,8 @@
   // Compute the field index for the given in-object offset; -1 if not tracked.
   int FieldOf(int offset) {
     if (offset >= kMaxTrackedFields * kPointerSize) return -1;
-    ASSERT((offset % kPointerSize) == 0);  // Assume aligned accesses.
+    // TODO(titzer): track misaligned loads in a separate list?
+    if ((offset % kPointerSize) != 0) return -1;  // Ignore misaligned accesses.
     return offset / kPointerSize;
   }
 
@@ -430,11 +463,7 @@
 
     // Kill non-agreeing fields for each store contained in these effects.
     for (int i = 0; i < stores_.length(); i++) {
-      HStoreNamedField* s = stores_[i];
-      int field = table->FieldOf(s->access());
-      if (field >= 0) {
-        table->KillFieldInternal(s->object()->ActualValue(), field, s->value());
-      }
+      table->KillStore(stores_[i]);
     }
   }