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 5128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5139 descriptor->Initialize( | 5139 descriptor->Initialize( |
| 5140 FUNCTION_ADDR(Runtime_TransitionStoreIC_MissFromStubFailure)); | 5140 FUNCTION_ADDR(Runtime_TransitionStoreIC_MissFromStubFailure)); |
| 5141 } | 5141 } |
| 5142 | 5142 |
| 5143 void NumberToStringStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { | 5143 void NumberToStringStub::InitializeDescriptor(CodeStubDescriptor* descriptor) { |
| 5144 descriptor->Initialize( | 5144 descriptor->Initialize( |
| 5145 Runtime::FunctionForId(Runtime::kNumberToString)->entry); | 5145 Runtime::FunctionForId(Runtime::kNumberToString)->entry); |
| 5146 descriptor->SetMissHandler(Runtime::kNumberToString); | 5146 descriptor->SetMissHandler(Runtime::kNumberToString); |
| 5147 } | 5147 } |
| 5148 | 5148 |
| 5149 | |
| 5150 void FastCloneShallowArrayStub::InitializeDescriptor( | |
| 5151 CodeStubDescriptor* descriptor) { | |
| 5152 FastCloneShallowArrayDescriptor call_descriptor(isolate()); | |
| 5153 descriptor->Initialize( | |
| 5154 Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry); | |
| 5155 descriptor->SetMissHandler(Runtime::kCreateArrayLiteralStubBailout); | |
| 5156 } | |
| 5157 | |
| 5158 void RegExpConstructResultStub::InitializeDescriptor( | 5149 void RegExpConstructResultStub::InitializeDescriptor( |
| 5159 CodeStubDescriptor* descriptor) { | 5150 CodeStubDescriptor* descriptor) { |
| 5160 descriptor->Initialize( | 5151 descriptor->Initialize( |
| 5161 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); | 5152 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); |
| 5162 descriptor->SetMissHandler(Runtime::kRegExpConstructResult); | 5153 descriptor->SetMissHandler(Runtime::kRegExpConstructResult); |
| 5163 } | 5154 } |
| 5164 | 5155 |
| 5165 | 5156 |
| 5166 void TransitionElementsKindStub::InitializeDescriptor( | 5157 void TransitionElementsKindStub::InitializeDescriptor( |
| 5167 CodeStubDescriptor* descriptor) { | 5158 CodeStubDescriptor* descriptor) { |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5656 Node* closure = assembler->Parameter(Descriptor::kClosure); | 5647 Node* closure = assembler->Parameter(Descriptor::kClosure); |
| 5657 Node* literal_index = assembler->Parameter(Descriptor::kLiteralIndex); | 5648 Node* literal_index = assembler->Parameter(Descriptor::kLiteralIndex); |
| 5658 Node* pattern = assembler->Parameter(Descriptor::kPattern); | 5649 Node* pattern = assembler->Parameter(Descriptor::kPattern); |
| 5659 Node* flags = assembler->Parameter(Descriptor::kFlags); | 5650 Node* flags = assembler->Parameter(Descriptor::kFlags); |
| 5660 Node* context = assembler->Parameter(Descriptor::kContext); | 5651 Node* context = assembler->Parameter(Descriptor::kContext); |
| 5661 | 5652 |
| 5662 assembler->Return( | 5653 assembler->Return( |
| 5663 Generate(assembler, closure, literal_index, pattern, flags, context)); | 5654 Generate(assembler, closure, literal_index, pattern, flags, context)); |
| 5664 } | 5655 } |
| 5665 | 5656 |
| 5657 // static | |
| 5658 compiler::Node* FastCloneShallowArrayStub::NonEmptyShallowClone( | |
| 5659 CodeStubAssembler* assembler, compiler::Node* boilerplate, | |
| 5660 compiler::Node* boilerplate_map, compiler::Node* boilerplate_elements, | |
| 5661 compiler::Node* allocation_site, compiler::Node* capacity, | |
| 5662 ElementsKind kind) { | |
| 5663 typedef compiler::Node Node; | |
| 5664 typedef CodeStubAssembler::ParameterMode ParameterMode; | |
| 5665 | |
| 5666 ParameterMode param_mode = CodeStubAssembler::SMI_PARAMETERS; | |
| 5667 | |
| 5668 Node* length = assembler->LoadJSArrayLength(boilerplate); | |
| 5669 | |
| 5670 if (assembler->Is64()) { | |
|
rmcilroy
2016/09/13 20:29:59
Any idea why this is different on 64bit?
klaasb
2016/09/14 18:24:51
This relates to the comment (now) at https://cs.ch
rmcilroy
2016/09/16 08:53:51
Interesting. I wonder why it isn't faster to use S
| |
| 5671 length = assembler->SmiUntag(length); | |
| 5672 capacity = assembler->SmiUntag(capacity); | |
| 5673 param_mode = CodeStubAssembler::INTEGER_PARAMETERS; | |
| 5674 } | |
| 5675 | |
| 5676 Node* array = assembler->AllocateEmptyJSArray( | |
| 5677 kind, boilerplate_map, length, allocation_site, param_mode, capacity); | |
| 5678 | |
| 5679 int elements_offset = | |
| 5680 JSArray::kSize + | |
| 5681 (allocation_site != nullptr ? AllocationMemento::kSize : 0); | |
| 5682 Node* elements = assembler->InnerAllocate(array, elements_offset); | |
| 5683 | |
| 5684 assembler->Comment("copy elements header"); | |
| 5685 for (int offset = 0; offset < FixedArrayBase::kHeaderSize; | |
| 5686 offset += kPointerSize) { | |
| 5687 Node* value = assembler->LoadObjectField(boilerplate_elements, offset); | |
| 5688 assembler->StoreObjectField(elements, offset, value); | |
| 5689 } | |
| 5690 | |
| 5691 assembler->Comment("copy boilerplate elements"); | |
| 5692 assembler->CopyFixedArrayElements(kind, boilerplate_elements, elements, | |
| 5693 length, SKIP_WRITE_BARRIER, param_mode); | |
| 5694 assembler->IncrementCounter( | |
| 5695 assembler->isolate()->counters()->inlined_copied_elements(), 1); | |
| 5696 | |
| 5697 return array; | |
| 5698 } | |
| 5699 | |
| 5700 // static | |
| 5701 compiler::Node* FastCloneShallowArrayStub::Generate( | |
| 5702 CodeStubAssembler* assembler, compiler::Node* closure, | |
| 5703 compiler::Node* literal_index, compiler::Node* constant_elements, | |
| 5704 compiler::Node* context, AllocationSiteMode allocation_site_mode) { | |
| 5705 typedef CodeStubAssembler::Label Label; | |
| 5706 typedef CodeStubAssembler::Variable Variable; | |
| 5707 typedef compiler::Node Node; | |
| 5708 | |
| 5709 Label call_runtime(assembler, Label::kDeferred), zero_capacity(assembler), | |
| 5710 fixed_cow(assembler), fixed(assembler), return_result(assembler); | |
| 5711 Variable result(assembler, MachineRepresentation::kTagged); | |
| 5712 | |
| 5713 Node* undefined = assembler->UndefinedConstant(); | |
| 5714 | |
| 5715 assembler->Comment("load literals array"); | |
| 5716 Node* literals_array = | |
| 5717 assembler->LoadObjectField(closure, JSFunction::kLiteralsOffset); | |
| 5718 assembler->Comment("load allocation site"); | |
| 5719 Node* allocation_site = assembler->LoadFixedArrayElement( | |
| 5720 literals_array, literal_index, | |
| 5721 LiteralsArray::kFirstLiteralIndex * kPointerSize, | |
| 5722 CodeStubAssembler::SMI_PARAMETERS); | |
| 5723 | |
| 5724 assembler->GotoIf(assembler->WordEqual(allocation_site, undefined), | |
| 5725 &call_runtime); | |
| 5726 | |
| 5727 assembler->Comment("load boilerplate"); | |
| 5728 Node* boilerplate = assembler->LoadObjectField( | |
| 5729 allocation_site, AllocationSite::kTransitionInfoOffset); | |
| 5730 Node* boilerplate_map = assembler->LoadMap(boilerplate); | |
| 5731 Node* boilerplate_elements = assembler->LoadElements(boilerplate); | |
| 5732 assembler->Comment("load capacity"); | |
|
rmcilroy
2016/09/13 20:29:59
not sure if these "load.." comments add much. I'm
klaasb
2016/09/14 18:24:52
Yes, they were mostly for my benefit when looking
| |
| 5733 Node* capacity = assembler->LoadFixedArrayBaseLength(boilerplate_elements); | |
| 5734 allocation_site = | |
| 5735 allocation_site_mode == TRACK_ALLOCATION_SITE ? allocation_site : nullptr; | |
| 5736 | |
| 5737 Node* zero = assembler->SmiConstant(Smi::FromInt(0)); | |
| 5738 assembler->GotoIf(assembler->SmiEqual(capacity, zero), &zero_capacity); | |
| 5739 | |
| 5740 Node* elements_map = assembler->LoadMap(boilerplate_elements); | |
| 5741 assembler->GotoIf( | |
| 5742 assembler->WordEqual(elements_map, assembler->FixedCowArrayMapConstant()), | |
| 5743 &fixed_cow); | |
| 5744 | |
| 5745 assembler->GotoIf( | |
| 5746 assembler->WordEqual(elements_map, assembler->FixedArrayMapConstant()), | |
| 5747 &fixed); | |
| 5748 { | |
| 5749 assembler->Comment("non fixed path"); | |
|
rmcilroy
2016/09/13 20:29:59
I don't think this is non-fixed, it's a fixed doub
klaasb
2016/09/14 18:24:52
Done.
| |
| 5750 Node* array = NonEmptyShallowClone(assembler, boilerplate, boilerplate_map, | |
| 5751 boilerplate_elements, allocation_site, | |
| 5752 capacity, FAST_DOUBLE_ELEMENTS); | |
| 5753 result.Bind(array); | |
| 5754 assembler->Goto(&return_result); | |
| 5755 } | |
| 5756 | |
| 5757 assembler->Bind(&fixed); | |
|
rmcilroy
2016/09/13 20:29:59
ditto - should this be fast_elements (and similar
klaasb
2016/09/14 18:24:51
Done.
| |
| 5758 { | |
| 5759 assembler->Comment("fixed path"); | |
| 5760 Node* array = NonEmptyShallowClone(assembler, boilerplate, boilerplate_map, | |
| 5761 boilerplate_elements, allocation_site, | |
| 5762 capacity, FAST_ELEMENTS); | |
| 5763 result.Bind(array); | |
| 5764 assembler->Goto(&return_result); | |
| 5765 } | |
| 5766 | |
| 5767 assembler->Bind(&fixed_cow); | |
|
rmcilroy
2016/09/13 20:29:59
fixed_cow_elements
klaasb
2016/09/14 18:24:51
Renamed to cow_elements, to mirror fast_elements.
| |
| 5768 { | |
| 5769 assembler->Comment("fixed cow path"); | |
| 5770 Node* length = assembler->LoadJSArrayLength(boilerplate); | |
| 5771 Node* array = assembler->AllocateEmptyJSArray( | |
| 5772 FAST_ELEMENTS, boilerplate_map, length, allocation_site, | |
| 5773 CodeStubAssembler::SMI_PARAMETERS); | |
| 5774 | |
| 5775 assembler->StoreObjectField(array, JSObject::kElementsOffset, | |
| 5776 boilerplate_elements); | |
| 5777 result.Bind(array); | |
| 5778 assembler->Goto(&return_result); | |
| 5779 } | |
| 5780 | |
| 5781 assembler->Bind(&zero_capacity); | |
| 5782 { | |
| 5783 assembler->Comment("zero capacity path"); | |
| 5784 Node* array = assembler->AllocateEmptyJSArray( | |
| 5785 FAST_ELEMENTS, boilerplate_map, zero, allocation_site, | |
| 5786 CodeStubAssembler::SMI_PARAMETERS); | |
| 5787 | |
| 5788 assembler->StoreObjectFieldRoot(array, JSObject::kElementsOffset, | |
| 5789 Heap::kEmptyFixedArrayRootIndex); | |
|
rmcilroy
2016/09/13 20:29:59
Would it be worth merging the allocations for fixe
klaasb
2016/09/14 18:24:51
I thought about that before, but seem to have forg
rmcilroy
2016/09/16 08:53:51
Yeah I realized the other branches couldn't be sha
| |
| 5790 result.Bind(array); | |
| 5791 assembler->Goto(&return_result); | |
| 5792 } | |
| 5793 | |
| 5794 assembler->Bind(&call_runtime); | |
| 5795 { | |
| 5796 assembler->Comment("call runtime"); | |
| 5797 Node* flags = assembler->SmiConstant( | |
| 5798 Smi::FromInt(ArrayLiteral::kShallowElements | | |
| 5799 (allocation_site_mode == TRACK_ALLOCATION_SITE | |
| 5800 ? 0 | |
| 5801 : ArrayLiteral::kDisableMementos))); | |
| 5802 Node* array = | |
| 5803 assembler->CallRuntime(Runtime::kCreateArrayLiteral, context, closure, | |
| 5804 literal_index, constant_elements, flags); | |
| 5805 result.Bind(array); | |
| 5806 assembler->Goto(&return_result); | |
| 5807 } | |
| 5808 | |
| 5809 assembler->Bind(&return_result); | |
| 5810 return result.value(); | |
| 5811 } | |
| 5812 | |
| 5813 void FastCloneShallowArrayStub::GenerateAssembly( | |
| 5814 CodeStubAssembler* assembler) const { | |
| 5815 typedef compiler::Node Node; | |
| 5816 Node* closure = assembler->Parameter(Descriptor::kClosure); | |
| 5817 Node* literal_index = assembler->Parameter(Descriptor::kLiteralIndex); | |
| 5818 Node* constant_elements = assembler->Parameter(Descriptor::kConstantElements); | |
| 5819 Node* context = assembler->Parameter(Descriptor::kContext); | |
| 5820 | |
| 5821 assembler->Return(Generate(assembler, closure, literal_index, | |
| 5822 constant_elements, context, | |
| 5823 allocation_site_mode())); | |
| 5824 } | |
| 5825 | |
| 5666 void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) { | 5826 void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) { |
| 5667 CreateAllocationSiteStub stub(isolate); | 5827 CreateAllocationSiteStub stub(isolate); |
| 5668 stub.GetCode(); | 5828 stub.GetCode(); |
| 5669 } | 5829 } |
| 5670 | 5830 |
| 5671 | 5831 |
| 5672 void CreateWeakCellStub::GenerateAheadOfTime(Isolate* isolate) { | 5832 void CreateWeakCellStub::GenerateAheadOfTime(Isolate* isolate) { |
| 5673 CreateWeakCellStub stub(isolate); | 5833 CreateWeakCellStub stub(isolate); |
| 5674 stub.GetCode(); | 5834 stub.GetCode(); |
| 5675 } | 5835 } |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5878 Node* native_context = assembler->LoadObjectField( | 6038 Node* native_context = assembler->LoadObjectField( |
| 5879 assembler->Parameter(Descriptor::kFunction), JSFunction::kContextOffset); | 6039 assembler->Parameter(Descriptor::kFunction), JSFunction::kContextOffset); |
| 5880 bool track_allocation_site = | 6040 bool track_allocation_site = |
| 5881 AllocationSite::GetMode(elements_kind()) == TRACK_ALLOCATION_SITE && | 6041 AllocationSite::GetMode(elements_kind()) == TRACK_ALLOCATION_SITE && |
| 5882 override_mode() != DISABLE_ALLOCATION_SITES; | 6042 override_mode() != DISABLE_ALLOCATION_SITES; |
| 5883 Node* allocation_site = | 6043 Node* allocation_site = |
| 5884 track_allocation_site ? assembler->Parameter(Descriptor::kAllocationSite) | 6044 track_allocation_site ? assembler->Parameter(Descriptor::kAllocationSite) |
| 5885 : nullptr; | 6045 : nullptr; |
| 5886 Node* array_map = | 6046 Node* array_map = |
| 5887 assembler->LoadJSArrayElementsMap(elements_kind(), native_context); | 6047 assembler->LoadJSArrayElementsMap(elements_kind(), native_context); |
| 5888 Node* array = assembler->AllocateJSArray( | 6048 Node* array = assembler->AllocateFilledJSArray( |
| 5889 elements_kind(), array_map, | 6049 elements_kind(), array_map, |
| 5890 assembler->IntPtrConstant(JSArray::kPreallocatedArrayElements), | 6050 assembler->IntPtrConstant(JSArray::kPreallocatedArrayElements), |
| 5891 assembler->IntPtrConstant(0), allocation_site); | 6051 assembler->IntPtrConstant(0), allocation_site); |
| 5892 assembler->Return(array); | 6052 assembler->Return(array); |
| 5893 } | 6053 } |
| 5894 | 6054 |
| 5895 void InternalArrayNoArgumentConstructorStub::GenerateAssembly( | 6055 void InternalArrayNoArgumentConstructorStub::GenerateAssembly( |
| 5896 CodeStubAssembler* assembler) const { | 6056 CodeStubAssembler* assembler) const { |
| 5897 typedef compiler::Node Node; | 6057 typedef compiler::Node Node; |
| 5898 Node* array_map = | 6058 Node* array_map = |
| 5899 assembler->LoadObjectField(assembler->Parameter(Descriptor::kFunction), | 6059 assembler->LoadObjectField(assembler->Parameter(Descriptor::kFunction), |
| 5900 JSFunction::kPrototypeOrInitialMapOffset); | 6060 JSFunction::kPrototypeOrInitialMapOffset); |
| 5901 Node* array = assembler->AllocateJSArray( | 6061 Node* array = assembler->AllocateFilledJSArray( |
| 5902 elements_kind(), array_map, | 6062 elements_kind(), array_map, |
| 5903 assembler->IntPtrConstant(JSArray::kPreallocatedArrayElements), | 6063 assembler->IntPtrConstant(JSArray::kPreallocatedArrayElements), |
| 5904 assembler->IntPtrConstant(0), nullptr); | 6064 assembler->IntPtrConstant(0), nullptr); |
| 5905 assembler->Return(array); | 6065 assembler->Return(array); |
| 5906 } | 6066 } |
| 5907 | 6067 |
| 5908 namespace { | 6068 namespace { |
| 5909 | 6069 |
| 5910 template <typename Descriptor> | 6070 template <typename Descriptor> |
| 5911 void SingleArgumentConstructorCommon(CodeStubAssembler* assembler, | 6071 void SingleArgumentConstructorCommon(CodeStubAssembler* assembler, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5945 AllocationMemento::kSize) / | 6105 AllocationMemento::kSize) / |
| 5946 element_size; | 6106 element_size; |
| 5947 assembler->Branch( | 6107 assembler->Branch( |
| 5948 assembler->SmiAboveOrEqual( | 6108 assembler->SmiAboveOrEqual( |
| 5949 size, assembler->SmiConstant(Smi::FromInt(max_fast_elements))), | 6109 size, assembler->SmiConstant(Smi::FromInt(max_fast_elements))), |
| 5950 &call_runtime, &small_smi_size); | 6110 &call_runtime, &small_smi_size); |
| 5951 } | 6111 } |
| 5952 | 6112 |
| 5953 assembler->Bind(&small_smi_size); | 6113 assembler->Bind(&small_smi_size); |
| 5954 { | 6114 { |
| 5955 Node* array = assembler->AllocateJSArray( | 6115 Node* array = assembler->AllocateFilledJSArray( |
| 5956 elements_kind, array_map, size, size, | 6116 elements_kind, array_map, size, size, |
| 5957 mode == DONT_TRACK_ALLOCATION_SITE ? nullptr : allocation_site, | 6117 mode == DONT_TRACK_ALLOCATION_SITE ? nullptr : allocation_site, |
| 5958 CodeStubAssembler::SMI_PARAMETERS); | 6118 CodeStubAssembler::SMI_PARAMETERS); |
| 5959 assembler->Return(array); | 6119 assembler->Return(array); |
| 5960 } | 6120 } |
| 5961 | 6121 |
| 5962 assembler->Bind(&call_runtime); | 6122 assembler->Bind(&call_runtime); |
| 5963 { | 6123 { |
| 5964 Node* context = assembler->Parameter(Descriptor::kContext); | 6124 Node* context = assembler->Parameter(Descriptor::kContext); |
| 5965 Node* function = assembler->Parameter(Descriptor::kFunction); | 6125 Node* function = assembler->Parameter(Descriptor::kFunction); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6061 | 6221 |
| 6062 if (type == MachineType::Pointer()) { | 6222 if (type == MachineType::Pointer()) { |
| 6063 return Representation::External(); | 6223 return Representation::External(); |
| 6064 } | 6224 } |
| 6065 | 6225 |
| 6066 return Representation::Tagged(); | 6226 return Representation::Tagged(); |
| 6067 } | 6227 } |
| 6068 | 6228 |
| 6069 } // namespace internal | 6229 } // namespace internal |
| 6070 } // namespace v8 | 6230 } // namespace v8 |
| OLD | NEW |