OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 var calls = 0; | 81 var calls = 0; |
82 | 82 |
83 // Testcase: setter in prototype chain | 83 // Testcase: setter in prototype chain |
84 foo = function(a) { var x = a[0]; return x + 3; } | 84 foo = function(a) { var x = a[0]; return x + 3; } |
85 var a = create_func(); | 85 var a = create_func(); |
86 var ap = []; | 86 var ap = []; |
87 ap.__defineGetter__(0, function() { calls++; return 0; }); | 87 ap.__defineGetter__(0, function() { calls++; return 0; }); |
88 | 88 |
89 foo(a); | 89 foo(a); |
90 assertUnoptimized(foo); | 90 assertUnoptimized(foo); |
| 91 // Smi and Double elements transition the KeyedLoadIC to Generic state |
| 92 // here, because they miss twice with the same map when loading the hole. |
| 93 // For FAST_HOLEY_ELEMENTS, however, the IC knows how to convert the hole |
| 94 // to undefined if the prototype is the original array prototype, so it |
| 95 // stays monomorphic for now... |
91 foo(a); | 96 foo(a); |
92 foo(a); | 97 foo(a); |
93 delete a[0]; | 98 delete a[0]; |
94 | 99 |
95 assertEquals(0, calls); | 100 assertEquals(0, calls); |
96 a.__proto__ = ap; | 101 a.__proto__ = ap; |
| 102 // ...and later becomes polymorphic when it sees a second map. Optimized |
| 103 // code will therefore inline the elements access, and deopt right away |
| 104 // when it loads the hole from index [0]. |
| 105 // Possible solutions: |
| 106 // - remove the convert_hole_to_undefined flag from the IC, to force it |
| 107 // into generic state for all elements kinds. Cost: slower ICs in code |
| 108 // that doesn't get optimized. |
| 109 // - teach Turbofan about the same trick: for holey elements with the |
| 110 // original array prototype, convert hole to undefined inline. Cost: |
| 111 // larger optimized code size, because the loads for different maps with |
| 112 // the same elements kind can no longer be consolidated if they handle |
| 113 // the hole differently. |
| 114 // - call "foo" twice after setting a.__proto__ and before optimizing it; |
| 115 // this is the simplest fix so let's do that for now. |
97 foo(a); | 116 foo(a); |
98 assertEquals(1, calls); | 117 assertEquals(1, calls); |
| 118 foo(a); |
| 119 assertEquals(2, calls); |
99 optimize(foo); | 120 optimize(foo); |
100 foo(a); | 121 foo(a); |
101 assertEquals(2, calls); | 122 assertEquals(3, calls); |
102 assertOptimized(foo); | 123 assertOptimized(foo); |
103 | 124 |
104 // Testcase: getter "deep" in prototype chain. | 125 // Testcase: getter "deep" in prototype chain. |
105 clearFunctionTypeFeedback(foo); | 126 clearFunctionTypeFeedback(foo); |
106 deoptimizeFunction(foo); | 127 deoptimizeFunction(foo); |
107 clearFunctionTypeFeedback(foo); | 128 clearFunctionTypeFeedback(foo); |
108 calls = 0; | 129 calls = 0; |
109 | 130 |
110 a = create_func(); | 131 a = create_func(); |
111 var ap2 = []; | 132 var ap2 = []; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 optimize(fun); | 243 optimize(fun); |
223 fun(a); | 244 fun(a); |
224 assertOptimized(fun); | 245 assertOptimized(fun); |
225 | 246 |
226 var calls = 0; | 247 var calls = 0; |
227 delete a[0]; | 248 delete a[0]; |
228 ap.__defineGetter__(0, function() { calls++; return 0; }); | 249 ap.__defineGetter__(0, function() { calls++; return 0; }); |
229 fun(a); | 250 fun(a); |
230 assertEquals(1, calls); | 251 assertEquals(1, calls); |
231 assertUnoptimized(fun); | 252 assertUnoptimized(fun); |
OLD | NEW |