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 |