OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // Flags: --allow-natives-syntax --expose-gc --turbo-inline-array-builtins |
| 6 |
| 7 var a = [0, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,0,0]; |
| 8 var b = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]; |
| 9 var c = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]; |
| 10 |
| 11 // Unknown field access leads to soft-deopt unrelated to forEach, should still |
| 12 // lead to correct result. |
| 13 (function() { |
| 14 var result = 0; |
| 15 var eagerDeoptInCalled = function(deopt) { |
| 16 var sum = function(v,i,o) { |
| 17 result += v; |
| 18 if (i == 13 && deopt) { |
| 19 a.abc = 25; |
| 20 } |
| 21 } |
| 22 a.forEach(sum); |
| 23 } |
| 24 eagerDeoptInCalled(); |
| 25 eagerDeoptInCalled(); |
| 26 %OptimizeFunctionOnNextCall(eagerDeoptInCalled); |
| 27 eagerDeoptInCalled(); |
| 28 eagerDeoptInCalled(true); |
| 29 eagerDeoptInCalled(); |
| 30 assertEquals(1500, result); |
| 31 })(); |
| 32 |
| 33 // Length change detected during loop, must cause properly handled eager deopt. |
| 34 (function() { |
| 35 var result = 0; |
| 36 var eagerDeoptInCalled = function(deopt) { |
| 37 var sum = function(v,i,o) { |
| 38 result += v; |
| 39 a.length = (i == 13 && deopt) ? 25 : 27; |
| 40 } |
| 41 a.forEach(sum); |
| 42 } |
| 43 eagerDeoptInCalled(); |
| 44 eagerDeoptInCalled(); |
| 45 %OptimizeFunctionOnNextCall(eagerDeoptInCalled); |
| 46 eagerDeoptInCalled(); |
| 47 eagerDeoptInCalled(true); |
| 48 eagerDeoptInCalled(); |
| 49 assertEquals(1500, result); |
| 50 })(); |
| 51 |
| 52 // Escape analyzed array |
| 53 (function() { |
| 54 var result = 0; |
| 55 var eagerDeoptInCalled = function(deopt) { |
| 56 var a_noescape = [0,1,2,3,4,5]; |
| 57 var sum = function(v,i,o) { |
| 58 result += v; |
| 59 if (i == 13 && deopt) { |
| 60 a_noescape.length = 25; |
| 61 } |
| 62 } |
| 63 a_noescape.forEach(sum); |
| 64 } |
| 65 eagerDeoptInCalled(); |
| 66 eagerDeoptInCalled(); |
| 67 %OptimizeFunctionOnNextCall(eagerDeoptInCalled); |
| 68 eagerDeoptInCalled(); |
| 69 eagerDeoptInCalled(true); |
| 70 eagerDeoptInCalled(); |
| 71 assertEquals(75, result); |
| 72 })(); |
| 73 |
| 74 // Escape analyzed array where sum function isn't inlined, forcing a lazy deopt |
| 75 // with GC that relies on the stashed-away return result fro the lazy deopt |
| 76 // being properly stored in a place on the stack that gets GC'ed. |
| 77 (function() { |
| 78 var result = 0; |
| 79 var lazyDeopt = function(deopt) { |
| 80 var b = [1,2,3]; |
| 81 var sum = function(v,i,o) { |
| 82 result += i; |
| 83 if (i == 1 && deopt) { |
| 84 %DeoptimizeFunction(lazyDeopt); |
| 85 } |
| 86 gc(); gc(); |
| 87 }; |
| 88 %NeverOptimizeFunction(sum); |
| 89 b.forEach(sum); |
| 90 } |
| 91 lazyDeopt(); |
| 92 lazyDeopt(); |
| 93 %OptimizeFunctionOnNextCall(lazyDeopt); |
| 94 lazyDeopt(); |
| 95 lazyDeopt(true); |
| 96 lazyDeopt(); |
| 97 })(); |
| 98 |
| 99 // Lazy deopt from runtime call from inlined callback function. |
| 100 (function() { |
| 101 var result = 0; |
| 102 var lazyDeopt = function(deopt) { |
| 103 var sum = function(v,i,o) { |
| 104 result += i; |
| 105 if (i == 13 && deopt) { |
| 106 %DeoptimizeNow(); |
| 107 } |
| 108 } |
| 109 b.forEach(sum); |
| 110 } |
| 111 lazyDeopt(); |
| 112 lazyDeopt(); |
| 113 %OptimizeFunctionOnNextCall(lazyDeopt); |
| 114 lazyDeopt(); |
| 115 lazyDeopt(true); |
| 116 lazyDeopt(); |
| 117 assertEquals(1500, result); |
| 118 })(); |
| 119 |
| 120 // Lazy deopt from runtime call from non-inline callback function. |
| 121 (function() { |
| 122 var result = 0; |
| 123 var lazyDeopt = function(deopt) { |
| 124 var sum = function(v,i,o) { |
| 125 result += i; |
| 126 if (i == 13 && deopt) { |
| 127 %DeoptimizeNow(); |
| 128 } |
| 129 }; |
| 130 %NeverOptimizeFunction(sum); |
| 131 b.forEach(sum); |
| 132 } |
| 133 lazyDeopt(); |
| 134 lazyDeopt(); |
| 135 %OptimizeFunctionOnNextCall(lazyDeopt); |
| 136 lazyDeopt(); |
| 137 lazyDeopt(true); |
| 138 lazyDeopt(); |
| 139 assertEquals(1500, result); |
| 140 })(); |
| 141 |
| 142 (function() { |
| 143 var result = 0; |
| 144 var lazyDeopt = function(deopt) { |
| 145 var sum = function(v,i,o) { |
| 146 result += i; |
| 147 if (i == 13 && deopt) { |
| 148 %DeoptimizeNow(); |
| 149 gc(); |
| 150 gc(); |
| 151 gc(); |
| 152 } |
| 153 } |
| 154 c.forEach(sum); |
| 155 } |
| 156 lazyDeopt(); |
| 157 lazyDeopt(); |
| 158 %OptimizeFunctionOnNextCall(lazyDeopt); |
| 159 lazyDeopt(); |
| 160 lazyDeopt(true); |
| 161 lazyDeopt(); |
| 162 assertEquals(1500, result); |
| 163 })(); |
| 164 |
| 165 // Call to a.forEach is done inside a try-catch block and the callback function |
| 166 // being called actually throws. |
| 167 (function() { |
| 168 var caught = false; |
| 169 var result = 0; |
| 170 var lazyDeopt = function(deopt) { |
| 171 var sum = function(v,i,o) { |
| 172 result += i; |
| 173 if (i == 1 && deopt) { |
| 174 throw("a"); |
| 175 } |
| 176 } |
| 177 try { |
| 178 c.forEach(sum); |
| 179 } catch (e) { |
| 180 caught = true; |
| 181 } |
| 182 } |
| 183 lazyDeopt(); |
| 184 lazyDeopt(); |
| 185 %OptimizeFunctionOnNextCall(lazyDeopt); |
| 186 lazyDeopt(); |
| 187 assertDoesNotThrow(lazyDeopt.bind(this, true)); |
| 188 assertTrue(caught); |
| 189 lazyDeopt(); |
| 190 })(); |
| 191 |
| 192 // Call to a.forEach is done inside a try-catch block and the callback function |
| 193 // being called actually throws, but the callback is not inlined. |
| 194 (function() { |
| 195 var caught = false; |
| 196 var result = 0; |
| 197 var lazyDeopt = function(deopt) { |
| 198 var sum = function(v,i,o) { |
| 199 result += i; |
| 200 if (i == 1 && deopt) { |
| 201 throw("a"); |
| 202 } |
| 203 }; |
| 204 %NeverOptimizeFunction(sum); |
| 205 try { |
| 206 c.forEach(sum); |
| 207 } catch (e) { |
| 208 caught = true; |
| 209 } |
| 210 } |
| 211 lazyDeopt(); |
| 212 lazyDeopt(); |
| 213 %OptimizeFunctionOnNextCall(lazyDeopt); |
| 214 lazyDeopt(); |
| 215 assertDoesNotThrow(lazyDeopt.bind(this, true)); |
| 216 assertTrue(caught); |
| 217 lazyDeopt(); |
| 218 })(); |
| 219 |
| 220 (function() { |
| 221 var re = /Array\.forEach/; |
| 222 var lazyDeopt = function(deopt) { |
| 223 var b = [1,2,3]; |
| 224 var result = 0; |
| 225 var sum = function(v,i,o) { |
| 226 result += v; |
| 227 if (i == 1) { |
| 228 var e = new Error(); |
| 229 assertTrue(re.exec(e.stack) !== null); |
| 230 } |
| 231 }; |
| 232 var o = [1,2,3]; |
| 233 b.forEach(sum); |
| 234 } |
| 235 lazyDeopt(); |
| 236 lazyDeopt(); |
| 237 %OptimizeFunctionOnNextCall(lazyDeopt); |
| 238 lazyDeopt(); |
| 239 })(); |
| 240 |
| 241 (function() { |
| 242 var re = /Array\.forEach/; |
| 243 var lazyDeopt = function(deopt) { |
| 244 var b = [1,2,3]; |
| 245 var result = 0; |
| 246 var sum = function(v,i,o) { |
| 247 result += v; |
| 248 if (i == 1) { |
| 249 var e = new Error(); |
| 250 assertTrue(re.exec(e.stack) !== null); |
| 251 } |
| 252 }; |
| 253 %NeverOptimizeFunction(sum); |
| 254 var o = [1,2,3]; |
| 255 b.forEach(sum); |
| 256 } |
| 257 lazyDeopt(); |
| 258 lazyDeopt(); |
| 259 %OptimizeFunctionOnNextCall(lazyDeopt); |
| 260 lazyDeopt(); |
| 261 })(); |
| 262 |
| 263 (function() { |
| 264 var re = /Array\.forEach/; |
| 265 var lazyDeopt = function(deopt) { |
| 266 var b = [1,2,3]; |
| 267 var result = 0; |
| 268 var sum = function(v,i,o) { |
| 269 result += v; |
| 270 if (i == 1) { |
| 271 %DeoptimizeNow(); |
| 272 } else if (i == 2) { |
| 273 var e = new Error(); |
| 274 assertTrue(re.exec(e.stack) !== null); |
| 275 } |
| 276 }; |
| 277 var o = [1,2,3]; |
| 278 b.forEach(sum); |
| 279 } |
| 280 lazyDeopt(); |
| 281 lazyDeopt(); |
| 282 %OptimizeFunctionOnNextCall(lazyDeopt); |
| 283 lazyDeopt(); |
| 284 })(); |
| 285 |
| 286 (function() { |
| 287 var re = /Array\.forEach/; |
| 288 var a = [1,2,3]; |
| 289 var result = 0; |
| 290 var lazyDeopt = function() { |
| 291 var sum = function(v,i,o) { |
| 292 result += i; |
| 293 if (i == 1) { |
| 294 %DeoptimizeFunction(lazyDeopt); |
| 295 throw new Error(); |
| 296 } |
| 297 }; |
| 298 a.forEach(sum); |
| 299 } |
| 300 assertThrows(() => lazyDeopt()); |
| 301 assertThrows(() => lazyDeopt()); |
| 302 try { |
| 303 lazyDeopt(); |
| 304 } catch (e) { |
| 305 assertTrue(re.exec(e.stack) !== null); |
| 306 } |
| 307 %OptimizeFunctionOnNextCall(lazyDeopt); |
| 308 try { |
| 309 lazyDeopt(); |
| 310 } catch (e) { |
| 311 assertTrue(re.exec(e.stack) !== null); |
| 312 } |
| 313 })(); |
OLD | NEW |