| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
| (...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 | 1757 |
| 1758 // Fill the marking stack with overflowed objects returned by the given | 1758 // Fill the marking stack with overflowed objects returned by the given |
| 1759 // iterator. Stop when the marking stack is filled or the end of the space | 1759 // iterator. Stop when the marking stack is filled or the end of the space |
| 1760 // is reached, whichever comes first. | 1760 // is reached, whichever comes first. |
| 1761 template <class T> | 1761 template <class T> |
| 1762 static void DiscoverGreyObjectsWithIterator(Heap* heap, | 1762 static void DiscoverGreyObjectsWithIterator(Heap* heap, |
| 1763 MarkingDeque* marking_deque, | 1763 MarkingDeque* marking_deque, |
| 1764 T* it) { | 1764 T* it) { |
| 1765 // The caller should ensure that the marking stack is initially not full, | 1765 // The caller should ensure that the marking stack is initially not full, |
| 1766 // so that we don't waste effort pointlessly scanning for objects. | 1766 // so that we don't waste effort pointlessly scanning for objects. |
| 1767 DCHECK(!marking_deque->IsFull()); | 1767 DCHECK(!marking_deque->overflowed()); |
| 1768 | 1768 |
| 1769 Map* filler_map = heap->one_pointer_filler_map(); | 1769 Map* filler_map = heap->one_pointer_filler_map(); |
| 1770 for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) { | 1770 for (HeapObject* object = it->Next(); object != NULL; object = it->Next()) { |
| 1771 MarkBit markbit = Marking::MarkBitFrom(object); | 1771 MarkBit markbit = Marking::MarkBitFrom(object); |
| 1772 if ((object->map() != filler_map) && Marking::IsGrey(markbit)) { | 1772 if ((object->map() != filler_map) && Marking::IsGrey(markbit)) { |
| 1773 Marking::GreyToBlack(markbit); | 1773 Marking::GreyToBlack(markbit); |
| 1774 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); | 1774 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); |
| 1775 marking_deque->PushBlack(object); | 1775 marking_deque->PushBlack(object); |
| 1776 if (marking_deque->IsFull()) return; | 1776 if (marking_deque->overflowed()) return; |
| 1777 } | 1777 } |
| 1778 } | 1778 } |
| 1779 } | 1779 } |
| 1780 | 1780 |
| 1781 | 1781 |
| 1782 static inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts); | 1782 static inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts); |
| 1783 | 1783 |
| 1784 | 1784 |
| 1785 static void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque, | 1785 static void DiscoverGreyObjectsOnPage(MarkingDeque* marking_deque, |
| 1786 MemoryChunk* p) { | 1786 MemoryChunk* p) { |
| 1787 DCHECK(!marking_deque->IsFull()); | 1787 DCHECK(!marking_deque->overflowed()); |
| 1788 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); | 1788 DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); |
| 1789 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); | 1789 DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0); |
| 1790 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); | 1790 DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0); |
| 1791 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); | 1791 DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); |
| 1792 | 1792 |
| 1793 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { | 1793 for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { |
| 1794 Address cell_base = it.CurrentCellBase(); | 1794 Address cell_base = it.CurrentCellBase(); |
| 1795 MarkBit::CellType* cell = it.CurrentCell(); | 1795 MarkBit::CellType* cell = it.CurrentCell(); |
| 1796 | 1796 |
| 1797 const MarkBit::CellType current_cell = *cell; | 1797 const MarkBit::CellType current_cell = *cell; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1811 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects); | 1811 int trailing_zeros = base::bits::CountTrailingZeros32(grey_objects); |
| 1812 grey_objects >>= trailing_zeros; | 1812 grey_objects >>= trailing_zeros; |
| 1813 offset += trailing_zeros; | 1813 offset += trailing_zeros; |
| 1814 MarkBit markbit(cell, 1 << offset, false); | 1814 MarkBit markbit(cell, 1 << offset, false); |
| 1815 DCHECK(Marking::IsGrey(markbit)); | 1815 DCHECK(Marking::IsGrey(markbit)); |
| 1816 Marking::GreyToBlack(markbit); | 1816 Marking::GreyToBlack(markbit); |
| 1817 Address addr = cell_base + offset * kPointerSize; | 1817 Address addr = cell_base + offset * kPointerSize; |
| 1818 HeapObject* object = HeapObject::FromAddress(addr); | 1818 HeapObject* object = HeapObject::FromAddress(addr); |
| 1819 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); | 1819 MemoryChunk::IncrementLiveBytesFromGC(object->address(), object->Size()); |
| 1820 marking_deque->PushBlack(object); | 1820 marking_deque->PushBlack(object); |
| 1821 if (marking_deque->IsFull()) return; | 1821 if (marking_deque->overflowed()) return; |
| 1822 offset += 2; | 1822 offset += 2; |
| 1823 grey_objects >>= 2; | 1823 grey_objects >>= 2; |
| 1824 } | 1824 } |
| 1825 | 1825 |
| 1826 grey_objects >>= (Bitmap::kBitsPerCell - 1); | 1826 grey_objects >>= (Bitmap::kBitsPerCell - 1); |
| 1827 } | 1827 } |
| 1828 } | 1828 } |
| 1829 | 1829 |
| 1830 | 1830 |
| 1831 int MarkCompactCollector::DiscoverAndEvacuateBlackObjectsOnPage( | 1831 int MarkCompactCollector::DiscoverAndEvacuateBlackObjectsOnPage( |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1889 return survivors_size; | 1889 return survivors_size; |
| 1890 } | 1890 } |
| 1891 | 1891 |
| 1892 | 1892 |
| 1893 static void DiscoverGreyObjectsInSpace(Heap* heap, MarkingDeque* marking_deque, | 1893 static void DiscoverGreyObjectsInSpace(Heap* heap, MarkingDeque* marking_deque, |
| 1894 PagedSpace* space) { | 1894 PagedSpace* space) { |
| 1895 PageIterator it(space); | 1895 PageIterator it(space); |
| 1896 while (it.has_next()) { | 1896 while (it.has_next()) { |
| 1897 Page* p = it.next(); | 1897 Page* p = it.next(); |
| 1898 DiscoverGreyObjectsOnPage(marking_deque, p); | 1898 DiscoverGreyObjectsOnPage(marking_deque, p); |
| 1899 if (marking_deque->IsFull()) return; | 1899 if (marking_deque->overflowed()) return; |
| 1900 } | 1900 } |
| 1901 } | 1901 } |
| 1902 | 1902 |
| 1903 | 1903 |
| 1904 static void DiscoverGreyObjectsInNewSpace(Heap* heap, | 1904 static void DiscoverGreyObjectsInNewSpace(Heap* heap, |
| 1905 MarkingDeque* marking_deque) { | 1905 MarkingDeque* marking_deque) { |
| 1906 NewSpace* space = heap->new_space(); | 1906 NewSpace* space = heap->new_space(); |
| 1907 NewSpacePageIterator it(space->bottom(), space->top()); | 1907 NewSpacePageIterator it(space->bottom(), space->top()); |
| 1908 while (it.has_next()) { | 1908 while (it.has_next()) { |
| 1909 NewSpacePage* page = it.next(); | 1909 NewSpacePage* page = it.next(); |
| 1910 DiscoverGreyObjectsOnPage(marking_deque, page); | 1910 DiscoverGreyObjectsOnPage(marking_deque, page); |
| 1911 if (marking_deque->IsFull()) return; | 1911 if (marking_deque->overflowed()) return; |
| 1912 } | 1912 } |
| 1913 } | 1913 } |
| 1914 | 1914 |
| 1915 | 1915 |
| 1916 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { | 1916 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { |
| 1917 Object* o = *p; | 1917 Object* o = *p; |
| 1918 if (!o->IsHeapObject()) return false; | 1918 if (!o->IsHeapObject()) return false; |
| 1919 HeapObject* heap_object = HeapObject::cast(o); | 1919 HeapObject* heap_object = HeapObject::cast(o); |
| 1920 MarkBit mark = Marking::MarkBitFrom(heap_object); | 1920 MarkBit mark = Marking::MarkBitFrom(heap_object); |
| 1921 return !mark.Get(); | 1921 return !mark.Get(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2027 | 2027 |
| 2028 // Sweep the heap for overflowed objects, clear their overflow bits, and | 2028 // Sweep the heap for overflowed objects, clear their overflow bits, and |
| 2029 // push them on the marking stack. Stop early if the marking stack fills | 2029 // push them on the marking stack. Stop early if the marking stack fills |
| 2030 // before sweeping completes. If sweeping completes, there are no remaining | 2030 // before sweeping completes. If sweeping completes, there are no remaining |
| 2031 // overflowed objects in the heap so the overflow flag on the markings stack | 2031 // overflowed objects in the heap so the overflow flag on the markings stack |
| 2032 // is cleared. | 2032 // is cleared. |
| 2033 void MarkCompactCollector::RefillMarkingDeque() { | 2033 void MarkCompactCollector::RefillMarkingDeque() { |
| 2034 DCHECK(marking_deque_.overflowed()); | 2034 DCHECK(marking_deque_.overflowed()); |
| 2035 | 2035 |
| 2036 DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_); | 2036 DiscoverGreyObjectsInNewSpace(heap(), &marking_deque_); |
| 2037 if (marking_deque_.IsFull()) return; | 2037 if (marking_deque_.overflowed()) return; |
| 2038 | 2038 |
| 2039 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, | 2039 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, |
| 2040 heap()->old_pointer_space()); | 2040 heap()->old_pointer_space()); |
| 2041 if (marking_deque_.IsFull()) return; | 2041 if (marking_deque_.overflowed()) return; |
| 2042 | 2042 |
| 2043 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_data_space()); | 2043 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->old_data_space()); |
| 2044 if (marking_deque_.IsFull()) return; | 2044 if (marking_deque_.overflowed()) return; |
| 2045 | 2045 |
| 2046 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); | 2046 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->code_space()); |
| 2047 if (marking_deque_.IsFull()) return; | 2047 if (marking_deque_.overflowed()) return; |
| 2048 | 2048 |
| 2049 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); | 2049 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->map_space()); |
| 2050 if (marking_deque_.IsFull()) return; | 2050 if (marking_deque_.overflowed()) return; |
| 2051 | 2051 |
| 2052 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); | 2052 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, heap()->cell_space()); |
| 2053 if (marking_deque_.IsFull()) return; | 2053 if (marking_deque_.overflowed()) return; |
| 2054 | 2054 |
| 2055 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, | 2055 DiscoverGreyObjectsInSpace(heap(), &marking_deque_, |
| 2056 heap()->property_cell_space()); | 2056 heap()->property_cell_space()); |
| 2057 if (marking_deque_.IsFull()) return; | 2057 if (marking_deque_.overflowed()) return; |
| 2058 | 2058 |
| 2059 LargeObjectIterator lo_it(heap()->lo_space()); | 2059 LargeObjectIterator lo_it(heap()->lo_space()); |
| 2060 DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it); | 2060 DiscoverGreyObjectsWithIterator(heap(), &marking_deque_, &lo_it); |
| 2061 if (marking_deque_.IsFull()) return; | 2061 if (marking_deque_.overflowed()) return; |
| 2062 | 2062 |
| 2063 marking_deque_.ClearOverflowed(); | 2063 marking_deque_.ClearOverflowed(); |
| 2064 } | 2064 } |
| 2065 | 2065 |
| 2066 | 2066 |
| 2067 // Mark all objects reachable (transitively) from objects on the marking | 2067 // Mark all objects reachable (transitively) from objects on the marking |
| 2068 // stack. Before: the marking stack contains zero or more heap object | 2068 // stack. Before: the marking stack contains zero or more heap object |
| 2069 // pointers. After: the marking stack is empty and there are no overflowed | 2069 // pointers. After: the marking stack is empty and there are no overflowed |
| 2070 // objects in the heap. | 2070 // objects in the heap. |
| 2071 void MarkCompactCollector::ProcessMarkingDeque() { | 2071 void MarkCompactCollector::ProcessMarkingDeque() { |
| (...skipping 2424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4496 SlotsBuffer* buffer = *buffer_address; | 4496 SlotsBuffer* buffer = *buffer_address; |
| 4497 while (buffer != NULL) { | 4497 while (buffer != NULL) { |
| 4498 SlotsBuffer* next_buffer = buffer->next(); | 4498 SlotsBuffer* next_buffer = buffer->next(); |
| 4499 DeallocateBuffer(buffer); | 4499 DeallocateBuffer(buffer); |
| 4500 buffer = next_buffer; | 4500 buffer = next_buffer; |
| 4501 } | 4501 } |
| 4502 *buffer_address = NULL; | 4502 *buffer_address = NULL; |
| 4503 } | 4503 } |
| 4504 } | 4504 } |
| 4505 } // namespace v8::internal | 4505 } // namespace v8::internal |
| OLD | NEW |