| Index: src/hydrogen-load-elimination.cc
|
| diff --git a/src/hydrogen-load-elimination.cc b/src/hydrogen-load-elimination.cc
|
| index f33ebe2fabcb61aed1429792618e745e58de73ce..3337188f9a46387591b51268453c2023dd291f0f 100644
|
| --- a/src/hydrogen-load-elimination.cc
|
| +++ b/src/hydrogen-load-elimination.cc
|
| @@ -212,7 +212,7 @@ class HLoadEliminationTable : public ZoneObject {
|
| // 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 @@ class HLoadEliminationTable : public ZoneObject {
|
| }
|
| }
|
|
|
| + // 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 @@ class HLoadEliminationTable : public ZoneObject {
|
| // 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 @@ class HLoadEliminationEffects : public ZoneObject {
|
|
|
| // 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]);
|
| }
|
| }
|
|
|
|
|