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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 } | 296 } |
297 __ Ret(); | 297 __ Ret(); |
298 } | 298 } |
299 | 299 |
300 | 300 |
301 static void CallRuntimePassFunction( | 301 static void CallRuntimePassFunction( |
302 MacroAssembler* masm, Runtime::FunctionId function_id) { | 302 MacroAssembler* masm, Runtime::FunctionId function_id) { |
303 FrameScope scope(masm, StackFrame::INTERNAL); | 303 FrameScope scope(masm, StackFrame::INTERNAL); |
304 // Push a copy of the function onto the stack. | 304 // Push a copy of the function onto the stack. |
305 // Push call kind information and function as parameter to the runtime call. | 305 // Push call kind information and function as parameter to the runtime call. |
306 __ Push(a1, t1, a1); | 306 __ Push(a1, a1); |
307 | 307 |
308 __ CallRuntime(function_id, 1); | 308 __ CallRuntime(function_id, 1); |
309 // Restore call kind information and receiver. | 309 // Restore call kind information and receiver. |
310 __ Pop(a1, t1); | 310 __ Pop(a1); |
311 } | 311 } |
312 | 312 |
313 | 313 |
314 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 314 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
315 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 315 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
316 __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset)); | 316 __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset)); |
317 __ Addu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag)); | 317 __ Addu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag)); |
318 __ Jump(at); | 318 __ Jump(at); |
319 } | 319 } |
320 | 320 |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 | 624 |
625 // Call the function. | 625 // Call the function. |
626 // a0: number of arguments | 626 // a0: number of arguments |
627 // a1: constructor function | 627 // a1: constructor function |
628 if (is_api_function) { | 628 if (is_api_function) { |
629 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 629 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
630 Handle<Code> code = | 630 Handle<Code> code = |
631 masm->isolate()->builtins()->HandleApiCallConstruct(); | 631 masm->isolate()->builtins()->HandleApiCallConstruct(); |
632 ParameterCount expected(0); | 632 ParameterCount expected(0); |
633 __ InvokeCode(code, expected, expected, | 633 __ InvokeCode(code, expected, expected, |
634 RelocInfo::CODE_TARGET, CALL_FUNCTION, CALL_AS_METHOD); | 634 RelocInfo::CODE_TARGET, CALL_FUNCTION); |
635 } else { | 635 } else { |
636 ParameterCount actual(a0); | 636 ParameterCount actual(a0); |
637 __ InvokeFunction(a1, actual, CALL_FUNCTION, | 637 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); |
638 NullCallWrapper(), CALL_AS_METHOD); | |
639 } | 638 } |
640 | 639 |
641 // Store offset of return address for deoptimizer. | 640 // Store offset of return address for deoptimizer. |
642 if (!is_api_function && !count_constructions) { | 641 if (!is_api_function && !count_constructions) { |
643 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 642 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
644 } | 643 } |
645 | 644 |
646 // Restore context from the frame. | 645 // Restore context from the frame. |
647 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 646 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
648 | 647 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 __ mov(a0, a3); | 760 __ mov(a0, a3); |
762 if (is_construct) { | 761 if (is_construct) { |
763 // No type feedback cell is available | 762 // No type feedback cell is available |
764 Handle<Object> undefined_sentinel( | 763 Handle<Object> undefined_sentinel( |
765 masm->isolate()->heap()->undefined_value(), masm->isolate()); | 764 masm->isolate()->heap()->undefined_value(), masm->isolate()); |
766 __ li(a2, Operand(undefined_sentinel)); | 765 __ li(a2, Operand(undefined_sentinel)); |
767 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); | 766 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); |
768 __ CallStub(&stub); | 767 __ CallStub(&stub); |
769 } else { | 768 } else { |
770 ParameterCount actual(a0); | 769 ParameterCount actual(a0); |
771 __ InvokeFunction(a1, actual, CALL_FUNCTION, | 770 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); |
772 NullCallWrapper(), CALL_AS_METHOD); | |
773 } | 771 } |
774 | 772 |
775 // Leave internal frame. | 773 // Leave internal frame. |
776 } | 774 } |
777 | 775 |
778 __ Jump(ra); | 776 __ Jump(ra); |
779 } | 777 } |
780 | 778 |
781 | 779 |
782 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 780 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
783 Generate_JSEntryTrampolineHelper(masm, false); | 781 Generate_JSEntryTrampolineHelper(masm, false); |
784 } | 782 } |
785 | 783 |
786 | 784 |
787 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 785 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
788 Generate_JSEntryTrampolineHelper(masm, true); | 786 Generate_JSEntryTrampolineHelper(masm, true); |
789 } | 787 } |
790 | 788 |
791 | 789 |
792 void Builtins::Generate_CompileUnoptimized(MacroAssembler* masm) { | 790 void Builtins::Generate_CompileUnoptimized(MacroAssembler* masm) { |
793 CallRuntimePassFunction(masm, Runtime::kCompileUnoptimized); | 791 CallRuntimePassFunction(masm, Runtime::kCompileUnoptimized); |
794 GenerateTailCallToReturnedCode(masm); | 792 GenerateTailCallToReturnedCode(masm); |
795 } | 793 } |
796 | 794 |
797 | 795 |
798 static void CallCompileOptimized(MacroAssembler* masm, | 796 static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) { |
799 bool concurrent) { | |
800 FrameScope scope(masm, StackFrame::INTERNAL); | 797 FrameScope scope(masm, StackFrame::INTERNAL); |
801 // Push a copy of the function onto the stack. | 798 // Push a copy of the function onto the stack. |
802 // Push call kind information and function as parameter to the runtime call. | 799 // Push function as parameter to the runtime call. |
803 __ Push(a1, t1, a1); | 800 __ Push(a1, a1); |
804 // Whether to compile in a background thread. | 801 // Whether to compile in a background thread. |
805 __ Push(masm->isolate()->factory()->ToBoolean(concurrent)); | 802 __ Push(masm->isolate()->factory()->ToBoolean(concurrent)); |
806 | 803 |
807 __ CallRuntime(Runtime::kCompileOptimized, 2); | 804 __ CallRuntime(Runtime::kCompileOptimized, 2); |
808 // Restore call kind information and receiver. | 805 // Restore receiver. |
809 __ Pop(a1, t1); | 806 __ Pop(a1); |
810 } | 807 } |
811 | 808 |
812 | 809 |
813 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 810 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { |
814 CallCompileOptimized(masm, false); | 811 CallCompileOptimized(masm, false); |
815 GenerateTailCallToReturnedCode(masm); | 812 GenerateTailCallToReturnedCode(masm); |
816 } | 813 } |
817 | 814 |
818 | 815 |
819 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { | 816 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 | 1167 |
1171 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, | 1168 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, |
1172 // or a function proxy via CALL_FUNCTION_PROXY. | 1169 // or a function proxy via CALL_FUNCTION_PROXY. |
1173 // a0: actual number of arguments | 1170 // a0: actual number of arguments |
1174 // a1: function | 1171 // a1: function |
1175 // t0: call type (0: JS function, 1: function proxy, 2: non-function) | 1172 // t0: call type (0: JS function, 1: function proxy, 2: non-function) |
1176 { Label function, non_proxy; | 1173 { Label function, non_proxy; |
1177 __ Branch(&function, eq, t0, Operand(zero_reg)); | 1174 __ Branch(&function, eq, t0, Operand(zero_reg)); |
1178 // Expected number of arguments is 0 for CALL_NON_FUNCTION. | 1175 // Expected number of arguments is 0 for CALL_NON_FUNCTION. |
1179 __ mov(a2, zero_reg); | 1176 __ mov(a2, zero_reg); |
1180 __ SetCallKind(t1, CALL_AS_METHOD); | |
1181 __ Branch(&non_proxy, ne, t0, Operand(1)); | 1177 __ Branch(&non_proxy, ne, t0, Operand(1)); |
1182 | 1178 |
1183 __ push(a1); // Re-add proxy object as additional argument. | 1179 __ push(a1); // Re-add proxy object as additional argument. |
1184 __ Addu(a0, a0, Operand(1)); | 1180 __ Addu(a0, a0, Operand(1)); |
1185 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); | 1181 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); |
1186 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1182 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1187 RelocInfo::CODE_TARGET); | 1183 RelocInfo::CODE_TARGET); |
1188 | 1184 |
1189 __ bind(&non_proxy); | 1185 __ bind(&non_proxy); |
1190 __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION); | 1186 __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION); |
1191 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1187 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1192 RelocInfo::CODE_TARGET); | 1188 RelocInfo::CODE_TARGET); |
1193 __ bind(&function); | 1189 __ bind(&function); |
1194 } | 1190 } |
1195 | 1191 |
1196 // 5b. Get the code to call from the function and check that the number of | 1192 // 5b. Get the code to call from the function and check that the number of |
1197 // expected arguments matches what we're providing. If so, jump | 1193 // expected arguments matches what we're providing. If so, jump |
1198 // (tail-call) to the code in register edx without checking arguments. | 1194 // (tail-call) to the code in register edx without checking arguments. |
1199 // a0: actual number of arguments | 1195 // a0: actual number of arguments |
1200 // a1: function | 1196 // a1: function |
1201 __ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 1197 __ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
1202 __ lw(a2, | 1198 __ lw(a2, |
1203 FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset)); | 1199 FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset)); |
1204 __ sra(a2, a2, kSmiTagSize); | 1200 __ sra(a2, a2, kSmiTagSize); |
1205 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 1201 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
1206 __ SetCallKind(t1, CALL_AS_FUNCTION); | |
1207 // Check formal and actual parameter counts. | 1202 // Check formal and actual parameter counts. |
1208 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1203 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1209 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); | 1204 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); |
1210 | 1205 |
1211 ParameterCount expected(0); | 1206 ParameterCount expected(0); |
1212 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, | 1207 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
1213 NullCallWrapper(), CALL_AS_FUNCTION); | |
1214 } | 1208 } |
1215 | 1209 |
1216 | 1210 |
1217 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 1211 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
1218 const int kIndexOffset = | 1212 const int kIndexOffset = |
1219 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1213 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
1220 const int kLimitOffset = | 1214 const int kLimitOffset = |
1221 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1215 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
1222 const int kArgsOffset = 2 * kPointerSize; | 1216 const int kArgsOffset = 2 * kPointerSize; |
1223 const int kRecvOffset = 3 * kPointerSize; | 1217 const int kRecvOffset = 3 * kPointerSize; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1340 __ Branch(&loop, ne, a0, Operand(a1)); | 1334 __ Branch(&loop, ne, a0, Operand(a1)); |
1341 | 1335 |
1342 // Call the function. | 1336 // Call the function. |
1343 Label call_proxy; | 1337 Label call_proxy; |
1344 ParameterCount actual(a0); | 1338 ParameterCount actual(a0); |
1345 __ sra(a0, a0, kSmiTagSize); | 1339 __ sra(a0, a0, kSmiTagSize); |
1346 __ lw(a1, MemOperand(fp, kFunctionOffset)); | 1340 __ lw(a1, MemOperand(fp, kFunctionOffset)); |
1347 __ GetObjectType(a1, a2, a2); | 1341 __ GetObjectType(a1, a2, a2); |
1348 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); | 1342 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); |
1349 | 1343 |
1350 __ InvokeFunction(a1, actual, CALL_FUNCTION, | 1344 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); |
1351 NullCallWrapper(), CALL_AS_FUNCTION); | |
1352 | 1345 |
1353 frame_scope.GenerateLeaveFrame(); | 1346 frame_scope.GenerateLeaveFrame(); |
1354 __ Ret(USE_DELAY_SLOT); | 1347 __ Ret(USE_DELAY_SLOT); |
1355 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. | 1348 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. |
1356 | 1349 |
1357 // Call the function proxy. | 1350 // Call the function proxy. |
1358 __ bind(&call_proxy); | 1351 __ bind(&call_proxy); |
1359 __ push(a1); // Add function proxy as last argument. | 1352 __ push(a1); // Add function proxy as last argument. |
1360 __ Addu(a0, a0, Operand(1)); | 1353 __ Addu(a0, a0, Operand(1)); |
1361 __ li(a2, Operand(0, RelocInfo::NONE32)); | 1354 __ li(a2, Operand(0, RelocInfo::NONE32)); |
1362 __ SetCallKind(t1, CALL_AS_FUNCTION); | |
1363 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); | 1355 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY); |
1364 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1356 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1365 RelocInfo::CODE_TARGET); | 1357 RelocInfo::CODE_TARGET); |
1366 // Tear down the internal frame and remove function, receiver and args. | 1358 // Tear down the internal frame and remove function, receiver and args. |
1367 } | 1359 } |
1368 | 1360 |
1369 __ Ret(USE_DELAY_SLOT); | 1361 __ Ret(USE_DELAY_SLOT); |
1370 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. | 1362 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. |
1371 } | 1363 } |
1372 | 1364 |
(...skipping 24 matching lines...) Expand all Loading... |
1397 } | 1389 } |
1398 | 1390 |
1399 | 1391 |
1400 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1392 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1401 // State setup as expected by MacroAssembler::InvokePrologue. | 1393 // State setup as expected by MacroAssembler::InvokePrologue. |
1402 // ----------- S t a t e ------------- | 1394 // ----------- S t a t e ------------- |
1403 // -- a0: actual arguments count | 1395 // -- a0: actual arguments count |
1404 // -- a1: function (passed through to callee) | 1396 // -- a1: function (passed through to callee) |
1405 // -- a2: expected arguments count | 1397 // -- a2: expected arguments count |
1406 // -- a3: callee code entry | 1398 // -- a3: callee code entry |
1407 // -- t1: call kind information | |
1408 // ----------------------------------- | 1399 // ----------------------------------- |
1409 | 1400 |
1410 Label invoke, dont_adapt_arguments; | 1401 Label invoke, dont_adapt_arguments; |
1411 | 1402 |
1412 Label enough, too_few; | 1403 Label enough, too_few; |
1413 __ Branch(&dont_adapt_arguments, eq, | 1404 __ Branch(&dont_adapt_arguments, eq, |
1414 a2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); | 1405 a2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); |
1415 // We use Uless as the number of argument should always be greater than 0. | 1406 // We use Uless as the number of argument should always be greater than 0. |
1416 __ Branch(&too_few, Uless, a0, Operand(a2)); | 1407 __ Branch(&too_few, Uless, a0, Operand(a2)); |
1417 | 1408 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 __ bind(&dont_adapt_arguments); | 1506 __ bind(&dont_adapt_arguments); |
1516 __ Jump(a3); | 1507 __ Jump(a3); |
1517 } | 1508 } |
1518 | 1509 |
1519 | 1510 |
1520 #undef __ | 1511 #undef __ |
1521 | 1512 |
1522 } } // namespace v8::internal | 1513 } } // namespace v8::internal |
1523 | 1514 |
1524 #endif // V8_TARGET_ARCH_MIPS | 1515 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |