From 6e34a2663c94beeb6e1dc2a416e5cf8b12b4127a Mon Sep 17 00:00:00 2001 From: Brian Hackett Date: Tue, 4 Aug 2015 15:41:26 -0700 Subject: [PATCH] Bug 1189137 - Don't treat integer stores to unboxed objects as truncated, r=jandem. --- js/src/jit-test/tests/ion/bug1189137.js | 12 ++++++++++++ js/src/jit/IonBuilder.cpp | 9 +++++++-- js/src/jit/MCallOptimize.cpp | 5 +++-- js/src/jit/MIR.h | 22 +++++++++++++++++++--- js/src/jit/RangeAnalysis.cpp | 4 ++-- 5 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 js/src/jit-test/tests/ion/bug1189137.js diff --git a/js/src/jit-test/tests/ion/bug1189137.js b/js/src/jit-test/tests/ion/bug1189137.js new file mode 100644 index 000000000000..27c564195da4 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1189137.js @@ -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 1900 ? 3975308642 : 1987654322); + } +} +f(); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 2daf9a018e3a..31348b003a6f 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -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; diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index acf90dc1b722..2c49134eedfc 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -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); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 3498e7f47bf5..d51b2cf1b8a9 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -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_; } diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index d6428b217843..bbc613d57cb3 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -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