Bug 937674 - Don't instantiate types when adding type object guards around type write barriers, r=jandem.

This commit is contained in:
Brian Hackett 2013-11-12 11:02:52 -07:00
Родитель d4e678eb60
Коммит f7c2610507
10 изменённых файлов: 100 добавлений и 4 удалений

Просмотреть файл

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