Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 5990005: Optimize instanceof further... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698