| 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 |