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