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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 __ pop(ebx); // Discard copy of return address. | 688 __ pop(ebx); // Discard copy of return address. |
676 __ dec(eax); // One fewer argument (first argument is new receiver). | 689 __ dec(eax); // One fewer argument (first argument is new receiver). |
677 } | 690 } |
678 | 691 |
679 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. | 692 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. |
680 { Label function; | 693 { Label function; |
681 __ test(edi, Operand(edi)); | 694 __ test(edi, Operand(edi)); |
682 __ j(not_zero, &function); | 695 __ j(not_zero, &function); |
683 __ Set(ebx, Immediate(0)); | 696 __ Set(ebx, Immediate(0)); |
684 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | 697 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
| 698 __ SetCallKind(ecx, CALL_AS_METHOD); |
685 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 699 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
686 RelocInfo::CODE_TARGET); | 700 RelocInfo::CODE_TARGET); |
687 __ bind(&function); | 701 __ bind(&function); |
688 } | 702 } |
689 | 703 |
690 // 5b. Get the code to call from the function and check that the number of | 704 // 5b. Get the code to call from the function and check that the number of |
691 // expected arguments matches what we're providing. If so, jump | 705 // expected arguments matches what we're providing. If so, jump |
692 // (tail-call) to the code in register edx without checking arguments. | 706 // (tail-call) to the code in register edx without checking arguments. |
693 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 707 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
694 __ mov(ebx, | 708 __ mov(ebx, |
695 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); | 709 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); |
696 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 710 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
697 __ SmiUntag(ebx); | 711 __ SmiUntag(ebx); |
| 712 __ SetCallKind(ecx, CALL_AS_METHOD); |
698 __ cmp(eax, Operand(ebx)); | 713 __ cmp(eax, Operand(ebx)); |
699 __ j(not_equal, | 714 __ j(not_equal, |
700 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); | 715 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); |
701 | 716 |
702 ParameterCount expected(0); | 717 ParameterCount expected(0); |
703 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION); | 718 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION); |
704 } | 719 } |
705 | 720 |
706 | 721 |
707 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 722 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1417 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 1432 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
1418 __ push(ebp); | 1433 __ push(ebp); |
1419 __ mov(ebp, Operand(esp)); | 1434 __ mov(ebp, Operand(esp)); |
1420 | 1435 |
1421 // Store the arguments adaptor context sentinel. | 1436 // Store the arguments adaptor context sentinel. |
1422 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 1437 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
1423 | 1438 |
1424 // Push the function on the stack. | 1439 // Push the function on the stack. |
1425 __ push(edi); | 1440 __ push(edi); |
1426 | 1441 |
1427 // Preserve the number of arguments on the stack. Must preserve both | 1442 // Preserve the number of arguments on the stack. Must preserve eax, |
1428 // eax and ebx because these registers are used when copying the | 1443 // ebx and ecx because these registers are used when copying the |
1429 // arguments and the receiver. | 1444 // arguments and the receiver. |
1430 ASSERT(kSmiTagSize == 1); | 1445 ASSERT(kSmiTagSize == 1); |
1431 __ lea(ecx, Operand(eax, eax, times_1, kSmiTag)); | 1446 __ lea(edi, Operand(eax, eax, times_1, kSmiTag)); |
1432 __ push(ecx); | 1447 __ push(edi); |
1433 } | 1448 } |
1434 | 1449 |
1435 | 1450 |
1436 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | 1451 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { |
1437 // Retrieve the number of arguments from the stack. | 1452 // Retrieve the number of arguments from the stack. |
1438 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1453 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1439 | 1454 |
1440 // Leave the frame. | 1455 // Leave the frame. |
1441 __ leave(); | 1456 __ leave(); |
1442 | 1457 |
1443 // Remove caller arguments from the stack. | 1458 // Remove caller arguments from the stack. |
1444 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 1459 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
1445 __ pop(ecx); | 1460 __ pop(ecx); |
1446 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 1461 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
1447 __ push(ecx); | 1462 __ push(ecx); |
1448 } | 1463 } |
1449 | 1464 |
1450 | 1465 |
1451 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1466 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1452 // ----------- S t a t e ------------- | 1467 // ----------- S t a t e ------------- |
1453 // -- eax : actual number of arguments | 1468 // -- eax : actual number of arguments |
1454 // -- ebx : expected number of arguments | 1469 // -- ebx : expected number of arguments |
| 1470 // -- ecx : call kind information |
1455 // -- edx : code entry to call | 1471 // -- edx : code entry to call |
1456 // ----------------------------------- | 1472 // ----------------------------------- |
1457 | 1473 |
1458 Label invoke, dont_adapt_arguments; | 1474 Label invoke, dont_adapt_arguments; |
1459 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); | 1475 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); |
1460 | 1476 |
1461 Label enough, too_few; | 1477 Label enough, too_few; |
1462 __ cmp(eax, Operand(ebx)); | 1478 __ cmp(eax, Operand(ebx)); |
1463 __ j(less, &too_few); | 1479 __ j(less, &too_few); |
1464 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); | 1480 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); |
1465 __ j(equal, &dont_adapt_arguments); | 1481 __ j(equal, &dont_adapt_arguments); |
1466 | 1482 |
1467 { // Enough parameters: Actual >= expected. | 1483 { // Enough parameters: Actual >= expected. |
1468 __ bind(&enough); | 1484 __ bind(&enough); |
1469 EnterArgumentsAdaptorFrame(masm); | 1485 EnterArgumentsAdaptorFrame(masm); |
1470 | 1486 |
1471 // Copy receiver and all expected arguments. | 1487 // Copy receiver and all expected arguments. |
1472 const int offset = StandardFrameConstants::kCallerSPOffset; | 1488 const int offset = StandardFrameConstants::kCallerSPOffset; |
1473 __ lea(eax, Operand(ebp, eax, times_4, offset)); | 1489 __ lea(eax, Operand(ebp, eax, times_4, offset)); |
1474 __ mov(ecx, -1); // account for receiver | 1490 __ mov(edi, -1); // account for receiver |
1475 | 1491 |
1476 Label copy; | 1492 Label copy; |
1477 __ bind(©); | 1493 __ bind(©); |
1478 __ inc(ecx); | 1494 __ inc(edi); |
1479 __ push(Operand(eax, 0)); | 1495 __ push(Operand(eax, 0)); |
1480 __ sub(Operand(eax), Immediate(kPointerSize)); | 1496 __ sub(Operand(eax), Immediate(kPointerSize)); |
1481 __ cmp(ecx, Operand(ebx)); | 1497 __ cmp(edi, Operand(ebx)); |
1482 __ j(less, ©); | 1498 __ j(less, ©); |
1483 __ jmp(&invoke); | 1499 __ jmp(&invoke); |
1484 } | 1500 } |
1485 | 1501 |
1486 { // Too few parameters: Actual < expected. | 1502 { // Too few parameters: Actual < expected. |
1487 __ bind(&too_few); | 1503 __ bind(&too_few); |
1488 EnterArgumentsAdaptorFrame(masm); | 1504 EnterArgumentsAdaptorFrame(masm); |
1489 | 1505 |
1490 // Copy receiver and all actual arguments. | 1506 // Copy receiver and all actual arguments. |
1491 const int offset = StandardFrameConstants::kCallerSPOffset; | 1507 const int offset = StandardFrameConstants::kCallerSPOffset; |
1492 __ lea(edi, Operand(ebp, eax, times_4, offset)); | 1508 __ lea(edi, Operand(ebp, eax, times_4, offset)); |
1493 __ mov(ecx, -1); // account for receiver | 1509 // ebx = expected - actual. |
| 1510 __ sub(ebx, Operand(eax)); |
| 1511 // eax = -actual - 1 |
| 1512 __ neg(eax); |
| 1513 __ sub(Operand(eax), Immediate(1)); |
1494 | 1514 |
1495 Label copy; | 1515 Label copy; |
1496 __ bind(©); | 1516 __ bind(©); |
1497 __ inc(ecx); | 1517 __ inc(eax); |
1498 __ push(Operand(edi, 0)); | 1518 __ push(Operand(edi, 0)); |
1499 __ sub(Operand(edi), Immediate(kPointerSize)); | 1519 __ sub(Operand(edi), Immediate(kPointerSize)); |
1500 __ cmp(ecx, Operand(eax)); | 1520 __ test(eax, Operand(eax)); |
1501 __ j(less, ©); | 1521 __ j(not_zero, ©); |
1502 | 1522 |
1503 // Fill remaining expected arguments with undefined values. | 1523 // Fill remaining expected arguments with undefined values. |
1504 Label fill; | 1524 Label fill; |
1505 __ bind(&fill); | 1525 __ bind(&fill); |
1506 __ inc(ecx); | 1526 __ inc(eax); |
1507 __ push(Immediate(masm->isolate()->factory()->undefined_value())); | 1527 __ push(Immediate(masm->isolate()->factory()->undefined_value())); |
1508 __ cmp(ecx, Operand(ebx)); | 1528 __ cmp(eax, Operand(ebx)); |
1509 __ j(less, &fill); | 1529 __ j(less, &fill); |
1510 | |
1511 // Restore function pointer. | |
1512 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | |
1513 } | 1530 } |
1514 | 1531 |
1515 // Call the entry point. | 1532 // Call the entry point. |
1516 __ bind(&invoke); | 1533 __ bind(&invoke); |
| 1534 // Restore function pointer. |
| 1535 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1517 __ call(Operand(edx)); | 1536 __ call(Operand(edx)); |
1518 | 1537 |
1519 // Leave frame and return. | 1538 // Leave frame and return. |
1520 LeaveArgumentsAdaptorFrame(masm); | 1539 LeaveArgumentsAdaptorFrame(masm); |
1521 __ ret(0); | 1540 __ ret(0); |
1522 | 1541 |
1523 // ------------------------------------------- | 1542 // ------------------------------------------- |
1524 // Dont adapt arguments. | 1543 // Dont adapt arguments. |
1525 // ------------------------------------------- | 1544 // ------------------------------------------- |
1526 __ bind(&dont_adapt_arguments); | 1545 __ bind(&dont_adapt_arguments); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1593 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); | 1612 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |
1594 generator.Generate(); | 1613 generator.Generate(); |
1595 } | 1614 } |
1596 | 1615 |
1597 | 1616 |
1598 #undef __ | 1617 #undef __ |
1599 } | 1618 } |
1600 } // namespace v8::internal | 1619 } // namespace v8::internal |
1601 | 1620 |
1602 #endif // V8_TARGET_ARCH_IA32 | 1621 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |