| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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: --allow-natives-syntax | 5 // Flags: --allow-natives-syntax |
| 6 | 6 |
| 7 function Migrator(o) { | 7 function literals_sharing_test(warmup, optimize) { |
| 8 return o.foo; | 8 function closure() { |
| 9 } | 9 // Ensure small array literals start in specific element kind mode. |
| 10 function Loader(o) { | 10 assertTrue(%HasFastSmiElements([])); |
| 11 return o[0]; | 11 assertTrue(%HasFastSmiElements([1])); |
| 12 assertTrue(%HasFastSmiElements([1,2])); |
| 13 assertTrue(%HasFastDoubleElements([1.1])); |
| 14 assertTrue(%HasFastDoubleElements([1.1,2])); |
| 15 |
| 16 var a = [1, 2, 3]; |
| 17 if (warmup) { |
| 18 // Transition elements kind during warmup... |
| 19 assertTrue(%HasFastSmiElements(a)); |
| 20 assertEquals(4, a.push(1.3)); |
| 21 } |
| 22 // ... and ensure that the information about transitioning is |
| 23 // propagated to the next closure. |
| 24 assertTrue(%HasFastDoubleElements(a)); |
| 25 }; |
| 26 if (optimize) %OptimizeFunctionOnNextCall(closure); |
| 27 closure(); |
| 12 } | 28 } |
| 13 | 29 |
| 14 var first_smi_array = [1]; | |
| 15 var second_smi_array = [2]; | |
| 16 var first_object_array = ["first"]; | |
| 17 var second_object_array = ["string"]; | |
| 18 | 30 |
| 19 assertTrue(%HasFastSmiElements(first_smi_array)); | 31 function test() { |
| 20 assertTrue(%HasFastSmiElements(second_smi_array)); | 32 var warmup = true; |
| 21 assertTrue(%HasFastObjectElements(first_object_array)); | 33 for (var i = 0; i < 3; i++) { |
| 22 assertTrue(%HasFastObjectElements(second_object_array)); | 34 print("iter: " + i + ", warmup: "+ warmup); |
| 35 literals_sharing_test(warmup, false); |
| 36 warmup = false; |
| 37 } |
| 38 print("iter: " + i + ", opt: true"); |
| 39 literals_sharing_test(warmup, true); |
| 40 } |
| 23 | 41 |
| 24 // Prepare identical transition chains for smi and object arrays. | |
| 25 first_smi_array.foo = 0; | |
| 26 second_smi_array.foo = 0; | |
| 27 first_object_array.foo = 0; | |
| 28 second_object_array.foo = 0; | |
| 29 | 42 |
| 30 // Collect type feedback for not-yet-deprecated original object array map. | 43 function stress_opt_test() {} |
| 31 for (var i = 0; i < 3; i++) Migrator(second_object_array); | 44 stress_opt_test(); |
| 32 | 45 if (%GetOptimizationStatus(stress_opt_test) == 2) { |
| 33 // Blaze a migration trail for smi array maps. | 46 // This test is not suitable for --always-opt mode. |
| 34 // This marks the migrated smi array map as a migration target. | 47 test(); |
| 35 first_smi_array.foo = 0.5; | 48 } |
| 36 print(second_smi_array.foo); | |
| 37 | |
| 38 // Deprecate original object array map. | |
| 39 // Use TryMigrate from deferred optimized code to migrate second object array. | |
| 40 first_object_array.foo = 0.5; | |
| 41 %OptimizeFunctionOnNextCall(Migrator); | |
| 42 Migrator(second_object_array); | |
| 43 | |
| 44 // |second_object_array| now erroneously has a smi map. | |
| 45 // Optimized code assuming smi elements will expose this. | |
| 46 | |
| 47 for (var i = 0; i < 3; i++) Loader(second_smi_array); | |
| 48 %OptimizeFunctionOnNextCall(Loader); | |
| 49 assertEquals("string", Loader(second_object_array)); | |
| 50 | |
| 51 // Any of the following checks will also fail: | |
| 52 assertTrue(%HasFastObjectElements(second_object_array)); | |
| 53 assertFalse(%HasFastSmiElements(second_object_array)); | |
| 54 assertTrue(%HaveSameMap(first_object_array, second_object_array)); | |
| 55 assertFalse(%HaveSameMap(first_smi_array, second_object_array)); | |
| 56 | |
| 57 %ClearFunctionTypeFeedback(Loader); | |
| 58 %ClearFunctionTypeFeedback(Migrator); | |
| OLD | NEW |