OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/full-codegen/full-codegen.h" | 9 #include "src/full-codegen/full-codegen.h" |
10 #include "src/heap/mark-compact.h" | 10 #include "src/heap/mark-compact.h" |
11 #include "src/macro-assembler.h" | 11 #include "src/macro-assembler.h" |
12 #include "src/msan.h" | 12 #include "src/msan.h" |
13 #include "src/snapshot/snapshot.h" | 13 #include "src/snapshot/snapshot.h" |
14 | 14 |
15 namespace v8 { | 15 namespace v8 { |
16 namespace internal { | 16 namespace internal { |
17 | 17 |
18 | 18 |
19 // ---------------------------------------------------------------------------- | 19 // ---------------------------------------------------------------------------- |
20 // HeapObjectIterator | 20 // HeapObjectIterator |
21 | 21 |
22 HeapObjectIterator::HeapObjectIterator(PagedSpace* space) { | 22 HeapObjectIterator::HeapObjectIterator(PagedSpace* space) { |
23 // You can't actually iterate over the anchor page. It is not a real page, | 23 // You can't actually iterate over the anchor page. It is not a real page, |
24 // just an anchor for the double linked page list. Initialize as if we have | 24 // just an anchor for the double linked page list. Initialize as if we have |
25 // reached the end of the anchor page, then the first iteration will move on | 25 // reached the end of the anchor page, then the first iteration will move on |
26 // to the first page. | 26 // to the first page. |
27 Initialize(space, NULL, NULL, kAllPagesInSpace, NULL); | 27 Initialize(space, NULL, NULL, kAllPagesInSpace); |
28 } | 28 } |
29 | 29 |
30 | 30 |
31 HeapObjectIterator::HeapObjectIterator(PagedSpace* space, | 31 HeapObjectIterator::HeapObjectIterator(Page* page) { |
32 HeapObjectCallback size_func) { | |
33 // You can't actually iterate over the anchor page. It is not a real page, | |
34 // just an anchor for the double linked page list. Initialize the current | |
35 // address and end as NULL, then the first iteration will move on | |
36 // to the first page. | |
37 Initialize(space, NULL, NULL, kAllPagesInSpace, size_func); | |
38 } | |
39 | |
40 | |
41 HeapObjectIterator::HeapObjectIterator(Page* page, | |
42 HeapObjectCallback size_func) { | |
43 Space* owner = page->owner(); | 32 Space* owner = page->owner(); |
44 DCHECK(owner == page->heap()->old_space() || | 33 DCHECK(owner == page->heap()->old_space() || |
45 owner == page->heap()->map_space() || | 34 owner == page->heap()->map_space() || |
46 owner == page->heap()->code_space()); | 35 owner == page->heap()->code_space()); |
47 Initialize(reinterpret_cast<PagedSpace*>(owner), page->area_start(), | 36 Initialize(reinterpret_cast<PagedSpace*>(owner), page->area_start(), |
48 page->area_end(), kOnePageOnly, size_func); | 37 page->area_end(), kOnePageOnly); |
49 DCHECK(page->WasSwept() || page->SweepingCompleted()); | 38 DCHECK(page->WasSwept() || page->SweepingCompleted()); |
50 } | 39 } |
51 | 40 |
52 | 41 |
53 void HeapObjectIterator::Initialize(PagedSpace* space, Address cur, Address end, | 42 void HeapObjectIterator::Initialize(PagedSpace* space, Address cur, Address end, |
54 HeapObjectIterator::PageMode mode, | 43 HeapObjectIterator::PageMode mode) { |
55 HeapObjectCallback size_f) { | |
56 space_ = space; | 44 space_ = space; |
57 cur_addr_ = cur; | 45 cur_addr_ = cur; |
58 cur_end_ = end; | 46 cur_end_ = end; |
59 page_mode_ = mode; | 47 page_mode_ = mode; |
60 size_func_ = size_f; | |
61 } | 48 } |
62 | 49 |
63 | 50 |
64 // We have hit the end of the page and should advance to the next block of | 51 // We have hit the end of the page and should advance to the next block of |
65 // objects. This happens at the end of the page. | 52 // objects. This happens at the end of the page. |
66 bool HeapObjectIterator::AdvanceToNextPage() { | 53 bool HeapObjectIterator::AdvanceToNextPage() { |
67 DCHECK(cur_addr_ == cur_end_); | 54 DCHECK(cur_addr_ == cur_end_); |
68 if (page_mode_ == kOnePageOnly) return false; | 55 if (page_mode_ == kOnePageOnly) return false; |
69 Page* cur_page; | 56 Page* cur_page; |
70 if (cur_addr_ == NULL) { | 57 if (cur_addr_ == NULL) { |
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 } | 989 } |
1003 | 990 |
1004 | 991 |
1005 Object* PagedSpace::FindObject(Address addr) { | 992 Object* PagedSpace::FindObject(Address addr) { |
1006 // Note: this function can only be called on iterable spaces. | 993 // Note: this function can only be called on iterable spaces. |
1007 DCHECK(!heap()->mark_compact_collector()->in_use()); | 994 DCHECK(!heap()->mark_compact_collector()->in_use()); |
1008 | 995 |
1009 if (!Contains(addr)) return Smi::FromInt(0); // Signaling not found. | 996 if (!Contains(addr)) return Smi::FromInt(0); // Signaling not found. |
1010 | 997 |
1011 Page* p = Page::FromAddress(addr); | 998 Page* p = Page::FromAddress(addr); |
1012 HeapObjectIterator it(p, NULL); | 999 HeapObjectIterator it(p); |
1013 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 1000 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
1014 Address cur = obj->address(); | 1001 Address cur = obj->address(); |
1015 Address next = cur + obj->Size(); | 1002 Address next = cur + obj->Size(); |
1016 if ((cur <= addr) && (addr < next)) return obj; | 1003 if ((cur <= addr) && (addr < next)) return obj; |
1017 } | 1004 } |
1018 | 1005 |
1019 UNREACHABLE(); | 1006 UNREACHABLE(); |
1020 return Smi::FromInt(0); | 1007 return Smi::FromInt(0); |
1021 } | 1008 } |
1022 | 1009 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 bool allocation_pointer_found_in_space = | 1166 bool allocation_pointer_found_in_space = |
1180 (allocation_info_.top() == allocation_info_.limit()); | 1167 (allocation_info_.top() == allocation_info_.limit()); |
1181 PageIterator page_iterator(this); | 1168 PageIterator page_iterator(this); |
1182 while (page_iterator.has_next()) { | 1169 while (page_iterator.has_next()) { |
1183 Page* page = page_iterator.next(); | 1170 Page* page = page_iterator.next(); |
1184 CHECK(page->owner() == this); | 1171 CHECK(page->owner() == this); |
1185 if (page == Page::FromAllocationTop(allocation_info_.top())) { | 1172 if (page == Page::FromAllocationTop(allocation_info_.top())) { |
1186 allocation_pointer_found_in_space = true; | 1173 allocation_pointer_found_in_space = true; |
1187 } | 1174 } |
1188 CHECK(page->WasSwept()); | 1175 CHECK(page->WasSwept()); |
1189 HeapObjectIterator it(page, NULL); | 1176 HeapObjectIterator it(page); |
1190 Address end_of_previous_object = page->area_start(); | 1177 Address end_of_previous_object = page->area_start(); |
1191 Address top = page->area_end(); | 1178 Address top = page->area_end(); |
1192 int black_size = 0; | 1179 int black_size = 0; |
1193 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { | 1180 for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) { |
1194 CHECK(end_of_previous_object <= object->address()); | 1181 CHECK(end_of_previous_object <= object->address()); |
1195 | 1182 |
1196 // The first word should be a map, and we expect all map pointers to | 1183 // The first word should be a map, and we expect all map pointers to |
1197 // be in map space. | 1184 // be in map space. |
1198 Map* map = object->map(); | 1185 Map* map = object->map(); |
1199 CHECK(map->IsMap()); | 1186 CHECK(map->IsMap()); |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1853 CHECK_NE(page, space->anchor()); | 1840 CHECK_NE(page, space->anchor()); |
1854 } | 1841 } |
1855 } | 1842 } |
1856 } | 1843 } |
1857 #endif | 1844 #endif |
1858 | 1845 |
1859 | 1846 |
1860 // ----------------------------------------------------------------------------- | 1847 // ----------------------------------------------------------------------------- |
1861 // SemiSpaceIterator implementation. | 1848 // SemiSpaceIterator implementation. |
1862 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space) { | 1849 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space) { |
1863 Initialize(space->bottom(), space->top(), NULL); | 1850 Initialize(space->bottom(), space->top()); |
1864 } | |
1865 | |
1866 | |
1867 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space, | |
1868 HeapObjectCallback size_func) { | |
1869 Initialize(space->bottom(), space->top(), size_func); | |
1870 } | 1851 } |
1871 | 1852 |
1872 | 1853 |
1873 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space, Address start) { | 1854 SemiSpaceIterator::SemiSpaceIterator(NewSpace* space, Address start) { |
1874 Initialize(start, space->top(), NULL); | 1855 Initialize(start, space->top()); |
1875 } | 1856 } |
1876 | 1857 |
1877 | 1858 |
1878 SemiSpaceIterator::SemiSpaceIterator(Address from, Address to) { | 1859 SemiSpaceIterator::SemiSpaceIterator(Address from, Address to) { |
1879 Initialize(from, to, NULL); | 1860 Initialize(from, to); |
1880 } | 1861 } |
1881 | 1862 |
1882 | 1863 |
1883 void SemiSpaceIterator::Initialize(Address start, Address end, | 1864 void SemiSpaceIterator::Initialize(Address start, Address end) { |
1884 HeapObjectCallback size_func) { | |
1885 SemiSpace::AssertValidRange(start, end); | 1865 SemiSpace::AssertValidRange(start, end); |
1886 current_ = start; | 1866 current_ = start; |
1887 limit_ = end; | 1867 limit_ = end; |
1888 size_func_ = size_func; | |
1889 } | 1868 } |
1890 | 1869 |
1891 | 1870 |
1892 #ifdef DEBUG | 1871 #ifdef DEBUG |
1893 // heap_histograms is shared, always clear it before using it. | 1872 // heap_histograms is shared, always clear it before using it. |
1894 static void ClearHistograms(Isolate* isolate) { | 1873 static void ClearHistograms(Isolate* isolate) { |
1895 // We reset the name each time, though it hasn't changed. | 1874 // We reset the name each time, though it hasn't changed. |
1896 #define DEF_TYPE_NAME(name) isolate->heap_histograms()[name].set_name(#name); | 1875 #define DEF_TYPE_NAME(name) isolate->heap_histograms()[name].set_name(#name); |
1897 INSTANCE_TYPE_LIST(DEF_TYPE_NAME) | 1876 INSTANCE_TYPE_LIST(DEF_TYPE_NAME) |
1898 #undef DEF_TYPE_NAME | 1877 #undef DEF_TYPE_NAME |
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2814 // the VerifyObject definition behind VERIFY_HEAP. | 2793 // the VerifyObject definition behind VERIFY_HEAP. |
2815 | 2794 |
2816 void MapSpace::VerifyObject(HeapObject* object) { CHECK(object->IsMap()); } | 2795 void MapSpace::VerifyObject(HeapObject* object) { CHECK(object->IsMap()); } |
2817 | 2796 |
2818 | 2797 |
2819 // ----------------------------------------------------------------------------- | 2798 // ----------------------------------------------------------------------------- |
2820 // LargeObjectIterator | 2799 // LargeObjectIterator |
2821 | 2800 |
2822 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space) { | 2801 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space) { |
2823 current_ = space->first_page_; | 2802 current_ = space->first_page_; |
2824 size_func_ = NULL; | |
2825 } | 2803 } |
2826 | 2804 |
2827 | 2805 |
2828 LargeObjectIterator::LargeObjectIterator(LargeObjectSpace* space, | |
2829 HeapObjectCallback size_func) { | |
2830 current_ = space->first_page_; | |
2831 size_func_ = size_func; | |
2832 } | |
2833 | |
2834 | |
2835 HeapObject* LargeObjectIterator::Next() { | 2806 HeapObject* LargeObjectIterator::Next() { |
2836 if (current_ == NULL) return NULL; | 2807 if (current_ == NULL) return NULL; |
2837 | 2808 |
2838 HeapObject* object = current_->GetObject(); | 2809 HeapObject* object = current_->GetObject(); |
2839 current_ = current_->next_page(); | 2810 current_ = current_->next_page(); |
2840 return object; | 2811 return object; |
2841 } | 2812 } |
2842 | 2813 |
2843 | 2814 |
2844 // ----------------------------------------------------------------------------- | 2815 // ----------------------------------------------------------------------------- |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3133 } | 3104 } |
3134 } | 3105 } |
3135 } | 3106 } |
3136 | 3107 |
3137 | 3108 |
3138 void Page::Print() { | 3109 void Page::Print() { |
3139 // Make a best-effort to print the objects in the page. | 3110 // Make a best-effort to print the objects in the page. |
3140 PrintF("Page@%p in %s\n", this->address(), | 3111 PrintF("Page@%p in %s\n", this->address(), |
3141 AllocationSpaceName(this->owner()->identity())); | 3112 AllocationSpaceName(this->owner()->identity())); |
3142 printf(" --------------------------------------\n"); | 3113 printf(" --------------------------------------\n"); |
3143 HeapObjectIterator objects(this, nullptr); | 3114 HeapObjectIterator objects(this); |
3144 unsigned mark_size = 0; | 3115 unsigned mark_size = 0; |
3145 for (HeapObject* object = objects.Next(); object != NULL; | 3116 for (HeapObject* object = objects.Next(); object != NULL; |
3146 object = objects.Next()) { | 3117 object = objects.Next()) { |
3147 bool is_marked = Marking::IsBlackOrGrey(Marking::MarkBitFrom(object)); | 3118 bool is_marked = Marking::IsBlackOrGrey(Marking::MarkBitFrom(object)); |
3148 PrintF(" %c ", (is_marked ? '!' : ' ')); // Indent a little. | 3119 PrintF(" %c ", (is_marked ? '!' : ' ')); // Indent a little. |
3149 if (is_marked) { | 3120 if (is_marked) { |
3150 mark_size += object->Size(); | 3121 mark_size += object->Size(); |
3151 } | 3122 } |
3152 object->ShortPrint(); | 3123 object->ShortPrint(); |
3153 PrintF("\n"); | 3124 PrintF("\n"); |
3154 } | 3125 } |
3155 printf(" --------------------------------------\n"); | 3126 printf(" --------------------------------------\n"); |
3156 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3127 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3157 } | 3128 } |
3158 | 3129 |
3159 #endif // DEBUG | 3130 #endif // DEBUG |
3160 } // namespace internal | 3131 } // namespace internal |
3161 } // namespace v8 | 3132 } // namespace v8 |
OLD | NEW |