Chromium Code Reviews| 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 |