From be32761a674ad42d3e6ede08c3a27ec006f42f3e Mon Sep 17 00:00:00 2001 From: "titzer@chromium.org" Date: Fri, 20 Dec 2013 12:12:41 +0000 Subject: [PATCH] Improve load elimination handling of transitioning stores. BUG= R=verwaest@chromium.org Review URL: https://codereview.chromium.org/106973005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18388 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/hydrogen-load-elimination.cc | 16 ++++++---------- test/mjsunit/compiler/load-elimination.js | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/hydrogen-load-elimination.cc b/src/hydrogen-load-elimination.cc index f3b5748..f2e993b 100644 --- a/src/hydrogen-load-elimination.cc +++ b/src/hydrogen-load-elimination.cc @@ -43,7 +43,6 @@ static const int kMaxTrackedObjects = 5; class HFieldApproximation : public ZoneObject { public: // Just a data blob. HValue* object_; - HLoadNamedField* last_load_; HValue* last_value_; HFieldApproximation* next_; @@ -52,7 +51,6 @@ class HFieldApproximation : public ZoneObject { if (this == NULL) return NULL; HFieldApproximation* copy = new(zone) HFieldApproximation(); copy->object_ = this->object_; - copy->last_load_ = this->last_load_; copy->last_value_ = this->last_value_; copy->next_ = this->next_->Copy(zone); return copy; @@ -197,7 +195,6 @@ class HLoadEliminationTable : public ZoneObject { if (approx->last_value_ == NULL) { // Load is not redundant. Fill out a new entry. - approx->last_load_ = instr; approx->last_value_ = instr; return instr; } else { @@ -217,12 +214,14 @@ class HLoadEliminationTable : public ZoneObject { HValue* object = instr->object()->ActualValue(); HValue* value = instr->value(); - // Kill non-equivalent may-alias entries. - KillFieldInternal(object, field, value); if (instr->has_transition()) { - // A transition store alters the map of the object. - // TODO(titzer): remember the new map (a constant) for the object. + // A transition introduces a new field and alters the map of the object. + // Since the field in the object is new, it cannot alias existing entries. + // TODO(titzer): introduce a constant for the new map and remember it. KillFieldInternal(object, FieldOf(JSObject::kMapOffset), NULL); + } else { + // Kill non-equivalent may-alias entries. + KillFieldInternal(object, field, value); } HFieldApproximation* approx = FindOrCreate(object, field); @@ -231,7 +230,6 @@ class HLoadEliminationTable : public ZoneObject { return NULL; } else { // The store is not redundant. Update the entry. - approx->last_load_ = NULL; approx->last_value_ = value; return instr; } @@ -314,7 +312,6 @@ class HLoadEliminationTable : public ZoneObject { // Insert the entry at the head of the list. approx->object_ = object; - approx->last_load_ = NULL; approx->last_value_ = NULL; approx->next_ = fields_[field]; fields_[field] = approx; @@ -397,7 +394,6 @@ class HLoadEliminationTable : public ZoneObject { PrintF(" field %d: ", i); for (HFieldApproximation* a = fields_[i]; a != NULL; a = a->next_) { PrintF("[o%d =", a->object_->id()); - if (a->last_load_ != NULL) PrintF(" L%d", a->last_load_->id()); if (a->last_value_ != NULL) PrintF(" v%d", a->last_value_->id()); PrintF("] "); } diff --git a/test/mjsunit/compiler/load-elimination.js b/test/mjsunit/compiler/load-elimination.js index e019508..9475d4b 100644 --- a/test/mjsunit/compiler/load-elimination.js +++ b/test/mjsunit/compiler/load-elimination.js @@ -35,6 +35,9 @@ function B(x, y) { return this; } +function C() { +} + function test_load() { var a = new B(1, 2); return a.x + a.x + a.x + a.x; @@ -64,6 +67,22 @@ function test_nonaliasing_store1() { return f + g + h + a.x; } +function test_transitioning_store1() { + var a = new B(2, 3); + var f = a.x, g = a.y; + var b = new B(3, 4); + return a.x + a.y; +} + +function test_transitioning_store2() { + var b = new C(); + var a = new B(-1, 5); + var f = a.x, g = a.y; + b.x = 9; + b.y = 11; + return a.x + a.y; +} + function killall() { try { } catch(e) { } } @@ -102,5 +121,7 @@ function test(x, f) { test(4, test_load); test(22, test_store_load); test(8, test_nonaliasing_store1); +test(5, test_transitioning_store1); +test(4, test_transitioning_store2); test(22, test_store_load_kill); test(7, test_store_store); -- 2.7.4