зеркало из https://github.com/mozilla/gecko-dev.git
Bug 937674 - Don't instantiate types when adding type object guards around type write barriers, r=jandem.
This commit is contained in:
Родитель
d4e678eb60
Коммит
f7c2610507
|
@ -1417,6 +1417,18 @@ CodeGenerator::visitGuardThreadLocalObject(LGuardThreadLocalObject *lir)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitGuardObjectIdentity(LGuardObjectIdentity *guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
|
||||
masm.cmpPtr(obj, ImmGCPtr(guard->mir()->singleObject()));
|
||||
|
||||
Assembler::Condition cond =
|
||||
guard->mir()->bailOnEquality() ? Assembler::Equal : Assembler::NotEqual;
|
||||
return bailoutIf(cond, guard->snapshot());
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitTypeBarrierV(LTypeBarrierV *lir)
|
||||
{
|
||||
|
|
|
@ -101,6 +101,7 @@ class CodeGenerator : public CodeGeneratorSpecific
|
|||
bool visitElements(LElements *lir);
|
||||
bool visitConvertElementsToDoubles(LConvertElementsToDoubles *lir);
|
||||
bool visitMaybeToDoubleElement(LMaybeToDoubleElement *lir);
|
||||
bool visitGuardObjectIdentity(LGuardObjectIdentity *guard);
|
||||
bool visitTypeBarrierV(LTypeBarrierV *lir);
|
||||
bool visitTypeBarrierO(LTypeBarrierO *lir);
|
||||
bool visitMonitorTypes(LMonitorTypes *lir);
|
||||
|
|
|
@ -5109,6 +5109,20 @@ class LPostWriteBarrierAllSlots : public LInstructionHelper<0, 1, 0>
|
|||
}
|
||||
};
|
||||
|
||||
// Guard against an object's identity.
|
||||
class LGuardObjectIdentity : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardObjectIdentity)
|
||||
|
||||
LGuardObjectIdentity(const LAllocation &in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardObjectIdentity *mir() const {
|
||||
return mir_->toGuardObjectIdentity();
|
||||
}
|
||||
};
|
||||
|
||||
// Guard against an object's class.
|
||||
class LGuardClass : public LInstructionHelper<0, 1, 1>
|
||||
{
|
||||
|
|
|
@ -163,6 +163,7 @@
|
|||
_(StoreSlotT) \
|
||||
_(GuardShape) \
|
||||
_(GuardObjectType) \
|
||||
_(GuardObjectIdentity) \
|
||||
_(GuardClass) \
|
||||
_(GuardThreadLocalObject) \
|
||||
_(TypeBarrierV) \
|
||||
|
|
|
@ -2830,6 +2830,13 @@ LIRGenerator::visitBindNameCache(MBindNameCache *ins)
|
|||
return define(lir, ins) && assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitGuardObjectIdentity(MGuardObjectIdentity *ins)
|
||||
{
|
||||
LGuardObjectIdentity *guard = new LGuardObjectIdentity(useRegister(ins->obj()));
|
||||
return assignSnapshot(guard) && add(guard, ins) && redefine(ins, ins->obj());
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitGuardClass(MGuardClass *ins)
|
||||
{
|
||||
|
|
|
@ -212,6 +212,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
|||
bool visitSetPropertyPolymorphic(MSetPropertyPolymorphic *ins);
|
||||
bool visitGetElementCache(MGetElementCache *ins);
|
||||
bool visitBindNameCache(MBindNameCache *ins);
|
||||
bool visitGuardObjectIdentity(MGuardObjectIdentity *ins);
|
||||
bool visitGuardClass(MGuardClass *ins);
|
||||
bool visitGuardObject(MGuardObject *ins);
|
||||
bool visitGuardString(MGuardString *ins);
|
||||
|
|
|
@ -3156,10 +3156,16 @@ TryAddTypeBarrierForWrite(types::CompilerConstraintList *constraints,
|
|||
}
|
||||
|
||||
static MInstruction *
|
||||
AddTypeGuard(MBasicBlock *current, MDefinition *obj, types::TypeObject *typeObject,
|
||||
AddTypeGuard(MBasicBlock *current, MDefinition *obj, types::TypeObjectKey *type,
|
||||
bool bailOnEquality)
|
||||
{
|
||||
MGuardObjectType *guard = MGuardObjectType::New(obj, typeObject, bailOnEquality);
|
||||
MInstruction *guard;
|
||||
|
||||
if (type->isTypeObject())
|
||||
guard = MGuardObjectType::New(obj, type->asTypeObject(), bailOnEquality);
|
||||
else
|
||||
guard = MGuardObjectIdentity::New(obj, type->asSingleObject(), bailOnEquality);
|
||||
|
||||
current->add(guard);
|
||||
|
||||
// For now, never move type object guards.
|
||||
|
@ -3223,7 +3229,7 @@ jit::PropertyWriteNeedsTypeBarrier(types::CompilerConstraintList *constraints,
|
|||
if (types->getObjectCount() <= 1)
|
||||
return true;
|
||||
|
||||
types::TypeObject *excluded = nullptr;
|
||||
types::TypeObjectKey *excluded = nullptr;
|
||||
for (size_t i = 0; i < types->getObjectCount(); i++) {
|
||||
types::TypeObjectKey *object = types->getObject(i);
|
||||
if (!object || object->unknownProperties())
|
||||
|
@ -3238,7 +3244,7 @@ jit::PropertyWriteNeedsTypeBarrier(types::CompilerConstraintList *constraints,
|
|||
|
||||
if ((property.maybeTypes() && !property.maybeTypes()->empty()) || excluded)
|
||||
return true;
|
||||
excluded = object->isTypeObject() ? object->asTypeObject() : object->asSingleObject()->getType(GetIonContext()->cx);
|
||||
excluded = object;
|
||||
}
|
||||
|
||||
JS_ASSERT(excluded);
|
||||
|
|
|
@ -6888,6 +6888,58 @@ class MGuardObjectType
|
|||
}
|
||||
};
|
||||
|
||||
// Guard on an object's identity, inclusively or exclusively.
|
||||
class MGuardObjectIdentity
|
||||
: public MUnaryInstruction,
|
||||
public SingleObjectPolicy
|
||||
{
|
||||
CompilerRoot<JSObject *> singleObject_;
|
||||
bool bailOnEquality_;
|
||||
|
||||
MGuardObjectIdentity(MDefinition *obj, JSObject *singleObject, bool bailOnEquality)
|
||||
: MUnaryInstruction(obj),
|
||||
singleObject_(singleObject),
|
||||
bailOnEquality_(bailOnEquality)
|
||||
{
|
||||
setGuard();
|
||||
setMovable();
|
||||
setResultType(MIRType_Object);
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(GuardObjectIdentity)
|
||||
|
||||
static MGuardObjectIdentity *New(MDefinition *obj, JSObject *singleObject,
|
||||
bool bailOnEquality) {
|
||||
return new MGuardObjectIdentity(obj, singleObject, bailOnEquality);
|
||||
}
|
||||
|
||||
TypePolicy *typePolicy() {
|
||||
return this;
|
||||
}
|
||||
MDefinition *obj() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
JSObject *singleObject() const {
|
||||
return singleObject_;
|
||||
}
|
||||
bool bailOnEquality() const {
|
||||
return bailOnEquality_;
|
||||
}
|
||||
bool congruentTo(MDefinition *ins) const {
|
||||
if (!ins->isGuardObjectIdentity())
|
||||
return false;
|
||||
if (singleObject() != ins->toGuardObjectIdentity()->singleObject())
|
||||
return false;
|
||||
if (bailOnEquality() != ins->toGuardObjectIdentity()->bailOnEquality())
|
||||
return false;
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
};
|
||||
|
||||
// Guard on an object's class.
|
||||
class MGuardClass
|
||||
: public MUnaryInstruction,
|
||||
|
|
|
@ -123,6 +123,7 @@ namespace jit {
|
|||
_(BindNameCache) \
|
||||
_(GuardShape) \
|
||||
_(GuardObjectType) \
|
||||
_(GuardObjectIdentity) \
|
||||
_(GuardClass) \
|
||||
_(ArrayLength) \
|
||||
_(TypedArrayLength) \
|
||||
|
|
|
@ -209,6 +209,7 @@ class ParallelSafetyVisitor : public MInstructionVisitor
|
|||
UNSAFE_OP(BindNameCache)
|
||||
SAFE_OP(GuardShape)
|
||||
SAFE_OP(GuardObjectType)
|
||||
SAFE_OP(GuardObjectIdentity)
|
||||
SAFE_OP(GuardClass)
|
||||
SAFE_OP(AssertRange)
|
||||
SAFE_OP(ArrayLength)
|
||||
|
|
Загрузка…
Ссылка в новой задаче