From 9c3ffc4f58c2e8c7bb58fd23216353bf24dcf289 Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Thu, 26 Sep 2013 15:28:46 +0000 Subject: [PATCH] Fix replaying of HCapturedObject for nested objects. R=titzer@chromium.org TEST=mjsunit/compiler/property-refs,mjsunit/compiler/escape-analysis Review URL: https://codereview.chromium.org/24561002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16969 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/hydrogen-instructions.cc | 23 ++++++++++++++++------- test/mjsunit/compiler/escape-analysis.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 6125ca2..a66b6ab 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -2341,18 +2341,27 @@ void HSimulate::ReplayEnvironment(HEnvironment* env) { } +static void ReplayEnvironmentNested(const ZoneList* values, + HCapturedObject* other) { + for (int i = 0; i < values->length(); ++i) { + HValue* value = values->at(i); + if (value->IsCapturedObject()) { + if (HCapturedObject::cast(value)->capture_id() == other->capture_id()) { + values->at(i) = other; + } else { + ReplayEnvironmentNested(HCapturedObject::cast(value)->values(), other); + } + } + } +} + + // Replay captured objects by replacing all captured objects with the // same capture id in the current and all outer environments. void HCapturedObject::ReplayEnvironment(HEnvironment* env) { ASSERT(env != NULL); while (env != NULL) { - for (int i = 0; i < env->length(); ++i) { - HValue* value = env->values()->at(i); - if (value->IsCapturedObject() && - HCapturedObject::cast(value)->capture_id() == this->capture_id()) { - env->SetValueAt(i, this); - } - } + ReplayEnvironmentNested(env->values(), this); env = env->outer(); } } diff --git a/test/mjsunit/compiler/escape-analysis.js b/test/mjsunit/compiler/escape-analysis.js index 74e638a..21ebcbbf 100644 --- a/test/mjsunit/compiler/escape-analysis.js +++ b/test/mjsunit/compiler/escape-analysis.js @@ -271,3 +271,33 @@ %OptimizeFunctionOnNextCall(oob); assertEquals(7, oob(cons2, true)); })(); + + +// Test non-shallow nested graph of captured objects. +(function testDeep() { + var deopt = { deopt:false }; + function constructor1() { + this.x = 23; + } + function constructor2(nested) { + this.a = 17; + this.b = nested; + this.c = 42; + } + function deep() { + var o1 = new constructor1(); + var o2 = new constructor2(o1); + assertEquals(17, o2.a); + assertEquals(23, o2.b.x); + assertEquals(42, o2.c); + o1.x = 99; + deopt.deopt; + assertEquals(99, o1.x); + assertEquals(99, o2.b.x); + } + deep(); deep(); + %OptimizeFunctionOnNextCall(deep); + deep(); deep(); + delete deopt.deopt; + deep(); deep(); +})(); -- 2.7.4