| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 __ add(eax, Immediate(num_extra_args + 1)); | 73 __ add(eax, Immediate(num_extra_args + 1)); |
| 74 __ JumpToExternalReference(ExternalReference(id, masm->isolate())); | 74 __ JumpToExternalReference(ExternalReference(id, masm->isolate())); |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 static void CallRuntimePassFunction( | 78 static void CallRuntimePassFunction( |
| 79 MacroAssembler* masm, Runtime::FunctionId function_id) { | 79 MacroAssembler* masm, Runtime::FunctionId function_id) { |
| 80 FrameScope scope(masm, StackFrame::INTERNAL); | 80 FrameScope scope(masm, StackFrame::INTERNAL); |
| 81 // Push a copy of the function. | 81 // Push a copy of the function. |
| 82 __ push(edi); | 82 __ push(edi); |
| 83 // Push call kind information. | |
| 84 __ push(ecx); | |
| 85 // Function is also the parameter to the runtime call. | 83 // Function is also the parameter to the runtime call. |
| 86 __ push(edi); | 84 __ push(edi); |
| 87 | 85 |
| 88 __ CallRuntime(function_id, 1); | 86 __ CallRuntime(function_id, 1); |
| 89 // Restore call kind information. | |
| 90 __ pop(ecx); | |
| 91 // Restore receiver. | 87 // Restore receiver. |
| 92 __ pop(edi); | 88 __ pop(edi); |
| 93 } | 89 } |
| 94 | 90 |
| 95 | 91 |
| 96 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 92 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
| 97 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 93 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 98 __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kCodeOffset)); | 94 __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kCodeOffset)); |
| 99 __ lea(eax, FieldOperand(eax, Code::kHeaderSize)); | 95 __ lea(eax, FieldOperand(eax, Code::kHeaderSize)); |
| 100 __ jmp(eax); | 96 __ jmp(eax); |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 __ push(Operand(ebx, ecx, times_4, 0)); | 357 __ push(Operand(ebx, ecx, times_4, 0)); |
| 362 __ bind(&entry); | 358 __ bind(&entry); |
| 363 __ dec(ecx); | 359 __ dec(ecx); |
| 364 __ j(greater_equal, &loop); | 360 __ j(greater_equal, &loop); |
| 365 | 361 |
| 366 // Call the function. | 362 // Call the function. |
| 367 if (is_api_function) { | 363 if (is_api_function) { |
| 368 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 364 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 369 Handle<Code> code = | 365 Handle<Code> code = |
| 370 masm->isolate()->builtins()->HandleApiCallConstruct(); | 366 masm->isolate()->builtins()->HandleApiCallConstruct(); |
| 371 ParameterCount expected(0); | 367 __ call(code, RelocInfo::CODE_TARGET); |
| 372 __ InvokeCode(code, expected, expected, RelocInfo::CODE_TARGET, | |
| 373 CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | |
| 374 } else { | 368 } else { |
| 375 ParameterCount actual(eax); | 369 ParameterCount actual(eax); |
| 376 __ InvokeFunction(edi, actual, CALL_FUNCTION, | 370 __ InvokeFunction(edi, actual, CALL_FUNCTION, |
| 377 NullCallWrapper(), CALL_AS_METHOD); | 371 NullCallWrapper()); |
| 378 } | 372 } |
| 379 | 373 |
| 380 // Store offset of return address for deoptimizer. | 374 // Store offset of return address for deoptimizer. |
| 381 if (!is_api_function && !count_constructions) { | 375 if (!is_api_function && !count_constructions) { |
| 382 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 376 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
| 383 } | 377 } |
| 384 | 378 |
| 385 // Restore context from the frame. | 379 // Restore context from the frame. |
| 386 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 380 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 387 | 381 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 if (is_construct) { | 474 if (is_construct) { |
| 481 // No type feedback cell is available | 475 // No type feedback cell is available |
| 482 Handle<Object> undefined_sentinel( | 476 Handle<Object> undefined_sentinel( |
| 483 masm->isolate()->heap()->undefined_value(), masm->isolate()); | 477 masm->isolate()->heap()->undefined_value(), masm->isolate()); |
| 484 __ mov(ebx, Immediate(undefined_sentinel)); | 478 __ mov(ebx, Immediate(undefined_sentinel)); |
| 485 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); | 479 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); |
| 486 __ CallStub(&stub); | 480 __ CallStub(&stub); |
| 487 } else { | 481 } else { |
| 488 ParameterCount actual(eax); | 482 ParameterCount actual(eax); |
| 489 __ InvokeFunction(edi, actual, CALL_FUNCTION, | 483 __ InvokeFunction(edi, actual, CALL_FUNCTION, |
| 490 NullCallWrapper(), CALL_AS_METHOD); | 484 NullCallWrapper()); |
| 491 } | 485 } |
| 492 | 486 |
| 493 // Exit the internal frame. Notice that this also removes the empty. | 487 // Exit the internal frame. Notice that this also removes the empty. |
| 494 // context and the function left on the stack by the code | 488 // context and the function left on the stack by the code |
| 495 // invocation. | 489 // invocation. |
| 496 } | 490 } |
| 497 __ ret(kPointerSize); // Remove receiver. | 491 __ ret(kPointerSize); // Remove receiver. |
| 498 } | 492 } |
| 499 | 493 |
| 500 | 494 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 512 CallRuntimePassFunction(masm, Runtime::kCompileUnoptimized); | 506 CallRuntimePassFunction(masm, Runtime::kCompileUnoptimized); |
| 513 GenerateTailCallToReturnedCode(masm); | 507 GenerateTailCallToReturnedCode(masm); |
| 514 } | 508 } |
| 515 | 509 |
| 516 | 510 |
| 517 | 511 |
| 518 static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) { | 512 static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) { |
| 519 FrameScope scope(masm, StackFrame::INTERNAL); | 513 FrameScope scope(masm, StackFrame::INTERNAL); |
| 520 // Push a copy of the function. | 514 // Push a copy of the function. |
| 521 __ push(edi); | 515 __ push(edi); |
| 522 // Push call kind information. | |
| 523 __ push(ecx); | |
| 524 // Function is also the parameter to the runtime call. | 516 // Function is also the parameter to the runtime call. |
| 525 __ push(edi); | 517 __ push(edi); |
| 526 // Whether to compile in a background thread. | 518 // Whether to compile in a background thread. |
| 527 __ Push(masm->isolate()->factory()->ToBoolean(concurrent)); | 519 __ Push(masm->isolate()->factory()->ToBoolean(concurrent)); |
| 528 | 520 |
| 529 __ CallRuntime(Runtime::kCompileOptimized, 2); | 521 __ CallRuntime(Runtime::kCompileOptimized, 2); |
| 530 // Restore call kind information. | |
| 531 __ pop(ecx); | |
| 532 // Restore receiver. | 522 // Restore receiver. |
| 533 __ pop(edi); | 523 __ pop(edi); |
| 534 } | 524 } |
| 535 | 525 |
| 536 | 526 |
| 537 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 527 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { |
| 538 CallCompileOptimized(masm, false); | 528 CallCompileOptimized(masm, false); |
| 539 GenerateTailCallToReturnedCode(masm); | 529 GenerateTailCallToReturnedCode(masm); |
| 540 } | 530 } |
| 541 | 531 |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 __ test(edx, edx); | 817 __ test(edx, edx); |
| 828 __ j(zero, &function); | 818 __ j(zero, &function); |
| 829 __ Set(ebx, Immediate(0)); | 819 __ Set(ebx, Immediate(0)); |
| 830 __ cmp(edx, Immediate(1)); | 820 __ cmp(edx, Immediate(1)); |
| 831 __ j(not_equal, &non_proxy); | 821 __ j(not_equal, &non_proxy); |
| 832 | 822 |
| 833 __ pop(edx); // return address | 823 __ pop(edx); // return address |
| 834 __ push(edi); // re-add proxy object as additional argument | 824 __ push(edi); // re-add proxy object as additional argument |
| 835 __ push(edx); | 825 __ push(edx); |
| 836 __ inc(eax); | 826 __ inc(eax); |
| 837 __ SetCallKind(ecx, CALL_AS_FUNCTION); | |
| 838 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); | 827 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); |
| 839 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 828 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 840 RelocInfo::CODE_TARGET); | 829 RelocInfo::CODE_TARGET); |
| 841 | 830 |
| 842 __ bind(&non_proxy); | 831 __ bind(&non_proxy); |
| 843 __ SetCallKind(ecx, CALL_AS_METHOD); | |
| 844 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | 832 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
| 845 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 833 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 846 RelocInfo::CODE_TARGET); | 834 RelocInfo::CODE_TARGET); |
| 847 __ bind(&function); | 835 __ bind(&function); |
| 848 } | 836 } |
| 849 | 837 |
| 850 // 5b. Get the code to call from the function and check that the number of | 838 // 5b. Get the code to call from the function and check that the number of |
| 851 // expected arguments matches what we're providing. If so, jump | 839 // expected arguments matches what we're providing. If so, jump |
| 852 // (tail-call) to the code in register edx without checking arguments. | 840 // (tail-call) to the code in register edx without checking arguments. |
| 853 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 841 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 854 __ mov(ebx, | 842 __ mov(ebx, |
| 855 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); | 843 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 856 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 844 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
| 857 __ SmiUntag(ebx); | 845 __ SmiUntag(ebx); |
| 858 __ SetCallKind(ecx, CALL_AS_FUNCTION); | |
| 859 __ cmp(eax, ebx); | 846 __ cmp(eax, ebx); |
| 860 __ j(not_equal, | 847 __ j(not_equal, |
| 861 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); | 848 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); |
| 862 | 849 |
| 863 ParameterCount expected(0); | 850 ParameterCount expected(0); |
| 864 __ InvokeCode(edx, expected, expected, JUMP_FUNCTION, NullCallWrapper(), | 851 __ InvokeCode(edx, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
| 865 CALL_AS_FUNCTION); | |
| 866 } | 852 } |
| 867 | 853 |
| 868 | 854 |
| 869 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 855 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
| 870 static const int kArgumentsOffset = 2 * kPointerSize; | 856 static const int kArgumentsOffset = 2 * kPointerSize; |
| 871 static const int kReceiverOffset = 3 * kPointerSize; | 857 static const int kReceiverOffset = 3 * kPointerSize; |
| 872 static const int kFunctionOffset = 4 * kPointerSize; | 858 static const int kFunctionOffset = 4 * kPointerSize; |
| 873 { | 859 { |
| 874 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 860 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 875 | 861 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 __ j(not_equal, &loop); | 978 __ j(not_equal, &loop); |
| 993 | 979 |
| 994 // Call the function. | 980 // Call the function. |
| 995 Label call_proxy; | 981 Label call_proxy; |
| 996 __ mov(eax, ecx); | 982 __ mov(eax, ecx); |
| 997 ParameterCount actual(eax); | 983 ParameterCount actual(eax); |
| 998 __ SmiUntag(eax); | 984 __ SmiUntag(eax); |
| 999 __ mov(edi, Operand(ebp, kFunctionOffset)); | 985 __ mov(edi, Operand(ebp, kFunctionOffset)); |
| 1000 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 986 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 1001 __ j(not_equal, &call_proxy); | 987 __ j(not_equal, &call_proxy); |
| 1002 __ InvokeFunction(edi, actual, CALL_FUNCTION, | 988 __ InvokeFunction(edi, actual, CALL_FUNCTION, NullCallWrapper()); |
| 1003 NullCallWrapper(), CALL_AS_FUNCTION); | |
| 1004 | 989 |
| 1005 frame_scope.GenerateLeaveFrame(); | 990 frame_scope.GenerateLeaveFrame(); |
| 1006 __ ret(3 * kPointerSize); // remove this, receiver, and arguments | 991 __ ret(3 * kPointerSize); // remove this, receiver, and arguments |
| 1007 | 992 |
| 1008 // Call the function proxy. | 993 // Call the function proxy. |
| 1009 __ bind(&call_proxy); | 994 __ bind(&call_proxy); |
| 1010 __ push(edi); // add function proxy as last argument | 995 __ push(edi); // add function proxy as last argument |
| 1011 __ inc(eax); | 996 __ inc(eax); |
| 1012 __ Set(ebx, Immediate(0)); | 997 __ Set(ebx, Immediate(0)); |
| 1013 __ SetCallKind(ecx, CALL_AS_FUNCTION); | |
| 1014 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); | 998 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); |
| 1015 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 999 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 1016 RelocInfo::CODE_TARGET); | 1000 RelocInfo::CODE_TARGET); |
| 1017 | 1001 |
| 1018 // Leave internal frame. | 1002 // Leave internal frame. |
| 1019 } | 1003 } |
| 1020 __ ret(3 * kPointerSize); // remove this, receiver, and arguments | 1004 __ ret(3 * kPointerSize); // remove this, receiver, and arguments |
| 1021 } | 1005 } |
| 1022 | 1006 |
| 1023 | 1007 |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1238 __ pop(ecx); | 1222 __ pop(ecx); |
| 1239 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 1223 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
| 1240 __ push(ecx); | 1224 __ push(ecx); |
| 1241 } | 1225 } |
| 1242 | 1226 |
| 1243 | 1227 |
| 1244 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1228 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
| 1245 // ----------- S t a t e ------------- | 1229 // ----------- S t a t e ------------- |
| 1246 // -- eax : actual number of arguments | 1230 // -- eax : actual number of arguments |
| 1247 // -- ebx : expected number of arguments | 1231 // -- ebx : expected number of arguments |
| 1248 // -- ecx : call kind information | 1232 // -- edi : function (passed through to callee) |
| 1249 // -- edx : code entry to call | |
| 1250 // ----------------------------------- | 1233 // ----------------------------------- |
| 1251 | 1234 |
| 1252 Label invoke, dont_adapt_arguments; | 1235 Label invoke, dont_adapt_arguments; |
| 1253 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); | 1236 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); |
| 1254 | 1237 |
| 1255 Label enough, too_few; | 1238 Label enough, too_few; |
| 1239 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
| 1256 __ cmp(eax, ebx); | 1240 __ cmp(eax, ebx); |
| 1257 __ j(less, &too_few); | 1241 __ j(less, &too_few); |
| 1258 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); | 1242 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); |
| 1259 __ j(equal, &dont_adapt_arguments); | 1243 __ j(equal, &dont_adapt_arguments); |
| 1260 | 1244 |
| 1261 { // Enough parameters: Actual >= expected. | 1245 { // Enough parameters: Actual >= expected. |
| 1262 __ bind(&enough); | 1246 __ bind(&enough); |
| 1263 EnterArgumentsAdaptorFrame(masm); | 1247 EnterArgumentsAdaptorFrame(masm); |
| 1264 | 1248 |
| 1265 // Copy receiver and all expected arguments. | 1249 // Copy receiver and all expected arguments. |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 | 1365 |
| 1382 __ bind(&ok); | 1366 __ bind(&ok); |
| 1383 __ ret(0); | 1367 __ ret(0); |
| 1384 } | 1368 } |
| 1385 | 1369 |
| 1386 #undef __ | 1370 #undef __ |
| 1387 } | 1371 } |
| 1388 } // namespace v8::internal | 1372 } // namespace v8::internal |
| 1389 | 1373 |
| 1390 #endif // V8_TARGET_ARCH_IA32 | 1374 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |