OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1547 tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask))); | 1547 tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask))); |
1548 b(ne, miss); | 1548 b(ne, miss); |
1549 | 1549 |
1550 // Get the value at the masked, scaled index and return. | 1550 // Get the value at the masked, scaled index and return. |
1551 const int kValueOffset = | 1551 const int kValueOffset = |
1552 SeededNumberDictionary::kElementsStartOffset + kPointerSize; | 1552 SeededNumberDictionary::kElementsStartOffset + kPointerSize; |
1553 ldr(result, FieldMemOperand(t2, kValueOffset)); | 1553 ldr(result, FieldMemOperand(t2, kValueOffset)); |
1554 } | 1554 } |
1555 | 1555 |
1556 | 1556 |
1557 void MacroAssembler::AllocateInNewSpace(int object_size, | 1557 ExternalReference MacroAssembler::GetTopAddress(AllocationTarget target) { |
1558 Register result, | 1558 if (target == NEW_SPACE) { |
1559 Register scratch1, | 1559 return ExternalReference::new_space_allocation_top_address(isolate()); |
1560 Register scratch2, | 1560 } else { |
1561 Label* gc_required, | 1561 return ExternalReference::old_pointer_space_allocation_top_address( |
1562 AllocationFlags flags) { | 1562 isolate()); |
| 1563 } |
| 1564 } |
| 1565 |
| 1566 |
| 1567 ExternalReference MacroAssembler::GetLimitAddress(AllocationTarget target) { |
| 1568 if (target == NEW_SPACE) { |
| 1569 return ExternalReference::new_space_allocation_limit_address(isolate()); |
| 1570 } else { |
| 1571 return ExternalReference::old_pointer_space_allocation_limit_address( |
| 1572 isolate()); |
| 1573 } |
| 1574 } |
| 1575 |
| 1576 |
| 1577 void MacroAssembler::Allocate(int object_size, |
| 1578 Register result, |
| 1579 Register scratch1, |
| 1580 Register scratch2, |
| 1581 Label* gc_required, |
| 1582 AllocationFlags flags, |
| 1583 AllocationTarget target) { |
1563 if (!FLAG_inline_new) { | 1584 if (!FLAG_inline_new) { |
1564 if (emit_debug_code()) { | 1585 if (emit_debug_code()) { |
1565 // Trash the registers to simulate an allocation failure. | 1586 // Trash the registers to simulate an allocation failure. |
1566 mov(result, Operand(0x7091)); | 1587 mov(result, Operand(0x7091)); |
1567 mov(scratch1, Operand(0x7191)); | 1588 mov(scratch1, Operand(0x7191)); |
1568 mov(scratch2, Operand(0x7291)); | 1589 mov(scratch2, Operand(0x7291)); |
1569 } | 1590 } |
1570 jmp(gc_required); | 1591 jmp(gc_required); |
1571 return; | 1592 return; |
1572 } | 1593 } |
1573 | 1594 |
1574 ASSERT(!result.is(scratch1)); | 1595 ASSERT(!result.is(scratch1)); |
1575 ASSERT(!result.is(scratch2)); | 1596 ASSERT(!result.is(scratch2)); |
1576 ASSERT(!scratch1.is(scratch2)); | 1597 ASSERT(!scratch1.is(scratch2)); |
1577 ASSERT(!scratch1.is(ip)); | 1598 ASSERT(!scratch1.is(ip)); |
1578 ASSERT(!scratch2.is(ip)); | 1599 ASSERT(!scratch2.is(ip)); |
1579 | 1600 |
1580 // Make object size into bytes. | 1601 // Make object size into bytes. |
1581 if ((flags & SIZE_IN_WORDS) != 0) { | 1602 if ((flags & SIZE_IN_WORDS) != 0) { |
1582 object_size *= kPointerSize; | 1603 object_size *= kPointerSize; |
1583 } | 1604 } |
1584 ASSERT_EQ(0, object_size & kObjectAlignmentMask); | 1605 ASSERT_EQ(0, object_size & kObjectAlignmentMask); |
1585 | 1606 |
1586 // Check relative positions of allocation top and limit addresses. | 1607 // Check relative positions of allocation top and limit addresses. |
1587 // The values must be adjacent in memory to allow the use of LDM. | 1608 // The values must be adjacent in memory to allow the use of LDM. |
1588 // Also, assert that the registers are numbered such that the values | 1609 // Also, assert that the registers are numbered such that the values |
1589 // are loaded in the correct order. | 1610 // are loaded in the correct order. |
1590 ExternalReference new_space_allocation_top = | 1611 ExternalReference allocation_top = GetTopAddress(target); |
1591 ExternalReference::new_space_allocation_top_address(isolate()); | 1612 ExternalReference allocation_limit = GetLimitAddress(target); |
1592 ExternalReference new_space_allocation_limit = | |
1593 ExternalReference::new_space_allocation_limit_address(isolate()); | |
1594 intptr_t top = | 1613 intptr_t top = |
1595 reinterpret_cast<intptr_t>(new_space_allocation_top.address()); | 1614 reinterpret_cast<intptr_t>(allocation_top.address()); |
1596 intptr_t limit = | 1615 intptr_t limit = |
1597 reinterpret_cast<intptr_t>(new_space_allocation_limit.address()); | 1616 reinterpret_cast<intptr_t>(allocation_limit.address()); |
1598 ASSERT((limit - top) == kPointerSize); | 1617 ASSERT((limit - top) == kPointerSize); |
1599 ASSERT(result.code() < ip.code()); | 1618 ASSERT(result.code() < ip.code()); |
1600 | 1619 |
1601 // Set up allocation top address and object size registers. | 1620 // Set up allocation top address and object size registers. |
1602 Register topaddr = scratch1; | 1621 Register topaddr = scratch1; |
1603 Register obj_size_reg = scratch2; | 1622 Register obj_size_reg = scratch2; |
1604 mov(topaddr, Operand(new_space_allocation_top)); | 1623 mov(topaddr, Operand(allocation_top)); |
1605 Operand obj_size_operand = Operand(object_size); | 1624 Operand obj_size_operand = Operand(object_size); |
1606 if (!obj_size_operand.is_single_instruction(this)) { | 1625 if (!obj_size_operand.is_single_instruction(this)) { |
1607 // We are about to steal IP, so we need to load this value first | 1626 // We are about to steal IP, so we need to load this value first |
1608 mov(obj_size_reg, obj_size_operand); | 1627 mov(obj_size_reg, obj_size_operand); |
1609 } | 1628 } |
1610 | 1629 |
1611 // This code stores a temporary value in ip. This is OK, as the code below | 1630 // This code stores a temporary value in ip. This is OK, as the code below |
1612 // does not need ip for implicit literal generation. | 1631 // does not need ip for implicit literal generation. |
1613 if ((flags & RESULT_CONTAINS_TOP) == 0) { | 1632 if ((flags & RESULT_CONTAINS_TOP) == 0) { |
1614 // Load allocation top into result and allocation limit into ip. | 1633 // Load allocation top into result and allocation limit into ip. |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1841 scratch1, | 1860 scratch1, |
1842 scratch2); | 1861 scratch2); |
1843 } | 1862 } |
1844 | 1863 |
1845 | 1864 |
1846 void MacroAssembler::AllocateTwoByteConsString(Register result, | 1865 void MacroAssembler::AllocateTwoByteConsString(Register result, |
1847 Register length, | 1866 Register length, |
1848 Register scratch1, | 1867 Register scratch1, |
1849 Register scratch2, | 1868 Register scratch2, |
1850 Label* gc_required) { | 1869 Label* gc_required) { |
1851 AllocateInNewSpace(ConsString::kSize, | 1870 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
1852 result, | 1871 TAG_OBJECT, NEW_SPACE); |
1853 scratch1, | |
1854 scratch2, | |
1855 gc_required, | |
1856 TAG_OBJECT); | |
1857 | 1872 |
1858 InitializeNewString(result, | 1873 InitializeNewString(result, |
1859 length, | 1874 length, |
1860 Heap::kConsStringMapRootIndex, | 1875 Heap::kConsStringMapRootIndex, |
1861 scratch1, | 1876 scratch1, |
1862 scratch2); | 1877 scratch2); |
1863 } | 1878 } |
1864 | 1879 |
1865 | 1880 |
1866 void MacroAssembler::AllocateAsciiConsString(Register result, | 1881 void MacroAssembler::AllocateAsciiConsString(Register result, |
1867 Register length, | 1882 Register length, |
1868 Register scratch1, | 1883 Register scratch1, |
1869 Register scratch2, | 1884 Register scratch2, |
1870 Label* gc_required) { | 1885 Label* gc_required) { |
1871 AllocateInNewSpace(ConsString::kSize, | 1886 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
1872 result, | 1887 TAG_OBJECT, NEW_SPACE); |
1873 scratch1, | |
1874 scratch2, | |
1875 gc_required, | |
1876 TAG_OBJECT); | |
1877 | 1888 |
1878 InitializeNewString(result, | 1889 InitializeNewString(result, |
1879 length, | 1890 length, |
1880 Heap::kConsAsciiStringMapRootIndex, | 1891 Heap::kConsAsciiStringMapRootIndex, |
1881 scratch1, | 1892 scratch1, |
1882 scratch2); | 1893 scratch2); |
1883 } | 1894 } |
1884 | 1895 |
1885 | 1896 |
1886 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | 1897 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
1887 Register length, | 1898 Register length, |
1888 Register scratch1, | 1899 Register scratch1, |
1889 Register scratch2, | 1900 Register scratch2, |
1890 Label* gc_required) { | 1901 Label* gc_required) { |
1891 AllocateInNewSpace(SlicedString::kSize, | 1902 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
1892 result, | 1903 TAG_OBJECT, NEW_SPACE); |
1893 scratch1, | |
1894 scratch2, | |
1895 gc_required, | |
1896 TAG_OBJECT); | |
1897 | 1904 |
1898 InitializeNewString(result, | 1905 InitializeNewString(result, |
1899 length, | 1906 length, |
1900 Heap::kSlicedStringMapRootIndex, | 1907 Heap::kSlicedStringMapRootIndex, |
1901 scratch1, | 1908 scratch1, |
1902 scratch2); | 1909 scratch2); |
1903 } | 1910 } |
1904 | 1911 |
1905 | 1912 |
1906 void MacroAssembler::AllocateAsciiSlicedString(Register result, | 1913 void MacroAssembler::AllocateAsciiSlicedString(Register result, |
1907 Register length, | 1914 Register length, |
1908 Register scratch1, | 1915 Register scratch1, |
1909 Register scratch2, | 1916 Register scratch2, |
1910 Label* gc_required) { | 1917 Label* gc_required) { |
1911 AllocateInNewSpace(SlicedString::kSize, | 1918 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
1912 result, | 1919 TAG_OBJECT, NEW_SPACE); |
1913 scratch1, | |
1914 scratch2, | |
1915 gc_required, | |
1916 TAG_OBJECT); | |
1917 | 1920 |
1918 InitializeNewString(result, | 1921 InitializeNewString(result, |
1919 length, | 1922 length, |
1920 Heap::kSlicedAsciiStringMapRootIndex, | 1923 Heap::kSlicedAsciiStringMapRootIndex, |
1921 scratch1, | 1924 scratch1, |
1922 scratch2); | 1925 scratch2); |
1923 } | 1926 } |
1924 | 1927 |
1925 | 1928 |
1926 void MacroAssembler::CompareObjectType(Register object, | 1929 void MacroAssembler::CompareObjectType(Register object, |
(...skipping 1318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3245 // Allocates a heap number or jumps to the need_gc label if the young space | 3248 // Allocates a heap number or jumps to the need_gc label if the young space |
3246 // is full and a scavenge is needed. | 3249 // is full and a scavenge is needed. |
3247 void MacroAssembler::AllocateHeapNumber(Register result, | 3250 void MacroAssembler::AllocateHeapNumber(Register result, |
3248 Register scratch1, | 3251 Register scratch1, |
3249 Register scratch2, | 3252 Register scratch2, |
3250 Register heap_number_map, | 3253 Register heap_number_map, |
3251 Label* gc_required, | 3254 Label* gc_required, |
3252 TaggingMode tagging_mode) { | 3255 TaggingMode tagging_mode) { |
3253 // Allocate an object in the heap for the heap number and tag it as a heap | 3256 // Allocate an object in the heap for the heap number and tag it as a heap |
3254 // object. | 3257 // object. |
3255 AllocateInNewSpace(HeapNumber::kSize, | 3258 Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, |
3256 result, | 3259 tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS, |
3257 scratch1, | 3260 NEW_SPACE); |
3258 scratch2, | |
3259 gc_required, | |
3260 tagging_mode == TAG_RESULT ? TAG_OBJECT : | |
3261 NO_ALLOCATION_FLAGS); | |
3262 | 3261 |
3263 // Store heap number map in the allocated object. | 3262 // Store heap number map in the allocated object. |
3264 AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); | 3263 AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
3265 if (tagging_mode == TAG_RESULT) { | 3264 if (tagging_mode == TAG_RESULT) { |
3266 str(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); | 3265 str(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); |
3267 } else { | 3266 } else { |
3268 str(heap_number_map, MemOperand(result, HeapObject::kMapOffset)); | 3267 str(heap_number_map, MemOperand(result, HeapObject::kMapOffset)); |
3269 } | 3268 } |
3270 } | 3269 } |
3271 | 3270 |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3990 void CodePatcher::EmitCondition(Condition cond) { | 3989 void CodePatcher::EmitCondition(Condition cond) { |
3991 Instr instr = Assembler::instr_at(masm_.pc_); | 3990 Instr instr = Assembler::instr_at(masm_.pc_); |
3992 instr = (instr & ~kCondMask) | cond; | 3991 instr = (instr & ~kCondMask) | cond; |
3993 masm_.emit(instr); | 3992 masm_.emit(instr); |
3994 } | 3993 } |
3995 | 3994 |
3996 | 3995 |
3997 } } // namespace v8::internal | 3996 } } // namespace v8::internal |
3998 | 3997 |
3999 #endif // V8_TARGET_ARCH_ARM | 3998 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |