| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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-typed-lowering.h" | 5 #include "src/compiler/js-typed-lowering.h" |
| 6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
| 7 #include "src/compilation-dependencies.h" | 7 #include "src/compilation-dependencies.h" |
| 8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/js-operator.h" | 10 #include "src/compiler/js-operator.h" |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 NewArrayBuffer(backing_store, sizeof(backing_store)); | 573 NewArrayBuffer(backing_store, sizeof(backing_store)); |
| 574 VectorSlotPair feedback; | 574 VectorSlotPair feedback; |
| 575 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { | 575 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { |
| 576 Handle<JSTypedArray> array = | 576 Handle<JSTypedArray> array = |
| 577 factory()->NewJSTypedArray(type, buffer, 0, kLength); | 577 factory()->NewJSTypedArray(type, buffer, 0, kLength); |
| 578 int const element_size = static_cast<int>(array->element_size()); | 578 int const element_size = static_cast<int>(array->element_size()); |
| 579 | 579 |
| 580 Node* key = Parameter( | 580 Node* key = Parameter( |
| 581 Type::Range(kMinInt / element_size, kMaxInt / element_size, zone())); | 581 Type::Range(kMinInt / element_size, kMaxInt / element_size, zone())); |
| 582 Node* base = HeapConstant(array); | 582 Node* base = HeapConstant(array); |
| 583 Node* vector = UndefinedConstant(); | |
| 584 Node* context = UndefinedConstant(); | 583 Node* context = UndefinedConstant(); |
| 585 Node* effect = graph()->start(); | 584 Node* effect = graph()->start(); |
| 586 Node* control = graph()->start(); | 585 Node* control = graph()->start(); |
| 587 Reduction r = Reduce(graph()->NewNode(javascript()->LoadProperty(feedback), | 586 Reduction r = |
| 588 base, key, vector, context, | 587 Reduce(graph()->NewNode(javascript()->LoadProperty(feedback), base, key, |
| 589 EmptyFrameState(), effect, control)); | 588 context, EmptyFrameState(), effect, control)); |
| 590 | 589 |
| 591 Matcher<Node*> offset_matcher = | 590 Matcher<Node*> offset_matcher = |
| 592 element_size == 1 | 591 element_size == 1 |
| 593 ? key | 592 ? key |
| 594 : IsNumberShiftLeft(key, | 593 : IsNumberShiftLeft(key, |
| 595 IsNumberConstant(WhichPowerOf2(element_size))); | 594 IsNumberConstant(WhichPowerOf2(element_size))); |
| 596 | 595 |
| 597 ASSERT_TRUE(r.Changed()); | 596 ASSERT_TRUE(r.Changed()); |
| 598 EXPECT_THAT( | 597 EXPECT_THAT( |
| 599 r.replacement(), | 598 r.replacement(), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 615 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { | 614 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { |
| 616 Handle<JSTypedArray> array = | 615 Handle<JSTypedArray> array = |
| 617 factory()->NewJSTypedArray(type, buffer, 0, kLength); | 616 factory()->NewJSTypedArray(type, buffer, 0, kLength); |
| 618 ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true); | 617 ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true); |
| 619 | 618 |
| 620 int min = random_number_generator()->NextInt(static_cast<int>(kLength)); | 619 int min = random_number_generator()->NextInt(static_cast<int>(kLength)); |
| 621 int max = random_number_generator()->NextInt(static_cast<int>(kLength)); | 620 int max = random_number_generator()->NextInt(static_cast<int>(kLength)); |
| 622 if (min > max) std::swap(min, max); | 621 if (min > max) std::swap(min, max); |
| 623 Node* key = Parameter(Type::Range(min, max, zone())); | 622 Node* key = Parameter(Type::Range(min, max, zone())); |
| 624 Node* base = HeapConstant(array); | 623 Node* base = HeapConstant(array); |
| 625 Node* vector = UndefinedConstant(); | |
| 626 Node* context = UndefinedConstant(); | 624 Node* context = UndefinedConstant(); |
| 627 Node* effect = graph()->start(); | 625 Node* effect = graph()->start(); |
| 628 Node* control = graph()->start(); | 626 Node* control = graph()->start(); |
| 629 Reduction r = Reduce(graph()->NewNode(javascript()->LoadProperty(feedback), | 627 Reduction r = |
| 630 base, key, vector, context, | 628 Reduce(graph()->NewNode(javascript()->LoadProperty(feedback), base, key, |
| 631 EmptyFrameState(), effect, control)); | 629 context, EmptyFrameState(), effect, control)); |
| 632 | 630 |
| 633 ASSERT_TRUE(r.Changed()); | 631 ASSERT_TRUE(r.Changed()); |
| 634 EXPECT_THAT( | 632 EXPECT_THAT( |
| 635 r.replacement(), | 633 r.replacement(), |
| 636 IsLoadElement(access, | 634 IsLoadElement(access, |
| 637 IsPointerConstant(bit_cast<intptr_t>(&backing_store[0])), | 635 IsPointerConstant(bit_cast<intptr_t>(&backing_store[0])), |
| 638 key, effect, control)); | 636 key, effect, control)); |
| 639 } | 637 } |
| 640 } | 638 } |
| 641 | 639 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 653 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { | 651 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
| 654 Handle<JSTypedArray> array = | 652 Handle<JSTypedArray> array = |
| 655 factory()->NewJSTypedArray(type, buffer, 0, kLength); | 653 factory()->NewJSTypedArray(type, buffer, 0, kLength); |
| 656 int const element_size = static_cast<int>(array->element_size()); | 654 int const element_size = static_cast<int>(array->element_size()); |
| 657 | 655 |
| 658 Node* key = Parameter( | 656 Node* key = Parameter( |
| 659 Type::Range(kMinInt / element_size, kMaxInt / element_size, zone())); | 657 Type::Range(kMinInt / element_size, kMaxInt / element_size, zone())); |
| 660 Node* base = HeapConstant(array); | 658 Node* base = HeapConstant(array); |
| 661 Node* value = | 659 Node* value = |
| 662 Parameter(AccessBuilder::ForTypedArrayElement(type, true).type); | 660 Parameter(AccessBuilder::ForTypedArrayElement(type, true).type); |
| 663 Node* vector = UndefinedConstant(); | |
| 664 Node* context = UndefinedConstant(); | 661 Node* context = UndefinedConstant(); |
| 665 Node* effect = graph()->start(); | 662 Node* effect = graph()->start(); |
| 666 Node* control = graph()->start(); | 663 Node* control = graph()->start(); |
| 667 VectorSlotPair feedback; | 664 VectorSlotPair feedback; |
| 668 const Operator* op = javascript()->StoreProperty(language_mode, feedback); | 665 const Operator* op = javascript()->StoreProperty(language_mode, feedback); |
| 669 Node* node = graph()->NewNode(op, base, key, value, vector, context, | 666 Node* node = graph()->NewNode(op, base, key, value, context, |
| 670 EmptyFrameState(), effect, control); | 667 EmptyFrameState(), effect, control); |
| 671 Reduction r = Reduce(node); | 668 Reduction r = Reduce(node); |
| 672 | 669 |
| 673 Matcher<Node*> offset_matcher = | 670 Matcher<Node*> offset_matcher = |
| 674 element_size == 1 | 671 element_size == 1 |
| 675 ? key | 672 ? key |
| 676 : IsNumberShiftLeft( | 673 : IsNumberShiftLeft( |
| 677 key, IsNumberConstant(WhichPowerOf2(element_size))); | 674 key, IsNumberConstant(WhichPowerOf2(element_size))); |
| 678 | 675 |
| 679 ASSERT_TRUE(r.Changed()); | 676 ASSERT_TRUE(r.Changed()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 697 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { | 694 TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { |
| 698 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { | 695 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
| 699 Handle<JSTypedArray> array = | 696 Handle<JSTypedArray> array = |
| 700 factory()->NewJSTypedArray(type, buffer, 0, kLength); | 697 factory()->NewJSTypedArray(type, buffer, 0, kLength); |
| 701 int const element_size = static_cast<int>(array->element_size()); | 698 int const element_size = static_cast<int>(array->element_size()); |
| 702 | 699 |
| 703 Node* key = Parameter( | 700 Node* key = Parameter( |
| 704 Type::Range(kMinInt / element_size, kMaxInt / element_size, zone())); | 701 Type::Range(kMinInt / element_size, kMaxInt / element_size, zone())); |
| 705 Node* base = HeapConstant(array); | 702 Node* base = HeapConstant(array); |
| 706 Node* value = Parameter(Type::Any()); | 703 Node* value = Parameter(Type::Any()); |
| 707 Node* vector = UndefinedConstant(); | |
| 708 Node* context = UndefinedConstant(); | 704 Node* context = UndefinedConstant(); |
| 709 Node* effect = graph()->start(); | 705 Node* effect = graph()->start(); |
| 710 Node* control = graph()->start(); | 706 Node* control = graph()->start(); |
| 711 // TODO(mstarzinger): Once the effect-control-linearizer provides a frame | 707 // TODO(mstarzinger): Once the effect-control-linearizer provides a frame |
| 712 // state we can get rid of this checkpoint again. The reducer won't care. | 708 // state we can get rid of this checkpoint again. The reducer won't care. |
| 713 Node* checkpoint = graph()->NewNode(common()->Checkpoint(), | 709 Node* checkpoint = graph()->NewNode(common()->Checkpoint(), |
| 714 EmptyFrameState(), effect, control); | 710 EmptyFrameState(), effect, control); |
| 715 VectorSlotPair feedback; | 711 VectorSlotPair feedback; |
| 716 const Operator* op = javascript()->StoreProperty(language_mode, feedback); | 712 const Operator* op = javascript()->StoreProperty(language_mode, feedback); |
| 717 Node* node = graph()->NewNode(op, base, key, value, vector, context, | 713 Node* node = graph()->NewNode(op, base, key, value, context, |
| 718 EmptyFrameState(), checkpoint, control); | 714 EmptyFrameState(), checkpoint, control); |
| 719 Reduction r = Reduce(node); | 715 Reduction r = Reduce(node); |
| 720 | 716 |
| 721 Matcher<Node*> offset_matcher = | 717 Matcher<Node*> offset_matcher = |
| 722 element_size == 1 | 718 element_size == 1 |
| 723 ? key | 719 ? key |
| 724 : IsNumberShiftLeft( | 720 : IsNumberShiftLeft( |
| 725 key, IsNumberConstant(WhichPowerOf2(element_size))); | 721 key, IsNumberConstant(WhichPowerOf2(element_size))); |
| 726 | 722 |
| 727 Matcher<Node*> value_matcher = | 723 Matcher<Node*> value_matcher = |
| (...skipping 24 matching lines...) Expand all Loading... |
| 752 Handle<JSTypedArray> array = | 748 Handle<JSTypedArray> array = |
| 753 factory()->NewJSTypedArray(type, buffer, 0, kLength); | 749 factory()->NewJSTypedArray(type, buffer, 0, kLength); |
| 754 ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true); | 750 ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true); |
| 755 | 751 |
| 756 int min = random_number_generator()->NextInt(static_cast<int>(kLength)); | 752 int min = random_number_generator()->NextInt(static_cast<int>(kLength)); |
| 757 int max = random_number_generator()->NextInt(static_cast<int>(kLength)); | 753 int max = random_number_generator()->NextInt(static_cast<int>(kLength)); |
| 758 if (min > max) std::swap(min, max); | 754 if (min > max) std::swap(min, max); |
| 759 Node* key = Parameter(Type::Range(min, max, zone())); | 755 Node* key = Parameter(Type::Range(min, max, zone())); |
| 760 Node* base = HeapConstant(array); | 756 Node* base = HeapConstant(array); |
| 761 Node* value = Parameter(access.type); | 757 Node* value = Parameter(access.type); |
| 762 Node* vector = UndefinedConstant(); | |
| 763 Node* context = UndefinedConstant(); | 758 Node* context = UndefinedConstant(); |
| 764 Node* effect = graph()->start(); | 759 Node* effect = graph()->start(); |
| 765 Node* control = graph()->start(); | 760 Node* control = graph()->start(); |
| 766 VectorSlotPair feedback; | 761 VectorSlotPair feedback; |
| 767 const Operator* op = javascript()->StoreProperty(language_mode, feedback); | 762 const Operator* op = javascript()->StoreProperty(language_mode, feedback); |
| 768 Node* node = graph()->NewNode(op, base, key, value, vector, context, | 763 Node* node = graph()->NewNode(op, base, key, value, context, |
| 769 EmptyFrameState(), effect, control); | 764 EmptyFrameState(), effect, control); |
| 770 Reduction r = Reduce(node); | 765 Reduction r = Reduce(node); |
| 771 | 766 |
| 772 ASSERT_TRUE(r.Changed()); | 767 ASSERT_TRUE(r.Changed()); |
| 773 EXPECT_THAT( | 768 EXPECT_THAT( |
| 774 r.replacement(), | 769 r.replacement(), |
| 775 IsStoreElement( | 770 IsStoreElement( |
| 776 access, IsPointerConstant(bit_cast<intptr_t>(&backing_store[0])), | 771 access, IsPointerConstant(bit_cast<intptr_t>(&backing_store[0])), |
| 777 key, value, effect, control)); | 772 key, value, effect, control)); |
| 778 } | 773 } |
| 779 } | 774 } |
| 780 } | 775 } |
| 781 | 776 |
| 782 | 777 |
| 783 // ----------------------------------------------------------------------------- | 778 // ----------------------------------------------------------------------------- |
| 784 // JSLoadNamed | 779 // JSLoadNamed |
| 785 | 780 |
| 786 | 781 |
| 787 TEST_F(JSTypedLoweringTest, JSLoadNamedStringLength) { | 782 TEST_F(JSTypedLoweringTest, JSLoadNamedStringLength) { |
| 788 VectorSlotPair feedback; | 783 VectorSlotPair feedback; |
| 789 Handle<Name> name = factory()->length_string(); | 784 Handle<Name> name = factory()->length_string(); |
| 790 Node* const receiver = Parameter(Type::String(), 0); | 785 Node* const receiver = Parameter(Type::String(), 0); |
| 791 Node* const vector = Parameter(Type::Internal(), 1); | |
| 792 Node* const context = UndefinedConstant(); | 786 Node* const context = UndefinedConstant(); |
| 793 Node* const effect = graph()->start(); | 787 Node* const effect = graph()->start(); |
| 794 Node* const control = graph()->start(); | 788 Node* const control = graph()->start(); |
| 795 Reduction const r = Reduce( | 789 Reduction const r = |
| 796 graph()->NewNode(javascript()->LoadNamed(name, feedback), receiver, | 790 Reduce(graph()->NewNode(javascript()->LoadNamed(name, feedback), receiver, |
| 797 vector, context, EmptyFrameState(), effect, control)); | 791 context, EmptyFrameState(), effect, control)); |
| 798 ASSERT_TRUE(r.Changed()); | 792 ASSERT_TRUE(r.Changed()); |
| 799 EXPECT_THAT(r.replacement(), IsLoadField(AccessBuilder::ForStringLength(), | 793 EXPECT_THAT(r.replacement(), IsLoadField(AccessBuilder::ForStringLength(), |
| 800 receiver, effect, control)); | 794 receiver, effect, control)); |
| 801 } | 795 } |
| 802 | 796 |
| 803 | 797 |
| 804 // ----------------------------------------------------------------------------- | 798 // ----------------------------------------------------------------------------- |
| 805 // JSAdd | 799 // JSAdd |
| 806 | 800 |
| 807 | 801 |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 EmptyFrameState(), effect, control)); | 993 EmptyFrameState(), effect, control)); |
| 1000 ASSERT_TRUE(r.Changed()); | 994 ASSERT_TRUE(r.Changed()); |
| 1001 EXPECT_THAT(r.replacement(), IsSpeculativeNumberBitwiseXor( | 995 EXPECT_THAT(r.replacement(), IsSpeculativeNumberBitwiseXor( |
| 1002 NumberOperationHint::kNumberOrOddball, lhs, | 996 NumberOperationHint::kNumberOrOddball, lhs, |
| 1003 rhs, effect, control)); | 997 rhs, effect, control)); |
| 1004 } | 998 } |
| 1005 | 999 |
| 1006 } // namespace compiler | 1000 } // namespace compiler |
| 1007 } // namespace internal | 1001 } // namespace internal |
| 1008 } // namespace v8 | 1002 } // namespace v8 |
| OLD | NEW |