mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-25 11:15:34 +00:00
Bug 1269313: IonMonkey - Use TI to break alias between instructions, r=jandem
This commit is contained in:
parent
7ff874f7ba
commit
7e12058989
@ -195,7 +195,8 @@ AliasAnalysis::analyze()
|
||||
MInstructionVector& aliasedStores = stores[*iter];
|
||||
for (int i = aliasedStores.length() - 1; i >= 0; i--) {
|
||||
MInstruction* store = aliasedStores[i];
|
||||
if (def->mightAlias(store) != MDefinition::AliasType::NoAlias &&
|
||||
if (genericMightAlias(*def, store) != MDefinition::AliasType::NoAlias &&
|
||||
def->mightAlias(store) != MDefinition::AliasType::NoAlias &&
|
||||
BlockMightReach(store->block(), *block))
|
||||
{
|
||||
if (lastStore->id() < store->id())
|
||||
@ -242,7 +243,9 @@ AliasAnalysis::analyze()
|
||||
MInstruction* store = aliasedStores[i];
|
||||
if (store->id() < firstLoopIns->id())
|
||||
break;
|
||||
if (ins->mightAlias(store) != MDefinition::AliasType::NoAlias) {
|
||||
if (genericMightAlias(ins, store) != MDefinition::AliasType::NoAlias &&
|
||||
ins->mightAlias(store) != MDefinition::AliasType::NoAlias)
|
||||
{
|
||||
hasAlias = true;
|
||||
IonSpewDependency(ins, store, "aliases", "store in loop body");
|
||||
break;
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "jit/AliasAnalysisShared.h"
|
||||
|
||||
#include "jit/MIR.h"
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
@ -40,5 +42,144 @@ AliasAnalysisShared::spewDependencyList()
|
||||
#endif
|
||||
}
|
||||
|
||||
// Unwrap any slot or element to its corresponding object.
|
||||
static inline const MDefinition*
|
||||
MaybeUnwrap(const MDefinition* object)
|
||||
{
|
||||
|
||||
while (object->isSlots() || object->isElements() || object->isConvertElementsToDoubles() ||
|
||||
object->isTypedArrayElements() || object->isTypedObjectElements())
|
||||
{
|
||||
MOZ_ASSERT(object->numOperands() == 1);
|
||||
object = object->getOperand(0);
|
||||
}
|
||||
|
||||
if (object->isConstantElements())
|
||||
return nullptr;
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
// Get the object of any load/store. Returns nullptr if not tied to
|
||||
// an object.
|
||||
static inline const MDefinition*
|
||||
GetObject(const MDefinition* ins)
|
||||
{
|
||||
if (!ins->getAliasSet().isStore() && !ins->getAliasSet().isLoad())
|
||||
return nullptr;
|
||||
|
||||
const MDefinition* object = nullptr;
|
||||
switch (ins->op()) {
|
||||
case MDefinition::Op_GetPropertyCache:
|
||||
if (!ins->toGetPropertyCache()->idempotent())
|
||||
return nullptr;
|
||||
object = ins->getOperand(0);
|
||||
break;
|
||||
case MDefinition::Op_InitializedLength:
|
||||
case MDefinition::Op_LoadElement:
|
||||
case MDefinition::Op_LoadUnboxedScalar:
|
||||
case MDefinition::Op_LoadUnboxedObjectOrNull:
|
||||
case MDefinition::Op_LoadUnboxedString:
|
||||
case MDefinition::Op_StoreElement:
|
||||
case MDefinition::Op_StoreUnboxedObjectOrNull:
|
||||
case MDefinition::Op_StoreUnboxedString:
|
||||
case MDefinition::Op_StoreUnboxedScalar:
|
||||
case MDefinition::Op_SetInitializedLength:
|
||||
case MDefinition::Op_ArrayLength:
|
||||
case MDefinition::Op_SetArrayLength:
|
||||
case MDefinition::Op_StoreElementHole:
|
||||
case MDefinition::Op_TypedObjectDescr:
|
||||
case MDefinition::Op_Slots:
|
||||
case MDefinition::Op_Elements:
|
||||
case MDefinition::Op_MaybeCopyElementsForWrite:
|
||||
case MDefinition::Op_MaybeToDoubleElement:
|
||||
case MDefinition::Op_UnboxedArrayLength:
|
||||
case MDefinition::Op_UnboxedArrayInitializedLength:
|
||||
case MDefinition::Op_IncrementUnboxedArrayInitializedLength:
|
||||
case MDefinition::Op_SetUnboxedArrayInitializedLength:
|
||||
case MDefinition::Op_TypedArrayLength:
|
||||
case MDefinition::Op_SetTypedObjectOffset:
|
||||
case MDefinition::Op_SetDisjointTypedElements:
|
||||
case MDefinition::Op_ArrayPopShift:
|
||||
case MDefinition::Op_ArrayPush:
|
||||
case MDefinition::Op_ArraySlice:
|
||||
case MDefinition::Op_LoadTypedArrayElementHole:
|
||||
case MDefinition::Op_StoreTypedArrayElementHole:
|
||||
case MDefinition::Op_LoadFixedSlot:
|
||||
case MDefinition::Op_LoadFixedSlotAndUnbox:
|
||||
case MDefinition::Op_StoreFixedSlot:
|
||||
case MDefinition::Op_GetPropertyPolymorphic:
|
||||
case MDefinition::Op_SetPropertyPolymorphic:
|
||||
case MDefinition::Op_GuardShape:
|
||||
case MDefinition::Op_GuardReceiverPolymorphic:
|
||||
case MDefinition::Op_GuardObjectGroup:
|
||||
case MDefinition::Op_GuardObjectIdentity:
|
||||
case MDefinition::Op_GuardClass:
|
||||
case MDefinition::Op_GuardUnboxedExpando:
|
||||
case MDefinition::Op_LoadUnboxedExpando:
|
||||
case MDefinition::Op_LoadSlot:
|
||||
case MDefinition::Op_StoreSlot:
|
||||
case MDefinition::Op_InArray:
|
||||
case MDefinition::Op_LoadElementHole:
|
||||
case MDefinition::Op_TypedArrayElements:
|
||||
case MDefinition::Op_TypedObjectElements:
|
||||
object = ins->getOperand(0);
|
||||
break;
|
||||
case MDefinition::Op_LoadTypedArrayElementStatic:
|
||||
case MDefinition::Op_StoreTypedArrayElementStatic:
|
||||
case MDefinition::Op_GetDOMProperty:
|
||||
case MDefinition::Op_GetDOMMember:
|
||||
case MDefinition::Op_Call:
|
||||
case MDefinition::Op_Compare:
|
||||
case MDefinition::Op_GetArgumentsObjectArg:
|
||||
case MDefinition::Op_SetArgumentsObjectArg:
|
||||
case MDefinition::Op_GetFrameArgument:
|
||||
case MDefinition::Op_SetFrameArgument:
|
||||
case MDefinition::Op_CompareExchangeTypedArrayElement:
|
||||
case MDefinition::Op_AtomicExchangeTypedArrayElement:
|
||||
case MDefinition::Op_AtomicTypedArrayElementBinop:
|
||||
case MDefinition::Op_AsmJSLoadHeap:
|
||||
case MDefinition::Op_AsmJSStoreHeap:
|
||||
case MDefinition::Op_AsmJSCompareExchangeHeap:
|
||||
case MDefinition::Op_AsmJSAtomicBinopHeap:
|
||||
case MDefinition::Op_AsmJSLoadGlobalVar:
|
||||
case MDefinition::Op_AsmJSStoreGlobalVar:
|
||||
case MDefinition::Op_ArrayJoin:
|
||||
return nullptr;
|
||||
default:
|
||||
#ifdef DEBUG
|
||||
// Crash when the default aliasSet is overriden, but when not added in the list above.
|
||||
if (!ins->getAliasSet().isStore() || ins->getAliasSet().flags() != AliasSet::Flag::Any)
|
||||
MOZ_CRASH("Overridden getAliasSet without updating AliasAnalysisShared GetObject");
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!ins->getAliasSet().isStore() || ins->getAliasSet().flags() != AliasSet::Flag::Any);
|
||||
object = MaybeUnwrap(object);
|
||||
MOZ_ASSERT_IF(object, object->type() == MIRType::Object);
|
||||
return object;
|
||||
}
|
||||
|
||||
// Generic comparing if a load aliases a store using TI information.
|
||||
MDefinition::AliasType
|
||||
AliasAnalysisShared::genericMightAlias(const MDefinition* load, const MDefinition* store)
|
||||
{
|
||||
const MDefinition* loadObject = GetObject(load);
|
||||
const MDefinition* storeObject = GetObject(store);
|
||||
if (!loadObject || !storeObject)
|
||||
return MDefinition::AliasType::MayAlias;
|
||||
|
||||
if (!loadObject->resultTypeSet() || !storeObject->resultTypeSet())
|
||||
return MDefinition::AliasType::MayAlias;
|
||||
|
||||
if (loadObject->resultTypeSet()->objectsIntersect(storeObject->resultTypeSet()))
|
||||
return MDefinition::AliasType::MayAlias;
|
||||
|
||||
return MDefinition::AliasType::NoAlias;
|
||||
}
|
||||
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
@ -31,6 +31,10 @@ class AliasAnalysisShared
|
||||
return true;
|
||||
}
|
||||
|
||||
static MDefinition::AliasType genericMightAlias(const MDefinition* load,
|
||||
const MDefinition* store);
|
||||
|
||||
|
||||
protected:
|
||||
void spewDependencyList();
|
||||
|
||||
|
@ -211,12 +211,18 @@ LoadAliasesStore(MDefinition* load, MDefinition* store)
|
||||
if ((load->getAliasSet() & store->getAliasSet()).isNone())
|
||||
return false;
|
||||
|
||||
// Check if the instruction might alias eachother.
|
||||
MDefinition::AliasType type = load->mightAlias(store);
|
||||
if (type != MDefinition::AliasType::NoAlias)
|
||||
return true;
|
||||
// On any operation that has a specific alias category we can use TI to know
|
||||
// the objects operating on don't intersect.
|
||||
MDefinition::AliasType mightAlias = AliasAnalysisShared::genericMightAlias(load, store);
|
||||
if (mightAlias == MDefinition::AliasType::NoAlias)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
// Check if the instruction might alias eachother.
|
||||
mightAlias = load->mightAlias(store);
|
||||
if (mightAlias == MDefinition::AliasType::NoAlias)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef JS_JITSPEW
|
||||
|
@ -3610,17 +3610,17 @@ LIRGenerator::visitGetPropertyCache(MGetPropertyCache* ins)
|
||||
void
|
||||
LIRGenerator::visitGetPropertyPolymorphic(MGetPropertyPolymorphic* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->obj()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
if (ins->type() == MIRType::Value) {
|
||||
LGetPropertyPolymorphicV* lir =
|
||||
new(alloc()) LGetPropertyPolymorphicV(useRegister(ins->obj()));
|
||||
new(alloc()) LGetPropertyPolymorphicV(useRegister(ins->object()));
|
||||
assignSnapshot(lir, Bailout_ShapeGuard);
|
||||
defineBox(lir, ins);
|
||||
} else {
|
||||
LDefinition maybeTemp = (ins->type() == MIRType::Double) ? temp() : LDefinition::BogusTemp();
|
||||
LGetPropertyPolymorphicT* lir =
|
||||
new(alloc()) LGetPropertyPolymorphicT(useRegister(ins->obj()), maybeTemp);
|
||||
new(alloc()) LGetPropertyPolymorphicT(useRegister(ins->object()), maybeTemp);
|
||||
assignSnapshot(lir, Bailout_ShapeGuard);
|
||||
define(lir, ins);
|
||||
}
|
||||
@ -3629,11 +3629,11 @@ LIRGenerator::visitGetPropertyPolymorphic(MGetPropertyPolymorphic* ins)
|
||||
void
|
||||
LIRGenerator::visitSetPropertyPolymorphic(MSetPropertyPolymorphic* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->obj()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
if (ins->value()->type() == MIRType::Value) {
|
||||
LSetPropertyPolymorphicV* lir =
|
||||
new(alloc()) LSetPropertyPolymorphicV(useRegister(ins->obj()),
|
||||
new(alloc()) LSetPropertyPolymorphicV(useRegister(ins->object()),
|
||||
useBox(ins->value()),
|
||||
temp());
|
||||
assignSnapshot(lir, Bailout_ShapeGuard);
|
||||
@ -3641,7 +3641,7 @@ LIRGenerator::visitSetPropertyPolymorphic(MSetPropertyPolymorphic* ins)
|
||||
} else {
|
||||
LAllocation value = useRegisterOrConstant(ins->value());
|
||||
LSetPropertyPolymorphicT* lir =
|
||||
new(alloc()) LSetPropertyPolymorphicT(useRegister(ins->obj()), value,
|
||||
new(alloc()) LSetPropertyPolymorphicT(useRegister(ins->object()), value,
|
||||
ins->value()->type(), temp());
|
||||
assignSnapshot(lir, Bailout_ShapeGuard);
|
||||
add(lir, ins);
|
||||
@ -3672,18 +3672,18 @@ LIRGenerator::visitCallBindVar(MCallBindVar* ins)
|
||||
void
|
||||
LIRGenerator::visitGuardObjectIdentity(MGuardObjectIdentity* ins)
|
||||
{
|
||||
LGuardObjectIdentity* guard = new(alloc()) LGuardObjectIdentity(useRegister(ins->obj()),
|
||||
LGuardObjectIdentity* guard = new(alloc()) LGuardObjectIdentity(useRegister(ins->object()),
|
||||
useRegister(ins->expected()));
|
||||
assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard);
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->obj());
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitGuardClass(MGuardClass* ins)
|
||||
{
|
||||
LDefinition t = temp();
|
||||
LGuardClass* guard = new(alloc()) LGuardClass(useRegister(ins->obj()), t);
|
||||
LGuardClass* guard = new(alloc()) LGuardClass(useRegister(ins->object()), t);
|
||||
assignSnapshot(guard, Bailout_ObjectIdentityOrTypeGuard);
|
||||
add(guard, ins);
|
||||
}
|
||||
@ -3711,7 +3711,7 @@ LIRGenerator::visitGuardSharedTypedArray(MGuardSharedTypedArray* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->input()->type() == MIRType::Object);
|
||||
LGuardSharedTypedArray* guard =
|
||||
new(alloc()) LGuardSharedTypedArray(useRegister(ins->obj()), temp());
|
||||
new(alloc()) LGuardSharedTypedArray(useRegister(ins->object()), temp());
|
||||
assignSnapshot(guard, Bailout_NonSharedTypedArrayInput);
|
||||
add(guard, ins);
|
||||
}
|
||||
@ -3726,24 +3726,24 @@ LIRGenerator::visitPolyInlineGuard(MPolyInlineGuard* ins)
|
||||
void
|
||||
LIRGenerator::visitGuardReceiverPolymorphic(MGuardReceiverPolymorphic* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->obj()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->type() == MIRType::Object);
|
||||
|
||||
LGuardReceiverPolymorphic* guard =
|
||||
new(alloc()) LGuardReceiverPolymorphic(useRegister(ins->obj()), temp());
|
||||
new(alloc()) LGuardReceiverPolymorphic(useRegister(ins->object()), temp());
|
||||
assignSnapshot(guard, Bailout_ShapeGuard);
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->obj());
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitGuardUnboxedExpando(MGuardUnboxedExpando* ins)
|
||||
{
|
||||
LGuardUnboxedExpando* guard =
|
||||
new(alloc()) LGuardUnboxedExpando(useRegister(ins->obj()));
|
||||
new(alloc()) LGuardUnboxedExpando(useRegister(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->obj());
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4865,148 +4865,6 @@ MLoadUnboxedObjectOrNull::foldsTo(TempAllocator& alloc)
|
||||
return foldsToStoredValue(alloc, store->value());
|
||||
}
|
||||
|
||||
// Gets the MDefinition* representing the source/target object's storage.
|
||||
// Usually this is just an MElements*, but sometimes there are layers
|
||||
// of indirection or inlining, which are handled elsewhere.
|
||||
static inline const MElements*
|
||||
MaybeUnwrapElements(const MDefinition* elementsOrObj)
|
||||
{
|
||||
// Sometimes there is a level of indirection for conversion.
|
||||
if (elementsOrObj->isConvertElementsToDoubles())
|
||||
return MaybeUnwrapElements(elementsOrObj->toConvertElementsToDoubles()->elements());
|
||||
|
||||
// For inline elements, the object may be passed directly, for example as MUnbox.
|
||||
if (elementsOrObj->type() == MIRType::Object)
|
||||
return nullptr;
|
||||
|
||||
// MTypedArrayElements and MTypedObjectElements aren't handled.
|
||||
if (!elementsOrObj->isElements())
|
||||
return nullptr;
|
||||
|
||||
return elementsOrObj->toElements();
|
||||
}
|
||||
|
||||
static inline const MDefinition*
|
||||
GetElementsObject(const MDefinition* elementsOrObj)
|
||||
{
|
||||
if (elementsOrObj->type() == MIRType::Object)
|
||||
return elementsOrObj;
|
||||
|
||||
const MDefinition* elements = MaybeUnwrapElements(elementsOrObj);
|
||||
if (elements)
|
||||
return elements->toElements()->input();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Gets the MDefinition of the target Object for the given store operation.
|
||||
static inline const MDefinition*
|
||||
GetStoreObject(const MDefinition* store)
|
||||
{
|
||||
switch (store->op()) {
|
||||
case MDefinition::Op_StoreElement:
|
||||
return GetElementsObject(store->toStoreElement()->elements());
|
||||
|
||||
case MDefinition::Op_StoreElementHole:
|
||||
return store->toStoreElementHole()->object();
|
||||
|
||||
case MDefinition::Op_StoreUnboxedObjectOrNull:
|
||||
return GetElementsObject(store->toStoreUnboxedObjectOrNull()->elements());
|
||||
|
||||
case MDefinition::Op_StoreUnboxedString:
|
||||
return GetElementsObject(store->toStoreUnboxedString()->elements());
|
||||
|
||||
case MDefinition::Op_StoreUnboxedScalar:
|
||||
return GetElementsObject(store->toStoreUnboxedScalar()->elements());
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Implements mightAlias() logic common to all load operations.
|
||||
static MDefinition::AliasType
|
||||
GenericLoadMightAlias(const MDefinition* elementsOrObj, const MDefinition* store)
|
||||
{
|
||||
const MElements* elements = MaybeUnwrapElements(elementsOrObj);
|
||||
if (elements)
|
||||
return elements->mightAlias(store);
|
||||
|
||||
// Unhandled Elements kind.
|
||||
if (elementsOrObj->type() != MIRType::Object)
|
||||
return MDefinition::AliasType::MayAlias;
|
||||
|
||||
// Inline storage for objects.
|
||||
// Refer to IsValidElementsType().
|
||||
const MDefinition* object = elementsOrObj;
|
||||
MOZ_ASSERT(object->type() == MIRType::Object);
|
||||
if (!object->resultTypeSet())
|
||||
return MDefinition::AliasType::MayAlias;
|
||||
|
||||
const MDefinition* storeObject = GetStoreObject(store);
|
||||
if (!storeObject)
|
||||
return MDefinition::AliasType::MayAlias;
|
||||
if (!storeObject->resultTypeSet())
|
||||
return MDefinition::AliasType::MayAlias;
|
||||
|
||||
if (object->resultTypeSet()->objectsIntersect(storeObject->resultTypeSet()))
|
||||
return MDefinition::AliasType::MayAlias;
|
||||
return MDefinition::AliasType::NoAlias;
|
||||
}
|
||||
|
||||
MDefinition::AliasType
|
||||
MElements::mightAlias(const MDefinition* store) const
|
||||
{
|
||||
if (!input()->resultTypeSet())
|
||||
return AliasType::MayAlias;
|
||||
|
||||
const MDefinition* storeObj = GetStoreObject(store);
|
||||
if (!storeObj)
|
||||
return AliasType::MayAlias;
|
||||
if (!storeObj->resultTypeSet())
|
||||
return AliasType::MayAlias;
|
||||
|
||||
if (input()->resultTypeSet()->objectsIntersect(storeObj->resultTypeSet()))
|
||||
return AliasType::MayAlias;
|
||||
return AliasType::NoAlias;
|
||||
}
|
||||
|
||||
MDefinition::AliasType
|
||||
MLoadElement::mightAlias(const MDefinition* store) const
|
||||
{
|
||||
return GenericLoadMightAlias(elements(), store);
|
||||
}
|
||||
|
||||
MDefinition::AliasType
|
||||
MInitializedLength::mightAlias(const MDefinition* store) const
|
||||
{
|
||||
return GenericLoadMightAlias(elements(), store);
|
||||
}
|
||||
|
||||
MDefinition::AliasType
|
||||
MLoadUnboxedObjectOrNull::mightAlias(const MDefinition* store) const
|
||||
{
|
||||
return GenericLoadMightAlias(elements(), store);
|
||||
}
|
||||
|
||||
MDefinition::AliasType
|
||||
MLoadUnboxedString::mightAlias(const MDefinition* store) const
|
||||
{
|
||||
return GenericLoadMightAlias(elements(), store);
|
||||
}
|
||||
|
||||
MDefinition::AliasType
|
||||
MLoadUnboxedScalar::mightAlias(const MDefinition* store) const
|
||||
{
|
||||
return GenericLoadMightAlias(elements(), store);
|
||||
}
|
||||
|
||||
MDefinition::AliasType
|
||||
MUnboxedArrayInitializedLength::mightAlias(const MDefinition* store) const
|
||||
{
|
||||
return GenericLoadMightAlias(object(), store);
|
||||
}
|
||||
|
||||
bool
|
||||
MGuardReceiverPolymorphic::congruentTo(const MDefinition* ins) const
|
||||
{
|
||||
|
@ -8534,7 +8534,6 @@ class MElements
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
AliasType mightAlias(const MDefinition* store) const override;
|
||||
|
||||
ALLOW_CLONE(MElements)
|
||||
};
|
||||
@ -8728,7 +8727,6 @@ class MInitializedLength
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
AliasType mightAlias(const MDefinition* store) const override;
|
||||
|
||||
void computeRange(TempAllocator& alloc) override;
|
||||
|
||||
@ -8826,7 +8824,6 @@ class MUnboxedArrayInitializedLength
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
AliasType mightAlias(const MDefinition* store) const override;
|
||||
|
||||
ALLOW_CLONE(MUnboxedArrayInitializedLength)
|
||||
};
|
||||
@ -9458,7 +9455,6 @@ class MLoadElement
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::Load(AliasSet::Element);
|
||||
}
|
||||
AliasType mightAlias(const MDefinition* store) const override;
|
||||
|
||||
ALLOW_CLONE(MLoadElement)
|
||||
};
|
||||
@ -9615,7 +9611,6 @@ class MLoadUnboxedObjectOrNull
|
||||
return AliasSet::Load(AliasSet::UnboxedElement);
|
||||
}
|
||||
MDefinition* foldsTo(TempAllocator& alloc) override;
|
||||
AliasType mightAlias(const MDefinition* store) const override;
|
||||
|
||||
ALLOW_CLONE(MLoadUnboxedObjectOrNull)
|
||||
};
|
||||
@ -9665,7 +9660,6 @@ class MLoadUnboxedString
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::Load(AliasSet::UnboxedElement);
|
||||
}
|
||||
AliasType mightAlias(const MDefinition* store) const override;
|
||||
|
||||
ALLOW_CLONE(MLoadUnboxedString)
|
||||
};
|
||||
@ -10273,7 +10267,6 @@ class MLoadUnboxedScalar
|
||||
return AliasSet::Store(AliasSet::UnboxedElement);
|
||||
return AliasSet::Load(AliasSet::UnboxedElement);
|
||||
}
|
||||
AliasType mightAlias(const MDefinition* store) const override;
|
||||
|
||||
bool congruentTo(const MDefinition* ins) const override {
|
||||
if (requiresBarrier_)
|
||||
@ -11150,7 +11143,7 @@ class MGetPropertyPolymorphic
|
||||
PropertyName* name() const {
|
||||
return name_;
|
||||
}
|
||||
MDefinition* obj() const {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
AliasSet getAliasSet() const override {
|
||||
@ -11223,7 +11216,7 @@ class MSetPropertyPolymorphic
|
||||
PropertyName* name() const {
|
||||
return name_;
|
||||
}
|
||||
MDefinition* obj() const {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
MDefinition* value() const {
|
||||
@ -11509,7 +11502,7 @@ class MGuardShape
|
||||
return new(alloc) MGuardShape(obj, shape, bailoutKind);
|
||||
}
|
||||
|
||||
MDefinition* obj() const {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
const Shape* shape() const {
|
||||
@ -11556,7 +11549,7 @@ class MGuardReceiverPolymorphic
|
||||
return new(alloc) MGuardReceiverPolymorphic(alloc, obj);
|
||||
}
|
||||
|
||||
MDefinition* obj() const {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
|
||||
@ -11611,7 +11604,7 @@ class MGuardObjectGroup
|
||||
return new(alloc) MGuardObjectGroup(obj, group, bailOnEquality, bailoutKind);
|
||||
}
|
||||
|
||||
MDefinition* obj() const {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
const ObjectGroup* group() const {
|
||||
@ -11663,7 +11656,7 @@ class MGuardObjectIdentity
|
||||
return new(alloc) MGuardObjectIdentity(obj, expected, bailOnEquality);
|
||||
}
|
||||
|
||||
MDefinition* obj() const {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
MDefinition* expected() const {
|
||||
@ -11706,7 +11699,7 @@ class MGuardClass
|
||||
return new(alloc) MGuardClass(obj, clasp);
|
||||
}
|
||||
|
||||
MDefinition* obj() const {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
const Class* getClass() const {
|
||||
@ -11752,7 +11745,7 @@ class MGuardUnboxedExpando
|
||||
return new(alloc) MGuardUnboxedExpando(obj, requireExpando, bailoutKind);
|
||||
}
|
||||
|
||||
MDefinition* obj() const {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
bool requireExpando() const {
|
||||
@ -12363,7 +12356,7 @@ class MSetDOMProperty
|
||||
return func_;
|
||||
}
|
||||
|
||||
MDefinition* object() {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
|
||||
@ -12465,7 +12458,7 @@ class MGetDOMProperty
|
||||
bool valueMayBeInSlot() const {
|
||||
return info_->isLazilyCachedInSlot;
|
||||
}
|
||||
MDefinition* object() {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
|
||||
@ -13910,7 +13903,7 @@ public:
|
||||
static MGuardSharedTypedArray* New(TempAllocator& alloc, MDefinition* obj) {
|
||||
return new(alloc) MGuardSharedTypedArray(obj);
|
||||
}
|
||||
MDefinition* obj() const {
|
||||
MDefinition* object() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
AliasSet getAliasSet() const override {
|
||||
|
@ -565,7 +565,7 @@ ObjectMemoryView::visitStoreSlot(MStoreSlot* ins)
|
||||
MSlots* slots = ins->slots()->toSlots();
|
||||
if (slots->object() != obj_) {
|
||||
// Guard objects are replaced when they are visited.
|
||||
MOZ_ASSERT(!slots->object()->isGuardShape() || slots->object()->toGuardShape()->obj() != obj_);
|
||||
MOZ_ASSERT(!slots->object()->isGuardShape() || slots->object()->toGuardShape()->object() != obj_);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -597,7 +597,7 @@ ObjectMemoryView::visitLoadSlot(MLoadSlot* ins)
|
||||
MSlots* slots = ins->slots()->toSlots();
|
||||
if (slots->object() != obj_) {
|
||||
// Guard objects are replaced when they are visited.
|
||||
MOZ_ASSERT(!slots->object()->isGuardShape() || slots->object()->toGuardShape()->obj() != obj_);
|
||||
MOZ_ASSERT(!slots->object()->isGuardShape() || slots->object()->toGuardShape()->object() != obj_);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -620,7 +620,7 @@ void
|
||||
ObjectMemoryView::visitGuardShape(MGuardShape* ins)
|
||||
{
|
||||
// Skip loads made on other objects.
|
||||
if (ins->obj() != obj_)
|
||||
if (ins->object() != obj_)
|
||||
return;
|
||||
|
||||
// Replace the shape guard by its object.
|
||||
|
@ -377,25 +377,25 @@ LIRGeneratorARM::newLTableSwitchV(MTableSwitch* tableswitch)
|
||||
void
|
||||
LIRGeneratorARM::visitGuardShape(MGuardShape* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->obj()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LDefinition tempObj = temp(LDefinition::OBJECT);
|
||||
LGuardShape* guard = new(alloc()) LGuardShape(useRegister(ins->obj()), tempObj);
|
||||
LGuardShape* guard = new(alloc()) LGuardShape(useRegister(ins->object()), tempObj);
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->obj());
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorARM::visitGuardObjectGroup(MGuardObjectGroup* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->obj()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LDefinition tempObj = temp(LDefinition::OBJECT);
|
||||
LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegister(ins->obj()), tempObj);
|
||||
LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegister(ins->object()), tempObj);
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->obj());
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -226,25 +226,25 @@ LIRGeneratorMIPSShared::newLTableSwitchV(MTableSwitch* tableswitch)
|
||||
void
|
||||
LIRGeneratorMIPSShared::visitGuardShape(MGuardShape* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->obj()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LDefinition tempObj = temp(LDefinition::OBJECT);
|
||||
LGuardShape* guard = new(alloc()) LGuardShape(useRegister(ins->obj()), tempObj);
|
||||
LGuardShape* guard = new(alloc()) LGuardShape(useRegister(ins->object()), tempObj);
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->obj());
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorMIPSShared::visitGuardObjectGroup(MGuardObjectGroup* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->obj()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LDefinition tempObj = temp(LDefinition::OBJECT);
|
||||
LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegister(ins->obj()), tempObj);
|
||||
LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegister(ins->object()), tempObj);
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->obj());
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -36,23 +36,23 @@ LIRGeneratorX86Shared::newLTableSwitchV(MTableSwitch* tableswitch)
|
||||
void
|
||||
LIRGeneratorX86Shared::visitGuardShape(MGuardShape* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->obj()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LGuardShape* guard = new(alloc()) LGuardShape(useRegisterAtStart(ins->obj()));
|
||||
LGuardShape* guard = new(alloc()) LGuardShape(useRegisterAtStart(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->obj());
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGeneratorX86Shared::visitGuardObjectGroup(MGuardObjectGroup* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->obj()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
|
||||
|
||||
LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegisterAtStart(ins->obj()));
|
||||
LGuardObjectGroup* guard = new(alloc()) LGuardObjectGroup(useRegisterAtStart(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->obj());
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user