bug-770309-mcall-bailout.js (1830B)
1 // Test various code paths associated with fused getprop/poly inlining. 2 3 function A(a) { this.a = a; } 4 A.prototype.foo = function (x) { return (x % 3) + this.a; }; 5 6 function B(b) { this.b = b; } 7 B.prototype.foo = function (x) { return (x % 3) + this.b + 1; }; 8 9 // c.foo() for some (c instanceof C) should always hit the fallback 10 // path of any fused poly inline cache created for it. 11 function C(c) { this.c = c; } 12 var GLOBX = {'x': function (x) { 13 if (x > 29500) 14 throw new Error("ERROR"); 15 return 2; 16 }}; 17 function C_foo1(x) { 18 return (x % 3) + this.c + GLOBX.x(x) + 1; 19 } 20 function C_foo2(x) { 21 return (x % 3) + this.c + GLOBX.x(x) + 2; 22 } 23 C.prototype.foo = C_foo1; 24 25 // Create an array of As, Bs, and Cs. 26 function makeArray(n) { 27 var classes = [A, B, C]; 28 var arr = []; 29 for (var i = 0; i < n; i++) { 30 arr.push(new classes[i % 3](i % 3)); 31 } 32 return arr; 33 } 34 35 // Call foo on them, sum up results into first elem of resultArray 36 function runner(arr, resultArray, len) { 37 for (var i = 0; i < len; i++) { 38 // This changes the type of returned value from C.foo(), leading to 39 // a bailout fater the call obj.foo() below. 40 var obj = arr[i]; 41 resultArray[0] += obj.foo(i); 42 } 43 } 44 45 // Make an array of instance. 46 var resultArray = [0]; 47 var arr = makeArray(30000); 48 49 // Run runner for a bit with C.prototype.foo being C_foo1 50 runner(arr, resultArray, 100); 51 52 // Run runner for a bit with C.prototype.foo being C_foo2 53 C.prototype.foo = C_foo2; 54 runner(arr, resultArray, 100); 55 56 // Run runner for a bit longer to force GLOBX.x to raise 57 // an error inside a call to C.prototype.foo within runner. 58 var gotError = false; 59 try { 60 runner(arr, resultArray, 30000); 61 } catch(err) { 62 gotError = true; 63 } 64 65 // Check results. 66 assertEq(gotError, true); 67 assertEq(resultArray[0], 108859);