OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 #include "src/ic/handler-configuration.h" | 8 #include "src/ic/handler-configuration.h" |
9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
10 | 10 |
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 | 674 |
675 Node* map = LoadMap(object); | 675 Node* map = LoadMap(object); |
676 | 676 |
677 // Bailout if instance type is not JS_ARRAY_TYPE. | 677 // Bailout if instance type is not JS_ARRAY_TYPE. |
678 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), | 678 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), |
679 if_false); | 679 if_false); |
680 | 680 |
681 Node* elements_kind = LoadMapElementsKind(map); | 681 Node* elements_kind = LoadMapElementsKind(map); |
682 | 682 |
683 // Bailout if receiver has slow elements. | 683 // Bailout if receiver has slow elements. |
684 GotoIf( | 684 GotoUnless(IsFastElementsKind(elements_kind), if_false); |
685 Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)), | |
686 if_false); | |
687 | 685 |
688 // Check prototype chain if receiver does not have packed elements. | 686 // Check prototype chain if receiver does not have packed elements. |
689 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); | 687 GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true); |
690 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); | 688 |
691 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); | |
692 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); | |
693 GotoIf(Word32Equal(holey_elements, Int32Constant(0)), if_true); | |
694 BranchIfPrototypesHaveNoElements(map, if_true, if_false); | 689 BranchIfPrototypesHaveNoElements(map, if_true, if_false); |
695 } | 690 } |
696 | 691 |
697 Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes, | 692 Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes, |
698 AllocationFlags flags, | 693 AllocationFlags flags, |
699 Node* top_address, | 694 Node* top_address, |
700 Node* limit_address) { | 695 Node* limit_address) { |
701 Node* top = Load(MachineType::Pointer(), top_address); | 696 Node* top = Load(MachineType::Pointer(), top_address); |
702 Node* limit = Load(MachineType::Pointer(), limit_address); | 697 Node* limit = Load(MachineType::Pointer(), limit_address); |
703 | 698 |
(...skipping 8051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8755 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), | 8750 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |
8756 &if_istypedarray, &if_isgeneric); | 8751 &if_istypedarray, &if_isgeneric); |
8757 | 8752 |
8758 Bind(&if_isgeneric); | 8753 Bind(&if_isgeneric); |
8759 { | 8754 { |
8760 Label if_isfast(this), if_isslow(this); | 8755 Label if_isfast(this), if_isslow(this); |
8761 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); | 8756 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); |
8762 | 8757 |
8763 Bind(&if_isfast); | 8758 Bind(&if_isfast); |
8764 { | 8759 { |
8765 Node* map_index = | 8760 Label if_ispacked(this), if_isholey(this); |
8766 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), | 8761 Node* elements_kind = LoadMapElementsKind(array_map); |
8767 LoadMapElementsKind(array_map)); | 8762 Branch(IsHoleyFastElementsKind(elements_kind), &if_isholey, |
8768 CSA_ASSERT(this, IntPtrGreaterThanOrEqual( | 8763 &if_ispacked); |
8769 map_index, IntPtrConstant(kBaseMapIndex + | |
8770 kFastIteratorOffset))); | |
8771 CSA_ASSERT(this, IntPtrLessThan(map_index, | |
8772 IntPtrConstant(kBaseMapIndex + | |
8773 kSlowIteratorOffset))); | |
8774 | 8764 |
8775 var_map_index.Bind(map_index); | 8765 Bind(&if_isholey); |
8776 var_array_map.Bind(array_map); | 8766 { |
8777 Goto(&allocate_iterator); | 8767 // Fast holey JSArrays can treat the hole as undefined if the |
| 8768 // protector cell is valid, and the prototype chain is unchanged from |
| 8769 // its initial state (because the protector cell is only tracked for |
| 8770 // initial the Array and Object prototypes). Check these conditions |
| 8771 // here, and take the slow path if any fail. |
| 8772 Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); |
| 8773 DCHECK(isolate()->heap()->array_protector()->IsPropertyCell()); |
| 8774 GotoUnless( |
| 8775 WordEqual( |
| 8776 LoadObjectField(protector_cell, PropertyCell::kValueOffset), |
| 8777 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), |
| 8778 &if_isslow); |
| 8779 |
| 8780 Node* native_context = LoadNativeContext(context); |
| 8781 |
| 8782 Node* prototype = LoadMapPrototype(array_map); |
| 8783 Node* array_prototype = LoadContextElement( |
| 8784 native_context, Context::INITIAL_ARRAY_PROTOTYPE_INDEX); |
| 8785 GotoUnless(WordEqual(prototype, array_prototype), &if_isslow); |
| 8786 |
| 8787 Node* map = LoadMap(prototype); |
| 8788 prototype = LoadMapPrototype(map); |
| 8789 Node* object_prototype = LoadContextElement( |
| 8790 native_context, Context::INITIAL_OBJECT_PROTOTYPE_INDEX); |
| 8791 GotoUnless(WordEqual(prototype, object_prototype), &if_isslow); |
| 8792 |
| 8793 map = LoadMap(prototype); |
| 8794 prototype = LoadMapPrototype(map); |
| 8795 Branch(IsNull(prototype), &if_ispacked, &if_isslow); |
| 8796 } |
| 8797 Bind(&if_ispacked); |
| 8798 { |
| 8799 Node* map_index = |
| 8800 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), |
| 8801 LoadMapElementsKind(array_map)); |
| 8802 CSA_ASSERT(this, IntPtrGreaterThanOrEqual( |
| 8803 map_index, IntPtrConstant(kBaseMapIndex + |
| 8804 kFastIteratorOffset))); |
| 8805 CSA_ASSERT(this, IntPtrLessThan(map_index, |
| 8806 IntPtrConstant(kBaseMapIndex + |
| 8807 kSlowIteratorOffset))); |
| 8808 |
| 8809 var_map_index.Bind(map_index); |
| 8810 var_array_map.Bind(array_map); |
| 8811 Goto(&allocate_iterator); |
| 8812 } |
8778 } | 8813 } |
8779 | 8814 |
8780 Bind(&if_isslow); | 8815 Bind(&if_isslow); |
8781 { | 8816 { |
8782 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), | 8817 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), |
8783 IntPtrConstant(kSlowIteratorOffset)); | 8818 IntPtrConstant(kSlowIteratorOffset)); |
8784 var_map_index.Bind(map_index); | 8819 var_map_index.Bind(map_index); |
8785 var_array_map.Bind(UndefinedConstant()); | 8820 var_array_map.Bind(UndefinedConstant()); |
8786 Goto(&allocate_iterator); | 8821 Goto(&allocate_iterator); |
8787 } | 8822 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8908 }, | 8943 }, |
8909 -kPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); | 8944 -kPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); |
8910 } | 8945 } |
8911 | 8946 |
8912 void CodeStubArguments::PopAndReturn(compiler::Node* value) { | 8947 void CodeStubArguments::PopAndReturn(compiler::Node* value) { |
8913 assembler_->PopAndReturn( | 8948 assembler_->PopAndReturn( |
8914 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), | 8949 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), |
8915 value); | 8950 value); |
8916 } | 8951 } |
8917 | 8952 |
| 8953 compiler::Node* CodeStubAssembler::IsFastElementsKind( |
| 8954 compiler::Node* elements_kind) { |
| 8955 return Uint32LessThanOrEqual(elements_kind, |
| 8956 Int32Constant(LAST_FAST_ELEMENTS_KIND)); |
| 8957 } |
| 8958 |
| 8959 compiler::Node* CodeStubAssembler::IsHoleyFastElementsKind( |
| 8960 compiler::Node* elements_kind) { |
| 8961 CSA_ASSERT(this, IsFastElementsKind(elements_kind)); |
| 8962 |
| 8963 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); |
| 8964 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); |
| 8965 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); |
| 8966 |
| 8967 // Check prototype chain if receiver does not have packed elements. |
| 8968 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); |
| 8969 return Word32Equal(holey_elements, Int32Constant(1)); |
| 8970 } |
| 8971 |
8918 } // namespace internal | 8972 } // namespace internal |
8919 } // namespace v8 | 8973 } // namespace v8 |
OLD | NEW |