OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 15 matching lines...) Expand all Loading... |
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 #include "compilation-cache.h" | 30 #include "compilation-cache.h" |
31 #include "execution.h" | 31 #include "execution.h" |
32 #include "heap-profiler.h" | 32 #include "heap-profiler.h" |
33 #include "gdb-jit.h" | 33 #include "gdb-jit.h" |
34 #include "global-handles.h" | 34 #include "global-handles.h" |
35 #include "ic-inl.h" | 35 #include "ic-inl.h" |
| 36 #include "liveobjectlist-inl.h" |
36 #include "mark-compact.h" | 37 #include "mark-compact.h" |
37 #include "objects-visiting.h" | 38 #include "objects-visiting.h" |
38 #include "stub-cache.h" | 39 #include "stub-cache.h" |
39 | 40 |
40 namespace v8 { | 41 namespace v8 { |
41 namespace internal { | 42 namespace internal { |
42 | 43 |
43 // ------------------------------------------------------------------------- | 44 // ------------------------------------------------------------------------- |
44 // MarkCompactCollector | 45 // MarkCompactCollector |
45 | 46 |
(...skipping 1607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1653 EncodeFreeRegion(free_start, static_cast<int>(current - free_start)); | 1654 EncodeFreeRegion(free_start, static_cast<int>(current - free_start)); |
1654 is_prev_alive = true; | 1655 is_prev_alive = true; |
1655 } | 1656 } |
1656 } else { // Non-live object. | 1657 } else { // Non-live object. |
1657 object_size = object->Size(); | 1658 object_size = object->Size(); |
1658 ProcessNonLive(object); | 1659 ProcessNonLive(object); |
1659 if (is_prev_alive) { // Transition from live to non-live. | 1660 if (is_prev_alive) { // Transition from live to non-live. |
1660 free_start = current; | 1661 free_start = current; |
1661 is_prev_alive = false; | 1662 is_prev_alive = false; |
1662 } | 1663 } |
| 1664 LiveObjectList::ProcessNonLive(object); |
1663 } | 1665 } |
1664 } | 1666 } |
1665 | 1667 |
1666 // If we ended on a free region, mark it. | 1668 // If we ended on a free region, mark it. |
1667 if (!is_prev_alive) { | 1669 if (!is_prev_alive) { |
1668 EncodeFreeRegion(free_start, static_cast<int>(end - free_start)); | 1670 EncodeFreeRegion(free_start, static_cast<int>(end - free_start)); |
1669 } | 1671 } |
1670 } | 1672 } |
1671 | 1673 |
1672 | 1674 |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1873 | 1875 |
1874 // Promotion failed. Just migrate object to another semispace. | 1876 // Promotion failed. Just migrate object to another semispace. |
1875 // Allocation cannot fail at this point: semispaces are of equal size. | 1877 // Allocation cannot fail at this point: semispaces are of equal size. |
1876 Object* target = space->AllocateRaw(size)->ToObjectUnchecked(); | 1878 Object* target = space->AllocateRaw(size)->ToObjectUnchecked(); |
1877 | 1879 |
1878 MigrateObject(HeapObject::cast(target)->address(), | 1880 MigrateObject(HeapObject::cast(target)->address(), |
1879 current, | 1881 current, |
1880 size, | 1882 size, |
1881 false); | 1883 false); |
1882 } else { | 1884 } else { |
| 1885 // Process the dead object before we write a NULL into its header. |
| 1886 LiveObjectList::ProcessNonLive(object); |
| 1887 |
1883 size = object->Size(); | 1888 size = object->Size(); |
1884 Memory::Address_at(current) = NULL; | 1889 Memory::Address_at(current) = NULL; |
1885 } | 1890 } |
1886 } | 1891 } |
1887 | 1892 |
1888 // Second pass: find pointers to new space and update them. | 1893 // Second pass: find pointers to new space and update them. |
1889 PointersToNewGenUpdatingVisitor updating_visitor; | 1894 PointersToNewGenUpdatingVisitor updating_visitor; |
1890 | 1895 |
1891 // Update pointers in to space. | 1896 // Update pointers in to space. |
1892 Address current = space->bottom(); | 1897 Address current = space->bottom(); |
1893 while (current < space->top()) { | 1898 while (current < space->top()) { |
1894 HeapObject* object = HeapObject::FromAddress(current); | 1899 HeapObject* object = HeapObject::FromAddress(current); |
1895 current += | 1900 current += |
1896 StaticPointersToNewGenUpdatingVisitor::IterateBody(object->map(), | 1901 StaticPointersToNewGenUpdatingVisitor::IterateBody(object->map(), |
1897 object); | 1902 object); |
1898 } | 1903 } |
1899 | 1904 |
1900 // Update roots. | 1905 // Update roots. |
1901 Heap::IterateRoots(&updating_visitor, VISIT_ALL_IN_SCAVENGE); | 1906 Heap::IterateRoots(&updating_visitor, VISIT_ALL_IN_SCAVENGE); |
| 1907 LiveObjectList::IterateElements(&updating_visitor); |
1902 | 1908 |
1903 // Update pointers in old spaces. | 1909 // Update pointers in old spaces. |
1904 Heap::IterateDirtyRegions(Heap::old_pointer_space(), | 1910 Heap::IterateDirtyRegions(Heap::old_pointer_space(), |
1905 &Heap::IteratePointersInDirtyRegion, | 1911 &Heap::IteratePointersInDirtyRegion, |
1906 &UpdatePointerToNewGen, | 1912 &UpdatePointerToNewGen, |
1907 Heap::WATERMARK_SHOULD_BE_VALID); | 1913 Heap::WATERMARK_SHOULD_BE_VALID); |
1908 | 1914 |
1909 Heap::lo_space()->IterateDirtyRegions(&UpdatePointerToNewGen); | 1915 Heap::lo_space()->IterateDirtyRegions(&UpdatePointerToNewGen); |
1910 | 1916 |
1911 // Update pointers from cells. | 1917 // Update pointers from cells. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1979 static_cast<int>(current - free_start), | 1985 static_cast<int>(current - free_start), |
1980 true); | 1986 true); |
1981 is_previous_alive = true; | 1987 is_previous_alive = true; |
1982 } | 1988 } |
1983 } else { | 1989 } else { |
1984 MarkCompactCollector::ReportDeleteIfNeeded(object); | 1990 MarkCompactCollector::ReportDeleteIfNeeded(object); |
1985 if (is_previous_alive) { // Transition from live to free. | 1991 if (is_previous_alive) { // Transition from live to free. |
1986 free_start = current; | 1992 free_start = current; |
1987 is_previous_alive = false; | 1993 is_previous_alive = false; |
1988 } | 1994 } |
| 1995 LiveObjectList::ProcessNonLive(object); |
1989 } | 1996 } |
1990 // The object is now unmarked for the call to Size() at the top of the | 1997 // The object is now unmarked for the call to Size() at the top of the |
1991 // loop. | 1998 // loop. |
1992 } | 1999 } |
1993 | 2000 |
1994 bool page_is_empty = (p->ObjectAreaStart() == p->AllocationTop()) | 2001 bool page_is_empty = (p->ObjectAreaStart() == p->AllocationTop()) |
1995 || (!is_previous_alive && free_start == p->ObjectAreaStart()); | 2002 || (!is_previous_alive && free_start == p->ObjectAreaStart()); |
1996 | 2003 |
1997 if (page_is_empty) { | 2004 if (page_is_empty) { |
1998 // This page is empty. Check whether we are in the middle of | 2005 // This page is empty. Check whether we are in the middle of |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2157 } | 2164 } |
2158 | 2165 |
2159 #ifdef DEBUG | 2166 #ifdef DEBUG |
2160 CheckNoMapsToEvacuate(); | 2167 CheckNoMapsToEvacuate(); |
2161 #endif | 2168 #endif |
2162 } | 2169 } |
2163 | 2170 |
2164 void UpdateMapPointersInRoots() { | 2171 void UpdateMapPointersInRoots() { |
2165 Heap::IterateRoots(&map_updating_visitor_, VISIT_ONLY_STRONG); | 2172 Heap::IterateRoots(&map_updating_visitor_, VISIT_ONLY_STRONG); |
2166 GlobalHandles::IterateWeakRoots(&map_updating_visitor_); | 2173 GlobalHandles::IterateWeakRoots(&map_updating_visitor_); |
| 2174 LiveObjectList::IterateElements(&map_updating_visitor_); |
2167 } | 2175 } |
2168 | 2176 |
2169 void UpdateMapPointersInPagedSpace(PagedSpace* space) { | 2177 void UpdateMapPointersInPagedSpace(PagedSpace* space) { |
2170 ASSERT(space != Heap::map_space()); | 2178 ASSERT(space != Heap::map_space()); |
2171 | 2179 |
2172 PageIterator it(space, PageIterator::PAGES_IN_USE); | 2180 PageIterator it(space, PageIterator::PAGES_IN_USE); |
2173 while (it.has_next()) { | 2181 while (it.has_next()) { |
2174 Page* p = it.next(); | 2182 Page* p = it.next(); |
2175 UpdateMapPointersInRange(p->ObjectAreaStart(), p->AllocationTop()); | 2183 UpdateMapPointersInRange(p->ObjectAreaStart(), p->AllocationTop()); |
2176 } | 2184 } |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2526 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); | 2534 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); |
2527 state_ = UPDATE_POINTERS; | 2535 state_ = UPDATE_POINTERS; |
2528 #endif | 2536 #endif |
2529 UpdatingVisitor updating_visitor; | 2537 UpdatingVisitor updating_visitor; |
2530 Heap::IterateRoots(&updating_visitor, VISIT_ONLY_STRONG); | 2538 Heap::IterateRoots(&updating_visitor, VISIT_ONLY_STRONG); |
2531 GlobalHandles::IterateWeakRoots(&updating_visitor); | 2539 GlobalHandles::IterateWeakRoots(&updating_visitor); |
2532 | 2540 |
2533 // Update the pointer to the head of the weak list of global contexts. | 2541 // Update the pointer to the head of the weak list of global contexts. |
2534 updating_visitor.VisitPointer(&Heap::global_contexts_list_); | 2542 updating_visitor.VisitPointer(&Heap::global_contexts_list_); |
2535 | 2543 |
| 2544 LiveObjectList::IterateElements(&updating_visitor); |
| 2545 |
2536 int live_maps_size = IterateLiveObjects(Heap::map_space(), | 2546 int live_maps_size = IterateLiveObjects(Heap::map_space(), |
2537 &UpdatePointersInOldObject); | 2547 &UpdatePointersInOldObject); |
2538 int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(), | 2548 int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(), |
2539 &UpdatePointersInOldObject); | 2549 &UpdatePointersInOldObject); |
2540 int live_data_olds_size = IterateLiveObjects(Heap::old_data_space(), | 2550 int live_data_olds_size = IterateLiveObjects(Heap::old_data_space(), |
2541 &UpdatePointersInOldObject); | 2551 &UpdatePointersInOldObject); |
2542 int live_codes_size = IterateLiveObjects(Heap::code_space(), | 2552 int live_codes_size = IterateLiveObjects(Heap::code_space(), |
2543 &UpdatePointersInOldObject); | 2553 &UpdatePointersInOldObject); |
2544 int live_cells_size = IterateLiveObjects(Heap::cell_space(), | 2554 int live_cells_size = IterateLiveObjects(Heap::cell_space(), |
2545 &UpdatePointersInOldObject); | 2555 &UpdatePointersInOldObject); |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2935 } | 2945 } |
2936 | 2946 |
2937 | 2947 |
2938 void MarkCompactCollector::Initialize() { | 2948 void MarkCompactCollector::Initialize() { |
2939 StaticPointersToNewGenUpdatingVisitor::Initialize(); | 2949 StaticPointersToNewGenUpdatingVisitor::Initialize(); |
2940 StaticMarkingVisitor::Initialize(); | 2950 StaticMarkingVisitor::Initialize(); |
2941 } | 2951 } |
2942 | 2952 |
2943 | 2953 |
2944 } } // namespace v8::internal | 2954 } } // namespace v8::internal |
OLD | NEW |