зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug 852092 (Improve DOM list ICs) - part 1, factor out ListBase checks for the Ion IC. r=jandem.
--HG-- extra : rebase_source : b0415e00f84262ad998567bfdd782b0d18a3871a
This commit is contained in:
Родитель
2d1456add4
Коммит
9cd16389c0
|
@ -488,6 +488,63 @@ EmitLoadSlot(MacroAssembler &masm, JSObject *holder, Shape *shape, Register hold
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GenerateListBaseChecks(JSContext *cx, MacroAssembler &masm, JSObject *obj,
|
||||
PropertyName *name, Register object, Label &stubFailure)
|
||||
{
|
||||
MOZ_ASSERT(IsCacheableListBase(obj));
|
||||
|
||||
// Guard the following:
|
||||
// 1. The object is a ListBase.
|
||||
// 2. The object does not have expando properties, or has an expando
|
||||
// which is known to not have the desired property.
|
||||
Address handlerAddr(object, JSObject::getFixedSlotOffset(JSSLOT_PROXY_HANDLER));
|
||||
Address expandoAddr(object, JSObject::getFixedSlotOffset(GetListBaseExpandoSlot()));
|
||||
|
||||
// Check that object is a ListBase.
|
||||
masm.branchPrivatePtr(Assembler::NotEqual, handlerAddr, ImmWord(GetProxyHandler(obj)), &stubFailure);
|
||||
|
||||
// For the remaining code, we need to reserve some registers to load a value.
|
||||
// This is ugly, but unvaoidable.
|
||||
RegisterSet listBaseRegSet(RegisterSet::All());
|
||||
listBaseRegSet.take(AnyRegister(object));
|
||||
ValueOperand tempVal = listBaseRegSet.takeValueOperand();
|
||||
masm.pushValue(tempVal);
|
||||
|
||||
Label failListBaseCheck;
|
||||
Label listBaseOk;
|
||||
|
||||
Value expandoVal = obj->getFixedSlot(GetListBaseExpandoSlot());
|
||||
JSObject *expando = expandoVal.isObject() ? &(expandoVal.toObject()) : NULL;
|
||||
JS_ASSERT_IF(expando, expando->isNative() && expando->getProto() == NULL);
|
||||
|
||||
masm.loadValue(expandoAddr, tempVal);
|
||||
|
||||
// If the incoming object does not have an expando object then we're sure we're not
|
||||
// shadowing.
|
||||
masm.branchTestUndefined(Assembler::Equal, tempVal, &listBaseOk);
|
||||
|
||||
if (expando && !expando->nativeContains(cx, name)) {
|
||||
// Reference object has an expando object that doesn't define the name. Check that
|
||||
// the incoming object has an expando object with the same shape.
|
||||
masm.branchTestObject(Assembler::NotEqual, tempVal, &failListBaseCheck);
|
||||
masm.extractObject(tempVal, tempVal.scratchReg());
|
||||
masm.branchPtr(Assembler::Equal,
|
||||
Address(tempVal.scratchReg(), JSObject::offsetOfShape()),
|
||||
ImmGCPtr(expando->lastProperty()),
|
||||
&listBaseOk);
|
||||
}
|
||||
|
||||
// Failure case: restore the tempVal registers and jump to failures.
|
||||
masm.bind(&failListBaseCheck);
|
||||
masm.popValue(tempVal);
|
||||
masm.jump(&stubFailure);
|
||||
|
||||
// Success case: restore the tempval and proceed.
|
||||
masm.bind(&listBaseOk);
|
||||
masm.popValue(tempVal);
|
||||
}
|
||||
|
||||
static void
|
||||
GenerateReadSlot(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
|
||||
JSObject *obj, JSObject *holder, Shape *shape, Register object,
|
||||
|
@ -618,57 +675,8 @@ GenerateCallGetter(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &
|
|||
masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfShape()),
|
||||
ImmGCPtr(obj->lastProperty()), &stubFailure);
|
||||
|
||||
// If this is a stub for a ListBase object, guard the following:
|
||||
// 1. The object is a ListBase.
|
||||
// 2. The object does not have expando properties, or has an expando
|
||||
// which is known to not have the desired property.
|
||||
if (IsCacheableListBase(obj)) {
|
||||
Address handlerAddr(object, JSObject::getFixedSlotOffset(JSSLOT_PROXY_HANDLER));
|
||||
Address expandoAddr(object, JSObject::getFixedSlotOffset(GetListBaseExpandoSlot()));
|
||||
|
||||
// Check that object is a ListBase.
|
||||
masm.branchPrivatePtr(Assembler::NotEqual, handlerAddr, ImmWord(GetProxyHandler(obj)), &stubFailure);
|
||||
|
||||
// For the remaining code, we need to reserve some registers to load a value.
|
||||
// This is ugly, but unvaoidable.
|
||||
RegisterSet listBaseRegSet(RegisterSet::All());
|
||||
listBaseRegSet.take(AnyRegister(object));
|
||||
ValueOperand tempVal = listBaseRegSet.takeValueOperand();
|
||||
masm.pushValue(tempVal);
|
||||
|
||||
Label failListBaseCheck;
|
||||
Label listBaseOk;
|
||||
|
||||
Value expandoVal = obj->getFixedSlot(GetListBaseExpandoSlot());
|
||||
JSObject *expando = expandoVal.isObject() ? &(expandoVal.toObject()) : NULL;
|
||||
JS_ASSERT_IF(expando, expando->isNative() && expando->getProto() == NULL);
|
||||
|
||||
masm.loadValue(expandoAddr, tempVal);
|
||||
|
||||
// If the incoming object does not have an expando object then we're sure we're not
|
||||
// shadowing.
|
||||
masm.branchTestUndefined(Assembler::Equal, tempVal, &listBaseOk);
|
||||
|
||||
if (expando && !expando->nativeContains(cx, name)) {
|
||||
// Reference object has an expando object that doesn't define the name. Check that
|
||||
// the incoming object has an expando object with the same shape.
|
||||
masm.branchTestObject(Assembler::NotEqual, tempVal, &failListBaseCheck);
|
||||
masm.extractObject(tempVal, tempVal.scratchReg());
|
||||
masm.branchPtr(Assembler::Equal,
|
||||
Address(tempVal.scratchReg(), JSObject::offsetOfShape()),
|
||||
ImmGCPtr(expando->lastProperty()),
|
||||
&listBaseOk);
|
||||
}
|
||||
|
||||
// Failure case: restore the tempVal registers and jump to failures.
|
||||
masm.bind(&failListBaseCheck);
|
||||
masm.popValue(tempVal);
|
||||
masm.jump(&stubFailure);
|
||||
|
||||
// Success case: restore the tempval and proceed.
|
||||
masm.bind(&listBaseOk);
|
||||
masm.popValue(tempVal);
|
||||
}
|
||||
if (IsCacheableListBase(obj))
|
||||
GenerateListBaseChecks(cx, masm, obj, name, object, stubFailure);
|
||||
|
||||
JS_ASSERT(output.hasValue());
|
||||
Register scratchReg = output.valueReg().scratchReg();
|
||||
|
|
Загрузка…
Ссылка в новой задаче