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 Label no_arguments_adaptor, formal_parameter_count_loaded; | 2086 Label no_arguments_adaptor, formal_parameter_count_loaded; |
2088 __ movp(scratch2, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 2087 __ movp(scratch2, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
2089 __ Cmp(Operand(scratch2, StandardFrameConstants::kContextOffset), | 2088 __ Cmp(Operand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset), |
2090 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 2089 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
2091 __ j(not_equal, &no_arguments_adaptor, Label::kNear); | 2090 __ j(not_equal, &no_arguments_adaptor, Label::kNear); |
2092 | 2091 |
2093 // Drop arguments adaptor frame and load arguments count. | 2092 // Drop arguments adaptor frame and load arguments count. |
2094 __ movp(rbp, scratch2); | 2093 __ movp(rbp, scratch2); |
2095 __ SmiToInteger32( | 2094 __ SmiToInteger32( |
2096 scratch1, Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2095 scratch1, Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
2097 __ jmp(&formal_parameter_count_loaded, Label::kNear); | 2096 __ jmp(&formal_parameter_count_loaded, Label::kNear); |
2098 | 2097 |
2099 __ bind(&no_arguments_adaptor); | 2098 __ bind(&no_arguments_adaptor); |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2743 __ ret(0); | 2742 __ ret(0); |
2744 } | 2743 } |
2745 | 2744 |
2746 | 2745 |
2747 #undef __ | 2746 #undef __ |
2748 | 2747 |
2749 } // namespace internal | 2748 } // namespace internal |
2750 } // namespace v8 | 2749 } // namespace v8 |
2751 | 2750 |
2752 #endif // V8_TARGET_ARCH_X64 | 2751 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |