mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 862103 - Split GuardShapeOrType into GuardShape and GuardObjectType, r=dvander.
This commit is contained in:
parent
cfcc459275
commit
986ed711e2
@ -6728,7 +6728,7 @@ IonBuilder::TestCommonPropFunc(JSContext *cx, types::StackTypeSet *types, Handle
|
||||
|
||||
// Pass the guard back so it can be an operand.
|
||||
if (isGetter) {
|
||||
JS_ASSERT(wrapper->isGuardShapeOrType());
|
||||
JS_ASSERT(wrapper->isGuardShape());
|
||||
*guardOut = wrapper;
|
||||
}
|
||||
|
||||
@ -7746,7 +7746,7 @@ IonBuilder::addBoundsCheck(MDefinition *index, MDefinition *length)
|
||||
MInstruction *
|
||||
IonBuilder::addShapeGuard(MDefinition *obj, const RawShape shape, BailoutKind bailoutKind)
|
||||
{
|
||||
MGuardShapeOrType *guard = MGuardShapeOrType::New(obj, shape, NULL, false, bailoutKind);
|
||||
MGuardShape *guard = MGuardShape::New(obj, shape, bailoutKind);
|
||||
current->add(guard);
|
||||
|
||||
// If a shape guard failed in the past, don't optimize shape guard.
|
||||
|
@ -130,7 +130,8 @@
|
||||
_(LoadSlotT) \
|
||||
_(StoreSlotV) \
|
||||
_(StoreSlotT) \
|
||||
_(GuardShapeOrType) \
|
||||
_(GuardShape) \
|
||||
_(GuardObjectType) \
|
||||
_(GuardClass) \
|
||||
_(ParWriteGuard) \
|
||||
_(ParDump) \
|
||||
|
@ -2480,13 +2480,12 @@ TryAddTypeBarrierForWrite(JSContext *cx, MBasicBlock *current, types::StackTypeS
|
||||
|
||||
static MInstruction *
|
||||
AddTypeGuard(MBasicBlock *current, MDefinition *obj, types::TypeObject *typeObject,
|
||||
bool bailOnEquality, BailoutKind bailoutKind)
|
||||
bool bailOnEquality)
|
||||
{
|
||||
MGuardShapeOrType *guard = MGuardShapeOrType::New(obj, NULL, typeObject,
|
||||
bailOnEquality, bailoutKind);
|
||||
MGuardObjectType *guard = MGuardObjectType::New(obj, typeObject, bailOnEquality);
|
||||
current->add(guard);
|
||||
|
||||
// For now, never move type guards.
|
||||
// For now, never move type object guards.
|
||||
guard->setNotMovable();
|
||||
|
||||
return guard;
|
||||
@ -2576,6 +2575,6 @@ ion::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinit
|
||||
|
||||
JS_ASSERT(excluded);
|
||||
|
||||
*pobj = AddTypeGuard(current, *pobj, excluded, /* bailOnEquality = */ true, Bailout_Normal);
|
||||
*pobj = AddTypeGuard(current, *pobj, excluded, /* bailOnEquality = */ true);
|
||||
return false;
|
||||
}
|
||||
|
@ -5525,37 +5525,29 @@ class MBindNameCache
|
||||
}
|
||||
};
|
||||
|
||||
// Guard on an object's shape or type, either inclusively or exclusively.
|
||||
class MGuardShapeOrType
|
||||
// Guard on an object's shape.
|
||||
class MGuardShape
|
||||
: public MUnaryInstruction,
|
||||
public SingleObjectPolicy
|
||||
{
|
||||
CompilerRootShape shape_;
|
||||
CompilerRoot<types::TypeObject*> typeObject_;
|
||||
bool bailOnEquality_;
|
||||
BailoutKind bailoutKind_;
|
||||
|
||||
MGuardShapeOrType(MDefinition *obj, Shape *shape, types::TypeObject *typeObject,
|
||||
bool bailOnEquality, BailoutKind bailoutKind)
|
||||
MGuardShape(MDefinition *obj, Shape *shape, BailoutKind bailoutKind)
|
||||
: MUnaryInstruction(obj),
|
||||
shape_(shape),
|
||||
typeObject_(typeObject),
|
||||
bailOnEquality_(bailOnEquality),
|
||||
bailoutKind_(bailoutKind)
|
||||
{
|
||||
// Exactly one of the shape or type object to guard on must be specified.
|
||||
JS_ASSERT(!!shape != !!typeObject);
|
||||
setGuard();
|
||||
setMovable();
|
||||
setResultType(MIRType_Object);
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(GuardShapeOrType)
|
||||
INSTRUCTION_HEADER(GuardShape)
|
||||
|
||||
static MGuardShapeOrType *New(MDefinition *obj, Shape *shape, types::TypeObject *typeObject,
|
||||
bool bailOnEquality, BailoutKind bailoutKind) {
|
||||
return new MGuardShapeOrType(obj, shape, typeObject, bailOnEquality, bailoutKind);
|
||||
static MGuardShape *New(MDefinition *obj, Shape *shape, BailoutKind bailoutKind) {
|
||||
return new MGuardShape(obj, shape, bailoutKind);
|
||||
}
|
||||
|
||||
TypePolicy *typePolicy() {
|
||||
@ -5567,25 +5559,67 @@ class MGuardShapeOrType
|
||||
const RawShape shape() const {
|
||||
return shape_;
|
||||
}
|
||||
types::TypeObject *typeObject() const {
|
||||
BailoutKind bailoutKind() const {
|
||||
return bailoutKind_;
|
||||
}
|
||||
bool congruentTo(MDefinition * const &ins) const {
|
||||
if (!ins->isGuardShape())
|
||||
return false;
|
||||
if (shape() != ins->toGuardShape()->shape())
|
||||
return false;
|
||||
if (bailoutKind() != ins->toGuardShape()->bailoutKind())
|
||||
return false;
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
};
|
||||
|
||||
// Guard on an object's type, inclusively or exclusively.
|
||||
class MGuardObjectType
|
||||
: public MUnaryInstruction,
|
||||
public SingleObjectPolicy
|
||||
{
|
||||
CompilerRoot<types::TypeObject *> typeObject_;
|
||||
bool bailOnEquality_;
|
||||
|
||||
MGuardObjectType(MDefinition *obj, types::TypeObject *typeObject, bool bailOnEquality)
|
||||
: MUnaryInstruction(obj),
|
||||
typeObject_(typeObject),
|
||||
bailOnEquality_(bailOnEquality)
|
||||
{
|
||||
setGuard();
|
||||
setMovable();
|
||||
setResultType(MIRType_Object);
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(GuardObjectType)
|
||||
|
||||
static MGuardObjectType *New(MDefinition *obj, types::TypeObject *typeObject,
|
||||
bool bailOnEquality) {
|
||||
return new MGuardObjectType(obj, typeObject, bailOnEquality);
|
||||
}
|
||||
|
||||
TypePolicy *typePolicy() {
|
||||
return this;
|
||||
}
|
||||
MDefinition *obj() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
const types::TypeObject *typeObject() const {
|
||||
return typeObject_;
|
||||
}
|
||||
bool bailOnEquality() const {
|
||||
return bailOnEquality_;
|
||||
}
|
||||
BailoutKind bailoutKind() const {
|
||||
return bailoutKind_;
|
||||
}
|
||||
bool congruentTo(MDefinition * const &ins) const {
|
||||
if (!ins->isGuardShapeOrType())
|
||||
if (!ins->isGuardObjectType())
|
||||
return false;
|
||||
if (shape() != ins->toGuardShapeOrType()->shape())
|
||||
if (typeObject() != ins->toGuardObjectType()->typeObject())
|
||||
return false;
|
||||
if (typeObject() != ins->toGuardShapeOrType()->typeObject())
|
||||
return false;
|
||||
if (bailOnEquality() != ins->toGuardShapeOrType()->bailOnEquality())
|
||||
return false;
|
||||
if (bailoutKind() != ins->toGuardShapeOrType()->bailoutKind())
|
||||
if (bailOnEquality() != ins->toGuardObjectType()->bailOnEquality())
|
||||
return false;
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
|
@ -102,7 +102,8 @@ namespace ion {
|
||||
_(GetPropertyCache) \
|
||||
_(GetElementCache) \
|
||||
_(BindNameCache) \
|
||||
_(GuardShapeOrType) \
|
||||
_(GuardShape) \
|
||||
_(GuardObjectType) \
|
||||
_(GuardClass) \
|
||||
_(ArrayLength) \
|
||||
_(TypedArrayLength) \
|
||||
|
@ -191,7 +191,8 @@ class ParallelArrayVisitor : public MInstructionVisitor
|
||||
SAFE_OP(GetPropertyCache)
|
||||
UNSAFE_OP(GetElementCache)
|
||||
UNSAFE_OP(BindNameCache)
|
||||
SAFE_OP(GuardShapeOrType)
|
||||
SAFE_OP(GuardShape)
|
||||
SAFE_OP(GuardObjectType)
|
||||
SAFE_OP(GuardClass)
|
||||
SAFE_OP(ArrayLength)
|
||||
SAFE_OP(TypedArrayLength)
|
||||
|
@ -1541,24 +1541,29 @@ CodeGeneratorARM::storeElementTyped(const LAllocation *value, MIRType valueType,
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorARM::visitGuardShapeOrType(LGuardShapeOrType *guard)
|
||||
CodeGeneratorARM::visitGuardShape(LGuardShape *guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Register tmp = ToRegister(guard->tempInt());
|
||||
|
||||
if (guard->mir()->shape()) {
|
||||
masm.ma_ldr(DTRAddr(obj, DtrOffImm(JSObject::offsetOfShape())), tmp);
|
||||
masm.ma_cmp(tmp, ImmGCPtr(guard->mir()->shape()));
|
||||
} else {
|
||||
|
||||
return bailoutIf(Assembler::NotEqual, guard->snapshot());
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorARM::visitGuardObjectType(LGuardObjectType *guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
Register tmp = ToRegister(guard->tempInt());
|
||||
|
||||
masm.ma_ldr(DTRAddr(obj, DtrOffImm(JSObject::offsetOfType())), tmp);
|
||||
masm.ma_cmp(tmp, ImmGCPtr(guard->mir()->typeObject()));
|
||||
}
|
||||
|
||||
Assembler::Condition cond =
|
||||
guard->mir()->bailOnEquality() ? Assembler::Equal : Assembler::NotEqual;
|
||||
if (!bailoutIf(cond, guard->snapshot()))
|
||||
return false;
|
||||
return true;
|
||||
return bailoutIf(cond, guard->snapshot());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -134,7 +134,8 @@ class CodeGeneratorARM : public CodeGeneratorShared
|
||||
|
||||
bool visitLoadElementT(LLoadElementT *load);
|
||||
|
||||
bool visitGuardShapeOrType(LGuardShapeOrType *guard);
|
||||
bool visitGuardShape(LGuardShape *guard);
|
||||
bool visitGuardObjectType(LGuardObjectType *guard);
|
||||
bool visitGuardClass(LGuardClass *guard);
|
||||
bool visitImplicitThis(LImplicitThis *lir);
|
||||
|
||||
|
@ -262,18 +262,34 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 2>
|
||||
}
|
||||
};
|
||||
|
||||
// Guard against an object's shape.
|
||||
class LGuardShapeOrType : public LInstructionHelper<0, 1, 1>
|
||||
class LGuardShape : public LInstructionHelper<0, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardShapeOrType);
|
||||
LIR_HEADER(GuardShape);
|
||||
|
||||
LGuardShapeOrType(const LAllocation &in, const LDefinition &temp) {
|
||||
LGuardShape(const LAllocation &in, const LDefinition &temp) {
|
||||
setOperand(0, in);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
const MGuardShapeOrType *mir() const {
|
||||
return mir_->toGuardShapeOrType();
|
||||
const MGuardShape *mir() const {
|
||||
return mir_->toGuardShape();
|
||||
}
|
||||
const LAllocation *tempInt() {
|
||||
return getTemp(0)->output();
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardObjectType : public LInstructionHelper<0, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardObjectType);
|
||||
|
||||
LGuardObjectType(const LAllocation &in, const LDefinition &temp) {
|
||||
setOperand(0, in);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
const MGuardObjectType *mir() const {
|
||||
return mir_->toGuardObjectType();
|
||||
}
|
||||
const LAllocation *tempInt() {
|
||||
return getTemp(0)->output();
|
||||
|
@ -302,12 +302,12 @@ LIRGeneratorARM::newLGetPropertyCacheT(MGetPropertyCache *ins)
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorARM::visitGuardShapeOrType(MGuardShapeOrType *ins)
|
||||
LIRGeneratorARM::visitGuardShape(MGuardShape *ins)
|
||||
{
|
||||
JS_ASSERT(ins->obj()->type() == MIRType_Object);
|
||||
|
||||
LDefinition tempObj = temp(LDefinition::OBJECT);
|
||||
LGuardShapeOrType *guard = new LGuardShapeOrType(useRegister(ins->obj()), tempObj);
|
||||
LGuardShape *guard = new LGuardShape(useRegister(ins->obj()), tempObj);
|
||||
if (!assignSnapshot(guard, ins->bailoutKind()))
|
||||
return false;
|
||||
if (!add(guard, ins))
|
||||
@ -315,6 +315,20 @@ LIRGeneratorARM::visitGuardShapeOrType(MGuardShapeOrType *ins)
|
||||
return redefine(ins, ins->obj());
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorARM::visitGuardObjectType(MGuardObjectType *ins)
|
||||
{
|
||||
JS_ASSERT(ins->obj()->type() == MIRType_Object);
|
||||
|
||||
LDefinition tempObj = temp(LDefinition::OBJECT);
|
||||
LGuardObjectType *guard = new LGuardObjectType(useRegister(ins->obj()), tempObj);
|
||||
if (!assignSnapshot(guard))
|
||||
return false;
|
||||
if (!add(guard, ins))
|
||||
return false;
|
||||
return redefine(ins, ins->obj());
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorARM::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins)
|
||||
{
|
||||
|
@ -64,7 +64,8 @@ class LIRGeneratorARM : public LIRGeneratorShared
|
||||
bool visitUnbox(MUnbox *unbox);
|
||||
bool visitReturn(MReturn *ret);
|
||||
bool lowerPhi(MPhi *phi);
|
||||
bool visitGuardShapeOrType(MGuardShapeOrType *ins);
|
||||
bool visitGuardShape(MGuardShape *ins);
|
||||
bool visitGuardObjectType(MGuardObjectType *ins);
|
||||
bool visitStoreTypedArrayElement(MStoreTypedArrayElement *ins);
|
||||
bool visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins);
|
||||
bool visitAsmJSUnsignedToDouble(MAsmJSUnsignedToDouble *ins);
|
||||
|
@ -1302,19 +1302,23 @@ CodeGeneratorX86Shared::visitRound(LRound *lir)
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorX86Shared::visitGuardShapeOrType(LGuardShapeOrType *guard)
|
||||
CodeGeneratorX86Shared::visitGuardShape(LGuardShape *guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
if (guard->mir()->shape())
|
||||
masm.cmpPtr(Operand(obj, JSObject::offsetOfShape()), ImmGCPtr(guard->mir()->shape()));
|
||||
else
|
||||
|
||||
return bailoutIf(Assembler::NotEqual, guard->snapshot());
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorX86Shared::visitGuardObjectType(LGuardObjectType *guard)
|
||||
{
|
||||
Register obj = ToRegister(guard->input());
|
||||
masm.cmpPtr(Operand(obj, JSObject::offsetOfType()), ImmGCPtr(guard->mir()->typeObject()));
|
||||
|
||||
Assembler::Condition cond =
|
||||
guard->mir()->bailOnEquality() ? Assembler::Equal : Assembler::NotEqual;
|
||||
if (!bailoutIf(cond, guard->snapshot()))
|
||||
return false;
|
||||
return true;
|
||||
return bailoutIf(cond, guard->snapshot());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -102,7 +102,8 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
|
||||
virtual bool visitMathD(LMathD *math);
|
||||
virtual bool visitFloor(LFloor *lir);
|
||||
virtual bool visitRound(LRound *lir);
|
||||
virtual bool visitGuardShapeOrType(LGuardShapeOrType *guard);
|
||||
virtual bool visitGuardShape(LGuardShape *guard);
|
||||
virtual bool visitGuardObjectType(LGuardObjectType *guard);
|
||||
virtual bool visitGuardClass(LGuardClass *guard);
|
||||
virtual bool visitEffectiveAddress(LEffectiveAddress *ins);
|
||||
virtual bool visitAsmJSDivOrMod(LAsmJSDivOrMod *ins);
|
||||
|
@ -173,17 +173,29 @@ class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 3>
|
||||
}
|
||||
};
|
||||
|
||||
// Guard against an object's shape.
|
||||
class LGuardShapeOrType : public LInstructionHelper<0, 1, 0>
|
||||
class LGuardShape : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardShapeOrType)
|
||||
LIR_HEADER(GuardShape)
|
||||
|
||||
LGuardShapeOrType(const LAllocation &in) {
|
||||
LGuardShape(const LAllocation &in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardShapeOrType *mir() const {
|
||||
return mir_->toGuardShapeOrType();
|
||||
const MGuardShape *mir() const {
|
||||
return mir_->toGuardShape();
|
||||
}
|
||||
};
|
||||
|
||||
class LGuardObjectType : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardObjectType)
|
||||
|
||||
LGuardObjectType(const LAllocation &in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const MGuardObjectType *mir() const {
|
||||
return mir_->toGuardObjectType();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -36,11 +36,11 @@ LIRGeneratorX86Shared::visitInterruptCheck(MInterruptCheck *ins)
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorX86Shared::visitGuardShapeOrType(MGuardShapeOrType *ins)
|
||||
LIRGeneratorX86Shared::visitGuardShape(MGuardShape *ins)
|
||||
{
|
||||
JS_ASSERT(ins->obj()->type() == MIRType_Object);
|
||||
|
||||
LGuardShapeOrType *guard = new LGuardShapeOrType(useRegister(ins->obj()));
|
||||
LGuardShape *guard = new LGuardShape(useRegister(ins->obj()));
|
||||
if (!assignSnapshot(guard, ins->bailoutKind()))
|
||||
return false;
|
||||
if (!add(guard, ins))
|
||||
@ -48,6 +48,19 @@ LIRGeneratorX86Shared::visitGuardShapeOrType(MGuardShapeOrType *ins)
|
||||
return redefine(ins, ins->obj());
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorX86Shared::visitGuardObjectType(MGuardObjectType *ins)
|
||||
{
|
||||
JS_ASSERT(ins->obj()->type() == MIRType_Object);
|
||||
|
||||
LGuardObjectType *guard = new LGuardObjectType(useRegister(ins->obj()));
|
||||
if (!assignSnapshot(guard))
|
||||
return false;
|
||||
if (!add(guard, ins))
|
||||
return false;
|
||||
return redefine(ins, ins->obj());
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorX86Shared::visitPowHalf(MPowHalf *ins)
|
||||
{
|
||||
|
@ -24,7 +24,8 @@ class LIRGeneratorX86Shared : public LIRGeneratorShared
|
||||
LTableSwitchV *newLTableSwitchV(MTableSwitch *ins);
|
||||
|
||||
bool visitInterruptCheck(MInterruptCheck *ins);
|
||||
bool visitGuardShapeOrType(MGuardShapeOrType *ins);
|
||||
bool visitGuardShape(MGuardShape *ins);
|
||||
bool visitGuardObjectType(MGuardObjectType *ins);
|
||||
bool visitPowHalf(MPowHalf *ins);
|
||||
bool visitConstant(MConstant *ins);
|
||||
bool visitAsmJSNeg(MAsmJSNeg *ins);
|
||||
|
Loading…
Reference in New Issue
Block a user