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

Side by Side Diff: src/gpu/GrMemoryPool.h

Issue 2525773002: Make GrMemoryPool play nice with bucketing allocators. (Closed)
Patch Set: Proper naming; kill friend Created 4 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 | « no previous file | src/gpu/GrMemoryPool.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef GrMemoryPool_DEFINED 8 #ifndef GrMemoryPool_DEFINED
9 #define GrMemoryPool_DEFINED 9 #define GrMemoryPool_DEFINED
10 10
11 #include "GrTypes.h" 11 #include "GrTypes.h"
12 12
13 /** 13 /**
14 * Allocates memory in blocks and parcels out space in the blocks for allocation 14 * Allocates memory in blocks and parcels out space in the blocks for allocation
15 * requests. It is optimized for allocate / release speed over memory 15 * requests. It is optimized for allocate / release speed over memory
16 * effeciency. The interface is designed to be used to implement operator new 16 * efficiency. The interface is designed to be used to implement operator new
17 * and delete overrides. All allocations are expected to be released before the 17 * and delete overrides. All allocations are expected to be released before the
18 * pool's destructor is called. Allocations will be 8-byte aligned. 18 * pool's destructor is called. Allocations will be 8-byte aligned.
19 */ 19 */
20 class GrMemoryPool { 20 class GrMemoryPool {
21 public: 21 public:
22 /** 22 /**
23 * Prealloc size is the amount of space to make available at pool creation 23 * Prealloc size is the amount of space to allocate at pool creation
24 * time and keep around until pool destruction. The min alloc size is the 24 * time and keep around until pool destruction. The min alloc size is
25 * smallest allowed size of additional allocations. 25 * the smallest allowed size of additional allocations. Both sizes are
26 * adjusted to ensure that:
27 * 1. they are are 8-byte aligned
herb_g 2016/11/29 18:31:14 Generally , 8-byte alignment is not enough. You sh
28 * 2. minAllocSize >= kSmallestMinAllocSize
29 * 3. preallocSize >= minAllocSize
30 *
31 * Both sizes is what the pool will end up allocating from the system, and
32 * portions of the allocated memory is used for internal bookkeeping.
26 */ 33 */
27 GrMemoryPool(size_t preallocSize, size_t minAllocSize); 34 GrMemoryPool(size_t preallocSize, size_t minAllocSize);
28 35
29 ~GrMemoryPool(); 36 ~GrMemoryPool();
30 37
31 /** 38 /**
32 * Allocates memory. The memory must be freed with release(). 39 * Allocates memory. The memory must be freed with release().
33 */ 40 */
34 void* allocate(size_t size); 41 void* allocate(size_t size);
35 42
36 /** 43 /**
37 * p must have been returned by allocate() 44 * p must have been returned by allocate()
38 */ 45 */
39 void release(void* p); 46 void release(void* p);
40 47
41 /** 48 /**
42 * Returns true if there are no unreleased allocations. 49 * Returns true if there are no unreleased allocations.
43 */ 50 */
44 bool isEmpty() const { return fTail == fHead && !fHead->fLiveCount; } 51 bool isEmpty() const { return fTail == fHead && !fHead->fLiveCount; }
45 52
46 /** 53 /**
47 * Returns the total allocated size of the GrMemoryPool minus any preallocat ed amount 54 * Returns the total allocated size of the GrMemoryPool minus any preallocat ed amount
48 */ 55 */
49 size_t size() const { return fSize; } 56 size_t size() const { return fSize; }
50 57
58 /**
59 * Returns the preallocated size of the GrMemoryPool
60 */
61 size_t preallocSize() const { return fHead->fSize; }
62
63 /**
64 * Minimum value of minAllocSize constructor argument.
65 */
66 constexpr static size_t kSmallestMinAllocSize = 1 << 10;
67
51 private: 68 private:
52 struct BlockHeader; 69 struct BlockHeader;
53 70
54 static BlockHeader* CreateBlock(size_t size); 71 static BlockHeader* CreateBlock(size_t size);
55 72
56 static void DeleteBlock(BlockHeader* block); 73 static void DeleteBlock(BlockHeader* block);
57 74
58 void validate(); 75 void validate();
59 76
60 struct BlockHeader { 77 struct BlockHeader {
(...skipping 13 matching lines...) Expand all
74 static const uint32_t kAssignedMarker = 0xCDCDCDCD; 91 static const uint32_t kAssignedMarker = 0xCDCDCDCD;
75 static const uint32_t kFreedMarker = 0xEFEFEFEF; 92 static const uint32_t kFreedMarker = 0xEFEFEFEF;
76 93
77 struct AllocHeader { 94 struct AllocHeader {
78 #ifdef SK_DEBUG 95 #ifdef SK_DEBUG
79 uint32_t fSentinal; ///< known value to check for memory stomping ( e.g., (CD)*) 96 uint32_t fSentinal; ///< known value to check for memory stomping ( e.g., (CD)*)
80 #endif 97 #endif
81 BlockHeader* fHeader; ///< pointer back to the block header in which an alloc resides 98 BlockHeader* fHeader; ///< pointer back to the block header in which an alloc resides
82 }; 99 };
83 100
84 enum {
85 // We assume this alignment is good enough for everybody.
86 kAlignment = 8,
87 kHeaderSize = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment),
88 kPerAllocPad = GR_CT_ALIGN_UP(sizeof(AllocHeader), kAlignment),
89 };
90 size_t fSize; 101 size_t fSize;
91 size_t fPreallocSize;
92 size_t fMinAllocSize; 102 size_t fMinAllocSize;
93 BlockHeader* fHead; 103 BlockHeader* fHead;
94 BlockHeader* fTail; 104 BlockHeader* fTail;
95 #ifdef SK_DEBUG 105 #ifdef SK_DEBUG
96 int fAllocationCnt; 106 int fAllocationCnt;
97 int fAllocBlockCnt; 107 int fAllocBlockCnt;
98 #endif 108 #endif
109
110 protected:
111 enum {
112 // We assume this alignment is good enough for everybody.
113 kAlignment = 8,
114 kHeaderSize = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment),
115 kPerAllocPad = GR_CT_ALIGN_UP(sizeof(AllocHeader), kAlignment),
116 };
99 }; 117 };
100 118
119 /**
120 * Variant of GrMemoryPool that can only allocate objects of a single type. It i s
121 * not as flexible as GrMemoryPool, but it has more convenient allocate() method ,
122 * and more importantly, it guarantees number of objects that are preallocated a t
123 * construction or when adding a new memory block. I.e.
124 *
125 * GrMemoryPool pool(3 * sizeof(T), 1000 * sizeof(T));
126 * pool.allocate(sizeof(T));
127 * pool.allocate(sizeof(T));
128 * pool.allocate(sizeof(T));
129 *
130 * will preallocate 3 * sizeof(T) bytes and use some of those bytes for internal
131 * structures. Because of that, last allocate() call will end up allocating a ne w
132 * block of 1000 * sizeof(T) bytes. In contrast,
133 *
134 * GrObjectMemoryPool<T> pool(3, 1000);
135 * pool.allocate();
136 * pool.allocate();
137 * pool.allocate();
138 *
139 * guarantees to preallocate enough memory for 3 objects of sizeof(T), so last
140 * allocate() will use preallocated memory and won't cause allocation of a new b lock.
141 *
142 * Same thing is true for the second (minAlloc) ctor argument: this class guaran tees
143 * that a newly added block will have enough space for 1000 objects of sizeof(T) , while
144 * GrMemoryPool does not.
145 */
146 template <class T>
147 class GrObjectMemoryPool: public GrMemoryPool {
148 public:
149 /**
150 * Preallocates memory for preallocCount objects, and sets new block size to be
151 * enough to hold minAllocCount objects.
152 */
153 GrObjectMemoryPool(size_t preallocCount, size_t minAllocCount)
154 : GrMemoryPool(CountToSize(preallocCount),
155 CountToSize(SkTMax(minAllocCount, kSmallestMinAllocCount) )) {
156 }
157
158 /**
159 * Allocates memory for an object, but doesn't construct or otherwise initia lize it.
160 * The memory must be freed with release().
161 */
162 T* allocate() { return static_cast<T*>(GrMemoryPool::allocate(sizeof(T))); }
herb_g 2016/11/29 18:31:14 I think this is a very dangerous API. It is not RA
163
164 private:
165 constexpr static size_t kTotalObjectSize =
166 kPerAllocPad + GR_CT_ALIGN_UP(sizeof(T), kAlignment);
167
168 constexpr static size_t CountToSize(size_t count) {
169 return kHeaderSize + count * kTotalObjectSize;
170 }
171
172 public:
173 /**
174 * Minimum value of minAllocCount constructor argument.
175 */
176 constexpr static size_t kSmallestMinAllocCount =
177 (GrMemoryPool::kSmallestMinAllocSize - kHeaderSize + kTotalObjectSize - 1) /
178 kTotalObjectSize;
179 };
180
181 template <class T>
182 constexpr size_t GrObjectMemoryPool<T>::kSmallestMinAllocCount;
183
101 #endif 184 #endif
OLDNEW
« no previous file with comments | « no previous file | src/gpu/GrMemoryPool.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698