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 // ----------- S t a t e ------------- | 123 // ----------- S t a t e ------------- |
124 // -- rax: number of arguments | 124 // -- rax: number of arguments |
125 // -- rdi: constructor function | 125 // -- rdi: constructor function |
126 // -- rbx: allocation site or undefined | 126 // -- rbx: allocation site or undefined |
127 // -- rdx: original constructor | 127 // -- rdx: new target |
128 // ----------------------------------- | 128 // ----------------------------------- |
129 | 129 |
130 // Enter a construct frame. | 130 // Enter a construct frame. |
131 { | 131 { |
132 FrameScope scope(masm, StackFrame::CONSTRUCT); | 132 FrameScope scope(masm, StackFrame::CONSTRUCT); |
133 | 133 |
134 // Preserve the incoming parameters on the stack. | 134 // Preserve the incoming parameters on the stack. |
135 __ AssertUndefinedOrAllocationSite(rbx); | 135 __ AssertUndefinedOrAllocationSite(rbx); |
136 __ Push(rbx); | 136 __ Push(rbx); |
137 __ Integer32ToSmi(rax, rax); | 137 __ Integer32ToSmi(rax, rax); |
138 __ Push(rax); | 138 __ Push(rax); |
139 __ Push(rdi); | 139 __ Push(rdi); |
140 __ Push(rdx); | 140 __ Push(rdx); |
141 | 141 |
142 // Try to allocate the object without transitioning into C code. If any of | 142 // Try to allocate the object without transitioning into C code. If any of |
143 // the preconditions is not met, the code bails out to the runtime call. | 143 // the preconditions is not met, the code bails out to the runtime call. |
144 Label rt_call, allocated; | 144 Label rt_call, allocated; |
145 if (FLAG_inline_new) { | 145 if (FLAG_inline_new) { |
146 ExternalReference debug_step_in_fp = | 146 ExternalReference debug_step_in_fp = |
147 ExternalReference::debug_step_in_fp_address(masm->isolate()); | 147 ExternalReference::debug_step_in_fp_address(masm->isolate()); |
148 __ Move(kScratchRegister, debug_step_in_fp); | 148 __ Move(kScratchRegister, debug_step_in_fp); |
149 __ cmpp(Operand(kScratchRegister, 0), Immediate(0)); | 149 __ cmpp(Operand(kScratchRegister, 0), Immediate(0)); |
150 __ j(not_equal, &rt_call); | 150 __ j(not_equal, &rt_call); |
151 | 151 |
152 // Verify that the original constructor is a JSFunction. | 152 // Verify that the new target is a JSFunction. |
153 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rbx); | 153 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rbx); |
154 __ j(not_equal, &rt_call); | 154 __ j(not_equal, &rt_call); |
155 | 155 |
156 // Load the initial map and verify that it is in fact a map. | 156 // Load the initial map and verify that it is in fact a map. |
157 // rdx: original constructor | 157 // rdx: new target |
158 __ movp(rax, FieldOperand(rdx, JSFunction::kPrototypeOrInitialMapOffset)); | 158 __ movp(rax, FieldOperand(rdx, JSFunction::kPrototypeOrInitialMapOffset)); |
159 // Will both indicate a NULL and a Smi | 159 // Will both indicate a NULL and a Smi |
160 DCHECK(kSmiTag == 0); | 160 DCHECK(kSmiTag == 0); |
161 __ JumpIfSmi(rax, &rt_call); | 161 __ JumpIfSmi(rax, &rt_call); |
162 // rdi: constructor | 162 // rdi: constructor |
163 // rax: initial map (if proven valid below) | 163 // rax: initial map (if proven valid below) |
164 __ CmpObjectType(rax, MAP_TYPE, rbx); | 164 __ CmpObjectType(rax, MAP_TYPE, rbx); |
165 __ j(not_equal, &rt_call); | 165 __ j(not_equal, &rt_call); |
166 | 166 |
167 // Fall back to runtime if the expected base constructor and base | 167 // Fall back to runtime if the expected base constructor and base |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 // and jump into the continuation code at any time from now on. | 267 // and jump into the continuation code at any time from now on. |
268 // rbx: JSObject (untagged) | 268 // rbx: JSObject (untagged) |
269 __ orp(rbx, Immediate(kHeapObjectTag)); | 269 __ orp(rbx, Immediate(kHeapObjectTag)); |
270 | 270 |
271 // Continue with JSObject being successfully allocated | 271 // Continue with JSObject being successfully allocated |
272 // rbx: JSObject (tagged) | 272 // rbx: JSObject (tagged) |
273 __ jmp(&allocated); | 273 __ jmp(&allocated); |
274 } | 274 } |
275 | 275 |
276 // Allocate the new receiver object using the runtime call. | 276 // Allocate the new receiver object using the runtime call. |
277 // rdx: original constructor | 277 // rdx: new target |
278 __ bind(&rt_call); | 278 __ bind(&rt_call); |
279 int offset = kPointerSize; | 279 int offset = kPointerSize; |
280 | 280 |
281 // Must restore rsi (context) and rdi (constructor) before calling runtime. | 281 // Must restore rsi (context) and rdi (constructor) before calling runtime. |
282 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 282 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
283 __ movp(rdi, Operand(rsp, offset)); | 283 __ movp(rdi, Operand(rsp, offset)); |
284 __ Push(rdi); // constructor function | 284 __ Push(rdi); // constructor function |
285 __ Push(rdx); // original constructor | 285 __ Push(rdx); // new target |
286 __ CallRuntime(Runtime::kNewObject, 2); | 286 __ CallRuntime(Runtime::kNewObject, 2); |
287 __ movp(rbx, rax); // store result in rbx | 287 __ movp(rbx, rax); // store result in rbx |
288 | 288 |
289 // New object allocated. | 289 // New object allocated. |
290 // rbx: newly allocated object | 290 // rbx: newly allocated object |
291 __ bind(&allocated); | 291 __ bind(&allocated); |
292 | 292 |
293 // Restore the parameters. | 293 // Restore the parameters. |
294 __ Pop(rdx); | 294 __ Pop(rdx); |
295 __ Pop(rdi); | 295 __ Pop(rdi); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 385 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
386 Generate_JSConstructStubHelper(masm, true); | 386 Generate_JSConstructStubHelper(masm, true); |
387 } | 387 } |
388 | 388 |
389 | 389 |
390 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { | 390 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { |
391 // ----------- S t a t e ------------- | 391 // ----------- S t a t e ------------- |
392 // -- rax: number of arguments | 392 // -- rax: number of arguments |
393 // -- rdi: constructor function | 393 // -- rdi: constructor function |
394 // -- rbx: allocation site or undefined | 394 // -- rbx: allocation site or undefined |
395 // -- rdx: original constructor | 395 // -- rdx: new target |
396 // ----------------------------------- | 396 // ----------------------------------- |
397 | 397 |
398 { | 398 { |
399 FrameScope frame_scope(masm, StackFrame::CONSTRUCT); | 399 FrameScope frame_scope(masm, StackFrame::CONSTRUCT); |
400 | 400 |
401 // Preserve allocation site. | 401 // Preserve allocation site. |
402 __ AssertUndefinedOrAllocationSite(rbx); | 402 __ AssertUndefinedOrAllocationSite(rbx); |
403 __ Push(rbx); | 403 __ Push(rbx); |
404 | 404 |
405 // Store a smi-tagged arguments count on the stack. | 405 // Store a smi-tagged arguments count on the stack. |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 // Call the target. | 826 // Call the target. |
827 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. | 827 __ PushReturnAddressFrom(kScratchRegister); // Re-push return address. |
828 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 828 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
829 } | 829 } |
830 | 830 |
831 | 831 |
832 // static | 832 // static |
833 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { | 833 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { |
834 // ----------- S t a t e ------------- | 834 // ----------- S t a t e ------------- |
835 // -- rax : the number of arguments (not including the receiver) | 835 // -- rax : the number of arguments (not including the receiver) |
836 // -- rdx : the original constructor (either the same as the constructor or | 836 // -- rdx : the new target (either the same as the constructor or |
837 // the JSFunction on which new was invoked initially) | 837 // the JSFunction on which new was invoked initially) |
838 // -- rdi : the constructor to call (can be any Object) | 838 // -- rdi : the constructor to call (can be any Object) |
839 // -- rbx : the address of the first argument to be pushed. Subsequent | 839 // -- rbx : the address of the first argument to be pushed. Subsequent |
840 // arguments should be consecutive above this, in the same order as | 840 // arguments should be consecutive above this, in the same order as |
841 // they are to be pushed onto the stack. | 841 // they are to be pushed onto the stack. |
842 // ----------------------------------- | 842 // ----------------------------------- |
843 | 843 |
844 // Pop return address to allow tail-call after pushing arguments. | 844 // Pop return address to allow tail-call after pushing arguments. |
845 __ PopReturnAddressTo(kScratchRegister); | 845 __ PopReturnAddressTo(kScratchRegister); |
846 | 846 |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 } | 1206 } |
1207 | 1207 |
1208 | 1208 |
1209 // Used by ReflectConstruct | 1209 // Used by ReflectConstruct |
1210 static void Generate_ConstructHelper(MacroAssembler* masm) { | 1210 static void Generate_ConstructHelper(MacroAssembler* masm) { |
1211 const int kFormalParameters = 3; | 1211 const int kFormalParameters = 3; |
1212 const int kStackSize = kFormalParameters + 1; | 1212 const int kStackSize = kFormalParameters + 1; |
1213 | 1213 |
1214 // Stack at entry: | 1214 // Stack at entry: |
1215 // rsp : return address | 1215 // rsp : return address |
1216 // rsp[8] : original constructor (new.target) | 1216 // rsp[8] : new target |
1217 // rsp[16] : arguments | 1217 // rsp[16] : arguments |
1218 // rsp[24] : constructor | 1218 // rsp[24] : constructor |
1219 { | 1219 { |
1220 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1220 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1221 // Stack frame: | 1221 // Stack frame: |
1222 // rbp : Old base pointer | 1222 // rbp : Old base pointer |
1223 // rbp[8] : return address | 1223 // rbp[8] : return address |
1224 // rbp[16] : original constructor (new.target) | 1224 // rbp[16] : new target |
1225 // rbp[24] : arguments | 1225 // rbp[24] : arguments |
1226 // rbp[32] : constructor | 1226 // rbp[32] : constructor |
1227 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; | 1227 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; |
1228 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; | 1228 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; |
1229 static const int kFunctionOffset = kArgumentsOffset + kPointerSize; | 1229 static const int kFunctionOffset = kArgumentsOffset + kPointerSize; |
1230 | 1230 |
1231 static const int kVectorOffset = | 1231 static const int kVectorOffset = |
1232 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; | 1232 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
1233 | 1233 |
1234 // Push the vector. | 1234 // Push the vector. |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1417 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); | 1417 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); |
1418 } | 1418 } |
1419 } | 1419 } |
1420 | 1420 |
1421 | 1421 |
1422 // static | 1422 // static |
1423 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1423 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
1424 // ----------- S t a t e ------------- | 1424 // ----------- S t a t e ------------- |
1425 // -- rax : number of arguments | 1425 // -- rax : number of arguments |
1426 // -- rdi : constructor function | 1426 // -- rdi : constructor function |
1427 // -- rdx : original constructor | 1427 // -- rdx : new target |
1428 // -- rsp[0] : return address | 1428 // -- rsp[0] : return address |
1429 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1429 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1430 // -- rsp[(argc + 1) * 8] : receiver | 1430 // -- rsp[(argc + 1) * 8] : receiver |
1431 // ----------------------------------- | 1431 // ----------------------------------- |
1432 | 1432 |
1433 // 1. Load the first argument into rbx and get rid of the rest (including the | 1433 // 1. Load the first argument into rbx and get rid of the rest (including the |
1434 // receiver). | 1434 // receiver). |
1435 { | 1435 { |
1436 StackArgumentsAccessor args(rsp, rax); | 1436 StackArgumentsAccessor args(rsp, rax); |
1437 Label no_arguments, done; | 1437 Label no_arguments, done; |
(...skipping 23 matching lines...) Expand all Loading... |
1461 __ Push(rdi); | 1461 __ Push(rdi); |
1462 __ Move(rax, rbx); | 1462 __ Move(rax, rbx); |
1463 __ CallStub(&stub); | 1463 __ CallStub(&stub); |
1464 __ Move(rbx, rax); | 1464 __ Move(rbx, rax); |
1465 __ Pop(rdi); | 1465 __ Pop(rdi); |
1466 __ Pop(rdx); | 1466 __ Pop(rdx); |
1467 } | 1467 } |
1468 __ bind(&done_convert); | 1468 __ bind(&done_convert); |
1469 } | 1469 } |
1470 | 1470 |
1471 // 3. Check if original constructor and constructor differ. | 1471 // 3. Check if new target and constructor differ. |
1472 Label new_object; | 1472 Label new_object; |
1473 __ cmpp(rdx, rdi); | 1473 __ cmpp(rdx, rdi); |
1474 __ j(not_equal, &new_object); | 1474 __ j(not_equal, &new_object); |
1475 | 1475 |
1476 // 4. Allocate a JSValue wrapper for the string. | 1476 // 4. Allocate a JSValue wrapper for the string. |
1477 { | 1477 { |
1478 // ----------- S t a t e ------------- | 1478 // ----------- S t a t e ------------- |
1479 // -- rbx : the first argument | 1479 // -- rbx : the first argument |
1480 // -- rdi : constructor function | 1480 // -- rdi : constructor function |
1481 // -- rdx : original constructor | 1481 // -- rdx : new target |
1482 // ----------------------------------- | 1482 // ----------------------------------- |
1483 __ Allocate(JSValue::kSize, rax, rcx, no_reg, &new_object, TAG_OBJECT); | 1483 __ Allocate(JSValue::kSize, rax, rcx, no_reg, &new_object, TAG_OBJECT); |
1484 | 1484 |
1485 // Initialize the JSValue in rax. | 1485 // Initialize the JSValue in rax. |
1486 __ LoadGlobalFunctionInitialMap(rdi, rcx); | 1486 __ LoadGlobalFunctionInitialMap(rdi, rcx); |
1487 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx); | 1487 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx); |
1488 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); | 1488 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); |
1489 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx); | 1489 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx); |
1490 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx); | 1490 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx); |
1491 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); | 1491 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); |
1492 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 1492 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
1493 __ Ret(); | 1493 __ Ret(); |
1494 } | 1494 } |
1495 | 1495 |
1496 // 5. Fallback to the runtime to create new object. | 1496 // 5. Fallback to the runtime to create new object. |
1497 __ bind(&new_object); | 1497 __ bind(&new_object); |
1498 { | 1498 { |
1499 FrameScope scope(masm, StackFrame::INTERNAL); | 1499 FrameScope scope(masm, StackFrame::INTERNAL); |
1500 __ Push(rbx); // the first argument | 1500 __ Push(rbx); // the first argument |
1501 __ Push(rdi); // constructor function | 1501 __ Push(rdi); // constructor function |
1502 __ Push(rdx); // original constructor | 1502 __ Push(rdx); // new target |
1503 __ CallRuntime(Runtime::kNewObject, 2); | 1503 __ CallRuntime(Runtime::kNewObject, 2); |
1504 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); | 1504 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); |
1505 } | 1505 } |
1506 __ Ret(); | 1506 __ Ret(); |
1507 } | 1507 } |
1508 | 1508 |
1509 | 1509 |
1510 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1510 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
1511 Label* stack_overflow) { | 1511 Label* stack_overflow) { |
1512 // ----------- S t a t e ------------- | 1512 // ----------- S t a t e ------------- |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1861 __ Push(rdi); | 1861 __ Push(rdi); |
1862 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1862 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); |
1863 } | 1863 } |
1864 } | 1864 } |
1865 | 1865 |
1866 | 1866 |
1867 // static | 1867 // static |
1868 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 1868 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
1869 // ----------- S t a t e ------------- | 1869 // ----------- S t a t e ------------- |
1870 // -- rax : the number of arguments (not including the receiver) | 1870 // -- rax : the number of arguments (not including the receiver) |
1871 // -- rdx : the original constructor (checked to be a JSFunction) | 1871 // -- rdx : the new target (checked to be a JSFunction) |
1872 // -- rdi : the constructor to call (checked to be a JSFunction) | 1872 // -- rdi : the constructor to call (checked to be a JSFunction) |
1873 // ----------------------------------- | 1873 // ----------------------------------- |
1874 __ AssertFunction(rdx); | 1874 __ AssertFunction(rdx); |
1875 __ AssertFunction(rdi); | 1875 __ AssertFunction(rdi); |
1876 | 1876 |
1877 // Calling convention for function specific ConstructStubs require | 1877 // Calling convention for function specific ConstructStubs require |
1878 // rbx to contain either an AllocationSite or undefined. | 1878 // rbx to contain either an AllocationSite or undefined. |
1879 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 1879 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
1880 | 1880 |
1881 // Tail call to the function-specific construct stub (still in the caller | 1881 // Tail call to the function-specific construct stub (still in the caller |
1882 // context at this point). | 1882 // context at this point). |
1883 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 1883 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
1884 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); | 1884 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset)); |
1885 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); | 1885 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); |
1886 __ jmp(rcx); | 1886 __ jmp(rcx); |
1887 } | 1887 } |
1888 | 1888 |
1889 | 1889 |
1890 // static | 1890 // static |
1891 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 1891 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
1892 // ----------- S t a t e ------------- | 1892 // ----------- S t a t e ------------- |
1893 // -- rax : the number of arguments (not including the receiver) | 1893 // -- rax : the number of arguments (not including the receiver) |
1894 // -- rdx : the original constructor (either the same as the constructor or | 1894 // -- rdx : the new target (either the same as the constructor or |
1895 // the JSFunction on which new was invoked initially) | 1895 // the JSFunction on which new was invoked initially) |
1896 // -- rdi : the constructor to call (checked to be a JSFunctionProxy) | 1896 // -- rdi : the constructor to call (checked to be a JSFunctionProxy) |
1897 // ----------------------------------- | 1897 // ----------------------------------- |
1898 | 1898 |
1899 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies. | 1899 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies. |
1900 __ movp(rdi, FieldOperand(rdi, JSFunctionProxy::kConstructTrapOffset)); | 1900 __ movp(rdi, FieldOperand(rdi, JSFunctionProxy::kConstructTrapOffset)); |
1901 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1901 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1902 } | 1902 } |
1903 | 1903 |
1904 | 1904 |
1905 // static | 1905 // static |
1906 void Builtins::Generate_Construct(MacroAssembler* masm) { | 1906 void Builtins::Generate_Construct(MacroAssembler* masm) { |
1907 // ----------- S t a t e ------------- | 1907 // ----------- S t a t e ------------- |
1908 // -- rax : the number of arguments (not including the receiver) | 1908 // -- rax : the number of arguments (not including the receiver) |
1909 // -- rdx : the original constructor (either the same as the constructor or | 1909 // -- rdx : the new target (either the same as the constructor or |
1910 // the JSFunction on which new was invoked initially) | 1910 // the JSFunction on which new was invoked initially) |
1911 // -- rdi : the constructor to call (can be any Object) | 1911 // -- rdi : the constructor to call (can be any Object) |
1912 // ----------------------------------- | 1912 // ----------------------------------- |
1913 StackArgumentsAccessor args(rsp, rax); | 1913 StackArgumentsAccessor args(rsp, rax); |
1914 | 1914 |
1915 // Check if target has a [[Construct]] internal method. | 1915 // Check if target has a [[Construct]] internal method. |
1916 Label non_constructor; | 1916 Label non_constructor; |
1917 __ JumpIfSmi(rdi, &non_constructor, Label::kNear); | 1917 __ JumpIfSmi(rdi, &non_constructor, Label::kNear); |
1918 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset)); | 1918 __ movp(rcx, FieldOperand(rdi, HeapObject::kMapOffset)); |
1919 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), | 1919 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2001 __ ret(0); | 2001 __ ret(0); |
2002 } | 2002 } |
2003 | 2003 |
2004 | 2004 |
2005 #undef __ | 2005 #undef __ |
2006 | 2006 |
2007 } // namespace internal | 2007 } // namespace internal |
2008 } // namespace v8 | 2008 } // namespace v8 |
2009 | 2009 |
2010 #endif // V8_TARGET_ARCH_X64 | 2010 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |