| 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 | 
|---|