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 #ifndef V8_HEAP_SPACES_H_ | 5 #ifndef V8_HEAP_SPACES_H_ |
6 #define V8_HEAP_SPACES_H_ | 6 #define V8_HEAP_SPACES_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/atomic-utils.h" | 9 #include "src/atomic-utils.h" |
10 #include "src/base/atomicops.h" | 10 #include "src/base/atomicops.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 | 95 |
96 #define DCHECK_MAP_PAGE_INDEX(index) \ | 96 #define DCHECK_MAP_PAGE_INDEX(index) \ |
97 DCHECK((0 <= index) && (index <= MapSpace::kMaxMapPageIndex)) | 97 DCHECK((0 <= index) && (index <= MapSpace::kMaxMapPageIndex)) |
98 | 98 |
99 class AllocationInfo; | 99 class AllocationInfo; |
100 class CompactionSpace; | 100 class CompactionSpace; |
101 class FreeList; | 101 class FreeList; |
102 class MemoryAllocator; | 102 class MemoryAllocator; |
103 class MemoryChunk; | 103 class MemoryChunk; |
104 class PagedSpace; | 104 class PagedSpace; |
| 105 class PostMortem; |
105 class Space; | 106 class Space; |
106 | 107 |
107 class MarkBit { | 108 class MarkBit { |
108 public: | 109 public: |
109 typedef uint32_t CellType; | 110 typedef uint32_t CellType; |
110 | 111 |
111 inline MarkBit(CellType* cell, CellType mask) : cell_(cell), mask_(mask) {} | 112 inline MarkBit(CellType* cell, CellType mask) : cell_(cell), mask_(mask) {} |
112 | 113 |
113 #ifdef DEBUG | 114 #ifdef DEBUG |
114 bool operator==(const MarkBit& other) { | 115 bool operator==(const MarkBit& other) { |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 // next_chunk_ holds a pointer of type MemoryChunk | 772 // next_chunk_ holds a pointer of type MemoryChunk |
772 AtomicValue<MemoryChunk*> next_chunk_; | 773 AtomicValue<MemoryChunk*> next_chunk_; |
773 // prev_chunk_ holds a pointer of type MemoryChunk | 774 // prev_chunk_ holds a pointer of type MemoryChunk |
774 AtomicValue<MemoryChunk*> prev_chunk_; | 775 AtomicValue<MemoryChunk*> prev_chunk_; |
775 | 776 |
776 private: | 777 private: |
777 void InitializeReservedMemory() { reservation_.Reset(); } | 778 void InitializeReservedMemory() { reservation_.Reset(); } |
778 | 779 |
779 friend class MemoryAllocator; | 780 friend class MemoryAllocator; |
780 friend class MemoryChunkValidator; | 781 friend class MemoryChunkValidator; |
| 782 |
| 783 // Used in postmortem |
| 784 friend class PostMortem; |
781 }; | 785 }; |
782 | 786 |
783 | 787 |
784 enum FreeListCategoryType { kSmall, kMedium, kLarge, kHuge }; | 788 enum FreeListCategoryType { kSmall, kMedium, kLarge, kHuge }; |
785 | 789 |
786 | 790 |
787 // ----------------------------------------------------------------------------- | 791 // ----------------------------------------------------------------------------- |
788 // A page is a memory chunk of a size 1MB. Large object pages may be larger. | 792 // A page is a memory chunk of a size 1MB. Large object pages may be larger. |
789 // | 793 // |
790 // The only way to get a page pointer is by calling factory methods: | 794 // The only way to get a page pointer is by calling factory methods: |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 } | 928 } |
925 UNREACHABLE(); | 929 UNREACHABLE(); |
926 return 0; | 930 return 0; |
927 } | 931 } |
928 | 932 |
929 #ifdef DEBUG | 933 #ifdef DEBUG |
930 void Print(); | 934 void Print(); |
931 #endif // DEBUG | 935 #endif // DEBUG |
932 | 936 |
933 friend class MemoryAllocator; | 937 friend class MemoryAllocator; |
| 938 |
| 939 // Used in postmortem |
| 940 friend class PostMortem; |
934 }; | 941 }; |
935 | 942 |
936 | 943 |
937 class LargePage : public MemoryChunk { | 944 class LargePage : public MemoryChunk { |
938 public: | 945 public: |
939 HeapObject* GetObject() { return HeapObject::FromAddress(area_start()); } | 946 HeapObject* GetObject() { return HeapObject::FromAddress(area_start()); } |
940 | 947 |
941 inline LargePage* next_page() { | 948 inline LargePage* next_page() { |
942 return static_cast<LargePage*>(next_chunk()); | 949 return static_cast<LargePage*>(next_chunk()); |
943 } | 950 } |
944 | 951 |
945 inline void set_next_page(LargePage* page) { set_next_chunk(page); } | 952 inline void set_next_page(LargePage* page) { set_next_chunk(page); } |
946 | 953 |
947 private: | 954 private: |
948 static inline LargePage* Initialize(Heap* heap, MemoryChunk* chunk); | 955 static inline LargePage* Initialize(Heap* heap, MemoryChunk* chunk); |
949 | 956 |
950 friend class MemoryAllocator; | 957 friend class MemoryAllocator; |
| 958 |
| 959 // Used in postmortem |
| 960 friend class PostMortem; |
951 }; | 961 }; |
952 | 962 |
953 | 963 |
954 // ---------------------------------------------------------------------------- | 964 // ---------------------------------------------------------------------------- |
955 // Space is the abstract superclass for all allocation spaces. | 965 // Space is the abstract superclass for all allocation spaces. |
956 class Space : public Malloced { | 966 class Space : public Malloced { |
957 public: | 967 public: |
958 Space(Heap* heap, AllocationSpace id, Executability executable) | 968 Space(Heap* heap, AllocationSpace id, Executability executable) |
959 : heap_(heap), | 969 : heap_(heap), |
960 id_(id), | 970 id_(id), |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1019 } | 1029 } |
1020 | 1030 |
1021 private: | 1031 private: |
1022 Heap* heap_; | 1032 Heap* heap_; |
1023 AllocationSpace id_; | 1033 AllocationSpace id_; |
1024 Executability executable_; | 1034 Executability executable_; |
1025 | 1035 |
1026 // Keeps track of committed memory in a space. | 1036 // Keeps track of committed memory in a space. |
1027 intptr_t committed_; | 1037 intptr_t committed_; |
1028 intptr_t max_committed_; | 1038 intptr_t max_committed_; |
| 1039 |
| 1040 // Used in postmortem |
| 1041 friend class PostMortem; |
1029 }; | 1042 }; |
1030 | 1043 |
1031 | 1044 |
1032 class MemoryChunkValidator { | 1045 class MemoryChunkValidator { |
1033 // Computed offsets should match the compiler generated ones. | 1046 // Computed offsets should match the compiler generated ones. |
1034 STATIC_ASSERT(MemoryChunk::kSizeOffset == offsetof(MemoryChunk, size_)); | 1047 STATIC_ASSERT(MemoryChunk::kSizeOffset == offsetof(MemoryChunk, size_)); |
1035 STATIC_ASSERT(MemoryChunk::kLiveBytesOffset == | 1048 STATIC_ASSERT(MemoryChunk::kLiveBytesOffset == |
1036 offsetof(MemoryChunk, live_byte_count_)); | 1049 offsetof(MemoryChunk, live_byte_count_)); |
1037 STATIC_ASSERT(MemoryChunk::kSlotsBufferOffset == | 1050 STATIC_ASSERT(MemoryChunk::kSlotsBufferOffset == |
1038 offsetof(MemoryChunk, slots_buffer_)); | 1051 offsetof(MemoryChunk, slots_buffer_)); |
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2151 Page* end_of_unswept_pages_; | 2164 Page* end_of_unswept_pages_; |
2152 | 2165 |
2153 // Mutex guarding any concurrent access to the space. | 2166 // Mutex guarding any concurrent access to the space. |
2154 base::Mutex space_mutex_; | 2167 base::Mutex space_mutex_; |
2155 | 2168 |
2156 friend class MarkCompactCollector; | 2169 friend class MarkCompactCollector; |
2157 friend class PageIterator; | 2170 friend class PageIterator; |
2158 | 2171 |
2159 // Used in cctest. | 2172 // Used in cctest. |
2160 friend class HeapTester; | 2173 friend class HeapTester; |
| 2174 |
| 2175 // Used in postmortem |
| 2176 friend class PostMortem; |
2161 }; | 2177 }; |
2162 | 2178 |
2163 | 2179 |
2164 class NumberAndSizeInfo BASE_EMBEDDED { | 2180 class NumberAndSizeInfo BASE_EMBEDDED { |
2165 public: | 2181 public: |
2166 NumberAndSizeInfo() : number_(0), bytes_(0) {} | 2182 NumberAndSizeInfo() : number_(0), bytes_(0) {} |
2167 | 2183 |
2168 int number() const { return number_; } | 2184 int number() const { return number_; } |
2169 void increment_number(int num) { number_ += num; } | 2185 void increment_number(int num) { number_ += num; } |
2170 | 2186 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2269 static NewSpacePage* Initialize(Heap* heap, Address start, | 2285 static NewSpacePage* Initialize(Heap* heap, Address start, |
2270 SemiSpace* semi_space); | 2286 SemiSpace* semi_space); |
2271 | 2287 |
2272 // Intialize a fake NewSpacePage used as sentinel at the ends | 2288 // Intialize a fake NewSpacePage used as sentinel at the ends |
2273 // of a doubly-linked list of real NewSpacePages. | 2289 // of a doubly-linked list of real NewSpacePages. |
2274 // Only uses the prev/next links, and sets flags to not be in new-space. | 2290 // Only uses the prev/next links, and sets flags to not be in new-space. |
2275 void InitializeAsAnchor(SemiSpace* owner); | 2291 void InitializeAsAnchor(SemiSpace* owner); |
2276 | 2292 |
2277 friend class SemiSpace; | 2293 friend class SemiSpace; |
2278 friend class SemiSpaceIterator; | 2294 friend class SemiSpaceIterator; |
| 2295 |
| 2296 // Used in postmortem |
| 2297 friend class PostMortem; |
2279 }; | 2298 }; |
2280 | 2299 |
2281 | 2300 |
2282 // ----------------------------------------------------------------------------- | 2301 // ----------------------------------------------------------------------------- |
2283 // SemiSpace in young generation | 2302 // SemiSpace in young generation |
2284 // | 2303 // |
2285 // A semispace is a contiguous chunk of memory holding page-like memory | 2304 // A semispace is a contiguous chunk of memory holding page-like memory |
2286 // chunks. The mark-compact collector uses the memory of the first page in | 2305 // chunks. The mark-compact collector uses the memory of the first page in |
2287 // the from space as a marking stack when tracing live objects. | 2306 // the from space as a marking stack when tracing live objects. |
2288 | 2307 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2447 uintptr_t object_expected_; | 2466 uintptr_t object_expected_; |
2448 | 2467 |
2449 bool committed_; | 2468 bool committed_; |
2450 SemiSpaceId id_; | 2469 SemiSpaceId id_; |
2451 | 2470 |
2452 NewSpacePage anchor_; | 2471 NewSpacePage anchor_; |
2453 NewSpacePage* current_page_; | 2472 NewSpacePage* current_page_; |
2454 | 2473 |
2455 friend class SemiSpaceIterator; | 2474 friend class SemiSpaceIterator; |
2456 friend class NewSpacePageIterator; | 2475 friend class NewSpacePageIterator; |
| 2476 |
| 2477 // Used in postmortem |
| 2478 friend class PostMortem; |
2457 }; | 2479 }; |
2458 | 2480 |
2459 | 2481 |
2460 // A SemiSpaceIterator is an ObjectIterator that iterates over the active | 2482 // A SemiSpaceIterator is an ObjectIterator that iterates over the active |
2461 // semispace of the heap's new space. It iterates over the objects in the | 2483 // semispace of the heap's new space. It iterates over the objects in the |
2462 // semispace from a given start address (defaulting to the bottom of the | 2484 // semispace from a given start address (defaulting to the bottom of the |
2463 // semispace) to the top of the semispace. New objects allocated after the | 2485 // semispace) to the top of the semispace. New objects allocated after the |
2464 // iterator is created are not iterated. | 2486 // iterator is created are not iterated. |
2465 class SemiSpaceIterator : public ObjectIterator { | 2487 class SemiSpaceIterator : public ObjectIterator { |
2466 public: | 2488 public: |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2939 | 2961 |
2940 // ----------------------------------------------------------------------------- | 2962 // ----------------------------------------------------------------------------- |
2941 // Old object space (includes the old space of objects and code space) | 2963 // Old object space (includes the old space of objects and code space) |
2942 | 2964 |
2943 class OldSpace : public PagedSpace { | 2965 class OldSpace : public PagedSpace { |
2944 public: | 2966 public: |
2945 // Creates an old space object. The constructor does not allocate pages | 2967 // Creates an old space object. The constructor does not allocate pages |
2946 // from OS. | 2968 // from OS. |
2947 OldSpace(Heap* heap, AllocationSpace id, Executability executable) | 2969 OldSpace(Heap* heap, AllocationSpace id, Executability executable) |
2948 : PagedSpace(heap, id, executable) {} | 2970 : PagedSpace(heap, id, executable) {} |
| 2971 |
| 2972 // Used in postmortem |
| 2973 friend class PostMortem; |
2949 }; | 2974 }; |
2950 | 2975 |
2951 | 2976 |
2952 // For contiguous spaces, top should be in the space (or at the end) and limit | 2977 // For contiguous spaces, top should be in the space (or at the end) and limit |
2953 // should be the end of the space. | 2978 // should be the end of the space. |
2954 #define DCHECK_SEMISPACE_ALLOCATION_INFO(info, space) \ | 2979 #define DCHECK_SEMISPACE_ALLOCATION_INFO(info, space) \ |
2955 SLOW_DCHECK((space).page_low() <= (info).top() && \ | 2980 SLOW_DCHECK((space).page_low() <= (info).top() && \ |
2956 (info).top() <= (space).page_high() && \ | 2981 (info).top() <= (space).page_high() && \ |
2957 (info).limit() <= (space).page_high()) | 2982 (info).limit() <= (space).page_high()) |
2958 | 2983 |
(...skipping 26 matching lines...) Expand all Loading... |
2985 | 3010 |
2986 private: | 3011 private: |
2987 static const int kMapsPerPage = Page::kAllocatableMemory / Map::kSize; | 3012 static const int kMapsPerPage = Page::kAllocatableMemory / Map::kSize; |
2988 | 3013 |
2989 // Do map space compaction if there is a page gap. | 3014 // Do map space compaction if there is a page gap. |
2990 int CompactionThreshold() { | 3015 int CompactionThreshold() { |
2991 return kMapsPerPage * (max_map_space_pages_ - 1); | 3016 return kMapsPerPage * (max_map_space_pages_ - 1); |
2992 } | 3017 } |
2993 | 3018 |
2994 const int max_map_space_pages_; | 3019 const int max_map_space_pages_; |
| 3020 |
| 3021 // Used in postmortem |
| 3022 friend class PostMortem; |
2995 }; | 3023 }; |
2996 | 3024 |
2997 | 3025 |
2998 // ----------------------------------------------------------------------------- | 3026 // ----------------------------------------------------------------------------- |
2999 // Large objects ( > Page::kMaxHeapObjectSize ) are allocated and managed by | 3027 // Large objects ( > Page::kMaxHeapObjectSize ) are allocated and managed by |
3000 // the large object space. A large object is allocated from OS heap with | 3028 // the large object space. A large object is allocated from OS heap with |
3001 // extra padding bytes (Page::kPageSize + Page::kObjectStartOffset). | 3029 // extra padding bytes (Page::kPageSize + Page::kObjectStartOffset). |
3002 // A large object always starts at Page::kObjectStartOffset to a page. | 3030 // A large object always starts at Page::kObjectStartOffset to a page. |
3003 // Large objects do not move during garbage collections. | 3031 // Large objects do not move during garbage collections. |
3004 | 3032 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3074 private: | 3102 private: |
3075 // The head of the linked list of large object chunks. | 3103 // The head of the linked list of large object chunks. |
3076 LargePage* first_page_; | 3104 LargePage* first_page_; |
3077 intptr_t size_; // allocated bytes | 3105 intptr_t size_; // allocated bytes |
3078 int page_count_; // number of chunks | 3106 int page_count_; // number of chunks |
3079 intptr_t objects_size_; // size of objects | 3107 intptr_t objects_size_; // size of objects |
3080 // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them | 3108 // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them |
3081 HashMap chunk_map_; | 3109 HashMap chunk_map_; |
3082 | 3110 |
3083 friend class LargeObjectIterator; | 3111 friend class LargeObjectIterator; |
| 3112 |
| 3113 // Used in postmortem |
| 3114 friend class PostMortem; |
3084 }; | 3115 }; |
3085 | 3116 |
3086 | 3117 |
3087 class LargeObjectIterator : public ObjectIterator { | 3118 class LargeObjectIterator : public ObjectIterator { |
3088 public: | 3119 public: |
3089 explicit LargeObjectIterator(LargeObjectSpace* space); | 3120 explicit LargeObjectIterator(LargeObjectSpace* space); |
3090 | 3121 |
3091 HeapObject* Next(); | 3122 HeapObject* Next(); |
3092 | 3123 |
3093 // implementation of ObjectIterator. | 3124 // implementation of ObjectIterator. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3127 count = 0; | 3158 count = 0; |
3128 } | 3159 } |
3129 // Must be small, since an iteration is used for lookup. | 3160 // Must be small, since an iteration is used for lookup. |
3130 static const int kMaxComments = 64; | 3161 static const int kMaxComments = 64; |
3131 }; | 3162 }; |
3132 #endif | 3163 #endif |
3133 } // namespace internal | 3164 } // namespace internal |
3134 } // namespace v8 | 3165 } // namespace v8 |
3135 | 3166 |
3136 #endif // V8_HEAP_SPACES_H_ | 3167 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |