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
This commit is contained in:
mstarzinger@chromium.org 2013-09-26 15:28:46 +00:00
parent 71bcf9a621
commit 9c3ffc4f58
2 changed files with 46 additions and 7 deletions

View File

@ -2341,18 +2341,27 @@ void HSimulate::ReplayEnvironment(HEnvironment* env) {
}
static void ReplayEnvironmentNested(const ZoneList<HValue*>* 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();
}
}

View File

@ -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();
})();