Bug 1269313: IonMonkey - Use TI to break alias between instructions, r=jandem

This commit is contained in:
Hannes Verschore 2016-05-24 07:43:20 +02:00
parent 7ff874f7ba
commit 7e12058989
11 changed files with 208 additions and 203 deletions

View File

@ -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;

View File

@ -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

View File

@ -31,6 +31,10 @@ class AliasAnalysisShared
return true;
}
static MDefinition::AliasType genericMightAlias(const MDefinition* load,
const MDefinition* store);
protected:
void spewDependencyList();

View File

@ -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

View File

@ -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

View File

@ -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
{

View File

@ -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 {

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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