Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/heap/spaces.h

Issue 1487853002: [heap] Move to LAB-based allocation for newspace evacuation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added comments describing LocalAllocationBuffer Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/spaces.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 // LocalAllocationBuffer represents a linear allocation area that is created
1879 // from a given {AllocationResult} and can be used to allocate memory without
1880 // synchronization.
1881 //
1882 // The buffer is properly closed upon destruction and reassignment.
1883 // Example:
1884 // {
1885 // AllocationResult result = ...;
1886 // LocalAllocationBuffer a(heap, result, size);
1887 // LocalAllocationBuffer b = a;
1888 // CHECK(!a.IsValid());
1889 // CHECK(b.IsValid());
1890 // // {a} is invalid now and cannot be used for further allocations.
1891 // }
1892 // // Since {b} went out of scope, the LAB is closed, resulting in creating a
1893 // // filler object for the remaining area.
1894 class LocalAllocationBuffer {
1895 public:
1896 // Indicates that a buffer cannot be used for allocations anymore. Can result
1897 // from either reassigning a buffer, or trying to construct it from an
1898 // invalid {AllocationResult}.
1899 static inline LocalAllocationBuffer InvalidBuffer();
1900
1901 // Creates a new LAB from a given {AllocationResult}. Results in
1902 // InvalidBuffer if the result indicates a retry.
1903 static inline LocalAllocationBuffer FromResult(Heap* heap,
1904 AllocationResult result,
1905 intptr_t size);
1906
1907 ~LocalAllocationBuffer() { Close(); }
1908
1909 // Convert to C++11 move-semantics once allowed by the style guide.
1910 LocalAllocationBuffer(const LocalAllocationBuffer& other);
1911 LocalAllocationBuffer& operator=(const LocalAllocationBuffer& other);
1912
1913 MUST_USE_RESULT inline AllocationResult AllocateRawAligned(
1914 int size_in_bytes, AllocationAlignment alignment);
1915
1916 inline bool IsValid() { return allocation_info_.top() != nullptr; }
1917
1918 // Try to merge LABs, which is only possible when they are adjacent in memory.
1919 // Returns true if the merge was successful, false otherwise.
1920 inline bool TryMerge(LocalAllocationBuffer* other);
1921
1922 private:
1923 LocalAllocationBuffer(Heap* heap, AllocationInfo allocation_info);
1924
1925 void Close();
1926
1927 Heap* heap_;
1928 AllocationInfo allocation_info_;
1929 };
1930
1931
1872 class PagedSpace : public Space { 1932 class PagedSpace : public Space {
1873 public: 1933 public:
1874 static const intptr_t kCompactionMemoryWanted = 500 * KB; 1934 static const intptr_t kCompactionMemoryWanted = 500 * KB;
1875 1935
1876 // Creates a space with an id. 1936 // Creates a space with an id.
1877 PagedSpace(Heap* heap, AllocationSpace id, Executability executable); 1937 PagedSpace(Heap* heap, AllocationSpace id, Executability executable);
1878 1938
1879 ~PagedSpace() override { TearDown(); } 1939 ~PagedSpace() override { TearDown(); }
1880 1940
1881 // Set up the space using the given address range of virtual memory (from 1941 // 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
1992 return size_in_bytes - wasted; 2052 return size_in_bytes - wasted;
1993 } 2053 }
1994 2054
1995 void ResetFreeList() { free_list_.Reset(); } 2055 void ResetFreeList() { free_list_.Reset(); }
1996 2056
1997 // Set space allocation info. 2057 // Set space allocation info.
1998 void SetTopAndLimit(Address top, Address limit) { 2058 void SetTopAndLimit(Address top, Address limit) {
1999 DCHECK(top == limit || 2059 DCHECK(top == limit ||
2000 Page::FromAddress(top) == Page::FromAddress(limit - 1)); 2060 Page::FromAddress(top) == Page::FromAddress(limit - 1));
2001 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); 2061 MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
2002 allocation_info_.set_top(top); 2062 allocation_info_.Reset(top, limit);
2003 allocation_info_.set_limit(limit);
2004 } 2063 }
2005 2064
2006 // Empty space allocation info, returning unused area to free list. 2065 // Empty space allocation info, returning unused area to free list.
2007 void EmptyAllocationInfo() { 2066 void EmptyAllocationInfo() {
2008 // Mark the old linear allocation area with a free space map so it can be 2067 // Mark the old linear allocation area with a free space map so it can be
2009 // skipped when scanning the heap. 2068 // skipped when scanning the heap.
2010 int old_linear_size = static_cast<int>(limit() - top()); 2069 int old_linear_size = static_cast<int>(limit() - top());
2011 Free(top(), old_linear_size); 2070 Free(top(), old_linear_size);
2012 SetTopAndLimit(NULL, NULL); 2071 SetTopAndLimit(NULL, NULL);
2013 } 2072 }
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
2734 2793
2735 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( 2794 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned(
2736 int size_in_bytes, AllocationAlignment alignment)); 2795 int size_in_bytes, AllocationAlignment alignment));
2737 2796
2738 MUST_USE_RESULT INLINE( 2797 MUST_USE_RESULT INLINE(
2739 AllocationResult AllocateRawUnaligned(int size_in_bytes)); 2798 AllocationResult AllocateRawUnaligned(int size_in_bytes));
2740 2799
2741 MUST_USE_RESULT INLINE(AllocationResult AllocateRaw( 2800 MUST_USE_RESULT INLINE(AllocationResult AllocateRaw(
2742 int size_in_bytes, AllocationAlignment alignment)); 2801 int size_in_bytes, AllocationAlignment alignment));
2743 2802
2803 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized(
2804 int size_in_bytes, AllocationAlignment alignment);
2805
2744 // Reset the allocation pointer to the beginning of the active semispace. 2806 // Reset the allocation pointer to the beginning of the active semispace.
2745 void ResetAllocationInfo(); 2807 void ResetAllocationInfo();
2746 2808
2747 void UpdateInlineAllocationLimit(int size_in_bytes); 2809 void UpdateInlineAllocationLimit(int size_in_bytes);
2748 2810
2749 // Allows observation of inline allocation. The observer->Step() method gets 2811 // Allows observation of inline allocation. The observer->Step() method gets
2750 // called after every step_size bytes have been allocated (approximately). 2812 // called after every step_size bytes have been allocated (approximately).
2751 // This works by adjusting the allocation limit to a lower value and adjusting 2813 // This works by adjusting the allocation limit to a lower value and adjusting
2752 // it after each step. 2814 // it after each step.
2753 void AddInlineAllocationObserver(InlineAllocationObserver* observer); 2815 void AddInlineAllocationObserver(InlineAllocationObserver* observer);
(...skipping 29 matching lines...) Expand all
2783 // respective semispace (not necessarily below the allocation pointer of the 2845 // respective semispace (not necessarily below the allocation pointer of the
2784 // semispace). 2846 // semispace).
2785 inline bool ToSpaceContains(Object* o) { return to_space_.Contains(o); } 2847 inline bool ToSpaceContains(Object* o) { return to_space_.Contains(o); }
2786 inline bool FromSpaceContains(Object* o) { return from_space_.Contains(o); } 2848 inline bool FromSpaceContains(Object* o) { return from_space_.Contains(o); }
2787 2849
2788 // Try to switch the active semispace to a new, empty, page. 2850 // Try to switch the active semispace to a new, empty, page.
2789 // Returns false if this isn't possible or reasonable (i.e., there 2851 // Returns false if this isn't possible or reasonable (i.e., there
2790 // are no pages, or the current page is already empty), or true 2852 // are no pages, or the current page is already empty), or true
2791 // if successful. 2853 // if successful.
2792 bool AddFreshPage(); 2854 bool AddFreshPage();
2855 bool AddFreshPageSynchronized();
2793 2856
2794 #ifdef VERIFY_HEAP 2857 #ifdef VERIFY_HEAP
2795 // Verify the active semispace. 2858 // Verify the active semispace.
2796 virtual void Verify(); 2859 virtual void Verify();
2797 #endif 2860 #endif
2798 2861
2799 #ifdef DEBUG 2862 #ifdef DEBUG
2800 // Print the active semispace. 2863 // Print the active semispace.
2801 void Print() override { to_space_.Print(); } 2864 void Print() override { to_space_.Print(); }
2802 #endif 2865 #endif
(...skipping 23 matching lines...) Expand all
2826 } 2889 }
2827 2890
2828 bool IsFromSpaceCommitted() { return from_space_.is_committed(); } 2891 bool IsFromSpaceCommitted() { return from_space_.is_committed(); }
2829 2892
2830 SemiSpace* active_space() { return &to_space_; } 2893 SemiSpace* active_space() { return &to_space_; }
2831 2894
2832 private: 2895 private:
2833 // Update allocation info to match the current to-space page. 2896 // Update allocation info to match the current to-space page.
2834 void UpdateAllocationInfo(); 2897 void UpdateAllocationInfo();
2835 2898
2899 base::Mutex mutex_;
2900
2836 Address chunk_base_; 2901 Address chunk_base_;
2837 uintptr_t chunk_size_; 2902 uintptr_t chunk_size_;
2838 2903
2839 // The semispaces. 2904 // The semispaces.
2840 SemiSpace to_space_; 2905 SemiSpace to_space_;
2841 SemiSpace from_space_; 2906 SemiSpace from_space_;
2842 base::VirtualMemory reservation_; 2907 base::VirtualMemory reservation_;
2843 int pages_used_; 2908 int pages_used_;
2844 2909
2845 // Start address and bit mask for containment testing. 2910 // Start address and bit mask for containment testing.
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
3155 count = 0; 3220 count = 0;
3156 } 3221 }
3157 // Must be small, since an iteration is used for lookup. 3222 // Must be small, since an iteration is used for lookup.
3158 static const int kMaxComments = 64; 3223 static const int kMaxComments = 64;
3159 }; 3224 };
3160 #endif 3225 #endif
3161 } // namespace internal 3226 } // namespace internal
3162 } // namespace v8 3227 } // namespace v8
3163 3228
3164 #endif // V8_HEAP_SPACES_H_ 3229 #endif // V8_HEAP_SPACES_H_
OLDNEW
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698