Bug 1054066 - OdinMonkey: issue deprecation warning for heaps less than 64kb (r=dougc)
authorLuke Wagner <luke@mozilla.com>
Thu, 21 Aug 2014 11:29:30 -0500
changeset 222541 57c6d6fd6bb1fbda360aba892d9b60c1c70c7778
parent 222540 880bd2e2b616fb5fe8761735d2cbfe8b894fb9c0
child 222542 6b9c89464dc6a988f033df4dbcf9699fe9736954
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdougc
bugs1054066
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1054066 - OdinMonkey: issue deprecation warning for heaps less than 64kb (r=dougc)
js/src/asmjs/AsmJSLink.cpp
js/src/asmjs/AsmJSValidate.h
js/src/jit-test/lib/asm.js
js/src/jit-test/tests/asm.js/bug941877.js
js/src/jit-test/tests/asm.js/testBasic.js
js/src/jit-test/tests/asm.js/testCaching.js
js/src/jit-test/tests/asm.js/testCloning.js
js/src/jit-test/tests/asm.js/testExpressions.js
js/src/jit-test/tests/asm.js/testFloat32.js
js/src/jit-test/tests/asm.js/testFloatingPoint.js
js/src/jit-test/tests/asm.js/testHeapAccess.js
js/src/jit-test/tests/asm.js/testX86ByteStore.js
js/src/jit-test/tests/asm.js/testZOOB.js
--- a/js/src/asmjs/AsmJSLink.cpp
+++ b/js/src/asmjs/AsmJSLink.cpp
@@ -240,31 +240,43 @@ ValidateConstant(JSContext *cx, AsmJSMod
 
     return true;
 }
 
 static bool
 LinkModuleToHeap(JSContext *cx, AsmJSModule &module, Handle<ArrayBufferObject*> heap)
 {
     uint32_t heapLength = heap->byteLength();
+
+    if (IsDeprecatedAsmJSHeapLength(heapLength)) {
+        LinkFail(cx, "ArrayBuffer byteLengths smaller than 64KB are deprecated and "
+                     "will cause a link-time failure in the future");
+
+        // The goal of deprecation is to give apps some time before linking
+        // fails. However, if warnings-as-errors is turned on (which happens as
+        // part of asm.js testing) an exception may be raised.
+        if (cx->isExceptionPending())
+            return false;
+    }
+
     if (!IsValidAsmJSHeapLength(heapLength)) {
         ScopedJSFreePtr<char> msg(
             JS_smprintf("ArrayBuffer byteLength 0x%x is not a valid heap length. The next "
                         "valid length is 0x%x",
                         heapLength,
                         RoundUpToNextValidAsmJSHeapLength(heapLength)));
         return LinkFail(cx, msg.get());
     }
 
     // This check is sufficient without considering the size of the loaded datum because heap
     // loads and stores start on an aligned boundary and the heap byteLength has larger alignment.
     JS_ASSERT((module.minHeapLength() - 1) <= INT32_MAX);
     if (heapLength < module.minHeapLength()) {
         ScopedJSFreePtr<char> msg(
-            JS_smprintf("ArrayBuffer byteLength of 0x%x is less than 0x%x (which is the"
+            JS_smprintf("ArrayBuffer byteLength of 0x%x is less than 0x%x (which is the "
                         "largest constant heap access offset rounded up to the next valid "
                         "heap size).",
                         heapLength,
                         module.minHeapLength()));
         return LinkFail(cx, msg.get());
     }
 
     // If we've generated the code with signal handlers in mind (for bounds
--- a/js/src/asmjs/AsmJSValidate.h
+++ b/js/src/asmjs/AsmJSValidate.h
@@ -64,39 +64,47 @@ static const size_t AsmJSMappedSize = 4 
 //  the heap object's byteLength must be either
 //    2^n for n in [12, 24)
 //  or
 //    2^24 * n for n >= 1.
 
 inline uint32_t
 RoundUpToNextValidAsmJSHeapLength(uint32_t length)
 {
-    if (length <= 4096)
-        return 4096;
+    if (length <= 4 * 1024)
+        return 4 * 1024;
 
     if (length <= 16 * 1024 * 1024)
         return mozilla::RoundUpPow2(length);
 
     JS_ASSERT(length <= 0xff000000);
     return (length + 0x00ffffff) & ~0x00ffffff;
 }
 
 inline bool
 IsValidAsmJSHeapLength(uint32_t length)
 {
-    bool valid = length >= 4096 &&
+    bool valid = length >= 4 * 1024 &&
                  (IsPowerOfTwo(length) ||
                   (length & 0x00ffffff) == 0);
 
     JS_ASSERT_IF(valid, length % AsmJSPageSize == 0);
     JS_ASSERT_IF(valid, length == RoundUpToNextValidAsmJSHeapLength(length));
 
     return valid;
 }
 
+// For now, power-of-2 lengths in this range are accepted, but in the future
+// we'll change this to cause link-time failure.
+inline bool
+IsDeprecatedAsmJSHeapLength(uint32_t length)
+{
+    return length >= 4 * 1024 && length < 64 * 1024 && IsPowerOfTwo(length);
+}
+
 // Return whether asm.js optimization is inhibited by the platform or
 // dynamically disabled:
 extern bool
 IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, JS::Value *vp);
 
 } // namespace js
 
 #endif // jit_AsmJS_h
--- a/js/src/jit-test/lib/asm.js
+++ b/js/src/jit-test/lib/asm.js
@@ -6,17 +6,18 @@ const ASM_OK_STRING = "successfully comp
 const ASM_TYPE_FAIL_STRING = "asm.js type error:";
 const ASM_DIRECTIVE_FAIL_STRING = "\"use asm\" is only meaningful in the Directive Prologue of a function body";
 
 const USE_ASM = '"use asm";';
 const HEAP_IMPORTS = "const i8=new glob.Int8Array(b);var u8=new glob.Uint8Array(b);"+
                      "const i16=new glob.Int16Array(b);var u16=new glob.Uint16Array(b);"+
                      "const i32=new glob.Int32Array(b);var u32=new glob.Uint32Array(b);"+
                      "const f32=new glob.Float32Array(b);var f64=new glob.Float64Array(b);";
-const BUF_64KB = new ArrayBuffer(64 * 1024);
+const BUF_MIN = 64 * 1024;
+const BUF_64KB = new ArrayBuffer(BUF_MIN);
 
 function asmCompile()
 {
     var f = Function.apply(null, arguments);
     assertEq(!isAsmJSCompilationAvailable() || isAsmJSModule(f), true);
     return f;
 }
 
@@ -155,16 +156,44 @@ function assertAsmLinkAlwaysFail(f)
     }
     if (!caught)
         throw new Error("Didn't catch the link failure error");
 
     // Turn warnings-as-errors back off
     options("werror");
 }
 
+function assertAsmLinkDeprecated(f)
+{
+    if (!isAsmJSCompilationAvailable())
+        return;
+
+    // Verify no error is thrown with warnings off
+    f.apply(null, Array.slice(arguments, 1));
+
+    // Turn on warnings-as-errors
+    var oldOpts = options("werror");
+    assertEq(oldOpts.indexOf("werror"), -1);
+
+    // Verify an error is thrown
+    var caught = false;
+    try {
+        f.apply(null, Array.slice(arguments, 1));
+    } catch (e) {
+        // Arbitrary code an run in the GetProperty, so don't assert any
+        // particular string
+        caught = true;
+    }
+    if (!caught)
+        throw new Error("Didn't catch the link failure error");
+
+    // Turn warnings-as-errors back off
+    options("werror");
+}
+
 // Linking should throw a warning-as-error but otherwise run fine
 function asmLink(f)
 {
     if (!isAsmJSCompilationAvailable())
         return f.apply(null, Array.slice(arguments, 1));
 
     // Turn on warnings-as-errors
     var oldOpts = options("werror");
--- a/js/src/jit-test/tests/asm.js/bug941877.js
+++ b/js/src/jit-test/tests/asm.js/bug941877.js
@@ -23,28 +23,28 @@ var F = (function (stdlib, n, heap) {
         };
         (((i3 - (0 < 0)) >>> ((.0 < -0) + (.0 > .0))) / 0) >> (0 + (((0 + 0) ^
 (9 > 0)) | 0))
     }
     return f;
 });
 
 var compiled = asmCompile('stdlib', 'n', 'heap', USE_ASM + FunctionBody(F));
-asmLink(compiled, this, null, new ArrayBuffer(4096))();
+asmLink(compiled, this, null, new ArrayBuffer(BUF_MIN))();
 
 var F = (function(stdlib, n, heap) {
     var Float64ArrayView = new stdlib.Float64Array(heap)
     function f() {
         Float64ArrayView[0] = +(0xffffffff / 0xffffffff >> 0)
     }
     return f;
 });
 
 var compiled = asmCompile('stdlib', 'n', 'heap', USE_ASM + FunctionBody(F));
-asmLink(compiled, this, null, new ArrayBuffer(4096))();
+asmLink(compiled, this, null, new ArrayBuffer(BUF_MIN))();
 
 function test0(x)
 {
    return (x >>> 0) % 10;
 }
 assertEq(test0(25), 5);
 assertEq(test0(24), 4);
 assertEq(test0(23), 3);
--- a/js/src/jit-test/tests/asm.js/testBasic.js
+++ b/js/src/jit-test/tests/asm.js/testBasic.js
@@ -48,30 +48,37 @@ assertAsmTypeFail(USE_ASM + 'function f(
 
 assertAsmTypeFail('glob', USE_ASM + 'var im=glob.imul; function f() {} return f');
 assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), null);
 assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), {});
 assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), {imul:Math.imul});
 assertEq(asmLink(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), {Math:{imul:Math.imul}})(2,3), 6);
 assertEq(asmLink(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), this)(8,4), 32);
 
-assertAsmLinkAlwaysFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), null, null);
-assertAsmLinkAlwaysFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, null);
-assertAsmLinkAlwaysFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, null);
-assertAsmLinkAlwaysFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, new ArrayBuffer(1));
-assertAsmLinkFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, new ArrayBuffer(100));
-assertAsmLinkFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, new ArrayBuffer(4000));
-assertEq(asmLink(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, new ArrayBuffer(4096))(), undefined);
-assertEq(asmLink(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, new ArrayBuffer(2*4096))(), undefined);
+var module = asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f');
+assertAsmLinkAlwaysFail(module, null, null);
+assertAsmLinkAlwaysFail(module, this, null, null);
+assertAsmLinkAlwaysFail(module, this, null, null);
+assertAsmLinkAlwaysFail(module, this, null, new ArrayBuffer(1));
+assertAsmLinkFail(module, this, null, new ArrayBuffer(4));
+assertAsmLinkFail(module, this, null, new ArrayBuffer(100));
+assertAsmLinkFail(module, this, null, new ArrayBuffer(4092));
+assertAsmLinkFail(module, this, null, new ArrayBuffer(64000));
+assertAsmLinkFail(module, this, null, new ArrayBuffer(BUF_MIN+4));
+assertAsmLinkDeprecated(module, this, null, new ArrayBuffer(4096));
+assertAsmLinkDeprecated(module, this, null, new ArrayBuffer(2*4096));
+assertAsmLinkDeprecated(module, this, null, new ArrayBuffer(4*4096));
+assertAsmLinkDeprecated(module, this, null, new ArrayBuffer(32*1024));
+assertEq(asmLink(module, this, null, new ArrayBuffer(BUF_MIN))(), undefined);
 
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i]|0; return i|0}; return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>1]|0; return i|0}; return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>1]|0; return i|0}; return f');
-assertAsmLinkAlwaysFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f'), this, null, new ArrayBuffer(4095));
-assertEq(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f')(this, null, new ArrayBuffer(4096))(), 0);
+assertAsmLinkAlwaysFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f'), this, null, new ArrayBuffer(BUF_MIN-1));
+assertEq(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f')(this, null, new ArrayBuffer(BUF_MIN))(), 0);
 
 var exp = asmLink(asmCompile(USE_ASM + "return {}"));
 assertEq(Object.keys(exp).length, 0);
 
 var exp = asmLink(asmCompile(USE_ASM + "function f() { return 3 } return {f:f,f:f}"));
 assertEq(exp.f(), 3);
 assertEq(Object.keys(exp).join(), 'f');
 
--- a/js/src/jit-test/tests/asm.js/testCaching.js
+++ b/js/src/jit-test/tests/asm.js/testCaching.js
@@ -91,12 +91,12 @@ assertEq(isAsmJSModule(m), false);
 // separate address space) to compile/cache the code. Ideally, every asmCompile
 // would do this, but that makes jit-tests run 100x slower. Do it here, for one
 // of each feature. asm.js/testBullet.js should pound on everything.
 assertEq(asmLink(asmCompileCached(USE_ASM + "function f(i) { i=i|0; return +((i+1)|0) } function g(d) { d=+d; return +(d + +f(42) + 1.5) } return g"))(.2), .2+43+1.5);
 assertEq(asmLink(asmCompileCached(USE_ASM + "function f1() { return 1 } function f2() { return 2 } function f(i) { i=i|0; return T[i&1]()|0 } var T=[f1,f2]; return f"))(1), 2);
 assertEq(asmLink(asmCompileCached("g", USE_ASM + "var s=g.Math.sin; function f(d) { d=+d; return +s(d) } return f"), this)(.3), Math.sin(.3));
 assertEq(asmLink(asmCompileCached("g","ffis", USE_ASM + "var ffi=ffis.ffi; function f(i) { i=i|0; return ffi(i|0)|0 } return f"), null, {ffi:function(i){return i+2}})(1), 3);
 assertEq(asmLink(asmCompileCached("g","ffis", USE_ASM + "var x=ffis.x|0; function f() { return x|0 } return f"), null, {x:43})(), 43);
-var i32 = new Int32Array(4096);
+var i32 = new Int32Array(BUF_MIN/4);
 i32[4] = 42;
 assertEq(asmLink(asmCompileCached("g","ffis","buf", USE_ASM + "var i32=new g.Int32Array(buf); function f(i) { i=i|0; return i32[i>>2]|0 } return f"), this, null, i32.buffer)(4*4), 42);
 assertEq(asmLink(asmCompileCached('glob', USE_ASM + 'var x=glob.Math.PI; function f() { return +x } return f'), this)(), Math.PI);
--- a/js/src/jit-test/tests/asm.js/testCloning.js
+++ b/js/src/jit-test/tests/asm.js/testCloning.js
@@ -1,18 +1,18 @@
 load(libdir + "asm.js");
 
 var code = asmCompile(USE_ASM + "function g() { return 42 } return g");
 assertEq(asmLink(code)(), 42);
 assertEq(asmLink(code)(), 42);
 
 var code = asmCompile('glob', 'ffis', 'buf', USE_ASM + 'var i32=new glob.Int32Array(buf); function g() { return i32[0]|0 } return g');
-var i32_1 = new Int32Array(4096);
+var i32_1 = new Int32Array(BUF_MIN/4);
 i32_1[0] = 42;
-var i32_2 = new Int32Array(4096);
+var i32_2 = new Int32Array(BUF_MIN/4);
 i32_2[0] = 13;
 assertEq(asmLink(code, this, null, i32_1.buffer)(), 42);
 assertEq(asmLink(code, this, null, i32_2.buffer)(), 13);
 var i32_3 = new Int32Array(4097);
 assertAsmLinkFail(code, this, null, i32_3.buffer);
 
 var code = asmCompile('glob', 'ffis', USE_ASM + 'var ffi=ffis.ffi; function g(n) { n=n|0; var i=0; for(; (i|0)<(n|0); i=(i+1)|0) ffi() } return g');
 var calls1 = 0, calls2 = 0;
--- a/js/src/jit-test/tests/asm.js/testExpressions.js
+++ b/js/src/jit-test/tests/asm.js/testExpressions.js
@@ -274,17 +274,17 @@ assertEq(f(0), -1);
 assertEq(f(1), 0);
 assertEq(f(2), 0);
 
 // beware ye constant-evaluate of boolean-producing operators
 assertEq(asmLink(asmCompile(USE_ASM + "function f() { return (4 | (2 == 2))|0 } return f"))(), 5);
 assertEq(asmLink(asmCompile(USE_ASM + "function f() { return (4 | (!2))|0 } return f"))(), 4);
 
 // get that order-of-operations right!
-var buf = new ArrayBuffer(4096);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob','imp','buf', USE_ASM + "var i32=new glob.Int32Array(buf); var x=0; function a() { return x|0 } function b() { x=42; return 0 } function f() { i32[((b()|0) & 0x3) >> 2] = a()|0 } return f"), this, null, buf)();
 assertEq(new Int32Array(buf)[0], 42);
 
 assertEq(asmLink(asmCompile(USE_ASM + "function f() { var a=0,i=0; for (; ~~i!=4; i=(i+1)|0) { a = (a*5)|0; if (+(a>>>0) != 0.0) return 1; } return 0; } return f"))(), 0)
 
 // Signed integer division by a power of two.
 var f = asmLink(asmCompile(USE_ASM + "function f(i) { i=i|0; return ((i|0)/1)|0; } return f;"));
 for (let i = 0; i < 31; i++) {
--- a/js/src/jit-test/tests/asm.js/testFloat32.js
+++ b/js/src/jit-test/tests/asm.js/testFloat32.js
@@ -1,13 +1,13 @@
 load(libdir + "asm.js");
 const TO_FLOAT32 = "var toF = glob.Math.fround;";
 const HEAP32 = "var f32 = new glob.Float32Array(heap);";
 const HEAP64 = "var f64 = new glob.Float64Array(heap);"
-var heap = new ArrayBuffer(4096);
+var heap = new ArrayBuffer(BUF_MIN);
 
 // Module linking
 assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() {} return f"), null);
 assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() {} return f"), {fround: Math.fround});
 assertAsmLinkFail(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() {} return f"), {Math: {fround: Math.imul}});
 assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f() {} return f"), {Math:{fround: Math.fround}})(), undefined);
 
 // Argument coercions
--- a/js/src/jit-test/tests/asm.js/testFloatingPoint.js
+++ b/js/src/jit-test/tests/asm.js/testFloatingPoint.js
@@ -89,17 +89,17 @@ assertEq(f(-Math.pow(2,31),-1), -Math.po
 var f = asmLink(asmCompile(USE_ASM + "function f(i,j) { i=i|0;j=j|0; return +(((i|0)%(j|0))|0) } return f"));
 assertEq(f(1,0), 0);
 assertEq(f(-Math.pow(2,31),-1), 0);
 
 var {f,g} = asmLink(asmCompile(USE_ASM + "function f() { return 3.5 } function g(d) { d=+d; return +(d+3.5) } return {f:f,g:g}"));
 assertEq(f(), 3.5);
 assertEq(g(1), 1+3.5);
 
-var buf = new ArrayBuffer(4096);
+var buf = new ArrayBuffer(BUF_MIN);
 var f64 = new Float64Array(buf);
 var i32 = new Int32Array(buf);
 var u32 = new Uint32Array(buf);
 var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[0] } return f'), this, null, buf);
 f64[0] = 0;
 assertEq(f(), 0);
 f64[0] = -1;
 assertEq(f(), -1);
--- a/js/src/jit-test/tests/asm.js/testHeapAccess.js
+++ b/js/src/jit-test/tests/asm.js/testHeapAccess.js
@@ -4,152 +4,152 @@ assertAsmTypeFail('glob', 'imp', 'b', US
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[0>>2] = 4; return +f32[0>>2]; } return f');
 
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { var x=0,y=0; return i8[x+y]|0 } return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { var x=0,y=0; return u8[x+y]|0 } return f');
 
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[0>>0]|0 }; return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[0>>1]|0 }; return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[0>>4]|0 }; return f');
-assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[0]|0 }; return f'), this, null, new ArrayBuffer(4096))(), 0);
+assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[0]|0 }; return f'), this, null, new ArrayBuffer(BUF_MIN))(), 0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0), 0);
 
 setCachingEnabled(true);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i8[0]|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0),0);
 assertEq(f(0x7f),0x7f);
 assertEq(f(0xff),-1);
 assertEq(f(0x100),0);
 
 // Test signal handlers deactivation
 (function() {
     var jco = getJitCompilerOptions();
     var signalHandlersBefore = jco["signals.enable"];
     if (signalHandlersBefore == 1) {
         setJitCompilerOption("signals.enable", 0);
 
         if (isCachingEnabled()) {
             // Cloned modules should fail on linking if the initial module has
             // been compiled with signals but signals are deactivated.
             var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i8[0]|0}; return f');
-            assertAsmLinkFail(code, this, null, new ArrayBuffer(4096));
+            assertAsmLinkFail(code, this, null, new ArrayBuffer(BUF_MIN));
         }
 
         var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + '/* not a clone */ function f(i) {i=i|0; i32[0] = i; return i8[0]|0}; return f');
-        var f = asmLink(code, this, null, new ArrayBuffer(4096));
+        var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
         assertEq(f(0),0);
         assertEq(f(0x7f),0x7f);
         assertEq(f(0xff),-1);
         assertEq(f(0x100),0);
         setJitCompilerOption("signals.enable", 1);
     }
     jco = getJitCompilerOptions();
     var signalHandlersAfter = jco["signals.enable"];
     assertEq(signalHandlersBefore, signalHandlersAfter);
 })();
 
 setCachingEnabled(false);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return u8[0]|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0),0);
 assertEq(f(0x7f),0x7f);
 assertEq(f(0xff),0xff);
 assertEq(f(0x100),0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i16[0]|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0),0);
 assertEq(f(0x7fff),0x7fff);
 assertEq(f(0xffff),-1);
 assertEq(f(0x10000),0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return u16[0]|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0),0);
 assertEq(f(0x7fff),0x7fff);
 assertEq(f(0xffff),0xffff);
 assertEq(f(0x10000),0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i32[0]|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0),0);
 assertEq(f(0x7fffffff),0x7fffffff);
 assertEq(f(0xffffffff),-1);
 assertEq(f(0x100000000),0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return u32[0]|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0),0);
 assertEq(f(0x7fffffff),0x7fffffff);
 assertEq(f(0xffffffff),-1);
 assertEq(f(0x100000000),0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return i8[0]|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0),0);
 assertEq(f(0x7f),0x7f);
 assertEq(f(0xff),-1);
 assertEq(f(0x100),0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i32[0] = i; return u8[0]|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0),0);
 assertEq(f(0x7f),0x7f);
 assertEq(f(0xff),0xff);
 assertEq(f(0x100),0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i8[0] = i; return i8[0]|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0),0);
 assertEq(f(0x7f),0x7f);
 assertEq(f(0xff),-1);
 assertEq(f(0x100),0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i8[0] = i; return u8[0]|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0),0);
 assertEq(f(0x7f),0x7f);
 assertEq(f(0xff),0xff);
 assertEq(f(0x100),0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return (~~+f64[i>>3])|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0, 1.3), 1);
-assertEq(f(4088, 2.5), 2);
-assertEq(f(4096, 3.8), 0);
+assertEq(f(BUF_MIN-8, 2.5), 2);
+assertEq(f(BUF_MIN, 3.8), 0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return (~~f64[i>>3])|0}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0, 1.3), 1);
-assertEq(f(4088, 2.5), 2);
-assertEq(f(4096, 3.8), 0);
+assertEq(f(BUF_MIN-8, 2.5), 2);
+assertEq(f(BUF_MIN, 3.8), 0);
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return +f64[i>>3]}; return f');
-var f = asmLink(code, this, null, new ArrayBuffer(4096));
+var f = asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 assertEq(f(0, 1.3), 1.3);
-assertEq(f(4088, 2.5), 2.5);
-assertEq(f(4096, 3.8), NaN);
+assertEq(f(BUF_MIN-8, 2.5), 2.5);
+assertEq(f(BUF_MIN, 3.8), NaN);
 
-var i32 = new Int32Array(4096);
+var i32 = new Int32Array(BUF_MIN);
 i32[0] = 42;
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[1] = i32[0] }; return f'), this, null, i32.buffer)();
 assertEq(i32[1], 42);
 
-var f64 = new Float64Array(4096);
+var f64 = new Float64Array(BUF_MIN);
 f64[0] = 42;
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[1] = f64[0] }; return f'), this, null, f64.buffer)();
 assertEq(f64[1], 42);
 
-var i32 = new Int32Array(4096/4);
+var i32 = new Int32Array(BUF_MIN/4);
 i32[0] = 13;
 i32[1] = 0xfffeeee;
 var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return i32[((i<<2)+1)>>2]|0 }; return f'), this, null, i32.buffer);
 assertEq(f(0), 13);
 assertEq(f(1), 0xfffeeee);
 var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; return i32[((i<<2)+2)>>2]|0 }; return f'), this, null, i32.buffer);
 assertEq(f(0), 13);
 assertEq(f(1), 0xfffeeee);
@@ -190,317 +190,317 @@ new Float64Array(BUF_64KB)[1] = 1.3;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[(8&0xffff)>>3] } return f'), this, null, BUF_64KB)(), 1.3);
 
 asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u8[255]; u8[i] } return f');
 asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u8[i&0xff]; u8[255] } return f');
 asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u32[63]; u32[i>>2] } return f');
 asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u32[i>>2]; u32[63] } return f');
 
 var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u32[64] } return f');
-asmLink(code, this, null, new ArrayBuffer(4096));
+asmLink(code, this, null, new ArrayBuffer(BUF_MIN));
 
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) { i=i|0; u32[12] = i } return f'), this, null, BUF_64KB)(11);
 assertEq(new Int32Array(BUF_64KB)[12], 11);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[12]|0 } return f'), this, null, BUF_64KB)(), 11);
 new Float64Array(BUF_64KB)[0] = 3.5;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +-f64[0] } return f'), this, null, BUF_64KB)(), -3.5);
 
 // Test constant loads.
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[1] = -1 } return f'), this, null, buf)();
 assertEq(new Uint8Array(buf)[0], 0);
 assertEq(new Uint8Array(buf)[1], 255);
 assertEq(new Uint8Array(buf)[2], 0);
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[4095] = -1 } return f'), this, null, buf)();
 assertEq(new Uint8Array(buf)[4094], 0);
 assertEq(new Uint8Array(buf)[4095], 255);
 assertEq(new Uint8Array(buf)[4096], 0);
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[4096] = -1 } return f'), this, null, buf)();
 assertEq(new Uint8Array(buf)[4095], 0);
 assertEq(new Uint8Array(buf)[4096], 255);
 assertEq(new Uint8Array(buf)[4097], 0);
-assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[8192] = -1 } return f'), this, null, buf);
+assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[' + BUF_MIN + '] = -1 } return f'), this, null, buf);
 var buf = new ArrayBuffer(262144);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[258048] = -1 } return f'), this, null, buf)();
 assertEq(new Uint8Array(buf)[258047], 0);
 assertEq(new Uint8Array(buf)[258048], 255);
 assertEq(new Uint8Array(buf)[258049], 0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[1] = -1 } return f'), this, null, buf)();
 assertEq(new Int8Array(buf)[0], 0);
 assertEq(new Int8Array(buf)[1], -1);
 assertEq(new Int8Array(buf)[2], 0);
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[4095] = -1 } return f'), this, null, buf)();
 assertEq(new Int8Array(buf)[4094], 0);
 assertEq(new Int8Array(buf)[4095], -1);
 assertEq(new Int8Array(buf)[4096], 0);
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[4096] = -1 } return f'), this, null, buf)();
 assertEq(new Int8Array(buf)[4095], 0);
 assertEq(new Int8Array(buf)[4096], -1);
 assertEq(new Int8Array(buf)[4097], 0);
-assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[8192] = -1 } return f'), this, null, buf);
+assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[' + BUF_MIN + '] = -1 } return f'), this, null, buf);
 var buf = new ArrayBuffer(262144);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[258048] = -1 } return f'), this, null, buf)();
 assertEq(new Int8Array(buf)[258047], 0);
 assertEq(new Int8Array(buf)[258048], -1);
 assertEq(new Int8Array(buf)[258049], 0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[1] = -1 } return f'), this, null, buf)();
 assertEq(new Uint16Array(buf)[0], 0);
 assertEq(new Uint16Array(buf)[1], 65535);
 assertEq(new Uint16Array(buf)[2], 0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[2047] = -1 } return f'), this, null, buf)();
-assertEq(new Uint16Array(buf)[2046], 0);
-assertEq(new Uint16Array(buf)[2047], 65535);
-assertEq(new Uint16Array(buf)[2048], 0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[2048] = -1 } return f'), this, null, buf)();
-assertEq(new Uint16Array(buf)[2047], 0);
-assertEq(new Uint16Array(buf)[2048], 65535);
-assertEq(new Uint16Array(buf)[2049], 0);
-assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[4096] = -1 } return f'), this, null, buf);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[' + (BUF_MIN/2-1) + '] = -1 } return f'), this, null, buf)();
+assertEq(new Uint16Array(buf)[BUF_MIN/2-2], 0);
+assertEq(new Uint16Array(buf)[BUF_MIN/2-1], 65535);
+assertEq(new Uint16Array(buf)[BUF_MIN/2], undefined);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[' + (BUF_MIN/4) + '] = -1 } return f'), this, null, buf)();
+assertEq(new Uint16Array(buf)[BUF_MIN/4-1], 0);
+assertEq(new Uint16Array(buf)[BUF_MIN/4], 65535);
+assertEq(new Uint16Array(buf)[BUF_MIN/4+1], 0);
+assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[' + (BUF_MIN/2) + '] = -1 } return f'), this, null, buf);
 var buf = new ArrayBuffer(262144);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[126976] = -1 } return f'), this, null, buf)();
 assertEq(new Uint16Array(buf)[126975], 0);
 assertEq(new Uint16Array(buf)[126976], 65535);
 assertEq(new Uint16Array(buf)[126977], 0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[1] = -1 } return f'), this, null, buf)();
 assertEq(new Int16Array(buf)[0], 0);
 assertEq(new Int16Array(buf)[1], -1);
 assertEq(new Int16Array(buf)[2], 0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[2047] = -1 } return f'), this, null, buf)();
-assertEq(new Int16Array(buf)[2046], 0);
-assertEq(new Int16Array(buf)[2047], -1);
-assertEq(new Int16Array(buf)[2048], 0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[2048] = -1 } return f'), this, null, buf)();
-assertEq(new Int16Array(buf)[2047], 0);
-assertEq(new Int16Array(buf)[2048], -1);
-assertEq(new Int16Array(buf)[2049], 0);
-assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[4096] = -1 } return f'), this, null, buf);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[' + (BUF_MIN/2-1) + '] = -1 } return f'), this, null, buf)();
+assertEq(new Int16Array(buf)[BUF_MIN/2-2], 0);
+assertEq(new Int16Array(buf)[BUF_MIN/2-1], -1);
+assertEq(new Int16Array(buf)[BUF_MIN/2], undefined);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[' + (BUF_MIN/4) + '] = -1 } return f'), this, null, buf)();
+assertEq(new Int16Array(buf)[BUF_MIN/4-1], 0);
+assertEq(new Int16Array(buf)[BUF_MIN/4], -1);
+assertEq(new Int16Array(buf)[BUF_MIN/4+1], 0);
+assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[' + (BUF_MIN/2) + '] = -1 } return f'), this, null, buf);
 var buf = new ArrayBuffer(262144);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[126976] = -1 } return f'), this, null, buf)();
 assertEq(new Int16Array(buf)[126975], 0);
 assertEq(new Int16Array(buf)[126976], -1);
 assertEq(new Int16Array(buf)[126977], 0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[1] = -1 } return f'), this, null, buf)();
 assertEq(new Uint32Array(buf)[0], 0);
 assertEq(new Uint32Array(buf)[1], 4294967295);
 assertEq(new Uint32Array(buf)[2], 0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[1023] = -1 } return f'), this, null, buf)();
-assertEq(new Uint32Array(buf)[1022], 0);
-assertEq(new Uint32Array(buf)[1023], 4294967295);
-assertEq(new Uint32Array(buf)[1024], 0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[1024] = -1 } return f'), this, null, buf)();
-assertEq(new Uint32Array(buf)[1023], 0);
-assertEq(new Uint32Array(buf)[1024], 4294967295);
-assertEq(new Uint32Array(buf)[1025], 0);
-assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[2048] = -1 } return f'), this, null, buf);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[' + (BUF_MIN/4-1) + '] = -1 } return f'), this, null, buf)();
+assertEq(new Uint32Array(buf)[BUF_MIN/4-2], 0);
+assertEq(new Uint32Array(buf)[BUF_MIN/4-1], 4294967295);
+assertEq(new Uint32Array(buf)[BUF_MIN/4], undefined);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[' + (BUF_MIN/8) + '] = -1 } return f'), this, null, buf)();
+assertEq(new Uint32Array(buf)[BUF_MIN/8-1], 0);
+assertEq(new Uint32Array(buf)[BUF_MIN/8], 4294967295);
+assertEq(new Uint32Array(buf)[BUF_MIN/8+1], 0);
+assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[' + (BUF_MIN/4) + '] = -1 } return f'), this, null, buf);
 var buf = new ArrayBuffer(262144);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[61440] = -1 } return f'), this, null, buf)();
 assertEq(new Uint32Array(buf)[61439], 0);
 assertEq(new Uint32Array(buf)[61440], 4294967295);
 assertEq(new Uint32Array(buf)[61441], 0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[1] = -1 } return f'), this, null, buf)();
 assertEq(new Int32Array(buf)[0], 0);
 assertEq(new Int32Array(buf)[1], -1);
 assertEq(new Int32Array(buf)[2], 0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[1023] = -1 } return f'), this, null, buf)();
-assertEq(new Int32Array(buf)[1022], 0);
-assertEq(new Int32Array(buf)[1023], -1);
-assertEq(new Int32Array(buf)[124], 0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[1024] = -1 } return f'), this, null, buf)();
-assertEq(new Int32Array(buf)[1023], 0);
-assertEq(new Int32Array(buf)[1024], -1);
-assertEq(new Int32Array(buf)[1025], 0);
-assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[2048] = -1 } return f'), this, null, buf);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[' + (BUF_MIN/4-1) + '] = -1 } return f'), this, null, buf)();
+assertEq(new Int32Array(buf)[BUF_MIN/4-2], 0);
+assertEq(new Int32Array(buf)[BUF_MIN/4-1], -1);
+assertEq(new Int32Array(buf)[BUF_MIN/4], undefined);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[' + (BUF_MIN/8) + '] = -1 } return f'), this, null, buf)();
+assertEq(new Int32Array(buf)[BUF_MIN/8-1], 0);
+assertEq(new Int32Array(buf)[BUF_MIN/8], -1);
+assertEq(new Int32Array(buf)[BUF_MIN/8+1], 0);
+assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[' + (BUF_MIN/4) + '] = -1 } return f'), this, null, buf);
 var buf = new ArrayBuffer(262144);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[61440] = -1 } return f'), this, null, buf)();
 assertEq(new Int32Array(buf)[61439], 0);
 assertEq(new Int32Array(buf)[61440], -1);
 assertEq(new Int32Array(buf)[61441], 0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[1] = -1.0 } return f'), this, null, buf)();
 assertEq(new Int32Array(buf)[0], 0);
 assertEq(new Float32Array(buf)[1], -1.0);
 assertEq(new Int32Array(buf)[2], 0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[1023] = -1.0 } return f'), this, null, buf)();
-assertEq(new Int32Array(buf)[1022], 0);
-assertEq(new Float32Array(buf)[1023], -1.0);
-assertEq(new Int32Array(buf)[124], 0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[1024] = -1.0 } return f'), this, null, buf)();
-assertEq(new Int32Array(buf)[1023], 0);
-assertEq(new Float32Array(buf)[1024], -1.0);
-assertEq(new Int32Array(buf)[1025], 0);
-assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[2048] = -1.0 } return f'), this, null, buf);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[' + (BUF_MIN/4-1) + '] = -1.0 } return f'), this, null, buf)();
+assertEq(new Int32Array(buf)[BUF_MIN/4-2], 0);
+assertEq(new Float32Array(buf)[BUF_MIN/4-1], -1.0);
+assertEq(new Int32Array(buf)[BUF_MIN/4], undefined);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[' + (BUF_MIN/8) + '] = -1.0 } return f'), this, null, buf)();
+assertEq(new Int32Array(buf)[BUF_MIN/8-1], 0);
+assertEq(new Float32Array(buf)[BUF_MIN/8], -1.0);
+assertEq(new Int32Array(buf)[BUF_MIN/8+1], 0);
+assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[' + (BUF_MIN/4) + '] = -1.0 } return f'), this, null, buf);
 var buf = new ArrayBuffer(262144);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[61440] = -1.0 } return f'), this, null, buf)();
 assertEq(new Float32Array(buf)[61439], 0.0);
 assertEq(new Float32Array(buf)[61440], -1.0);
 assertEq(new Float32Array(buf)[61441], 0.0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[1] = -1.0 } return f'), this, null, buf)();
 assertEq(new Float64Array(buf)[0], 0.0);
 assertEq(new Float64Array(buf)[1], -1.0);
 assertEq(new Float64Array(buf)[2], 0.0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[511] = -1.0 } return f'), this, null, buf)();
-assertEq(new Float64Array(buf)[510], 0.0);
-assertEq(new Float64Array(buf)[511], -1.0);
-assertEq(new Float64Array(buf)[512], 0.0);
-var buf = new ArrayBuffer(8192);
-asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[512] = -1.0 } return f'), this, null, buf)();
-assertEq(new Float64Array(buf)[511], 0.0);
-assertEq(new Float64Array(buf)[512], -1.0);
-assertEq(new Float64Array(buf)[513], 0.0);
-assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[1024] = -1.0 } return f'), this, null, buf);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[' + (BUF_MIN/8-1) + '] = -1.0 } return f'), this, null, buf)();
+assertEq(new Float64Array(buf)[BUF_MIN/8-2], 0.0);
+assertEq(new Float64Array(buf)[BUF_MIN/8-1], -1.0);
+assertEq(new Float64Array(buf)[BUF_MIN/8], undefined);
+var buf = new ArrayBuffer(BUF_MIN);
+asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[' + (BUF_MIN/16) + '] = -1.0 } return f'), this, null, buf)();
+assertEq(new Float64Array(buf)[BUF_MIN/16-1], 0.0);
+assertEq(new Float64Array(buf)[BUF_MIN/16], -1.0);
+assertEq(new Float64Array(buf)[BUF_MIN/16+1], 0.0);
+assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[' + (BUF_MIN/8) + '] = -1.0 } return f'), this, null, buf);
 var buf = new ArrayBuffer(262144);
 asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[28672] = -1.0 } return f'), this, null, buf)();
 assertEq(new Float64Array(buf)[28671], 0.0);
 assertEq(new Float64Array(buf)[28672], -1.0);
 assertEq(new Float64Array(buf)[28673], 0.0);
 
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Uint8Array(buf)[1] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[1]|0; } return f'), this, null, buf)(),255);
 new Int8Array(buf)[1] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i8[1]|0; } return f'), this, null, buf)(),-1);
 var buf = new ArrayBuffer(262144);
 new Uint8Array(buf)[126976] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[126976]|0; } return f'), this, null, buf)(),255);
 new Int8Array(buf)[126976] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i8[126976]|0; } return f'), this, null, buf)(),-1);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Uint16Array(buf)[1] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u16[1]|0; } return f'), this, null, buf)(),65535);
 new Int16Array(buf)[1] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i16[1]|0; } return f'), this, null, buf)(),-1);
 var buf = new ArrayBuffer(262144);
 new Uint16Array(buf)[126976] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u16[126976]|0; } return f'), this, null, buf)(),65535);
 new Int16Array(buf)[126976] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i16[126976]|0; } return f'), this, null, buf)(),-1);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Uint32Array(buf)[1] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[1]|0; } return f'), this, null, buf)(),-1);
 new Int32Array(buf)[1] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[1]|0; } return f'), this, null, buf)(),-1);
 var buf = new ArrayBuffer(262144);
 new Int32Array(buf)[61440] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[61440]|0; } return f'), this, null, buf)(),-1);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Float32Array(buf)[1] = -1.0;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[1]; } return f'), this, null, buf)(),-1.0);
-new Float32Array(buf)[1023] = -1.0;
-assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[1023]; } return f'), this, null, buf)(),-1.0);
-new Float32Array(buf)[1024] = -1.0;
-assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[1024]; } return f'), this, null, buf)(),-1.0);
-assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[2048]; } return f'), this, null, buf);
+new Float32Array(buf)[BUF_MIN/4-1] = -1.0;
+assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[' + (BUF_MIN/4-1) + ']; } return f'), this, null, buf)(),-1.0);
+new Float32Array(buf)[BUF_MIN/8] = -1.0;
+assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[' + (BUF_MIN/8) + ']; } return f'), this, null, buf)(),-1.0);
+assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[' + (BUF_MIN/4) + ']; } return f'), this, null, buf);
 var buf = new ArrayBuffer(262144);
 new Float32Array(buf)[61440] = -1.0;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[61440]; } return f'), this, null, buf)(),-1.0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Float64Array(buf)[1] = -1.0;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[1]; } return f'), this, null, buf)(),-1.0);
-new Float64Array(buf)[511] = -1.0;
-assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[511]; } return f'), this, null, buf)(),-1.0);
-new Float64Array(buf)[512] = -1.0;
-assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[512]; } return f'), this, null, buf)(),-1.0);
-assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[1024]; } return f'), this, null, buf);
+new Float64Array(buf)[BUF_MIN/8-1] = -1.0;
+assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[' + (BUF_MIN/8-1) + ']; } return f'), this, null, buf)(),-1.0);
+new Float64Array(buf)[BUF_MIN/16] = -1.0;
+assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[' + (BUF_MIN/16) + ']; } return f'), this, null, buf)(),-1.0);
+assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[' + (BUF_MIN/8) + ']; } return f'), this, null, buf);
 var buf = new ArrayBuffer(262144);
 new Float64Array(buf)[28672] = -1.0;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[28672]; } return f'), this, null, buf)(),-1.0);
 
 // Test bitwise-and optimizations.
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Uint8Array(buf)[8191] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[8191&8191]|0; } return f'), this, null, buf)(),255);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[(8191&8191)>>0]|0; } return f'), this, null, buf)(),255);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[8192&8191] = -1; u8[0] = 0; return u8[8192&8191]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u8[(8192&8191)>>0] = -1; u8[0] = 0; return u8[(8192&8191)>>0]|0; } return f'), this, null, buf)(),0);
 new Int8Array(buf)[8191] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i8[8191&8191]|0; } return f'), this, null, buf)(),-1);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i8[(8191&8191)>>0]|0; } return f'), this, null, buf)(),-1);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[8192&8191] = -1; i8[0] = 0; return i8[8192&8191]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i8[(8192&8191)>>0] = -1; i8[0] = 0; return i8[(8192&8191)>>0]|0; } return f'), this, null, buf)(),0);
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Uint16Array(buf)[4095] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u16[(8190&8191)>>1]|0; } return f'), this, null, buf)(),65535);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u16[(8191&8191)>>1]|0; } return f'), this, null, buf)(),65535);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u16[(8192&8191)>>1] = -1; u16[0] = 0; return u16[(8192&8191)>>1]|0; } return f'), this, null, buf)(),0);
 new Int16Array(buf)[4095] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i16[(8190&8191)>>1]|0; } return f'), this, null, buf)(),-1);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i16[(8191&8191)>>1]|0; } return f'), this, null, buf)(),-1);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i16[(8192&8191)>>1] = -1; i16[0] = 0; return i16[(8192&8191)>>1]|0; } return f'), this, null, buf)(),0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Uint32Array(buf)[2047] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[(8188&8191)>>2]|0; } return f'), this, null, buf)(),-1);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[(8191&8191)>>2]|0; } return f'), this, null, buf)(),-1);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { u32[(8192&8191)>>2] = -1; u32[0] = 0; return u32[(8192&8191)>>2]|0; } return f'), this, null, buf)(),0);
 new Int32Array(buf)[2047] = -1;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[(8188&8191)>>2]|0; } return f'), this, null, buf)(),-1);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[(8191&8191)>>2]|0; } return f'), this, null, buf)(),-1);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { i32[(8192&8191)>>2] = -1; i32[0] = 0; return i32[(8192&8191)>>2]|0; } return f'), this, null, buf)(),0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Float32Array(buf)[2047] = -1.0;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[(8188&8191)>>2]; } return f'), this, null, buf)(),-1.0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f32[(8191&8191)>>2]; } return f'), this, null, buf)(),-1.0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[(8192&8191)>>2] = -1.0; f32[0] = 0.0; return +f32[(8192&8191)>>2]; } return f'), this, null, buf)(),0.0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Float64Array(buf)[1023] = -1.0;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[(8184&8191)>>3]; } return f'), this, null, buf)(),-1.0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[(8191&8191)>>3]; } return f'), this, null, buf)(),-1.0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[(8192&8191)>>3] = -1.0; f64[0] = 0.0; return +f64[(8192&8191)>>3]; } return f'), this, null, buf)(),0.0);
 
 // Bug 913867
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Int32Array(buf)[0] = 0x55aa5a5a;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[(0&0)>>2]|0; } return f'), this, null, buf)(),0x55aa5a5a);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[(4&0)>>2]|0; } return f'), this, null, buf)(),0x55aa5a5a);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f1() { i32[0] = 1; return 8; }; function f() { return i32[((f1()|0)&0)>>2]|0; } return f'), this, null, buf)(),1);
 assertEq(new Int32Array(buf)[0], 1);
 
 
 // Bug 882012
 assertEq(asmLink(asmCompile('stdlib', 'foreign', 'heap', USE_ASM + "var id=foreign.id;var doubles=new stdlib.Float64Array(heap);function g(){doubles[0]=+id(2.0);return +doubles[0];}return g"), this, {id: function(x){return x;}}, BUF_64KB)(), 2.0);
 
 
 // Some literal constant paths.
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[0>>4294967295]|0; } return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[0>>-1]|0; } return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[0>>0x80000000]|0; } return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[0>>-2147483648]|0; } return f');
 
 new Uint32Array(buf)[0] = 0xAA;
 new Uint32Array(buf)[0x5A>>2] = 0xA5;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[(0x5A&4294967295)>>2]|0; } return f'), this, null, buf)(),0xA5);
@@ -525,17 +525,17 @@ assertEq(asmLink(asmCompile('glob', 'imp
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=4294967295; function f() { return u32[i>>2]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[-1>>2]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=-1; function f() { return u32[i>>2]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[0x80000000>>2]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=0x80000000; function f() { return u32[i>>2]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u32[-2147483648>>2]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=-2147483648; function f() { return u32[-2147483648>>2]|0; } return f'), this, null, buf)(),0);
 
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 new Uint8Array(buf)[0] = 0xAA;
 new Uint8Array(buf)[0x5A] = 0xA5;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x5A&4294967295]|0; } return f'), this, null, buf)(),0xA5);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=4294967295; function f() { return u8[0x5A&i]|0; } return f'), this, null, buf)(),0xA5);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x5A&-1]|0; } return f'), this, null, buf)(),0xA5);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=-1; function f() { return u8[0x5A&i]|0; } return f'), this, null, buf)(),0xA5);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x5A&0x80000000]|0; } return f'), this, null, buf)(),0xAA);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=0x80000000; function f() { return u8[0x5A&i]|0; } return f'), this, null, buf)(),0xAA);
@@ -565,30 +565,30 @@ assertEq(asmLink(asmCompile('glob', 'imp
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[-1>>0]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=-1; function f() { return u8[i>>0]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[0x80000000>>0]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=0x80000000; function f() { return u8[i>>0]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return u8[-2147483648>>0]|0; } return f'), this, null, buf)(),0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'const i=-2147483648; function f() { return u8[i>>0]|0; } return f'), this, null, buf)(),0);
 
 // GVN checks
-var buf = new ArrayBuffer(8192);
+var buf = new ArrayBuffer(BUF_MIN);
 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]; i = x; y = 0|u8[i]; return y|0;} return f'), this, null, buf)(),2);
 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 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));
+assertAsmLinkAlwaysFail(m, this, null, new ArrayBuffer(0xffff));
+assertEq(asmLink(m, this, null, new ArrayBuffer(0x10000))(0),0);
+assertAsmLinkFail(m, this, null, new ArrayBuffer(0x10010));
+assertEq(asmLink(m, this, null, new ArrayBuffer(0x20000))(0),0);
+assertAsmLinkFail(m, this, null, new ArrayBuffer(0xfe0000));
+assertAsmLinkFail(m, this, null, new ArrayBuffer(0xfe0010));
+assertAsmLinkFail(m, this, null, new ArrayBuffer(0xfe0000));
+assertAsmLinkFail(m, this, null, new ArrayBuffer(0xff8000));
 var buf = new ArrayBuffer(0x100000);
 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);
--- a/js/src/jit-test/tests/asm.js/testX86ByteStore.js
+++ b/js/src/jit-test/tests/asm.js/testX86ByteStore.js
@@ -15,17 +15,17 @@ var body =
         d=(b+c+i+j)|0;\
         e=(a+j+c)|0;\
         f=(a+i+k)|0;\
         i8[i] = f;\
         return (a+b+c+d+e+f)|0;\
     }\
     return g;';
 
-var buf=new ArrayBuffer(4096);
+var buf=new ArrayBuffer(BUF_MIN);
 var g = asmLink(asmCompile('global','foreign','buffer',body), this, null, buf);
 assertEq(g(1,2,3), 46);
 assertEq(new Int8Array(buf)[1], 7);
 
 var body =
 '   "use asm";\
     var i8=new global.Int8Array(buffer);\
     function g(i,j,k) {\
@@ -40,17 +40,17 @@ var body =
         d=(b+c+i+j)|0;\
         e=(a+j+c)|0;\
         f=(a+i+k)|0;\
         i8[i] = e;\
         return (a+b+c+d+e+f)|0;\
     }\
     return g;';
 
-var buf=new ArrayBuffer(4096);
+var buf=new ArrayBuffer(BUF_MIN);
 var g = asmLink(asmCompile('global','foreign','buffer',body), this, null, buf);
 assertEq(g(1,2,3), 46);
 assertEq(new Int8Array(buf)[1], 9);
 
 var body =
 '   "use asm";\
     var i8=new global.Int8Array(buffer);\
     function g(i,j,k) {\
@@ -66,12 +66,12 @@ var body =
         e=(a+j+c)|0;\
         f=(a+i+k)|0;\
         g=(f+j+b)|0;\
         i8[i] = g;\
         return (a+b+c+d+e+f+g)|0;\
     }\
     return g;';
 
-var buf=new ArrayBuffer(4096);
+var buf=new ArrayBuffer(BUF_MIN);
 var g = asmLink(asmCompile('global','foreign','buffer',body), this, null, buf);
 assertEq(g(1,2,3), 63);
 assertEq(new Int8Array(buf)[1], 17);
--- a/js/src/jit-test/tests/asm.js/testZOOB.js
+++ b/js/src/jit-test/tests/asm.js/testZOOB.js
@@ -1,15 +1,15 @@
 load(libdir + "asm.js");
 
 setIonCheckGraphCoherency(false);
 setCachingEnabled(false);
 
 // constants
-var buf = new ArrayBuffer(4096);
+var buf = new ArrayBuffer(BUF_MIN);
 
 // An unshifted literal constant byte index in the range 0 to 2^31-1 inclusive should give a link failure.
 assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b);  function f() {return arr[0x7fffffff]|0 } return f'), this, null, buf);
 assertAsmLinkFail(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x1fffffff]|0 } return f'), this, null, buf);
 
 
 // An unshifted literal constant byte index outside the range 0 to 2^31-1 inclusive should cause an error compiling.
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x20000000]|0 } return f');
@@ -41,25 +41,25 @@ assertEq(asmLink(asmCompile('glob', 'imp
 
 // A non-intish shifted literal constant index should cause an error compiling.
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b); function f() {return arr[0x100000000>>0]|0 } return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int32Array(b); function f() {return arr[0x100000000>>2]|0 } return f');
 
 // Folded non-intish constant expressions should cause an error compiling.
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.Int8Array(b);  function f() {return arr[0xffffffff+1]|0 } return f');
 
-
+var ab = new ArrayBuffer(BUF_MIN);
+var arr = new Int32Array(BUF_MIN);
+for (var i = 0; i < arr.length; i++)
+    arr[i] = i;
 
 function testInt(ctor, shift, scale, disp) {
-    var ab = new ArrayBuffer(4096);
     var arr = new ctor(ab);
-    for (var i = 0; i < arr.length; i++)
-        arr[i] = i;
     var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.' + ctor.name + '(b); function f(i) {i=i|0; return arr[((i<<' + scale + ')+' + disp + ')>>' + shift + ']|0 } return f'), this, null, ab);
-    for (var i of [0,1,2,3,4,1023,1024,1025,4095,4096,4097])
+    for (var i of [0,1,2,3,4,1023,1024,1025,BUF_MIN-2,BUF_MIN-1,BUF_MIN,BUF_MIN+1])
         assertEq(f(i), arr[((i<<scale)+disp)>>shift]|0);
 
     for (var i of [-Math.pow(2,28),Math.pow(2,28),-Math.pow(2,29),Math.pow(2,29),-Math.pow(2,30),Math.pow(2,30),-Math.pow(2,31),Math.pow(2,31),-Math.pow(2,32),Math.pow(2,32)]) {
         for (var j of [-8,-4,-1,0,1,4,8])
             assertEq(f(i+j), arr[(((i+j)<<scale)+disp)>>shift]|0);
     }
 
     var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.' + ctor.name + '(b); function f(i,j) {i=i|0;j=j|0; arr[((i<<' + scale + ')+' + disp + ')>>' + shift + '] = j } return f'), this, null, ab);
@@ -78,22 +78,19 @@ function testInt(ctor, shift, scale, dis
             arr[index] = 0;
             f(i+j, v);
             assertEq(arr[index]|0, v);
         }
     }
 }
 
 function testFloat(ctor, shift, scale, disp, coercion) {
-    var ab = new ArrayBuffer(4096);
     var arr = new ctor(ab);
-    for (var i = 0; i < arr.length; i++)
-        arr[i] = i;
     var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.' + ctor.name + '(b); var toF = glob.Math.fround; function f(i) {i=i|0; return ' + coercion + '(arr[((i<<' + scale + ')+' + disp + ')>>' + shift + ']) } return f'), this, null, ab);
-    for (var i of [0,1,2,3,4,1023,1024,1025,4095,4096,4097])
+    for (var i of [0,1,2,3,4,1023,1024,1025,BUF_MIN-2,BUF_MIN-1,BUF_MIN,BUF_MIN+1])
         assertEq(f(i), +arr[((i<<scale)+disp)>>shift]);
 
     for (var i of [-Math.pow(2,31), Math.pow(2,31)-1, Math.pow(2,32)]) {
         for (var j of [-8,-4,-1,0,1,4,8])
             assertEq(f(i+j), +arr[(((i+j)<<scale)+disp)>>shift]);
     }
 
     var f = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + 'var arr=new glob.' + ctor.name + '(b); var toF = glob.Math.fround; function f(i,j) {i=i|0;j=+j; arr[((i<<' + scale + ')+' + disp + ')>>' + shift + '] = j } return f'), this, null, ab);