mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 06:35:42 +00:00
Bug 1115043: Ensure that range analysis takes size of element into account when removing bounds checks of AsmJS{Load/Store}Heap; r=luke
--HG-- extra : rebase_source : a7d3b262ca4ac87871da03a37cff99e355533098
This commit is contained in:
parent
db4a263c26
commit
b898694f7d
@ -782,7 +782,7 @@ AsmJSModule::initHeap(Handle<ArrayBufferObjectMaybeShared *> heap, JSContext *cx
|
||||
// ptr + data-type-byte-size > heapLength
|
||||
// i.e. ptr >= heapLength + 1 - data-type-byte-size
|
||||
// (Note that we need >= as this is what codegen uses.)
|
||||
size_t scalarByteSize = 1 << TypedArrayShift(access.type());
|
||||
size_t scalarByteSize = TypedArrayElemSize(access.type());
|
||||
X86Assembler::setPointer(access.patchLengthAt(code_),
|
||||
(void*)(heap->byteLength() + 1 - scalarByteSize));
|
||||
}
|
||||
@ -804,7 +804,7 @@ AsmJSModule::initHeap(Handle<ArrayBufferObjectMaybeShared *> heap, JSContext *cx
|
||||
const jit::AsmJSHeapAccess &access = heapAccesses_[i];
|
||||
if (access.hasLengthCheck()) {
|
||||
// See comment above for x86 codegen.
|
||||
size_t scalarByteSize = 1 << TypedArrayShift(access.type());
|
||||
size_t scalarByteSize = TypedArrayElemSize(access.type());
|
||||
X86Assembler::setInt32(access.patchLengthAt(code_), heapLength + 1 - scalarByteSize);
|
||||
}
|
||||
}
|
||||
|
@ -4360,7 +4360,7 @@ CheckArrayAccess(FunctionCompiler &f, ParseNode *viewName, ParseNode *indexExpr,
|
||||
if (byteOffset > INT32_MAX)
|
||||
return f.fail(indexExpr, "constant index out of range");
|
||||
|
||||
unsigned elementSize = 1 << TypedArrayShift(*viewType);
|
||||
unsigned elementSize = TypedArrayElemSize(*viewType);
|
||||
if (!f.m().tryRequireHeapLengthToBeAtLeast(byteOffset + elementSize)) {
|
||||
return f.failf(indexExpr, "constant index outside heap size range declared by the "
|
||||
"change-heap function (0x%x - 0x%x)",
|
||||
@ -4375,7 +4375,7 @@ CheckArrayAccess(FunctionCompiler &f, ParseNode *viewName, ParseNode *indexExpr,
|
||||
// Mask off the low bits to account for the clearing effect of a right shift
|
||||
// followed by the left shift implicit in the array access. E.g., H32[i>>2]
|
||||
// loses the low two bits.
|
||||
int32_t mask = ~((uint32_t(1) << TypedArrayShift(*viewType)) - 1);
|
||||
int32_t mask = ~(TypedArrayElemSize(*viewType) - 1);
|
||||
|
||||
MDefinition *pointerDef;
|
||||
if (indexExpr->isKind(PNK_RSH)) {
|
||||
|
@ -1128,6 +1128,29 @@ assertEqX4(f32l(SIZE - 1), BatNaN);
|
||||
assertEqX4(f32l(SIZE - 2), BatNaN);
|
||||
assertEqX4(f32l(SIZE - 3), BatNaN);
|
||||
|
||||
var code = `
|
||||
"use asm";
|
||||
var f4 = glob.SIMD.float32x4;
|
||||
var f4l = f4.load;
|
||||
var u8 = new glob.Uint8Array(heap);
|
||||
|
||||
function g(x) {
|
||||
x = x|0;
|
||||
// set a constraint on the size of the heap
|
||||
var ptr = 0;
|
||||
ptr = u8[0xFFFF] | 0;
|
||||
// give a precise range to x
|
||||
x = (x>>0) > 5 ? 5 : x;
|
||||
x = (x>>0) < 0 ? 0 : x;
|
||||
// ptr value gets a precise range but the bounds check shouldn't get
|
||||
// eliminated.
|
||||
return f4(f4l(u8, 0xFFFA + x | 0));
|
||||
}
|
||||
|
||||
return g;
|
||||
`;
|
||||
assertEqX4(asmLink(asmCompile('glob', 'ffi', 'heap', code), this, {}, new ArrayBuffer(0x10000))(0), BatNaN);
|
||||
|
||||
// Float32x4.store
|
||||
function f32s(n, v) { return m.f32s((n|0) << 2 | 0, v); };
|
||||
|
||||
|
@ -2206,15 +2206,17 @@ RangeAnalysis::analyze()
|
||||
if (iter->isAsmJSLoadHeap()) {
|
||||
MAsmJSLoadHeap *ins = iter->toAsmJSLoadHeap();
|
||||
Range *range = ins->ptr()->range();
|
||||
uint32_t elemSize = TypedArrayElemSize(ins->viewType());
|
||||
if (range && range->hasInt32LowerBound() && range->lower() >= 0 &&
|
||||
range->hasInt32UpperBound() && (uint32_t) range->upper() < minHeapLength) {
|
||||
range->hasInt32UpperBound() && uint32_t(range->upper()) + elemSize < minHeapLength) {
|
||||
ins->removeBoundsCheck();
|
||||
}
|
||||
} else if (iter->isAsmJSStoreHeap()) {
|
||||
MAsmJSStoreHeap *ins = iter->toAsmJSStoreHeap();
|
||||
Range *range = ins->ptr()->range();
|
||||
uint32_t elemSize = TypedArrayElemSize(ins->viewType());
|
||||
if (range && range->hasInt32LowerBound() && range->lower() >= 0 &&
|
||||
range->hasInt32UpperBound() && (uint32_t) range->upper() < minHeapLength) {
|
||||
range->hasInt32UpperBound() && uint32_t(range->upper()) + elemSize < minHeapLength) {
|
||||
ins->removeBoundsCheck();
|
||||
}
|
||||
}
|
||||
|
@ -304,6 +304,12 @@ TypedArrayShift(Scalar::Type viewType)
|
||||
MOZ_CRASH("Unexpected array type");
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
TypedArrayElemSize(Scalar::Type viewType)
|
||||
{
|
||||
return 1u << TypedArrayShift(viewType);
|
||||
}
|
||||
|
||||
class DataViewObject : public NativeObject
|
||||
{
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user