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/bit-vector.h" | 5 #include "src/bit-vector.h" |
6 #include "src/compiler/escape-analysis.h" | 6 #include "src/compiler/escape-analysis.h" |
7 #include "src/compiler/escape-analysis-reducer.h" | 7 #include "src/compiler/escape-analysis-reducer.h" |
8 #include "src/compiler/graph-visualizer.h" | 8 #include "src/compiler/graph-visualizer.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 if (!effect) { | 78 if (!effect) { |
79 effect = effect_; | 79 effect = effect_; |
80 } | 80 } |
81 if (!control) { | 81 if (!control) { |
82 control = control_; | 82 control = control_; |
83 } | 83 } |
84 return effect_ = graph()->NewNode(simplified()->StoreField(access), | 84 return effect_ = graph()->NewNode(simplified()->StoreField(access), |
85 allocation, value, effect, control); | 85 allocation, value, effect, control); |
86 } | 86 } |
87 | 87 |
| 88 Node* StoreElement(const ElementAccess& access, Node* allocation, Node* index, |
| 89 Node* value, Node* effect = nullptr, |
| 90 Node* control = nullptr) { |
| 91 if (!effect) { |
| 92 effect = effect_; |
| 93 } |
| 94 if (!control) { |
| 95 control = control_; |
| 96 } |
| 97 return effect_ = |
| 98 graph()->NewNode(simplified()->StoreElement(access), allocation, |
| 99 index, value, effect, control); |
| 100 } |
| 101 |
88 Node* Load(const FieldAccess& access, Node* from, Node* effect = nullptr, | 102 Node* Load(const FieldAccess& access, Node* from, Node* effect = nullptr, |
89 Node* control = nullptr) { | 103 Node* control = nullptr) { |
90 if (!effect) { | 104 if (!effect) { |
91 effect = effect_; | 105 effect = effect_; |
92 } | 106 } |
93 if (!control) { | 107 if (!control) { |
94 control = control_; | 108 control = control_; |
95 } | 109 } |
96 return graph()->NewNode(simplified()->LoadField(access), from, effect, | 110 return graph()->NewNode(simplified()->LoadField(access), from, effect, |
97 control); | 111 control); |
(...skipping 26 matching lines...) Expand all Loading... |
124 Node* IfTrue() { | 138 Node* IfTrue() { |
125 return control_ = graph()->NewNode(common()->IfTrue(), control_); | 139 return control_ = graph()->NewNode(common()->IfTrue(), control_); |
126 } | 140 } |
127 | 141 |
128 Node* IfFalse() { return graph()->NewNode(common()->IfFalse(), control_); } | 142 Node* IfFalse() { return graph()->NewNode(common()->IfFalse(), control_); } |
129 | 143 |
130 Node* Merge2(Node* control1, Node* control2) { | 144 Node* Merge2(Node* control1, Node* control2) { |
131 return control_ = graph()->NewNode(common()->Merge(2), control1, control2); | 145 return control_ = graph()->NewNode(common()->Merge(2), control1, control2); |
132 } | 146 } |
133 | 147 |
134 FieldAccess AccessAtIndex(int offset) { | 148 FieldAccess FieldAccessAtIndex(int offset) { |
135 FieldAccess access = {kTaggedBase, offset, MaybeHandle<Name>(), Type::Any(), | 149 FieldAccess access = {kTaggedBase, offset, MaybeHandle<Name>(), Type::Any(), |
136 MachineType::AnyTagged()}; | 150 MachineType::AnyTagged()}; |
137 return access; | 151 return access; |
138 } | 152 } |
139 | 153 |
| 154 ElementAccess MakeElementAccess(int header_size) { |
| 155 ElementAccess access = {kTaggedBase, header_size, Type::Any(), |
| 156 MachineType::AnyTagged()}; |
| 157 return access; |
| 158 } |
| 159 |
140 // ---------------------------------Assertion Helper-------------------------- | 160 // ---------------------------------Assertion Helper-------------------------- |
141 | 161 |
142 void ExpectReplacement(Node* node, Node* rep) { | 162 void ExpectReplacement(Node* node, Node* rep) { |
143 EXPECT_EQ(rep, escape_analysis()->GetReplacement(node)); | 163 EXPECT_EQ(rep, escape_analysis()->GetReplacement(node)); |
144 } | 164 } |
145 | 165 |
146 void ExpectReplacementPhi(Node* node, Node* left, Node* right) { | 166 void ExpectReplacementPhi(Node* node, Node* left, Node* right) { |
147 Node* rep = escape_analysis()->GetReplacement(node); | 167 Node* rep = escape_analysis()->GetReplacement(node); |
148 ASSERT_NE(nullptr, rep); | 168 ASSERT_NE(nullptr, rep); |
149 ASSERT_EQ(IrOpcode::kPhi, rep->opcode()); | 169 ASSERT_EQ(IrOpcode::kPhi, rep->opcode()); |
150 EXPECT_EQ(left, NodeProperties::GetValueInput(rep, 0)); | 170 EXPECT_EQ(left, NodeProperties::GetValueInput(rep, 0)); |
151 EXPECT_EQ(right, NodeProperties::GetValueInput(rep, 1)); | 171 EXPECT_EQ(right, NodeProperties::GetValueInput(rep, 1)); |
152 } | 172 } |
153 | 173 |
154 void ExpectVirtual(Node* node) { | 174 void ExpectVirtual(Node* node) { |
155 EXPECT_TRUE(node->opcode() == IrOpcode::kAllocate || | 175 EXPECT_TRUE(node->opcode() == IrOpcode::kAllocate || |
156 node->opcode() == IrOpcode::kFinishRegion); | 176 node->opcode() == IrOpcode::kFinishRegion); |
157 EXPECT_TRUE(escape_analysis()->IsVirtual(node)); | 177 EXPECT_TRUE(escape_analysis()->IsVirtual(node)); |
158 } | 178 } |
159 | 179 |
160 void ExpectEscaped(Node* node) { | 180 void ExpectEscaped(Node* node) { |
161 EXPECT_TRUE(node->opcode() == IrOpcode::kAllocate || | 181 EXPECT_TRUE(node->opcode() == IrOpcode::kAllocate || |
162 node->opcode() == IrOpcode::kFinishRegion); | 182 node->opcode() == IrOpcode::kFinishRegion); |
163 EXPECT_TRUE(escape_analysis()->IsEscaped(node)); | 183 EXPECT_TRUE(escape_analysis()->IsEscaped(node)); |
164 } | 184 } |
165 | 185 |
166 SimplifiedOperatorBuilder* simplified() { return &simplified_; } | 186 SimplifiedOperatorBuilder* simplified() { return &simplified_; } |
167 | 187 |
168 Node* effect() { return effect_; } | 188 Node* effect() { return effect_; } |
| 189 Node* control() { return control_; } |
169 | 190 |
170 private: | 191 private: |
171 SimplifiedOperatorBuilder simplified_; | 192 SimplifiedOperatorBuilder simplified_; |
172 JSGraph jsgraph_; | 193 JSGraph jsgraph_; |
173 EscapeAnalysis escape_analysis_; | 194 EscapeAnalysis escape_analysis_; |
174 | 195 |
175 Node* effect_; | 196 Node* effect_; |
176 Node* control_; | 197 Node* control_; |
177 }; | 198 }; |
178 | 199 |
179 | 200 |
180 // ----------------------------------------------------------------------------- | 201 // ----------------------------------------------------------------------------- |
181 // Test cases. | 202 // Test cases. |
182 | 203 |
183 | 204 |
184 TEST_F(EscapeAnalysisTest, StraightNonEscape) { | 205 TEST_F(EscapeAnalysisTest, StraightNonEscape) { |
185 Node* object1 = Constant(1); | 206 Node* object1 = Constant(1); |
186 BeginRegion(); | 207 BeginRegion(); |
187 Node* allocation = Allocate(Constant(kPointerSize)); | 208 Node* allocation = Allocate(Constant(kPointerSize)); |
188 Store(AccessAtIndex(0), allocation, object1); | 209 Store(FieldAccessAtIndex(0), allocation, object1); |
189 Node* finish = FinishRegion(allocation); | 210 Node* finish = FinishRegion(allocation); |
190 Node* load = Load(AccessAtIndex(0), finish); | 211 Node* load = Load(FieldAccessAtIndex(0), finish); |
191 Node* result = Return(load); | 212 Node* result = Return(load); |
192 EndGraph(); | 213 EndGraph(); |
193 | 214 |
194 Analysis(); | 215 Analysis(); |
195 | 216 |
196 ExpectVirtual(allocation); | 217 ExpectVirtual(allocation); |
197 ExpectReplacement(load, object1); | 218 ExpectReplacement(load, object1); |
198 | 219 |
199 Transformation(); | 220 Transformation(); |
200 | 221 |
201 ASSERT_EQ(object1, NodeProperties::GetValueInput(result, 0)); | 222 ASSERT_EQ(object1, NodeProperties::GetValueInput(result, 0)); |
202 } | 223 } |
203 | 224 |
204 | 225 |
| 226 TEST_F(EscapeAnalysisTest, StraightNonEscapeNonConstStore) { |
| 227 Node* object1 = Constant(1); |
| 228 Node* object2 = Constant(2); |
| 229 BeginRegion(); |
| 230 Node* allocation = Allocate(Constant(kPointerSize)); |
| 231 Store(FieldAccessAtIndex(0), allocation, object1); |
| 232 Node* index = |
| 233 graph()->NewNode(common()->Select(MachineRepresentation::kTagged), |
| 234 object1, object2, control()); |
| 235 StoreElement(MakeElementAccess(0), allocation, index, object1); |
| 236 Node* finish = FinishRegion(allocation); |
| 237 Node* load = Load(FieldAccessAtIndex(0), finish); |
| 238 Node* result = Return(load); |
| 239 EndGraph(); |
| 240 |
| 241 Analysis(); |
| 242 |
| 243 ExpectEscaped(allocation); |
| 244 ExpectReplacement(load, nullptr); |
| 245 |
| 246 Transformation(); |
| 247 |
| 248 ASSERT_EQ(load, NodeProperties::GetValueInput(result, 0)); |
| 249 } |
| 250 |
| 251 |
205 TEST_F(EscapeAnalysisTest, StraightEscape) { | 252 TEST_F(EscapeAnalysisTest, StraightEscape) { |
206 Node* object1 = Constant(1); | 253 Node* object1 = Constant(1); |
207 BeginRegion(); | 254 BeginRegion(); |
208 Node* allocation = Allocate(Constant(kPointerSize)); | 255 Node* allocation = Allocate(Constant(kPointerSize)); |
209 Store(AccessAtIndex(0), allocation, object1); | 256 Store(FieldAccessAtIndex(0), allocation, object1); |
210 Node* finish = FinishRegion(allocation); | 257 Node* finish = FinishRegion(allocation); |
211 Node* load = Load(AccessAtIndex(0), finish); | 258 Node* load = Load(FieldAccessAtIndex(0), finish); |
212 Node* result = Return(allocation); | 259 Node* result = Return(allocation); |
213 EndGraph(); | 260 EndGraph(); |
214 graph()->end()->AppendInput(zone(), load); | 261 graph()->end()->AppendInput(zone(), load); |
215 | 262 |
216 Analysis(); | 263 Analysis(); |
217 | 264 |
218 ExpectEscaped(allocation); | 265 ExpectEscaped(allocation); |
219 ExpectReplacement(load, object1); | 266 ExpectReplacement(load, object1); |
220 | 267 |
221 Transformation(); | 268 Transformation(); |
222 | 269 |
223 ASSERT_EQ(allocation, NodeProperties::GetValueInput(result, 0)); | 270 ASSERT_EQ(allocation, NodeProperties::GetValueInput(result, 0)); |
224 } | 271 } |
225 | 272 |
226 | 273 |
227 TEST_F(EscapeAnalysisTest, StoreLoadEscape) { | 274 TEST_F(EscapeAnalysisTest, StoreLoadEscape) { |
228 Node* object1 = Constant(1); | 275 Node* object1 = Constant(1); |
229 | 276 |
230 BeginRegion(); | 277 BeginRegion(); |
231 Node* allocation1 = Allocate(Constant(kPointerSize)); | 278 Node* allocation1 = Allocate(Constant(kPointerSize)); |
232 Store(AccessAtIndex(0), allocation1, object1); | 279 Store(FieldAccessAtIndex(0), allocation1, object1); |
233 Node* finish1 = FinishRegion(allocation1); | 280 Node* finish1 = FinishRegion(allocation1); |
234 | 281 |
235 BeginRegion(); | 282 BeginRegion(); |
236 Node* allocation2 = Allocate(Constant(kPointerSize)); | 283 Node* allocation2 = Allocate(Constant(kPointerSize)); |
237 Store(AccessAtIndex(0), allocation2, finish1); | 284 Store(FieldAccessAtIndex(0), allocation2, finish1); |
238 Node* finish2 = FinishRegion(allocation2); | 285 Node* finish2 = FinishRegion(allocation2); |
239 | 286 |
240 Node* load = Load(AccessAtIndex(0), finish2); | 287 Node* load = Load(FieldAccessAtIndex(0), finish2); |
241 Node* result = Return(load); | 288 Node* result = Return(load); |
242 EndGraph(); | 289 EndGraph(); |
243 Analysis(); | 290 Analysis(); |
244 | 291 |
245 ExpectEscaped(allocation1); | 292 ExpectEscaped(allocation1); |
246 ExpectVirtual(allocation2); | 293 ExpectVirtual(allocation2); |
247 ExpectReplacement(load, finish1); | 294 ExpectReplacement(load, finish1); |
248 | 295 |
249 Transformation(); | 296 Transformation(); |
250 | 297 |
251 ASSERT_EQ(finish1, NodeProperties::GetValueInput(result, 0)); | 298 ASSERT_EQ(finish1, NodeProperties::GetValueInput(result, 0)); |
252 } | 299 } |
253 | 300 |
254 | 301 |
255 TEST_F(EscapeAnalysisTest, BranchNonEscape) { | 302 TEST_F(EscapeAnalysisTest, BranchNonEscape) { |
256 Node* object1 = Constant(1); | 303 Node* object1 = Constant(1); |
257 Node* object2 = Constant(2); | 304 Node* object2 = Constant(2); |
258 BeginRegion(); | 305 BeginRegion(); |
259 Node* allocation = Allocate(Constant(kPointerSize)); | 306 Node* allocation = Allocate(Constant(kPointerSize)); |
260 Store(AccessAtIndex(0), allocation, object1); | 307 Store(FieldAccessAtIndex(0), allocation, object1); |
261 Node* finish = FinishRegion(allocation); | 308 Node* finish = FinishRegion(allocation); |
262 Branch(); | 309 Branch(); |
263 Node* ifFalse = IfFalse(); | 310 Node* ifFalse = IfFalse(); |
264 Node* ifTrue = IfTrue(); | 311 Node* ifTrue = IfTrue(); |
265 Node* effect1 = Store(AccessAtIndex(0), allocation, object1, finish, ifFalse); | 312 Node* effect1 = |
266 Node* effect2 = Store(AccessAtIndex(0), allocation, object2, finish, ifTrue); | 313 Store(FieldAccessAtIndex(0), allocation, object1, finish, ifFalse); |
| 314 Node* effect2 = |
| 315 Store(FieldAccessAtIndex(0), allocation, object2, finish, ifTrue); |
267 Node* merge = Merge2(ifFalse, ifTrue); | 316 Node* merge = Merge2(ifFalse, ifTrue); |
268 Node* phi = graph()->NewNode(common()->EffectPhi(2), effect1, effect2, merge); | 317 Node* phi = graph()->NewNode(common()->EffectPhi(2), effect1, effect2, merge); |
269 Node* load = Load(AccessAtIndex(0), finish, phi, merge); | 318 Node* load = Load(FieldAccessAtIndex(0), finish, phi, merge); |
270 Node* result = Return(load, phi); | 319 Node* result = Return(load, phi); |
271 EndGraph(); | 320 EndGraph(); |
272 graph()->end()->AppendInput(zone(), result); | 321 graph()->end()->AppendInput(zone(), result); |
273 | 322 |
274 Analysis(); | 323 Analysis(); |
275 | 324 |
276 ExpectVirtual(allocation); | 325 ExpectVirtual(allocation); |
277 ExpectReplacementPhi(load, object1, object2); | 326 ExpectReplacementPhi(load, object1, object2); |
278 Node* replacement_phi = escape_analysis()->GetReplacement(load); | 327 Node* replacement_phi = escape_analysis()->GetReplacement(load); |
279 | 328 |
280 Transformation(); | 329 Transformation(); |
281 | 330 |
282 ASSERT_EQ(replacement_phi, NodeProperties::GetValueInput(result, 0)); | 331 ASSERT_EQ(replacement_phi, NodeProperties::GetValueInput(result, 0)); |
283 } | 332 } |
284 | 333 |
285 | 334 |
286 TEST_F(EscapeAnalysisTest, DanglingLoadOrder) { | 335 TEST_F(EscapeAnalysisTest, DanglingLoadOrder) { |
287 Node* object1 = Constant(1); | 336 Node* object1 = Constant(1); |
288 Node* object2 = Constant(2); | 337 Node* object2 = Constant(2); |
289 Node* allocation = Allocate(Constant(kPointerSize)); | 338 Node* allocation = Allocate(Constant(kPointerSize)); |
290 Node* store1 = Store(AccessAtIndex(0), allocation, object1); | 339 Node* store1 = Store(FieldAccessAtIndex(0), allocation, object1); |
291 Node* load1 = Load(AccessAtIndex(0), allocation); | 340 Node* load1 = Load(FieldAccessAtIndex(0), allocation); |
292 Node* store2 = Store(AccessAtIndex(0), allocation, object2); | 341 Node* store2 = Store(FieldAccessAtIndex(0), allocation, object2); |
293 Node* load2 = Load(AccessAtIndex(0), allocation, store1); | 342 Node* load2 = Load(FieldAccessAtIndex(0), allocation, store1); |
294 Node* result = Return(load2); | 343 Node* result = Return(load2); |
295 EndGraph(); | 344 EndGraph(); |
296 graph()->end()->AppendInput(zone(), store2); | 345 graph()->end()->AppendInput(zone(), store2); |
297 graph()->end()->AppendInput(zone(), load1); | 346 graph()->end()->AppendInput(zone(), load1); |
298 | 347 |
299 Analysis(); | 348 Analysis(); |
300 | 349 |
301 ExpectVirtual(allocation); | 350 ExpectVirtual(allocation); |
302 ExpectReplacement(load1, object1); | 351 ExpectReplacement(load1, object1); |
303 ExpectReplacement(load2, object1); | 352 ExpectReplacement(load2, object1); |
304 | 353 |
305 Transformation(); | 354 Transformation(); |
306 | 355 |
307 ASSERT_EQ(object1, NodeProperties::GetValueInput(result, 0)); | 356 ASSERT_EQ(object1, NodeProperties::GetValueInput(result, 0)); |
308 } | 357 } |
309 | 358 |
310 | 359 |
311 TEST_F(EscapeAnalysisTest, DeoptReplacement) { | 360 TEST_F(EscapeAnalysisTest, DeoptReplacement) { |
312 Node* object1 = Constant(1); | 361 Node* object1 = Constant(1); |
313 BeginRegion(); | 362 BeginRegion(); |
314 Node* allocation = Allocate(Constant(kPointerSize)); | 363 Node* allocation = Allocate(Constant(kPointerSize)); |
315 Store(AccessAtIndex(0), allocation, object1); | 364 Store(FieldAccessAtIndex(0), allocation, object1); |
316 Node* finish = FinishRegion(allocation); | 365 Node* finish = FinishRegion(allocation); |
317 Node* effect1 = Store(AccessAtIndex(0), allocation, object1, finish); | 366 Node* effect1 = Store(FieldAccessAtIndex(0), allocation, object1, finish); |
318 Branch(); | 367 Branch(); |
319 Node* ifFalse = IfFalse(); | 368 Node* ifFalse = IfFalse(); |
320 Node* state_values1 = graph()->NewNode(common()->StateValues(1), finish); | 369 Node* state_values1 = graph()->NewNode(common()->StateValues(1), finish); |
321 Node* state_values2 = graph()->NewNode(common()->StateValues(0)); | 370 Node* state_values2 = graph()->NewNode(common()->StateValues(0)); |
322 Node* state_values3 = graph()->NewNode(common()->StateValues(0)); | 371 Node* state_values3 = graph()->NewNode(common()->StateValues(0)); |
323 Node* frame_state = graph()->NewNode( | 372 Node* frame_state = graph()->NewNode( |
324 common()->FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(), | 373 common()->FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(), |
325 nullptr), | 374 nullptr), |
326 state_values1, state_values2, state_values3, UndefinedConstant(), | 375 state_values1, state_values2, state_values3, UndefinedConstant(), |
327 graph()->start(), graph()->start()); | 376 graph()->start(), graph()->start()); |
328 Node* deopt = graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), | 377 Node* deopt = graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), |
329 frame_state, effect1, ifFalse); | 378 frame_state, effect1, ifFalse); |
330 Node* ifTrue = IfTrue(); | 379 Node* ifTrue = IfTrue(); |
331 Node* load = Load(AccessAtIndex(0), finish, effect1, ifTrue); | 380 Node* load = Load(FieldAccessAtIndex(0), finish, effect1, ifTrue); |
332 Node* result = Return(load, effect1, ifTrue); | 381 Node* result = Return(load, effect1, ifTrue); |
333 EndGraph(); | 382 EndGraph(); |
334 graph()->end()->AppendInput(zone(), deopt); | 383 graph()->end()->AppendInput(zone(), deopt); |
335 Analysis(); | 384 Analysis(); |
336 | 385 |
337 ExpectVirtual(allocation); | 386 ExpectVirtual(allocation); |
338 ExpectReplacement(load, object1); | 387 ExpectReplacement(load, object1); |
339 | 388 |
340 Transformation(); | 389 Transformation(); |
341 | 390 |
342 ASSERT_EQ(object1, NodeProperties::GetValueInput(result, 0)); | 391 ASSERT_EQ(object1, NodeProperties::GetValueInput(result, 0)); |
343 Node* object_state = NodeProperties::GetValueInput(state_values1, 0); | 392 Node* object_state = NodeProperties::GetValueInput(state_values1, 0); |
344 ASSERT_EQ(object_state->opcode(), IrOpcode::kObjectState); | 393 ASSERT_EQ(object_state->opcode(), IrOpcode::kObjectState); |
345 ASSERT_EQ(1, object_state->op()->ValueInputCount()); | 394 ASSERT_EQ(1, object_state->op()->ValueInputCount()); |
346 ASSERT_EQ(object1, NodeProperties::GetValueInput(object_state, 0)); | 395 ASSERT_EQ(object1, NodeProperties::GetValueInput(object_state, 0)); |
347 } | 396 } |
348 | 397 |
349 | 398 |
350 TEST_F(EscapeAnalysisTest, DeoptReplacementIdentity) { | 399 TEST_F(EscapeAnalysisTest, DeoptReplacementIdentity) { |
351 Node* object1 = Constant(1); | 400 Node* object1 = Constant(1); |
352 BeginRegion(); | 401 BeginRegion(); |
353 Node* allocation = Allocate(Constant(kPointerSize * 2)); | 402 Node* allocation = Allocate(Constant(kPointerSize * 2)); |
354 Store(AccessAtIndex(0), allocation, object1); | 403 Store(FieldAccessAtIndex(0), allocation, object1); |
355 Store(AccessAtIndex(kPointerSize), allocation, allocation); | 404 Store(FieldAccessAtIndex(kPointerSize), allocation, allocation); |
356 Node* finish = FinishRegion(allocation); | 405 Node* finish = FinishRegion(allocation); |
357 Node* effect1 = Store(AccessAtIndex(0), allocation, object1, finish); | 406 Node* effect1 = Store(FieldAccessAtIndex(0), allocation, object1, finish); |
358 Branch(); | 407 Branch(); |
359 Node* ifFalse = IfFalse(); | 408 Node* ifFalse = IfFalse(); |
360 Node* state_values1 = graph()->NewNode(common()->StateValues(1), finish); | 409 Node* state_values1 = graph()->NewNode(common()->StateValues(1), finish); |
361 Node* state_values2 = graph()->NewNode(common()->StateValues(1), finish); | 410 Node* state_values2 = graph()->NewNode(common()->StateValues(1), finish); |
362 Node* state_values3 = graph()->NewNode(common()->StateValues(0)); | 411 Node* state_values3 = graph()->NewNode(common()->StateValues(0)); |
363 Node* frame_state = graph()->NewNode( | 412 Node* frame_state = graph()->NewNode( |
364 common()->FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(), | 413 common()->FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(), |
365 nullptr), | 414 nullptr), |
366 state_values1, state_values2, state_values3, UndefinedConstant(), | 415 state_values1, state_values2, state_values3, UndefinedConstant(), |
367 graph()->start(), graph()->start()); | 416 graph()->start(), graph()->start()); |
368 Node* deopt = graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), | 417 Node* deopt = graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), |
369 frame_state, effect1, ifFalse); | 418 frame_state, effect1, ifFalse); |
370 Node* ifTrue = IfTrue(); | 419 Node* ifTrue = IfTrue(); |
371 Node* load = Load(AccessAtIndex(0), finish, effect1, ifTrue); | 420 Node* load = Load(FieldAccessAtIndex(0), finish, effect1, ifTrue); |
372 Node* result = Return(load, effect1, ifTrue); | 421 Node* result = Return(load, effect1, ifTrue); |
373 EndGraph(); | 422 EndGraph(); |
374 graph()->end()->AppendInput(zone(), deopt); | 423 graph()->end()->AppendInput(zone(), deopt); |
375 Analysis(); | 424 Analysis(); |
376 | 425 |
377 ExpectVirtual(allocation); | 426 ExpectVirtual(allocation); |
378 ExpectReplacement(load, object1); | 427 ExpectReplacement(load, object1); |
379 | 428 |
380 Transformation(); | 429 Transformation(); |
381 | 430 |
382 ASSERT_EQ(object1, NodeProperties::GetValueInput(result, 0)); | 431 ASSERT_EQ(object1, NodeProperties::GetValueInput(result, 0)); |
383 | 432 |
384 Node* object_state = NodeProperties::GetValueInput(state_values1, 0); | 433 Node* object_state = NodeProperties::GetValueInput(state_values1, 0); |
385 ASSERT_EQ(object_state->opcode(), IrOpcode::kObjectState); | 434 ASSERT_EQ(object_state->opcode(), IrOpcode::kObjectState); |
386 ASSERT_EQ(2, object_state->op()->ValueInputCount()); | 435 ASSERT_EQ(2, object_state->op()->ValueInputCount()); |
387 ASSERT_EQ(object1, NodeProperties::GetValueInput(object_state, 0)); | 436 ASSERT_EQ(object1, NodeProperties::GetValueInput(object_state, 0)); |
388 ASSERT_EQ(object_state, NodeProperties::GetValueInput(object_state, 1)); | 437 ASSERT_EQ(object_state, NodeProperties::GetValueInput(object_state, 1)); |
389 | 438 |
390 Node* object_state2 = NodeProperties::GetValueInput(state_values1, 0); | 439 Node* object_state2 = NodeProperties::GetValueInput(state_values1, 0); |
391 ASSERT_EQ(object_state, object_state2); | 440 ASSERT_EQ(object_state, object_state2); |
392 } | 441 } |
393 | 442 |
394 } // namespace compiler | 443 } // namespace compiler |
395 } // namespace internal | 444 } // namespace internal |
396 } // namespace v8 | 445 } // namespace v8 |
OLD | NEW |