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 |