Bug 847045 - Avoid frequent ExcludeType bailouts. r=nbp

This commit is contained in:
Jan de Mooij 2013-03-06 19:13:05 +01:00
Родитель fb908073ee
Коммит 7c0147addc
10 изменённых файлов: 32 добавлений и 110 удалений

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

@ -957,20 +957,6 @@ CodeGenerator::visitMonitorTypes(LMonitorTypes *lir)
return true;
}
bool
CodeGenerator::visitExcludeType(LExcludeType *lir)
{
ValueOperand operand = ToValue(lir, LExcludeType::Input);
Register scratch = ToRegister(lir->temp());
Label matched, miss;
masm.guardType(operand, lir->mir()->type(), scratch, &matched, &miss);
if (matched.used() && !bailoutFrom(&matched, lir->snapshot()))
return false;
masm.bind(&miss);
return true;
}
bool
CodeGenerator::visitCallNative(LCallNative *call)
{

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

@ -84,7 +84,6 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitConvertElementsToDoubles(LConvertElementsToDoubles *lir);
bool visitTypeBarrier(LTypeBarrier *lir);
bool visitMonitorTypes(LMonitorTypes *lir);
bool visitExcludeType(LExcludeType *lir);
bool visitCallNative(LCallNative *call);
bool emitCallInvokeFunction(LInstruction *call, Register callereg,
uint32_t argc, uint32_t unusedStack);

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

@ -3027,10 +3027,13 @@ IonBuilder::addTypeBarrier(uint32_t i, CallInfo &callinfo, types::StackTypeSet *
callerObs = callinfo.getArgType(i - 1);
}
bool needsBarrier = false;
while (excluded) {
if (excluded->target == calleeObs && callerObs->hasType(excluded->type)) {
if (excluded->type == types::Type::DoubleType() &&
calleeObs->hasType(types::Type::Int32Type())) {
calleeObs->hasType(types::Type::Int32Type()))
{
// The double type also implies int32, so this implies that
// double should be coerced into int if possible, and other
// types should remain.
@ -3040,7 +3043,6 @@ IonBuilder::addTypeBarrier(uint32_t i, CallInfo &callinfo, types::StackTypeSet *
MInstruction *bailType = MToInt32::New(ins);
current->add(bailType);
ins = bailType;
break;
} else {
// We expect either an Int or a Value, this variant is not
// optimized and favor the int variant by filtering out all
@ -3054,18 +3056,21 @@ IonBuilder::addTypeBarrier(uint32_t i, CallInfo &callinfo, types::StackTypeSet *
current->add(toInt);
ins = toInt;
}
} else {
JS_ASSERT(!calleeObs->hasType(excluded->type));
// Filter out unexpected type which are not yet added to the set
// observed type but which are infered by type inference.
MInstruction *bailType = MExcludeType::New(ins, excluded->type);
current->add(bailType);
needsBarrier = false;
break;
}
needsBarrier = true;
}
excluded = excluded->next;
}
if (needsBarrier) {
MTypeBarrier *barrier = MTypeBarrier::New(ins, cloneTypeSet(calleeObs), Bailout_Normal);
current->add(barrier);
}
if (i == 0)
callinfo.setThis(ins);
else

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

@ -3735,11 +3735,10 @@ class LParDump : public LCallInstructionHelper<0, BOX_PIECES, 0>
};
// Guard that a value is in a TypeSet.
class LTypeBarrier : public LInstructionHelper<BOX_PIECES, BOX_PIECES, 1>
class LTypeBarrier : public LInstructionHelper<0, BOX_PIECES, 1>
{
public:
LIR_HEADER(TypeBarrier)
BOX_OUTPUT_ACCESSORS()
LTypeBarrier(const LDefinition &temp) {
setTemp(0, temp);
@ -3775,27 +3774,6 @@ class LMonitorTypes : public LInstructionHelper<0, BOX_PIECES, 1>
}
};
// Guard that a value is in a TypeSet.
class LExcludeType : public LInstructionHelper<0, BOX_PIECES, 1>
{
public:
LIR_HEADER(ExcludeType);
BOX_OUTPUT_ACCESSORS();
LExcludeType(const LDefinition &temp) {
setTemp(0, temp);
}
static const size_t Input = 0;
const MExcludeType *mir() const {
return mir_->toExcludeType();
}
const LDefinition *temp() {
return getTemp(0);
}
};
// Guard against an object's class.
class LGuardClass : public LInstructionHelper<0, 1, 1>
{

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

@ -134,7 +134,6 @@
_(ParDump) \
_(TypeBarrier) \
_(MonitorTypes) \
_(ExcludeType) \
_(InitializedLength) \
_(SetInitializedLength) \
_(BoundsCheck) \

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

@ -1650,7 +1650,7 @@ LIRGenerator::visitTypeBarrier(MTypeBarrier *ins)
return false;
if (!assignSnapshot(barrier, ins->bailoutKind()))
return false;
return defineAs(barrier, ins, ins->input()) && add(barrier);
return redefine(ins, ins->input()) && add(barrier, ins);
}
bool
@ -1664,18 +1664,6 @@ LIRGenerator::visitMonitorTypes(MMonitorTypes *ins)
return assignSnapshot(lir, Bailout_Monitor) && add(lir, ins);
}
bool
LIRGenerator::visitExcludeType(MExcludeType *ins)
{
LExcludeType *filter = new LExcludeType(temp());
if (!useBox(filter, LExcludeType::Input, ins->input()))
return false;
if (!assignSnapshot(filter, ins->bailoutKind()))
return false;
filter->setMir(ins);
return add(filter);
}
bool
LIRGenerator::visitArrayLength(MArrayLength *ins)
{

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

@ -160,7 +160,6 @@ class LIRGenerator : public LIRGeneratorSpecific
bool visitStoreSlot(MStoreSlot *ins);
bool visitTypeBarrier(MTypeBarrier *ins);
bool visitMonitorTypes(MMonitorTypes *ins);
bool visitExcludeType(MExcludeType *ins);
bool visitArrayLength(MArrayLength *ins);
bool visitTypedArrayLength(MTypedArrayLength *ins);
bool visitTypedArrayElements(MTypedArrayElements *ins);

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

@ -6162,28 +6162,39 @@ class MParDump
// Given a value, guard that the value is in a particular TypeSet, then returns
// that value.
class MTypeBarrier : public MUnaryInstruction
class MTypeBarrier
: public MUnaryInstruction,
public BoxInputsPolicy
{
BailoutKind bailoutKind_;
const types::StackTypeSet *typeSet_;
MTypeBarrier(MDefinition *def, const types::StackTypeSet *types)
MTypeBarrier(MDefinition *def, const types::StackTypeSet *types, BailoutKind bailoutKind)
: MUnaryInstruction(def),
typeSet_(types)
{
setResultType(MIRType_Value);
setGuard();
setMovable();
bailoutKind_ = def->isEffectful()
? Bailout_TypeBarrier
: Bailout_Normal;
bailoutKind_ = bailoutKind;
}
public:
INSTRUCTION_HEADER(TypeBarrier)
static MTypeBarrier *New(MDefinition *def, const types::StackTypeSet *types) {
return new MTypeBarrier(def, types);
BailoutKind bailoutKind = def->isEffectful()
? Bailout_TypeBarrier
: Bailout_Normal;
return new MTypeBarrier(def, types, bailoutKind);
}
static MTypeBarrier *New(MDefinition *def, const types::StackTypeSet *types,
BailoutKind bailoutKind) {
return new MTypeBarrier(def, types, bailoutKind);
}
TypePolicy *typePolicy() {
return this;
}
bool congruentTo(MDefinition * const &def) const {
@ -6204,7 +6215,6 @@ class MTypeBarrier : public MUnaryInstruction
virtual bool neverHoist() const {
return typeSet()->empty();
}
};
// Like MTypeBarrier, guard that the value is in the given type set. This is
@ -6240,46 +6250,6 @@ class MMonitorTypes : public MUnaryInstruction
}
};
// Guards that the incoming value does not have the specified Type.
class MExcludeType
: public MUnaryInstruction,
public BoxInputsPolicy
{
types::Type type_;
MExcludeType(MDefinition *def, types::Type type)
: MUnaryInstruction(def),
type_(type)
{
setGuard();
setMovable();
}
public:
INSTRUCTION_HEADER(ExcludeType);
static MExcludeType *New(MDefinition *def, types::Type type) {
return new MExcludeType(def, type);
}
MDefinition *input() const {
return getOperand(0);
}
BailoutKind bailoutKind() const {
return Bailout_Normal;
}
types::Type type() const {
return type_;
}
TypePolicy *typePolicy() {
return this;
}
AliasSet getAliasSet() const {
return AliasSet::None();
}
};
class MNewSlots : public MNullaryInstruction
{
unsigned nslots_;

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

@ -98,7 +98,6 @@ namespace ion {
_(FunctionEnvironment) \
_(TypeBarrier) \
_(MonitorTypes) \
_(ExcludeType) \
_(GetPropertyCache) \
_(GetElementCache) \
_(BindNameCache) \

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

@ -194,7 +194,6 @@ class ParallelArrayVisitor : public MInstructionVisitor
SAFE_OP(FunctionEnvironment) // just a load of func env ptr
SAFE_OP(TypeBarrier) // causes a bailout if the type is not found: a-ok with us
SAFE_OP(MonitorTypes) // causes a bailout if the type is not found: a-ok with us
SAFE_OP(ExcludeType) // causes a bailout if the type is not found: a-ok with us
UNSAFE_OP(GetPropertyCache)
UNSAFE_OP(GetElementCache)
UNSAFE_OP(BindNameCache)