Bug 1065996 - Split data / methods of TypePolicy classes. r=jandem

This commit is contained in:
Nicolas B. Pierron 2014-09-18 18:07:44 +02:00
parent 9d8c68e789
commit 9d4603e4ae
5 changed files with 396 additions and 656 deletions

View File

@ -1065,8 +1065,13 @@ TypeAnalyzer::adjustPhiInputs(MPhi *phi)
bool
TypeAnalyzer::adjustInputs(MDefinition *def)
{
TypePolicy *policy = def->typePolicy();
if (policy && !policy->adjustInputs(alloc(), def->toInstruction()))
// Definitions such as MPhi have no type policy.
if (!def->isInstruction())
return true;
MInstruction *ins = def->toInstruction();
TypePolicy *policy = ins->typePolicy();
if (policy && !policy->adjustInputs(alloc(), ins))
return false;
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -690,7 +690,7 @@ ParallelSafetyVisitor::insertWriteGuard(MInstruction *writeInstruction,
MGuardThreadExclusive *writeGuard =
MGuardThreadExclusive::New(alloc(), ForkJoinContext(), object);
block->insertBefore(writeInstruction, writeGuard);
writeGuard->adjustInputs(alloc(), writeGuard);
writeGuard->typePolicy()->adjustInputs(alloc(), writeGuard);
return true;
}

View File

@ -64,7 +64,8 @@ BoxInputsPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
bool
ArithPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
{
if (specialization_ == MIRType_None)
MIRType specialization = ins->typePolicySpecialization();
if (specialization == MIRType_None)
return BoxInputsPolicy::adjustInputs(alloc, ins);
JS_ASSERT(ins->type() == MIRType_Double || ins->type() == MIRType_Int32 || ins->type() == MIRType_Float32);
@ -318,11 +319,12 @@ TestPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
bool
BitwisePolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
{
if (specialization_ == MIRType_None)
MIRType specialization = ins->typePolicySpecialization();
if (specialization == MIRType_None)
return BoxInputsPolicy::adjustInputs(alloc, ins);
JS_ASSERT(ins->type() == specialization_);
JS_ASSERT(specialization_ == MIRType_Int32 || specialization_ == MIRType_Double);
MOZ_ASSERT(ins->type() == specialization);
MOZ_ASSERT(specialization == MIRType_Int32 || specialization == MIRType_Double);
// This policy works for both unary and binary bitwise operations.
for (size_t i = 0, e = ins->numOperands(); i < e; i++) {
@ -344,14 +346,15 @@ BitwisePolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
bool
PowPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
{
JS_ASSERT(specialization_ == MIRType_Int32 || specialization_ == MIRType_Double);
MIRType specialization = ins->typePolicySpecialization();
JS_ASSERT(specialization == MIRType_Int32 || specialization == MIRType_Double);
// Input must be a double.
if (!DoublePolicy<0>::staticAdjustInputs(alloc, ins))
return false;
// Power may be an int32 or a double. Integers receive a faster path.
if (specialization_ == MIRType_Double)
if (specialization == MIRType_Double)
return DoublePolicy<1>::staticAdjustInputs(alloc, ins);
return IntPolicy<1>::staticAdjustInputs(alloc, ins);
}
@ -469,6 +472,18 @@ template bool Float32Policy<0>::staticAdjustInputs(TempAllocator &alloc, MInstru
template bool Float32Policy<1>::staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
template bool Float32Policy<2>::staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
template <unsigned Op>
bool
FloatingPointPolicy<Op>::adjustInputs(TempAllocator &alloc, MInstruction *def)
{
MIRType policyType = def->typePolicySpecialization();
if (policyType == MIRType_Double)
return DoublePolicy<Op>::staticAdjustInputs(alloc, def);
return Float32Policy<Op>::staticAdjustInputs(alloc, def);
}
template bool FloatingPointPolicy<0>::adjustInputs(TempAllocator &alloc, MInstruction *def);
template <unsigned Op>
bool
NoFloatPolicy<Op>::staticAdjustInputs(TempAllocator &alloc, MInstruction *def)
@ -856,3 +871,133 @@ FilterTypeSetPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
return true;
}
// Lists of all TypePolicy specializations which are used by MIR Instructions.
#define TYPE_POLICY_LIST(_) \
_(ArithPolicy) \
_(BitwisePolicy) \
_(BoxInputsPolicy) \
_(CallPolicy) \
_(CallSetElementPolicy) \
_(ClampPolicy) \
_(ComparePolicy) \
_(FilterTypeSetPolicy) \
_(InstanceOfPolicy) \
_(PowPolicy) \
_(StoreTypedArrayElementStaticPolicy) \
_(StoreTypedArrayHolePolicy) \
_(StoreTypedArrayPolicy) \
_(TestPolicy) \
_(ToDoublePolicy) \
_(ToInt32Policy) \
_(ToStringPolicy) \
_(TypeBarrierPolicy)
#define TEMPLATE_TYPE_POLICY_LIST(_) \
_(BoxExceptPolicy<0, MIRType_String>) \
_(BoxPolicy<0>) \
_(ConvertToInt32Policy<0>) \
_(ConvertToStringPolicy<0>) \
_(DoublePolicy<0>) \
_(FloatingPointPolicy<0>) \
_(IntPolicy<0>) \
_(IntPolicy<1>) \
_(Mix3Policy<ObjectPolicy<0>, BoxExceptPolicy<1, MIRType_String>, BoxPolicy<2> >) \
_(Mix3Policy<ObjectPolicy<0>, BoxPolicy<1>, BoxPolicy<2> >) \
_(Mix3Policy<ObjectPolicy<0>, BoxPolicy<1>, ObjectPolicy<2> >) \
_(Mix3Policy<ObjectPolicy<0>, IntPolicy<1>, BoxPolicy<2> >) \
_(Mix3Policy<ObjectPolicy<0>, IntPolicy<1>, IntPolicy<2> >) \
_(Mix3Policy<ObjectPolicy<0>, ObjectPolicy<1>, IntPolicy<2> >) \
_(Mix3Policy<StringPolicy<0>, ObjectPolicy<1>, StringPolicy<2> >) \
_(Mix3Policy<StringPolicy<0>, StringPolicy<1>, StringPolicy<2> >) \
_(MixPolicy<BoxPolicy<0>, ObjectPolicy<1> >) \
_(MixPolicy<ConvertToStringPolicy<0>, ConvertToStringPolicy<1> >) \
_(MixPolicy<ConvertToStringPolicy<0>, ObjectPolicy<1> >) \
_(MixPolicy<DoublePolicy<0>, DoublePolicy<1> >) \
_(MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >) \
_(MixPolicy<ObjectPolicy<0>, ConvertToStringPolicy<1> >) \
_(MixPolicy<ObjectPolicy<0>, IntPolicy<1> >) \
_(MixPolicy<ObjectPolicy<0>, NoFloatPolicy<1> >) \
_(MixPolicy<ObjectPolicy<0>, NoFloatPolicy<2> >) \
_(MixPolicy<ObjectPolicy<0>, NoFloatPolicy<3> >) \
_(MixPolicy<ObjectPolicy<0>, ObjectPolicy<1> >) \
_(MixPolicy<ObjectPolicy<0>, StringPolicy<1> >) \
_(MixPolicy<ObjectPolicy<1>, ConvertToStringPolicy<0> >) \
_(MixPolicy<StringPolicy<0>, IntPolicy<1> >) \
_(MixPolicy<StringPolicy<0>, StringPolicy<1> >) \
_(NoFloatPolicy<0>) \
_(ObjectPolicy<0>) \
_(ObjectPolicy<1>) \
_(ObjectPolicy<3>) \
_(StringPolicy<0>)
namespace js {
namespace jit {
// Define for all used TypePolicy specialization, the definition for
// |TypePolicy::Data::thisTypePolicy|. This function returns one constant
// instance of the TypePolicy which is shared among all MIR Instructions of the
// same type.
//
// This Macro use __VA_ARGS__ to account for commas of template parameters.
#define DEFINE_TYPE_POLICY_SINGLETON_INSTANCES_(...) \
TypePolicy * \
__VA_ARGS__::Data::thisTypePolicy() \
{ \
static __VA_ARGS__ singletonType; \
return &singletonType; \
}
TYPE_POLICY_LIST(DEFINE_TYPE_POLICY_SINGLETON_INSTANCES_)
TEMPLATE_TYPE_POLICY_LIST(template<> DEFINE_TYPE_POLICY_SINGLETON_INSTANCES_)
#undef DEFINE_TYPE_POLICY_SINGLETON_INSTANCES_
}
}
namespace {
// Default function visited by the C++ lookup rules, if the MIR Instruction does
// not inherit from a TypePolicy::Data type.
static TypePolicy *
thisTypePolicy() {
return nullptr;
}
static MIRType
thisTypeSpecialization() {
MOZ_CRASH("TypeSpecialization lacks definition of thisTypeSpecialization.");
}
}
TypePolicy *
MGetElementCache::thisTypePolicy()
{
if (type() == MIRType_Value)
return PolicyV.thisTypePolicy();
return PolicyT.thisTypePolicy();
}
// For each MIR Instruction, this macro define the |typePolicy| method which is
// using the |thisTypePolicy| function. We use the C++ lookup rules to select
// the right |thisTypePolicy| member. The |thisTypePolicy| function can either
// be a member of the MIR Instruction, such as done for MGetElementCache, or a
// member inherited from the TypePolicy::Data structure, or at last the global
// with the same name if the instruction has no TypePolicy.
#define DEFINE_MIR_TYPEPOLICY_MEMBERS_(op) \
TypePolicy * \
js::jit::M##op::typePolicy() \
{ \
return thisTypePolicy(); \
} \
\
MIRType \
js::jit::M##op::typePolicySpecialization() \
{ \
return thisTypeSpecialization(); \
}
MIR_OPCODE_LIST(DEFINE_MIR_TYPEPOLICY_MEMBERS_)
#undef DEFINE_MIR_TYPEPOLICY_MEMBERS_

View File

@ -30,48 +30,67 @@ class TypePolicy
virtual bool adjustInputs(TempAllocator &alloc, MInstruction *def) = 0;
};
struct TypeSpecializationData
{
protected:
// Specifies three levels of specialization:
// - < Value. This input is expected and required.
// - == None. This op should not be specialized.
MIRType specialization_;
MIRType thisTypeSpecialization() {
return specialization_;
}
public:
MIRType specialization() const {
return specialization_;
}
};
#define EMPTY_DATA_ \
struct Data \
{ \
static TypePolicy *thisTypePolicy(); \
}
#define INHERIT_DATA_(DATA_TYPE) \
struct Data : public DATA_TYPE \
{ \
static TypePolicy *thisTypePolicy(); \
}
#define SPECIALIZATION_DATA_ INHERIT_DATA_(TypeSpecializationData)
class BoxInputsPolicy : public TypePolicy
{
protected:
static MDefinition *boxAt(TempAllocator &alloc, MInstruction *at, MDefinition *operand);
public:
EMPTY_DATA_;
static MDefinition *alwaysBoxAt(TempAllocator &alloc, MInstruction *at, MDefinition *operand);
virtual bool adjustInputs(TempAllocator &alloc, MInstruction *def);
};
class ArithPolicy : public BoxInputsPolicy
{
protected:
// Specifies three levels of specialization:
// - < Value. This input is expected and required.
// - == Any. Inputs are probably primitive.
// - == None. This op should not be specialized.
MIRType specialization_;
public:
SPECIALIZATION_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *def);
};
class BitwisePolicy : public BoxInputsPolicy
{
protected:
// Specifies three levels of specialization:
// - < Value. This input is expected and required.
// - == Any. Inputs are probably primitive.
// - == None. This op should not be specialized.
MIRType specialization_;
public:
SPECIALIZATION_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *def);
MIRType specialization() const {
return specialization_;
}
};
class ComparePolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *def);
};
@ -79,31 +98,29 @@ class ComparePolicy : public BoxInputsPolicy
class TestPolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
};
class TypeBarrierPolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
};
class CallPolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *def);
};
// Policy for MPow. First operand Double; second Double or Int32.
class PowPolicy : public BoxInputsPolicy
{
MIRType specialization_;
public:
explicit PowPolicy(MIRType specialization)
: specialization_(specialization)
{ }
SPECIALIZATION_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
};
@ -112,6 +129,7 @@ template <unsigned Op>
class StringPolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
@ -123,6 +141,7 @@ template <unsigned Op>
class ConvertToStringPolicy : public TypePolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
@ -134,6 +153,7 @@ template <unsigned Op>
class IntPolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
@ -145,6 +165,7 @@ template <unsigned Op>
class ConvertToInt32Policy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
@ -156,6 +177,7 @@ template <unsigned Op>
class DoublePolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
@ -167,6 +189,7 @@ template <unsigned Op>
class Float32Policy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
@ -178,23 +201,32 @@ class Float32Policy : public BoxInputsPolicy
template <unsigned Op>
class FloatingPointPolicy : public TypePolicy
{
MIRType policyType_;
public:
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
if (policyType_ == MIRType_Double)
return DoublePolicy<Op>::staticAdjustInputs(alloc, def);
return Float32Policy<Op>::staticAdjustInputs(alloc, def);
}
void setPolicyType(MIRType type) {
policyType_ = type;
}
struct PolicyTypeData
{
MIRType policyType_;
void setPolicyType(MIRType type) {
policyType_ = type;
}
protected:
MIRType &thisTypeSpecialization() {
return policyType_;
}
};
INHERIT_DATA_(PolicyTypeData);
bool adjustInputs(TempAllocator &alloc, MInstruction *def);
};
template <unsigned Op>
class NoFloatPolicy : public TypePolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
@ -205,6 +237,7 @@ class NoFloatPolicy : public TypePolicy
class ToDoublePolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
@ -215,6 +248,7 @@ class ToDoublePolicy : public BoxInputsPolicy
class ToInt32Policy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
@ -225,6 +259,7 @@ class ToInt32Policy : public BoxInputsPolicy
class ToStringPolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
@ -235,6 +270,7 @@ template <unsigned Op>
class ObjectPolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
return staticAdjustInputs(alloc, ins);
@ -243,13 +279,13 @@ class ObjectPolicy : public BoxInputsPolicy
// Single-object input. If the input is a Value, it is unboxed. If it is
// a primitive, we use ValueToNonNullObject.
class SingleObjectPolicy : public ObjectPolicy<0>
{ };
typedef ObjectPolicy<0> SingleObjectPolicy;
template <unsigned Op>
class BoxPolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
return staticAdjustInputs(alloc, ins);
@ -261,6 +297,7 @@ template <unsigned Op, MIRType Type>
class BoxExceptPolicy : public TypePolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
bool adjustInputs(TempAllocator &alloc, MInstruction *ins) {
return staticAdjustInputs(alloc, ins);
@ -272,6 +309,7 @@ template <class Lhs, class Rhs>
class MixPolicy : public TypePolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins) {
return Lhs::staticAdjustInputs(alloc, ins) && Rhs::staticAdjustInputs(alloc, ins);
}
@ -285,6 +323,7 @@ template <class Policy1, class Policy2, class Policy3>
class Mix3Policy : public TypePolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *ins) {
return Policy1::staticAdjustInputs(alloc, ins) &&
Policy2::staticAdjustInputs(alloc, ins) &&
@ -298,6 +337,7 @@ class Mix3Policy : public TypePolicy
class CallSetElementPolicy : public SingleObjectPolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *def);
};
@ -306,6 +346,7 @@ class CallSetElementPolicy : public SingleObjectPolicy
class InstanceOfPolicy : public TypePolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *def);
};
@ -315,18 +356,21 @@ class StoreTypedArrayPolicy : public BoxInputsPolicy
bool adjustValueInput(TempAllocator &alloc, MInstruction *ins, int arrayType, MDefinition *value, int valueOperand);
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
};
class StoreTypedArrayHolePolicy : public StoreTypedArrayPolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
};
class StoreTypedArrayElementStaticPolicy : public StoreTypedArrayPolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
};
@ -334,12 +378,14 @@ class StoreTypedArrayElementStaticPolicy : public StoreTypedArrayPolicy
class ClampPolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
};
class FilterTypeSetPolicy : public BoxInputsPolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
};
@ -351,6 +397,9 @@ CoercesToDouble(MIRType type)
return false;
}
#undef SPECIALIZATION_DATA_
#undef INHERIT_DATA_
#undef EMPTY_DATA_
} // namespace jit
} // namespace js