recover-lambdas.js (1662B)
1 // |jit-test| --no-ion; --ion-osr=off 2 // Warp lacks Scalar Replacement support (bug 1650233). Re-evaluate after that 3 // bug has been fixed. 4 5 var max = 40; 6 setJitCompilerOption("ion.warmup.trigger", max - 10); 7 8 // Prevent the GC from cancelling Ion compilations, when we expect them to succeed 9 gczeal(0); 10 11 // This function is used to escape "g" which is a non-escaped inner function. 12 // As it is not escaped within "f", the lambda for "g" would be computed on the 13 // bailout path. Resolving the first ".caller" implies that we have to recover 14 // the lambda. Resolving the second ".caller" is needed such as we can build the 15 // test case without explicitly escaping "g", which would prevent this 16 // optimization. 17 18 function return_f(i) { 19 if (i != max - 1) 20 return f; 21 22 // return_f.caller == g 23 // return_f.caller.caller == f 24 return return_f.caller.caller; 25 } 26 27 function f(i) { 28 function g() { 29 return return_f(i); 30 } 31 32 assertRecoveredOnBailout(g, true); 33 return g(); 34 } 35 36 // This function is used to cause an invalidation after having removed a branch. 37 // These functions are used to check if we correctly recover the lambda 38 // and its environment during a bailout. 39 var uceFault = function (i) { 40 if (i == max - 1) 41 uceFault = function (i) { return true; }; 42 return false; 43 }; 44 45 var uceFault_lambdaCall = eval(`(${uceFault})`.replace('uceFault', 'uceFault_lambdaCall')); 46 function lambdaCall(i) { 47 function g() { 48 return i; 49 } 50 51 if (uceFault_lambdaCall(i) || uceFault_lambdaCall(i)) 52 assertEq(g(), i); 53 54 assertRecoveredOnBailout(g, true); 55 }; 56 57 58 59 for (var i = 0; i < max; i++) { 60 assertEq(f(i), f); 61 lambdaCall(i); 62 }