OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1687 Register reg = ToRegister(instr->input()); | 1687 Register reg = ToRegister(instr->input()); |
1688 int true_block = instr->true_block_id(); | 1688 int true_block = instr->true_block_id(); |
1689 int false_block = instr->false_block_id(); | 1689 int false_block = instr->false_block_id(); |
1690 | 1690 |
1691 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); | 1691 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); |
1692 EmitBranch(true_block, false_block, equal); | 1692 EmitBranch(true_block, false_block, equal); |
1693 } | 1693 } |
1694 | 1694 |
1695 | 1695 |
1696 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 1696 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { |
1697 // Object and function are in fixed registers eax and edx. | 1697 // Object and function are in fixed registers defined by the stub. |
1698 InstanceofStub stub(InstanceofStub::kArgsInRegisters); | 1698 InstanceofStub stub(InstanceofStub::kArgsInRegisters); |
1699 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 1699 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1700 | 1700 |
1701 NearLabel true_value, done; | 1701 NearLabel true_value, done; |
1702 __ test(eax, Operand(eax)); | 1702 __ test(eax, Operand(eax)); |
1703 __ j(zero, &true_value); | 1703 __ j(zero, &true_value); |
1704 __ mov(ToRegister(instr->result()), Factory::false_value()); | 1704 __ mov(ToRegister(instr->result()), Factory::false_value()); |
1705 __ jmp(&done); | 1705 __ jmp(&done); |
1706 __ bind(&true_value); | 1706 __ bind(&true_value); |
1707 __ mov(ToRegister(instr->result()), Factory::true_value()); | 1707 __ mov(ToRegister(instr->result()), Factory::true_value()); |
1708 __ bind(&done); | 1708 __ bind(&done); |
1709 } | 1709 } |
1710 | 1710 |
1711 | 1711 |
1712 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { | 1712 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { |
1713 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1713 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
1714 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1714 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
1715 | 1715 |
1716 InstanceofStub stub(InstanceofStub::kArgsInRegisters); | 1716 InstanceofStub stub(InstanceofStub::kArgsInRegisters); |
1717 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 1717 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1718 __ test(eax, Operand(eax)); | 1718 __ test(eax, Operand(eax)); |
1719 EmitBranch(true_block, false_block, zero); | 1719 EmitBranch(true_block, false_block, zero); |
1720 } | 1720 } |
1721 | 1721 |
1722 | 1722 |
| 1723 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { |
| 1724 class DeferredInstanceOfKnownGlobal: public LDeferredCode { |
| 1725 public: |
| 1726 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, |
| 1727 LInstanceOfKnownGlobal* instr) |
| 1728 : LDeferredCode(codegen), instr_(instr) { } |
| 1729 virtual void Generate() { |
| 1730 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_); |
| 1731 } |
| 1732 |
| 1733 Label* map_check() { return &map_check_; } |
| 1734 |
| 1735 private: |
| 1736 LInstanceOfKnownGlobal* instr_; |
| 1737 Label map_check_; |
| 1738 }; |
| 1739 |
| 1740 DeferredInstanceOfKnownGlobal* deferred; |
| 1741 deferred = new DeferredInstanceOfKnownGlobal(this, instr); |
| 1742 |
| 1743 Label done, false_result; |
| 1744 Register object = ToRegister(instr->input()); |
| 1745 Register temp = ToRegister(instr->temp()); |
| 1746 |
| 1747 // A Smi is not instance of anything. |
| 1748 __ test(object, Immediate(kSmiTagMask)); |
| 1749 __ j(zero, &false_result, not_taken); |
| 1750 |
| 1751 // This is the inlined call site instanceof cache. The two occourences of the |
| 1752 // hole value will be patched to the last map/result pair generated by the |
| 1753 // instanceof stub. |
| 1754 NearLabel cache_miss; |
| 1755 Register map = ToRegister(instr->temp()); |
| 1756 __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); |
| 1757 __ bind(deferred->map_check()); // Label for calculating code patching. |
| 1758 __ cmp(map, Factory::the_hole_value()); // Patched to cached map. |
| 1759 __ j(not_equal, &cache_miss, not_taken); |
| 1760 __ mov(eax, Factory::the_hole_value()); // Patched to either true or false. |
| 1761 __ jmp(&done); |
| 1762 |
| 1763 // The inlined call site cache did not match. Check null and string before |
| 1764 // calling the deferred code. |
| 1765 __ bind(&cache_miss); |
| 1766 // Null is not instance of anything. |
| 1767 __ cmp(object, Factory::null_value()); |
| 1768 __ j(equal, &false_result); |
| 1769 |
| 1770 // String values is not instance of anything. |
| 1771 Condition is_string = masm_->IsObjectStringType(object, temp, temp); |
| 1772 __ j(is_string, &false_result); |
| 1773 |
| 1774 // Go to the deferred code. |
| 1775 __ jmp(deferred->entry()); |
| 1776 |
| 1777 __ bind(&false_result); |
| 1778 __ mov(ToRegister(instr->result()), Factory::false_value()); |
| 1779 |
| 1780 // Here result has either true or false. Deferred code also produces true or |
| 1781 // false object. |
| 1782 __ bind(deferred->exit()); |
| 1783 __ bind(&done); |
| 1784 } |
| 1785 |
| 1786 |
| 1787 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, |
| 1788 Label* map_check) { |
| 1789 __ PushSafepointRegisters(); |
| 1790 |
| 1791 InstanceofStub::Flags flags = InstanceofStub::kNoFlags; |
| 1792 flags = static_cast<InstanceofStub::Flags>( |
| 1793 flags | InstanceofStub::kArgsInRegisters); |
| 1794 flags = static_cast<InstanceofStub::Flags>( |
| 1795 flags | InstanceofStub::kCallSiteInlineCheck); |
| 1796 flags = static_cast<InstanceofStub::Flags>( |
| 1797 flags | InstanceofStub::kReturnTrueFalseObject); |
| 1798 InstanceofStub stub(flags); |
| 1799 |
| 1800 // Get the temp register reserved by the instruction. This needs to be edi as |
| 1801 // its slot of the pushing of safepoint registers is used to communicate the |
| 1802 // offset to the location of the map check. |
| 1803 Register temp = ToRegister(instr->temp()); |
| 1804 ASSERT(temp.is(edi)); |
| 1805 __ mov(InstanceofStub::right(), Immediate(instr->function())); |
| 1806 static const int kAdditionalDelta = 13; |
| 1807 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; |
| 1808 Label before_push_delta; |
| 1809 __ bind(&before_push_delta); |
| 1810 __ mov(temp, Immediate(delta)); |
| 1811 __ mov(Operand(esp, EspIndexForPushAll(temp) * kPointerSize), temp); |
| 1812 __ call(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 1813 ASSERT_EQ(kAdditionalDelta, |
| 1814 masm_->SizeOfCodeGeneratedSince(&before_push_delta)); |
| 1815 RecordSafepointWithRegisters( |
| 1816 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); |
| 1817 // Put the result value into the eax slot and restore all registers. |
| 1818 __ mov(Operand(esp, EspIndexForPushAll(eax) * kPointerSize), eax); |
| 1819 |
| 1820 __ PopSafepointRegisters(); |
| 1821 } |
| 1822 |
| 1823 |
1723 static Condition ComputeCompareCondition(Token::Value op) { | 1824 static Condition ComputeCompareCondition(Token::Value op) { |
1724 switch (op) { | 1825 switch (op) { |
1725 case Token::EQ_STRICT: | 1826 case Token::EQ_STRICT: |
1726 case Token::EQ: | 1827 case Token::EQ: |
1727 return equal; | 1828 return equal; |
1728 case Token::LT: | 1829 case Token::LT: |
1729 return less; | 1830 return less; |
1730 case Token::GT: | 1831 case Token::GT: |
1731 return greater; | 1832 return greater; |
1732 case Token::LTE: | 1833 case Token::LTE: |
(...skipping 1567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3300 ASSERT(!environment->HasBeenRegistered()); | 3401 ASSERT(!environment->HasBeenRegistered()); |
3301 RegisterEnvironmentForDeoptimization(environment); | 3402 RegisterEnvironmentForDeoptimization(environment); |
3302 ASSERT(osr_pc_offset_ == -1); | 3403 ASSERT(osr_pc_offset_ == -1); |
3303 osr_pc_offset_ = masm()->pc_offset(); | 3404 osr_pc_offset_ = masm()->pc_offset(); |
3304 } | 3405 } |
3305 | 3406 |
3306 | 3407 |
3307 #undef __ | 3408 #undef __ |
3308 | 3409 |
3309 } } // namespace v8::internal | 3410 } } // namespace v8::internal |
OLD | NEW |