Chromium Code Reviews| 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 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 | 673 |
| 674 Node* map = LoadMap(object); | 674 Node* map = LoadMap(object); |
| 675 | 675 |
| 676 // Bailout if instance type is not JS_ARRAY_TYPE. | 676 // Bailout if instance type is not JS_ARRAY_TYPE. |
| 677 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), | 677 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), |
| 678 if_false); | 678 if_false); |
| 679 | 679 |
| 680 Node* elements_kind = LoadMapElementsKind(map); | 680 Node* elements_kind = LoadMapElementsKind(map); |
| 681 | 681 |
| 682 // Bailout if receiver has slow elements. | 682 // Bailout if receiver has slow elements. |
| 683 GotoIf( | 683 GotoUnless(IsFastElementsKind(elements_kind), if_false); |
|
Benedikt Meurer
2016/11/09 20:00:32
Nice!
| |
| 684 Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)), | |
| 685 if_false); | |
| 686 | 684 |
| 687 // Check prototype chain if receiver does not have packed elements. | 685 // Check prototype chain if receiver does not have packed elements. |
| 688 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); | 686 GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true); |
| 689 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); | 687 |
| 690 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); | |
| 691 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); | |
| 692 GotoIf(Word32Equal(holey_elements, Int32Constant(0)), if_true); | |
| 693 BranchIfPrototypesHaveNoElements(map, if_true, if_false); | 688 BranchIfPrototypesHaveNoElements(map, if_true, if_false); |
| 694 } | 689 } |
| 695 | 690 |
| 696 Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes, | 691 Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes, |
| 697 AllocationFlags flags, | 692 AllocationFlags flags, |
| 698 Node* top_address, | 693 Node* top_address, |
| 699 Node* limit_address) { | 694 Node* limit_address) { |
| 700 Node* top = Load(MachineType::Pointer(), top_address); | 695 Node* top = Load(MachineType::Pointer(), top_address); |
| 701 Node* limit = Load(MachineType::Pointer(), limit_address); | 696 Node* limit = Load(MachineType::Pointer(), limit_address); |
| 702 | 697 |
| (...skipping 8000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8703 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), | 8698 Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |
| 8704 &if_istypedarray, &if_isgeneric); | 8699 &if_istypedarray, &if_isgeneric); |
| 8705 | 8700 |
| 8706 Bind(&if_isgeneric); | 8701 Bind(&if_isgeneric); |
| 8707 { | 8702 { |
| 8708 Label if_isfast(this), if_isslow(this); | 8703 Label if_isfast(this), if_isslow(this); |
| 8709 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); | 8704 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); |
| 8710 | 8705 |
| 8711 Bind(&if_isfast); | 8706 Bind(&if_isfast); |
| 8712 { | 8707 { |
| 8713 Node* map_index = | 8708 Label if_ispacked(this), if_isholey(this); |
| 8714 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), | 8709 Node* elements_kind = LoadMapElementsKind(array_map); |
| 8715 LoadMapElementsKind(array_map)); | 8710 Branch(IsHoleyFastElementsKind(elements_kind), &if_isholey, |
| 8716 CSA_ASSERT(IntPtrGreaterThanOrEqual( | 8711 &if_ispacked); |
| 8717 map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset))); | |
| 8718 CSA_ASSERT(IntPtrLessThan( | |
| 8719 map_index, IntPtrConstant(kBaseMapIndex + kSlowIteratorOffset))); | |
| 8720 | 8712 |
| 8721 var_map_index.Bind(map_index); | 8713 Bind(&if_isholey); |
| 8722 var_array_map.Bind(array_map); | 8714 { |
| 8723 Goto(&allocate_iterator); | 8715 // Fast holey JSArrays can treat the hole as undefined if the |
| 8716 // protector cell is valid, and the prototype chain is unchanged from | |
| 8717 // its initial state (because the protector cell is only tracked for | |
| 8718 // initial the Array and Object prototypes). Check these conditions | |
| 8719 // here, and take the slow path if any fail. | |
| 8720 Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); | |
| 8721 DCHECK(isolate()->heap()->array_protector()->IsPropertyCell()); | |
| 8722 GotoUnless( | |
| 8723 WordEqual( | |
| 8724 LoadObjectField(protector_cell, PropertyCell::kValueOffset), | |
| 8725 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), | |
| 8726 &if_isslow); | |
| 8727 | |
| 8728 Node* native_context = LoadNativeContext(context); | |
| 8729 | |
| 8730 Node* prototype = LoadMapPrototype(array_map); | |
| 8731 Node* array_prototype = LoadContextElement( | |
| 8732 native_context, Context::INITIAL_ARRAY_PROTOTYPE_INDEX); | |
| 8733 GotoUnless(WordEqual(prototype, array_prototype), &if_isslow); | |
| 8734 | |
| 8735 Node* map = LoadMap(prototype); | |
| 8736 prototype = LoadMapPrototype(map); | |
| 8737 Node* object_prototype = LoadContextElement( | |
| 8738 native_context, Context::INITIAL_OBJECT_PROTOTYPE_INDEX); | |
| 8739 GotoUnless(WordEqual(prototype, object_prototype), &if_isslow); | |
| 8740 | |
| 8741 map = LoadMap(prototype); | |
| 8742 prototype = LoadMapPrototype(map); | |
| 8743 Branch(IsNull(prototype), &if_ispacked, &if_isslow); | |
| 8744 } | |
| 8745 Bind(&if_ispacked); | |
| 8746 { | |
| 8747 Node* map_index = | |
| 8748 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), | |
| 8749 LoadMapElementsKind(array_map)); | |
| 8750 CSA_ASSERT(IntPtrGreaterThanOrEqual( | |
| 8751 map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset))); | |
| 8752 CSA_ASSERT(IntPtrLessThan( | |
| 8753 map_index, IntPtrConstant(kBaseMapIndex + kSlowIteratorOffset))); | |
| 8754 | |
| 8755 var_map_index.Bind(map_index); | |
| 8756 var_array_map.Bind(array_map); | |
| 8757 Goto(&allocate_iterator); | |
| 8758 } | |
| 8724 } | 8759 } |
| 8725 | 8760 |
| 8726 Bind(&if_isslow); | 8761 Bind(&if_isslow); |
| 8727 { | 8762 { |
| 8728 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), | 8763 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), |
| 8729 IntPtrConstant(kSlowIteratorOffset)); | 8764 IntPtrConstant(kSlowIteratorOffset)); |
| 8730 var_map_index.Bind(map_index); | 8765 var_map_index.Bind(map_index); |
| 8731 var_array_map.Bind(UndefinedConstant()); | 8766 var_array_map.Bind(UndefinedConstant()); |
| 8732 Goto(&allocate_iterator); | 8767 Goto(&allocate_iterator); |
| 8733 } | 8768 } |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8853 }, | 8888 }, |
| 8854 -kPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); | 8889 -kPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); |
| 8855 } | 8890 } |
| 8856 | 8891 |
| 8857 void CodeStubArguments::PopAndReturn(compiler::Node* value) { | 8892 void CodeStubArguments::PopAndReturn(compiler::Node* value) { |
| 8858 assembler_->PopAndReturn( | 8893 assembler_->PopAndReturn( |
| 8859 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), | 8894 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), |
| 8860 value); | 8895 value); |
| 8861 } | 8896 } |
| 8862 | 8897 |
| 8898 compiler::Node* CodeStubAssembler::IsFastElementsKind( | |
| 8899 compiler::Node* elements_kind) { | |
| 8900 return Uint32LessThanOrEqual(elements_kind, | |
| 8901 Int32Constant(LAST_FAST_ELEMENTS_KIND)); | |
| 8902 } | |
| 8903 | |
| 8904 compiler::Node* CodeStubAssembler::IsHoleyFastElementsKind( | |
| 8905 compiler::Node* elements_kind) { | |
| 8906 CSA_ASSERT(IsFastElementsKind(elements_kind)); | |
| 8907 | |
| 8908 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); | |
| 8909 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); | |
| 8910 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); | |
| 8911 | |
| 8912 // Check prototype chain if receiver does not have packed elements. | |
| 8913 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); | |
| 8914 return Word32Equal(holey_elements, Int32Constant(1)); | |
| 8915 } | |
| 8916 | |
| 8863 } // namespace internal | 8917 } // namespace internal |
| 8864 } // namespace v8 | 8918 } // namespace v8 |
| OLD | NEW |