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