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 8187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8891 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), | 8886 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |
8892 &if_istypedarray, &if_isgeneric); | 8887 &if_istypedarray, &if_isgeneric); |
8893 | 8888 |
8894 Bind(&if_isgeneric); | 8889 Bind(&if_isgeneric); |
8895 { | 8890 { |
8896 Label if_isfast(this), if_isslow(this); | 8891 Label if_isfast(this), if_isslow(this); |
8897 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); | 8892 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); |
8898 | 8893 |
8899 Bind(&if_isfast); | 8894 Bind(&if_isfast); |
8900 { | 8895 { |
8901 Node* map_index = | 8896 Label if_ispacked(this), if_isholey(this); |
8902 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), | 8897 Node* elements_kind = LoadMapElementsKind(array_map); |
8903 LoadMapElementsKind(array_map)); | 8898 Branch(IsHoleyFastElementsKind(elements_kind), &if_isholey, |
8904 CSA_ASSERT(this, IntPtrGreaterThanOrEqual( | 8899 &if_ispacked); |
8905 map_index, IntPtrConstant(kBaseMapIndex + | |
8906 kFastIteratorOffset))); | |
8907 CSA_ASSERT(this, IntPtrLessThan(map_index, | |
8908 IntPtrConstant(kBaseMapIndex + | |
8909 kSlowIteratorOffset))); | |
8910 | 8900 |
8911 var_map_index.Bind(map_index); | 8901 Bind(&if_isholey); |
8912 var_array_map.Bind(array_map); | 8902 { |
8913 Goto(&allocate_iterator); | 8903 // Fast holey JSArrays can treat the hole as undefined if the |
| 8904 // protector cell is valid, and the prototype chain is unchanged from |
| 8905 // its initial state (because the protector cell is only tracked for |
| 8906 // initial the Array and Object prototypes). Check these conditions |
| 8907 // here, and take the slow path if any fail. |
| 8908 Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); |
| 8909 DCHECK(isolate()->heap()->array_protector()->IsPropertyCell()); |
| 8910 GotoUnless( |
| 8911 WordEqual( |
| 8912 LoadObjectField(protector_cell, PropertyCell::kValueOffset), |
| 8913 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), |
| 8914 &if_isslow); |
| 8915 |
| 8916 Node* native_context = LoadNativeContext(context); |
| 8917 |
| 8918 Node* prototype = LoadMapPrototype(array_map); |
| 8919 Node* array_prototype = LoadContextElement( |
| 8920 native_context, Context::INITIAL_ARRAY_PROTOTYPE_INDEX); |
| 8921 GotoUnless(WordEqual(prototype, array_prototype), &if_isslow); |
| 8922 |
| 8923 Node* map = LoadMap(prototype); |
| 8924 prototype = LoadMapPrototype(map); |
| 8925 Node* object_prototype = LoadContextElement( |
| 8926 native_context, Context::INITIAL_OBJECT_PROTOTYPE_INDEX); |
| 8927 GotoUnless(WordEqual(prototype, object_prototype), &if_isslow); |
| 8928 |
| 8929 map = LoadMap(prototype); |
| 8930 prototype = LoadMapPrototype(map); |
| 8931 Branch(IsNull(prototype), &if_ispacked, &if_isslow); |
| 8932 } |
| 8933 Bind(&if_ispacked); |
| 8934 { |
| 8935 Node* map_index = |
| 8936 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), |
| 8937 LoadMapElementsKind(array_map)); |
| 8938 CSA_ASSERT(this, IntPtrGreaterThanOrEqual( |
| 8939 map_index, IntPtrConstant(kBaseMapIndex + |
| 8940 kFastIteratorOffset))); |
| 8941 CSA_ASSERT(this, IntPtrLessThan(map_index, |
| 8942 IntPtrConstant(kBaseMapIndex + |
| 8943 kSlowIteratorOffset))); |
| 8944 |
| 8945 var_map_index.Bind(map_index); |
| 8946 var_array_map.Bind(array_map); |
| 8947 Goto(&allocate_iterator); |
| 8948 } |
8914 } | 8949 } |
8915 | 8950 |
8916 Bind(&if_isslow); | 8951 Bind(&if_isslow); |
8917 { | 8952 { |
8918 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), | 8953 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), |
8919 IntPtrConstant(kSlowIteratorOffset)); | 8954 IntPtrConstant(kSlowIteratorOffset)); |
8920 var_map_index.Bind(map_index); | 8955 var_map_index.Bind(map_index); |
8921 var_array_map.Bind(UndefinedConstant()); | 8956 var_array_map.Bind(UndefinedConstant()); |
8922 Goto(&allocate_iterator); | 8957 Goto(&allocate_iterator); |
8923 } | 8958 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9044 }, | 9079 }, |
9045 -kPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); | 9080 -kPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); |
9046 } | 9081 } |
9047 | 9082 |
9048 void CodeStubArguments::PopAndReturn(compiler::Node* value) { | 9083 void CodeStubArguments::PopAndReturn(compiler::Node* value) { |
9049 assembler_->PopAndReturn( | 9084 assembler_->PopAndReturn( |
9050 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), | 9085 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), |
9051 value); | 9086 value); |
9052 } | 9087 } |
9053 | 9088 |
| 9089 compiler::Node* CodeStubAssembler::IsFastElementsKind( |
| 9090 compiler::Node* elements_kind) { |
| 9091 return Uint32LessThanOrEqual(elements_kind, |
| 9092 Int32Constant(LAST_FAST_ELEMENTS_KIND)); |
| 9093 } |
| 9094 |
| 9095 compiler::Node* CodeStubAssembler::IsHoleyFastElementsKind( |
| 9096 compiler::Node* elements_kind) { |
| 9097 CSA_ASSERT(this, IsFastElementsKind(elements_kind)); |
| 9098 |
| 9099 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); |
| 9100 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); |
| 9101 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); |
| 9102 |
| 9103 // Check prototype chain if receiver does not have packed elements. |
| 9104 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); |
| 9105 return Word32Equal(holey_elements, Int32Constant(1)); |
| 9106 } |
| 9107 |
9054 } // namespace internal | 9108 } // namespace internal |
9055 } // namespace v8 | 9109 } // namespace v8 |
OLD | NEW |