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 #include "src/compiler.h" | 5 #include "src/compiler.h" |
6 | 6 |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/js-operator.h" | 9 #include "src/compiler/js-operator.h" |
10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 | 107 |
108 | 108 |
109 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmi) { | 109 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmi) { |
110 const int kValue = 111; | 110 const int kValue = 111; |
111 const char* kName = "banana"; | 111 const char* kName = "banana"; |
112 SetGlobalProperty(kName, kValue); | 112 SetGlobalProperty(kName, kValue); |
113 | 113 |
114 Node* ret = ReturnLoadNamedFromGlobal( | 114 Node* ret = ReturnLoadNamedFromGlobal( |
115 kName, graph()->start(), graph()->start(), | 115 kName, graph()->start(), graph()->start(), |
116 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 116 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
117 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 117 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
118 | 118 |
119 Reduction r = Reduce(ret->InputAt(0), | 119 Reduction r = Reduce(ret->InputAt(0), |
120 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 120 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
121 EXPECT_FALSE(r.Changed()); | 121 EXPECT_FALSE(r.Changed()); |
122 EXPECT_TRUE(dependencies()->IsEmpty()); | 122 EXPECT_TRUE(dependencies()->IsEmpty()); |
123 } | 123 } |
124 | 124 |
125 | 125 |
126 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmiWithDeoptimization) { | 126 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmiWithDeoptimization) { |
127 const int kValue = 111; | 127 const int kValue = 111; |
128 const char* kName = "banana"; | 128 const char* kName = "banana"; |
129 SetGlobalProperty(kName, kValue); | 129 SetGlobalProperty(kName, kValue); |
130 | 130 |
131 Node* ret = ReturnLoadNamedFromGlobal( | 131 Node* ret = ReturnLoadNamedFromGlobal( |
132 kName, graph()->start(), graph()->start(), | 132 kName, graph()->start(), graph()->start(), |
133 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 133 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
134 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 134 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
135 | 135 |
136 Reduction r = Reduce(ret->InputAt(0), | 136 Reduction r = Reduce(ret->InputAt(0), |
137 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 137 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
138 | 138 |
139 // Check LoadNamed(global) => HeapConstant[kValue] | 139 // Check LoadNamed(global) => HeapConstant[kValue] |
140 ASSERT_TRUE(r.Changed()); | 140 ASSERT_TRUE(r.Changed()); |
141 EXPECT_THAT(r.replacement(), IsNumberConstant(kValue)); | 141 EXPECT_THAT(r.replacement(), IsNumberConstant(kValue)); |
142 | 142 |
143 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), | 143 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), |
144 graph()->start())); | 144 graph()->start())); |
145 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 145 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
146 | 146 |
147 EXPECT_FALSE(dependencies()->IsEmpty()); | 147 EXPECT_FALSE(dependencies()->IsEmpty()); |
148 dependencies()->Rollback(); | 148 dependencies()->Rollback(); |
149 } | 149 } |
150 | 150 |
151 | 151 |
152 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumber) { | 152 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumber) { |
153 const double kValue = -11.25; | 153 const double kValue = -11.25; |
154 const char* kName = "kiwi"; | 154 const char* kName = "kiwi"; |
155 SetGlobalProperty(kName, kValue); | 155 SetGlobalProperty(kName, kValue); |
156 | 156 |
157 Node* ret = ReturnLoadNamedFromGlobal( | 157 Node* ret = ReturnLoadNamedFromGlobal( |
158 kName, graph()->start(), graph()->start(), | 158 kName, graph()->start(), graph()->start(), |
159 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 159 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
160 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 160 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
161 | 161 |
162 Reduction r = Reduce(ret->InputAt(0), | 162 Reduction r = Reduce(ret->InputAt(0), |
163 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 163 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
164 | 164 |
165 EXPECT_FALSE(r.Changed()); | 165 EXPECT_FALSE(r.Changed()); |
166 EXPECT_TRUE(dependencies()->IsEmpty()); | 166 EXPECT_TRUE(dependencies()->IsEmpty()); |
167 } | 167 } |
168 | 168 |
169 | 169 |
170 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumberWithDeoptimization) { | 170 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumberWithDeoptimization) { |
171 const double kValue = -11.25; | 171 const double kValue = -11.25; |
172 const char* kName = "kiwi"; | 172 const char* kName = "kiwi"; |
173 SetGlobalProperty(kName, kValue); | 173 SetGlobalProperty(kName, kValue); |
174 | 174 |
175 Node* ret = ReturnLoadNamedFromGlobal( | 175 Node* ret = ReturnLoadNamedFromGlobal( |
176 kName, graph()->start(), graph()->start(), | 176 kName, graph()->start(), graph()->start(), |
177 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 177 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
178 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 178 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
179 | 179 |
180 Reduction r = Reduce(ret->InputAt(0), | 180 Reduction r = Reduce(ret->InputAt(0), |
181 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 181 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
182 | 182 |
183 // Check LoadNamed(global) => HeapConstant[kValue] | 183 // Check LoadNamed(global) => HeapConstant[kValue] |
184 ASSERT_TRUE(r.Changed()); | 184 ASSERT_TRUE(r.Changed()); |
185 EXPECT_THAT(r.replacement(), IsNumberConstant(kValue)); | 185 EXPECT_THAT(r.replacement(), IsNumberConstant(kValue)); |
186 | 186 |
187 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), | 187 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), |
188 graph()->start())); | 188 graph()->start())); |
189 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 189 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
190 | 190 |
191 EXPECT_FALSE(dependencies()->IsEmpty()); | 191 EXPECT_FALSE(dependencies()->IsEmpty()); |
192 } | 192 } |
193 | 193 |
194 | 194 |
195 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstString) { | 195 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstString) { |
196 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( | 196 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( |
197 isolate()->factory()->undefined_string()); | 197 isolate()->factory()->undefined_string()); |
198 const char* kName = "mango"; | 198 const char* kName = "mango"; |
199 SetGlobalProperty(kName, kValue.handle()); | 199 SetGlobalProperty(kName, kValue.handle()); |
200 | 200 |
201 Node* ret = ReturnLoadNamedFromGlobal( | 201 Node* ret = ReturnLoadNamedFromGlobal( |
202 kName, graph()->start(), graph()->start(), | 202 kName, graph()->start(), graph()->start(), |
203 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 203 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
204 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 204 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
205 | 205 |
206 Reduction r = Reduce(ret->InputAt(0), | 206 Reduction r = Reduce(ret->InputAt(0), |
207 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 207 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
208 ASSERT_FALSE(r.Changed()); | 208 ASSERT_FALSE(r.Changed()); |
209 EXPECT_TRUE(dependencies()->IsEmpty()); | 209 EXPECT_TRUE(dependencies()->IsEmpty()); |
210 } | 210 } |
211 | 211 |
212 | 212 |
213 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstStringWithDeoptimization) { | 213 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstStringWithDeoptimization) { |
214 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( | 214 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( |
215 isolate()->factory()->undefined_string()); | 215 isolate()->factory()->undefined_string()); |
216 const char* kName = "mango"; | 216 const char* kName = "mango"; |
217 SetGlobalProperty(kName, kValue.handle()); | 217 SetGlobalProperty(kName, kValue.handle()); |
218 | 218 |
219 Node* ret = ReturnLoadNamedFromGlobal( | 219 Node* ret = ReturnLoadNamedFromGlobal( |
220 kName, graph()->start(), graph()->start(), | 220 kName, graph()->start(), graph()->start(), |
221 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 221 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
222 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 222 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
223 | 223 |
224 Reduction r = Reduce(ret->InputAt(0), | 224 Reduction r = Reduce(ret->InputAt(0), |
225 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 225 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
226 | 226 |
227 // Check LoadNamed(global) => HeapConstant[kValue] | 227 // Check LoadNamed(global) => HeapConstant[kValue] |
228 ASSERT_TRUE(r.Changed()); | 228 ASSERT_TRUE(r.Changed()); |
229 EXPECT_THAT(r.replacement(), IsHeapConstant(kValue)); | 229 EXPECT_THAT(r.replacement(), IsHeapConstant(kValue)); |
230 | 230 |
231 EXPECT_THAT(ret, IsReturn(IsHeapConstant(kValue), graph()->start(), | 231 EXPECT_THAT(ret, IsReturn(IsHeapConstant(kValue), graph()->start(), |
232 graph()->start())); | 232 graph()->start())); |
233 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 233 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
234 | 234 |
235 EXPECT_FALSE(dependencies()->IsEmpty()); | 235 EXPECT_FALSE(dependencies()->IsEmpty()); |
236 dependencies()->Rollback(); | 236 dependencies()->Rollback(); |
237 } | 237 } |
238 | 238 |
239 | 239 |
240 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmi) { | 240 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmi) { |
241 const char* kName = "melon"; | 241 const char* kName = "melon"; |
242 SetGlobalProperty(kName, 123); | 242 SetGlobalProperty(kName, 123); |
243 SetGlobalProperty(kName, 124); | 243 SetGlobalProperty(kName, 124); |
244 | 244 |
245 Node* ret = ReturnLoadNamedFromGlobal( | 245 Node* ret = ReturnLoadNamedFromGlobal( |
246 kName, graph()->start(), graph()->start(), | 246 kName, graph()->start(), graph()->start(), |
247 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 247 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
248 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 248 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
249 | 249 |
250 Reduction r = Reduce(ret->InputAt(0), | 250 Reduction r = Reduce(ret->InputAt(0), |
251 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 251 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
252 ASSERT_FALSE(r.Changed()); | 252 ASSERT_FALSE(r.Changed()); |
253 EXPECT_TRUE(dependencies()->IsEmpty()); | 253 EXPECT_TRUE(dependencies()->IsEmpty()); |
254 } | 254 } |
255 | 255 |
256 | 256 |
257 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmiWithDeoptimization) { | 257 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmiWithDeoptimization) { |
258 const char* kName = "melon"; | 258 const char* kName = "melon"; |
259 SetGlobalProperty(kName, 123); | 259 SetGlobalProperty(kName, 123); |
260 SetGlobalProperty(kName, 124); | 260 SetGlobalProperty(kName, 124); |
261 | 261 |
262 Node* ret = ReturnLoadNamedFromGlobal( | 262 Node* ret = ReturnLoadNamedFromGlobal( |
263 kName, graph()->start(), graph()->start(), | 263 kName, graph()->start(), graph()->start(), |
264 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 264 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
265 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 265 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
266 | 266 |
267 Reduction r = Reduce(ret->InputAt(0), | 267 Reduction r = Reduce(ret->InputAt(0), |
268 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 268 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
269 | 269 |
270 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) | 270 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) |
271 ASSERT_TRUE(r.Changed()); | 271 ASSERT_TRUE(r.Changed()); |
272 FieldAccess access = AccessBuilder::ForPropertyCellValue(); | 272 FieldAccess access = AccessBuilder::ForPropertyCellValue(); |
273 Capture<Node*> cell_capture; | 273 Capture<Node*> cell_capture; |
274 Matcher<Node*> load_field_match = IsLoadField( | 274 Matcher<Node*> load_field_match = IsLoadField( |
275 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); | 275 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); |
(...skipping 13 matching lines...) Expand all Loading... |
289 | 289 |
290 | 290 |
291 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellString) { | 291 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellString) { |
292 const char* kName = "pineapple"; | 292 const char* kName = "pineapple"; |
293 SetGlobalProperty(kName, isolate()->factory()->undefined_string()); | 293 SetGlobalProperty(kName, isolate()->factory()->undefined_string()); |
294 SetGlobalProperty(kName, isolate()->factory()->undefined_value()); | 294 SetGlobalProperty(kName, isolate()->factory()->undefined_value()); |
295 | 295 |
296 Node* ret = ReturnLoadNamedFromGlobal( | 296 Node* ret = ReturnLoadNamedFromGlobal( |
297 kName, graph()->start(), graph()->start(), | 297 kName, graph()->start(), graph()->start(), |
298 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 298 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
299 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 299 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
300 | 300 |
301 Reduction r = Reduce(ret->InputAt(0), | 301 Reduction r = Reduce(ret->InputAt(0), |
302 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 302 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
303 ASSERT_FALSE(r.Changed()); | 303 ASSERT_FALSE(r.Changed()); |
304 EXPECT_TRUE(dependencies()->IsEmpty()); | 304 EXPECT_TRUE(dependencies()->IsEmpty()); |
305 } | 305 } |
306 | 306 |
307 | 307 |
308 TEST_F(JSTypeFeedbackTest, | 308 TEST_F(JSTypeFeedbackTest, |
309 JSLoadNamedGlobalPropertyCellStringWithDeoptimization) { | 309 JSLoadNamedGlobalPropertyCellStringWithDeoptimization) { |
310 const char* kName = "pineapple"; | 310 const char* kName = "pineapple"; |
311 SetGlobalProperty(kName, isolate()->factory()->undefined_string()); | 311 SetGlobalProperty(kName, isolate()->factory()->undefined_string()); |
312 SetGlobalProperty(kName, isolate()->factory()->undefined_value()); | 312 SetGlobalProperty(kName, isolate()->factory()->undefined_value()); |
313 | 313 |
314 Node* ret = ReturnLoadNamedFromGlobal( | 314 Node* ret = ReturnLoadNamedFromGlobal( |
315 kName, graph()->start(), graph()->start(), | 315 kName, graph()->start(), graph()->start(), |
316 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 316 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
317 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 317 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
318 | 318 |
319 Reduction r = Reduce(ret->InputAt(0), | 319 Reduction r = Reduce(ret->InputAt(0), |
320 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 320 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
321 | 321 |
322 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) | 322 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) |
323 ASSERT_TRUE(r.Changed()); | 323 ASSERT_TRUE(r.Changed()); |
324 FieldAccess access = AccessBuilder::ForPropertyCellValue(); | 324 FieldAccess access = AccessBuilder::ForPropertyCellValue(); |
325 Capture<Node*> cell_capture; | 325 Capture<Node*> cell_capture; |
326 Matcher<Node*> load_field_match = IsLoadField( | 326 Matcher<Node*> load_field_match = IsLoadField( |
327 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); | 327 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); |
328 EXPECT_THAT(r.replacement(), load_field_match); | 328 EXPECT_THAT(r.replacement(), load_field_match); |
329 | 329 |
330 HeapObjectMatcher<PropertyCell> cell(cell_capture.value()); | 330 HeapObjectMatcher<PropertyCell> cell(cell_capture.value()); |
331 EXPECT_TRUE(cell.HasValue()); | 331 EXPECT_TRUE(cell.HasValue()); |
332 EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); | 332 EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); |
333 | 333 |
334 EXPECT_THAT(ret, | 334 EXPECT_THAT(ret, |
335 IsReturn(load_field_match, load_field_match, graph()->start())); | 335 IsReturn(load_field_match, load_field_match, graph()->start())); |
336 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 336 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
337 | 337 |
338 EXPECT_FALSE(dependencies()->IsEmpty()); | 338 EXPECT_FALSE(dependencies()->IsEmpty()); |
339 dependencies()->Rollback(); | 339 dependencies()->Rollback(); |
340 } | 340 } |
341 | 341 |
342 } // namespace compiler | 342 } // namespace compiler |
343 } // namespace internal | 343 } // namespace internal |
344 } // namespace v8 | 344 } // namespace v8 |
OLD | NEW |