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 1454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 | 1465 |
1466 | 1466 |
1467 // ----------------------------------------------------------------------------- | 1467 // ----------------------------------------------------------------------------- |
1468 // A space has a circular list of pages. The next page can be accessed via | 1468 // A space has a circular list of pages. The next page can be accessed via |
1469 // Page::next_page() call. | 1469 // Page::next_page() call. |
1470 | 1470 |
1471 // An abstraction of allocation and relocation pointers in a page-structured | 1471 // An abstraction of allocation and relocation pointers in a page-structured |
1472 // space. | 1472 // space. |
1473 class AllocationInfo { | 1473 class AllocationInfo { |
1474 public: | 1474 public: |
1475 AllocationInfo() : top_(NULL), limit_(NULL) {} | 1475 AllocationInfo() : top_(nullptr), limit_(nullptr) {} |
| 1476 AllocationInfo(Address top, Address limit) : top_(top), limit_(limit) {} |
| 1477 |
| 1478 void Reset(Address top, Address limit) { |
| 1479 set_top(top); |
| 1480 set_limit(limit); |
| 1481 } |
1476 | 1482 |
1477 INLINE(void set_top(Address top)) { | 1483 INLINE(void set_top(Address top)) { |
1478 SLOW_DCHECK(top == NULL || | 1484 SLOW_DCHECK(top == NULL || |
1479 (reinterpret_cast<intptr_t>(top) & kHeapObjectTagMask) == 0); | 1485 (reinterpret_cast<intptr_t>(top) & kHeapObjectTagMask) == 0); |
1480 top_ = top; | 1486 top_ = top; |
1481 } | 1487 } |
1482 | 1488 |
1483 INLINE(Address top()) const { | 1489 INLINE(Address top()) const { |
1484 SLOW_DCHECK(top_ == NULL || | 1490 SLOW_DCHECK(top_ == NULL || |
1485 (reinterpret_cast<intptr_t>(top_) & kHeapObjectTagMask) == 0); | 1491 (reinterpret_cast<intptr_t>(top_) & kHeapObjectTagMask) == 0); |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1862 explicit AllocationResult(AllocationSpace space) | 1868 explicit AllocationResult(AllocationSpace space) |
1863 : object_(Smi::FromInt(static_cast<int>(space))) {} | 1869 : object_(Smi::FromInt(static_cast<int>(space))) {} |
1864 | 1870 |
1865 Object* object_; | 1871 Object* object_; |
1866 }; | 1872 }; |
1867 | 1873 |
1868 | 1874 |
1869 STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize); | 1875 STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize); |
1870 | 1876 |
1871 | 1877 |
| 1878 class LocalAllocationBuffer { |
| 1879 public: |
| 1880 static inline LocalAllocationBuffer InvalidBuffer(); |
| 1881 static inline LocalAllocationBuffer FromResult(Heap* heap, |
| 1882 AllocationResult result, |
| 1883 intptr_t size); |
| 1884 |
| 1885 ~LocalAllocationBuffer() { Close(); } |
| 1886 |
| 1887 // Convert to C++11 move-semantics once allowed by the style guide. |
| 1888 LocalAllocationBuffer(const LocalAllocationBuffer& other); |
| 1889 LocalAllocationBuffer& operator=(const LocalAllocationBuffer& other); |
| 1890 |
| 1891 MUST_USE_RESULT inline AllocationResult AllocateRawAligned( |
| 1892 int size_in_bytes, AllocationAlignment alignment); |
| 1893 |
| 1894 inline bool IsValid() { return allocation_info_.top() != nullptr; } |
| 1895 |
| 1896 private: |
| 1897 LocalAllocationBuffer(Heap* heap, AllocationInfo allocation_info); |
| 1898 |
| 1899 void Close(); |
| 1900 |
| 1901 Heap* heap_; |
| 1902 AllocationInfo allocation_info_; |
| 1903 }; |
| 1904 |
| 1905 |
1872 class PagedSpace : public Space { | 1906 class PagedSpace : public Space { |
1873 public: | 1907 public: |
1874 static const intptr_t kCompactionMemoryWanted = 500 * KB; | 1908 static const intptr_t kCompactionMemoryWanted = 500 * KB; |
1875 | 1909 |
1876 // Creates a space with an id. | 1910 // Creates a space with an id. |
1877 PagedSpace(Heap* heap, AllocationSpace id, Executability executable); | 1911 PagedSpace(Heap* heap, AllocationSpace id, Executability executable); |
1878 | 1912 |
1879 ~PagedSpace() override { TearDown(); } | 1913 ~PagedSpace() override { TearDown(); } |
1880 | 1914 |
1881 // Set up the space using the given address range of virtual memory (from | 1915 // 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... |
1992 return size_in_bytes - wasted; | 2026 return size_in_bytes - wasted; |
1993 } | 2027 } |
1994 | 2028 |
1995 void ResetFreeList() { free_list_.Reset(); } | 2029 void ResetFreeList() { free_list_.Reset(); } |
1996 | 2030 |
1997 // Set space allocation info. | 2031 // Set space allocation info. |
1998 void SetTopAndLimit(Address top, Address limit) { | 2032 void SetTopAndLimit(Address top, Address limit) { |
1999 DCHECK(top == limit || | 2033 DCHECK(top == limit || |
2000 Page::FromAddress(top) == Page::FromAddress(limit - 1)); | 2034 Page::FromAddress(top) == Page::FromAddress(limit - 1)); |
2001 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); | 2035 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); |
2002 allocation_info_.set_top(top); | 2036 allocation_info_.Reset(top, limit); |
2003 allocation_info_.set_limit(limit); | |
2004 } | 2037 } |
2005 | 2038 |
2006 // Empty space allocation info, returning unused area to free list. | 2039 // Empty space allocation info, returning unused area to free list. |
2007 void EmptyAllocationInfo() { | 2040 void EmptyAllocationInfo() { |
2008 // Mark the old linear allocation area with a free space map so it can be | 2041 // Mark the old linear allocation area with a free space map so it can be |
2009 // skipped when scanning the heap. | 2042 // skipped when scanning the heap. |
2010 int old_linear_size = static_cast<int>(limit() - top()); | 2043 int old_linear_size = static_cast<int>(limit() - top()); |
2011 Free(top(), old_linear_size); | 2044 Free(top(), old_linear_size); |
2012 SetTopAndLimit(NULL, NULL); | 2045 SetTopAndLimit(NULL, NULL); |
2013 } | 2046 } |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2734 | 2767 |
2735 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( | 2768 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( |
2736 int size_in_bytes, AllocationAlignment alignment)); | 2769 int size_in_bytes, AllocationAlignment alignment)); |
2737 | 2770 |
2738 MUST_USE_RESULT INLINE( | 2771 MUST_USE_RESULT INLINE( |
2739 AllocationResult AllocateRawUnaligned(int size_in_bytes)); | 2772 AllocationResult AllocateRawUnaligned(int size_in_bytes)); |
2740 | 2773 |
2741 MUST_USE_RESULT INLINE(AllocationResult AllocateRaw( | 2774 MUST_USE_RESULT INLINE(AllocationResult AllocateRaw( |
2742 int size_in_bytes, AllocationAlignment alignment)); | 2775 int size_in_bytes, AllocationAlignment alignment)); |
2743 | 2776 |
| 2777 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized( |
| 2778 int size_in_bytes, AllocationAlignment alignment); |
| 2779 |
2744 // Reset the allocation pointer to the beginning of the active semispace. | 2780 // Reset the allocation pointer to the beginning of the active semispace. |
2745 void ResetAllocationInfo(); | 2781 void ResetAllocationInfo(); |
2746 | 2782 |
2747 void UpdateInlineAllocationLimit(int size_in_bytes); | 2783 void UpdateInlineAllocationLimit(int size_in_bytes); |
2748 | 2784 |
2749 // Allows observation of inline allocation. The observer->Step() method gets | 2785 // Allows observation of inline allocation. The observer->Step() method gets |
2750 // called after every step_size bytes have been allocated (approximately). | 2786 // called after every step_size bytes have been allocated (approximately). |
2751 // This works by adjusting the allocation limit to a lower value and adjusting | 2787 // This works by adjusting the allocation limit to a lower value and adjusting |
2752 // it after each step. | 2788 // it after each step. |
2753 void AddInlineAllocationObserver(InlineAllocationObserver* observer); | 2789 void AddInlineAllocationObserver(InlineAllocationObserver* observer); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2786 // respective semispace (not necessarily below the allocation pointer of the | 2822 // respective semispace (not necessarily below the allocation pointer of the |
2787 // semispace). | 2823 // semispace). |
2788 inline bool ToSpaceContains(Object* o) { return to_space_.Contains(o); } | 2824 inline bool ToSpaceContains(Object* o) { return to_space_.Contains(o); } |
2789 inline bool FromSpaceContains(Object* o) { return from_space_.Contains(o); } | 2825 inline bool FromSpaceContains(Object* o) { return from_space_.Contains(o); } |
2790 | 2826 |
2791 // Try to switch the active semispace to a new, empty, page. | 2827 // Try to switch the active semispace to a new, empty, page. |
2792 // Returns false if this isn't possible or reasonable (i.e., there | 2828 // Returns false if this isn't possible or reasonable (i.e., there |
2793 // are no pages, or the current page is already empty), or true | 2829 // are no pages, or the current page is already empty), or true |
2794 // if successful. | 2830 // if successful. |
2795 bool AddFreshPage(); | 2831 bool AddFreshPage(); |
| 2832 bool AddFreshPageSynchronized(); |
2796 | 2833 |
2797 #ifdef VERIFY_HEAP | 2834 #ifdef VERIFY_HEAP |
2798 // Verify the active semispace. | 2835 // Verify the active semispace. |
2799 virtual void Verify(); | 2836 virtual void Verify(); |
2800 #endif | 2837 #endif |
2801 | 2838 |
2802 #ifdef DEBUG | 2839 #ifdef DEBUG |
2803 // Print the active semispace. | 2840 // Print the active semispace. |
2804 void Print() override { to_space_.Print(); } | 2841 void Print() override { to_space_.Print(); } |
2805 #endif | 2842 #endif |
(...skipping 23 matching lines...) Expand all Loading... |
2829 } | 2866 } |
2830 | 2867 |
2831 bool IsFromSpaceCommitted() { return from_space_.is_committed(); } | 2868 bool IsFromSpaceCommitted() { return from_space_.is_committed(); } |
2832 | 2869 |
2833 SemiSpace* active_space() { return &to_space_; } | 2870 SemiSpace* active_space() { return &to_space_; } |
2834 | 2871 |
2835 private: | 2872 private: |
2836 // Update allocation info to match the current to-space page. | 2873 // Update allocation info to match the current to-space page. |
2837 void UpdateAllocationInfo(); | 2874 void UpdateAllocationInfo(); |
2838 | 2875 |
| 2876 base::Mutex mutex_; |
| 2877 |
2839 Address chunk_base_; | 2878 Address chunk_base_; |
2840 uintptr_t chunk_size_; | 2879 uintptr_t chunk_size_; |
2841 | 2880 |
2842 // The semispaces. | 2881 // The semispaces. |
2843 SemiSpace to_space_; | 2882 SemiSpace to_space_; |
2844 SemiSpace from_space_; | 2883 SemiSpace from_space_; |
2845 base::VirtualMemory reservation_; | 2884 base::VirtualMemory reservation_; |
2846 int pages_used_; | 2885 int pages_used_; |
2847 | 2886 |
2848 // Start address and bit mask for containment testing. | 2887 // Start address and bit mask for containment testing. |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3140 count = 0; | 3179 count = 0; |
3141 } | 3180 } |
3142 // Must be small, since an iteration is used for lookup. | 3181 // Must be small, since an iteration is used for lookup. |
3143 static const int kMaxComments = 64; | 3182 static const int kMaxComments = 64; |
3144 }; | 3183 }; |
3145 #endif | 3184 #endif |
3146 } // namespace internal | 3185 } // namespace internal |
3147 } // namespace v8 | 3186 } // namespace v8 |
3148 | 3187 |
3149 #endif // V8_HEAP_SPACES_H_ | 3188 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |