Bug 1135042: Share more code between StoreTypedArray* classes; r=bhackett

This commit is contained in:
Benjamin Bouvier 2015-03-03 11:07:49 +01:00
parent 8c280cce36
commit 71d94d71fd
3 changed files with 66 additions and 51 deletions

View File

@ -2984,9 +2984,9 @@ LIRGenerator::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins)
if (ins->isSimdWrite()) {
MOZ_ASSERT_IF(ins->writeType() == Scalar::Float32x4, ins->value()->type() == MIRType_Float32x4);
MOZ_ASSERT_IF(ins->writeType() == Scalar::Int32x4, ins->value()->type() == MIRType_Int32x4);
} else if (ins->isFloatArray()) {
MOZ_ASSERT_IF(ins->arrayType() == Scalar::Float32, ins->value()->type() == MIRType_Float32);
MOZ_ASSERT_IF(ins->arrayType() == Scalar::Float64, ins->value()->type() == MIRType_Double);
} else if (ins->isFloatWrite()) {
MOZ_ASSERT_IF(ins->writeType() == Scalar::Float32, ins->value()->type() == MIRType_Float32);
MOZ_ASSERT_IF(ins->writeType() == Scalar::Float64, ins->value()->type() == MIRType_Double);
} else {
MOZ_ASSERT(ins->value()->type() == MIRType_Int32);
}
@ -2996,7 +2996,7 @@ LIRGenerator::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins)
LAllocation value;
// For byte arrays, the value has to be in a byte register on x86.
if (ins->isByteArray() && !ins->isSimdWrite())
if (ins->isByteWrite())
value = useByteOpRegisterOrNonDoubleConstant(ins->value());
else
value = useRegisterOrNonDoubleConstant(ins->value());
@ -3023,7 +3023,7 @@ LIRGenerator::visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins)
MOZ_ASSERT(ins->index()->type() == MIRType_Int32);
MOZ_ASSERT(ins->length()->type() == MIRType_Int32);
if (ins->isFloatArray()) {
if (ins->isFloatWrite()) {
MOZ_ASSERT_IF(ins->arrayType() == Scalar::Float32, ins->value()->type() == MIRType_Float32);
MOZ_ASSERT_IF(ins->arrayType() == Scalar::Float64, ins->value()->type() == MIRType_Double);
} else {
@ -3036,7 +3036,7 @@ LIRGenerator::visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins)
LAllocation value;
// For byte arrays, the value has to be in a byte register on x86.
if (ins->isByteArray())
if (ins->isByteWrite())
value = useByteOpRegisterOrNonDoubleConstant(ins->value());
else
value = useRegisterOrNonDoubleConstant(ins->value());

View File

@ -9062,12 +9062,52 @@ class MLoadTypedArrayElementStatic
void collectRangeInfoPreTrunc() MOZ_OVERRIDE;
};
// Base class for MIR ops that write to typed arrays.
class StoreTypedArrayBase
{
Scalar::Type writeType_;
protected:
StoreTypedArrayBase(Scalar::Type writeType)
: writeType_(writeType)
{
MOZ_ASSERT(isIntegerWrite() || isFloatWrite() || isSimdWrite());
}
public:
void setWriteType(Scalar::Type type) {
writeType_ = type;
}
Scalar::Type writeType() const {
return writeType_;
}
bool isByteWrite() const {
return writeType_ == Scalar::Int8 ||
writeType_ == Scalar::Uint8 ||
writeType_ == Scalar::Uint8Clamped;
}
bool isIntegerWrite() const {
return isByteWrite () ||
writeType_ == Scalar::Int16 ||
writeType_ == Scalar::Uint16 ||
writeType_ == Scalar::Int32 ||
writeType_ == Scalar::Uint32;
}
bool isFloatWrite() const {
return writeType_ == Scalar::Float32 ||
writeType_ == Scalar::Float64;
}
bool isSimdWrite() const {
return Scalar::isSimdType(writeType());
}
};
class MStoreTypedArrayElement
: public MTernaryInstruction,
public StoreTypedArrayBase,
public StoreTypedArrayPolicy::Data
{
Scalar::Type arrayType_;
Scalar::Type writeType_;
bool requiresBarrier_;
int32_t offsetAdjustment_;
@ -9078,8 +9118,8 @@ class MStoreTypedArrayElement
Scalar::Type arrayType, MemoryBarrierRequirement requiresBarrier,
int32_t offsetAdjustment)
: MTernaryInstruction(elements, index, value),
StoreTypedArrayBase(arrayType),
arrayType_(arrayType),
writeType_(arrayType),
requiresBarrier_(requiresBarrier == DoesRequireMemoryBarrier),
offsetAdjustment_(offsetAdjustment),
racy_(false)
@ -9105,27 +9145,9 @@ class MStoreTypedArrayElement
requiresBarrier, offsetAdjustment);
}
void setWriteType(Scalar::Type type) {
writeType_ = type;
}
Scalar::Type writeType() const {
return writeType_;
}
Scalar::Type arrayType() const {
return arrayType_;
}
bool isSimdWrite() const {
return Scalar::isSimdType(writeType());
}
bool isByteArray() const {
return arrayType_ == Scalar::Int8 ||
arrayType_ == Scalar::Uint8 ||
arrayType_ == Scalar::Uint8Clamped;
}
bool isFloatArray() const {
return arrayType_ == Scalar::Float32 ||
arrayType_ == Scalar::Float64;
}
MDefinition *elements() const {
return getOperand(0);
}
@ -9161,13 +9183,13 @@ class MStoreTypedArrayElement
class MStoreTypedArrayElementHole
: public MAryInstruction<4>,
public StoreTypedArrayBase,
public StoreTypedArrayHolePolicy::Data
{
Scalar::Type arrayType_;
MStoreTypedArrayElementHole(MDefinition *elements, MDefinition *length, MDefinition *index,
MDefinition *value, Scalar::Type arrayType)
: MAryInstruction<4>(), arrayType_(arrayType)
: MAryInstruction<4>(),
StoreTypedArrayBase(arrayType)
{
initOperand(0, elements);
initOperand(1, length);
@ -9191,16 +9213,9 @@ class MStoreTypedArrayElementHole
}
Scalar::Type arrayType() const {
return arrayType_;
}
bool isByteArray() const {
return arrayType_ == Scalar::Int8 ||
arrayType_ == Scalar::Uint8 ||
arrayType_ == Scalar::Uint8Clamped;
}
bool isFloatArray() const {
return arrayType_ == Scalar::Float32 ||
arrayType_ == Scalar::Float64;
MOZ_ASSERT(!Scalar::isSimdType(writeType()),
"arrayType == writeType iff the write type isn't SIMD");
return writeType();
}
MDefinition *elements() const {
return getOperand(0);
@ -9220,7 +9235,7 @@ class MStoreTypedArrayElementHole
TruncateKind operandTruncateKind(size_t index) const MOZ_OVERRIDE;
bool canConsumeFloat32(MUse *use) const MOZ_OVERRIDE {
return use == getUseFor(3) && arrayType_ == Scalar::Float32;
return use == getUseFor(3) && arrayType() == Scalar::Float32;
}
ALLOW_CLONE(MStoreTypedArrayElementHole)
@ -9228,16 +9243,20 @@ class MStoreTypedArrayElementHole
// Store a value infallibly to a statically known typed array.
class MStoreTypedArrayElementStatic :
public MBinaryInstruction
, public StoreTypedArrayElementStaticPolicy::Data
public MBinaryInstruction,
public StoreTypedArrayBase,
public StoreTypedArrayElementStaticPolicy::Data
{
MStoreTypedArrayElementStatic(JSObject *someTypedArray, MDefinition *ptr, MDefinition *v,
int32_t offset, bool needsBoundsCheck)
: MBinaryInstruction(ptr, v), someTypedArray_(someTypedArray),
: MBinaryInstruction(ptr, v),
StoreTypedArrayBase(AnyTypedArrayType(someTypedArray_)),
someTypedArray_(someTypedArray),
offset_(offset), needsBoundsCheck_(needsBoundsCheck)
{}
AlwaysTenured<JSObject*> someTypedArray_;
// An offset to be encoded in the store instruction - taking advantage of the
// addressing modes. This is only non-zero when the access is proven to be
// within bounds.
@ -9257,11 +9276,7 @@ class MStoreTypedArrayElementStatic :
}
Scalar::Type accessType() const {
return AnyTypedArrayType(someTypedArray_);
}
bool isFloatArray() const {
return accessType() == Scalar::Float32 ||
accessType() == Scalar::Float64;
return writeType();
}
void *base() const;

View File

@ -2645,21 +2645,21 @@ MDefinition::TruncateKind
MStoreTypedArrayElement::operandTruncateKind(size_t index) const
{
// An integer store truncates the stored value.
return index == 2 && !isFloatArray() && !isSimdWrite() ? Truncate : NoTruncate;
return index == 2 && isIntegerWrite() ? Truncate : NoTruncate;
}
MDefinition::TruncateKind
MStoreTypedArrayElementHole::operandTruncateKind(size_t index) const
{
// An integer store truncates the stored value.
return index == 3 && !isFloatArray() ? Truncate : NoTruncate;
return index == 3 && isIntegerWrite() ? Truncate : NoTruncate;
}
MDefinition::TruncateKind
MStoreTypedArrayElementStatic::operandTruncateKind(size_t index) const
{
// An integer store truncates the stored value.
return index == 1 && !isFloatArray() ? Truncate : NoTruncate;
return index == 1 && isIntegerWrite() ? Truncate : NoTruncate;
}
MDefinition::TruncateKind