OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 __ addq(rax, Immediate(num_extra_args + 1)); | 72 __ addq(rax, Immediate(num_extra_args + 1)); |
73 __ JumpToExternalReference(ExternalReference(id, masm->isolate()), 1); | 73 __ JumpToExternalReference(ExternalReference(id, masm->isolate()), 1); |
74 } | 74 } |
75 | 75 |
76 | 76 |
77 static void CallRuntimePassFunction( | 77 static void CallRuntimePassFunction( |
78 MacroAssembler* masm, Runtime::FunctionId function_id) { | 78 MacroAssembler* masm, Runtime::FunctionId function_id) { |
79 FrameScope scope(masm, StackFrame::INTERNAL); | 79 FrameScope scope(masm, StackFrame::INTERNAL); |
80 // Push a copy of the function onto the stack. | 80 // Push a copy of the function onto the stack. |
81 __ push(rdi); | 81 __ push(rdi); |
82 // Push call kind information. | |
83 __ push(rcx); | |
84 // Function is also the parameter to the runtime call. | 82 // Function is also the parameter to the runtime call. |
85 __ push(rdi); | 83 __ push(rdi); |
86 | 84 |
87 __ CallRuntime(function_id, 1); | 85 __ CallRuntime(function_id, 1); |
88 // Restore call kind information. | |
89 __ pop(rcx); | |
90 // Restore receiver. | 86 // Restore receiver. |
91 __ pop(rdi); | 87 __ pop(rdi); |
92 } | 88 } |
93 | 89 |
94 | 90 |
95 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 91 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
96 __ movq(kScratchRegister, | 92 __ movq(kScratchRegister, |
97 FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 93 FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
98 __ movq(kScratchRegister, | 94 __ movq(kScratchRegister, |
99 FieldOperand(kScratchRegister, SharedFunctionInfo::kCodeOffset)); | 95 FieldOperand(kScratchRegister, SharedFunctionInfo::kCodeOffset)); |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 __ decq(rcx); | 364 __ decq(rcx); |
369 __ j(greater_equal, &loop); | 365 __ j(greater_equal, &loop); |
370 | 366 |
371 // Call the function. | 367 // Call the function. |
372 if (is_api_function) { | 368 if (is_api_function) { |
373 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 369 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
374 Handle<Code> code = | 370 Handle<Code> code = |
375 masm->isolate()->builtins()->HandleApiCallConstruct(); | 371 masm->isolate()->builtins()->HandleApiCallConstruct(); |
376 ParameterCount expected(0); | 372 ParameterCount expected(0); |
377 __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET, | 373 __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET, |
378 CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 374 CALL_FUNCTION, NullCallWrapper()); |
379 } else { | 375 } else { |
380 ParameterCount actual(rax); | 376 ParameterCount actual(rax); |
381 __ InvokeFunction(rdi, actual, CALL_FUNCTION, | 377 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper()); |
382 NullCallWrapper(), CALL_AS_METHOD); | |
383 } | 378 } |
384 | 379 |
385 // Store offset of return address for deoptimizer. | 380 // Store offset of return address for deoptimizer. |
386 if (!is_api_function && !count_constructions) { | 381 if (!is_api_function && !count_constructions) { |
387 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 382 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
388 } | 383 } |
389 | 384 |
390 // Restore context from the frame. | 385 // Restore context from the frame. |
391 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 386 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
392 | 387 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 // No type feedback cell is available | 537 // No type feedback cell is available |
543 Handle<Object> undefined_sentinel( | 538 Handle<Object> undefined_sentinel( |
544 masm->isolate()->factory()->undefined_value()); | 539 masm->isolate()->factory()->undefined_value()); |
545 __ Move(rbx, undefined_sentinel); | 540 __ Move(rbx, undefined_sentinel); |
546 // Expects rdi to hold function pointer. | 541 // Expects rdi to hold function pointer. |
547 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); | 542 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); |
548 __ CallStub(&stub); | 543 __ CallStub(&stub); |
549 } else { | 544 } else { |
550 ParameterCount actual(rax); | 545 ParameterCount actual(rax); |
551 // Function must be in rdi. | 546 // Function must be in rdi. |
552 __ InvokeFunction(rdi, actual, CALL_FUNCTION, | 547 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper()); |
553 NullCallWrapper(), CALL_AS_METHOD); | |
554 } | 548 } |
555 // Exit the internal frame. Notice that this also removes the empty | 549 // Exit the internal frame. Notice that this also removes the empty |
556 // context and the function left on the stack by the code | 550 // context and the function left on the stack by the code |
557 // invocation. | 551 // invocation. |
558 } | 552 } |
559 | 553 |
560 // TODO(X64): Is argument correct? Is there a receiver to remove? | 554 // TODO(X64): Is argument correct? Is there a receiver to remove? |
561 __ ret(1 * kPointerSize); // Remove receiver. | 555 __ ret(1 * kPointerSize); // Remove receiver. |
562 } | 556 } |
563 | 557 |
(...skipping 12 matching lines...) Expand all Loading... |
576 CallRuntimePassFunction(masm, Runtime::kCompileUnoptimized); | 570 CallRuntimePassFunction(masm, Runtime::kCompileUnoptimized); |
577 GenerateTailCallToReturnedCode(masm); | 571 GenerateTailCallToReturnedCode(masm); |
578 } | 572 } |
579 | 573 |
580 | 574 |
581 static void CallCompileOptimized(MacroAssembler* masm, | 575 static void CallCompileOptimized(MacroAssembler* masm, |
582 bool concurrent) { | 576 bool concurrent) { |
583 FrameScope scope(masm, StackFrame::INTERNAL); | 577 FrameScope scope(masm, StackFrame::INTERNAL); |
584 // Push a copy of the function onto the stack. | 578 // Push a copy of the function onto the stack. |
585 __ push(rdi); | 579 __ push(rdi); |
586 // Push call kind information. | |
587 __ push(rcx); | |
588 // Function is also the parameter to the runtime call. | 580 // Function is also the parameter to the runtime call. |
589 __ push(rdi); | 581 __ push(rdi); |
590 // Whether to compile in a background thread. | 582 // Whether to compile in a background thread. |
591 __ Push(masm->isolate()->factory()->ToBoolean(concurrent)); | 583 __ Push(masm->isolate()->factory()->ToBoolean(concurrent)); |
592 | 584 |
593 __ CallRuntime(Runtime::kCompileOptimized, 2); | 585 __ CallRuntime(Runtime::kCompileOptimized, 2); |
594 // Restore call kind information. | |
595 __ pop(rcx); | |
596 // Restore receiver. | 586 // Restore receiver. |
597 __ pop(rdi); | 587 __ pop(rdi); |
598 } | 588 } |
599 | 589 |
600 | 590 |
601 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 591 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { |
602 CallCompileOptimized(masm, false); | 592 CallCompileOptimized(masm, false); |
603 GenerateTailCallToReturnedCode(masm); | 593 GenerateTailCallToReturnedCode(masm); |
604 } | 594 } |
605 | 595 |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 __ pop(rbx); // Discard copy of return address. | 873 __ pop(rbx); // Discard copy of return address. |
884 __ decq(rax); // One fewer argument (first argument is new receiver). | 874 __ decq(rax); // One fewer argument (first argument is new receiver). |
885 } | 875 } |
886 | 876 |
887 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, | 877 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, |
888 // or a function proxy via CALL_FUNCTION_PROXY. | 878 // or a function proxy via CALL_FUNCTION_PROXY. |
889 { Label function, non_proxy; | 879 { Label function, non_proxy; |
890 __ testq(rdx, rdx); | 880 __ testq(rdx, rdx); |
891 __ j(zero, &function); | 881 __ j(zero, &function); |
892 __ Set(rbx, 0); | 882 __ Set(rbx, 0); |
893 __ SetCallKind(rcx, CALL_AS_METHOD); | |
894 __ cmpq(rdx, Immediate(1)); | 883 __ cmpq(rdx, Immediate(1)); |
895 __ j(not_equal, &non_proxy); | 884 __ j(not_equal, &non_proxy); |
896 | 885 |
897 __ PopReturnAddressTo(rdx); | 886 __ PopReturnAddressTo(rdx); |
898 __ push(rdi); // re-add proxy object as additional argument | 887 __ push(rdi); // re-add proxy object as additional argument |
899 __ PushReturnAddressFrom(rdx); | 888 __ PushReturnAddressFrom(rdx); |
900 __ incq(rax); | 889 __ incq(rax); |
901 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); | 890 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); |
902 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 891 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
903 RelocInfo::CODE_TARGET); | 892 RelocInfo::CODE_TARGET); |
904 | 893 |
905 __ bind(&non_proxy); | 894 __ bind(&non_proxy); |
906 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); | 895 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); |
907 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 896 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
908 RelocInfo::CODE_TARGET); | 897 RelocInfo::CODE_TARGET); |
909 __ bind(&function); | 898 __ bind(&function); |
910 } | 899 } |
911 | 900 |
912 // 5b. Get the code to call from the function and check that the number of | 901 // 5b. Get the code to call from the function and check that the number of |
913 // expected arguments matches what we're providing. If so, jump | 902 // expected arguments matches what we're providing. If so, jump |
914 // (tail-call) to the code in register edx without checking arguments. | 903 // (tail-call) to the code in register edx without checking arguments. |
915 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 904 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
916 __ movsxlq(rbx, | 905 __ movsxlq(rbx, |
917 FieldOperand(rdx, | 906 FieldOperand(rdx, |
918 SharedFunctionInfo::kFormalParameterCountOffset)); | 907 SharedFunctionInfo::kFormalParameterCountOffset)); |
919 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 908 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
920 __ SetCallKind(rcx, CALL_AS_FUNCTION); | |
921 __ cmpq(rax, rbx); | 909 __ cmpq(rax, rbx); |
922 __ j(not_equal, | 910 __ j(not_equal, |
923 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 911 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
924 RelocInfo::CODE_TARGET); | 912 RelocInfo::CODE_TARGET); |
925 | 913 |
926 ParameterCount expected(0); | 914 ParameterCount expected(0); |
927 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION, | 915 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
928 NullCallWrapper(), CALL_AS_FUNCTION); | |
929 } | 916 } |
930 | 917 |
931 | 918 |
932 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 919 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
933 // Stack at entry: | 920 // Stack at entry: |
934 // rsp : return address | 921 // rsp : return address |
935 // rsp[8] : arguments | 922 // rsp[8] : arguments |
936 // rsp[16] : receiver ("this") | 923 // rsp[16] : receiver ("this") |
937 // rsp[24] : function | 924 // rsp[24] : function |
938 { | 925 { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 __ cmpq(rax, Operand(rbp, kLimitOffset)); | 1049 __ cmpq(rax, Operand(rbp, kLimitOffset)); |
1063 __ j(not_equal, &loop); | 1050 __ j(not_equal, &loop); |
1064 | 1051 |
1065 // Call the function. | 1052 // Call the function. |
1066 Label call_proxy; | 1053 Label call_proxy; |
1067 ParameterCount actual(rax); | 1054 ParameterCount actual(rax); |
1068 __ SmiToInteger32(rax, rax); | 1055 __ SmiToInteger32(rax, rax); |
1069 __ movq(rdi, Operand(rbp, kFunctionOffset)); | 1056 __ movq(rdi, Operand(rbp, kFunctionOffset)); |
1070 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); | 1057 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
1071 __ j(not_equal, &call_proxy); | 1058 __ j(not_equal, &call_proxy); |
1072 __ InvokeFunction(rdi, actual, CALL_FUNCTION, | 1059 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper()); |
1073 NullCallWrapper(), CALL_AS_FUNCTION); | |
1074 | 1060 |
1075 frame_scope.GenerateLeaveFrame(); | 1061 frame_scope.GenerateLeaveFrame(); |
1076 __ ret(3 * kPointerSize); // remove this, receiver, and arguments | 1062 __ ret(3 * kPointerSize); // remove this, receiver, and arguments |
1077 | 1063 |
1078 // Call the function proxy. | 1064 // Call the function proxy. |
1079 __ bind(&call_proxy); | 1065 __ bind(&call_proxy); |
1080 __ push(rdi); // add function proxy as last argument | 1066 __ push(rdi); // add function proxy as last argument |
1081 __ incq(rax); | 1067 __ incq(rax); |
1082 __ Set(rbx, 0); | 1068 __ Set(rbx, 0); |
1083 __ SetCallKind(rcx, CALL_AS_FUNCTION); | |
1084 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); | 1069 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); |
1085 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1070 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1086 RelocInfo::CODE_TARGET); | 1071 RelocInfo::CODE_TARGET); |
1087 | 1072 |
1088 // Leave internal frame. | 1073 // Leave internal frame. |
1089 } | 1074 } |
1090 __ ret(3 * kPointerSize); // remove this, receiver, and arguments | 1075 __ ret(3 * kPointerSize); // remove this, receiver, and arguments |
1091 } | 1076 } |
1092 | 1077 |
1093 | 1078 |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1311 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); | 1296 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); |
1312 __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); | 1297 __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); |
1313 __ PushReturnAddressFrom(rcx); | 1298 __ PushReturnAddressFrom(rcx); |
1314 } | 1299 } |
1315 | 1300 |
1316 | 1301 |
1317 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1302 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1318 // ----------- S t a t e ------------- | 1303 // ----------- S t a t e ------------- |
1319 // -- rax : actual number of arguments | 1304 // -- rax : actual number of arguments |
1320 // -- rbx : expected number of arguments | 1305 // -- rbx : expected number of arguments |
1321 // -- rcx : call kind information | |
1322 // -- rdx : code entry to call | 1306 // -- rdx : code entry to call |
1323 // ----------------------------------- | 1307 // ----------------------------------- |
1324 | 1308 |
1325 Label invoke, dont_adapt_arguments; | 1309 Label invoke, dont_adapt_arguments; |
1326 Counters* counters = masm->isolate()->counters(); | 1310 Counters* counters = masm->isolate()->counters(); |
1327 __ IncrementCounter(counters->arguments_adaptors(), 1); | 1311 __ IncrementCounter(counters->arguments_adaptors(), 1); |
1328 | 1312 |
1329 Label enough, too_few; | 1313 Label enough, too_few; |
1330 __ cmpq(rax, rbx); | 1314 __ cmpq(rax, rbx); |
1331 __ j(less, &too_few); | 1315 __ j(less, &too_few); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1451 __ bind(&ok); | 1435 __ bind(&ok); |
1452 __ ret(0); | 1436 __ ret(0); |
1453 } | 1437 } |
1454 | 1438 |
1455 | 1439 |
1456 #undef __ | 1440 #undef __ |
1457 | 1441 |
1458 } } // namespace v8::internal | 1442 } } // namespace v8::internal |
1459 | 1443 |
1460 #endif // V8_TARGET_ARCH_X64 | 1444 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |