mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1388388 - Add a megamorphic SetElement stub. r=evilpie
This commit is contained in:
parent
9f891645fa
commit
0cbf2d7387
@ -2006,6 +2006,42 @@ BaselineCacheIRCompiler::emitCallProxySetByValue()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCacheIRCompiler::emitMegamorphicSetElement()
|
||||
{
|
||||
Register obj = allocator.useRegister(masm, reader.objOperandId());
|
||||
ValueOperand idVal = allocator.useValueRegister(masm, reader.valOperandId());
|
||||
ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
|
||||
bool strict = reader.readBool();
|
||||
|
||||
allocator.discardStack(masm);
|
||||
|
||||
// We need a scratch register but we don't have any registers available on
|
||||
// x86, so temporarily store |obj| in the frame's scratch slot.
|
||||
int scratchOffset = BaselineFrame::reverseOffsetOfScratchValue();
|
||||
masm.storePtr(obj, Address(BaselineFrameReg, scratchOffset));
|
||||
|
||||
AutoStubFrame stubFrame(*this);
|
||||
stubFrame.enter(masm, obj);
|
||||
|
||||
// Restore |obj|. Because we entered a stub frame we first have to load
|
||||
// the original frame pointer.
|
||||
masm.loadPtr(Address(BaselineFrameReg, 0), obj);
|
||||
masm.loadPtr(Address(obj, scratchOffset), obj);
|
||||
|
||||
masm.Push(Imm32(strict));
|
||||
masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj)));
|
||||
masm.Push(val);
|
||||
masm.Push(idVal);
|
||||
masm.Push(obj);
|
||||
|
||||
if (!callVM(masm, SetObjectElementInfo))
|
||||
return false;
|
||||
|
||||
stubFrame.leave(masm);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCacheIRCompiler::emitTypeMonitorResult()
|
||||
{
|
||||
|
@ -2359,11 +2359,6 @@ BaselineCompiler::emit_JSOP_STRICTSETELEM()
|
||||
return emit_JSOP_SETELEM();
|
||||
}
|
||||
|
||||
typedef bool (*SetObjectElementFn)(JSContext*, HandleObject, HandleValue,
|
||||
HandleValue, HandleValue, bool);
|
||||
static const VMFunction SetObjectElementInfo =
|
||||
FunctionInfo<SetObjectElementFn>(js::SetObjectElement, "SetObjectElement");
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_SETELEM_SUPER()
|
||||
{
|
||||
|
@ -2646,6 +2646,10 @@ SetPropIRGenerator::tryAttachStub()
|
||||
return false;
|
||||
|
||||
ObjOperandId objId = writer.guardIsObject(objValId);
|
||||
if (IsPropertySetOp(JSOp(*pc_))) {
|
||||
if (tryAttachMegamorphicSetElement(obj, objId, rhsValId))
|
||||
return true;
|
||||
}
|
||||
if (nameOrSymbol) {
|
||||
if (tryAttachNativeSetSlot(obj, objId, id, rhsValId))
|
||||
return true;
|
||||
@ -3573,6 +3577,26 @@ SetPropIRGenerator::tryAttachProxyElement(HandleObject obj, ObjOperandId objId,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropIRGenerator::tryAttachMegamorphicSetElement(HandleObject obj, ObjOperandId objId,
|
||||
ValOperandId rhsId)
|
||||
{
|
||||
MOZ_ASSERT(IsPropertySetOp(JSOp(*pc_)));
|
||||
|
||||
if (mode_ != ICState::Mode::Megamorphic || cacheKind_ != CacheKind::SetElem)
|
||||
return false;
|
||||
|
||||
// The generic proxy stubs are faster.
|
||||
if (obj->is<ProxyObject>())
|
||||
return false;
|
||||
|
||||
writer.megamorphicSetElement(objId, setElemKeyValueId(), rhsId, IsStrictSetPC(pc_));
|
||||
writer.returnFromIC();
|
||||
|
||||
trackAttached("MegamorphicSetElement");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropIRGenerator::tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, HandleId id,
|
||||
ValOperandId rhsId)
|
||||
|
@ -203,6 +203,7 @@ extern const char* CacheKindNames[];
|
||||
_(MegamorphicLoadSlotResult) \
|
||||
_(MegamorphicLoadSlotByValueResult) \
|
||||
_(MegamorphicStoreSlot) \
|
||||
_(MegamorphicSetElement) \
|
||||
_(MegamorphicHasOwnResult) \
|
||||
\
|
||||
/* See CacheIR.cpp 'DOM proxies' comment. */ \
|
||||
@ -880,6 +881,12 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
|
||||
writeOperandId(rhs);
|
||||
buffer_.writeByte(needsTypeBarrier);
|
||||
}
|
||||
void megamorphicSetElement(ObjOperandId obj, ValOperandId id, ValOperandId rhs, bool strict) {
|
||||
writeOpWithOperandId(CacheOp::MegamorphicSetElement, obj);
|
||||
writeOperandId(id);
|
||||
writeOperandId(rhs);
|
||||
buffer_.writeByte(uint32_t(strict));
|
||||
}
|
||||
void megamorphicHasOwnResult(ObjOperandId obj, ValOperandId id) {
|
||||
writeOpWithOperandId(CacheOp::MegamorphicHasOwnResult, obj);
|
||||
writeOperandId(id);
|
||||
@ -1424,6 +1431,7 @@ class MOZ_RAII SetPropIRGenerator : public IRGenerator
|
||||
ValOperandId rhsId);
|
||||
bool tryAttachProxy(HandleObject obj, ObjOperandId objId, HandleId id, ValOperandId rhsId);
|
||||
bool tryAttachProxyElement(HandleObject obj, ObjOperandId objId, ValOperandId rhsId);
|
||||
bool tryAttachMegamorphicSetElement(HandleObject obj, ObjOperandId objId, ValOperandId rhsId);
|
||||
|
||||
void trackAttached(const char* name);
|
||||
|
||||
|
@ -10211,18 +10211,15 @@ CodeGenerator::visitCallGetElement(LCallGetElement* lir)
|
||||
}
|
||||
}
|
||||
|
||||
typedef bool (*SetObjectElementFn)(JSContext*, HandleObject, HandleValue, HandleValue,
|
||||
bool strict);
|
||||
static const VMFunction SetObjectElementInfo =
|
||||
FunctionInfo<SetObjectElementFn>(SetObjectElement, "SetObjectElement");
|
||||
|
||||
void
|
||||
CodeGenerator::visitCallSetElement(LCallSetElement* lir)
|
||||
{
|
||||
Register obj = ToRegister(lir->getOperand(0));
|
||||
pushArg(Imm32(lir->mir()->strict()));
|
||||
pushArg(TypedOrValueRegister(MIRType::Object, AnyRegister(obj)));
|
||||
pushArg(ToValue(lir, LCallSetElement::Value));
|
||||
pushArg(ToValue(lir, LCallSetElement::Index));
|
||||
pushArg(ToRegister(lir->getOperand(0)));
|
||||
pushArg(obj);
|
||||
callVM(SetObjectElementInfo, lir);
|
||||
}
|
||||
|
||||
|
@ -2066,6 +2066,28 @@ IonCacheIRCompiler::emitCallProxySetByValue()
|
||||
return callVM(masm, ProxySetPropertyByValueInfo);
|
||||
}
|
||||
|
||||
bool
|
||||
IonCacheIRCompiler::emitMegamorphicSetElement()
|
||||
{
|
||||
AutoSaveLiveRegisters save(*this);
|
||||
|
||||
Register obj = allocator.useRegister(masm, reader.objOperandId());
|
||||
ConstantOrRegister idVal = allocator.useConstantOrRegister(masm, reader.valOperandId());
|
||||
ConstantOrRegister val = allocator.useConstantOrRegister(masm, reader.valOperandId());
|
||||
bool strict = reader.readBool();
|
||||
|
||||
allocator.discardStack(masm);
|
||||
prepareVMCall(masm);
|
||||
|
||||
masm.Push(Imm32(strict));
|
||||
masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj)));
|
||||
masm.Push(val);
|
||||
masm.Push(idVal);
|
||||
masm.Push(obj);
|
||||
|
||||
return callVM(masm, SetObjectElementInfo);
|
||||
}
|
||||
|
||||
bool
|
||||
IonCacheIRCompiler::emitLoadTypedObjectResult()
|
||||
{
|
||||
|
@ -1820,5 +1820,10 @@ GetPrototypeOf(JSContext* cx, HandleObject target, MutableHandleValue rval)
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*SetObjectElementFn)(JSContext*, HandleObject, HandleValue,
|
||||
HandleValue, HandleValue, bool);
|
||||
const VMFunction SetObjectElementInfo =
|
||||
FunctionInfo<SetObjectElementFn>(js::SetObjectElement, "SetObjectElement");
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
@ -892,6 +892,8 @@ TypeOfObject(JSObject* obj, JSRuntime* rt);
|
||||
bool
|
||||
GetPrototypeOf(JSContext* cx, HandleObject target, MutableHandleValue rval);
|
||||
|
||||
extern const VMFunction SetObjectElementInfo;
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user