| 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/node-properties.h" | 5 #include "src/compiler/node-properties.h" |
| 6 #include "src/compiler/common-operator.h" | 6 #include "src/compiler/common-operator.h" |
| 7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
| 8 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
| 9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 } | 326 } |
| 327 if (b->opcode() == IrOpcode::kCheckHeapObject) { | 327 if (b->opcode() == IrOpcode::kCheckHeapObject) { |
| 328 b = GetValueInput(b, 0); | 328 b = GetValueInput(b, 0); |
| 329 continue; | 329 continue; |
| 330 } | 330 } |
| 331 return a == b; | 331 return a == b; |
| 332 } | 332 } |
| 333 } | 333 } |
| 334 | 334 |
| 335 // static | 335 // static |
| 336 bool NodeProperties::InferReceiverMaps(Node* receiver, Node* effect, | 336 NodeProperties::InferReceiverMapsResult NodeProperties::InferReceiverMaps( |
| 337 ZoneHandleSet<Map>* maps_return) { | 337 Node* receiver, Node* effect, ZoneHandleSet<Map>* maps_return) { |
| 338 HeapObjectMatcher m(receiver); | 338 HeapObjectMatcher m(receiver); |
| 339 if (m.HasValue()) { | 339 if (m.HasValue()) { |
| 340 Handle<Map> receiver_map(m.Value()->map()); | 340 Handle<Map> receiver_map(m.Value()->map()); |
| 341 if (receiver_map->is_stable()) { | 341 if (receiver_map->is_stable()) { |
| 342 // The {receiver_map} is only reliable when we install a stability |
| 343 // code dependency. |
| 342 *maps_return = ZoneHandleSet<Map>(receiver_map); | 344 *maps_return = ZoneHandleSet<Map>(receiver_map); |
| 343 return true; | 345 return kUnreliableReceiverMaps; |
| 344 } | 346 } |
| 345 } | 347 } |
| 348 InferReceiverMapsResult result = kReliableReceiverMaps; |
| 346 while (true) { | 349 while (true) { |
| 347 switch (effect->opcode()) { | 350 switch (effect->opcode()) { |
| 348 case IrOpcode::kCheckMaps: { | 351 case IrOpcode::kCheckMaps: { |
| 349 Node* const object = GetValueInput(effect, 0); | 352 Node* const object = GetValueInput(effect, 0); |
| 350 if (IsSame(receiver, object)) { | 353 if (IsSame(receiver, object)) { |
| 351 *maps_return = CheckMapsParametersOf(effect->op()).maps(); | 354 *maps_return = CheckMapsParametersOf(effect->op()).maps(); |
| 352 return true; | 355 return result; |
| 353 } | 356 } |
| 354 break; | 357 break; |
| 355 } | 358 } |
| 356 case IrOpcode::kJSCreate: { | 359 case IrOpcode::kJSCreate: { |
| 357 if (IsSame(receiver, effect)) { | 360 if (IsSame(receiver, effect)) { |
| 358 HeapObjectMatcher mtarget(GetValueInput(effect, 0)); | 361 HeapObjectMatcher mtarget(GetValueInput(effect, 0)); |
| 359 HeapObjectMatcher mnewtarget(GetValueInput(effect, 1)); | 362 HeapObjectMatcher mnewtarget(GetValueInput(effect, 1)); |
| 360 if (mtarget.HasValue() && mnewtarget.HasValue()) { | 363 if (mtarget.HasValue() && mnewtarget.HasValue()) { |
| 361 Handle<JSFunction> original_constructor = | 364 Handle<JSFunction> original_constructor = |
| 362 Handle<JSFunction>::cast(mnewtarget.Value()); | 365 Handle<JSFunction>::cast(mnewtarget.Value()); |
| 363 if (original_constructor->has_initial_map()) { | 366 if (original_constructor->has_initial_map()) { |
| 364 Handle<Map> initial_map(original_constructor->initial_map()); | 367 Handle<Map> initial_map(original_constructor->initial_map()); |
| 365 if (initial_map->constructor_or_backpointer() == | 368 if (initial_map->constructor_or_backpointer() == |
| 366 *mtarget.Value()) { | 369 *mtarget.Value()) { |
| 367 *maps_return = ZoneHandleSet<Map>(initial_map); | 370 *maps_return = ZoneHandleSet<Map>(initial_map); |
| 368 return true; | 371 return result; |
| 369 } | 372 } |
| 370 } | 373 } |
| 371 } | 374 } |
| 372 // We reached the allocation of the {receiver}. | 375 // We reached the allocation of the {receiver}. |
| 373 return false; | 376 return kNoReceiverMaps; |
| 374 } | 377 } |
| 375 break; | 378 break; |
| 376 } | 379 } |
| 377 case IrOpcode::kStoreField: { | 380 case IrOpcode::kStoreField: { |
| 378 // We only care about StoreField of maps. | 381 // We only care about StoreField of maps. |
| 379 Node* const object = GetValueInput(effect, 0); | 382 Node* const object = GetValueInput(effect, 0); |
| 380 FieldAccess const& access = FieldAccessOf(effect->op()); | 383 FieldAccess const& access = FieldAccessOf(effect->op()); |
| 381 if (access.base_is_tagged == kTaggedBase && | 384 if (access.base_is_tagged == kTaggedBase && |
| 382 access.offset == HeapObject::kMapOffset) { | 385 access.offset == HeapObject::kMapOffset) { |
| 383 if (IsSame(receiver, object)) { | 386 if (IsSame(receiver, object)) { |
| 384 Node* const value = GetValueInput(effect, 1); | 387 Node* const value = GetValueInput(effect, 1); |
| 385 HeapObjectMatcher m(value); | 388 HeapObjectMatcher m(value); |
| 386 if (m.HasValue()) { | 389 if (m.HasValue()) { |
| 387 *maps_return = ZoneHandleSet<Map>(Handle<Map>::cast(m.Value())); | 390 *maps_return = ZoneHandleSet<Map>(Handle<Map>::cast(m.Value())); |
| 388 return true; | 391 return result; |
| 389 } | 392 } |
| 390 } | 393 } |
| 391 // Without alias analysis we cannot tell whether this | 394 // Without alias analysis we cannot tell whether this |
| 392 // StoreField[map] affects {receiver} or not. | 395 // StoreField[map] affects {receiver} or not. |
| 393 return false; | 396 result = kUnreliableReceiverMaps; |
| 394 } | 397 } |
| 395 break; | 398 break; |
| 396 } | 399 } |
| 397 case IrOpcode::kJSStoreMessage: | 400 case IrOpcode::kJSStoreMessage: |
| 398 case IrOpcode::kJSStoreModule: | 401 case IrOpcode::kJSStoreModule: |
| 399 case IrOpcode::kStoreElement: | 402 case IrOpcode::kStoreElement: |
| 400 case IrOpcode::kStoreTypedElement: { | 403 case IrOpcode::kStoreTypedElement: { |
| 401 // These never change the map of objects. | 404 // These never change the map of objects. |
| 402 break; | 405 break; |
| 403 } | 406 } |
| 404 default: { | 407 default: { |
| 405 DCHECK_EQ(1, effect->op()->EffectOutputCount()); | 408 DCHECK_EQ(1, effect->op()->EffectOutputCount()); |
| 406 if (effect->op()->EffectInputCount() != 1 || | 409 if (effect->op()->EffectInputCount() != 1) { |
| 407 !effect->op()->HasProperty(Operator::kNoWrite)) { | |
| 408 // Didn't find any appropriate CheckMaps node. | 410 // Didn't find any appropriate CheckMaps node. |
| 409 return false; | 411 return kNoReceiverMaps; |
| 412 } |
| 413 if (!effect->op()->HasProperty(Operator::kNoWrite)) { |
| 414 // Without alias/escape analysis we cannot tell whether this |
| 415 // {effect} affects {receiver} or not. |
| 416 result = kUnreliableReceiverMaps; |
| 410 } | 417 } |
| 411 break; | 418 break; |
| 412 } | 419 } |
| 413 } | 420 } |
| 414 DCHECK_EQ(1, effect->op()->EffectInputCount()); | 421 DCHECK_EQ(1, effect->op()->EffectInputCount()); |
| 415 effect = NodeProperties::GetEffectInput(effect); | 422 effect = NodeProperties::GetEffectInput(effect); |
| 416 } | 423 } |
| 417 } | 424 } |
| 418 | 425 |
| 419 // static | 426 // static |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 // static | 478 // static |
| 472 bool NodeProperties::IsInputRange(Edge edge, int first, int num) { | 479 bool NodeProperties::IsInputRange(Edge edge, int first, int num) { |
| 473 if (num == 0) return false; | 480 if (num == 0) return false; |
| 474 int const index = edge.index(); | 481 int const index = edge.index(); |
| 475 return first <= index && index < first + num; | 482 return first <= index && index < first + num; |
| 476 } | 483 } |
| 477 | 484 |
| 478 } // namespace compiler | 485 } // namespace compiler |
| 479 } // namespace internal | 486 } // namespace internal |
| 480 } // namespace v8 | 487 } // namespace v8 |
| OLD | NEW |