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