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