| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| 12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
| 15 // | 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #if defined(V8_TARGET_ARCH_ARM) |
| 31 |
| 30 #include "ic-inl.h" | 32 #include "ic-inl.h" |
| 31 #include "codegen-inl.h" | 33 #include "codegen-inl.h" |
| 32 #include "stub-cache.h" | 34 #include "stub-cache.h" |
| 33 | 35 |
| 34 namespace v8 { | 36 namespace v8 { |
| 35 namespace internal { | 37 namespace internal { |
| 36 | 38 |
| 37 #define __ ACCESS_MASM(masm) | 39 #define __ ACCESS_MASM(masm) |
| 38 | 40 |
| 39 | 41 |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 lookup->holder(), | 501 lookup->holder(), |
| 500 lookup->GetFieldIndex()); | 502 lookup->GetFieldIndex()); |
| 501 __ Ret(); | 503 __ Ret(); |
| 502 } else { | 504 } else { |
| 503 ASSERT(lookup->type() == CALLBACKS); | 505 ASSERT(lookup->type() == CALLBACKS); |
| 504 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); | 506 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); |
| 505 ASSERT(callback != NULL); | 507 ASSERT(callback != NULL); |
| 506 ASSERT(callback->getter() != NULL); | 508 ASSERT(callback->getter() != NULL); |
| 507 | 509 |
| 508 Label cleanup; | 510 Label cleanup; |
| 509 __ pop(scratch2); | 511 __ push(receiver); |
| 510 __ Push(receiver, scratch2); | |
| 511 | 512 |
| 512 holder = stub_compiler->CheckPrototypes(holder_obj, holder, | 513 holder = stub_compiler->CheckPrototypes(holder_obj, holder, |
| 513 lookup->holder(), scratch1, | 514 lookup->holder(), scratch1, |
| 514 scratch2, | 515 scratch2, |
| 515 name, | 516 name, |
| 516 &cleanup); | 517 &cleanup); |
| 517 | 518 |
| 518 __ push(holder); | 519 __ push(holder); |
| 519 __ Move(holder, Handle<AccessorInfo>(callback)); | 520 __ Move(holder, Handle<AccessorInfo>(callback)); |
| 520 __ push(holder); | 521 __ push(holder); |
| 521 __ ldr(scratch1, FieldMemOperand(holder, AccessorInfo::kDataOffset)); | 522 __ ldr(scratch1, FieldMemOperand(holder, AccessorInfo::kDataOffset)); |
| 522 __ Push(scratch1, name_); | 523 __ Push(scratch1, name_); |
| 523 | 524 |
| 524 ExternalReference ref = | 525 ExternalReference ref = |
| 525 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | 526 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); |
| 526 __ TailCallExternalReference(ref, 5, 1); | 527 __ TailCallExternalReference(ref, 5, 1); |
| 527 | 528 |
| 528 __ bind(&cleanup); | 529 __ bind(&cleanup); |
| 529 __ pop(scratch1); | |
| 530 __ pop(scratch2); | 530 __ pop(scratch2); |
| 531 __ push(scratch1); | |
| 532 } | 531 } |
| 533 } | 532 } |
| 534 | 533 |
| 535 | 534 |
| 536 void CompileRegular(MacroAssembler* masm, | 535 void CompileRegular(MacroAssembler* masm, |
| 537 Register receiver, | 536 Register receiver, |
| 538 Register holder, | 537 Register holder, |
| 539 Register scratch, | 538 Register scratch, |
| 540 JSObject* holder_obj, | 539 JSObject* holder_obj, |
| 541 Label* miss_label) { | 540 Label* miss_label) { |
| (...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1611 | 1610 |
| 1612 // Return the generated code. | 1611 // Return the generated code. |
| 1613 return GetCode(NORMAL, name); | 1612 return GetCode(NORMAL, name); |
| 1614 } | 1613 } |
| 1615 | 1614 |
| 1616 | 1615 |
| 1617 Object* LoadStubCompiler::CompileLoadNonexistent(String* name, | 1616 Object* LoadStubCompiler::CompileLoadNonexistent(String* name, |
| 1618 JSObject* object, | 1617 JSObject* object, |
| 1619 JSObject* last) { | 1618 JSObject* last) { |
| 1620 // ----------- S t a t e ------------- | 1619 // ----------- S t a t e ------------- |
| 1621 // -- r2 : name | 1620 // -- r0 : receiver |
| 1622 // -- lr : return address | 1621 // -- lr : return address |
| 1623 // -- [sp] : receiver | |
| 1624 // ----------------------------------- | 1622 // ----------------------------------- |
| 1625 Label miss; | 1623 Label miss; |
| 1626 | 1624 |
| 1627 // Load receiver. | |
| 1628 __ ldr(r0, MemOperand(sp, 0)); | |
| 1629 | |
| 1630 // Check that receiver is not a smi. | 1625 // Check that receiver is not a smi. |
| 1631 __ tst(r0, Operand(kSmiTagMask)); | 1626 __ tst(r0, Operand(kSmiTagMask)); |
| 1632 __ b(eq, &miss); | 1627 __ b(eq, &miss); |
| 1633 | 1628 |
| 1634 // Check the maps of the full prototype chain. | 1629 // Check the maps of the full prototype chain. |
| 1635 CheckPrototypes(object, r0, last, r3, r1, name, &miss); | 1630 CheckPrototypes(object, r0, last, r3, r1, name, &miss); |
| 1636 | 1631 |
| 1637 // If the last object in the prototype chain is a global object, | 1632 // If the last object in the prototype chain is a global object, |
| 1638 // check that the global property cell is empty. | 1633 // check that the global property cell is empty. |
| 1639 if (last->IsGlobalObject()) { | 1634 if (last->IsGlobalObject()) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1656 // Return the generated code. | 1651 // Return the generated code. |
| 1657 return GetCode(NONEXISTENT, Heap::empty_string()); | 1652 return GetCode(NONEXISTENT, Heap::empty_string()); |
| 1658 } | 1653 } |
| 1659 | 1654 |
| 1660 | 1655 |
| 1661 Object* LoadStubCompiler::CompileLoadField(JSObject* object, | 1656 Object* LoadStubCompiler::CompileLoadField(JSObject* object, |
| 1662 JSObject* holder, | 1657 JSObject* holder, |
| 1663 int index, | 1658 int index, |
| 1664 String* name) { | 1659 String* name) { |
| 1665 // ----------- S t a t e ------------- | 1660 // ----------- S t a t e ------------- |
| 1661 // -- r0 : receiver |
| 1666 // -- r2 : name | 1662 // -- r2 : name |
| 1667 // -- lr : return address | 1663 // -- lr : return address |
| 1668 // -- [sp] : receiver | |
| 1669 // ----------------------------------- | 1664 // ----------------------------------- |
| 1670 Label miss; | 1665 Label miss; |
| 1671 | 1666 |
| 1672 __ ldr(r0, MemOperand(sp, 0)); | |
| 1673 | |
| 1674 GenerateLoadField(object, holder, r0, r3, r1, index, name, &miss); | 1667 GenerateLoadField(object, holder, r0, r3, r1, index, name, &miss); |
| 1675 __ bind(&miss); | 1668 __ bind(&miss); |
| 1676 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1669 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 1677 | 1670 |
| 1678 // Return the generated code. | 1671 // Return the generated code. |
| 1679 return GetCode(FIELD, name); | 1672 return GetCode(FIELD, name); |
| 1680 } | 1673 } |
| 1681 | 1674 |
| 1682 | 1675 |
| 1683 Object* LoadStubCompiler::CompileLoadCallback(String* name, | 1676 Object* LoadStubCompiler::CompileLoadCallback(String* name, |
| 1684 JSObject* object, | 1677 JSObject* object, |
| 1685 JSObject* holder, | 1678 JSObject* holder, |
| 1686 AccessorInfo* callback) { | 1679 AccessorInfo* callback) { |
| 1687 // ----------- S t a t e ------------- | 1680 // ----------- S t a t e ------------- |
| 1681 // -- r0 : receiver |
| 1688 // -- r2 : name | 1682 // -- r2 : name |
| 1689 // -- lr : return address | 1683 // -- lr : return address |
| 1690 // -- [sp] : receiver | |
| 1691 // ----------------------------------- | 1684 // ----------------------------------- |
| 1692 Label miss; | 1685 Label miss; |
| 1693 | 1686 |
| 1694 __ ldr(r0, MemOperand(sp, 0)); | |
| 1695 Failure* failure = Failure::InternalError(); | 1687 Failure* failure = Failure::InternalError(); |
| 1696 bool success = GenerateLoadCallback(object, holder, r0, r2, r3, r1, | 1688 bool success = GenerateLoadCallback(object, holder, r0, r2, r3, r1, |
| 1697 callback, name, &miss, &failure); | 1689 callback, name, &miss, &failure); |
| 1698 if (!success) return failure; | 1690 if (!success) return failure; |
| 1699 | 1691 |
| 1700 __ bind(&miss); | 1692 __ bind(&miss); |
| 1701 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1693 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 1702 | 1694 |
| 1703 // Return the generated code. | 1695 // Return the generated code. |
| 1704 return GetCode(CALLBACKS, name); | 1696 return GetCode(CALLBACKS, name); |
| 1705 } | 1697 } |
| 1706 | 1698 |
| 1707 | 1699 |
| 1708 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 1700 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, |
| 1709 JSObject* holder, | 1701 JSObject* holder, |
| 1710 Object* value, | 1702 Object* value, |
| 1711 String* name) { | 1703 String* name) { |
| 1712 // ----------- S t a t e ------------- | 1704 // ----------- S t a t e ------------- |
| 1705 // -- r0 : receiver |
| 1713 // -- r2 : name | 1706 // -- r2 : name |
| 1714 // -- lr : return address | 1707 // -- lr : return address |
| 1715 // -- [sp] : receiver | |
| 1716 // ----------------------------------- | 1708 // ----------------------------------- |
| 1717 Label miss; | 1709 Label miss; |
| 1718 | 1710 |
| 1719 __ ldr(r0, MemOperand(sp, 0)); | |
| 1720 | |
| 1721 GenerateLoadConstant(object, holder, r0, r3, r1, value, name, &miss); | 1711 GenerateLoadConstant(object, holder, r0, r3, r1, value, name, &miss); |
| 1722 __ bind(&miss); | 1712 __ bind(&miss); |
| 1723 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1713 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 1724 | 1714 |
| 1725 // Return the generated code. | 1715 // Return the generated code. |
| 1726 return GetCode(CONSTANT_FUNCTION, name); | 1716 return GetCode(CONSTANT_FUNCTION, name); |
| 1727 } | 1717 } |
| 1728 | 1718 |
| 1729 | 1719 |
| 1730 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, | 1720 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, |
| 1731 JSObject* holder, | 1721 JSObject* holder, |
| 1732 String* name) { | 1722 String* name) { |
| 1733 // ----------- S t a t e ------------- | 1723 // ----------- S t a t e ------------- |
| 1724 // -- r0 : receiver |
| 1734 // -- r2 : name | 1725 // -- r2 : name |
| 1735 // -- lr : return address | 1726 // -- lr : return address |
| 1736 // -- [sp] : receiver | |
| 1737 // ----------------------------------- | 1727 // ----------------------------------- |
| 1738 Label miss; | 1728 Label miss; |
| 1739 | 1729 |
| 1740 __ ldr(r0, MemOperand(sp, 0)); | |
| 1741 | |
| 1742 LookupResult lookup; | 1730 LookupResult lookup; |
| 1743 LookupPostInterceptor(holder, name, &lookup); | 1731 LookupPostInterceptor(holder, name, &lookup); |
| 1744 GenerateLoadInterceptor(object, | 1732 GenerateLoadInterceptor(object, |
| 1745 holder, | 1733 holder, |
| 1746 &lookup, | 1734 &lookup, |
| 1747 r0, | 1735 r0, |
| 1748 r2, | 1736 r2, |
| 1749 r3, | 1737 r3, |
| 1750 r1, | 1738 r1, |
| 1751 name, | 1739 name, |
| 1752 &miss); | 1740 &miss); |
| 1753 __ bind(&miss); | 1741 __ bind(&miss); |
| 1754 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1742 GenerateLoadMiss(masm(), Code::LOAD_IC); |
| 1755 | 1743 |
| 1756 // Return the generated code. | 1744 // Return the generated code. |
| 1757 return GetCode(INTERCEPTOR, name); | 1745 return GetCode(INTERCEPTOR, name); |
| 1758 } | 1746 } |
| 1759 | 1747 |
| 1760 | 1748 |
| 1761 Object* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 1749 Object* LoadStubCompiler::CompileLoadGlobal(JSObject* object, |
| 1762 GlobalObject* holder, | 1750 GlobalObject* holder, |
| 1763 JSGlobalPropertyCell* cell, | 1751 JSGlobalPropertyCell* cell, |
| 1764 String* name, | 1752 String* name, |
| 1765 bool is_dont_delete) { | 1753 bool is_dont_delete) { |
| 1766 // ----------- S t a t e ------------- | 1754 // ----------- S t a t e ------------- |
| 1755 // -- r0 : receiver |
| 1767 // -- r2 : name | 1756 // -- r2 : name |
| 1768 // -- lr : return address | 1757 // -- lr : return address |
| 1769 // -- r0 : receiver | |
| 1770 // -- sp[0] : receiver | |
| 1771 // ----------------------------------- | 1758 // ----------------------------------- |
| 1772 Label miss; | 1759 Label miss; |
| 1773 | 1760 |
| 1774 // If the object is the holder then we know that it's a global | 1761 // If the object is the holder then we know that it's a global |
| 1775 // object which can only happen for contextual calls. In this case, | 1762 // object which can only happen for contextual calls. In this case, |
| 1776 // the receiver cannot be a smi. | 1763 // the receiver cannot be a smi. |
| 1777 if (object != holder) { | 1764 if (object != holder) { |
| 1778 __ tst(r0, Operand(kSmiTagMask)); | 1765 __ tst(r0, Operand(kSmiTagMask)); |
| 1779 __ b(eq, &miss); | 1766 __ b(eq, &miss); |
| 1780 } | 1767 } |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1967 return GetCode(CALLBACKS, name); | 1954 return GetCode(CALLBACKS, name); |
| 1968 } | 1955 } |
| 1969 | 1956 |
| 1970 | 1957 |
| 1971 Object* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 1958 Object* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
| 1972 int index, | 1959 int index, |
| 1973 Map* transition, | 1960 Map* transition, |
| 1974 String* name) { | 1961 String* name) { |
| 1975 // ----------- S t a t e ------------- | 1962 // ----------- S t a t e ------------- |
| 1976 // -- r0 : value | 1963 // -- r0 : value |
| 1977 // -- r2 : name | 1964 // -- r1 : key |
| 1965 // -- r2 : receiver |
| 1978 // -- lr : return address | 1966 // -- lr : return address |
| 1979 // -- [sp] : receiver | |
| 1980 // ----------------------------------- | 1967 // ----------------------------------- |
| 1981 Label miss; | 1968 Label miss; |
| 1982 | 1969 |
| 1983 __ IncrementCounter(&Counters::keyed_store_field, 1, r1, r3); | 1970 __ IncrementCounter(&Counters::keyed_store_field, 1, r3, r4); |
| 1984 | 1971 |
| 1985 // Check that the name has not changed. | 1972 // Check that the name has not changed. |
| 1986 __ cmp(r2, Operand(Handle<String>(name))); | 1973 __ cmp(r1, Operand(Handle<String>(name))); |
| 1987 __ b(ne, &miss); | 1974 __ b(ne, &miss); |
| 1988 | 1975 |
| 1989 // Load receiver from the stack. | 1976 // r3 is used as scratch register. r1 and r2 keep their values if a jump to |
| 1990 __ ldr(r3, MemOperand(sp)); | 1977 // the miss label is generated. |
| 1991 // r1 is used as scratch register, r3 and r2 might be clobbered. | |
| 1992 GenerateStoreField(masm(), | 1978 GenerateStoreField(masm(), |
| 1993 object, | 1979 object, |
| 1994 index, | 1980 index, |
| 1995 transition, | 1981 transition, |
| 1996 r3, r2, r1, | 1982 r2, r1, r3, |
| 1997 &miss); | 1983 &miss); |
| 1998 __ bind(&miss); | 1984 __ bind(&miss); |
| 1999 | 1985 |
| 2000 __ DecrementCounter(&Counters::keyed_store_field, 1, r1, r3); | 1986 __ DecrementCounter(&Counters::keyed_store_field, 1, r3, r4); |
| 2001 __ mov(r2, Operand(Handle<String>(name))); // restore name register. | |
| 2002 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 1987 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); |
| 1988 |
| 2003 __ Jump(ic, RelocInfo::CODE_TARGET); | 1989 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 2004 | 1990 |
| 2005 // Return the generated code. | 1991 // Return the generated code. |
| 2006 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 1992 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
| 2007 } | 1993 } |
| 2008 | 1994 |
| 2009 | 1995 |
| 2010 Object* ConstructStubCompiler::CompileConstructStub( | 1996 Object* ConstructStubCompiler::CompileConstructStub( |
| 2011 SharedFunctionInfo* shared) { | 1997 SharedFunctionInfo* shared) { |
| 2012 // ----------- S t a t e ------------- | 1998 // ----------- S t a t e ------------- |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2146 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 2132 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 2147 | 2133 |
| 2148 // Return the generated code. | 2134 // Return the generated code. |
| 2149 return GetCode(); | 2135 return GetCode(); |
| 2150 } | 2136 } |
| 2151 | 2137 |
| 2152 | 2138 |
| 2153 #undef __ | 2139 #undef __ |
| 2154 | 2140 |
| 2155 } } // namespace v8::internal | 2141 } } // namespace v8::internal |
| 2142 |
| 2143 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |