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

Side by Side Diff: src/builtins/builtins-arguments.cc

Issue 2752143004: [refactor] Separate generated builtins and C++ builtins into separate files (Closed)
Patch Set: tentative gcmole fix Created 3 years, 9 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/builtins/builtins.cc ('k') | src/builtins/builtins-arguments-gen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/builtins/builtins-arguments.h"
6 #include "src/builtins/builtins-utils.h"
7 #include "src/builtins/builtins.h"
8 #include "src/code-factory.h"
9 #include "src/code-stub-assembler.h"
10 #include "src/interface-descriptors.h"
11 #include "src/objects-inl.h"
12
13 namespace v8 {
14 namespace internal {
15
16 typedef compiler::Node Node;
17
18 std::tuple<Node*, Node*, Node*>
19 ArgumentsBuiltinsAssembler::GetArgumentsFrameAndCount(Node* function,
20 ParameterMode mode) {
21 CSA_ASSERT(this, HasInstanceType(function, JS_FUNCTION_TYPE));
22
23 Variable frame_ptr(this, MachineType::PointerRepresentation());
24 frame_ptr.Bind(LoadParentFramePointer());
25 CSA_ASSERT(this,
26 WordEqual(function,
27 LoadBufferObject(frame_ptr.value(),
28 StandardFrameConstants::kFunctionOffset,
29 MachineType::Pointer())));
30 Variable argument_count(this, ParameterRepresentation(mode));
31 VariableList list({&frame_ptr, &argument_count}, zone());
32 Label done_argument_count(this, list);
33
34 // Determine the number of passed parameters, which is either the count stored
35 // in an arguments adapter frame or fetched from the shared function info.
36 Node* frame_ptr_above = LoadBufferObject(
37 frame_ptr.value(), StandardFrameConstants::kCallerFPOffset,
38 MachineType::Pointer());
39 Node* shared =
40 LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset);
41 Node* formal_parameter_count = LoadSharedFunctionInfoSpecialField(
42 shared, SharedFunctionInfo::kFormalParameterCountOffset, mode);
43 argument_count.Bind(formal_parameter_count);
44 Node* marker_or_function = LoadBufferObject(
45 frame_ptr_above, CommonFrameConstants::kContextOrFrameTypeOffset);
46 GotoIf(
47 MarkerIsNotFrameType(marker_or_function, StackFrame::ARGUMENTS_ADAPTOR),
48 &done_argument_count);
49 Node* adapted_parameter_count = LoadBufferObject(
50 frame_ptr_above, ArgumentsAdaptorFrameConstants::kLengthOffset);
51 frame_ptr.Bind(frame_ptr_above);
52 argument_count.Bind(TaggedToParameter(adapted_parameter_count, mode));
53 Goto(&done_argument_count);
54
55 Bind(&done_argument_count);
56 return std::tuple<Node*, Node*, Node*>(
57 frame_ptr.value(), argument_count.value(), formal_parameter_count);
58 }
59
60 std::tuple<Node*, Node*, Node*>
61 ArgumentsBuiltinsAssembler::AllocateArgumentsObject(Node* map,
62 Node* arguments_count,
63 Node* parameter_map_count,
64 ParameterMode mode,
65 int base_size) {
66 // Allocate the parameter object (either a Rest parameter object, a strict
67 // argument object or a sloppy arguments object) and the elements/mapped
68 // arguments together.
69 int elements_offset = base_size;
70 Node* element_count = arguments_count;
71 if (parameter_map_count != nullptr) {
72 base_size += FixedArray::kHeaderSize;
73 element_count = IntPtrOrSmiAdd(element_count, parameter_map_count, mode);
74 }
75 bool empty = IsIntPtrOrSmiConstantZero(arguments_count);
76 DCHECK_IMPLIES(empty, parameter_map_count == nullptr);
77 Node* size =
78 empty ? IntPtrConstant(base_size)
79 : ElementOffsetFromIndex(element_count, FAST_ELEMENTS, mode,
80 base_size + FixedArray::kHeaderSize);
81 Node* result = Allocate(size);
82 Comment("Initialize arguments object");
83 StoreMapNoWriteBarrier(result, map);
84 Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex);
85 StoreObjectField(result, JSArray::kPropertiesOffset, empty_fixed_array);
86 Node* smi_arguments_count = ParameterToTagged(arguments_count, mode);
87 StoreObjectFieldNoWriteBarrier(result, JSArray::kLengthOffset,
88 smi_arguments_count);
89 Node* arguments = nullptr;
90 if (!empty) {
91 arguments = InnerAllocate(result, elements_offset);
92 StoreObjectFieldNoWriteBarrier(arguments, FixedArray::kLengthOffset,
93 smi_arguments_count);
94 Node* fixed_array_map = LoadRoot(Heap::kFixedArrayMapRootIndex);
95 StoreMapNoWriteBarrier(arguments, fixed_array_map);
96 }
97 Node* parameter_map = nullptr;
98 if (parameter_map_count != nullptr) {
99 Node* parameter_map_offset = ElementOffsetFromIndex(
100 arguments_count, FAST_ELEMENTS, mode, FixedArray::kHeaderSize);
101 parameter_map = InnerAllocate(arguments, parameter_map_offset);
102 StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset,
103 parameter_map);
104 Node* sloppy_elements_map =
105 LoadRoot(Heap::kSloppyArgumentsElementsMapRootIndex);
106 StoreMapNoWriteBarrier(parameter_map, sloppy_elements_map);
107 parameter_map_count = ParameterToTagged(parameter_map_count, mode);
108 StoreObjectFieldNoWriteBarrier(parameter_map, FixedArray::kLengthOffset,
109 parameter_map_count);
110 } else {
111 if (empty) {
112 StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset,
113 empty_fixed_array);
114 } else {
115 StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset,
116 arguments);
117 }
118 }
119 return std::tuple<Node*, Node*, Node*>(result, arguments, parameter_map);
120 }
121
122 Node* ArgumentsBuiltinsAssembler::ConstructParametersObjectFromArgs(
123 Node* map, Node* frame_ptr, Node* arg_count, Node* first_arg,
124 Node* rest_count, ParameterMode param_mode, int base_size) {
125 // Allocate the parameter object (either a Rest parameter object, a strict
126 // argument object or a sloppy arguments object) and the elements together and
127 // fill in the contents with the arguments above |formal_parameter_count|.
128 Node* result;
129 Node* elements;
130 Node* unused;
131 std::tie(result, elements, unused) =
132 AllocateArgumentsObject(map, rest_count, nullptr, param_mode, base_size);
133 DCHECK(unused == nullptr);
134 CodeStubArguments arguments(this, arg_count, frame_ptr, param_mode);
135 Variable offset(this, MachineType::PointerRepresentation());
136 offset.Bind(IntPtrConstant(FixedArrayBase::kHeaderSize - kHeapObjectTag));
137 VariableList list({&offset}, zone());
138 arguments.ForEach(list,
139 [this, elements, &offset](Node* arg) {
140 StoreNoWriteBarrier(MachineRepresentation::kTagged,
141 elements, offset.value(), arg);
142 Increment(offset, kPointerSize);
143 },
144 first_arg, nullptr, param_mode);
145 return result;
146 }
147
148 Node* ArgumentsBuiltinsAssembler::EmitFastNewRestParameter(Node* context,
149 Node* function) {
150 Node* frame_ptr;
151 Node* argument_count;
152 Node* formal_parameter_count;
153
154 ParameterMode mode = OptimalParameterMode();
155 Node* zero = IntPtrOrSmiConstant(0, mode);
156
157 std::tie(frame_ptr, argument_count, formal_parameter_count) =
158 GetArgumentsFrameAndCount(function, mode);
159
160 Variable result(this, MachineRepresentation::kTagged);
161 Label no_rest_parameters(this), runtime(this, Label::kDeferred),
162 done(this, &result);
163
164 Node* rest_count =
165 IntPtrOrSmiSub(argument_count, formal_parameter_count, mode);
166 Node* const native_context = LoadNativeContext(context);
167 Node* const array_map = LoadJSArrayElementsMap(FAST_ELEMENTS, native_context);
168 GotoIf(IntPtrOrSmiLessThanOrEqual(rest_count, zero, mode),
169 &no_rest_parameters);
170
171 GotoIfFixedArraySizeDoesntFitInNewSpace(
172 rest_count, &runtime, JSArray::kSize + FixedArray::kHeaderSize, mode);
173
174 // Allocate the Rest JSArray and the elements together and fill in the
175 // contents with the arguments above |formal_parameter_count|.
176 result.Bind(ConstructParametersObjectFromArgs(
177 array_map, frame_ptr, argument_count, formal_parameter_count, rest_count,
178 mode, JSArray::kSize));
179 Goto(&done);
180
181 Bind(&no_rest_parameters);
182 {
183 Node* arguments;
184 Node* elements;
185 Node* unused;
186 std::tie(arguments, elements, unused) =
187 AllocateArgumentsObject(array_map, zero, nullptr, mode, JSArray::kSize);
188 result.Bind(arguments);
189 Goto(&done);
190 }
191
192 Bind(&runtime);
193 {
194 result.Bind(CallRuntime(Runtime::kNewRestParameter, context, function));
195 Goto(&done);
196 }
197
198 Bind(&done);
199 return result.value();
200 }
201
202 TF_BUILTIN(FastNewRestParameter, ArgumentsBuiltinsAssembler) {
203 Node* function = Parameter(FastNewArgumentsDescriptor::kFunction);
204 Node* context = Parameter(FastNewArgumentsDescriptor::kContext);
205 Return(EmitFastNewRestParameter(context, function));
206 }
207
208 Node* ArgumentsBuiltinsAssembler::EmitFastNewStrictArguments(Node* context,
209 Node* function) {
210 Variable result(this, MachineRepresentation::kTagged);
211 Label done(this, &result), empty(this), runtime(this, Label::kDeferred);
212
213 Node* frame_ptr;
214 Node* argument_count;
215 Node* formal_parameter_count;
216
217 ParameterMode mode = OptimalParameterMode();
218 Node* zero = IntPtrOrSmiConstant(0, mode);
219
220 std::tie(frame_ptr, argument_count, formal_parameter_count) =
221 GetArgumentsFrameAndCount(function, mode);
222
223 GotoIfFixedArraySizeDoesntFitInNewSpace(
224 argument_count, &runtime,
225 JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize, mode);
226
227 Node* const native_context = LoadNativeContext(context);
228 Node* const map =
229 LoadContextElement(native_context, Context::STRICT_ARGUMENTS_MAP_INDEX);
230 GotoIf(WordEqual(argument_count, zero), &empty);
231
232 result.Bind(ConstructParametersObjectFromArgs(
233 map, frame_ptr, argument_count, zero, argument_count, mode,
234 JSStrictArgumentsObject::kSize));
235 Goto(&done);
236
237 Bind(&empty);
238 {
239 Node* arguments;
240 Node* elements;
241 Node* unused;
242 std::tie(arguments, elements, unused) = AllocateArgumentsObject(
243 map, zero, nullptr, mode, JSStrictArgumentsObject::kSize);
244 result.Bind(arguments);
245 Goto(&done);
246 }
247
248 Bind(&runtime);
249 {
250 result.Bind(CallRuntime(Runtime::kNewStrictArguments, context, function));
251 Goto(&done);
252 }
253
254 Bind(&done);
255 return result.value();
256 }
257
258 TF_BUILTIN(FastNewStrictArguments, ArgumentsBuiltinsAssembler) {
259 Node* function = Parameter(FastNewArgumentsDescriptor::kFunction);
260 Node* context = Parameter(FastNewArgumentsDescriptor::kContext);
261 Return(EmitFastNewStrictArguments(context, function));
262 }
263
264 Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context,
265 Node* function) {
266 Node* frame_ptr;
267 Node* argument_count;
268 Node* formal_parameter_count;
269 Variable result(this, MachineRepresentation::kTagged);
270
271 ParameterMode mode = OptimalParameterMode();
272 Node* zero = IntPtrOrSmiConstant(0, mode);
273
274 Label done(this, &result), empty(this), no_parameters(this),
275 runtime(this, Label::kDeferred);
276
277 std::tie(frame_ptr, argument_count, formal_parameter_count) =
278 GetArgumentsFrameAndCount(function, mode);
279
280 GotoIf(WordEqual(argument_count, zero), &empty);
281
282 GotoIf(WordEqual(formal_parameter_count, zero), &no_parameters);
283
284 {
285 Comment("Mapped parameter JSSloppyArgumentsObject");
286
287 Node* mapped_count =
288 IntPtrOrSmiMin(argument_count, formal_parameter_count, mode);
289
290 Node* parameter_map_size =
291 IntPtrOrSmiAdd(mapped_count, IntPtrOrSmiConstant(2, mode), mode);
292
293 // Verify that the overall allocation will fit in new space.
294 Node* elements_allocated =
295 IntPtrOrSmiAdd(argument_count, parameter_map_size, mode);
296 GotoIfFixedArraySizeDoesntFitInNewSpace(
297 elements_allocated, &runtime,
298 JSSloppyArgumentsObject::kSize + FixedArray::kHeaderSize * 2, mode);
299
300 Node* const native_context = LoadNativeContext(context);
301 Node* const map = LoadContextElement(
302 native_context, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX);
303 Node* argument_object;
304 Node* elements;
305 Node* map_array;
306 std::tie(argument_object, elements, map_array) =
307 AllocateArgumentsObject(map, argument_count, parameter_map_size, mode,
308 JSSloppyArgumentsObject::kSize);
309 StoreObjectFieldNoWriteBarrier(
310 argument_object, JSSloppyArgumentsObject::kCalleeOffset, function);
311 StoreFixedArrayElement(map_array, 0, context, SKIP_WRITE_BARRIER);
312 StoreFixedArrayElement(map_array, 1, elements, SKIP_WRITE_BARRIER);
313
314 Comment("Fill in non-mapped parameters");
315 Node* argument_offset =
316 ElementOffsetFromIndex(argument_count, FAST_ELEMENTS, mode,
317 FixedArray::kHeaderSize - kHeapObjectTag);
318 Node* mapped_offset =
319 ElementOffsetFromIndex(mapped_count, FAST_ELEMENTS, mode,
320 FixedArray::kHeaderSize - kHeapObjectTag);
321 CodeStubArguments arguments(this, argument_count, frame_ptr, mode);
322 Variable current_argument(this, MachineType::PointerRepresentation());
323 current_argument.Bind(arguments.AtIndexPtr(argument_count, mode));
324 VariableList var_list1({&current_argument}, zone());
325 mapped_offset = BuildFastLoop(
326 var_list1, argument_offset, mapped_offset,
327 [this, elements, &current_argument](Node* offset) {
328 Increment(current_argument, kPointerSize);
329 Node* arg = LoadBufferObject(current_argument.value(), 0);
330 StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, offset,
331 arg);
332 },
333 -kPointerSize, INTPTR_PARAMETERS);
334
335 // Copy the parameter slots and the holes in the arguments.
336 // We need to fill in mapped_count slots. They index the context,
337 // where parameters are stored in reverse order, at
338 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+argument_count-1
339 // The mapped parameter thus need to get indices
340 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
341 // MIN_CONTEXT_SLOTS+argument_count-mapped_count
342 // We loop from right to left.
343 Comment("Fill in mapped parameters");
344 Variable context_index(this, OptimalParameterRepresentation());
345 context_index.Bind(IntPtrOrSmiSub(
346 IntPtrOrSmiAdd(IntPtrOrSmiConstant(Context::MIN_CONTEXT_SLOTS, mode),
347 formal_parameter_count, mode),
348 mapped_count, mode));
349 Node* the_hole = TheHoleConstant();
350 VariableList var_list2({&context_index}, zone());
351 const int kParameterMapHeaderSize =
352 FixedArray::kHeaderSize + 2 * kPointerSize;
353 Node* adjusted_map_array = IntPtrAdd(
354 BitcastTaggedToWord(map_array),
355 IntPtrConstant(kParameterMapHeaderSize - FixedArray::kHeaderSize));
356 Node* zero_offset = ElementOffsetFromIndex(
357 zero, FAST_ELEMENTS, mode, FixedArray::kHeaderSize - kHeapObjectTag);
358 BuildFastLoop(var_list2, mapped_offset, zero_offset,
359 [this, the_hole, elements, adjusted_map_array, &context_index,
360 mode](Node* offset) {
361 StoreNoWriteBarrier(MachineRepresentation::kTagged,
362 elements, offset, the_hole);
363 StoreNoWriteBarrier(
364 MachineRepresentation::kTagged, adjusted_map_array,
365 offset, ParameterToTagged(context_index.value(), mode));
366 Increment(context_index, 1, mode);
367 },
368 -kPointerSize, INTPTR_PARAMETERS);
369
370 result.Bind(argument_object);
371 Goto(&done);
372 }
373
374 Bind(&no_parameters);
375 {
376 Comment("No parameters JSSloppyArgumentsObject");
377 GotoIfFixedArraySizeDoesntFitInNewSpace(
378 argument_count, &runtime,
379 JSSloppyArgumentsObject::kSize + FixedArray::kHeaderSize, mode);
380 Node* const native_context = LoadNativeContext(context);
381 Node* const map =
382 LoadContextElement(native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX);
383 result.Bind(ConstructParametersObjectFromArgs(
384 map, frame_ptr, argument_count, zero, argument_count, mode,
385 JSSloppyArgumentsObject::kSize));
386 StoreObjectFieldNoWriteBarrier(
387 result.value(), JSSloppyArgumentsObject::kCalleeOffset, function);
388 Goto(&done);
389 }
390
391 Bind(&empty);
392 {
393 Comment("Empty JSSloppyArgumentsObject");
394 Node* const native_context = LoadNativeContext(context);
395 Node* const map =
396 LoadContextElement(native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX);
397 Node* arguments;
398 Node* elements;
399 Node* unused;
400 std::tie(arguments, elements, unused) = AllocateArgumentsObject(
401 map, zero, nullptr, mode, JSSloppyArgumentsObject::kSize);
402 result.Bind(arguments);
403 StoreObjectFieldNoWriteBarrier(
404 result.value(), JSSloppyArgumentsObject::kCalleeOffset, function);
405 Goto(&done);
406 }
407
408 Bind(&runtime);
409 {
410 result.Bind(CallRuntime(Runtime::kNewSloppyArguments, context, function));
411 Goto(&done);
412 }
413
414 Bind(&done);
415 return result.value();
416 }
417
418 TF_BUILTIN(FastNewSloppyArguments, ArgumentsBuiltinsAssembler) {
419 Node* function = Parameter(FastNewArgumentsDescriptor::kFunction);
420 Node* context = Parameter(FastNewArgumentsDescriptor::kContext);
421 Return(EmitFastNewSloppyArguments(context, function));
422 }
423
424 } // namespace internal
425 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.cc ('k') | src/builtins/builtins-arguments-gen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698