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

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

Powered by Google App Engine
This is Rietveld 408576698