| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Flags: --turbo --turbo-escape --allow-natives-syntax --no-always-opt | 5 // Flags: --turbo --turbo-escape --allow-natives-syntax --no-always-opt |
| 6 | 6 |
| 7 "use strict"; | 7 "use strict"; |
| 8 | 8 |
| 9 const kDeoptimized = 2; | |
| 10 const kTurbofanned = 7; | |
| 11 const kInterpreted = 8; | |
| 12 | |
| 13 function GetOptimizationStatus(fn) { | |
| 14 let status = %GetOptimizationStatus(fn); | |
| 15 switch (status) { | |
| 16 case kInterpreted: // Treat interpreted frames as unoptimized | |
| 17 status = kDeoptimized; | |
| 18 break; | |
| 19 } | |
| 20 | |
| 21 return status; | |
| 22 } | |
| 23 | |
| 24 let global = this; | 9 let global = this; |
| 25 let tests = { | 10 let tests = { |
| 26 FastElementsKind() { | 11 FastElementsKind() { |
| 27 let runners = { | 12 let runners = { |
| 28 FAST_SMI_ELEMENTS(array) { | 13 FAST_SMI_ELEMENTS(array) { |
| 29 let sum = 0; | 14 let sum = 0; |
| 30 for (let x of array) sum += x; | 15 for (let x of array) sum += x; |
| 31 return sum; | 16 return sum; |
| 32 }, | 17 }, |
| 33 | 18 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 let { array, expected, array2, expected2 } = tests[key]; | 96 let { array, expected, array2, expected2 } = tests[key]; |
| 112 | 97 |
| 113 // Warmup: | 98 // Warmup: |
| 114 fn(array); | 99 fn(array); |
| 115 fn(array); | 100 fn(array); |
| 116 %OptimizeFunctionOnNextCall(fn); | 101 %OptimizeFunctionOnNextCall(fn); |
| 117 fn(array); | 102 fn(array); |
| 118 | 103 |
| 119 // TODO(bmeurer): FAST_HOLEY_DOUBLE_ELEMENTS maps generally deopt when | 104 // TODO(bmeurer): FAST_HOLEY_DOUBLE_ELEMENTS maps generally deopt when |
| 120 // a hole is encountered. Test should be fixed once that is corrected. | 105 // a hole is encountered. Test should be fixed once that is corrected. |
| 121 let status = /HOLEY_DOUBLE/.test(key) ? kDeoptimized : kTurbofanned; | 106 let expect_deopt = /HOLEY_DOUBLE/.test(key); |
| 122 | 107 |
| 123 assertEquals(status, GetOptimizationStatus(fn), key); | 108 if (expect_deopt) { |
| 109 assertUnoptimized(fn, '', key); |
| 110 } else { |
| 111 assertOptimized(fn, '', key); |
| 112 } |
| 124 assertEquals(expected, fn(array), key); | 113 assertEquals(expected, fn(array), key); |
| 125 assertEquals(status, GetOptimizationStatus(fn), key); | 114 if (expect_deopt) { |
| 115 assertUnoptimized(fn, '', key); |
| 116 } else { |
| 117 assertOptimized(fn, '', key); |
| 118 } |
| 126 | 119 |
| 127 // Check no deopt when another arra with the same map is used | 120 // Check no deopt when another array with the same map is used |
| 128 assertTrue(%HaveSameMap(array, array2), key); | 121 assertTrue(%HaveSameMap(array, array2), key); |
| 129 assertEquals(status, GetOptimizationStatus(fn), key); | 122 if (expect_deopt) { |
| 123 assertUnoptimized(fn, '', key); |
| 124 } else { |
| 125 assertOptimized(fn, '', key); |
| 126 } |
| 130 assertEquals(expected2, fn(array2), key); | 127 assertEquals(expected2, fn(array2), key); |
| 131 | 128 |
| 132 // CheckMaps bailout | 129 // CheckMaps bailout |
| 133 let newArray = Object.defineProperty( | 130 let newArray = Object.defineProperty( |
| 134 [1, 2, 3], 2, { enumerable: false, configurable: false, | 131 [1, 2, 3], 2, { enumerable: false, configurable: false, |
| 135 get() { return 7; } }); | 132 get() { return 7; } }); |
| 136 fn(newArray); | 133 fn(newArray); |
| 137 assertEquals(kDeoptimized, GetOptimizationStatus(fn), key); | 134 assertUnoptimized(fn, '', key); |
| 138 } | 135 } |
| 139 }, | 136 }, |
| 140 | 137 |
| 141 TypedArrays() { | 138 TypedArrays() { |
| 142 let tests = { | 139 let tests = { |
| 143 Uint8Array: { | 140 Uint8Array: { |
| 144 array: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, -1, 256]), | 141 array: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, -1, 256]), |
| 145 expected: 291, | 142 expected: 291, |
| 146 array2: new Uint8Array([1, 2, 3]), | 143 array2: new Uint8Array([1, 2, 3]), |
| 147 expected2: 6 | 144 expected2: 6 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 for (let x of array) ret += x; | 212 for (let x of array) ret += x; |
| 216 return ret; | 213 return ret; |
| 217 }; | 214 }; |
| 218 | 215 |
| 219 // Warmup | 216 // Warmup |
| 220 sum(array); | 217 sum(array); |
| 221 sum(array); | 218 sum(array); |
| 222 %OptimizeFunctionOnNextCall(sum); | 219 %OptimizeFunctionOnNextCall(sum); |
| 223 assertEquals(expected, sum(array), key); | 220 assertEquals(expected, sum(array), key); |
| 224 | 221 |
| 225 assertEquals(kTurbofanned, GetOptimizationStatus(sum), key); | 222 assertOptimized(sum, '', key); |
| 226 | 223 |
| 227 // Not deoptimized when called on typed array of same type / map | 224 // Not deoptimized when called on typed array of same type / map |
| 228 assertTrue(%HaveSameMap(array, array2)); | 225 assertTrue(%HaveSameMap(array, array2)); |
| 229 assertEquals(expected2, sum(array2), key); | 226 assertEquals(expected2, sum(array2), key); |
| 230 assertEquals(kTurbofanned, GetOptimizationStatus(sum), key); | 227 assertOptimized(sum, '', key); |
| 231 | 228 |
| 232 // Throw when detached | 229 // Throw when detached |
| 233 let clone = new array.constructor(array); | 230 let clone = new array.constructor(array); |
| 234 %ArrayBufferNeuter(clone.buffer); | 231 %ArrayBufferNeuter(clone.buffer); |
| 235 assertThrows(() => sum(clone), TypeError); | 232 assertThrows(() => sum(clone), TypeError); |
| 236 } | 233 } |
| 237 } | 234 } |
| 238 }; | 235 }; |
| 239 | 236 |
| 240 for (let name of Object.keys(tests)) { | 237 for (let name of Object.keys(tests)) { |
| 241 let test = tests[name]; | 238 let test = tests[name]; |
| 242 test(); | 239 test(); |
| 243 } | 240 } |
| OLD | NEW |