| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 GenerateTailCallToSharedCode(masm); | 117 GenerateTailCallToSharedCode(masm); |
| 118 } | 118 } |
| 119 | 119 |
| 120 | 120 |
| 121 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 121 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| 122 bool is_api_function, | 122 bool is_api_function, |
| 123 bool create_implicit_receiver, | 123 bool create_implicit_receiver, |
| 124 bool check_derived_construct) { | 124 bool check_derived_construct) { |
| 125 // ----------- S t a t e ------------- | 125 // ----------- S t a t e ------------- |
| 126 // -- rax: number of arguments | 126 // -- rax: number of arguments |
| 127 // -- rsi: context |
| 127 // -- rdi: constructor function | 128 // -- rdi: constructor function |
| 128 // -- rbx: allocation site or undefined | 129 // -- rbx: allocation site or undefined |
| 129 // -- rdx: new target | 130 // -- rdx: new target |
| 130 // ----------------------------------- | 131 // ----------------------------------- |
| 131 | 132 |
| 132 // Enter a construct frame. | 133 // Enter a construct frame. |
| 133 { | 134 { |
| 134 FrameScope scope(masm, StackFrame::CONSTRUCT); | 135 FrameScope scope(masm, StackFrame::CONSTRUCT); |
| 135 | 136 |
| 136 // Preserve the incoming parameters on the stack. | 137 // Preserve the incoming parameters on the stack. |
| 137 __ AssertUndefinedOrAllocationSite(rbx); | 138 __ AssertUndefinedOrAllocationSite(rbx); |
| 139 __ Push(rsi); |
| 138 __ Push(rbx); | 140 __ Push(rbx); |
| 139 __ Integer32ToSmi(rcx, rax); | 141 __ Integer32ToSmi(rcx, rax); |
| 140 __ Push(rcx); | 142 __ Push(rcx); |
| 141 | 143 |
| 142 if (create_implicit_receiver) { | 144 if (create_implicit_receiver) { |
| 143 // Allocate the new receiver object. | 145 // Allocate the new receiver object. |
| 144 __ Push(rdi); | 146 __ Push(rdi); |
| 145 __ Push(rdx); | 147 __ Push(rdx); |
| 146 FastNewObjectStub stub(masm->isolate()); | 148 FastNewObjectStub stub(masm->isolate()); |
| 147 __ CallStub(&stub); | 149 __ CallStub(&stub); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 __ InvokeFunction(rdi, rdx, actual, CALL_FUNCTION, | 195 __ InvokeFunction(rdi, rdx, actual, CALL_FUNCTION, |
| 194 CheckDebugStepCallWrapper()); | 196 CheckDebugStepCallWrapper()); |
| 195 } | 197 } |
| 196 | 198 |
| 197 // Store offset of return address for deoptimizer. | 199 // Store offset of return address for deoptimizer. |
| 198 if (create_implicit_receiver && !is_api_function) { | 200 if (create_implicit_receiver && !is_api_function) { |
| 199 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 201 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
| 200 } | 202 } |
| 201 | 203 |
| 202 // Restore context from the frame. | 204 // Restore context from the frame. |
| 203 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 205 __ movp(rsi, Operand(rbp, ConstructFrameConstants::kContextOffset)); |
| 204 | 206 |
| 205 if (create_implicit_receiver) { | 207 if (create_implicit_receiver) { |
| 206 // If the result is an object (in the ECMA sense), we should get rid | 208 // If the result is an object (in the ECMA sense), we should get rid |
| 207 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 | 209 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 |
| 208 // on page 74. | 210 // on page 74. |
| 209 Label use_receiver, exit; | 211 Label use_receiver, exit; |
| 210 // If the result is a smi, it is *not* an object in the ECMA sense. | 212 // If the result is a smi, it is *not* an object in the ECMA sense. |
| 211 __ JumpIfSmi(rax, &use_receiver); | 213 __ JumpIfSmi(rax, &use_receiver); |
| 212 | 214 |
| 213 // If the type of the result (stored in its map) is less than | 215 // If the type of the result (stored in its map) is less than |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 // new.target. | 346 // new.target. |
| 345 | 347 |
| 346 #ifdef _WIN64 | 348 #ifdef _WIN64 |
| 347 // MSVC parameters in: | 349 // MSVC parameters in: |
| 348 // rcx : new_target | 350 // rcx : new_target |
| 349 // rdx : function | 351 // rdx : function |
| 350 // r8 : receiver | 352 // r8 : receiver |
| 351 // r9 : argc | 353 // r9 : argc |
| 352 // [rsp+0x20] : argv | 354 // [rsp+0x20] : argv |
| 353 | 355 |
| 354 // Clear the context before we push it when entering the internal frame. | |
| 355 __ Set(rsi, 0); | |
| 356 | |
| 357 // Enter an internal frame. | 356 // Enter an internal frame. |
| 358 FrameScope scope(masm, StackFrame::INTERNAL); | 357 FrameScope scope(masm, StackFrame::INTERNAL); |
| 359 | 358 |
| 360 // Setup the context (we need to use the caller context from the isolate). | 359 // Setup the context (we need to use the caller context from the isolate). |
| 361 ExternalReference context_address(Isolate::kContextAddress, | 360 ExternalReference context_address(Isolate::kContextAddress, |
| 362 masm->isolate()); | 361 masm->isolate()); |
| 363 __ movp(rsi, masm->ExternalOperand(context_address)); | 362 __ movp(rsi, masm->ExternalOperand(context_address)); |
| 364 | 363 |
| 365 // Push the function and the receiver onto the stack. | 364 // Push the function and the receiver onto the stack. |
| 366 __ Push(rdx); | 365 __ Push(rdx); |
| (...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1863 // Fill remaining expected arguments with undefined values. | 1862 // Fill remaining expected arguments with undefined values. |
| 1864 Label fill; | 1863 Label fill; |
| 1865 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); | 1864 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); |
| 1866 __ bind(&fill); | 1865 __ bind(&fill); |
| 1867 __ incp(r8); | 1866 __ incp(r8); |
| 1868 __ Push(kScratchRegister); | 1867 __ Push(kScratchRegister); |
| 1869 __ cmpp(r8, rbx); | 1868 __ cmpp(r8, rbx); |
| 1870 __ j(less, &fill); | 1869 __ j(less, &fill); |
| 1871 | 1870 |
| 1872 // Restore function pointer. | 1871 // Restore function pointer. |
| 1873 __ movp(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1872 __ movp(rdi, Operand(rbp, ArgumentsAdaptorFrameConstants::kFunctionOffset)); |
| 1874 } | 1873 } |
| 1875 | 1874 |
| 1876 // Call the entry point. | 1875 // Call the entry point. |
| 1877 __ bind(&invoke); | 1876 __ bind(&invoke); |
| 1878 __ movp(rax, rbx); | 1877 __ movp(rax, rbx); |
| 1879 // rax : expected number of arguments | 1878 // rax : expected number of arguments |
| 1880 // rdx : new target (passed through to callee) | 1879 // rdx : new target (passed through to callee) |
| 1881 // rdi : function (passed through to callee) | 1880 // rdi : function (passed through to callee) |
| 1882 __ movp(rcx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 1881 __ movp(rcx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
| 1883 __ call(rcx); | 1882 __ call(rcx); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2069 Label done; | 2068 Label done; |
| 2070 ExternalReference debug_is_active = | 2069 ExternalReference debug_is_active = |
| 2071 ExternalReference::debug_is_active_address(masm->isolate()); | 2070 ExternalReference::debug_is_active_address(masm->isolate()); |
| 2072 __ Move(kScratchRegister, debug_is_active); | 2071 __ Move(kScratchRegister, debug_is_active); |
| 2073 __ cmpb(Operand(kScratchRegister, 0), Immediate(0)); | 2072 __ cmpb(Operand(kScratchRegister, 0), Immediate(0)); |
| 2074 __ j(not_equal, &done); | 2073 __ j(not_equal, &done); |
| 2075 | 2074 |
| 2076 // Drop possible interpreter handler/stub frame. | 2075 // Drop possible interpreter handler/stub frame. |
| 2077 { | 2076 { |
| 2078 Label no_interpreter_frame; | 2077 Label no_interpreter_frame; |
| 2079 __ Cmp(Operand(rbp, StandardFrameConstants::kMarkerOffset), | 2078 __ Cmp(Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset), |
| 2080 Smi::FromInt(StackFrame::STUB)); | 2079 Smi::FromInt(StackFrame::STUB)); |
| 2081 __ j(not_equal, &no_interpreter_frame, Label::kNear); | 2080 __ j(not_equal, &no_interpreter_frame, Label::kNear); |
| 2082 __ movp(rbp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 2081 __ movp(rbp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 2083 __ bind(&no_interpreter_frame); | 2082 __ bind(&no_interpreter_frame); |
| 2084 } | 2083 } |
| 2085 | 2084 |
| 2086 // Check if next frame is an arguments adaptor frame. | 2085 // Check if next frame is an arguments adaptor frame. |
| 2087 Register caller_args_count_reg = scratch1; | 2086 Register caller_args_count_reg = scratch1; |
| 2088 Label no_arguments_adaptor, formal_parameter_count_loaded; | 2087 Label no_arguments_adaptor, formal_parameter_count_loaded; |
| 2089 __ movp(scratch2, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 2088 __ movp(scratch2, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 2090 __ Cmp(Operand(scratch2, StandardFrameConstants::kContextOffset), | 2089 __ Cmp(Operand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset), |
| 2091 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 2090 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
| 2092 __ j(not_equal, &no_arguments_adaptor, Label::kNear); | 2091 __ j(not_equal, &no_arguments_adaptor, Label::kNear); |
| 2093 | 2092 |
| 2094 // Drop current frame and load arguments count from arguments adaptor frame. | 2093 // Drop current frame and load arguments count from arguments adaptor frame. |
| 2095 __ movp(rbp, scratch2); | 2094 __ movp(rbp, scratch2); |
| 2096 __ SmiToInteger32( | 2095 __ SmiToInteger32( |
| 2097 caller_args_count_reg, | 2096 caller_args_count_reg, |
| 2098 Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2097 Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 2099 __ jmp(&formal_parameter_count_loaded, Label::kNear); | 2098 __ jmp(&formal_parameter_count_loaded, Label::kNear); |
| 2100 | 2099 |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2704 __ ret(0); | 2703 __ ret(0); |
| 2705 } | 2704 } |
| 2706 | 2705 |
| 2707 | 2706 |
| 2708 #undef __ | 2707 #undef __ |
| 2709 | 2708 |
| 2710 } // namespace internal | 2709 } // namespace internal |
| 2711 } // namespace v8 | 2710 } // namespace v8 |
| 2712 | 2711 |
| 2713 #endif // V8_TARGET_ARCH_X64 | 2712 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |