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-utils.h" | 5 #include "src/builtins/builtins-utils.h" |
6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
7 #include "src/code-stub-assembler.h" | 7 #include "src/code-stub-assembler.h" |
8 #include "src/interface-descriptors.h" | 8 #include "src/interface-descriptors.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 | 10 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 Label runtime(&assembler, CodeStubAssembler::Label::kDeferred); | 134 Label runtime(&assembler, CodeStubAssembler::Label::kDeferred); |
135 Node* elements = assembler.LoadElements(object); | 135 Node* elements = assembler.LoadElements(object); |
136 elements = assembler.TryGrowElementsCapacity(object, elements, FAST_ELEMENTS, | 136 elements = assembler.TryGrowElementsCapacity(object, elements, FAST_ELEMENTS, |
137 key, &runtime); | 137 key, &runtime); |
138 assembler.Return(elements); | 138 assembler.Return(elements); |
139 | 139 |
140 assembler.Bind(&runtime); | 140 assembler.Bind(&runtime); |
141 assembler.TailCallRuntime(Runtime::kGrowArrayElements, context, object, key); | 141 assembler.TailCallRuntime(Runtime::kGrowArrayElements, context, object, key); |
142 } | 142 } |
143 | 143 |
144 namespace { | |
145 | |
146 void Generate_NewArgumentsElements(CodeStubAssembler* assembler, | |
147 compiler::Node* frame, | |
148 compiler::Node* length) { | |
149 typedef CodeStubAssembler::Label Label; | |
150 typedef CodeStubAssembler::Variable Variable; | |
151 typedef compiler::Node Node; | |
152 | |
153 // Compute the effective {offset} into the {frame}. | |
154 Node* offset = assembler->IntPtrAdd(length, assembler->IntPtrConstant(1)); | |
Jarin
2016/12/08 07:49:21
Why is this defined here? Would not it be enough t
Benedikt Meurer
2016/12/08 07:58:15
Indeed.
| |
155 | |
156 // Check if we can allocate in new space. | |
157 ElementsKind kind = FAST_ELEMENTS; | |
158 int max_elements = FixedArray::GetMaxLengthForNewSpaceAllocation(kind); | |
159 Label if_newspace(assembler), if_oldspace(assembler, Label::kDeferred); | |
160 assembler->Branch(assembler->IntPtrLessThan( | |
161 length, assembler->IntPtrConstant(max_elements)), | |
162 &if_newspace, &if_oldspace); | |
163 | |
164 assembler->Bind(&if_newspace); | |
165 { | |
166 // Prefer EmptyFixedArray in case of non-positive {length} (the {length} | |
167 // can be negative here for rest parameters). | |
168 Label if_empty(assembler), if_notempty(assembler); | |
169 assembler->Branch( | |
170 assembler->IntPtrLessThanOrEqual(length, assembler->IntPtrConstant(0)), | |
171 &if_empty, &if_notempty); | |
172 | |
173 assembler->Bind(&if_empty); | |
174 assembler->Return(assembler->EmptyFixedArrayConstant()); | |
175 | |
176 assembler->Bind(&if_notempty); | |
177 { | |
178 // Allocate a FixedArray in new space. | |
179 Node* result = assembler->AllocateFixedArray( | |
180 kind, length, CodeStubAssembler::INTPTR_PARAMETERS); | |
181 | |
182 // Copy the parameters from {frame} (starting at {offset}) to {result}. | |
183 Variable var_index(assembler, MachineType::PointerRepresentation()); | |
184 Label loop(assembler, &var_index), done_loop(assembler); | |
185 var_index.Bind(assembler->IntPtrConstant(0)); | |
186 assembler->Goto(&loop); | |
187 assembler->Bind(&loop); | |
188 { | |
189 // Load the current {index}. | |
190 Node* index = var_index.value(); | |
191 | |
192 // Check if we are done. | |
193 assembler->GotoIf(assembler->WordEqual(index, length), &done_loop); | |
194 | |
195 // Load the parameter at the given {index}. | |
196 Node* value = assembler->Load( | |
197 MachineType::AnyTagged(), frame, | |
198 assembler->WordShl(assembler->IntPtrSub(offset, index), | |
199 assembler->IntPtrConstant(kPointerSizeLog2))); | |
200 | |
201 // Store the {value} into the {result}. | |
202 assembler->StoreFixedArrayElement(result, index, value, | |
203 SKIP_WRITE_BARRIER, 0, | |
204 CodeStubAssembler::INTPTR_PARAMETERS); | |
205 | |
206 // Continue with next {index}. | |
207 var_index.Bind( | |
208 assembler->IntPtrAdd(index, assembler->IntPtrConstant(1))); | |
209 assembler->Goto(&loop); | |
210 } | |
211 | |
212 assembler->Bind(&done_loop); | |
213 assembler->Return(result); | |
214 } | |
215 } | |
216 | |
217 assembler->Bind(&if_oldspace); | |
218 { | |
219 // Allocate in old space (or large object space). | |
220 assembler->TailCallRuntime( | |
221 Runtime::kNewArgumentsElements, assembler->NoContextConstant(), | |
222 assembler->BitcastWordToTagged(frame), assembler->SmiFromWord(length)); | |
223 } | |
224 } | |
225 | |
226 } // namespace | |
227 | |
228 void Builtins::Generate_NewUnmappedArgumentsElements( | |
229 compiler::CodeAssemblerState* state) { | |
230 typedef CodeStubAssembler::Label Label; | |
231 typedef CodeStubAssembler::Variable Variable; | |
232 typedef compiler::Node Node; | |
233 typedef NewArgumentsElementsDescriptor Descriptor; | |
234 CodeStubAssembler assembler(state); | |
235 | |
236 Node* formal_parameter_count = | |
237 assembler.Parameter(Descriptor::kFormalParameterCount); | |
238 | |
239 // Determine the frame that holds the parameters. | |
240 Label done(&assembler); | |
241 Variable var_frame(&assembler, MachineType::PointerRepresentation()), | |
242 var_length(&assembler, MachineType::PointerRepresentation()); | |
243 var_frame.Bind(assembler.LoadParentFramePointer()); | |
244 var_length.Bind(formal_parameter_count); | |
245 Node* parent_frame = assembler.Load( | |
246 MachineType::Pointer(), var_frame.value(), | |
247 assembler.IntPtrConstant(StandardFrameConstants::kCallerFPOffset)); | |
248 Node* parent_frame_type = | |
249 assembler.Load(MachineType::AnyTagged(), parent_frame, | |
250 assembler.IntPtrConstant( | |
251 CommonFrameConstants::kContextOrFrameTypeOffset)); | |
252 assembler.GotoUnless( | |
253 assembler.WordEqual( | |
254 parent_frame_type, | |
255 assembler.SmiConstant(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))), | |
256 &done); | |
257 { | |
258 // Determine the length from the ArgumentsAdaptorFrame. | |
259 Node* length = assembler.LoadAndUntagSmi( | |
260 parent_frame, ArgumentsAdaptorFrameConstants::kLengthOffset); | |
261 | |
262 // Take the arguments from the ArgumentsAdaptorFrame. | |
263 var_frame.Bind(parent_frame); | |
264 var_length.Bind(length); | |
265 } | |
266 assembler.Goto(&done); | |
267 | |
268 // Allocate the actual FixedArray for the elements. | |
269 assembler.Bind(&done); | |
270 Generate_NewArgumentsElements(&assembler, var_frame.value(), | |
271 var_length.value()); | |
272 } | |
273 | |
274 void Builtins::Generate_NewRestParameterElements( | |
275 compiler::CodeAssemblerState* state) { | |
276 typedef CodeStubAssembler::Label Label; | |
277 typedef compiler::Node Node; | |
278 typedef NewArgumentsElementsDescriptor Descriptor; | |
279 CodeStubAssembler assembler(state); | |
280 | |
281 Node* formal_parameter_count = | |
282 assembler.Parameter(Descriptor::kFormalParameterCount); | |
283 | |
284 // Check if we have an ArgumentsAdaptorFrame, as we will only have rest | |
285 // parameters in that case. | |
286 Label if_empty(&assembler); | |
287 Node* frame = assembler.Load( | |
288 MachineType::Pointer(), assembler.LoadParentFramePointer(), | |
289 assembler.IntPtrConstant(StandardFrameConstants::kCallerFPOffset)); | |
290 Node* frame_type = | |
291 assembler.Load(MachineType::AnyTagged(), frame, | |
292 assembler.IntPtrConstant( | |
293 CommonFrameConstants::kContextOrFrameTypeOffset)); | |
294 assembler.GotoUnless( | |
295 assembler.WordEqual(frame_type, assembler.SmiConstant(Smi::FromInt( | |
296 StackFrame::ARGUMENTS_ADAPTOR))), | |
297 &if_empty); | |
298 | |
299 // Determine the length from the ArgumentsAdaptorFrame. | |
300 Node* frame_length = assembler.LoadAndUntagSmi( | |
301 frame, ArgumentsAdaptorFrameConstants::kLengthOffset); | |
302 | |
303 // Compute the actual rest parameter length (may be negative). | |
304 Node* length = assembler.IntPtrSub(frame_length, formal_parameter_count); | |
305 | |
306 // Allocate the actual FixedArray for the elements. | |
307 Generate_NewArgumentsElements(&assembler, frame, length); | |
308 | |
309 // No rest parameters, return an empty FixedArray. | |
310 assembler.Bind(&if_empty); | |
311 assembler.Return(assembler.EmptyFixedArrayConstant()); | |
312 } | |
313 | |
144 } // namespace internal | 314 } // namespace internal |
145 } // namespace v8 | 315 } // namespace v8 |
OLD | NEW |