Index: src/arm64/code-stubs-arm64.cc |
diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc |
index a3ab71d61e40c05ff4510b15374492c3641cfc81..acba33f5459ad735d920242a5c678a6ae0cbfda6 100644 |
--- a/src/arm64/code-stubs-arm64.cc |
+++ b/src/arm64/code-stubs-arm64.cc |
@@ -3350,581 +3350,6 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) { |
GenerateCase(masm, FAST_ELEMENTS); |
} |
-void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
- // ----------- S t a t e ------------- |
- // -- x1 : function |
- // -- cp : context |
- // -- fp : frame pointer |
- // -- lr : return address |
- // ----------------------------------- |
- __ AssertFunction(x1); |
- |
- // Make x2 point to the JavaScript frame. |
- __ Mov(x2, fp); |
- if (skip_stub_frame()) { |
- // For Ignition we need to skip the handler/stub frame to reach the |
- // JavaScript frame for the function. |
- __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset)); |
- } |
- if (FLAG_debug_code) { |
- Label ok; |
- __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kFunctionOffset)); |
- __ Cmp(x3, x1); |
- __ B(eq, &ok); |
- __ Abort(kInvalidFrameForFastNewRestArgumentsStub); |
- __ Bind(&ok); |
- } |
- |
- // Check if we have rest parameters (only possible if we have an |
- // arguments adaptor frame below the function frame). |
- Label no_rest_parameters; |
- __ Ldr(x2, MemOperand(x2, CommonFrameConstants::kCallerFPOffset)); |
- __ Ldr(x3, MemOperand(x2, CommonFrameConstants::kContextOrFrameTypeOffset)); |
- __ Cmp(x3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
- __ B(ne, &no_rest_parameters); |
- |
- // Check if the arguments adaptor frame contains more arguments than |
- // specified by the function's internal formal parameter count. |
- Label rest_parameters; |
- __ Ldrsw(x0, UntagSmiMemOperand( |
- x2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
- __ Ldrsw( |
- x3, FieldMemOperand(x3, SharedFunctionInfo::kFormalParameterCountOffset)); |
- __ Subs(x0, x0, x3); |
- __ B(gt, &rest_parameters); |
- |
- // Return an empty rest parameter array. |
- __ Bind(&no_rest_parameters); |
- { |
- // ----------- S t a t e ------------- |
- // -- cp : context |
- // -- lr : return address |
- // ----------------------------------- |
- |
- // Allocate an empty rest parameter array. |
- Label allocate, done_allocate; |
- __ Allocate(JSArray::kSize, x0, x1, x2, &allocate, NO_ALLOCATION_FLAGS); |
- __ Bind(&done_allocate); |
- |
- // Setup the rest parameter array in x0. |
- __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, x1); |
- __ Str(x1, FieldMemOperand(x0, JSArray::kMapOffset)); |
- __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex); |
- __ Str(x1, FieldMemOperand(x0, JSArray::kPropertiesOffset)); |
- __ Str(x1, FieldMemOperand(x0, JSArray::kElementsOffset)); |
- __ Mov(x1, Smi::kZero); |
- __ Str(x1, FieldMemOperand(x0, JSArray::kLengthOffset)); |
- STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
- __ Ret(); |
- |
- // Fall back to %AllocateInNewSpace. |
- __ Bind(&allocate); |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- __ Push(Smi::FromInt(JSArray::kSize)); |
- __ CallRuntime(Runtime::kAllocateInNewSpace); |
- } |
- __ B(&done_allocate); |
- } |
- |
- __ Bind(&rest_parameters); |
- { |
- // Compute the pointer to the first rest parameter (skippping the receiver). |
- __ Add(x2, x2, Operand(x0, LSL, kPointerSizeLog2)); |
- __ Add(x2, x2, StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize); |
- |
- // ----------- S t a t e ------------- |
- // -- cp : context |
- // -- x0 : number of rest parameters |
- // -- x1 : function |
- // -- x2 : pointer to first rest parameters |
- // -- lr : return address |
- // ----------------------------------- |
- |
- // Allocate space for the rest parameter array plus the backing store. |
- Label allocate, done_allocate; |
- __ Mov(x6, JSArray::kSize + FixedArray::kHeaderSize); |
- __ Add(x6, x6, Operand(x0, LSL, kPointerSizeLog2)); |
- __ Allocate(x6, x3, x4, x5, &allocate, NO_ALLOCATION_FLAGS); |
- __ Bind(&done_allocate); |
- |
- // Compute arguments.length in x6. |
- __ SmiTag(x6, x0); |
- |
- // Setup the elements array in x3. |
- __ LoadRoot(x1, Heap::kFixedArrayMapRootIndex); |
- __ Str(x1, FieldMemOperand(x3, FixedArray::kMapOffset)); |
- __ Str(x6, FieldMemOperand(x3, FixedArray::kLengthOffset)); |
- __ Add(x4, x3, FixedArray::kHeaderSize); |
- { |
- Label loop, done_loop; |
- __ Add(x0, x4, Operand(x0, LSL, kPointerSizeLog2)); |
- __ Bind(&loop); |
- __ Cmp(x4, x0); |
- __ B(eq, &done_loop); |
- __ Ldr(x5, MemOperand(x2, 0 * kPointerSize)); |
- __ Str(x5, FieldMemOperand(x4, 0 * kPointerSize)); |
- __ Sub(x2, x2, Operand(1 * kPointerSize)); |
- __ Add(x4, x4, Operand(1 * kPointerSize)); |
- __ B(&loop); |
- __ Bind(&done_loop); |
- } |
- |
- // Setup the rest parameter array in x0. |
- __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, x1); |
- __ Str(x1, FieldMemOperand(x0, JSArray::kMapOffset)); |
- __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex); |
- __ Str(x1, FieldMemOperand(x0, JSArray::kPropertiesOffset)); |
- __ Str(x3, FieldMemOperand(x0, JSArray::kElementsOffset)); |
- __ Str(x6, FieldMemOperand(x0, JSArray::kLengthOffset)); |
- STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
- __ Ret(); |
- |
- // Fall back to %AllocateInNewSpace (if not too big). |
- Label too_big_for_new_space; |
- __ Bind(&allocate); |
- __ Cmp(x6, Operand(kMaxRegularHeapObjectSize)); |
- __ B(gt, &too_big_for_new_space); |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- __ SmiTag(x0); |
- __ SmiTag(x6); |
- __ Push(x0, x2, x6); |
- __ CallRuntime(Runtime::kAllocateInNewSpace); |
- __ Mov(x3, x0); |
- __ Pop(x2, x0); |
- __ SmiUntag(x0); |
- } |
- __ B(&done_allocate); |
- |
- // Fall back to %NewRestParameter. |
- __ Bind(&too_big_for_new_space); |
- __ Push(x1); |
- __ TailCallRuntime(Runtime::kNewRestParameter); |
- } |
-} |
- |
- |
-void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) { |
- // ----------- S t a t e ------------- |
- // -- x1 : function |
- // -- cp : context |
- // -- fp : frame pointer |
- // -- lr : return address |
- // ----------------------------------- |
- __ AssertFunction(x1); |
- |
- // Make x6 point to the JavaScript frame. |
- __ Mov(x6, fp); |
- if (skip_stub_frame()) { |
- // For Ignition we need to skip the handler/stub frame to reach the |
- // JavaScript frame for the function. |
- __ Ldr(x6, MemOperand(x6, StandardFrameConstants::kCallerFPOffset)); |
- } |
- if (FLAG_debug_code) { |
- Label ok; |
- __ Ldr(x3, MemOperand(x6, StandardFrameConstants::kFunctionOffset)); |
- __ Cmp(x3, x1); |
- __ B(eq, &ok); |
- __ Abort(kInvalidFrameForFastNewRestArgumentsStub); |
- __ Bind(&ok); |
- } |
- |
- // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub. |
- __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
- __ Ldrsw( |
- x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset)); |
- __ Add(x3, x6, Operand(x2, LSL, kPointerSizeLog2)); |
- __ Add(x3, x3, Operand(StandardFrameConstants::kCallerSPOffset)); |
- __ SmiTag(x2); |
- |
- // x1 : function |
- // x2 : number of parameters (tagged) |
- // x3 : parameters pointer |
- // x6 : JavaScript frame pointer |
- // |
- // Returns pointer to result object in x0. |
- |
- // Make an untagged copy of the parameter count. |
- // Note: arg_count_smi is an alias of param_count_smi. |
- Register function = x1; |
- Register arg_count_smi = x2; |
- Register param_count_smi = x2; |
- Register recv_arg = x3; |
- Register param_count = x7; |
- __ SmiUntag(param_count, param_count_smi); |
- |
- // Check if the calling frame is an arguments adaptor frame. |
- Register caller_fp = x11; |
- Register caller_ctx = x12; |
- Label runtime; |
- Label adaptor_frame, try_allocate; |
- __ Ldr(caller_fp, MemOperand(x6, StandardFrameConstants::kCallerFPOffset)); |
- __ Ldr( |
- caller_ctx, |
- MemOperand(caller_fp, CommonFrameConstants::kContextOrFrameTypeOffset)); |
- __ Cmp(caller_ctx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
- __ B(eq, &adaptor_frame); |
- |
- // No adaptor, parameter count = argument count. |
- |
- // x1 function function pointer |
- // x2 arg_count_smi number of function arguments (smi) |
- // x3 recv_arg pointer to receiver arguments |
- // x4 mapped_params number of mapped params, min(params, args) (uninit) |
- // x7 param_count number of function parameters |
- // x11 caller_fp caller's frame pointer |
- // x14 arg_count number of function arguments (uninit) |
- |
- Register arg_count = x14; |
- Register mapped_params = x4; |
- __ Mov(arg_count, param_count); |
- __ Mov(mapped_params, param_count); |
- __ B(&try_allocate); |
- |
- // We have an adaptor frame. Patch the parameters pointer. |
- __ Bind(&adaptor_frame); |
- __ Ldr(arg_count_smi, |
- MemOperand(caller_fp, |
- ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- __ SmiUntag(arg_count, arg_count_smi); |
- __ Add(x10, caller_fp, Operand(arg_count, LSL, kPointerSizeLog2)); |
- __ Add(recv_arg, x10, StandardFrameConstants::kCallerSPOffset); |
- |
- // Compute the mapped parameter count = min(param_count, arg_count) |
- __ Cmp(param_count, arg_count); |
- __ Csel(mapped_params, param_count, arg_count, lt); |
- |
- __ Bind(&try_allocate); |
- |
- // x0 alloc_obj pointer to allocated objects: param map, backing |
- // store, arguments (uninit) |
- // x1 function function pointer |
- // x2 arg_count_smi number of function arguments (smi) |
- // x3 recv_arg pointer to receiver arguments |
- // x4 mapped_params number of mapped parameters, min(params, args) |
- // x7 param_count number of function parameters |
- // x10 size size of objects to allocate (uninit) |
- // x14 arg_count number of function arguments |
- |
- // Compute the size of backing store, parameter map, and arguments object. |
- // 1. Parameter map, has two extra words containing context and backing |
- // store. |
- const int kParameterMapHeaderSize = |
- FixedArray::kHeaderSize + 2 * kPointerSize; |
- |
- // Calculate the parameter map size, assuming it exists. |
- Register size = x10; |
- __ Mov(size, Operand(mapped_params, LSL, kPointerSizeLog2)); |
- __ Add(size, size, kParameterMapHeaderSize); |
- |
- // If there are no mapped parameters, set the running size total to zero. |
- // Otherwise, use the parameter map size calculated earlier. |
- __ Cmp(mapped_params, 0); |
- __ CzeroX(size, eq); |
- |
- // 2. Add the size of the backing store and arguments object. |
- __ Add(size, size, Operand(arg_count, LSL, kPointerSizeLog2)); |
- __ Add(size, size, FixedArray::kHeaderSize + JSSloppyArgumentsObject::kSize); |
- |
- // Do the allocation of all three objects in one go. Assign this to x0, as it |
- // will be returned to the caller. |
- Register alloc_obj = x0; |
- __ Allocate(size, alloc_obj, x11, x12, &runtime, NO_ALLOCATION_FLAGS); |
- |
- // Get the arguments boilerplate from the current (global) context. |
- |
- // x0 alloc_obj pointer to allocated objects (param map, backing |
- // store, arguments) |
- // x1 function function pointer |
- // x2 arg_count_smi number of function arguments (smi) |
- // x3 recv_arg pointer to receiver arguments |
- // x4 mapped_params number of mapped parameters, min(params, args) |
- // x7 param_count number of function parameters |
- // x11 sloppy_args_map offset to args (or aliased args) map (uninit) |
- // x14 arg_count number of function arguments |
- |
- Register global_ctx = x10; |
- Register sloppy_args_map = x11; |
- Register aliased_args_map = x10; |
- __ Ldr(global_ctx, NativeContextMemOperand()); |
- |
- __ Ldr(sloppy_args_map, |
- ContextMemOperand(global_ctx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); |
- __ Ldr( |
- aliased_args_map, |
- ContextMemOperand(global_ctx, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)); |
- __ Cmp(mapped_params, 0); |
- __ CmovX(sloppy_args_map, aliased_args_map, ne); |
- |
- // Copy the JS object part. |
- __ Str(sloppy_args_map, FieldMemOperand(alloc_obj, JSObject::kMapOffset)); |
- __ LoadRoot(x10, Heap::kEmptyFixedArrayRootIndex); |
- __ Str(x10, FieldMemOperand(alloc_obj, JSObject::kPropertiesOffset)); |
- __ Str(x10, FieldMemOperand(alloc_obj, JSObject::kElementsOffset)); |
- |
- // Set up the callee in-object property. |
- __ AssertNotSmi(function); |
- __ Str(function, |
- FieldMemOperand(alloc_obj, JSSloppyArgumentsObject::kCalleeOffset)); |
- |
- // Use the length and set that as an in-object property. |
- __ Str(arg_count_smi, |
- FieldMemOperand(alloc_obj, JSSloppyArgumentsObject::kLengthOffset)); |
- |
- // Set up the elements pointer in the allocated arguments object. |
- // If we allocated a parameter map, "elements" will point there, otherwise |
- // it will point to the backing store. |
- |
- // x0 alloc_obj pointer to allocated objects (param map, backing |
- // store, arguments) |
- // x1 function function pointer |
- // x2 arg_count_smi number of function arguments (smi) |
- // x3 recv_arg pointer to receiver arguments |
- // x4 mapped_params number of mapped parameters, min(params, args) |
- // x5 elements pointer to parameter map or backing store (uninit) |
- // x6 backing_store pointer to backing store (uninit) |
- // x7 param_count number of function parameters |
- // x14 arg_count number of function arguments |
- |
- Register elements = x5; |
- __ Add(elements, alloc_obj, JSSloppyArgumentsObject::kSize); |
- __ Str(elements, FieldMemOperand(alloc_obj, JSObject::kElementsOffset)); |
- |
- // Initialize parameter map. If there are no mapped arguments, we're done. |
- Label skip_parameter_map; |
- __ Cmp(mapped_params, 0); |
- // Set up backing store address, because it is needed later for filling in |
- // the unmapped arguments. |
- Register backing_store = x6; |
- __ CmovX(backing_store, elements, eq); |
- __ B(eq, &skip_parameter_map); |
- |
- __ LoadRoot(x10, Heap::kSloppyArgumentsElementsMapRootIndex); |
- __ Str(x10, FieldMemOperand(elements, FixedArray::kMapOffset)); |
- __ Add(x10, mapped_params, 2); |
- __ SmiTag(x10); |
- __ Str(x10, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
- __ Str(cp, FieldMemOperand(elements, |
- FixedArray::kHeaderSize + 0 * kPointerSize)); |
- __ Add(x10, elements, Operand(mapped_params, LSL, kPointerSizeLog2)); |
- __ Add(x10, x10, kParameterMapHeaderSize); |
- __ Str(x10, FieldMemOperand(elements, |
- FixedArray::kHeaderSize + 1 * kPointerSize)); |
- |
- // Copy the parameter slots and the holes in the arguments. |
- // We need to fill in mapped_parameter_count slots. Then index the context, |
- // where parameters are stored in reverse order, at: |
- // |
- // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS + parameter_count - 1 |
- // |
- // The mapped parameter thus needs to get indices: |
- // |
- // MIN_CONTEXT_SLOTS + parameter_count - 1 .. |
- // MIN_CONTEXT_SLOTS + parameter_count - mapped_parameter_count |
- // |
- // We loop from right to left. |
- |
- // x0 alloc_obj pointer to allocated objects (param map, backing |
- // store, arguments) |
- // x1 function function pointer |
- // x2 arg_count_smi number of function arguments (smi) |
- // x3 recv_arg pointer to receiver arguments |
- // x4 mapped_params number of mapped parameters, min(params, args) |
- // x5 elements pointer to parameter map or backing store (uninit) |
- // x6 backing_store pointer to backing store (uninit) |
- // x7 param_count number of function parameters |
- // x11 loop_count parameter loop counter (uninit) |
- // x12 index parameter index (smi, uninit) |
- // x13 the_hole hole value (uninit) |
- // x14 arg_count number of function arguments |
- |
- Register loop_count = x11; |
- Register index = x12; |
- Register the_hole = x13; |
- Label parameters_loop, parameters_test; |
- __ Mov(loop_count, mapped_params); |
- __ Add(index, param_count, static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
- __ Sub(index, index, mapped_params); |
- __ SmiTag(index); |
- __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex); |
- __ Add(backing_store, elements, Operand(loop_count, LSL, kPointerSizeLog2)); |
- __ Add(backing_store, backing_store, kParameterMapHeaderSize); |
- |
- __ B(¶meters_test); |
- |
- __ Bind(¶meters_loop); |
- __ Sub(loop_count, loop_count, 1); |
- __ Mov(x10, Operand(loop_count, LSL, kPointerSizeLog2)); |
- __ Add(x10, x10, kParameterMapHeaderSize - kHeapObjectTag); |
- __ Str(index, MemOperand(elements, x10)); |
- __ Sub(x10, x10, kParameterMapHeaderSize - FixedArray::kHeaderSize); |
- __ Str(the_hole, MemOperand(backing_store, x10)); |
- __ Add(index, index, Smi::FromInt(1)); |
- __ Bind(¶meters_test); |
- __ Cbnz(loop_count, ¶meters_loop); |
- |
- __ Bind(&skip_parameter_map); |
- // Copy arguments header and remaining slots (if there are any.) |
- __ LoadRoot(x10, Heap::kFixedArrayMapRootIndex); |
- __ Str(x10, FieldMemOperand(backing_store, FixedArray::kMapOffset)); |
- __ Str(arg_count_smi, FieldMemOperand(backing_store, |
- FixedArray::kLengthOffset)); |
- |
- // x0 alloc_obj pointer to allocated objects (param map, backing |
- // store, arguments) |
- // x1 function function pointer |
- // x2 arg_count_smi number of function arguments (smi) |
- // x3 recv_arg pointer to receiver arguments |
- // x4 mapped_params number of mapped parameters, min(params, args) |
- // x6 backing_store pointer to backing store (uninit) |
- // x14 arg_count number of function arguments |
- |
- Label arguments_loop, arguments_test; |
- __ Mov(x10, mapped_params); |
- __ Sub(recv_arg, recv_arg, Operand(x10, LSL, kPointerSizeLog2)); |
- __ B(&arguments_test); |
- |
- __ Bind(&arguments_loop); |
- __ Sub(recv_arg, recv_arg, kPointerSize); |
- __ Ldr(x11, MemOperand(recv_arg)); |
- __ Add(x12, backing_store, Operand(x10, LSL, kPointerSizeLog2)); |
- __ Str(x11, FieldMemOperand(x12, FixedArray::kHeaderSize)); |
- __ Add(x10, x10, 1); |
- |
- __ Bind(&arguments_test); |
- __ Cmp(x10, arg_count); |
- __ B(lt, &arguments_loop); |
- |
- __ Ret(); |
- |
- // Do the runtime call to allocate the arguments object. |
- __ Bind(&runtime); |
- __ Push(function, recv_arg, arg_count_smi); |
- __ TailCallRuntime(Runtime::kNewSloppyArguments); |
-} |
- |
- |
-void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { |
- // ----------- S t a t e ------------- |
- // -- x1 : function |
- // -- cp : context |
- // -- fp : frame pointer |
- // -- lr : return address |
- // ----------------------------------- |
- __ AssertFunction(x1); |
- |
- // Make x2 point to the JavaScript frame. |
- __ Mov(x2, fp); |
- if (skip_stub_frame()) { |
- // For Ignition we need to skip the handler/stub frame to reach the |
- // JavaScript frame for the function. |
- __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset)); |
- } |
- if (FLAG_debug_code) { |
- Label ok; |
- __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kFunctionOffset)); |
- __ Cmp(x3, x1); |
- __ B(eq, &ok); |
- __ Abort(kInvalidFrameForFastNewRestArgumentsStub); |
- __ Bind(&ok); |
- } |
- |
- // Check if we have an arguments adaptor frame below the function frame. |
- Label arguments_adaptor, arguments_done; |
- __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kCallerFPOffset)); |
- __ Ldr(x4, MemOperand(x3, CommonFrameConstants::kContextOrFrameTypeOffset)); |
- __ Cmp(x4, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
- __ B(eq, &arguments_adaptor); |
- { |
- __ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
- __ Ldrsw(x0, FieldMemOperand( |
- x4, SharedFunctionInfo::kFormalParameterCountOffset)); |
- __ Add(x2, x2, Operand(x0, LSL, kPointerSizeLog2)); |
- __ Add(x2, x2, StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize); |
- } |
- __ B(&arguments_done); |
- __ Bind(&arguments_adaptor); |
- { |
- __ Ldrsw(x0, UntagSmiMemOperand( |
- x3, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- __ Add(x2, x3, Operand(x0, LSL, kPointerSizeLog2)); |
- __ Add(x2, x2, StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize); |
- } |
- __ Bind(&arguments_done); |
- |
- // ----------- S t a t e ------------- |
- // -- cp : context |
- // -- x0 : number of rest parameters |
- // -- x1 : function |
- // -- x2 : pointer to first rest parameters |
- // -- lr : return address |
- // ----------------------------------- |
- |
- // Allocate space for the strict arguments object plus the backing store. |
- Label allocate, done_allocate; |
- __ Mov(x6, JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize); |
- __ Add(x6, x6, Operand(x0, LSL, kPointerSizeLog2)); |
- __ Allocate(x6, x3, x4, x5, &allocate, NO_ALLOCATION_FLAGS); |
- __ Bind(&done_allocate); |
- |
- // Compute arguments.length in x6. |
- __ SmiTag(x6, x0); |
- |
- // Setup the elements array in x3. |
- __ LoadRoot(x1, Heap::kFixedArrayMapRootIndex); |
- __ Str(x1, FieldMemOperand(x3, FixedArray::kMapOffset)); |
- __ Str(x6, FieldMemOperand(x3, FixedArray::kLengthOffset)); |
- __ Add(x4, x3, FixedArray::kHeaderSize); |
- { |
- Label loop, done_loop; |
- __ Add(x0, x4, Operand(x0, LSL, kPointerSizeLog2)); |
- __ Bind(&loop); |
- __ Cmp(x4, x0); |
- __ B(eq, &done_loop); |
- __ Ldr(x5, MemOperand(x2, 0 * kPointerSize)); |
- __ Str(x5, FieldMemOperand(x4, 0 * kPointerSize)); |
- __ Sub(x2, x2, Operand(1 * kPointerSize)); |
- __ Add(x4, x4, Operand(1 * kPointerSize)); |
- __ B(&loop); |
- __ Bind(&done_loop); |
- } |
- |
- // Setup the strict arguments object in x0. |
- __ LoadNativeContextSlot(Context::STRICT_ARGUMENTS_MAP_INDEX, x1); |
- __ Str(x1, FieldMemOperand(x0, JSStrictArgumentsObject::kMapOffset)); |
- __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex); |
- __ Str(x1, FieldMemOperand(x0, JSStrictArgumentsObject::kPropertiesOffset)); |
- __ Str(x3, FieldMemOperand(x0, JSStrictArgumentsObject::kElementsOffset)); |
- __ Str(x6, FieldMemOperand(x0, JSStrictArgumentsObject::kLengthOffset)); |
- STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize); |
- __ Ret(); |
- |
- // Fall back to %AllocateInNewSpace (if not too big). |
- Label too_big_for_new_space; |
- __ Bind(&allocate); |
- __ Cmp(x6, Operand(kMaxRegularHeapObjectSize)); |
- __ B(gt, &too_big_for_new_space); |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- __ SmiTag(x0); |
- __ SmiTag(x6); |
- __ Push(x0, x2, x6); |
- __ CallRuntime(Runtime::kAllocateInNewSpace); |
- __ Mov(x3, x0); |
- __ Pop(x2, x0); |
- __ SmiUntag(x0); |
- } |
- __ B(&done_allocate); |
- |
- // Fall back to %NewStrictArguments. |
- __ Bind(&too_big_for_new_space); |
- __ Push(x1); |
- __ TailCallRuntime(Runtime::kNewStrictArguments); |
-} |
- |
- |
// The number of register that CallApiFunctionAndReturn will need to save on |
// the stack. The space for these registers need to be allocated in the |
// ExitFrame before calling CallApiFunctionAndReturn. |