OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 __ movq(rbx, FieldOperand(rbx, SharedFunctionInfo::kConstructStubOffset)); | 91 __ movq(rbx, FieldOperand(rbx, SharedFunctionInfo::kConstructStubOffset)); |
92 __ lea(rbx, FieldOperand(rbx, Code::kHeaderSize)); | 92 __ lea(rbx, FieldOperand(rbx, Code::kHeaderSize)); |
93 __ jmp(rbx); | 93 __ jmp(rbx); |
94 | 94 |
95 // rdi: called object | 95 // rdi: called object |
96 // rax: number of arguments | 96 // rax: number of arguments |
97 __ bind(&non_function_call); | 97 __ bind(&non_function_call); |
98 // Set expected number of arguments to zero (not changing rax). | 98 // Set expected number of arguments to zero (not changing rax). |
99 __ Set(rbx, 0); | 99 __ Set(rbx, 0); |
100 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 100 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
| 101 __ SetCallKind(rcx, CALL_AS_METHOD); |
101 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 102 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
102 RelocInfo::CODE_TARGET); | 103 RelocInfo::CODE_TARGET); |
103 } | 104 } |
104 | 105 |
105 | 106 |
106 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 107 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
107 bool is_api_function, | 108 bool is_api_function, |
108 bool count_constructions) { | 109 bool count_constructions) { |
109 // Should never count constructions for api objects. | 110 // Should never count constructions for api objects. |
110 ASSERT(!is_api_function || !count_constructions); | 111 ASSERT(!is_api_function || !count_constructions); |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 Generate_JSEntryTrampolineHelper(masm, true); | 520 Generate_JSEntryTrampolineHelper(masm, true); |
520 } | 521 } |
521 | 522 |
522 | 523 |
523 void Builtins::Generate_LazyCompile(MacroAssembler* masm) { | 524 void Builtins::Generate_LazyCompile(MacroAssembler* masm) { |
524 // Enter an internal frame. | 525 // Enter an internal frame. |
525 __ EnterInternalFrame(); | 526 __ EnterInternalFrame(); |
526 | 527 |
527 // Push a copy of the function onto the stack. | 528 // Push a copy of the function onto the stack. |
528 __ push(rdi); | 529 __ push(rdi); |
| 530 // Push call kind information. |
| 531 __ push(rcx); |
529 | 532 |
530 __ push(rdi); // Function is also the parameter to the runtime call. | 533 __ push(rdi); // Function is also the parameter to the runtime call. |
531 __ CallRuntime(Runtime::kLazyCompile, 1); | 534 __ CallRuntime(Runtime::kLazyCompile, 1); |
| 535 |
| 536 // Restore call kind information. |
| 537 __ pop(rcx); |
| 538 // Restore receiver. |
532 __ pop(rdi); | 539 __ pop(rdi); |
533 | 540 |
534 // Tear down temporary frame. | 541 // Tear down temporary frame. |
535 __ LeaveInternalFrame(); | 542 __ LeaveInternalFrame(); |
536 | 543 |
537 // Do a tail-call of the compiled function. | 544 // Do a tail-call of the compiled function. |
538 __ lea(rcx, FieldOperand(rax, Code::kHeaderSize)); | 545 __ lea(rax, FieldOperand(rax, Code::kHeaderSize)); |
539 __ jmp(rcx); | 546 __ jmp(rax); |
540 } | 547 } |
541 | 548 |
542 | 549 |
543 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) { | 550 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) { |
544 // Enter an internal frame. | 551 // Enter an internal frame. |
545 __ EnterInternalFrame(); | 552 __ EnterInternalFrame(); |
546 | 553 |
547 // Push a copy of the function onto the stack. | 554 // Push a copy of the function onto the stack. |
548 __ push(rdi); | 555 __ push(rdi); |
| 556 // Push call kind information. |
| 557 __ push(rcx); |
549 | 558 |
550 __ push(rdi); // Function is also the parameter to the runtime call. | 559 __ push(rdi); // Function is also the parameter to the runtime call. |
551 __ CallRuntime(Runtime::kLazyRecompile, 1); | 560 __ CallRuntime(Runtime::kLazyRecompile, 1); |
552 | 561 |
553 // Restore function and tear down temporary frame. | 562 // Restore call kind information. |
| 563 __ pop(rcx); |
| 564 // Restore function. |
554 __ pop(rdi); | 565 __ pop(rdi); |
| 566 |
| 567 // Tear down temporary frame. |
555 __ LeaveInternalFrame(); | 568 __ LeaveInternalFrame(); |
556 | 569 |
557 // Do a tail-call of the compiled function. | 570 // Do a tail-call of the compiled function. |
558 __ lea(rcx, FieldOperand(rax, Code::kHeaderSize)); | 571 __ lea(rax, FieldOperand(rax, Code::kHeaderSize)); |
559 __ jmp(rcx); | 572 __ jmp(rax); |
560 } | 573 } |
561 | 574 |
562 | 575 |
563 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, | 576 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
564 Deoptimizer::BailoutType type) { | 577 Deoptimizer::BailoutType type) { |
565 // Enter an internal frame. | 578 // Enter an internal frame. |
566 __ EnterInternalFrame(); | 579 __ EnterInternalFrame(); |
567 | 580 |
568 // Pass the deoptimization type to the runtime system. | 581 // Pass the deoptimization type to the runtime system. |
569 __ Push(Smi::FromInt(static_cast<int>(type))); | 582 __ Push(Smi::FromInt(static_cast<int>(type))); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 __ pop(rbx); // Discard copy of return address. | 746 __ pop(rbx); // Discard copy of return address. |
734 __ decq(rax); // One fewer argument (first argument is new receiver). | 747 __ decq(rax); // One fewer argument (first argument is new receiver). |
735 } | 748 } |
736 | 749 |
737 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. | 750 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. |
738 { Label function; | 751 { Label function; |
739 __ testq(rdi, rdi); | 752 __ testq(rdi, rdi); |
740 __ j(not_zero, &function); | 753 __ j(not_zero, &function); |
741 __ Set(rbx, 0); | 754 __ Set(rbx, 0); |
742 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); | 755 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); |
| 756 __ SetCallKind(rcx, CALL_AS_METHOD); |
743 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 757 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
744 RelocInfo::CODE_TARGET); | 758 RelocInfo::CODE_TARGET); |
745 __ bind(&function); | 759 __ bind(&function); |
746 } | 760 } |
747 | 761 |
748 // 5b. Get the code to call from the function and check that the number of | 762 // 5b. Get the code to call from the function and check that the number of |
749 // expected arguments matches what we're providing. If so, jump | 763 // expected arguments matches what we're providing. If so, jump |
750 // (tail-call) to the code in register edx without checking arguments. | 764 // (tail-call) to the code in register edx without checking arguments. |
751 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 765 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
752 __ movsxlq(rbx, | 766 __ movsxlq(rbx, |
753 FieldOperand(rdx, | 767 FieldOperand(rdx, |
754 SharedFunctionInfo::kFormalParameterCountOffset)); | 768 SharedFunctionInfo::kFormalParameterCountOffset)); |
755 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 769 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
| 770 __ SetCallKind(rcx, CALL_AS_METHOD); |
756 __ cmpq(rax, rbx); | 771 __ cmpq(rax, rbx); |
757 __ j(not_equal, | 772 __ j(not_equal, |
758 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 773 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
759 RelocInfo::CODE_TARGET); | 774 RelocInfo::CODE_TARGET); |
760 | 775 |
761 ParameterCount expected(0); | 776 ParameterCount expected(0); |
762 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION); | 777 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION); |
763 } | 778 } |
764 | 779 |
765 | 780 |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 1343 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
1329 __ push(rbp); | 1344 __ push(rbp); |
1330 __ movq(rbp, rsp); | 1345 __ movq(rbp, rsp); |
1331 | 1346 |
1332 // Store the arguments adaptor context sentinel. | 1347 // Store the arguments adaptor context sentinel. |
1333 __ Push(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 1348 __ Push(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
1334 | 1349 |
1335 // Push the function on the stack. | 1350 // Push the function on the stack. |
1336 __ push(rdi); | 1351 __ push(rdi); |
1337 | 1352 |
1338 // Preserve the number of arguments on the stack. Must preserve both | 1353 // Preserve the number of arguments on the stack. Must preserve rax, |
1339 // rax and rbx because these registers are used when copying the | 1354 // rbx and rcx because these registers are used when copying the |
1340 // arguments and the receiver. | 1355 // arguments and the receiver. |
1341 __ Integer32ToSmi(rcx, rax); | 1356 __ Integer32ToSmi(r8, rax); |
1342 __ push(rcx); | 1357 __ push(r8); |
1343 } | 1358 } |
1344 | 1359 |
1345 | 1360 |
1346 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | 1361 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { |
1347 // Retrieve the number of arguments from the stack. Number is a Smi. | 1362 // Retrieve the number of arguments from the stack. Number is a Smi. |
1348 __ movq(rbx, Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1363 __ movq(rbx, Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1349 | 1364 |
1350 // Leave the frame. | 1365 // Leave the frame. |
1351 __ movq(rsp, rbp); | 1366 __ movq(rsp, rbp); |
1352 __ pop(rbp); | 1367 __ pop(rbp); |
1353 | 1368 |
1354 // Remove caller arguments from the stack. | 1369 // Remove caller arguments from the stack. |
1355 __ pop(rcx); | 1370 __ pop(rcx); |
1356 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); | 1371 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); |
1357 __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); | 1372 __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); |
1358 __ push(rcx); | 1373 __ push(rcx); |
1359 } | 1374 } |
1360 | 1375 |
1361 | 1376 |
1362 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1377 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1363 // ----------- S t a t e ------------- | 1378 // ----------- S t a t e ------------- |
1364 // -- rax : actual number of arguments | 1379 // -- rax : actual number of arguments |
1365 // -- rbx : expected number of arguments | 1380 // -- rbx : expected number of arguments |
| 1381 // -- rcx : call kind information |
1366 // -- rdx : code entry to call | 1382 // -- rdx : code entry to call |
1367 // ----------------------------------- | 1383 // ----------------------------------- |
1368 | 1384 |
1369 Label invoke, dont_adapt_arguments; | 1385 Label invoke, dont_adapt_arguments; |
1370 Counters* counters = masm->isolate()->counters(); | 1386 Counters* counters = masm->isolate()->counters(); |
1371 __ IncrementCounter(counters->arguments_adaptors(), 1); | 1387 __ IncrementCounter(counters->arguments_adaptors(), 1); |
1372 | 1388 |
1373 Label enough, too_few; | 1389 Label enough, too_few; |
1374 __ cmpq(rax, rbx); | 1390 __ cmpq(rax, rbx); |
1375 __ j(less, &too_few); | 1391 __ j(less, &too_few); |
1376 __ cmpq(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); | 1392 __ cmpq(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); |
1377 __ j(equal, &dont_adapt_arguments); | 1393 __ j(equal, &dont_adapt_arguments); |
1378 | 1394 |
1379 { // Enough parameters: Actual >= expected. | 1395 { // Enough parameters: Actual >= expected. |
1380 __ bind(&enough); | 1396 __ bind(&enough); |
1381 EnterArgumentsAdaptorFrame(masm); | 1397 EnterArgumentsAdaptorFrame(masm); |
1382 | 1398 |
1383 // Copy receiver and all expected arguments. | 1399 // Copy receiver and all expected arguments. |
1384 const int offset = StandardFrameConstants::kCallerSPOffset; | 1400 const int offset = StandardFrameConstants::kCallerSPOffset; |
1385 __ lea(rax, Operand(rbp, rax, times_pointer_size, offset)); | 1401 __ lea(rax, Operand(rbp, rax, times_pointer_size, offset)); |
1386 __ Set(rcx, -1); // account for receiver | 1402 __ Set(r8, -1); // account for receiver |
1387 | 1403 |
1388 Label copy; | 1404 Label copy; |
1389 __ bind(©); | 1405 __ bind(©); |
1390 __ incq(rcx); | 1406 __ incq(r8); |
1391 __ push(Operand(rax, 0)); | 1407 __ push(Operand(rax, 0)); |
1392 __ subq(rax, Immediate(kPointerSize)); | 1408 __ subq(rax, Immediate(kPointerSize)); |
1393 __ cmpq(rcx, rbx); | 1409 __ cmpq(r8, rbx); |
1394 __ j(less, ©); | 1410 __ j(less, ©); |
1395 __ jmp(&invoke); | 1411 __ jmp(&invoke); |
1396 } | 1412 } |
1397 | 1413 |
1398 { // Too few parameters: Actual < expected. | 1414 { // Too few parameters: Actual < expected. |
1399 __ bind(&too_few); | 1415 __ bind(&too_few); |
1400 EnterArgumentsAdaptorFrame(masm); | 1416 EnterArgumentsAdaptorFrame(masm); |
1401 | 1417 |
1402 // Copy receiver and all actual arguments. | 1418 // Copy receiver and all actual arguments. |
1403 const int offset = StandardFrameConstants::kCallerSPOffset; | 1419 const int offset = StandardFrameConstants::kCallerSPOffset; |
1404 __ lea(rdi, Operand(rbp, rax, times_pointer_size, offset)); | 1420 __ lea(rdi, Operand(rbp, rax, times_pointer_size, offset)); |
1405 __ Set(rcx, -1); // account for receiver | 1421 __ Set(r8, -1); // account for receiver |
1406 | 1422 |
1407 Label copy; | 1423 Label copy; |
1408 __ bind(©); | 1424 __ bind(©); |
1409 __ incq(rcx); | 1425 __ incq(r8); |
1410 __ push(Operand(rdi, 0)); | 1426 __ push(Operand(rdi, 0)); |
1411 __ subq(rdi, Immediate(kPointerSize)); | 1427 __ subq(rdi, Immediate(kPointerSize)); |
1412 __ cmpq(rcx, rax); | 1428 __ cmpq(r8, rax); |
1413 __ j(less, ©); | 1429 __ j(less, ©); |
1414 | 1430 |
1415 // Fill remaining expected arguments with undefined values. | 1431 // Fill remaining expected arguments with undefined values. |
1416 Label fill; | 1432 Label fill; |
1417 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); | 1433 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); |
1418 __ bind(&fill); | 1434 __ bind(&fill); |
1419 __ incq(rcx); | 1435 __ incq(r8); |
1420 __ push(kScratchRegister); | 1436 __ push(kScratchRegister); |
1421 __ cmpq(rcx, rbx); | 1437 __ cmpq(r8, rbx); |
1422 __ j(less, &fill); | 1438 __ j(less, &fill); |
1423 | 1439 |
1424 // Restore function pointer. | 1440 // Restore function pointer. |
1425 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1441 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1426 } | 1442 } |
1427 | 1443 |
1428 // Call the entry point. | 1444 // Call the entry point. |
1429 __ bind(&invoke); | 1445 __ bind(&invoke); |
1430 __ call(rdx); | 1446 __ call(rdx); |
1431 | 1447 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1495 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); | 1511 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |
1496 generator.Generate(); | 1512 generator.Generate(); |
1497 } | 1513 } |
1498 | 1514 |
1499 | 1515 |
1500 #undef __ | 1516 #undef __ |
1501 | 1517 |
1502 } } // namespace v8::internal | 1518 } } // namespace v8::internal |
1503 | 1519 |
1504 #endif // V8_TARGET_ARCH_X64 | 1520 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |