Index: src/ia32/code-stubs-ia32.cc |
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
index 9cf2e56a8a2a9e3f24a4f059c063e4c4f6e02dff..cd6f64e015e896a12d22f3d8b386de9636e84c12 100644 |
--- a/src/ia32/code-stubs-ia32.cc |
+++ b/src/ia32/code-stubs-ia32.cc |
@@ -3065,558 +3065,6 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) { |
GenerateCase(masm, FAST_ELEMENTS); |
} |
-void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
- // ----------- S t a t e ------------- |
- // -- edi : function |
- // -- esi : context |
- // -- ebp : frame pointer |
- // -- esp[0] : return address |
- // ----------------------------------- |
- __ AssertFunction(edi); |
- |
- // Make edx point to the JavaScript frame. |
- __ mov(edx, ebp); |
- if (skip_stub_frame()) { |
- // For Ignition we need to skip the handler/stub frame to reach the |
- // JavaScript frame for the function. |
- __ mov(edx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); |
- } |
- if (FLAG_debug_code) { |
- Label ok; |
- __ cmp(edi, Operand(edx, StandardFrameConstants::kFunctionOffset)); |
- __ j(equal, &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; |
- __ mov(ebx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); |
- __ cmp(Operand(ebx, CommonFrameConstants::kContextOrFrameTypeOffset), |
- Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
- __ j(not_equal, &no_rest_parameters, Label::kNear); |
- |
- // Check if the arguments adaptor frame contains more arguments than |
- // specified by the function's internal formal parameter count. |
- Label rest_parameters; |
- __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
- __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- __ sub(eax, |
- FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); |
- __ j(greater, &rest_parameters); |
- |
- // Return an empty rest parameter array. |
- __ bind(&no_rest_parameters); |
- { |
- // ----------- S t a t e ------------- |
- // -- esi : context |
- // -- esp[0] : return address |
- // ----------------------------------- |
- |
- // Allocate an empty rest parameter array. |
- Label allocate, done_allocate; |
- __ Allocate(JSArray::kSize, eax, edx, ecx, &allocate, NO_ALLOCATION_FLAGS); |
- __ bind(&done_allocate); |
- |
- // Setup the rest parameter array in rax. |
- __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); |
- __ mov(FieldOperand(eax, JSArray::kMapOffset), ecx); |
- __ mov(ecx, isolate()->factory()->empty_fixed_array()); |
- __ mov(FieldOperand(eax, JSArray::kPropertiesOffset), ecx); |
- __ mov(FieldOperand(eax, JSArray::kElementsOffset), ecx); |
- __ mov(FieldOperand(eax, JSArray::kLengthOffset), Immediate(Smi::kZero)); |
- 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); |
- } |
- __ jmp(&done_allocate); |
- } |
- |
- __ bind(&rest_parameters); |
- { |
- // Compute the pointer to the first rest parameter (skippping the receiver). |
- __ lea(ebx, |
- Operand(ebx, eax, times_half_pointer_size, |
- StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize)); |
- |
- // ----------- S t a t e ------------- |
- // -- esi : context |
- // -- eax : number of rest parameters (tagged) |
- // -- ebx : pointer to first rest parameters |
- // -- esp[0] : return address |
- // ----------------------------------- |
- |
- // Allocate space for the rest parameter array plus the backing store. |
- Label allocate, done_allocate; |
- __ lea(ecx, Operand(eax, times_half_pointer_size, |
- JSArray::kSize + FixedArray::kHeaderSize)); |
- __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
- __ bind(&done_allocate); |
- |
- // Setup the elements array in edx. |
- __ mov(FieldOperand(edx, FixedArray::kMapOffset), |
- isolate()->factory()->fixed_array_map()); |
- __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); |
- { |
- Label loop, done_loop; |
- __ Move(ecx, Smi::kZero); |
- __ bind(&loop); |
- __ cmp(ecx, eax); |
- __ j(equal, &done_loop, Label::kNear); |
- __ mov(edi, Operand(ebx, 0 * kPointerSize)); |
- __ mov(FieldOperand(edx, ecx, times_half_pointer_size, |
- FixedArray::kHeaderSize), |
- edi); |
- __ sub(ebx, Immediate(1 * kPointerSize)); |
- __ add(ecx, Immediate(Smi::FromInt(1))); |
- __ jmp(&loop); |
- __ bind(&done_loop); |
- } |
- |
- // Setup the rest parameter array in edi. |
- __ lea(edi, |
- Operand(edx, eax, times_half_pointer_size, FixedArray::kHeaderSize)); |
- __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); |
- __ mov(FieldOperand(edi, JSArray::kMapOffset), ecx); |
- __ mov(FieldOperand(edi, JSArray::kPropertiesOffset), |
- isolate()->factory()->empty_fixed_array()); |
- __ mov(FieldOperand(edi, JSArray::kElementsOffset), edx); |
- __ mov(FieldOperand(edi, JSArray::kLengthOffset), eax); |
- STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
- __ mov(eax, edi); |
- __ Ret(); |
- |
- // Fall back to %AllocateInNewSpace (if not too big). |
- Label too_big_for_new_space; |
- __ bind(&allocate); |
- __ cmp(ecx, Immediate(kMaxRegularHeapObjectSize)); |
- __ j(greater, &too_big_for_new_space); |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- __ SmiTag(ecx); |
- __ Push(eax); |
- __ Push(ebx); |
- __ Push(ecx); |
- __ CallRuntime(Runtime::kAllocateInNewSpace); |
- __ mov(edx, eax); |
- __ Pop(ebx); |
- __ Pop(eax); |
- } |
- __ jmp(&done_allocate); |
- |
- // Fall back to %NewRestParameter. |
- __ bind(&too_big_for_new_space); |
- __ PopReturnAddressTo(ecx); |
- // We reload the function from the caller frame due to register pressure |
- // within this stub. This is the slow path, hence reloading is preferable. |
- if (skip_stub_frame()) { |
- // For Ignition we need to skip the handler/stub frame to reach the |
- // JavaScript frame for the function. |
- __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
- __ Push(Operand(edx, StandardFrameConstants::kFunctionOffset)); |
- } else { |
- __ Push(Operand(ebp, StandardFrameConstants::kFunctionOffset)); |
- } |
- __ PushReturnAddressFrom(ecx); |
- __ TailCallRuntime(Runtime::kNewRestParameter); |
- } |
-} |
- |
- |
-void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) { |
- // ----------- S t a t e ------------- |
- // -- edi : function |
- // -- esi : context |
- // -- ebp : frame pointer |
- // -- esp[0] : return address |
- // ----------------------------------- |
- __ AssertFunction(edi); |
- |
- // Make ecx point to the JavaScript frame. |
- __ mov(ecx, ebp); |
- if (skip_stub_frame()) { |
- // For Ignition we need to skip the handler/stub frame to reach the |
- // JavaScript frame for the function. |
- __ mov(ecx, Operand(ecx, StandardFrameConstants::kCallerFPOffset)); |
- } |
- if (FLAG_debug_code) { |
- Label ok; |
- __ cmp(edi, Operand(ecx, StandardFrameConstants::kFunctionOffset)); |
- __ j(equal, &ok); |
- __ Abort(kInvalidFrameForFastNewSloppyArgumentsStub); |
- __ bind(&ok); |
- } |
- |
- // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub. |
- __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
- __ mov(ebx, |
- FieldOperand(ebx, SharedFunctionInfo::kFormalParameterCountOffset)); |
- __ lea(edx, Operand(ecx, ebx, times_half_pointer_size, |
- StandardFrameConstants::kCallerSPOffset)); |
- |
- // ebx : number of parameters (tagged) |
- // edx : parameters pointer |
- // edi : function |
- // ecx : JavaScript frame pointer. |
- // esp[0] : return address |
- |
- // Check if the calling frame is an arguments adaptor frame. |
- Label adaptor_frame, try_allocate, runtime; |
- __ mov(eax, Operand(ecx, StandardFrameConstants::kCallerFPOffset)); |
- __ mov(eax, Operand(eax, CommonFrameConstants::kContextOrFrameTypeOffset)); |
- __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
- __ j(equal, &adaptor_frame, Label::kNear); |
- |
- // No adaptor, parameter count = argument count. |
- __ mov(ecx, ebx); |
- __ push(ebx); |
- __ jmp(&try_allocate, Label::kNear); |
- |
- // We have an adaptor frame. Patch the parameters pointer. |
- __ bind(&adaptor_frame); |
- __ push(ebx); |
- __ mov(edx, Operand(ecx, StandardFrameConstants::kCallerFPOffset)); |
- __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- __ lea(edx, Operand(edx, ecx, times_2, |
- StandardFrameConstants::kCallerSPOffset)); |
- |
- // ebx = parameter count (tagged) |
- // ecx = argument count (smi-tagged) |
- // Compute the mapped parameter count = min(ebx, ecx) in ebx. |
- __ cmp(ebx, ecx); |
- __ j(less_equal, &try_allocate, Label::kNear); |
- __ mov(ebx, ecx); |
- |
- // Save mapped parameter count and function. |
- __ bind(&try_allocate); |
- __ push(edi); |
- __ push(ebx); |
- |
- // Compute the sizes of backing store, parameter map, and arguments object. |
- // 1. Parameter map, has 2 extra words containing context and backing store. |
- const int kParameterMapHeaderSize = |
- FixedArray::kHeaderSize + 2 * kPointerSize; |
- Label no_parameter_map; |
- __ test(ebx, ebx); |
- __ j(zero, &no_parameter_map, Label::kNear); |
- __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize)); |
- __ bind(&no_parameter_map); |
- |
- // 2. Backing store. |
- __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); |
- |
- // 3. Arguments object. |
- __ add(ebx, Immediate(JSSloppyArgumentsObject::kSize)); |
- |
- // Do the allocation of all three objects in one go. |
- __ Allocate(ebx, eax, edi, no_reg, &runtime, NO_ALLOCATION_FLAGS); |
- |
- // eax = address of new object(s) (tagged) |
- // ecx = argument count (smi-tagged) |
- // esp[0] = mapped parameter count (tagged) |
- // esp[4] = function |
- // esp[8] = parameter count (tagged) |
- // Get the arguments map from the current native context into edi. |
- Label has_mapped_parameters, instantiate; |
- __ mov(edi, NativeContextOperand()); |
- __ mov(ebx, Operand(esp, 0 * kPointerSize)); |
- __ test(ebx, ebx); |
- __ j(not_zero, &has_mapped_parameters, Label::kNear); |
- __ mov( |
- edi, |
- Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX))); |
- __ jmp(&instantiate, Label::kNear); |
- |
- __ bind(&has_mapped_parameters); |
- __ mov(edi, Operand(edi, Context::SlotOffset( |
- Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX))); |
- __ bind(&instantiate); |
- |
- // eax = address of new object (tagged) |
- // ebx = mapped parameter count (tagged) |
- // ecx = argument count (smi-tagged) |
- // edi = address of arguments map (tagged) |
- // esp[0] = mapped parameter count (tagged) |
- // esp[4] = function |
- // esp[8] = parameter count (tagged) |
- // Copy the JS object part. |
- __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); |
- __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), |
- masm->isolate()->factory()->empty_fixed_array()); |
- __ mov(FieldOperand(eax, JSObject::kElementsOffset), |
- masm->isolate()->factory()->empty_fixed_array()); |
- |
- // Set up the callee in-object property. |
- STATIC_ASSERT(JSSloppyArgumentsObject::kCalleeIndex == 1); |
- __ mov(edi, Operand(esp, 1 * kPointerSize)); |
- __ AssertNotSmi(edi); |
- __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kCalleeOffset), edi); |
- |
- // Use the length (smi tagged) and set that as an in-object property too. |
- __ AssertSmi(ecx); |
- __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kLengthOffset), ecx); |
- |
- // Set up the elements pointer in the allocated arguments object. |
- // If we allocated a parameter map, edi will point there, otherwise to the |
- // backing store. |
- __ lea(edi, Operand(eax, JSSloppyArgumentsObject::kSize)); |
- __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); |
- |
- // eax = address of new object (tagged) |
- // ebx = mapped parameter count (tagged) |
- // ecx = argument count (tagged) |
- // edx = address of receiver argument |
- // edi = address of parameter map or backing store (tagged) |
- // esp[0] = mapped parameter count (tagged) |
- // esp[4] = function |
- // esp[8] = parameter count (tagged) |
- // Free two registers. |
- __ push(edx); |
- __ push(eax); |
- |
- // Initialize parameter map. If there are no mapped arguments, we're done. |
- Label skip_parameter_map; |
- __ test(ebx, ebx); |
- __ j(zero, &skip_parameter_map); |
- |
- __ mov(FieldOperand(edi, FixedArray::kMapOffset), |
- Immediate(isolate()->factory()->sloppy_arguments_elements_map())); |
- __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2)))); |
- __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax); |
- __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi); |
- __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize)); |
- __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax); |
- |
- // Copy the parameter slots and the holes in the arguments. |
- // We need to fill in mapped_parameter_count slots. They index the context, |
- // where parameters are stored in reverse order, at |
- // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 |
- // The mapped parameter thus need to get indices |
- // MIN_CONTEXT_SLOTS+parameter_count-1 .. |
- // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count |
- // We loop from right to left. |
- Label parameters_loop, parameters_test; |
- __ push(ecx); |
- __ mov(eax, Operand(esp, 3 * kPointerSize)); |
- __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); |
- __ add(ebx, Operand(esp, 5 * kPointerSize)); |
- __ sub(ebx, eax); |
- __ mov(ecx, isolate()->factory()->the_hole_value()); |
- __ mov(edx, edi); |
- __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize)); |
- // eax = loop variable (tagged) |
- // ebx = mapping index (tagged) |
- // ecx = the hole value |
- // edx = address of parameter map (tagged) |
- // edi = address of backing store (tagged) |
- // esp[0] = argument count (tagged) |
- // esp[4] = address of new object (tagged) |
- // esp[8] = address of receiver argument |
- // esp[12] = mapped parameter count (tagged) |
- // esp[16] = function |
- // esp[20] = parameter count (tagged) |
- __ jmp(¶meters_test, Label::kNear); |
- |
- __ bind(¶meters_loop); |
- __ sub(eax, Immediate(Smi::FromInt(1))); |
- __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx); |
- __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx); |
- __ add(ebx, Immediate(Smi::FromInt(1))); |
- __ bind(¶meters_test); |
- __ test(eax, eax); |
- __ j(not_zero, ¶meters_loop, Label::kNear); |
- __ pop(ecx); |
- |
- __ bind(&skip_parameter_map); |
- |
- // ecx = argument count (tagged) |
- // edi = address of backing store (tagged) |
- // esp[0] = address of new object (tagged) |
- // esp[4] = address of receiver argument |
- // esp[8] = mapped parameter count (tagged) |
- // esp[12] = function |
- // esp[16] = parameter count (tagged) |
- // Copy arguments header and remaining slots (if there are any). |
- __ mov(FieldOperand(edi, FixedArray::kMapOffset), |
- Immediate(isolate()->factory()->fixed_array_map())); |
- __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); |
- |
- Label arguments_loop, arguments_test; |
- __ mov(ebx, Operand(esp, 2 * kPointerSize)); |
- __ mov(edx, Operand(esp, 1 * kPointerSize)); |
- __ sub(edx, ebx); // Is there a smarter way to do negative scaling? |
- __ sub(edx, ebx); |
- __ jmp(&arguments_test, Label::kNear); |
- |
- __ bind(&arguments_loop); |
- __ sub(edx, Immediate(kPointerSize)); |
- __ mov(eax, Operand(edx, 0)); |
- __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax); |
- __ add(ebx, Immediate(Smi::FromInt(1))); |
- |
- __ bind(&arguments_test); |
- __ cmp(ebx, ecx); |
- __ j(less, &arguments_loop, Label::kNear); |
- |
- // Restore. |
- __ pop(eax); // Address of arguments object. |
- __ Drop(4); |
- |
- // Return. |
- __ ret(0); |
- |
- // Do the runtime call to allocate the arguments object. |
- __ bind(&runtime); |
- __ pop(eax); // Remove saved mapped parameter count. |
- __ pop(edi); // Pop saved function. |
- __ pop(eax); // Remove saved parameter count. |
- __ pop(eax); // Pop return address. |
- __ push(edi); // Push function. |
- __ push(edx); // Push parameters pointer. |
- __ push(ecx); // Push parameter count. |
- __ push(eax); // Push return address. |
- __ TailCallRuntime(Runtime::kNewSloppyArguments); |
-} |
- |
-void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { |
- // ----------- S t a t e ------------- |
- // -- edi : function |
- // -- esi : context |
- // -- ebp : frame pointer |
- // -- esp[0] : return address |
- // ----------------------------------- |
- __ AssertFunction(edi); |
- |
- // Make edx point to the JavaScript frame. |
- __ mov(edx, ebp); |
- if (skip_stub_frame()) { |
- // For Ignition we need to skip the handler/stub frame to reach the |
- // JavaScript frame for the function. |
- __ mov(edx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); |
- } |
- if (FLAG_debug_code) { |
- Label ok; |
- __ cmp(edi, Operand(edx, StandardFrameConstants::kFunctionOffset)); |
- __ j(equal, &ok); |
- __ Abort(kInvalidFrameForFastNewStrictArgumentsStub); |
- __ bind(&ok); |
- } |
- |
- // Check if we have an arguments adaptor frame below the function frame. |
- Label arguments_adaptor, arguments_done; |
- __ mov(ebx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); |
- __ cmp(Operand(ebx, CommonFrameConstants::kContextOrFrameTypeOffset), |
- Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
- __ j(equal, &arguments_adaptor, Label::kNear); |
- { |
- __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
- __ mov(eax, |
- FieldOperand(eax, SharedFunctionInfo::kFormalParameterCountOffset)); |
- __ lea(ebx, |
- Operand(edx, eax, times_half_pointer_size, |
- StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize)); |
- } |
- __ jmp(&arguments_done, Label::kNear); |
- __ bind(&arguments_adaptor); |
- { |
- __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
- __ lea(ebx, |
- Operand(ebx, eax, times_half_pointer_size, |
- StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize)); |
- } |
- __ bind(&arguments_done); |
- |
- // ----------- S t a t e ------------- |
- // -- eax : number of arguments (tagged) |
- // -- ebx : pointer to the first argument |
- // -- esi : context |
- // -- esp[0] : return address |
- // ----------------------------------- |
- |
- // Allocate space for the strict arguments object plus the backing store. |
- Label allocate, done_allocate; |
- __ lea(ecx, |
- Operand(eax, times_half_pointer_size, |
- JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize)); |
- __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
- __ bind(&done_allocate); |
- |
- // Setup the elements array in edx. |
- __ mov(FieldOperand(edx, FixedArray::kMapOffset), |
- isolate()->factory()->fixed_array_map()); |
- __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); |
- { |
- Label loop, done_loop; |
- __ Move(ecx, Smi::kZero); |
- __ bind(&loop); |
- __ cmp(ecx, eax); |
- __ j(equal, &done_loop, Label::kNear); |
- __ mov(edi, Operand(ebx, 0 * kPointerSize)); |
- __ mov(FieldOperand(edx, ecx, times_half_pointer_size, |
- FixedArray::kHeaderSize), |
- edi); |
- __ sub(ebx, Immediate(1 * kPointerSize)); |
- __ add(ecx, Immediate(Smi::FromInt(1))); |
- __ jmp(&loop); |
- __ bind(&done_loop); |
- } |
- |
- // Setup the rest parameter array in edi. |
- __ lea(edi, |
- Operand(edx, eax, times_half_pointer_size, FixedArray::kHeaderSize)); |
- __ LoadGlobalFunction(Context::STRICT_ARGUMENTS_MAP_INDEX, ecx); |
- __ mov(FieldOperand(edi, JSStrictArgumentsObject::kMapOffset), ecx); |
- __ mov(FieldOperand(edi, JSStrictArgumentsObject::kPropertiesOffset), |
- isolate()->factory()->empty_fixed_array()); |
- __ mov(FieldOperand(edi, JSStrictArgumentsObject::kElementsOffset), edx); |
- __ mov(FieldOperand(edi, JSStrictArgumentsObject::kLengthOffset), eax); |
- STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize); |
- __ mov(eax, edi); |
- __ Ret(); |
- |
- // Fall back to %AllocateInNewSpace (if not too big). |
- Label too_big_for_new_space; |
- __ bind(&allocate); |
- __ cmp(ecx, Immediate(kMaxRegularHeapObjectSize)); |
- __ j(greater, &too_big_for_new_space); |
- { |
- FrameScope scope(masm, StackFrame::INTERNAL); |
- __ SmiTag(ecx); |
- __ Push(eax); |
- __ Push(ebx); |
- __ Push(ecx); |
- __ CallRuntime(Runtime::kAllocateInNewSpace); |
- __ mov(edx, eax); |
- __ Pop(ebx); |
- __ Pop(eax); |
- } |
- __ jmp(&done_allocate); |
- |
- // Fall back to %NewStrictArguments. |
- __ bind(&too_big_for_new_space); |
- __ PopReturnAddressTo(ecx); |
- // We reload the function from the caller frame due to register pressure |
- // within this stub. This is the slow path, hence reloading is preferable. |
- if (skip_stub_frame()) { |
- // For Ignition we need to skip the handler/stub frame to reach the |
- // JavaScript frame for the function. |
- __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
- __ Push(Operand(edx, StandardFrameConstants::kFunctionOffset)); |
- } else { |
- __ Push(Operand(ebp, StandardFrameConstants::kFunctionOffset)); |
- } |
- __ PushReturnAddressFrom(ecx); |
- __ TailCallRuntime(Runtime::kNewStrictArguments); |
-} |
- |
- |
// Generates an Operand for saving parameters after PrepareCallApiFunction. |
static Operand ApiParameterOperand(int index) { |
return Operand(esp, index * kPointerSize); |