Bug 1189137 - Don't treat integer stores to unboxed objects as truncated, r=jandem.

This commit is contained in:
Brian Hackett 2015-08-04 15:41:26 -07:00
Родитель f674124112
Коммит 6e34a2663c
5 изменённых файлов: 43 добавлений и 9 удалений

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

@ -0,0 +1,12 @@
var arr = [];
for (var i=0; i<2000; i++)
arr.push({amount: i > 1900 ? 1987654321 : 1});
function f() {
for (var i=0; i<arr.length; i++) {
arr[i].amount += 1987654321;
assertEq(arr[i].amount, i > 1900 ? 3975308642 : 1987654322);
}
}
f();

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

@ -9391,7 +9391,8 @@ IonBuilder::jsop_setelem_typed(Scalar::Type arrayType,
ins = MStoreTypedArrayElementHole::New(alloc(), elements, length, id, toWrite, arrayType);
} else {
MStoreUnboxedScalar* store =
MStoreUnboxedScalar::New(alloc(), elements, id, toWrite, arrayType);
MStoreUnboxedScalar::New(alloc(), elements, id, toWrite, arrayType,
MStoreUnboxedScalar::TruncateInput);
ins = store;
}
@ -11660,16 +11661,19 @@ IonBuilder::storeUnboxedValue(MDefinition* obj, MDefinition* elements, int32_t e
switch (unboxedType) {
case JSVAL_TYPE_BOOLEAN:
store = MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, value, Scalar::Uint8,
MStoreUnboxedScalar::DontTruncateInput,
DoesNotRequireMemoryBarrier, elementsOffset);
break;
case JSVAL_TYPE_INT32:
store = MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, value, Scalar::Int32,
MStoreUnboxedScalar::DontTruncateInput,
DoesNotRequireMemoryBarrier, elementsOffset);
break;
case JSVAL_TYPE_DOUBLE:
store = MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, value, Scalar::Float64,
MStoreUnboxedScalar::DontTruncateInput,
DoesNotRequireMemoryBarrier, elementsOffset);
break;
@ -13033,7 +13037,8 @@ IonBuilder::storeScalarTypedObjectValue(MDefinition* typedObj,
MStoreUnboxedScalar* store =
MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, toWrite,
type, DoesNotRequireMemoryBarrier, adjustment);
type, MStoreUnboxedScalar::TruncateInput,
DoesNotRequireMemoryBarrier, adjustment);
current->add(store);
return true;

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

@ -2905,7 +2905,7 @@ IonBuilder::inlineAtomicsStore(CallInfo& callInfo)
}
MStoreUnboxedScalar* store =
MStoreUnboxedScalar::New(alloc(), elements, index, toWrite, arrayType,
DoesRequireMemoryBarrier);
MStoreUnboxedScalar::TruncateInput, DoesRequireMemoryBarrier);
current->add(store);
current->push(value);
@ -3477,7 +3477,8 @@ IonBuilder::inlineSimdStore(CallInfo& callInfo, JSNative native, SimdTypeDescr::
MDefinition* valueToWrite = callInfo.getArg(2);
MStoreUnboxedScalar* store = MStoreUnboxedScalar::New(alloc(), elements, index,
valueToWrite, arrayType);
valueToWrite, arrayType,
MStoreUnboxedScalar::TruncateInput);
store->setSimdWrite(simdType, numElems);
current->add(store);

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

@ -9635,17 +9635,29 @@ class MStoreUnboxedScalar
public StoreUnboxedScalarBase,
public StoreUnboxedScalarPolicy::Data
{
public:
enum TruncateInputKind {
DontTruncateInput,
TruncateInput
};
private:
Scalar::Type storageType_;
// Whether this store truncates out of range inputs, for use by range analysis.
TruncateInputKind truncateInput_;
bool requiresBarrier_;
int32_t offsetAdjustment_;
unsigned numElems_; // used only for SIMD
MStoreUnboxedScalar(MDefinition* elements, MDefinition* index, MDefinition* value,
Scalar::Type storageType, MemoryBarrierRequirement requiresBarrier,
int32_t offsetAdjustment)
Scalar::Type storageType, TruncateInputKind truncateInput,
MemoryBarrierRequirement requiresBarrier, int32_t offsetAdjustment)
: MTernaryInstruction(elements, index, value),
StoreUnboxedScalarBase(storageType),
storageType_(storageType),
truncateInput_(truncateInput),
requiresBarrier_(requiresBarrier == DoesRequireMemoryBarrier),
offsetAdjustment_(offsetAdjustment),
numElems_(1)
@ -9665,12 +9677,13 @@ class MStoreUnboxedScalar
static MStoreUnboxedScalar* New(TempAllocator& alloc,
MDefinition* elements, MDefinition* index,
MDefinition* value, Scalar::Type storageType,
TruncateInputKind truncateInput,
MemoryBarrierRequirement requiresBarrier =
DoesNotRequireMemoryBarrier,
int32_t offsetAdjustment = 0)
{
return new(alloc) MStoreUnboxedScalar(elements, index, value, storageType,
requiresBarrier, offsetAdjustment);
truncateInput, requiresBarrier, offsetAdjustment);
}
void setSimdWrite(Scalar::Type writeType, unsigned numElems) {
@ -9696,6 +9709,9 @@ class MStoreUnboxedScalar
AliasSet getAliasSet() const override {
return AliasSet::Store(AliasSet::UnboxedElement);
}
TruncateInputKind truncateInput() const {
return truncateInput_;
}
bool requiresMemoryBarrier() const {
return requiresBarrier_;
}

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

@ -2683,8 +2683,8 @@ MToDouble::operandTruncateKind(size_t index) const
MDefinition::TruncateKind
MStoreUnboxedScalar::operandTruncateKind(size_t index) const
{
// An integer store truncates the stored value.
return index == 2 && isIntegerWrite() ? Truncate : NoTruncate;
// Some receiver objects, such as typed arrays, will truncate out of range integer inputs.
return (truncateInput() && index == 2 && isIntegerWrite()) ? Truncate : NoTruncate;
}
MDefinition::TruncateKind