зеркало из https://github.com/mozilla/gecko-dev.git
Fix prototype guards on array hole ICs (bug 615440, r=dmandelin).
This commit is contained in:
Родитель
73e6445027
Коммит
884504296d
|
@ -0,0 +1,5 @@
|
||||||
|
Array.prototype.__proto__ = null;
|
||||||
|
for (var r = 0; r < 3; ++r) [][0] = 1;
|
||||||
|
|
||||||
|
// Don't crash.
|
||||||
|
|
|
@ -2373,24 +2373,21 @@ SetElementIC::attachHoleStub(JSContext *cx, JSObject *obj, int32 keyval)
|
||||||
|
|
||||||
Assembler masm;
|
Assembler masm;
|
||||||
|
|
||||||
// Test for indexed properties in Array.prototype. It is safe to bake in
|
Vector<Jump, 4> fails(cx);
|
||||||
// this pointer because changing __proto__ will slowify.
|
|
||||||
JSObject *arrayProto = obj->getProto();
|
|
||||||
masm.move(ImmPtr(arrayProto), objReg);
|
|
||||||
Jump extendedArray = masm.branchTest32(Assembler::NonZero,
|
|
||||||
Address(objReg, offsetof(JSObject, flags)),
|
|
||||||
Imm32(JSObject::INDEXED));
|
|
||||||
|
|
||||||
// Text for indexed properties in Object.prototype. Guard that
|
// Test for indexed properties in Array.prototype. We test each shape
|
||||||
// Array.prototype doesn't change, too.
|
// along the proto chain. This affords us two optimizations:
|
||||||
JSObject *objProto = arrayProto->getProto();
|
// 1) Loading the prototype can be avoided because the shape would change;
|
||||||
Jump sameProto = masm.branchPtr(Assembler::NotEqual,
|
// instead we can bake in their identities.
|
||||||
Address(objReg, offsetof(JSObject, proto)),
|
// 2) We only have to test the shape, rather than INDEXED.
|
||||||
ImmPtr(objProto));
|
for (JSObject *pobj = obj->getProto(); pobj; pobj = pobj->getProto()) {
|
||||||
masm.move(ImmPtr(objProto), objReg);
|
if (!pobj->isNative())
|
||||||
Jump extendedObject = masm.branchTest32(Assembler::NonZero,
|
return disable(cx, "non-native array prototype");
|
||||||
Address(objReg, offsetof(JSObject, flags)),
|
masm.move(ImmPtr(pobj), objReg);
|
||||||
Imm32(JSObject::INDEXED));
|
Jump j = masm.guardShape(objReg, pobj);
|
||||||
|
if (!fails.append(j))
|
||||||
|
return error(cx);
|
||||||
|
}
|
||||||
|
|
||||||
// Restore |obj|.
|
// Restore |obj|.
|
||||||
masm.rematPayload(StateRemat::FromInt32(objRemat), objReg);
|
masm.rematPayload(StateRemat::FromInt32(objRemat), objReg);
|
||||||
|
@ -2438,9 +2435,8 @@ SetElementIC::attachHoleStub(JSContext *cx, JSObject *obj, int32 keyval)
|
||||||
return disable(cx, "code memory is out of range");
|
return disable(cx, "code memory is out of range");
|
||||||
|
|
||||||
// Patch all guards.
|
// Patch all guards.
|
||||||
buffer.link(extendedArray, slowPathStart);
|
for (size_t i = 0; i < fails.length(); i++)
|
||||||
buffer.link(sameProto, slowPathStart);
|
buffer.link(fails[i], slowPathStart);
|
||||||
buffer.link(extendedObject, slowPathStart);
|
|
||||||
buffer.link(done, fastPathRejoin);
|
buffer.link(done, fastPathRejoin);
|
||||||
|
|
||||||
CodeLocationLabel cs = buffer.finalize();
|
CodeLocationLabel cs = buffer.finalize();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче