Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Side by Side Diff: src/code-stubs.cc

Issue 2304573004: Port FastCloneShallowArrayStub to Turbofan (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: break live range of allocation_site so instruction selection uses nice addressing modes Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/code-stubs.h ('k') | src/code-stubs-hydrogen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/code-stubs-hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698