[fullcode][mips][mips64][ppc][s390] Avoid trashing of a home object when doing a count operation with keyed load/store to a super.
BUG=chromium:631917 Review-Url: https://codereview.chromium.org/2191663004 Cr-Commit-Position: refs/heads/master@{#38139}
This commit is contained in:
parent
ba6e348ffe
commit
fc66694de8
@ -3203,25 +3203,23 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object());
|
||||
PushOperand(result_register());
|
||||
const Register scratch = a1;
|
||||
__ lw(scratch, MemOperand(sp, kPointerSize));
|
||||
PushOperands(scratch, result_register());
|
||||
__ lw(scratch, MemOperand(sp, 0)); // this
|
||||
PushOperands(result_register(), scratch, result_register());
|
||||
EmitNamedSuperPropertyLoad(prop);
|
||||
break;
|
||||
}
|
||||
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object());
|
||||
const Register scratch = a1;
|
||||
const Register scratch1 = t0;
|
||||
__ Move(scratch, result_register());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
PushOperands(scratch, result_register());
|
||||
__ lw(scratch1, MemOperand(sp, 2 * kPointerSize));
|
||||
PushOperands(scratch1, scratch, result_register());
|
||||
const Register scratch1 = a1;
|
||||
const Register scratch2 = t0;
|
||||
__ lw(scratch1, MemOperand(sp, 1 * kPointerSize)); // this
|
||||
__ lw(scratch2, MemOperand(sp, 0 * kPointerSize)); // home object
|
||||
PushOperands(result_register(), scratch1, scratch2, result_register());
|
||||
EmitKeyedSuperPropertyLoad(prop);
|
||||
break;
|
||||
}
|
||||
|
@ -3203,25 +3203,23 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object());
|
||||
PushOperand(result_register());
|
||||
const Register scratch = a1;
|
||||
__ ld(scratch, MemOperand(sp, kPointerSize));
|
||||
PushOperands(scratch, result_register());
|
||||
__ ld(scratch, MemOperand(sp, 0)); // this
|
||||
PushOperands(result_register(), scratch, result_register());
|
||||
EmitNamedSuperPropertyLoad(prop);
|
||||
break;
|
||||
}
|
||||
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object());
|
||||
const Register scratch = a1;
|
||||
const Register scratch1 = a4;
|
||||
__ Move(scratch, result_register());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
PushOperands(scratch, result_register());
|
||||
__ ld(scratch1, MemOperand(sp, 2 * kPointerSize));
|
||||
PushOperands(scratch1, scratch, result_register());
|
||||
const Register scratch1 = a1;
|
||||
const Register scratch2 = a4;
|
||||
__ ld(scratch1, MemOperand(sp, 1 * kPointerSize)); // this
|
||||
__ ld(scratch2, MemOperand(sp, 0 * kPointerSize)); // home object
|
||||
PushOperands(result_register(), scratch1, scratch2, result_register());
|
||||
EmitKeyedSuperPropertyLoad(prop);
|
||||
break;
|
||||
}
|
||||
|
@ -3191,25 +3191,23 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object());
|
||||
PushOperand(result_register());
|
||||
const Register scratch = r4;
|
||||
__ LoadP(scratch, MemOperand(sp, kPointerSize));
|
||||
PushOperands(scratch, result_register());
|
||||
__ LoadP(scratch, MemOperand(sp, 0)); // this
|
||||
PushOperands(result_register(), scratch, result_register());
|
||||
EmitNamedSuperPropertyLoad(prop);
|
||||
break;
|
||||
}
|
||||
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object());
|
||||
const Register scratch = r4;
|
||||
const Register scratch1 = r5;
|
||||
__ mr(scratch, result_register());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
PushOperands(scratch, result_register());
|
||||
__ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize));
|
||||
PushOperands(scratch1, scratch, result_register());
|
||||
const Register scratch1 = r4;
|
||||
const Register scratch2 = r5;
|
||||
__ LoadP(scratch1, MemOperand(sp, 1 * kPointerSize)); // this
|
||||
__ LoadP(scratch2, MemOperand(sp, 0 * kPointerSize)); // home object
|
||||
PushOperands(result_register(), scratch1, scratch2, result_register());
|
||||
EmitKeyedSuperPropertyLoad(prop);
|
||||
break;
|
||||
}
|
||||
|
@ -3110,25 +3110,23 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object());
|
||||
PushOperand(result_register());
|
||||
const Register scratch = r3;
|
||||
__ LoadP(scratch, MemOperand(sp, kPointerSize));
|
||||
PushOperands(scratch, result_register());
|
||||
__ LoadP(scratch, MemOperand(sp, 0)); // this
|
||||
PushOperands(result_register(), scratch, result_register());
|
||||
EmitNamedSuperPropertyLoad(prop);
|
||||
break;
|
||||
}
|
||||
|
||||
case KEYED_SUPER_PROPERTY: {
|
||||
VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
|
||||
VisitForAccumulatorValue(
|
||||
VisitForStackValue(
|
||||
prop->obj()->AsSuperPropertyReference()->home_object());
|
||||
const Register scratch = r3;
|
||||
const Register scratch1 = r4;
|
||||
__ LoadRR(scratch, result_register());
|
||||
VisitForAccumulatorValue(prop->key());
|
||||
PushOperands(scratch, result_register());
|
||||
__ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize));
|
||||
PushOperands(scratch1, scratch, result_register());
|
||||
const Register scratch1 = r3;
|
||||
const Register scratch2 = r4;
|
||||
__ LoadP(scratch1, MemOperand(sp, 1 * kPointerSize)); // this
|
||||
__ LoadP(scratch2, MemOperand(sp, 0 * kPointerSize)); // home object
|
||||
PushOperands(result_register(), scratch1, scratch2, result_register());
|
||||
EmitKeyedSuperPropertyLoad(prop);
|
||||
break;
|
||||
}
|
||||
|
38
test/mjsunit/regress/regress-crbug-631917.js
Normal file
38
test/mjsunit/regress/regress-crbug-631917.js
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2016 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
var b = { toString: function() { return "b"; } };
|
||||
var c = { toString: function() { return "c"; } };
|
||||
|
||||
(function() {
|
||||
var expected_receiver;
|
||||
var obj1 = {
|
||||
a: 100,
|
||||
b_: 200,
|
||||
get b() { assertEquals(expected_receiver, this); return this.b_; },
|
||||
set b(v) { assertEquals(expected_receiver, this); this.b_ = v; },
|
||||
c_: 300,
|
||||
get c() { assertEquals(expected_receiver, this); return this.c_; },
|
||||
set c(v) { assertEquals(expected_receiver, this); this.c_ = v; },
|
||||
};
|
||||
var obj2 = {
|
||||
boom() {
|
||||
super.a++;
|
||||
super[b]++;
|
||||
super[c]++;
|
||||
},
|
||||
}
|
||||
Object.setPrototypeOf(obj2, obj1);
|
||||
|
||||
expected_receiver = obj2;
|
||||
obj2.boom();
|
||||
assertEquals(101, obj2.a);
|
||||
assertEquals(201, obj2[b]);
|
||||
assertEquals(301, obj2[c]);
|
||||
|
||||
expected_receiver = obj1;
|
||||
assertEquals(100, obj1.a);
|
||||
assertEquals(200, obj1[b]);
|
||||
assertEquals(300, obj1[c]);
|
||||
}());
|
Loading…
Reference in New Issue
Block a user