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 1447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1458 | 1458 |
1459 | 1459 |
1460 // ----------------------------------------------------------------------------- | 1460 // ----------------------------------------------------------------------------- |
1461 // A space has a circular list of pages. The next page can be accessed via | 1461 // A space has a circular list of pages. The next page can be accessed via |
1462 // Page::next_page() call. | 1462 // Page::next_page() call. |
1463 | 1463 |
1464 // An abstraction of allocation and relocation pointers in a page-structured | 1464 // An abstraction of allocation and relocation pointers in a page-structured |
1465 // space. | 1465 // space. |
1466 class AllocationInfo { | 1466 class AllocationInfo { |
1467 public: | 1467 public: |
1468 AllocationInfo() : top_(NULL), limit_(NULL) {} | 1468 AllocationInfo() : top_(nullptr), limit_(nullptr) {} |
1469 AllocationInfo(Address top, Address limit) : top_(top), limit_(limit) {} | |
1470 | |
1471 void Reset(Address top, Address limit) { | |
1472 set_top(top); | |
1473 set_limit(limit); | |
1474 } | |
1469 | 1475 |
1470 INLINE(void set_top(Address top)) { | 1476 INLINE(void set_top(Address top)) { |
1471 SLOW_DCHECK(top == NULL || | 1477 SLOW_DCHECK(top == NULL || |
1472 (reinterpret_cast<intptr_t>(top) & kHeapObjectTagMask) == 0); | 1478 (reinterpret_cast<intptr_t>(top) & kHeapObjectTagMask) == 0); |
1473 top_ = top; | 1479 top_ = top; |
1474 } | 1480 } |
1475 | 1481 |
1476 INLINE(Address top()) const { | 1482 INLINE(Address top()) const { |
1477 SLOW_DCHECK(top_ == NULL || | 1483 SLOW_DCHECK(top_ == NULL || |
1478 (reinterpret_cast<intptr_t>(top_) & kHeapObjectTagMask) == 0); | 1484 (reinterpret_cast<intptr_t>(top_) & kHeapObjectTagMask) == 0); |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1855 explicit AllocationResult(AllocationSpace space) | 1861 explicit AllocationResult(AllocationSpace space) |
1856 : object_(Smi::FromInt(static_cast<int>(space))) {} | 1862 : object_(Smi::FromInt(static_cast<int>(space))) {} |
1857 | 1863 |
1858 Object* object_; | 1864 Object* object_; |
1859 }; | 1865 }; |
1860 | 1866 |
1861 | 1867 |
1862 STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize); | 1868 STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize); |
1863 | 1869 |
1864 | 1870 |
1871 class LocalAllocationBuffer { | |
Hannes Payer (out of office)
2015/12/18 10:29:06
This class needs a bunch of comments, explaining w
Michael Lippautz
2015/12/18 10:53:05
Done.
| |
1872 public: | |
1873 static inline LocalAllocationBuffer InvalidBuffer(); | |
1874 static inline LocalAllocationBuffer FromResult(Heap* heap, | |
1875 AllocationResult result, | |
1876 intptr_t size); | |
1877 | |
1878 ~LocalAllocationBuffer() { Close(); } | |
1879 | |
1880 // Convert to C++11 move-semantics once allowed by the style guide. | |
1881 LocalAllocationBuffer(const LocalAllocationBuffer& other); | |
1882 LocalAllocationBuffer& operator=(const LocalAllocationBuffer& other); | |
1883 | |
1884 MUST_USE_RESULT inline AllocationResult AllocateRawAligned( | |
1885 int size_in_bytes, AllocationAlignment alignment); | |
1886 | |
1887 inline bool IsValid() { return allocation_info_.top() != nullptr; } | |
1888 | |
1889 // Try to merge LABs, which is only possible when they are adjacent in memory. | |
1890 inline bool TryMerge(LocalAllocationBuffer* other); | |
1891 | |
1892 private: | |
1893 LocalAllocationBuffer(Heap* heap, AllocationInfo allocation_info); | |
1894 | |
1895 void Close(); | |
1896 | |
1897 Heap* heap_; | |
1898 AllocationInfo allocation_info_; | |
1899 }; | |
1900 | |
1901 | |
1865 class PagedSpace : public Space { | 1902 class PagedSpace : public Space { |
1866 public: | 1903 public: |
1867 static const intptr_t kCompactionMemoryWanted = 500 * KB; | 1904 static const intptr_t kCompactionMemoryWanted = 500 * KB; |
1868 | 1905 |
1869 // Creates a space with an id. | 1906 // Creates a space with an id. |
1870 PagedSpace(Heap* heap, AllocationSpace id, Executability executable); | 1907 PagedSpace(Heap* heap, AllocationSpace id, Executability executable); |
1871 | 1908 |
1872 ~PagedSpace() override { TearDown(); } | 1909 ~PagedSpace() override { TearDown(); } |
1873 | 1910 |
1874 // Set up the space using the given address range of virtual memory (from | 1911 // Set up the space using the given address range of virtual memory (from |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1985 return size_in_bytes - wasted; | 2022 return size_in_bytes - wasted; |
1986 } | 2023 } |
1987 | 2024 |
1988 void ResetFreeList() { free_list_.Reset(); } | 2025 void ResetFreeList() { free_list_.Reset(); } |
1989 | 2026 |
1990 // Set space allocation info. | 2027 // Set space allocation info. |
1991 void SetTopAndLimit(Address top, Address limit) { | 2028 void SetTopAndLimit(Address top, Address limit) { |
1992 DCHECK(top == limit || | 2029 DCHECK(top == limit || |
1993 Page::FromAddress(top) == Page::FromAddress(limit - 1)); | 2030 Page::FromAddress(top) == Page::FromAddress(limit - 1)); |
1994 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); | 2031 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); |
1995 allocation_info_.set_top(top); | 2032 allocation_info_.Reset(top, limit); |
1996 allocation_info_.set_limit(limit); | |
1997 } | 2033 } |
1998 | 2034 |
1999 // Empty space allocation info, returning unused area to free list. | 2035 // Empty space allocation info, returning unused area to free list. |
2000 void EmptyAllocationInfo() { | 2036 void EmptyAllocationInfo() { |
2001 // Mark the old linear allocation area with a free space map so it can be | 2037 // Mark the old linear allocation area with a free space map so it can be |
2002 // skipped when scanning the heap. | 2038 // skipped when scanning the heap. |
2003 int old_linear_size = static_cast<int>(limit() - top()); | 2039 int old_linear_size = static_cast<int>(limit() - top()); |
2004 Free(top(), old_linear_size); | 2040 Free(top(), old_linear_size); |
2005 SetTopAndLimit(NULL, NULL); | 2041 SetTopAndLimit(NULL, NULL); |
2006 } | 2042 } |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2727 | 2763 |
2728 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( | 2764 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( |
2729 int size_in_bytes, AllocationAlignment alignment)); | 2765 int size_in_bytes, AllocationAlignment alignment)); |
2730 | 2766 |
2731 MUST_USE_RESULT INLINE( | 2767 MUST_USE_RESULT INLINE( |
2732 AllocationResult AllocateRawUnaligned(int size_in_bytes)); | 2768 AllocationResult AllocateRawUnaligned(int size_in_bytes)); |
2733 | 2769 |
2734 MUST_USE_RESULT INLINE(AllocationResult AllocateRaw( | 2770 MUST_USE_RESULT INLINE(AllocationResult AllocateRaw( |
2735 int size_in_bytes, AllocationAlignment alignment)); | 2771 int size_in_bytes, AllocationAlignment alignment)); |
2736 | 2772 |
2773 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized( | |
2774 int size_in_bytes, AllocationAlignment alignment); | |
2775 | |
2737 // Reset the allocation pointer to the beginning of the active semispace. | 2776 // Reset the allocation pointer to the beginning of the active semispace. |
2738 void ResetAllocationInfo(); | 2777 void ResetAllocationInfo(); |
2739 | 2778 |
2740 void UpdateInlineAllocationLimit(int size_in_bytes); | 2779 void UpdateInlineAllocationLimit(int size_in_bytes); |
2741 | 2780 |
2742 // Allows observation of inline allocation. The observer->Step() method gets | 2781 // Allows observation of inline allocation. The observer->Step() method gets |
2743 // called after every step_size bytes have been allocated (approximately). | 2782 // called after every step_size bytes have been allocated (approximately). |
2744 // This works by adjusting the allocation limit to a lower value and adjusting | 2783 // This works by adjusting the allocation limit to a lower value and adjusting |
2745 // it after each step. | 2784 // it after each step. |
2746 void AddInlineAllocationObserver(InlineAllocationObserver* observer); | 2785 void AddInlineAllocationObserver(InlineAllocationObserver* observer); |
(...skipping 29 matching lines...) Expand all Loading... | |
2776 // respective semispace (not necessarily below the allocation pointer of the | 2815 // respective semispace (not necessarily below the allocation pointer of the |
2777 // semispace). | 2816 // semispace). |
2778 inline bool ToSpaceContains(Object* o) { return to_space_.Contains(o); } | 2817 inline bool ToSpaceContains(Object* o) { return to_space_.Contains(o); } |
2779 inline bool FromSpaceContains(Object* o) { return from_space_.Contains(o); } | 2818 inline bool FromSpaceContains(Object* o) { return from_space_.Contains(o); } |
2780 | 2819 |
2781 // Try to switch the active semispace to a new, empty, page. | 2820 // Try to switch the active semispace to a new, empty, page. |
2782 // Returns false if this isn't possible or reasonable (i.e., there | 2821 // Returns false if this isn't possible or reasonable (i.e., there |
2783 // are no pages, or the current page is already empty), or true | 2822 // are no pages, or the current page is already empty), or true |
2784 // if successful. | 2823 // if successful. |
2785 bool AddFreshPage(); | 2824 bool AddFreshPage(); |
2825 bool AddFreshPageSynchronized(); | |
2786 | 2826 |
2787 #ifdef VERIFY_HEAP | 2827 #ifdef VERIFY_HEAP |
2788 // Verify the active semispace. | 2828 // Verify the active semispace. |
2789 virtual void Verify(); | 2829 virtual void Verify(); |
2790 #endif | 2830 #endif |
2791 | 2831 |
2792 #ifdef DEBUG | 2832 #ifdef DEBUG |
2793 // Print the active semispace. | 2833 // Print the active semispace. |
2794 void Print() override { to_space_.Print(); } | 2834 void Print() override { to_space_.Print(); } |
2795 #endif | 2835 #endif |
(...skipping 23 matching lines...) Expand all Loading... | |
2819 } | 2859 } |
2820 | 2860 |
2821 bool IsFromSpaceCommitted() { return from_space_.is_committed(); } | 2861 bool IsFromSpaceCommitted() { return from_space_.is_committed(); } |
2822 | 2862 |
2823 SemiSpace* active_space() { return &to_space_; } | 2863 SemiSpace* active_space() { return &to_space_; } |
2824 | 2864 |
2825 private: | 2865 private: |
2826 // Update allocation info to match the current to-space page. | 2866 // Update allocation info to match the current to-space page. |
2827 void UpdateAllocationInfo(); | 2867 void UpdateAllocationInfo(); |
2828 | 2868 |
2869 base::Mutex mutex_; | |
2870 | |
2829 Address chunk_base_; | 2871 Address chunk_base_; |
2830 uintptr_t chunk_size_; | 2872 uintptr_t chunk_size_; |
2831 | 2873 |
2832 // The semispaces. | 2874 // The semispaces. |
2833 SemiSpace to_space_; | 2875 SemiSpace to_space_; |
2834 SemiSpace from_space_; | 2876 SemiSpace from_space_; |
2835 base::VirtualMemory reservation_; | 2877 base::VirtualMemory reservation_; |
2836 int pages_used_; | 2878 int pages_used_; |
2837 | 2879 |
2838 // Start address and bit mask for containment testing. | 2880 // Start address and bit mask for containment testing. |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3148 count = 0; | 3190 count = 0; |
3149 } | 3191 } |
3150 // Must be small, since an iteration is used for lookup. | 3192 // Must be small, since an iteration is used for lookup. |
3151 static const int kMaxComments = 64; | 3193 static const int kMaxComments = 64; |
3152 }; | 3194 }; |
3153 #endif | 3195 #endif |
3154 } // namespace internal | 3196 } // namespace internal |
3155 } // namespace v8 | 3197 } // namespace v8 |
3156 | 3198 |
3157 #endif // V8_HEAP_SPACES_H_ | 3199 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |