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

Side by Side Diff: src/core/SkSmallAllocator.h

Issue 2482683002: Use perfect forwarding in createT of SkSmallAllocator. (Closed)
Patch Set: Created 4 years, 1 month 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/utils/SkTextureCompressor_ASTC.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 2014 Google, Inc 2 * Copyright 2014 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 SkSmallAllocator_DEFINED 8 #ifndef SkSmallAllocator_DEFINED
9 #define SkSmallAllocator_DEFINED 9 #define SkSmallAllocator_DEFINED
10 10
11 #include "SkTDArray.h" 11 #include "SkTDArray.h"
12 #include "SkTypes.h" 12 #include "SkTypes.h"
13 13
14 #include <new> 14 #include <new>
mtklein_C 2016/11/06 13:25:16 Probably a good idea to include <utility>
herb_g 2016/11/07 04:44:40 Done.
15 15
16 /* 16 /*
17 * Template class for allocating small objects without additional heap memory 17 * Template class for allocating small objects without additional heap memory
18 * allocations. kMaxObjects is a hard limit on the number of objects that can 18 * allocations. kMaxObjects is a hard limit on the number of objects that can
19 * be allocated using this class. After that, attempts to create more objects 19 * be allocated using this class. After that, attempts to create more objects
20 * with this class will assert and return nullptr. 20 * with this class will assert and return nullptr.
21 * 21 *
22 * kTotalBytes is the total number of bytes provided for storage for all 22 * kTotalBytes is the total number of bytes provided for storage for all
23 * objects created by this allocator. If an object to be created is larger 23 * objects created by this allocator. If an object to be created is larger
24 * than the storage (minus storage already used), it will be allocated on the 24 * than the storage (minus storage already used), it will be allocated on the
25 * heap. This class's destructor will handle calling the destructor for each 25 * heap. This class's destructor will handle calling the destructor for each
26 * object it allocated and freeing its memory. 26 * object it allocated and freeing its memory.
27 * 27 *
28 * Current the class always aligns each allocation to 16-bytes to be safe, but future 28 * Current the class always aligns each allocation to 16-bytes to be safe, but future
29 * may reduce this to only the alignment that is required per alloc. 29 * may reduce this to only the alignment that is required per alloc.
30 */ 30 */
31 template<uint32_t kMaxObjects, size_t kTotalBytes> 31 template<uint32_t kMaxObjects, size_t kTotalBytes>
32 class SkSmallAllocator : SkNoncopyable { 32 class SkSmallAllocator : SkNoncopyable {
33 public: 33 public:
34 SkSmallAllocator() 34 SkSmallAllocator()
35 : fStorageUsed(0) 35 : fStorageUsed(0)
36 , fNumObjects(0) 36 , fNumObjects(0) { }
37 {}
mtklein_C 2016/11/06 13:25:16 Seems unnecessary?
herb_g 2016/11/07 04:44:40 Done.
38 37
39 ~SkSmallAllocator() { 38 ~SkSmallAllocator() {
40 // Destruct in reverse order, in case an earlier object points to a 39 // Destruct in reverse order, in case an earlier object points to a
41 // later object. 40 // later object.
42 while (fNumObjects > 0) { 41 while (fNumObjects > 0) {
43 fNumObjects--; 42 fNumObjects--;
44 Rec* rec = &fRecs[fNumObjects]; 43 Rec* rec = &fRecs[fNumObjects];
45 rec->fKillProc(rec->fObj); 44 rec->fKillProc(rec->fObj);
46 // Safe to do if fObj is in fStorage, since fHeapStorage will 45 // Safe to do if fObj is in fStorage, since fHeapStorage will
47 // point to nullptr. 46 // point to nullptr.
48 sk_free(rec->fHeapStorage); 47 sk_free(rec->fHeapStorage);
49 } 48 }
50 } 49 }
51 50
52 /* 51 /*
53 * Create a new object of type T. Its lifetime will be handled by this 52 * Create a new object of type T. Its lifetime will be handled by this
54 * SkSmallAllocator. 53 * SkSmallAllocator.
55 * Note: If kMaxObjects have been created by this SkSmallAllocator, nullptr 54 * Note: If kMaxObjects have been created by this SkSmallAllocator, nullptr
56 * will be returned. 55 * will be returned.
57 */ 56 */
58 template<typename T, typename... Args> 57 template<typename T, typename... Args>
59 T* createT(const Args&... args) { 58 T* createT(Args&&... args) {
60 void* buf = this->reserveT<T>(); 59 void* buf = this->reserveT<T>();
61 if (nullptr == buf) { 60 if (nullptr == buf) {
62 return nullptr; 61 return nullptr;
63 } 62 }
64 return new (buf) T(args...); 63 return new (buf) T(std::forward<Args>(args)...);
65 } 64 }
66 65
67 /* 66 /*
68 * Reserve a specified amount of space (must be enough space for one T). 67 * Reserve a specified amount of space (must be enough space for one T).
69 * The space will be in fStorage if there is room, or on the heap otherwise . 68 * The space will be in fStorage if there is room, or on the heap otherwise .
70 * Either way, this class will call ~T() in its destructor and free the hea p 69 * Either way, this class will call ~T() in its destructor and free the hea p
71 * allocation if necessary. 70 * allocation if necessary.
72 * Unlike createT(), this method will not call the constructor of T. 71 * Unlike createT(), this method will not call the constructor of T.
73 */ 72 */
74 template<typename T> void* reserveT(size_t storageRequired = sizeof(T)) { 73 template<typename T> void* reserveT(size_t storageRequired = sizeof(T)) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 void freeLast() { 108 void freeLast() {
110 SkASSERT(fNumObjects > 0); 109 SkASSERT(fNumObjects > 0);
111 Rec* rec = &fRecs[fNumObjects - 1]; 110 Rec* rec = &fRecs[fNumObjects - 1];
112 sk_free(rec->fHeapStorage); 111 sk_free(rec->fHeapStorage);
113 fStorageUsed -= rec->fStorageSize; 112 fStorageUsed -= rec->fStorageSize;
114 113
115 fNumObjects--; 114 fNumObjects--;
116 } 115 }
117 116
118 private: 117 private:
118 static constexpr size_t kAlignment = 16UL;
mtklein_C 2016/11/06 13:25:16 Unused?
herb_g 2016/11/07 04:44:40 Done.
119 struct Rec { 119 struct Rec {
120 size_t fStorageSize; // 0 if allocated on heap 120 size_t fStorageSize; // 0 if allocated on heap
121 void* fObj; 121 void* fObj;
122 void* fHeapStorage; 122 void* fHeapStorage;
123 void (*fKillProc)(void*); 123 void (*fKillProc)(void*);
124 }; 124 };
125 125
126 // Used to call the destructor for allocated objects. 126 // Used to call the destructor for allocated objects.
127 template<typename T> 127 template<typename T>
128 static void DestroyT(void* ptr) { 128 static void DestroyT(void* ptr) {
129 static_cast<T*>(ptr)->~T(); 129 static_cast<T*>(ptr)->~T();
130 } 130 }
131 131
132 alignas(16) char fStorage[kTotalBytes]; 132 alignas(16) char fStorage[kTotalBytes];
133 // Number of bytes used so far. 133 size_t fStorageUsed; // Number of bytes used so far.
134 size_t fStorageUsed; 134 uint32_t fNumObjects;
135 uint32_t fNumObjects; 135 Rec fRecs[kMaxObjects];
136 Rec fRecs[kMaxObjects];
137 }; 136 };
138 137
139 #endif // SkSmallAllocator_DEFINED 138 #endif // SkSmallAllocator_DEFINED
OLDNEW
« no previous file with comments | « no previous file | src/utils/SkTextureCompressor_ASTC.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698