OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 | |
6 "use strict"; | |
7 | |
8 // Test non-JSObject receiver. | |
9 function f(o) { | |
10 var result = []; | |
11 for (var i in o) { | |
12 result.push(i); | |
13 } | |
14 return result; | |
15 } | |
16 | |
17 assertEquals(["0"], f("a")); | |
18 assertEquals(["0"], f("a")); | |
19 | |
20 %OptimizeFunctionOnNextCall(f); | |
21 assertEquals(["0","1","2"], f("bla")); | |
22 | |
23 // Test the lazy deopt points. | |
24 var keys = ["a", "b", "c", "d"]; | |
25 var property_descriptor_keys = []; | |
26 var deopt_enum = false; | |
27 var deopt_property_descriptor = false; | |
28 | |
29 var handler = { | |
30 ownKeys() { | |
31 if (deopt_enum) { | |
32 %DeoptimizeFunction(f2); | |
33 deopt_enum = false; | |
34 } | |
35 return keys; | |
36 }, | |
37 getOwnPropertyDescriptor(target, k) { | |
38 if (deopt_property_descriptor) { | |
39 %DeoptimizeFunction(f2); | |
40 deopt_property_descriptor = false; | |
41 } | |
42 property_descriptor_keys.push(k); | |
43 return { enumerable: true, configurable: true } | |
44 }, | |
45 }; | |
46 | |
47 | |
48 var proxy = new Proxy({}, handler); | |
49 var o = {__proto__: proxy}; | |
50 | |
51 function f2(o) { | |
52 var result = []; | |
53 for (var i in o) { | |
54 result.push(i); | |
55 } | |
56 return result; | |
57 } | |
58 | |
59 function check_f2() { | |
60 assertEquals(keys, f2(o)); | |
61 assertEquals(keys, property_descriptor_keys); | |
62 property_descriptor_keys.length = 0; | |
63 } | |
64 | |
65 check_f2(); | |
66 check_f2(); | |
67 | |
68 // Test lazy deopt after ForInEnumerate | |
69 %OptimizeFunctionOnNextCall(f2); | |
70 deopt_enum = true; | |
71 check_f2(); | |
72 | |
73 // Test lazy deopt after FILTER_KEY | |
74 %OptimizeFunctionOnNextCall(f2); | |
75 deopt_property_descriptor = true; | |
76 check_f2(); | |
77 | |
78 | |
79 function f3(o) { | |
80 for (var i in o) { | |
81 } | |
82 } | |
83 | |
84 f3({__proto__:{x:1}}); | |
85 f3({__proto__:{x:1}}); | |
86 | |
87 %OptimizeFunctionOnNextCall(f3); | |
88 f3(undefined); | |
89 f3(null); | |
90 | |
91 // Reliable repro for an issue previously flushed out by GC stress. | |
92 var p = {x: "x"} | |
93 | |
94 function f4(o, p) { | |
95 var result = []; | |
96 for (var i in o) { | |
97 var j = p.x + "str"; | |
98 result.push(i); | |
99 } | |
100 return result; | |
101 } | |
102 | |
103 function check_f4() { | |
104 assertEquals(keys, f4(o, p)); | |
105 assertEquals(keys, property_descriptor_keys); | |
106 property_descriptor_keys.length = 0; | |
107 } | |
108 | |
109 check_f4(); | |
110 check_f4(); | |
111 | |
112 %OptimizeFunctionOnNextCall(f4); | |
113 | |
114 p.y = "y"; // Change map, cause eager deopt. | |
115 check_f4(); | |
116 | |
117 // Repro for Turbofan equivalent. | |
118 var x; | |
119 var count = 0; | |
120 | |
121 var Debug = debug.Debug; | |
122 | |
123 function listener(event, exec_state, event_data, data) { | |
124 if (event == Debug.DebugEvent.Break) { | |
125 %DeoptimizeFunction(f5); | |
126 } | |
127 } | |
128 | |
129 var handler3 = { | |
130 ownKeys() { return ["a", "b"] }, | |
131 getOwnPropertyDescriptor(target, k) { | |
132 if (k == "a") count++; | |
133 if (x) %ScheduleBreak() | |
134 return { enumerable: true, configurable: true } | |
135 } | |
136 }; | |
137 | |
138 var proxy3 = new Proxy({}, handler3); | |
139 var o3 = {__proto__: proxy3}; | |
140 | |
141 function f5() { | |
142 for (var p in o3) { | |
143 print(p); | |
144 } | |
145 } | |
146 | |
147 x = false; | |
148 | |
149 f5(); f5(); f5(); | |
150 %OptimizeFunctionOnNextCall(f5); | |
151 x = true; | |
152 count = 0; | |
153 Debug.setListener(listener); | |
154 f5(); | |
155 Debug.setListener(null); | |
156 assertEquals(1, count); | |
OLD | NEW |