recover-inline-rest.js (3227B)
1 // |jit-test| --fast-warmup; --no-threads 2 3 setJitCompilerOption("baseline.warmup.trigger", 0); 4 setJitCompilerOption("ion.warmup.trigger", 100); 5 6 // Prevent GC from cancelling/discarding Ion compilations. 7 gczeal(0); 8 9 // This function is used to force a bailout when it is inlined, and to recover 10 // the frame which is inlining this function. 11 var resumeHere = function (i) { if (i >= 99) bailout(); }; 12 13 // This function is used to cause an invalidation after having removed a branch 14 // after DCE. This is made to check if we correctly recover an array 15 // allocation. 16 var uceFault = function (i) { 17 if (i > 98) 18 uceFault = function (i) { return true; }; 19 return false; 20 }; 21 22 var uceFault_lengthRest = eval(`(${uceFault})`.replace('uceFault', 'uceFault_lengthRest')); 23 function lengthRest(i, ...rest) { 24 if (uceFault_lengthRest(i) || uceFault_lengthRest(i)) { 25 return empty.apply(null, rest); 26 } 27 assertRecoveredOnBailout(rest, true); 28 return 0; 29 } 30 function lengthRestOuter(i) { 31 return lengthRest(i); 32 } 33 assertEq(isSmallFunction(lengthRest), true, 34 "function must be small enough to be inlined to create an inline rest array"); 35 36 var uceFault_elemRest = eval(`(${uceFault})`.replace('uceFault', 'uceFault_elemRest')); 37 function elemRest(i, ...rest) { 38 if (uceFault_elemRest(i) || uceFault_elemRest(i)) { 39 return empty.apply(null, rest); 40 } 41 assertRecoveredOnBailout(rest, true); 42 return 0; 43 } 44 function elemRestOuter(i) { 45 return elemRest(i); 46 } 47 assertEq(isSmallFunction(elemRest), true, 48 "function must be small enough to be inlined to create an inline rest array"); 49 50 function empty() {} 51 52 var uceFault_applyRest = eval(`(${uceFault})`.replace('uceFault', 'uceFault_applyRest')); 53 function applyRest(i, ...rest) { 54 if (uceFault_applyRest(i) || uceFault_applyRest(i)) { 55 return empty.apply(null, rest); 56 } 57 assertRecoveredOnBailout(rest, true); 58 return 0; 59 } 60 function applyRestOuter(i) { 61 return applyRest(i); 62 } 63 assertEq(isSmallFunction(applyRest), true, 64 "function must be small enough to be inlined to create an inline rest array"); 65 66 var uceFault_spreadRest = eval(`(${uceFault})`.replace('uceFault', 'uceFault_spreadRest')); 67 function spreadRest(i, ...rest) { 68 if (uceFault_spreadRest(i) || uceFault_spreadRest(i)) { 69 return empty(...rest); 70 } 71 assertRecoveredOnBailout(rest, true); 72 return 0; 73 } 74 function spreadRestOuter(i) { 75 return spreadRest(i); 76 } 77 assertEq(isSmallFunction(spreadRest), true, 78 "function must be small enough to be inlined to create an inline rest array"); 79 80 var uceFault_newSpreadRest = eval(`(${uceFault})`.replace('uceFault', 'uceFault_newSpreadRest')); 81 function newSpreadRest(i, ...rest) { 82 if (uceFault_newSpreadRest(i) || uceFault_newSpreadRest(i)) { 83 return new empty(...rest); 84 } 85 assertRecoveredOnBailout(rest, true); 86 return 0; 87 } 88 function newSpreadRestOuter(i) { 89 return newSpreadRest(i); 90 } 91 assertEq(isSmallFunction(newSpreadRest), true, 92 "function must be small enough to be inlined to create an inline rest array"); 93 94 // Prevent compilation of the top-level 95 eval(`(${resumeHere})`); 96 97 for (let i = 0; i < 100; i++) { 98 lengthRestOuter(i); 99 elemRestOuter(i); 100 applyRestOuter(i); 101 spreadRestOuter(i); 102 newSpreadRestOuter(i); 103 }