mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1014292 - OdinMonkey: restrict ArrayBuffer heap length rules to something regular and not ARM-specific (r=dougc)
This commit is contained in:
parent
c81d90b9e0
commit
81219bd5c1
@ -544,99 +544,34 @@ assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'var i=
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'var i=0; function f() { var x = 0, y = 0; u8[0] = 1; u8[1] = 2; x = 0|u8[i]; y = 0|u8[i]; return (x+y)|0;} return f'), this, null, buf)(),2);
|
||||
|
||||
// Heap length constraints
|
||||
var buf = new ArrayBuffer(0x0fff);
|
||||
assertAsmLinkAlwaysFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
var buf = new ArrayBuffer(0x1000);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
var buf = new ArrayBuffer(0x1010);
|
||||
assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
var buf = new ArrayBuffer(0x2000);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
var buf = new ArrayBuffer(0xfe000);
|
||||
new Uint8Array(buf)[0xfdfff] = 0xAA;
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xfdfff),0xAA);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xfe000),0);
|
||||
var buf = new ArrayBuffer(0xfe010);
|
||||
assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
var buf = new ArrayBuffer(0xff000);
|
||||
new Uint8Array(buf)[0xfefff] = 0xAA;
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xfefff),0xAA);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xff000),0);
|
||||
var buf = new ArrayBuffer(0xff800);
|
||||
assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
var m = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f');
|
||||
assertAsmLinkAlwaysFail(m, this, null, new ArrayBuffer(0x0fff));
|
||||
assertEq(asmLink(m, this, null, new ArrayBuffer(0x1000))(0),0);
|
||||
assertAsmLinkFail(m, this, null, new ArrayBuffer(0x1010));
|
||||
assertEq(asmLink(m, this, null, new ArrayBuffer(0x2000))(0),0);
|
||||
assertAsmLinkFail(m, this, null, new ArrayBuffer(0xfe000));
|
||||
assertAsmLinkFail(m, this, null, new ArrayBuffer(0xfe010));
|
||||
assertAsmLinkFail(m, this, null, new ArrayBuffer(0xfe000));
|
||||
assertAsmLinkFail(m, this, null, new ArrayBuffer(0xff800));
|
||||
var buf = new ArrayBuffer(0x100000);
|
||||
new Uint8Array(buf)[0xfffff] = 0xAA;
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xfffff),0xAA);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x100000),0);
|
||||
var buf = new ArrayBuffer(0x104000);
|
||||
new Uint8Array(buf)[0x103fff] = 0xAA;
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x103fff]|0; } return f'), this, null, buf)(),0xAA);
|
||||
var buf = new ArrayBuffer(0x3f8000);
|
||||
new Uint8Array(buf)[0x3f7fff] = 0xAA;
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3f7fff),0xAA);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3f8000),0);
|
||||
var buf = new ArrayBuffer(0x3fc000); // 4080K
|
||||
new Uint8Array(buf)[0x3fbfff] = 0xAA;
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3fbfff),0xAA);
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3fc000),0);
|
||||
var buf = new ArrayBuffer(0x3fe000);
|
||||
assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
var buf = new ArrayBuffer(0x410000);
|
||||
new Uint8Array(buf)[0x40ffff] = 0xAA;
|
||||
assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x40ffff]|0; } return f'), this, null, buf)(),0xAA);
|
||||
// The rest are getting too large for regular testing.
|
||||
//var buf = new ArrayBuffer(0xfe8000);
|
||||
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
//var buf = new ArrayBuffer(0xff0000); // 16302K
|
||||
//new Uint8Array(buf)[0xfeffff] = 0xAA;
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xfeffff),0xAA);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xff0000),0);
|
||||
//var buf = new ArrayBuffer(0xff8000);
|
||||
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
//var buf = new ArrayBuffer(0x3fb0000);
|
||||
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
//var buf = new ArrayBuffer(0x3fc0000); // 65280K
|
||||
//new Uint8Array(buf)[0x3fbffff] = 0xAA;
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3fbffff),0xAA);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3fc0000),0);
|
||||
//var buf = new ArrayBuffer(0x3fe0000);
|
||||
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
//var buf = new ArrayBuffer(0xfe80000);
|
||||
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
//var buf = new ArrayBuffer(0xff00000); // 255M
|
||||
//new Uint8Array(buf)[0xfeffff] = 0xAA;
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xfeffff),0xAA);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0xff00000),0);
|
||||
//var buf = new ArrayBuffer(0xff80000);
|
||||
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
//var buf = new ArrayBuffer(0x10400000);
|
||||
//new Uint8Array(buf)[0x103fffff] = 0xAA;
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x103fffff]|0; } return f'), this, null, buf)(),0xAA);
|
||||
//var buf = new ArrayBuffer(0x3fa00000);
|
||||
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
//var buf = new ArrayBuffer(0x3fc00000); // 1020M
|
||||
//new Uint8Array(buf)[0x3fbfffff] = 0xAA;
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3fbfffff),0xAA);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3fc00000),0);
|
||||
//var buf = new ArrayBuffer(0x3fe00000);
|
||||
//assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf);
|
||||
//var buf = new ArrayBuffer(0x40000000); // 1024M
|
||||
//new Uint8Array(buf)[0x3fffffff] = 0xAA;
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x3fffffff),0xAA);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x40000000),0);
|
||||
//var buf = new ArrayBuffer(0x4f000000); // 1264M - currently the largest possible heap length.
|
||||
//new Uint8Array(buf)[0x4effffff] = 0xAA;
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0),0);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x4effffff),0xAA);
|
||||
//assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; return u8[i]|0; } return f'), this, null, buf)(0x4f000000),0);
|
||||
|
||||
new Uint8Array(buf)[0x4242] = 0xAA;
|
||||
var f = asmLink(m, this, null, buf);
|
||||
assertEq(f(0),0);
|
||||
assertEq(f(0x4242),0xAA);
|
||||
assertEq(f(0x100000),0);
|
||||
assertAsmLinkFail(m, this, null, new ArrayBuffer(0x104000));
|
||||
assertEq(asmLink(m, this, null, new ArrayBuffer(0x200000))(0),0);
|
||||
assertAsmLinkFail(m, this, null, new ArrayBuffer(0x3f8000));
|
||||
assertAsmLinkFail(m, this, null, new ArrayBuffer(0x3fe000));
|
||||
assertAsmLinkFail(m, this, null, new ArrayBuffer(0x3fc000));
|
||||
assertEq(asmLink(m, this, null, new ArrayBuffer(0x400000))(0),0);
|
||||
assertAsmLinkFail(m, this, null, new ArrayBuffer(0x410000));
|
||||
assertEq(asmLink(m, this, null, new ArrayBuffer(0x800000))(0),0);
|
||||
var buf = new ArrayBuffer(0x1000000);
|
||||
new Uint8Array(buf)[0x424242] = 0xAA;
|
||||
var f = asmLink(m, this, null, buf);
|
||||
assertEq(f(0),0);
|
||||
assertEq(f(0x424242),0xAA);
|
||||
assertEq(f(0x1000000),0);
|
||||
assertEq(asmLink(m, this, null, new ArrayBuffer(0x2000000))(0),0);
|
||||
assertEq(asmLink(m, this, null, new ArrayBuffer(0x3000000))(0),0);
|
||||
|
@ -7,8 +7,12 @@
|
||||
#ifndef jit_AsmJS_h
|
||||
#define jit_AsmJS_h
|
||||
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "jsutil.h"
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "vm/ObjectImpl.h"
|
||||
|
||||
@ -88,77 +92,33 @@ IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
#endif // JS_ION
|
||||
|
||||
// The Asm.js heap length is constrained by the x64 backend heap access scheme
|
||||
// to be a multiple of the page size which is 4096 bytes, and also constrained
|
||||
// by the limits of ARM backends 'cmp immediate' instruction which supports a
|
||||
// complex range for the immediate argument.
|
||||
//
|
||||
// ARMv7 mode supports the following immediate constants, and the Thumb T2
|
||||
// instruction encoding also supports the subset of immediate constants used.
|
||||
// abcdefgh 00000000 00000000 00000000
|
||||
// 00abcdef gh000000 00000000 00000000
|
||||
// 0000abcd efgh0000 00000000 00000000
|
||||
// 000000ab cdefgh00 00000000 00000000
|
||||
// 00000000 abcdefgh 00000000 00000000
|
||||
// 00000000 00abcdef gh000000 00000000
|
||||
// 00000000 0000abcd efgh0000 00000000
|
||||
// ...
|
||||
//
|
||||
// The 4096 page size constraint restricts the length to:
|
||||
// xxxxxxxx xxxxxxxx xxxx0000 00000000
|
||||
//
|
||||
// Intersecting all the above constraints gives:
|
||||
// Heap length 0x40000000 to 0xff000000 quanta 0x01000000
|
||||
// Heap length 0x10000000 to 0x3fc00000 quanta 0x00400000
|
||||
// Heap length 0x04000000 to 0x0ff00000 quanta 0x00100000
|
||||
// Heap length 0x01000000 to 0x03fc0000 quanta 0x00040000
|
||||
// Heap length 0x00400000 to 0x00ff0000 quanta 0x00010000
|
||||
// Heap length 0x00100000 to 0x003fc000 quanta 0x00004000
|
||||
// Heap length 0x00001000 to 0x000ff000 quanta 0x00001000
|
||||
//
|
||||
inline uint32_t
|
||||
RoundUpToNextValidAsmJSHeapLength(uint32_t length)
|
||||
{
|
||||
if (length < 0x00001000u) // Minimum length is the pages size of 4096.
|
||||
return 0x1000u;
|
||||
if (length < 0x00100000u) // < 1M quanta 4K
|
||||
return (length + 0x00000fff) & ~0x00000fff;
|
||||
if (length < 0x00400000u) // < 4M quanta 16K
|
||||
return (length + 0x00003fff) & ~0x00003fff;
|
||||
if (length < 0x01000000u) // < 16M quanta 64K
|
||||
return (length + 0x0000ffff) & ~0x0000ffff;
|
||||
if (length < 0x04000000u) // < 64M quanta 256K
|
||||
return (length + 0x0003ffff) & ~0x0003ffff;
|
||||
if (length < 0x10000000u) // < 256M quanta 1M
|
||||
return (length + 0x000fffff) & ~0x000fffff;
|
||||
if (length < 0x40000000u) // < 1024M quanta 4M
|
||||
return (length + 0x003fffff) & ~0x003fffff;
|
||||
// < 4096M quanta 16M. Note zero is returned if over 0xff000000 but such
|
||||
// lengths are not currently valid.
|
||||
JS_ASSERT(length <= 0xff000000);
|
||||
return (length + 0x00ffffff) & ~0x00ffffff;
|
||||
}
|
||||
|
||||
// To succesfully link an asm.js module to an ArrayBuffer heap, the
|
||||
// ArrayBuffer's byteLength must be:
|
||||
// - greater or equal to 4096
|
||||
// - either a power of 2 OR a multiple of 16MB
|
||||
inline bool
|
||||
IsValidAsmJSHeapLength(uint32_t length)
|
||||
{
|
||||
if (length < AsmJSAllocationGranularity)
|
||||
if (length < 4096)
|
||||
return false;
|
||||
if (length <= 0x00100000u)
|
||||
return (length & 0x00000fff) == 0;
|
||||
if (length <= 0x00400000u)
|
||||
return (length & 0x00003fff) == 0;
|
||||
if (length <= 0x01000000u)
|
||||
return (length & 0x0000ffff) == 0;
|
||||
if (length <= 0x04000000u)
|
||||
return (length & 0x0003ffff) == 0;
|
||||
if (length <= 0x10000000u)
|
||||
return (length & 0x000fffff) == 0;
|
||||
if (length <= 0x40000000u)
|
||||
return (length & 0x003fffff) == 0;
|
||||
if (length <= 0xff000000u)
|
||||
|
||||
if (IsPowerOfTwo(length))
|
||||
return true;
|
||||
|
||||
return (length & 0x00ffffff) == 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline uint32_t
|
||||
RoundUpToNextValidAsmJSHeapLength(uint32_t length)
|
||||
{
|
||||
if (length < 4096)
|
||||
return 4096;
|
||||
|
||||
if (length < 16 * 1024 * 1024)
|
||||
return mozilla::RoundUpPow2(length);
|
||||
|
||||
JS_ASSERT(length <= 0xff000000);
|
||||
return (length + 0x00ffffff) & ~0x00ffffff;
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
Loading…
Reference in New Issue
Block a user