diff options
Diffstat (limited to 'js/src/jit-test/tests/ion/bug-770309-mcall-bailout.js')
-rw-r--r-- | js/src/jit-test/tests/ion/bug-770309-mcall-bailout.js | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/ion/bug-770309-mcall-bailout.js b/js/src/jit-test/tests/ion/bug-770309-mcall-bailout.js new file mode 100644 index 0000000000..9886a75a1d --- /dev/null +++ b/js/src/jit-test/tests/ion/bug-770309-mcall-bailout.js @@ -0,0 +1,68 @@ + +// Test various code paths associated with fused getprop/poly inlining. + +function A(a) { this.a = a; } +A.prototype.foo = function (x) { return (x % 3) + this.a; }; + +function B(b) { this.b = b; } +B.prototype.foo = function (x) { return (x % 3) + this.b + 1; }; + +// c.foo() for some (c instanceof C) should always hit the fallback +// path of any fused poly inline cache created for it. +function C(c) { this.c = c; } +var GLOBX = {'x': function (x) { + if (x > 29500) + throw new Error("ERROR"); + return 2; +}}; +function C_foo1(x) { + return (x % 3) + this.c + GLOBX.x(x) + 1; +} +function C_foo2(x) { + return (x % 3) + this.c + GLOBX.x(x) + 2; +} +C.prototype.foo = C_foo1; + +// Create an array of As, Bs, and Cs. +function makeArray(n) { + var classes = [A, B, C]; + var arr = []; + for (var i = 0; i < n; i++) { + arr.push(new classes[i % 3](i % 3)); + } + return arr; +} + +// Call foo on them, sum up results into first elem of resultArray +function runner(arr, resultArray, len) { + for (var i = 0; i < len; i++) { + // This changes the type of returned value from C.foo(), leading to + // a bailout fater the call obj.foo() below. + var obj = arr[i]; + resultArray[0] += obj.foo(i); + } +} + +// Make an array of instance. +var resultArray = [0]; +var arr = makeArray(30000); + +// Run runner for a bit with C.prototype.foo being C_foo1 +runner(arr, resultArray, 100); + +// Run runner for a bit with C.prototype.foo being C_foo2 +C.prototype.foo = C_foo2; +runner(arr, resultArray, 100); + +// Run runner for a bit longer to force GLOBX.x to raise +// an error inside a call to C.prototype.foo within runner. +var gotError = false; +try { + runner(arr, resultArray, 30000); +} catch(err) { + gotError = true; +} + +// Check results. +assertEq(gotError, true); +assertEq(resultArray[0], 108859); |