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/js-native-context-specialization.h" | 5 #include "src/compiler/js-native-context-specialization.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 Node* fallthrough_control = control; | 545 Node* fallthrough_control = control; |
546 for (ElementAccessInfo const& access_info : access_infos) { | 546 for (ElementAccessInfo const& access_info : access_infos) { |
547 Node* this_receiver = receiver; | 547 Node* this_receiver = receiver; |
548 Node* this_value = value; | 548 Node* this_value = value; |
549 Node* this_index = index; | 549 Node* this_index = index; |
550 Node* this_effect = effect; | 550 Node* this_effect = effect; |
551 Node* this_control; | 551 Node* this_control; |
552 | 552 |
553 // Perform map check on {receiver}. | 553 // Perform map check on {receiver}. |
554 Type* receiver_type = access_info.receiver_type(); | 554 Type* receiver_type = access_info.receiver_type(); |
| 555 bool receiver_is_jsarray = true; |
555 { | 556 { |
556 ZoneVector<Node*> this_controls(zone()); | 557 ZoneVector<Node*> this_controls(zone()); |
557 for (auto i = access_info.receiver_type()->Classes(); !i.Done(); | 558 for (auto i = access_info.receiver_type()->Classes(); !i.Done(); |
558 i.Advance()) { | 559 i.Advance()) { |
559 Handle<Map> map = i.Current(); | 560 Handle<Map> map = i.Current(); |
560 Node* check = | 561 Node* check = |
561 graph()->NewNode(simplified()->ReferenceEqual(Type::Internal()), | 562 graph()->NewNode(simplified()->ReferenceEqual(Type::Internal()), |
562 receiver_map, jsgraph()->Constant(map)); | 563 receiver_map, jsgraph()->Constant(map)); |
563 Node* branch = | 564 Node* branch = |
564 graph()->NewNode(common()->Branch(), check, fallthrough_control); | 565 graph()->NewNode(common()->Branch(), check, fallthrough_control); |
565 this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch)); | 566 this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch)); |
566 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch); | 567 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch); |
| 568 if (!map->IsJSArrayMap()) receiver_is_jsarray = false; |
567 } | 569 } |
568 int const this_control_count = static_cast<int>(this_controls.size()); | 570 int const this_control_count = static_cast<int>(this_controls.size()); |
569 this_control = | 571 this_control = |
570 (this_control_count == 1) | 572 (this_control_count == 1) |
571 ? this_controls.front() | 573 ? this_controls.front() |
572 : graph()->NewNode(common()->Merge(this_control_count), | 574 : graph()->NewNode(common()->Merge(this_control_count), |
573 this_control_count, &this_controls.front()); | 575 this_control_count, &this_controls.front()); |
574 } | 576 } |
575 | 577 |
576 // Certain stores need a prototype chain check because shape changes | 578 // Certain stores need a prototype chain check because shape changes |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 check = graph()->NewNode( | 627 check = graph()->NewNode( |
626 simplified()->ReferenceEqual(Type::Any()), this_elements_map, | 628 simplified()->ReferenceEqual(Type::Any()), this_elements_map, |
627 jsgraph()->HeapConstant(factory()->fixed_array_map())); | 629 jsgraph()->HeapConstant(factory()->fixed_array_map())); |
628 branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, | 630 branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, |
629 this_control); | 631 this_control); |
630 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); | 632 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); |
631 this_control = graph()->NewNode(common()->IfTrue(), branch); | 633 this_control = graph()->NewNode(common()->IfTrue(), branch); |
632 } | 634 } |
633 | 635 |
634 // Load the length of the {receiver}. | 636 // Load the length of the {receiver}. |
635 FieldAccess length_access = { | 637 Node* this_length; |
636 kTaggedBase, JSArray::kLengthOffset, factory()->name_string(), | 638 if (receiver_is_jsarray) { |
637 type_cache_.kJSArrayLengthType, kMachAnyTagged}; | 639 FieldAccess length_access = { |
638 if (IsFastDoubleElementsKind(elements_kind)) { | 640 kTaggedBase, JSArray::kLengthOffset, factory()->name_string(), |
639 length_access.type = type_cache_.kFixedDoubleArrayLengthType; | 641 type_cache_.kJSArrayLengthType, kMachAnyTagged}; |
640 } else if (IsFastElementsKind(elements_kind)) { | 642 if (IsFastDoubleElementsKind(elements_kind)) { |
641 length_access.type = type_cache_.kFixedArrayLengthType; | 643 length_access.type = type_cache_.kFixedDoubleArrayLengthType; |
| 644 } else if (IsFastElementsKind(elements_kind)) { |
| 645 length_access.type = type_cache_.kFixedArrayLengthType; |
| 646 } |
| 647 this_length = this_effect = |
| 648 graph()->NewNode(simplified()->LoadField(length_access), |
| 649 this_receiver, this_effect, this_control); |
| 650 } else { |
| 651 this_length = this_effect = graph()->NewNode( |
| 652 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), |
| 653 this_elements, this_effect, this_control); |
642 } | 654 } |
643 Node* this_length = this_effect = | |
644 graph()->NewNode(simplified()->LoadField(length_access), this_receiver, | |
645 this_effect, this_control); | |
646 | 655 |
647 // Check that the {index} is in the valid range for the {receiver}. | 656 // Check that the {index} is in the valid range for the {receiver}. |
648 Node* check = graph()->NewNode(simplified()->NumberLessThan(), this_index, | 657 Node* check = graph()->NewNode(simplified()->NumberLessThan(), this_index, |
649 this_length); | 658 this_length); |
650 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, | 659 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, |
651 this_control); | 660 this_control); |
652 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); | 661 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); |
653 this_control = graph()->NewNode(common()->IfTrue(), branch); | 662 this_control = graph()->NewNode(common()->IfTrue(), branch); |
654 | 663 |
655 // Compute the element access. | 664 // Compute the element access. |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
889 } | 898 } |
890 | 899 |
891 | 900 |
892 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 901 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
893 return jsgraph()->simplified(); | 902 return jsgraph()->simplified(); |
894 } | 903 } |
895 | 904 |
896 } // namespace compiler | 905 } // namespace compiler |
897 } // namespace internal | 906 } // namespace internal |
898 } // namespace v8 | 907 } // namespace v8 |
OLD | NEW |