OLD | NEW |
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 1565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 // in initial map. | 1576 // in initial map. |
1577 __ bind(&non_instance); | 1577 __ bind(&non_instance); |
1578 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); | 1578 __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); |
1579 | 1579 |
1580 // All done. | 1580 // All done. |
1581 __ bind(&done); | 1581 __ bind(&done); |
1582 } | 1582 } |
1583 | 1583 |
1584 | 1584 |
1585 void LCodeGen::DoLoadElements(LLoadElements* instr) { | 1585 void LCodeGen::DoLoadElements(LLoadElements* instr) { |
1586 Abort("DoLoadElements unimplemented."); | 1586 ASSERT(instr->result()->Equals(instr->input())); |
| 1587 Register reg = ToRegister(instr->input()); |
| 1588 Register scratch = scratch0(); |
| 1589 |
| 1590 __ ldr(reg, FieldMemOperand(reg, JSObject::kElementsOffset)); |
| 1591 if (FLAG_debug_code) { |
| 1592 Label done; |
| 1593 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1594 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); |
| 1595 __ cmp(scratch, ip); |
| 1596 __ b(eq, &done); |
| 1597 __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex); |
| 1598 __ cmp(scratch, ip); |
| 1599 __ Check(eq, "Check for fast elements failed."); |
| 1600 __ bind(&done); |
| 1601 } |
1587 } | 1602 } |
1588 | 1603 |
1589 | 1604 |
1590 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { | 1605 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |
1591 Register arguments = ToRegister(instr->arguments()); | 1606 Register arguments = ToRegister(instr->arguments()); |
1592 Register length = ToRegister(instr->length()); | 1607 Register length = ToRegister(instr->length()); |
1593 Register index = ToRegister(instr->index()); | 1608 Register index = ToRegister(instr->index()); |
1594 Register result = ToRegister(instr->result()); | 1609 Register result = ToRegister(instr->result()); |
1595 | 1610 |
1596 // Bailout index is not a valid argument index. Use unsigned check to get | 1611 // Bailout index is not a valid argument index. Use unsigned check to get |
1597 // negative check for free. | 1612 // negative check for free. |
1598 __ sub(length, length, index, SetCC); | 1613 __ sub(length, length, index, SetCC); |
1599 DeoptimizeIf(ls, instr->environment()); | 1614 DeoptimizeIf(ls, instr->environment()); |
1600 | 1615 |
1601 // There are two words between the frame pointer and the last argument. | 1616 // There are two words between the frame pointer and the last argument. |
1602 // Subtracting from length accounts for one of them add one more. | 1617 // Subtracting from length accounts for one of them add one more. |
1603 __ add(length, length, Operand(1)); | 1618 __ add(length, length, Operand(1)); |
1604 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); | 1619 __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2)); |
1605 } | 1620 } |
1606 | 1621 |
1607 | 1622 |
1608 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { | 1623 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
1609 Abort("DoLoadKeyedFastElement unimplemented."); | 1624 Register elements = ToRegister(instr->elements()); |
| 1625 Register key = EmitLoadRegister(instr->key(), scratch0()); |
| 1626 Register result; |
| 1627 Register scratch = scratch0(); |
| 1628 |
| 1629 if (instr->load_result() != NULL) { |
| 1630 result = ToRegister(instr->load_result()); |
| 1631 } else { |
| 1632 result = ToRegister(instr->result()); |
| 1633 ASSERT(result.is(elements)); |
| 1634 } |
| 1635 |
| 1636 // Load the result. |
| 1637 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
| 1638 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
| 1639 |
| 1640 Representation r = instr->hydrogen()->representation(); |
| 1641 if (r.IsInteger32()) { |
| 1642 // Untag and check for smi. |
| 1643 __ SmiUntag(result); |
| 1644 DeoptimizeIf(cs, instr->environment()); |
| 1645 } else if (r.IsDouble()) { |
| 1646 EmitNumberUntagD(result, |
| 1647 ToDoubleRegister(instr->result()), |
| 1648 instr->environment()); |
| 1649 } else { |
| 1650 // Check for the hole value. |
| 1651 ASSERT(r.IsTagged()); |
| 1652 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
| 1653 __ cmp(result, scratch); |
| 1654 DeoptimizeIf(eq, instr->environment()); |
| 1655 } |
1610 } | 1656 } |
1611 | 1657 |
1612 | 1658 |
1613 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 1659 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
1614 ASSERT(ToRegister(instr->object()).is(r1)); | 1660 ASSERT(ToRegister(instr->object()).is(r1)); |
1615 ASSERT(ToRegister(instr->key()).is(r0)); | 1661 ASSERT(ToRegister(instr->key()).is(r0)); |
1616 | 1662 |
1617 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1663 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1618 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 1664 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
1619 } | 1665 } |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1814 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); | 1860 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); |
1815 } | 1861 } |
1816 | 1862 |
1817 | 1863 |
1818 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 1864 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
1819 CallRuntime(instr->function(), instr->arity(), instr); | 1865 CallRuntime(instr->function(), instr->arity(), instr); |
1820 } | 1866 } |
1821 | 1867 |
1822 | 1868 |
1823 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 1869 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
1824 Abort("DoStoreNamedField unimplemented."); | 1870 Register object = ToRegister(instr->object()); |
| 1871 Register value = ToRegister(instr->value()); |
| 1872 Register scratch = scratch0(); |
| 1873 int offset = instr->offset(); |
| 1874 |
| 1875 ASSERT(!object.is(value)); |
| 1876 |
| 1877 if (!instr->transition().is_null()) { |
| 1878 __ mov(scratch, Operand(instr->transition())); |
| 1879 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
| 1880 } |
| 1881 |
| 1882 // Do the store. |
| 1883 if (instr->is_in_object()) { |
| 1884 __ str(value, FieldMemOperand(object, offset)); |
| 1885 if (instr->needs_write_barrier()) { |
| 1886 // Update the write barrier for the object for in-object properties. |
| 1887 __ RecordWrite(object, Operand(offset), value, scratch); |
| 1888 } |
| 1889 } else { |
| 1890 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 1891 __ str(value, FieldMemOperand(scratch, offset)); |
| 1892 if (instr->needs_write_barrier()) { |
| 1893 // Update the write barrier for the properties array. |
| 1894 // object is used as a scratch register. |
| 1895 __ RecordWrite(scratch, Operand(offset), value, object); |
| 1896 } |
| 1897 } |
1825 } | 1898 } |
1826 | 1899 |
1827 | 1900 |
1828 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 1901 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
1829 ASSERT(ToRegister(instr->object()).is(r1)); | 1902 ASSERT(ToRegister(instr->object()).is(r1)); |
1830 ASSERT(ToRegister(instr->value()).is(r0)); | 1903 ASSERT(ToRegister(instr->value()).is(r0)); |
1831 | 1904 |
1832 // Name is always in r2. | 1905 // Name is always in r2. |
1833 __ mov(r2, Operand(instr->name())); | 1906 __ mov(r2, Operand(instr->name())); |
1834 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1907 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1835 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 1908 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
1836 } | 1909 } |
1837 | 1910 |
1838 | 1911 |
1839 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 1912 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
1840 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); | 1913 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); |
1841 DeoptimizeIf(hs, instr->environment()); | 1914 DeoptimizeIf(hs, instr->environment()); |
1842 } | 1915 } |
1843 | 1916 |
1844 | 1917 |
1845 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { | 1918 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { |
1846 Abort("DoStoreKeyedFastElement unimplemented."); | 1919 Register value = ToRegister(instr->value()); |
| 1920 Register elements = ToRegister(instr->object()); |
| 1921 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
| 1922 Register scratch = scratch0(); |
| 1923 |
| 1924 // Do the store. |
| 1925 if (instr->key()->IsConstantOperand()) { |
| 1926 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
| 1927 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
| 1928 int offset = |
| 1929 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; |
| 1930 __ str(value, FieldMemOperand(elements, offset)); |
| 1931 } else { |
| 1932 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
| 1933 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
| 1934 } |
| 1935 |
| 1936 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 1937 // Compute address of modified element and store it into key register. |
| 1938 __ add(key, scratch, Operand(FixedArray::kHeaderSize)); |
| 1939 __ RecordWrite(elements, key, value); |
| 1940 } |
1847 } | 1941 } |
1848 | 1942 |
1849 | 1943 |
1850 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 1944 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
1851 ASSERT(ToRegister(instr->object()).is(r2)); | 1945 ASSERT(ToRegister(instr->object()).is(r2)); |
1852 ASSERT(ToRegister(instr->key()).is(r1)); | 1946 ASSERT(ToRegister(instr->key()).is(r1)); |
1853 ASSERT(ToRegister(instr->value()).is(r0)); | 1947 ASSERT(ToRegister(instr->value()).is(r0)); |
1854 | 1948 |
1855 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1949 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
1856 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 1950 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2478 | 2572 |
2479 | 2573 |
2480 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 2574 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
2481 Abort("DoOsrEntry unimplemented."); | 2575 Abort("DoOsrEntry unimplemented."); |
2482 } | 2576 } |
2483 | 2577 |
2484 | 2578 |
2485 #undef __ | 2579 #undef __ |
2486 | 2580 |
2487 } } // namespace v8::internal | 2581 } } // namespace v8::internal |
OLD | NEW |