| 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 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 | 901 |
| 902 friend class MemoryAllocator; | 902 friend class MemoryAllocator; |
| 903 }; | 903 }; |
| 904 | 904 |
| 905 | 905 |
| 906 // ---------------------------------------------------------------------------- | 906 // ---------------------------------------------------------------------------- |
| 907 // Space is the abstract superclass for all allocation spaces. | 907 // Space is the abstract superclass for all allocation spaces. |
| 908 class Space : public Malloced { | 908 class Space : public Malloced { |
| 909 public: | 909 public: |
| 910 Space(Heap* heap, AllocationSpace id, Executability executable) | 910 Space(Heap* heap, AllocationSpace id, Executability executable) |
| 911 : heap_(heap), id_(id), executable_(executable) {} | 911 : heap_(heap), |
| 912 id_(id), |
| 913 executable_(executable), |
| 914 committed_(0), |
| 915 max_committed_(0) {} |
| 912 | 916 |
| 913 virtual ~Space() {} | 917 virtual ~Space() {} |
| 914 | 918 |
| 915 Heap* heap() const { return heap_; } | 919 Heap* heap() const { return heap_; } |
| 916 | 920 |
| 917 // Does the space need executable memory? | 921 // Does the space need executable memory? |
| 918 Executability executable() { return executable_; } | 922 Executability executable() { return executable_; } |
| 919 | 923 |
| 920 // Identity used in error reporting. | 924 // Identity used in error reporting. |
| 921 AllocationSpace identity() { return id_; } | 925 AllocationSpace identity() { return id_; } |
| 922 | 926 |
| 927 // Return the total amount committed memory for this space, i.e., allocatable |
| 928 // memory and page headers. |
| 929 virtual intptr_t CommittedMemory() { return committed_; } |
| 930 |
| 931 virtual intptr_t MaximumCommittedMemory() { return max_committed_; } |
| 932 |
| 923 // Returns allocated size. | 933 // Returns allocated size. |
| 924 virtual intptr_t Size() = 0; | 934 virtual intptr_t Size() = 0; |
| 925 | 935 |
| 926 // Returns size of objects. Can differ from the allocated size | 936 // Returns size of objects. Can differ from the allocated size |
| 927 // (e.g. see LargeObjectSpace). | 937 // (e.g. see LargeObjectSpace). |
| 928 virtual intptr_t SizeOfObjects() { return Size(); } | 938 virtual intptr_t SizeOfObjects() { return Size(); } |
| 929 | 939 |
| 930 // Return the total amount of memory committed for new space. | |
| 931 virtual intptr_t CommittedMemory() = 0; | |
| 932 | |
| 933 // Approximate amount of physical memory committed for this space. | 940 // Approximate amount of physical memory committed for this space. |
| 934 virtual size_t CommittedPhysicalMemory() = 0; | 941 virtual size_t CommittedPhysicalMemory() = 0; |
| 935 | 942 |
| 936 // Return the available bytes without growing. | 943 // Return the available bytes without growing. |
| 937 virtual intptr_t Available() = 0; | 944 virtual intptr_t Available() = 0; |
| 938 | 945 |
| 939 virtual int RoundSizeDownToObjectAlignment(int size) { | 946 virtual int RoundSizeDownToObjectAlignment(int size) { |
| 940 if (id_ == CODE_SPACE) { | 947 if (id_ == CODE_SPACE) { |
| 941 return RoundDown(size, kCodeAlignment); | 948 return RoundDown(size, kCodeAlignment); |
| 942 } else { | 949 } else { |
| 943 return RoundDown(size, kPointerSize); | 950 return RoundDown(size, kPointerSize); |
| 944 } | 951 } |
| 945 } | 952 } |
| 946 | 953 |
| 947 #ifdef DEBUG | 954 #ifdef DEBUG |
| 948 virtual void Print() = 0; | 955 virtual void Print() = 0; |
| 949 #endif | 956 #endif |
| 950 | 957 |
| 958 protected: |
| 959 void AccountCommitted(intptr_t bytes) { |
| 960 DCHECK_GE(bytes, 0); |
| 961 committed_ += bytes; |
| 962 if (committed_ > max_committed_) { |
| 963 max_committed_ = committed_; |
| 964 } |
| 965 } |
| 966 |
| 967 void AccountUncommitted(intptr_t bytes) { |
| 968 DCHECK_GE(bytes, 0); |
| 969 committed_ -= bytes; |
| 970 DCHECK_GE(committed_, 0); |
| 971 } |
| 972 |
| 951 private: | 973 private: |
| 952 Heap* heap_; | 974 Heap* heap_; |
| 953 AllocationSpace id_; | 975 AllocationSpace id_; |
| 954 Executability executable_; | 976 Executability executable_; |
| 977 |
| 978 // Keeps track of committed memory in a space. |
| 979 intptr_t committed_; |
| 980 intptr_t max_committed_; |
| 955 }; | 981 }; |
| 956 | 982 |
| 957 | 983 |
| 958 class MemoryChunkValidator { | 984 class MemoryChunkValidator { |
| 959 // Computed offsets should match the compiler generated ones. | 985 // Computed offsets should match the compiler generated ones. |
| 960 STATIC_ASSERT(MemoryChunk::kSizeOffset == offsetof(MemoryChunk, size_)); | 986 STATIC_ASSERT(MemoryChunk::kSizeOffset == offsetof(MemoryChunk, size_)); |
| 961 STATIC_ASSERT(MemoryChunk::kLiveBytesOffset == | 987 STATIC_ASSERT(MemoryChunk::kLiveBytesOffset == |
| 962 offsetof(MemoryChunk, live_byte_count_)); | 988 offsetof(MemoryChunk, live_byte_count_)); |
| 963 STATIC_ASSERT(MemoryChunk::kSlotsBufferOffset == | 989 STATIC_ASSERT(MemoryChunk::kSlotsBufferOffset == |
| 964 offsetof(MemoryChunk, slots_buffer_)); | 990 offsetof(MemoryChunk, slots_buffer_)); |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1804 // During boot the free_space_map is created, and afterwards we may need | 1830 // During boot the free_space_map is created, and afterwards we may need |
| 1805 // to write it into the free list nodes that were already created. | 1831 // to write it into the free list nodes that were already created. |
| 1806 void RepairFreeListsAfterDeserialization(); | 1832 void RepairFreeListsAfterDeserialization(); |
| 1807 | 1833 |
| 1808 // Prepares for a mark-compact GC. | 1834 // Prepares for a mark-compact GC. |
| 1809 void PrepareForMarkCompact(); | 1835 void PrepareForMarkCompact(); |
| 1810 | 1836 |
| 1811 // Current capacity without growing (Size() + Available()). | 1837 // Current capacity without growing (Size() + Available()). |
| 1812 intptr_t Capacity() { return accounting_stats_.Capacity(); } | 1838 intptr_t Capacity() { return accounting_stats_.Capacity(); } |
| 1813 | 1839 |
| 1814 // Total amount of memory committed for this space. For paged | |
| 1815 // spaces this equals the capacity. | |
| 1816 intptr_t CommittedMemory() override { return Capacity(); } | |
| 1817 | |
| 1818 // The maximum amount of memory ever committed for this space. | |
| 1819 intptr_t MaximumCommittedMemory() { return accounting_stats_.MaxCapacity(); } | |
| 1820 | |
| 1821 // Approximate amount of physical memory committed for this space. | 1840 // Approximate amount of physical memory committed for this space. |
| 1822 size_t CommittedPhysicalMemory() override; | 1841 size_t CommittedPhysicalMemory() override; |
| 1823 | 1842 |
| 1824 void ResetFreeListStatistics(); | 1843 void ResetFreeListStatistics(); |
| 1825 | 1844 |
| 1826 // Sets the capacity, the available space and the wasted space to zero. | 1845 // Sets the capacity, the available space and the wasted space to zero. |
| 1827 // The stats are rebuilt during sweeping by adding each page to the | 1846 // The stats are rebuilt during sweeping by adding each page to the |
| 1828 // capacity and the size when it is encountered. As free spaces are | 1847 // capacity and the size when it is encountered. As free spaces are |
| 1829 // discovered during the sweeping they are subtracted from the size and added | 1848 // discovered during the sweeping they are subtracted from the size and added |
| 1830 // to the available and wasted totals. | 1849 // to the available and wasted totals. |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2278 // If we don't have these here then SemiSpace will be abstract. However | 2297 // If we don't have these here then SemiSpace will be abstract. However |
| 2279 // they should never be called: | 2298 // they should never be called: |
| 2280 | 2299 |
| 2281 intptr_t Size() override { | 2300 intptr_t Size() override { |
| 2282 UNREACHABLE(); | 2301 UNREACHABLE(); |
| 2283 return 0; | 2302 return 0; |
| 2284 } | 2303 } |
| 2285 | 2304 |
| 2286 intptr_t SizeOfObjects() override { return Size(); } | 2305 intptr_t SizeOfObjects() override { return Size(); } |
| 2287 | 2306 |
| 2288 intptr_t CommittedMemory() override { | |
| 2289 UNREACHABLE(); | |
| 2290 return 0; | |
| 2291 } | |
| 2292 | |
| 2293 intptr_t Available() override { | 2307 intptr_t Available() override { |
| 2294 UNREACHABLE(); | 2308 UNREACHABLE(); |
| 2295 return 0; | 2309 return 0; |
| 2296 } | 2310 } |
| 2297 | 2311 |
| 2298 | 2312 |
| 2299 bool is_committed() { return committed_; } | 2313 bool is_committed() { return committed_; } |
| 2300 bool Commit(); | 2314 bool Commit(); |
| 2301 bool Uncommit(); | 2315 bool Uncommit(); |
| 2302 | 2316 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2327 // Returns the maximum total capacity of the semispace. | 2341 // Returns the maximum total capacity of the semispace. |
| 2328 int MaximumTotalCapacity() { return maximum_total_capacity_; } | 2342 int MaximumTotalCapacity() { return maximum_total_capacity_; } |
| 2329 | 2343 |
| 2330 // Returns the initial capacity of the semispace. | 2344 // Returns the initial capacity of the semispace. |
| 2331 int InitialTotalCapacity() { return initial_total_capacity_; } | 2345 int InitialTotalCapacity() { return initial_total_capacity_; } |
| 2332 | 2346 |
| 2333 SemiSpaceId id() { return id_; } | 2347 SemiSpaceId id() { return id_; } |
| 2334 | 2348 |
| 2335 static void Swap(SemiSpace* from, SemiSpace* to); | 2349 static void Swap(SemiSpace* from, SemiSpace* to); |
| 2336 | 2350 |
| 2337 // Returns the maximum amount of memory ever committed by the semi space. | |
| 2338 size_t MaximumCommittedMemory() { return maximum_committed_; } | |
| 2339 | |
| 2340 // Approximate amount of physical memory committed for this space. | 2351 // Approximate amount of physical memory committed for this space. |
| 2341 size_t CommittedPhysicalMemory() override; | 2352 size_t CommittedPhysicalMemory() override; |
| 2342 | 2353 |
| 2343 private: | 2354 private: |
| 2344 // Flips the semispace between being from-space and to-space. | 2355 // Flips the semispace between being from-space and to-space. |
| 2345 // Copies the flags into the masked positions on all pages in the space. | 2356 // Copies the flags into the masked positions on all pages in the space. |
| 2346 void FlipPages(intptr_t flags, intptr_t flag_mask); | 2357 void FlipPages(intptr_t flags, intptr_t flag_mask); |
| 2347 | 2358 |
| 2348 // Updates Capacity and MaximumCommitted based on new capacity. | 2359 // Updates Capacity and MaximumCommitted based on new capacity. |
| 2349 void SetCapacity(int new_capacity); | 2360 void SetCapacity(int new_capacity); |
| 2350 | 2361 |
| 2351 NewSpacePage* anchor() { return &anchor_; } | 2362 NewSpacePage* anchor() { return &anchor_; } |
| 2352 | 2363 |
| 2353 // The current and maximum total capacity of the space. | 2364 // The current and maximum total capacity of the space. |
| 2354 int total_capacity_; | 2365 int total_capacity_; |
| 2355 int target_capacity_; | 2366 int target_capacity_; |
| 2356 int maximum_total_capacity_; | 2367 int maximum_total_capacity_; |
| 2357 int initial_total_capacity_; | 2368 int initial_total_capacity_; |
| 2358 | 2369 |
| 2359 intptr_t maximum_committed_; | |
| 2360 | |
| 2361 // The start address of the space. | 2370 // The start address of the space. |
| 2362 Address start_; | 2371 Address start_; |
| 2363 // Used to govern object promotion during mark-compact collection. | 2372 // Used to govern object promotion during mark-compact collection. |
| 2364 Address age_mark_; | 2373 Address age_mark_; |
| 2365 | 2374 |
| 2366 // Masks and comparison values to test for containment in this semispace. | 2375 // Masks and comparison values to test for containment in this semispace. |
| 2367 uintptr_t address_mask_; | 2376 uintptr_t address_mask_; |
| 2368 uintptr_t object_mask_; | 2377 uintptr_t object_mask_; |
| 2369 uintptr_t object_expected_; | 2378 uintptr_t object_expected_; |
| 2370 | 2379 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2504 NewSpacePage::kAreaSize; | 2513 NewSpacePage::kAreaSize; |
| 2505 } | 2514 } |
| 2506 | 2515 |
| 2507 // Return the current size of a semispace, allocatable and non-allocatable | 2516 // Return the current size of a semispace, allocatable and non-allocatable |
| 2508 // memory. | 2517 // memory. |
| 2509 intptr_t TotalCapacity() { | 2518 intptr_t TotalCapacity() { |
| 2510 DCHECK(to_space_.TotalCapacity() == from_space_.TotalCapacity()); | 2519 DCHECK(to_space_.TotalCapacity() == from_space_.TotalCapacity()); |
| 2511 return to_space_.TotalCapacity(); | 2520 return to_space_.TotalCapacity(); |
| 2512 } | 2521 } |
| 2513 | 2522 |
| 2514 // Return the total amount of memory committed for new space. | 2523 // Committed memory for NewSpace is the committed memory of both semi-spaces |
| 2524 // combined. |
| 2515 intptr_t CommittedMemory() override { | 2525 intptr_t CommittedMemory() override { |
| 2516 if (from_space_.is_committed()) return 2 * Capacity(); | 2526 return from_space_.CommittedMemory() + to_space_.CommittedMemory(); |
| 2517 return TotalCapacity(); | |
| 2518 } | 2527 } |
| 2519 | 2528 |
| 2520 // Return the total amount of memory committed for new space. | 2529 intptr_t MaximumCommittedMemory() override { |
| 2521 intptr_t MaximumCommittedMemory() { | 2530 return from_space_.MaximumCommittedMemory() + |
| 2522 return to_space_.MaximumCommittedMemory() + | 2531 to_space_.MaximumCommittedMemory(); |
| 2523 from_space_.MaximumCommittedMemory(); | |
| 2524 } | 2532 } |
| 2525 | 2533 |
| 2526 // Approximate amount of physical memory committed for this space. | 2534 // Approximate amount of physical memory committed for this space. |
| 2527 size_t CommittedPhysicalMemory() override; | 2535 size_t CommittedPhysicalMemory() override; |
| 2528 | 2536 |
| 2529 // Return the available bytes without growing. | 2537 // Return the available bytes without growing. |
| 2530 intptr_t Available() override { return Capacity() - Size(); } | 2538 intptr_t Available() override { return Capacity() - Size(); } |
| 2531 | 2539 |
| 2532 intptr_t PagesFromStart(Address addr) { | 2540 intptr_t PagesFromStart(Address addr) { |
| 2533 return static_cast<intptr_t>(addr - bottom()) / Page::kPageSize; | 2541 return static_cast<intptr_t>(addr - bottom()) / Page::kPageSize; |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2881 MUST_USE_RESULT AllocationResult | 2889 MUST_USE_RESULT AllocationResult |
| 2882 AllocateRaw(int object_size, Executability executable); | 2890 AllocateRaw(int object_size, Executability executable); |
| 2883 | 2891 |
| 2884 // Available bytes for objects in this space. | 2892 // Available bytes for objects in this space. |
| 2885 inline intptr_t Available() override; | 2893 inline intptr_t Available() override; |
| 2886 | 2894 |
| 2887 intptr_t Size() override { return size_; } | 2895 intptr_t Size() override { return size_; } |
| 2888 | 2896 |
| 2889 intptr_t SizeOfObjects() override { return objects_size_; } | 2897 intptr_t SizeOfObjects() override { return objects_size_; } |
| 2890 | 2898 |
| 2891 intptr_t MaximumCommittedMemory() { return maximum_committed_; } | |
| 2892 | |
| 2893 intptr_t CommittedMemory() override { return Size(); } | |
| 2894 | |
| 2895 // Approximate amount of physical memory committed for this space. | 2899 // Approximate amount of physical memory committed for this space. |
| 2896 size_t CommittedPhysicalMemory() override; | 2900 size_t CommittedPhysicalMemory() override; |
| 2897 | 2901 |
| 2898 int PageCount() { return page_count_; } | 2902 int PageCount() { return page_count_; } |
| 2899 | 2903 |
| 2900 // Finds an object for a given address, returns a Smi if it is not found. | 2904 // Finds an object for a given address, returns a Smi if it is not found. |
| 2901 // The function iterates through all objects in this space, may be slow. | 2905 // The function iterates through all objects in this space, may be slow. |
| 2902 Object* FindObject(Address a); | 2906 Object* FindObject(Address a); |
| 2903 | 2907 |
| 2904 // Finds a large object page containing the given address, returns NULL | 2908 // Finds a large object page containing the given address, returns NULL |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2927 #ifdef DEBUG | 2931 #ifdef DEBUG |
| 2928 void Print() override; | 2932 void Print() override; |
| 2929 void ReportStatistics(); | 2933 void ReportStatistics(); |
| 2930 void CollectCodeStatistics(); | 2934 void CollectCodeStatistics(); |
| 2931 #endif | 2935 #endif |
| 2932 // Checks whether an address is in the object area in this space. It | 2936 // Checks whether an address is in the object area in this space. It |
| 2933 // iterates all objects in the space. May be slow. | 2937 // iterates all objects in the space. May be slow. |
| 2934 bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); } | 2938 bool SlowContains(Address addr) { return FindObject(addr)->IsHeapObject(); } |
| 2935 | 2939 |
| 2936 private: | 2940 private: |
| 2937 intptr_t maximum_committed_; | |
| 2938 // The head of the linked list of large object chunks. | 2941 // The head of the linked list of large object chunks. |
| 2939 LargePage* first_page_; | 2942 LargePage* first_page_; |
| 2940 intptr_t size_; // allocated bytes | 2943 intptr_t size_; // allocated bytes |
| 2941 int page_count_; // number of chunks | 2944 int page_count_; // number of chunks |
| 2942 intptr_t objects_size_; // size of objects | 2945 intptr_t objects_size_; // size of objects |
| 2943 // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them | 2946 // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them |
| 2944 HashMap chunk_map_; | 2947 HashMap chunk_map_; |
| 2945 | 2948 |
| 2946 friend class LargeObjectIterator; | 2949 friend class LargeObjectIterator; |
| 2947 }; | 2950 }; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2990 count = 0; | 2993 count = 0; |
| 2991 } | 2994 } |
| 2992 // Must be small, since an iteration is used for lookup. | 2995 // Must be small, since an iteration is used for lookup. |
| 2993 static const int kMaxComments = 64; | 2996 static const int kMaxComments = 64; |
| 2994 }; | 2997 }; |
| 2995 #endif | 2998 #endif |
| 2996 } // namespace internal | 2999 } // namespace internal |
| 2997 } // namespace v8 | 3000 } // namespace v8 |
| 2998 | 3001 |
| 2999 #endif // V8_HEAP_SPACES_H_ | 3002 #endif // V8_HEAP_SPACES_H_ |
| OLD | NEW |