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 | 4 |
5 #include "src/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 #include "src/interface-descriptors.h" | 7 #include "src/interface-descriptors.h" |
8 #include "src/macro-assembler.h" | 8 #include "src/macro-assembler.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 masm->TailCallRuntime(Runtime::kStackGuard); | 50 masm->TailCallRuntime(Runtime::kStackGuard); |
51 } | 51 } |
52 | 52 |
53 // ----------------------------------------------------------------------------- | 53 // ----------------------------------------------------------------------------- |
54 // TurboFan support builtins. | 54 // TurboFan support builtins. |
55 | 55 |
56 void Builtins::Generate_CopyFastSmiOrObjectElements( | 56 void Builtins::Generate_CopyFastSmiOrObjectElements( |
57 CodeStubAssembler* assembler) { | 57 CodeStubAssembler* assembler) { |
58 typedef CodeStubAssembler::Label Label; | 58 typedef CodeStubAssembler::Label Label; |
59 typedef compiler::Node Node; | 59 typedef compiler::Node Node; |
60 typedef CodeStubAssembler::Variable Variable; | |
61 typedef CopyFastSmiOrObjectElementsDescriptor Descriptor; | 60 typedef CopyFastSmiOrObjectElementsDescriptor Descriptor; |
62 | 61 |
63 Node* object = assembler->Parameter(Descriptor::kObject); | 62 Node* object = assembler->Parameter(Descriptor::kObject); |
64 | 63 |
65 // Load the {object}s elements. | 64 // Load the {object}s elements. |
66 Node* source = assembler->LoadObjectField(object, JSObject::kElementsOffset); | 65 Node* source = assembler->LoadObjectField(object, JSObject::kElementsOffset); |
67 | 66 |
68 // Load the {source} length. | 67 CodeStubAssembler::ParameterMode mode = |
69 Node* source_length_tagged = | 68 assembler->Is64() ? CodeStubAssembler::INTEGER_PARAMETERS |
70 assembler->LoadObjectField(source, FixedArray::kLengthOffset); | 69 : CodeStubAssembler::SMI_PARAMETERS; |
71 Node* source_length = assembler->SmiToWord(source_length_tagged); | 70 Node* length = (mode == CodeStubAssembler::INTEGER_PARAMETERS) |
72 | 71 ? assembler->LoadAndUntagFixedArrayBaseLength(source) |
73 // Compute the size of {source} in bytes. | 72 : assembler->LoadFixedArrayBaseLength(source); |
74 Node* source_size = assembler->IntPtrAdd( | |
75 assembler->WordShl(source_length, | |
76 assembler->IntPtrConstant(kPointerSizeLog2)), | |
77 assembler->IntPtrConstant(FixedArray::kHeaderSize)); | |
78 | 73 |
79 // Check if we can allocate in new space. | 74 // Check if we can allocate in new space. |
| 75 ElementsKind kind = FAST_ELEMENTS; |
| 76 int max_elements = FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind); |
80 Label if_newspace(assembler), if_oldspace(assembler); | 77 Label if_newspace(assembler), if_oldspace(assembler); |
81 assembler->Branch(assembler->UintPtrLessThan( | 78 assembler->Branch( |
82 source_size, assembler->IntPtrConstant( | 79 assembler->UintPtrLessThan( |
83 Page::kMaxRegularHeapObjectSize)), | 80 length, assembler->IntPtrOrSmiConstant(max_elements, mode)), |
84 &if_newspace, &if_oldspace); | 81 &if_newspace, &if_oldspace); |
85 | 82 |
86 assembler->Bind(&if_newspace); | 83 assembler->Bind(&if_newspace); |
87 { | 84 { |
88 // Allocate the targeting FixedArray in new space. | 85 Node* target = assembler->AllocateFixedArray(kind, length, mode); |
89 Node* target = assembler->Allocate(source_size); | 86 assembler->CopyFixedArrayElements(kind, source, target, length, |
90 assembler->StoreMapNoWriteBarrier( | 87 SKIP_WRITE_BARRIER, mode); |
91 target, assembler->LoadRoot(Heap::kFixedArrayMapRootIndex)); | 88 assembler->StoreObjectField(object, JSObject::kElementsOffset, target); |
92 assembler->StoreObjectFieldNoWriteBarrier(target, FixedArray::kLengthOffset, | 89 assembler->Return(target); |
93 source_length_tagged); | |
94 | |
95 // Compute the limit. | |
96 Node* limit = assembler->IntPtrSub( | |
97 source_size, assembler->IntPtrConstant(kHeapObjectTag)); | |
98 | |
99 // Copy the {source} to the {target}. | |
100 Variable var_offset(assembler, MachineType::PointerRepresentation()); | |
101 Label loop(assembler, &var_offset), done_loop(assembler); | |
102 var_offset.Bind( | |
103 assembler->IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); | |
104 assembler->Goto(&loop); | |
105 assembler->Bind(&loop); | |
106 { | |
107 // Determine the current {offset}. | |
108 Node* offset = var_offset.value(); | |
109 | |
110 // Check if we are done. | |
111 assembler->GotoUnless(assembler->UintPtrLessThan(offset, limit), | |
112 &done_loop); | |
113 | |
114 // Load the value from {source}. | |
115 Node* value = assembler->Load(MachineType::AnyTagged(), source, offset); | |
116 | |
117 // Store the {value} to the {target} without a write barrier, since we | |
118 // know that the {target} is allocated in new space. | |
119 assembler->StoreNoWriteBarrier(MachineRepresentation::kTagged, target, | |
120 offset, value); | |
121 | |
122 // Increment {offset} and continue. | |
123 var_offset.Bind(assembler->IntPtrAdd( | |
124 offset, assembler->IntPtrConstant(kPointerSize))); | |
125 assembler->Goto(&loop); | |
126 } | |
127 | |
128 assembler->Bind(&done_loop); | |
129 { | |
130 // Update the {object}s element to {target}. | |
131 assembler->StoreObjectField(object, JSObject::kElementsOffset, target); | |
132 assembler->Return(target); | |
133 } | |
134 } | 90 } |
135 | 91 |
136 assembler->Bind(&if_oldspace); | 92 assembler->Bind(&if_oldspace); |
137 { | 93 { |
138 // Allocate the targeting FixedArray in old space | 94 Node* target = assembler->AllocateFixedArray( |
139 // (maybe even in large object space). | 95 kind, length, mode, compiler::CodeAssembler::kPretenured); |
140 Node* flags = assembler->SmiConstant( | 96 assembler->CopyFixedArrayElements(kind, source, target, length, |
141 Smi::FromInt(AllocateDoubleAlignFlag::encode(false) | | 97 UPDATE_WRITE_BARRIER, mode); |
142 AllocateTargetSpace::encode(AllocationSpace::OLD_SPACE))); | 98 assembler->StoreObjectField(object, JSObject::kElementsOffset, target); |
143 Node* source_size_tagged = assembler->SmiFromWord(source_size); | 99 assembler->Return(target); |
144 Node* target = assembler->CallRuntime(Runtime::kAllocateInTargetSpace, | |
145 assembler->NoContextConstant(), | |
146 source_size_tagged, flags); | |
147 assembler->StoreMapNoWriteBarrier( | |
148 target, assembler->LoadRoot(Heap::kFixedArrayMapRootIndex)); | |
149 assembler->StoreObjectFieldNoWriteBarrier(target, FixedArray::kLengthOffset, | |
150 source_length_tagged); | |
151 | |
152 // Compute the limit. | |
153 Node* limit = assembler->IntPtrSub( | |
154 source_size, assembler->IntPtrConstant(kHeapObjectTag)); | |
155 | |
156 // Copy the {source} to the {target}. | |
157 Variable var_offset(assembler, MachineType::PointerRepresentation()); | |
158 Label loop(assembler, &var_offset), done_loop(assembler); | |
159 var_offset.Bind( | |
160 assembler->IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); | |
161 assembler->Goto(&loop); | |
162 assembler->Bind(&loop); | |
163 { | |
164 // Determine the current {offset}. | |
165 Node* offset = var_offset.value(); | |
166 | |
167 // Check if we are done. | |
168 assembler->GotoUnless(assembler->UintPtrLessThan(offset, limit), | |
169 &done_loop); | |
170 | |
171 // Load the value from {source}. | |
172 Node* value = assembler->Load(MachineType::AnyTagged(), source, offset); | |
173 | |
174 // Store the {value} to the {target} with a proper write barrier. | |
175 assembler->Store(MachineRepresentation::kTagged, target, offset, value); | |
176 | |
177 // Increment {offset} and continue. | |
178 var_offset.Bind(assembler->IntPtrAdd( | |
179 offset, assembler->IntPtrConstant(kPointerSize))); | |
180 assembler->Goto(&loop); | |
181 } | |
182 | |
183 assembler->Bind(&done_loop); | |
184 { | |
185 // Update the {object}s element to {target}. | |
186 assembler->StoreObjectField(object, JSObject::kElementsOffset, target); | |
187 assembler->Return(target); | |
188 } | |
189 } | 100 } |
190 } | 101 } |
191 | 102 |
192 void Builtins::Generate_GrowFastDoubleElements(CodeStubAssembler* assembler) { | 103 void Builtins::Generate_GrowFastDoubleElements(CodeStubAssembler* assembler) { |
193 typedef CodeStubAssembler::Label Label; | 104 typedef CodeStubAssembler::Label Label; |
194 typedef compiler::Node Node; | 105 typedef compiler::Node Node; |
195 typedef GrowArrayElementsDescriptor Descriptor; | 106 typedef GrowArrayElementsDescriptor Descriptor; |
196 | 107 |
197 Node* object = assembler->Parameter(Descriptor::kObject); | 108 Node* object = assembler->Parameter(Descriptor::kObject); |
198 Node* key = assembler->Parameter(Descriptor::kKey); | 109 Node* key = assembler->Parameter(Descriptor::kKey); |
(...skipping 26 matching lines...) Expand all Loading... |
225 context, elements, FAST_ELEMENTS, key, &runtime); | 136 context, elements, FAST_ELEMENTS, key, &runtime); |
226 assembler->StoreObjectField(object, JSObject::kElementsOffset, elements); | 137 assembler->StoreObjectField(object, JSObject::kElementsOffset, elements); |
227 assembler->Return(elements); | 138 assembler->Return(elements); |
228 | 139 |
229 assembler->Bind(&runtime); | 140 assembler->Bind(&runtime); |
230 assembler->TailCallRuntime(Runtime::kGrowArrayElements, context, object, key); | 141 assembler->TailCallRuntime(Runtime::kGrowArrayElements, context, object, key); |
231 } | 142 } |
232 | 143 |
233 } // namespace internal | 144 } // namespace internal |
234 } // namespace v8 | 145 } // namespace v8 |
OLD | NEW |