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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 __ jmp(Operand(ebx)); | 95 __ jmp(Operand(ebx)); |
96 | 96 |
97 // edi: called object | 97 // edi: called object |
98 // eax: number of arguments | 98 // eax: number of arguments |
99 __ bind(&non_function_call); | 99 __ bind(&non_function_call); |
100 // Set expected number of arguments to zero (not changing eax). | 100 // Set expected number of arguments to zero (not changing eax). |
101 __ Set(ebx, Immediate(0)); | 101 __ Set(ebx, Immediate(0)); |
102 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 102 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
103 Handle<Code> arguments_adaptor = | 103 Handle<Code> arguments_adaptor = |
104 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 104 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
| 105 __ SetCallKind(ecx, CALL_AS_METHOD); |
105 __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET); | 106 __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET); |
106 } | 107 } |
107 | 108 |
108 | 109 |
109 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 110 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
110 bool is_api_function, | 111 bool is_api_function, |
111 bool count_constructions) { | 112 bool count_constructions) { |
112 // Should never count constructions for api objects. | 113 // Should never count constructions for api objects. |
113 ASSERT(!is_api_function || !count_constructions); | 114 ASSERT(!is_api_function || !count_constructions); |
114 | 115 |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 | 461 |
461 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 462 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
462 Generate_JSEntryTrampolineHelper(masm, true); | 463 Generate_JSEntryTrampolineHelper(masm, true); |
463 } | 464 } |
464 | 465 |
465 | 466 |
466 void Builtins::Generate_LazyCompile(MacroAssembler* masm) { | 467 void Builtins::Generate_LazyCompile(MacroAssembler* masm) { |
467 // Enter an internal frame. | 468 // Enter an internal frame. |
468 __ EnterInternalFrame(); | 469 __ EnterInternalFrame(); |
469 | 470 |
470 // Push a copy of the function onto the stack. | 471 // Push a copy of the function. |
471 __ push(edi); | 472 __ push(edi); |
| 473 // Push call kind information. |
| 474 __ push(ecx); |
472 | 475 |
473 __ push(edi); // Function is also the parameter to the runtime call. | 476 __ push(edi); // Function is also the parameter to the runtime call. |
474 __ CallRuntime(Runtime::kLazyCompile, 1); | 477 __ CallRuntime(Runtime::kLazyCompile, 1); |
| 478 |
| 479 // Restore call kind information. |
| 480 __ pop(ecx); |
| 481 // Restore receiver. |
475 __ pop(edi); | 482 __ pop(edi); |
476 | 483 |
477 // Tear down temporary frame. | 484 // Tear down temporary frame. |
478 __ LeaveInternalFrame(); | 485 __ LeaveInternalFrame(); |
479 | 486 |
480 // Do a tail-call of the compiled function. | 487 // Do a tail-call of the compiled function. |
481 __ lea(ecx, FieldOperand(eax, Code::kHeaderSize)); | 488 __ lea(eax, FieldOperand(eax, Code::kHeaderSize)); |
482 __ jmp(Operand(ecx)); | 489 __ jmp(Operand(eax)); |
483 } | 490 } |
484 | 491 |
485 | 492 |
486 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) { | 493 void Builtins::Generate_LazyRecompile(MacroAssembler* masm) { |
487 // Enter an internal frame. | 494 // Enter an internal frame. |
488 __ EnterInternalFrame(); | 495 __ EnterInternalFrame(); |
489 | 496 |
490 // Push a copy of the function onto the stack. | 497 // Push a copy of the function onto the stack. |
491 __ push(edi); | 498 __ push(edi); |
| 499 // Push call kind information. |
| 500 __ push(ecx); |
492 | 501 |
493 __ push(edi); // Function is also the parameter to the runtime call. | 502 __ push(edi); // Function is also the parameter to the runtime call. |
494 __ CallRuntime(Runtime::kLazyRecompile, 1); | 503 __ CallRuntime(Runtime::kLazyRecompile, 1); |
495 | 504 |
496 // Restore function and tear down temporary frame. | 505 // Restore call kind information. |
| 506 __ pop(ecx); |
| 507 // Restore receiver. |
497 __ pop(edi); | 508 __ pop(edi); |
| 509 |
| 510 // Tear down temporary frame. |
498 __ LeaveInternalFrame(); | 511 __ LeaveInternalFrame(); |
499 | 512 |
500 // Do a tail-call of the compiled function. | 513 // Do a tail-call of the compiled function. |
501 __ lea(ecx, FieldOperand(eax, Code::kHeaderSize)); | 514 __ lea(eax, FieldOperand(eax, Code::kHeaderSize)); |
502 __ jmp(Operand(ecx)); | 515 __ jmp(Operand(eax)); |
503 } | 516 } |
504 | 517 |
505 | 518 |
506 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, | 519 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
507 Deoptimizer::BailoutType type) { | 520 Deoptimizer::BailoutType type) { |
508 // Enter an internal frame. | 521 // Enter an internal frame. |
509 __ EnterInternalFrame(); | 522 __ EnterInternalFrame(); |
510 | 523 |
511 // Pass the function and deoptimization type to the runtime system. | 524 // Pass the function and deoptimization type to the runtime system. |
512 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); | 525 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 __ pop(ebx); // Discard copy of return address. | 689 __ pop(ebx); // Discard copy of return address. |
677 __ dec(eax); // One fewer argument (first argument is new receiver). | 690 __ dec(eax); // One fewer argument (first argument is new receiver). |
678 } | 691 } |
679 | 692 |
680 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. | 693 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. |
681 { Label function; | 694 { Label function; |
682 __ test(edi, Operand(edi)); | 695 __ test(edi, Operand(edi)); |
683 __ j(not_zero, &function); | 696 __ j(not_zero, &function); |
684 __ Set(ebx, Immediate(0)); | 697 __ Set(ebx, Immediate(0)); |
685 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | 698 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
| 699 __ SetCallKind(ecx, CALL_AS_METHOD); |
686 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 700 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
687 RelocInfo::CODE_TARGET); | 701 RelocInfo::CODE_TARGET); |
688 __ bind(&function); | 702 __ bind(&function); |
689 } | 703 } |
690 | 704 |
691 // 5b. Get the code to call from the function and check that the number of | 705 // 5b. Get the code to call from the function and check that the number of |
692 // expected arguments matches what we're providing. If so, jump | 706 // expected arguments matches what we're providing. If so, jump |
693 // (tail-call) to the code in register edx without checking arguments. | 707 // (tail-call) to the code in register edx without checking arguments. |
694 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 708 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
695 __ mov(ebx, | 709 __ mov(ebx, |
696 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); | 710 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); |
697 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 711 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
698 __ SmiUntag(ebx); | 712 __ SmiUntag(ebx); |
| 713 __ SetCallKind(ecx, CALL_AS_METHOD); |
699 __ cmp(eax, Operand(ebx)); | 714 __ cmp(eax, Operand(ebx)); |
700 __ j(not_equal, | 715 __ j(not_equal, |
701 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); | 716 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); |
702 | 717 |
703 ParameterCount expected(0); | 718 ParameterCount expected(0); |
704 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION); | 719 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION); |
705 } | 720 } |
706 | 721 |
707 | 722 |
708 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 723 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 1437 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
1423 __ push(ebp); | 1438 __ push(ebp); |
1424 __ mov(ebp, Operand(esp)); | 1439 __ mov(ebp, Operand(esp)); |
1425 | 1440 |
1426 // Store the arguments adaptor context sentinel. | 1441 // Store the arguments adaptor context sentinel. |
1427 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 1442 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
1428 | 1443 |
1429 // Push the function on the stack. | 1444 // Push the function on the stack. |
1430 __ push(edi); | 1445 __ push(edi); |
1431 | 1446 |
1432 // Preserve the number of arguments on the stack. Must preserve both | 1447 // Preserve the number of arguments on the stack. Must preserve eax, |
1433 // eax and ebx because these registers are used when copying the | 1448 // ebx and ecx because these registers are used when copying the |
1434 // arguments and the receiver. | 1449 // arguments and the receiver. |
1435 ASSERT(kSmiTagSize == 1); | 1450 ASSERT(kSmiTagSize == 1); |
1436 __ lea(ecx, Operand(eax, eax, times_1, kSmiTag)); | 1451 __ lea(edi, Operand(eax, eax, times_1, kSmiTag)); |
1437 __ push(ecx); | 1452 __ push(edi); |
1438 } | 1453 } |
1439 | 1454 |
1440 | 1455 |
1441 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | 1456 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { |
1442 // Retrieve the number of arguments from the stack. | 1457 // Retrieve the number of arguments from the stack. |
1443 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1458 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1444 | 1459 |
1445 // Leave the frame. | 1460 // Leave the frame. |
1446 __ leave(); | 1461 __ leave(); |
1447 | 1462 |
1448 // Remove caller arguments from the stack. | 1463 // Remove caller arguments from the stack. |
1449 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 1464 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
1450 __ pop(ecx); | 1465 __ pop(ecx); |
1451 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 1466 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
1452 __ push(ecx); | 1467 __ push(ecx); |
1453 } | 1468 } |
1454 | 1469 |
1455 | 1470 |
1456 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1471 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1457 // ----------- S t a t e ------------- | 1472 // ----------- S t a t e ------------- |
1458 // -- eax : actual number of arguments | 1473 // -- eax : actual number of arguments |
1459 // -- ebx : expected number of arguments | 1474 // -- ebx : expected number of arguments |
| 1475 // -- ecx : call kind information |
1460 // -- edx : code entry to call | 1476 // -- edx : code entry to call |
1461 // ----------------------------------- | 1477 // ----------------------------------- |
1462 | 1478 |
1463 Label invoke, dont_adapt_arguments; | 1479 Label invoke, dont_adapt_arguments; |
1464 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); | 1480 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); |
1465 | 1481 |
1466 Label enough, too_few; | 1482 Label enough, too_few; |
1467 __ cmp(eax, Operand(ebx)); | 1483 __ cmp(eax, Operand(ebx)); |
1468 __ j(less, &too_few); | 1484 __ j(less, &too_few); |
1469 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); | 1485 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); |
1470 __ j(equal, &dont_adapt_arguments); | 1486 __ j(equal, &dont_adapt_arguments); |
1471 | 1487 |
1472 { // Enough parameters: Actual >= expected. | 1488 { // Enough parameters: Actual >= expected. |
1473 __ bind(&enough); | 1489 __ bind(&enough); |
1474 EnterArgumentsAdaptorFrame(masm); | 1490 EnterArgumentsAdaptorFrame(masm); |
1475 | 1491 |
1476 // Copy receiver and all expected arguments. | 1492 // Copy receiver and all expected arguments. |
1477 const int offset = StandardFrameConstants::kCallerSPOffset; | 1493 const int offset = StandardFrameConstants::kCallerSPOffset; |
1478 __ lea(eax, Operand(ebp, eax, times_4, offset)); | 1494 __ lea(eax, Operand(ebp, eax, times_4, offset)); |
1479 __ mov(ecx, -1); // account for receiver | 1495 __ mov(edi, -1); // account for receiver |
1480 | 1496 |
1481 Label copy; | 1497 Label copy; |
1482 __ bind(©); | 1498 __ bind(©); |
1483 __ inc(ecx); | 1499 __ inc(edi); |
1484 __ push(Operand(eax, 0)); | 1500 __ push(Operand(eax, 0)); |
1485 __ sub(Operand(eax), Immediate(kPointerSize)); | 1501 __ sub(Operand(eax), Immediate(kPointerSize)); |
1486 __ cmp(ecx, Operand(ebx)); | 1502 __ cmp(edi, Operand(ebx)); |
1487 __ j(less, ©); | 1503 __ j(less, ©); |
1488 __ jmp(&invoke); | 1504 __ jmp(&invoke); |
1489 } | 1505 } |
1490 | 1506 |
1491 { // Too few parameters: Actual < expected. | 1507 { // Too few parameters: Actual < expected. |
1492 __ bind(&too_few); | 1508 __ bind(&too_few); |
1493 EnterArgumentsAdaptorFrame(masm); | 1509 EnterArgumentsAdaptorFrame(masm); |
1494 | 1510 |
1495 // Copy receiver and all actual arguments. | 1511 // Copy receiver and all actual arguments. |
1496 const int offset = StandardFrameConstants::kCallerSPOffset; | 1512 const int offset = StandardFrameConstants::kCallerSPOffset; |
1497 __ lea(edi, Operand(ebp, eax, times_4, offset)); | 1513 __ lea(edi, Operand(ebp, eax, times_4, offset)); |
1498 __ mov(ecx, -1); // account for receiver | 1514 // ebx = expected - actual. |
| 1515 __ sub(ebx, Operand(eax)); |
| 1516 // eax = -actual - 1 |
| 1517 __ neg(eax); |
| 1518 __ sub(Operand(eax), Immediate(1)); |
1499 | 1519 |
1500 Label copy; | 1520 Label copy; |
1501 __ bind(©); | 1521 __ bind(©); |
1502 __ inc(ecx); | 1522 __ inc(eax); |
1503 __ push(Operand(edi, 0)); | 1523 __ push(Operand(edi, 0)); |
1504 __ sub(Operand(edi), Immediate(kPointerSize)); | 1524 __ sub(Operand(edi), Immediate(kPointerSize)); |
1505 __ cmp(ecx, Operand(eax)); | 1525 __ test(eax, Operand(eax)); |
1506 __ j(less, ©); | 1526 __ j(not_zero, ©); |
1507 | 1527 |
1508 // Fill remaining expected arguments with undefined values. | 1528 // Fill remaining expected arguments with undefined values. |
1509 Label fill; | 1529 Label fill; |
1510 __ bind(&fill); | 1530 __ bind(&fill); |
1511 __ inc(ecx); | 1531 __ inc(eax); |
1512 __ push(Immediate(masm->isolate()->factory()->undefined_value())); | 1532 __ push(Immediate(masm->isolate()->factory()->undefined_value())); |
1513 __ cmp(ecx, Operand(ebx)); | 1533 __ cmp(eax, Operand(ebx)); |
1514 __ j(less, &fill); | 1534 __ j(less, &fill); |
1515 | |
1516 // Restore function pointer. | |
1517 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | |
1518 } | 1535 } |
1519 | 1536 |
1520 // Call the entry point. | 1537 // Call the entry point. |
1521 __ bind(&invoke); | 1538 __ bind(&invoke); |
| 1539 // Restore function pointer. |
| 1540 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1522 __ call(Operand(edx)); | 1541 __ call(Operand(edx)); |
1523 | 1542 |
1524 // Leave frame and return. | 1543 // Leave frame and return. |
1525 LeaveArgumentsAdaptorFrame(masm); | 1544 LeaveArgumentsAdaptorFrame(masm); |
1526 __ ret(0); | 1545 __ ret(0); |
1527 | 1546 |
1528 // ------------------------------------------- | 1547 // ------------------------------------------- |
1529 // Dont adapt arguments. | 1548 // Dont adapt arguments. |
1530 // ------------------------------------------- | 1549 // ------------------------------------------- |
1531 __ bind(&dont_adapt_arguments); | 1550 __ bind(&dont_adapt_arguments); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1598 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); | 1617 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |
1599 generator.Generate(); | 1618 generator.Generate(); |
1600 } | 1619 } |
1601 | 1620 |
1602 | 1621 |
1603 #undef __ | 1622 #undef __ |
1604 } | 1623 } |
1605 } // namespace v8::internal | 1624 } // namespace v8::internal |
1606 | 1625 |
1607 #endif // V8_TARGET_ARCH_IA32 | 1626 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |