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

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

Issue 6113004: Version 3.0.7 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
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 are not instances 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 1993
1893 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 1994 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
1894 Register arguments = ToRegister(instr->arguments()); 1995 Register arguments = ToRegister(instr->arguments());
1895 Register length = ToRegister(instr->length()); 1996 Register length = ToRegister(instr->length());
1896 Operand index = ToOperand(instr->index()); 1997 Operand index = ToOperand(instr->index());
1897 Register result = ToRegister(instr->result()); 1998 Register result = ToRegister(instr->result());
1898 1999
1899 __ sub(length, index); 2000 __ sub(length, index);
1900 DeoptimizeIf(below_equal, instr->environment()); 2001 DeoptimizeIf(below_equal, instr->environment());
1901 2002
2003 // There are two words between the frame pointer and the last argument.
2004 // Subtracting from length accounts for one of them add one more.
1902 __ mov(result, Operand(arguments, length, times_4, kPointerSize)); 2005 __ mov(result, Operand(arguments, length, times_4, kPointerSize));
1903 } 2006 }
1904 2007
1905 2008
1906 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2009 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
1907 Register elements = ToRegister(instr->elements()); 2010 Register elements = ToRegister(instr->elements());
1908 Register key = ToRegister(instr->key()); 2011 Register key = ToRegister(instr->key());
1909 Register result; 2012 Register result;
1910 if (instr->load_result() != NULL) { 2013 if (instr->load_result() != NULL) {
1911 result = ToRegister(instr->load_result()); 2014 result = ToRegister(instr->load_result());
(...skipping 29 matching lines...) Expand all
1941 2044
1942 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 2045 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1943 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2046 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1944 } 2047 }
1945 2048
1946 2049
1947 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 2050 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
1948 Register result = ToRegister(instr->result()); 2051 Register result = ToRegister(instr->result());
1949 2052
1950 // Check for arguments adapter frame. 2053 // Check for arguments adapter frame.
1951 Label done, adapted; 2054 NearLabel done, adapted;
1952 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2055 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
1953 __ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); 2056 __ mov(result, Operand(result, StandardFrameConstants::kContextOffset));
1954 __ cmp(Operand(result), 2057 __ cmp(Operand(result),
1955 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 2058 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1956 __ j(equal, &adapted); 2059 __ j(equal, &adapted);
1957 2060
1958 // No arguments adaptor frame. 2061 // No arguments adaptor frame.
1959 __ mov(result, Operand(ebp)); 2062 __ mov(result, Operand(ebp));
1960 __ jmp(&done); 2063 __ jmp(&done);
1961 2064
1962 // Arguments adaptor frame present. 2065 // Arguments adaptor frame present.
1963 __ bind(&adapted); 2066 __ bind(&adapted);
1964 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2067 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
1965 2068
1966 // Done. Pointer to topmost argument is in result. 2069 // Result is the frame pointer for the frame if not adapted and for the real
2070 // frame below the adaptor frame if adapted.
1967 __ bind(&done); 2071 __ bind(&done);
1968 } 2072 }
1969 2073
1970 2074
1971 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 2075 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
1972 Operand elem = ToOperand(instr->input()); 2076 Operand elem = ToOperand(instr->input());
1973 Register result = ToRegister(instr->result()); 2077 Register result = ToRegister(instr->result());
1974 2078
1975 Label done; 2079 NearLabel done;
1976 2080
1977 // No arguments adaptor frame. Number of arguments is fixed. 2081 // If no arguments adaptor frame the number of arguments is fixed.
1978 __ cmp(ebp, elem); 2082 __ cmp(ebp, elem);
1979 __ mov(result, Immediate(scope()->num_parameters())); 2083 __ mov(result, Immediate(scope()->num_parameters()));
1980 __ j(equal, &done); 2084 __ j(equal, &done);
1981 2085
1982 // Arguments adaptor frame present. Get argument length from there. 2086 // Arguments adaptor frame present. Get argument length from there.
1983 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 2087 __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
1984 __ mov(result, Operand(result, 2088 __ mov(result, Operand(result,
1985 ArgumentsAdaptorFrameConstants::kLengthOffset)); 2089 ArgumentsAdaptorFrameConstants::kLengthOffset));
1986 __ SmiUntag(result); 2090 __ SmiUntag(result);
1987 2091
1988 // Done. Argument length is in result register. 2092 // Argument length is in result register.
1989 __ bind(&done); 2093 __ bind(&done);
1990 } 2094 }
1991 2095
1992 2096
1993 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { 2097 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
1994 Register receiver = ToRegister(instr->receiver()); 2098 Register receiver = ToRegister(instr->receiver());
1995 ASSERT(ToRegister(instr->function()).is(edi)); 2099 ASSERT(ToRegister(instr->function()).is(edi));
1996 ASSERT(ToRegister(instr->result()).is(eax)); 2100 ASSERT(ToRegister(instr->result()).is(eax));
1997 2101
1998 // If the receiver is null or undefined, we have to pass the 2102 // If the receiver is null or undefined, we have to pass the
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
2527 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 2631 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
2528 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 2632 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
2529 int offset = 2633 int offset =
2530 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; 2634 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize;
2531 __ mov(FieldOperand(elements, offset), value); 2635 __ mov(FieldOperand(elements, offset), value);
2532 } else { 2636 } else {
2533 __ mov(FieldOperand(elements, key, times_4, FixedArray::kHeaderSize), 2637 __ mov(FieldOperand(elements, key, times_4, FixedArray::kHeaderSize),
2534 value); 2638 value);
2535 } 2639 }
2536 2640
2537 // Update the write barrier unless we're certain that we're storing a smi.
2538 if (instr->hydrogen()->NeedsWriteBarrier()) { 2641 if (instr->hydrogen()->NeedsWriteBarrier()) {
2539 // Compute address of modified element and store it into key register. 2642 // Compute address of modified element and store it into key register.
2540 __ lea(key, FieldOperand(elements, key, times_4, FixedArray::kHeaderSize)); 2643 __ lea(key, FieldOperand(elements, key, times_4, FixedArray::kHeaderSize));
2541 __ RecordWrite(elements, key, value); 2644 __ RecordWrite(elements, key, value);
2542 } 2645 }
2543 } 2646 }
2544 2647
2545 2648
2546 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 2649 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
2547 ASSERT(ToRegister(instr->object()).is(edx)); 2650 ASSERT(ToRegister(instr->object()).is(edx));
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
3300 ASSERT(!environment->HasBeenRegistered()); 3403 ASSERT(!environment->HasBeenRegistered());
3301 RegisterEnvironmentForDeoptimization(environment); 3404 RegisterEnvironmentForDeoptimization(environment);
3302 ASSERT(osr_pc_offset_ == -1); 3405 ASSERT(osr_pc_offset_ == -1);
3303 osr_pc_offset_ = masm()->pc_offset(); 3406 osr_pc_offset_ = masm()->pc_offset();
3304 } 3407 }
3305 3408
3306 3409
3307 #undef __ 3410 #undef __
3308 3411
3309 } } // namespace v8::internal 3412 } } // 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