OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 5024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5035 | 5035 |
5036 // static | 5036 // static |
5037 compiler::Node* FastCloneShallowObjectStub::GenerateFastPath( | 5037 compiler::Node* FastCloneShallowObjectStub::GenerateFastPath( |
5038 CodeStubAssembler* assembler, compiler::CodeAssembler::Label* call_runtime, | 5038 CodeStubAssembler* assembler, compiler::CodeAssembler::Label* call_runtime, |
5039 compiler::Node* closure, compiler::Node* literals_index, | 5039 compiler::Node* closure, compiler::Node* literals_index, |
5040 compiler::Node* properties_count) { | 5040 compiler::Node* properties_count) { |
5041 typedef compiler::Node Node; | 5041 typedef compiler::Node Node; |
5042 typedef compiler::CodeAssembler::Label Label; | 5042 typedef compiler::CodeAssembler::Label Label; |
5043 typedef compiler::CodeAssembler::Variable Variable; | 5043 typedef compiler::CodeAssembler::Variable Variable; |
5044 | 5044 |
5045 Node* undefined = assembler->UndefinedConstant(); | |
5046 Node* literals_array = | 5045 Node* literals_array = |
5047 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset); | 5046 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset); |
5048 Node* allocation_site = assembler->LoadFixedArrayElement( | 5047 Node* allocation_site = assembler->LoadFixedArrayElement( |
5049 literals_array, literals_index, | 5048 literals_array, literals_index, |
5050 LiteralsArray::kFirstLiteralIndex * kPointerSize, | 5049 LiteralsArray::kFirstLiteralIndex * kPointerSize, |
5051 CodeStubAssembler::SMI_PARAMETERS); | 5050 CodeStubAssembler::SMI_PARAMETERS); |
5051 Node* undefined = assembler->UndefinedConstant(); | |
5052 assembler->GotoIf(assembler->WordEqual(allocation_site, undefined), | 5052 assembler->GotoIf(assembler->WordEqual(allocation_site, undefined), |
5053 call_runtime); | 5053 call_runtime); |
5054 | 5054 |
5055 // Calculate the object and allocation size based on the properties count. | 5055 // Calculate the object and allocation size based on the properties count. |
5056 Node* object_size = assembler->IntPtrAdd( | 5056 Node* object_size = assembler->IntPtrAdd( |
5057 assembler->WordShl(properties_count, kPointerSizeLog2), | 5057 assembler->WordShl(properties_count, kPointerSizeLog2), |
5058 assembler->IntPtrConstant(JSObject::kHeaderSize)); | 5058 assembler->IntPtrConstant(JSObject::kHeaderSize)); |
5059 Node* allocation_size = object_size; | 5059 Node* allocation_size = object_size; |
5060 if (FLAG_allocation_site_pretenuring) { | 5060 if (FLAG_allocation_site_pretenuring) { |
5061 allocation_size = assembler->IntPtrAdd( | 5061 allocation_size = assembler->IntPtrAdd( |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5222 } | 5222 } |
5223 } | 5223 } |
5224 | 5224 |
5225 | 5225 |
5226 void NumberToStringStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { | 5226 void NumberToStringStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { |
5227 descriptor->Initialize( | 5227 descriptor->Initialize( |
5228 Runtime::FunctionForId(Runtime::kNumberToString)->entry); | 5228 Runtime::FunctionForId(Runtime::kNumberToString)->entry); |
5229 descriptor->SetMissHandler(Runtime::kNumberToString); | 5229 descriptor->SetMissHandler(Runtime::kNumberToString); |
5230 } | 5230 } |
5231 | 5231 |
5232 | |
5233 void FastCloneShallowArrayStub::InitializeDescriptor( | |
5234 CodeStubDescriptor* descriptor) { | |
5235 FastCloneShallowArrayDescriptor call_descriptor(isolate()); | |
5236 descriptor->Initialize( | |
5237 Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry); | |
5238 descriptor->SetMissHandler(Runtime::kCreateArrayLiteralStubBailout); | |
5239 } | |
5240 | |
5241 void RegExpConstructResultStub::InitializeDescriptor( | 5232 void RegExpConstructResultStub::InitializeDescriptor( |
5242 CodeStubDescriptor* descriptor) { | 5233 CodeStubDescriptor* descriptor) { |
5243 descriptor->Initialize( | 5234 descriptor->Initialize( |
5244 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); | 5235 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); |
5245 descriptor->SetMissHandler(Runtime::kRegExpConstructResult); | 5236 descriptor->SetMissHandler(Runtime::kRegExpConstructResult); |
5246 } | 5237 } |
5247 | 5238 |
5248 | 5239 |
5249 void TransitionElementsKindStub::InitializeDescriptor( | 5240 void TransitionElementsKindStub::InitializeDescriptor( |
5250 CodeStubDescriptor* descriptor) { | 5241 CodeStubDescriptor* descriptor) { |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5739 Node* closure = assembler->Parameter(Descriptor::kClosure); | 5730 Node* closure = assembler->Parameter(Descriptor::kClosure); |
5740 Node* literal_index = assembler->Parameter(Descriptor::kLiteralIndex); | 5731 Node* literal_index = assembler->Parameter(Descriptor::kLiteralIndex); |
5741 Node* pattern = assembler->Parameter(Descriptor::kPattern); | 5732 Node* pattern = assembler->Parameter(Descriptor::kPattern); |
5742 Node* flags = assembler->Parameter(Descriptor::kFlags); | 5733 Node* flags = assembler->Parameter(Descriptor::kFlags); |
5743 Node* context = assembler->Parameter(Descriptor::kContext); | 5734 Node* context = assembler->Parameter(Descriptor::kContext); |
5744 | 5735 |
5745 assembler->Return( | 5736 assembler->Return( |
5746 Generate(assembler, closure, literal_index, pattern, flags, context)); | 5737 Generate(assembler, closure, literal_index, pattern, flags, context)); |
5747 } | 5738 } |
5748 | 5739 |
5740 namespace { | |
5741 | |
5742 compiler::Node* NonEmptyShallowClone(CodeStubAssembler* assembler, | |
5743 compiler::Node* boilerplate, | |
5744 compiler::Node* boilerplate_map, | |
5745 compiler::Node* boilerplate_elements, | |
5746 compiler::Node* allocation_site, | |
5747 compiler::Node* capacity, | |
5748 ElementsKind kind) { | |
5749 typedef compiler::Node Node; | |
5750 typedef CodeStubAssembler::ParameterMode ParameterMode; | |
5751 | |
5752 ParameterMode param_mode = CodeStubAssembler::SMI_PARAMETERS; | |
5753 | |
5754 Node* length = assembler->LoadJSArrayLength(boilerplate); | |
5755 | |
5756 if (assembler->Is64()) { | |
5757 capacity = assembler->SmiUntag(capacity); | |
5758 param_mode = CodeStubAssembler::INTEGER_PARAMETERS; | |
5759 } | |
5760 | |
5761 Node *array, *elements; | |
5762 std::tie(array, elements) = | |
5763 assembler->AllocateUninitializedJSArrayWithElements( | |
5764 kind, boilerplate_map, length, allocation_site, capacity, param_mode); | |
5765 | |
5766 assembler->Comment("copy elements header"); | |
5767 for (int offset = 0; offset < FixedArrayBase::kHeaderSize; | |
5768 offset += kPointerSize) { | |
5769 Node* value = assembler->LoadObjectField(boilerplate_elements, offset); | |
5770 assembler->StoreObjectField(elements, offset, value); | |
5771 } | |
5772 | |
5773 if (assembler->Is64()) { | |
5774 length = assembler->SmiUntag(length); | |
5775 } | |
5776 | |
5777 assembler->Comment("copy boilerplate elements"); | |
5778 assembler->CopyFixedArrayElements(kind, boilerplate_elements, elements, | |
5779 length, SKIP_WRITE_BARRIER, param_mode); | |
5780 assembler->IncrementCounter( | |
5781 assembler->isolate()->counters()->inlined_copied_elements(), 1); | |
5782 | |
5783 return array; | |
5784 } | |
5785 | |
5786 } // namespace | |
5787 | |
5788 // static | |
5789 compiler::Node* FastCloneShallowArrayStub::Generate( | |
5790 CodeStubAssembler* assembler, compiler::Node* closure, | |
5791 compiler::Node* literal_index, compiler::Node* constant_elements, | |
5792 compiler::Node* context, AllocationSiteMode allocation_site_mode) { | |
5793 typedef CodeStubAssembler::Label Label; | |
5794 typedef CodeStubAssembler::Variable Variable; | |
5795 typedef compiler::Node Node; | |
5796 | |
5797 Label call_runtime(assembler, Label::kDeferred), zero_capacity(assembler), | |
5798 cow_elements(assembler), fast_elements(assembler), | |
5799 return_result(assembler); | |
5800 Variable result(assembler, MachineRepresentation::kTagged); | |
5801 | |
5802 Node* literals_array = | |
5803 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset); | |
5804 Node* allocation_site = assembler->LoadFixedArrayElement( | |
5805 literals_array, literal_index, | |
5806 LiteralsArray::kFirstLiteralIndex * kPointerSize, | |
5807 CodeStubAssembler::SMI_PARAMETERS); | |
5808 | |
5809 Node* undefined = assembler->UndefinedConstant(); | |
5810 assembler->GotoIf(assembler->WordEqual(allocation_site, undefined), | |
5811 &call_runtime); | |
5812 allocation_site = assembler->LoadFixedArrayElement( | |
5813 literals_array, literal_index, | |
5814 LiteralsArray::kFirstLiteralIndex * kPointerSize, | |
5815 CodeStubAssembler::SMI_PARAMETERS); | |
klaasb
2016/09/19 18:39:25
This live range breaking allows the TF instruction
| |
5816 | |
5817 Node* boilerplate = assembler->LoadObjectField( | |
5818 allocation_site, AllocationSite::kTransitionInfoOffset); | |
5819 Node* boilerplate_map = assembler->LoadMap(boilerplate); | |
5820 Node* boilerplate_elements = assembler->LoadElements(boilerplate); | |
5821 Node* capacity = assembler->LoadFixedArrayBaseLength(boilerplate_elements); | |
5822 allocation_site = | |
5823 allocation_site_mode == TRACK_ALLOCATION_SITE ? allocation_site : nullptr; | |
5824 | |
5825 Node* zero = assembler->SmiConstant(Smi::FromInt(0)); | |
5826 assembler->GotoIf(assembler->SmiEqual(capacity, zero), &zero_capacity); | |
5827 | |
5828 Node* elements_map = assembler->LoadMap(boilerplate_elements); | |
5829 assembler->GotoIf( | |
5830 assembler->WordEqual(elements_map, assembler->FixedCowArrayMapConstant()), | |
5831 &cow_elements); | |
5832 | |
5833 assembler->GotoIf( | |
5834 assembler->WordEqual(elements_map, assembler->FixedArrayMapConstant()), | |
5835 &fast_elements); | |
5836 { | |
5837 assembler->Comment("fast double elements path"); | |
5838 if (FLAG_debug_code) { | |
5839 Label correct_elements_map(assembler), abort(assembler, Label::kDeferred); | |
5840 assembler->BranchIf( | |
5841 assembler->WordEqual(elements_map, | |
5842 assembler->FixedDoubleArrayMapConstant()), | |
5843 &correct_elements_map, &abort); | |
5844 | |
5845 assembler->Bind(&abort); | |
5846 { | |
5847 Node* abort_id = assembler->SmiConstant( | |
5848 Smi::FromInt(BailoutReason::kExpectedFixedDoubleArrayMap)); | |
5849 assembler->TailCallRuntime(Runtime::kAbort, context, abort_id); | |
5850 } | |
5851 assembler->Bind(&correct_elements_map); | |
5852 } | |
5853 | |
5854 Node* array = NonEmptyShallowClone(assembler, boilerplate, boilerplate_map, | |
5855 boilerplate_elements, allocation_site, | |
5856 capacity, FAST_DOUBLE_ELEMENTS); | |
5857 result.Bind(array); | |
5858 assembler->Goto(&return_result); | |
5859 } | |
5860 | |
5861 assembler->Bind(&fast_elements); | |
5862 { | |
5863 assembler->Comment("fast elements path"); | |
5864 Node* array = NonEmptyShallowClone(assembler, boilerplate, boilerplate_map, | |
5865 boilerplate_elements, allocation_site, | |
5866 capacity, FAST_ELEMENTS); | |
5867 result.Bind(array); | |
5868 assembler->Goto(&return_result); | |
5869 } | |
5870 | |
5871 Variable length(assembler, MachineRepresentation::kTagged), | |
5872 elements(assembler, MachineRepresentation::kTagged); | |
5873 Label allocate_without_elements(assembler); | |
5874 | |
5875 assembler->Bind(&cow_elements); | |
5876 { | |
5877 assembler->Comment("fixed cow path"); | |
5878 length.Bind(assembler->LoadJSArrayLength(boilerplate)); | |
5879 elements.Bind(boilerplate_elements); | |
5880 | |
5881 assembler->Goto(&allocate_without_elements); | |
5882 } | |
5883 | |
5884 assembler->Bind(&zero_capacity); | |
5885 { | |
5886 assembler->Comment("zero capacity path"); | |
5887 length.Bind(zero); | |
5888 elements.Bind(assembler->LoadRoot(Heap::kEmptyFixedArrayRootIndex)); | |
5889 | |
5890 assembler->Goto(&allocate_without_elements); | |
5891 } | |
5892 | |
5893 assembler->Bind(&allocate_without_elements); | |
5894 { | |
5895 Node* array = assembler->AllocateUninitializedJSArrayWithoutElements( | |
5896 FAST_ELEMENTS, boilerplate_map, length.value(), allocation_site); | |
5897 assembler->StoreObjectField(array, JSObject::kElementsOffset, | |
5898 elements.value()); | |
5899 result.Bind(array); | |
5900 assembler->Goto(&return_result); | |
5901 } | |
5902 | |
5903 assembler->Bind(&call_runtime); | |
5904 { | |
5905 assembler->Comment("call runtime"); | |
5906 Node* flags = assembler->SmiConstant( | |
5907 Smi::FromInt(ArrayLiteral::kShallowElements | | |
5908 (allocation_site_mode == TRACK_ALLOCATION_SITE | |
5909 ? 0 | |
5910 : ArrayLiteral::kDisableMementos))); | |
5911 Node* array = | |
5912 assembler->CallRuntime(Runtime::kCreateArrayLiteral, context, closure, | |
5913 literal_index, constant_elements, flags); | |
5914 result.Bind(array); | |
5915 assembler->Goto(&return_result); | |
5916 } | |
5917 | |
5918 assembler->Bind(&return_result); | |
5919 return result.value(); | |
5920 } | |
5921 | |
5922 void FastCloneShallowArrayStub::GenerateAssembly( | |
5923 CodeStubAssembler* assembler) const { | |
5924 typedef compiler::Node Node; | |
5925 Node* closure = assembler->Parameter(Descriptor::kClosure); | |
5926 Node* literal_index = assembler->Parameter(Descriptor::kLiteralIndex); | |
5927 Node* constant_elements = assembler->Parameter(Descriptor::kConstantElements); | |
5928 Node* context = assembler->Parameter(Descriptor::kContext); | |
5929 | |
5930 assembler->Return(Generate(assembler, closure, literal_index, | |
5931 constant_elements, context, | |
5932 allocation_site_mode())); | |
5933 } | |
5934 | |
5749 void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) { | 5935 void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) { |
5750 CreateAllocationSiteStub stub(isolate); | 5936 CreateAllocationSiteStub stub(isolate); |
5751 stub.GetCode(); | 5937 stub.GetCode(); |
5752 } | 5938 } |
5753 | 5939 |
5754 | 5940 |
5755 void CreateWeakCellStub::GenerateAheadOfTime(Isolate* isolate) { | 5941 void CreateWeakCellStub::GenerateAheadOfTime(Isolate* isolate) { |
5756 CreateWeakCellStub stub(isolate); | 5942 CreateWeakCellStub stub(isolate); |
5757 stub.GetCode(); | 5943 stub.GetCode(); |
5758 } | 5944 } |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5944 AllocationSite::GetMode(elements_kind()) == TRACK_ALLOCATION_SITE && | 6130 AllocationSite::GetMode(elements_kind()) == TRACK_ALLOCATION_SITE && |
5945 override_mode() != DISABLE_ALLOCATION_SITES; | 6131 override_mode() != DISABLE_ALLOCATION_SITES; |
5946 Node* allocation_site = | 6132 Node* allocation_site = |
5947 track_allocation_site ? assembler->Parameter(Descriptor::kAllocationSite) | 6133 track_allocation_site ? assembler->Parameter(Descriptor::kAllocationSite) |
5948 : nullptr; | 6134 : nullptr; |
5949 Node* array_map = | 6135 Node* array_map = |
5950 assembler->LoadJSArrayElementsMap(elements_kind(), native_context); | 6136 assembler->LoadJSArrayElementsMap(elements_kind(), native_context); |
5951 Node* array = assembler->AllocateJSArray( | 6137 Node* array = assembler->AllocateJSArray( |
5952 elements_kind(), array_map, | 6138 elements_kind(), array_map, |
5953 assembler->IntPtrConstant(JSArray::kPreallocatedArrayElements), | 6139 assembler->IntPtrConstant(JSArray::kPreallocatedArrayElements), |
5954 assembler->IntPtrConstant(0), allocation_site); | 6140 assembler->SmiConstant(Smi::FromInt(0)), allocation_site); |
5955 assembler->Return(array); | 6141 assembler->Return(array); |
5956 } | 6142 } |
5957 | 6143 |
5958 void InternalArrayNoArgumentConstructorStub::GenerateAssembly( | 6144 void InternalArrayNoArgumentConstructorStub::GenerateAssembly( |
5959 CodeStubAssembler* assembler) const { | 6145 CodeStubAssembler* assembler) const { |
5960 typedef compiler::Node Node; | 6146 typedef compiler::Node Node; |
5961 Node* array_map = | 6147 Node* array_map = |
5962 assembler->LoadObjectField(assembler->Parameter(Descriptor::kFunction), | 6148 assembler->LoadObjectField(assembler->Parameter(Descriptor::kFunction), |
5963 JSFunction::kPrototypeOrInitialMapOffset); | 6149 JSFunction::kPrototypeOrInitialMapOffset); |
5964 Node* array = assembler->AllocateJSArray( | 6150 Node* array = assembler->AllocateJSArray( |
5965 elements_kind(), array_map, | 6151 elements_kind(), array_map, |
5966 assembler->IntPtrConstant(JSArray::kPreallocatedArrayElements), | 6152 assembler->IntPtrConstant(JSArray::kPreallocatedArrayElements), |
5967 assembler->IntPtrConstant(0), nullptr); | 6153 assembler->SmiConstant(Smi::FromInt(0)), nullptr); |
5968 assembler->Return(array); | 6154 assembler->Return(array); |
5969 } | 6155 } |
5970 | 6156 |
5971 namespace { | 6157 namespace { |
5972 | 6158 |
5973 template <typename Descriptor> | 6159 template <typename Descriptor> |
5974 void SingleArgumentConstructorCommon(CodeStubAssembler* assembler, | 6160 void SingleArgumentConstructorCommon(CodeStubAssembler* assembler, |
5975 ElementsKind elements_kind, | 6161 ElementsKind elements_kind, |
5976 compiler::Node* array_map, | 6162 compiler::Node* array_map, |
5977 compiler::Node* allocation_site, | 6163 compiler::Node* allocation_site, |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6124 | 6310 |
6125 if (type == MachineType::Pointer()) { | 6311 if (type == MachineType::Pointer()) { |
6126 return Representation::External(); | 6312 return Representation::External(); |
6127 } | 6313 } |
6128 | 6314 |
6129 return Representation::Tagged(); | 6315 return Representation::Tagged(); |
6130 } | 6316 } |
6131 | 6317 |
6132 } // namespace internal | 6318 } // namespace internal |
6133 } // namespace v8 | 6319 } // namespace v8 |
OLD | NEW |