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 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1525 | 1525 |
1526 MaybeObject* MacroAssembler::TryJumpToExternalReference( | 1526 MaybeObject* MacroAssembler::TryJumpToExternalReference( |
1527 const ExternalReference& ext) { | 1527 const ExternalReference& ext) { |
1528 // Set the entry point and jump to the C entry runtime stub. | 1528 // Set the entry point and jump to the C entry runtime stub. |
1529 mov(ebx, Immediate(ext)); | 1529 mov(ebx, Immediate(ext)); |
1530 CEntryStub ces(1); | 1530 CEntryStub ces(1); |
1531 return TryTailCallStub(&ces); | 1531 return TryTailCallStub(&ces); |
1532 } | 1532 } |
1533 | 1533 |
1534 | 1534 |
| 1535 void MacroAssembler::SetCallKind(Register dst, CallKind call_kind) { |
| 1536 // This macro takes the dst register to make the code more readable |
| 1537 // at the call sites. However, the dst register has to be ecx to |
| 1538 // follow the calling convention which requires the call type to be |
| 1539 // in ecx. |
| 1540 ASSERT(dst.is(ecx)); |
| 1541 if (call_kind == CALL_AS_FUNCTION) { |
| 1542 // Set to some non-zero smi by updating the least significant |
| 1543 // byte. |
| 1544 mov_b(Operand(dst), 1 << kSmiTagSize); |
| 1545 } else { |
| 1546 // Set to smi zero by clearing the register. |
| 1547 xor_(dst, Operand(dst)); |
| 1548 } |
| 1549 } |
| 1550 |
| 1551 |
1535 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 1552 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
1536 const ParameterCount& actual, | 1553 const ParameterCount& actual, |
1537 Handle<Code> code_constant, | 1554 Handle<Code> code_constant, |
1538 const Operand& code_operand, | 1555 const Operand& code_operand, |
1539 Label* done, | 1556 Label* done, |
1540 InvokeFlag flag, | 1557 InvokeFlag flag, |
1541 Label::Distance done_near, | 1558 Label::Distance done_near, |
1542 const CallWrapper& call_wrapper) { | 1559 const CallWrapper& call_wrapper, |
| 1560 CallKind call_kind) { |
1543 bool definitely_matches = false; | 1561 bool definitely_matches = false; |
1544 Label invoke; | 1562 Label invoke; |
1545 if (expected.is_immediate()) { | 1563 if (expected.is_immediate()) { |
1546 ASSERT(actual.is_immediate()); | 1564 ASSERT(actual.is_immediate()); |
1547 if (expected.immediate() == actual.immediate()) { | 1565 if (expected.immediate() == actual.immediate()) { |
1548 definitely_matches = true; | 1566 definitely_matches = true; |
1549 } else { | 1567 } else { |
1550 mov(eax, actual.immediate()); | 1568 mov(eax, actual.immediate()); |
1551 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 1569 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
1552 if (expected.immediate() == sentinel) { | 1570 if (expected.immediate() == sentinel) { |
(...skipping 30 matching lines...) Expand all Loading... |
1583 isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 1601 isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
1584 if (!code_constant.is_null()) { | 1602 if (!code_constant.is_null()) { |
1585 mov(edx, Immediate(code_constant)); | 1603 mov(edx, Immediate(code_constant)); |
1586 add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); | 1604 add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); |
1587 } else if (!code_operand.is_reg(edx)) { | 1605 } else if (!code_operand.is_reg(edx)) { |
1588 mov(edx, code_operand); | 1606 mov(edx, code_operand); |
1589 } | 1607 } |
1590 | 1608 |
1591 if (flag == CALL_FUNCTION) { | 1609 if (flag == CALL_FUNCTION) { |
1592 call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET)); | 1610 call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET)); |
| 1611 SetCallKind(ecx, call_kind); |
1593 call(adaptor, RelocInfo::CODE_TARGET); | 1612 call(adaptor, RelocInfo::CODE_TARGET); |
1594 call_wrapper.AfterCall(); | 1613 call_wrapper.AfterCall(); |
1595 jmp(done, done_near); | 1614 jmp(done, done_near); |
1596 } else { | 1615 } else { |
| 1616 SetCallKind(ecx, call_kind); |
1597 jmp(adaptor, RelocInfo::CODE_TARGET); | 1617 jmp(adaptor, RelocInfo::CODE_TARGET); |
1598 } | 1618 } |
1599 bind(&invoke); | 1619 bind(&invoke); |
1600 } | 1620 } |
1601 } | 1621 } |
1602 | 1622 |
1603 | 1623 |
1604 void MacroAssembler::InvokeCode(const Operand& code, | 1624 void MacroAssembler::InvokeCode(const Operand& code, |
1605 const ParameterCount& expected, | 1625 const ParameterCount& expected, |
1606 const ParameterCount& actual, | 1626 const ParameterCount& actual, |
1607 InvokeFlag flag, | 1627 InvokeFlag flag, |
1608 const CallWrapper& call_wrapper) { | 1628 const CallWrapper& call_wrapper, |
| 1629 CallKind call_kind) { |
1609 Label done; | 1630 Label done; |
1610 InvokePrologue(expected, actual, Handle<Code>::null(), code, | 1631 InvokePrologue(expected, actual, Handle<Code>::null(), code, |
1611 &done, flag, Label::kNear, call_wrapper); | 1632 &done, flag, Label::kNear, call_wrapper, |
| 1633 call_kind); |
1612 if (flag == CALL_FUNCTION) { | 1634 if (flag == CALL_FUNCTION) { |
1613 call_wrapper.BeforeCall(CallSize(code)); | 1635 call_wrapper.BeforeCall(CallSize(code)); |
| 1636 SetCallKind(ecx, call_kind); |
1614 call(code); | 1637 call(code); |
1615 call_wrapper.AfterCall(); | 1638 call_wrapper.AfterCall(); |
1616 } else { | 1639 } else { |
1617 ASSERT(flag == JUMP_FUNCTION); | 1640 ASSERT(flag == JUMP_FUNCTION); |
| 1641 SetCallKind(ecx, call_kind); |
1618 jmp(code); | 1642 jmp(code); |
1619 } | 1643 } |
1620 bind(&done); | 1644 bind(&done); |
1621 } | 1645 } |
1622 | 1646 |
1623 | 1647 |
1624 void MacroAssembler::InvokeCode(Handle<Code> code, | 1648 void MacroAssembler::InvokeCode(Handle<Code> code, |
1625 const ParameterCount& expected, | 1649 const ParameterCount& expected, |
1626 const ParameterCount& actual, | 1650 const ParameterCount& actual, |
1627 RelocInfo::Mode rmode, | 1651 RelocInfo::Mode rmode, |
1628 InvokeFlag flag, | 1652 InvokeFlag flag, |
1629 const CallWrapper& call_wrapper) { | 1653 const CallWrapper& call_wrapper, |
| 1654 CallKind call_kind) { |
1630 Label done; | 1655 Label done; |
1631 Operand dummy(eax); | 1656 Operand dummy(eax); |
1632 InvokePrologue(expected, actual, code, dummy, &done, flag, Label::kNear, | 1657 InvokePrologue(expected, actual, code, dummy, &done, flag, Label::kNear, |
1633 call_wrapper); | 1658 call_wrapper, call_kind); |
1634 if (flag == CALL_FUNCTION) { | 1659 if (flag == CALL_FUNCTION) { |
1635 call_wrapper.BeforeCall(CallSize(code, rmode)); | 1660 call_wrapper.BeforeCall(CallSize(code, rmode)); |
| 1661 SetCallKind(ecx, call_kind); |
1636 call(code, rmode); | 1662 call(code, rmode); |
1637 call_wrapper.AfterCall(); | 1663 call_wrapper.AfterCall(); |
1638 } else { | 1664 } else { |
1639 ASSERT(flag == JUMP_FUNCTION); | 1665 ASSERT(flag == JUMP_FUNCTION); |
| 1666 SetCallKind(ecx, call_kind); |
1640 jmp(code, rmode); | 1667 jmp(code, rmode); |
1641 } | 1668 } |
1642 bind(&done); | 1669 bind(&done); |
1643 } | 1670 } |
1644 | 1671 |
1645 | 1672 |
1646 void MacroAssembler::InvokeFunction(Register fun, | 1673 void MacroAssembler::InvokeFunction(Register fun, |
1647 const ParameterCount& actual, | 1674 const ParameterCount& actual, |
1648 InvokeFlag flag, | 1675 InvokeFlag flag, |
1649 const CallWrapper& call_wrapper) { | 1676 const CallWrapper& call_wrapper, |
| 1677 CallKind call_kind) { |
1650 ASSERT(fun.is(edi)); | 1678 ASSERT(fun.is(edi)); |
1651 mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 1679 mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
1652 mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 1680 mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
1653 mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); | 1681 mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); |
1654 SmiUntag(ebx); | 1682 SmiUntag(ebx); |
1655 | 1683 |
1656 ParameterCount expected(ebx); | 1684 ParameterCount expected(ebx); |
1657 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), | 1685 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), |
1658 expected, actual, flag, call_wrapper); | 1686 expected, actual, flag, call_wrapper, call_kind); |
1659 } | 1687 } |
1660 | 1688 |
1661 | 1689 |
1662 void MacroAssembler::InvokeFunction(JSFunction* function, | 1690 void MacroAssembler::InvokeFunction(JSFunction* function, |
1663 const ParameterCount& actual, | 1691 const ParameterCount& actual, |
1664 InvokeFlag flag, | 1692 InvokeFlag flag, |
1665 const CallWrapper& call_wrapper) { | 1693 const CallWrapper& call_wrapper) { |
1666 ASSERT(function->is_compiled()); | 1694 ASSERT(function->is_compiled()); |
1667 // Get the function and setup the context. | 1695 // Get the function and setup the context. |
1668 mov(edi, Immediate(Handle<JSFunction>(function))); | 1696 mov(edi, Immediate(Handle<JSFunction>(function))); |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2099 | 2127 |
2100 // Check that the code was patched as expected. | 2128 // Check that the code was patched as expected. |
2101 ASSERT(masm_.pc_ == address_ + size_); | 2129 ASSERT(masm_.pc_ == address_ + size_); |
2102 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2130 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
2103 } | 2131 } |
2104 | 2132 |
2105 | 2133 |
2106 } } // namespace v8::internal | 2134 } } // namespace v8::internal |
2107 | 2135 |
2108 #endif // V8_TARGET_ARCH_IA32 | 2136 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |