Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / test / mjsunit / getters-on-elements.js
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 // Flags: --allow-natives-syntax --max-opt-count=100 --noalways-opt
29 // Flags: --nocollect-maps
30
31 // We specify max-opt-count because we opt/deopt the same function many
32 // times.
33
34 // We specify nocollect-maps because in gcstress we can end up deoptimizing
35 // a function in a gc in the stack guard at the beginning of the (optimized)
36 // function due to leftover map clearing work that results in deoptimizing
37 // dependent code from those maps. The choice is to insert strategic gc()
38 // calls or specify this flag.
39
40 // It's nice to run this in other browsers too.
41 var standalone = false;
42 if (standalone) {
43   assertTrue = function(val) {
44     if (val != true) {
45       print("FAILURE");
46     }
47   }
48
49   assertFalse = function(val) {
50     if (val != false) {
51       print("FAILURE");
52     }
53   }
54
55   assertEquals = function(expected, val) {
56     if (expected !== val) {
57       print("FAILURE");
58     }
59   }
60
61   empty_func = function(name) { }
62   assertUnoptimized = empty_func;
63   assertOptimized = empty_func;
64
65   optimize = empty_func;
66   clearFunctionTypeFeedback = empty_func;
67   deoptimizeFunction = empty_func;
68 } else {
69   optimize = function(name) {
70     %OptimizeFunctionOnNextCall(name);
71   }
72   clearFunctionTypeFeedback = function(name) {
73     %ClearFunctionTypeFeedback(name);
74   }
75   deoptimizeFunction = function(name) {
76     %DeoptimizeFunction(name);
77   }
78 }
79
80 function base_getter_test(create_func) {
81   var calls = 0;
82
83   // Testcase: setter in prototype chain
84   foo = function(a) { var x = a[0]; return x + 3; }
85   var a = create_func();
86   var ap = [];
87   ap.__defineGetter__(0, function() { calls++; return 0; });
88
89   foo(a);
90   foo(a);
91   foo(a);
92   delete a[0];
93
94   assertEquals(0, calls);
95   a.__proto__ = ap;
96   foo(a);
97   assertEquals(1, calls);
98   optimize(foo);
99   foo(a);
100   assertEquals(2, calls);
101   assertOptimized(foo);
102
103   // Testcase: getter "deep" in prototype chain.
104   clearFunctionTypeFeedback(foo);
105   deoptimizeFunction(foo);
106   clearFunctionTypeFeedback(foo);
107   calls = 0;
108
109   a = create_func();
110   var ap2 = [];
111   a.__proto__ = ap2;
112   foo(a);
113   foo(a);
114   foo(a);
115   delete a[0];
116
117   assertEquals(0, calls);
118
119   ap2.__proto__ = ap;  // "sneak" in a callback.
120   // The sneak case should be caught by unoptimized code too.
121   assertUnoptimized(foo);
122   foo(a);
123   foo(a);
124   foo(a);
125   assertEquals(3, calls);
126
127   // Testcase: getter added after optimization (feedback is monomorphic)
128   clearFunctionTypeFeedback(foo);
129   deoptimizeFunction(foo);
130   clearFunctionTypeFeedback(foo);
131   calls = 0;
132
133   a = create_func();
134   ap2 = [];
135   a.__proto__ = ap2;
136   foo(a);
137   foo(a);
138   foo(a);
139   optimize(foo);
140   foo(a);
141   assertOptimized(foo);
142   delete a[0];
143   ap2.__proto__ = ap;
144   foo(a);
145   assertOptimized(foo);  // getters don't require deopt on shape change.
146   assertEquals(1, calls);
147
148   // Testcase: adding additional getters to a prototype chain that already has
149   // one shouldn't deopt anything.
150   clearFunctionTypeFeedback(foo);
151   calls = 0;
152
153   a = create_func();
154   a.__proto__ = ap2;
155   bar = function(a) { return a[3] + 600; }
156   bar(a);
157   bar(a);
158   bar(a);
159   optimize(bar);
160   bar(a);
161   assertOptimized(bar);
162   assertEquals(0, calls);
163   delete a[3];
164   ap2.__defineGetter__(3, function() { calls++; return 0; });
165   bar(a);
166   assertOptimized(bar);
167   assertEquals(1, calls);
168 }
169
170 // Verify that map transitions don't confuse us.
171 create_func_smi = function() { return [,,,,,,5]; }
172 create_func_double = function() { return [,,,,,,5.5]; }
173 create_func_fast = function() { return [,,,,,,true]; }
174
175 var cf = [create_func_smi,
176           create_func_double,
177           create_func_fast];
178
179 for(var c = 0; c < cf.length; c++) {
180   base_getter_test(cf[c]);
181 }
182
183 // A special test for LoadKeyedHoleMode. Ensure that optimized is generated
184 // which sets ALLOW_RETURN_HOLE, then add a setter on the prototype that should
185 // cause the function to deoptimize.
186
187 var a = [3.5,,,3.5];
188 fun = function(a) { return a[0] + 5.5; }
189 fun(a);
190 fun(a);
191 fun(a);  // should have a monomorphic KeyedLoadIC.
192 optimize(fun);
193 fun(a);
194 assertOptimized(fun);
195
196 // returning undefined shouldn't phase us.
197 delete a[0];
198 fun(a);
199 assertOptimized(fun);
200
201 // but messing up the prototype chain will.
202 a.__proto__ = [];
203 fun(a);
204 assertUnoptimized(fun);
205
206 // Construct a non-trivial prototype chain.
207 var a = [3.5,,,,3.5];
208 var ap = [,,3.5];
209 ap.__proto__ = a.__proto__;
210 a.__proto__ = ap;
211 fun(a);
212 optimize(fun);
213 fun(a);
214 assertOptimized(fun);
215
216 var calls = 0;
217 delete a[0];
218 ap.__defineGetter__(0, function() { calls++; return 0; });
219 fun(a);
220 assertEquals(1, calls);
221 assertUnoptimized(fun);