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

Side by Side Diff: include/private/SkTemplates.h

Issue 1656143003: Move Google3-specific stack limitation logic to template classes. Remove #ifdefs in other files. (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Rename constants, update documentation. Created 4 years, 10 months 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 | « include/core/SkTypes.h ('k') | src/gpu/GrContext.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 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #ifndef SkTemplates_DEFINED 10 #ifndef SkTemplates_DEFINED
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 void swap(SkAutoTArray& other) { 157 void swap(SkAutoTArray& other) {
158 SkTSwap(fArray, other.fArray); 158 SkTSwap(fArray, other.fArray);
159 SkDEBUGCODE(SkTSwap(fCount, other.fCount)); 159 SkDEBUGCODE(SkTSwap(fCount, other.fCount));
160 } 160 }
161 161
162 private: 162 private:
163 T* fArray; 163 T* fArray;
164 SkDEBUGCODE(int fCount;) 164 SkDEBUGCODE(int fCount;)
165 }; 165 };
166 166
167 /** Wraps SkAutoTArray, with room for up to N elements preallocated 167 /** Wraps SkAutoTArray, with room for kCountRequested elements preallocated.
168 */ 168 */
169 template <int N, typename T> class SkAutoSTArray : SkNoncopyable { 169 template <int kCountRequested, typename T> class SkAutoSTArray : SkNoncopyable {
170 public: 170 public:
171 /** Initialize with no objects */ 171 /** Initialize with no objects */
172 SkAutoSTArray() { 172 SkAutoSTArray() {
173 fArray = NULL; 173 fArray = NULL;
174 fCount = 0; 174 fCount = 0;
175 } 175 }
176 176
177 /** Allocate count number of T elements 177 /** Allocate count number of T elements
178 */ 178 */
179 SkAutoSTArray(int count) { 179 SkAutoSTArray(int count) {
180 fArray = NULL; 180 fArray = NULL;
181 fCount = 0; 181 fCount = 0;
182 this->reset(count); 182 this->reset(count);
183 } 183 }
184 184
185 ~SkAutoSTArray() { 185 ~SkAutoSTArray() {
186 this->reset(0); 186 this->reset(0);
187 } 187 }
188 188
189 /** Destroys previous objects in the array and default constructs count numb er of objects */ 189 /** Destroys previous objects in the array and default constructs count numb er of objects */
190 void reset(int count) { 190 void reset(int count) {
191 T* start = fArray; 191 T* start = fArray;
192 T* iter = start + fCount; 192 T* iter = start + fCount;
193 while (iter > start) { 193 while (iter > start) {
194 (--iter)->~T(); 194 (--iter)->~T();
195 } 195 }
196 196
197 if (fCount != count) { 197 if (fCount != count) {
198 if (fCount > N) { 198 if (fCount > kCount) {
199 // 'fArray' was allocated last time so free it now 199 // 'fArray' was allocated last time so free it now
200 SkASSERT((T*) fStorage != fArray); 200 SkASSERT((T*) fStorage != fArray);
201 sk_free(fArray); 201 sk_free(fArray);
202 } 202 }
203 203
204 if (count > N) { 204 if (count > kCount) {
205 const uint64_t size64 = sk_64_mul(count, sizeof(T)); 205 const uint64_t size64 = sk_64_mul(count, sizeof(T));
206 const size_t size = static_cast<size_t>(size64); 206 const size_t size = static_cast<size_t>(size64);
207 if (size != size64) { 207 if (size != size64) {
208 sk_out_of_memory(); 208 sk_out_of_memory();
209 } 209 }
210 fArray = (T*) sk_malloc_throw(size); 210 fArray = (T*) sk_malloc_throw(size);
211 } else if (count > 0) { 211 } else if (count > 0) {
212 fArray = (T*) fStorage; 212 fArray = (T*) fStorage;
213 } else { 213 } else {
214 fArray = NULL; 214 fArray = NULL;
(...skipping 18 matching lines...) Expand all
233 T* get() const { return fArray; } 233 T* get() const { return fArray; }
234 234
235 /** Return the nth element in the array 235 /** Return the nth element in the array
236 */ 236 */
237 T& operator[](int index) const { 237 T& operator[](int index) const {
238 SkASSERT(index < fCount); 238 SkASSERT(index < fCount);
239 return fArray[index]; 239 return fArray[index];
240 } 240 }
241 241
242 private: 242 private:
243 #if defined(GOOGLE3)
244 // Stack frame size is limited for GOOGLE3. 4k is less than the actual max, but some functions
245 // have multiple large stack allocations.
246 static const int kMaxBytes = 4 * 1024;
247 static const int kCount = kCountRequested * sizeof(T) > kMaxBytes
248 ? kMaxBytes / sizeof(T)
249 : kCountRequested;
250 #else
251 static const int kCount = kCountRequested;
252 #endif
253
243 int fCount; 254 int fCount;
244 T* fArray; 255 T* fArray;
245 // since we come right after fArray, fStorage should be properly aligned 256 // since we come right after fArray, fStorage should be properly aligned
246 char fStorage[N * sizeof(T)]; 257 char fStorage[kCount * sizeof(T)];
247 }; 258 };
248 259
249 /** Manages an array of T elements, freeing the array in the destructor. 260 /** Manages an array of T elements, freeing the array in the destructor.
250 * Does NOT call any constructors/destructors on T (T must be POD). 261 * Does NOT call any constructors/destructors on T (T must be POD).
251 */ 262 */
252 template <typename T> class SkAutoTMalloc : SkNoncopyable { 263 template <typename T> class SkAutoTMalloc : SkNoncopyable {
253 public: 264 public:
254 /** Takes ownership of the ptr. The ptr must be a value which can be passed to sk_free. */ 265 /** Takes ownership of the ptr. The ptr must be a value which can be passed to sk_free. */
255 explicit SkAutoTMalloc(T* ptr = NULL) { 266 explicit SkAutoTMalloc(T* ptr = NULL) {
256 fPtr = ptr; 267 fPtr = ptr;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 T* detach() { 321 T* detach() {
311 T* ptr = fPtr; 322 T* ptr = fPtr;
312 fPtr = NULL; 323 fPtr = NULL;
313 return ptr; 324 return ptr;
314 } 325 }
315 326
316 private: 327 private:
317 T* fPtr; 328 T* fPtr;
318 }; 329 };
319 330
320 template <size_t N, typename T> class SkAutoSTMalloc : SkNoncopyable { 331 template <size_t kCountRequested, typename T> class SkAutoSTMalloc : SkNoncopyab le {
321 public: 332 public:
322 SkAutoSTMalloc() : fPtr(fTStorage) {} 333 SkAutoSTMalloc() : fPtr(fTStorage) {}
323 334
324 SkAutoSTMalloc(size_t count) { 335 SkAutoSTMalloc(size_t count) {
325 if (count > N) { 336 if (count > kCount) {
326 fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_M ALLOC_TEMP); 337 fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_M ALLOC_TEMP);
327 } else { 338 } else {
328 fPtr = fTStorage; 339 fPtr = fTStorage;
329 } 340 }
330 } 341 }
331 342
332 ~SkAutoSTMalloc() { 343 ~SkAutoSTMalloc() {
333 if (fPtr != fTStorage) { 344 if (fPtr != fTStorage) {
334 sk_free(fPtr); 345 sk_free(fPtr);
335 } 346 }
336 } 347 }
337 348
338 // doesn't preserve contents 349 // doesn't preserve contents
339 T* reset(size_t count) { 350 T* reset(size_t count) {
340 if (fPtr != fTStorage) { 351 if (fPtr != fTStorage) {
341 sk_free(fPtr); 352 sk_free(fPtr);
342 } 353 }
343 if (count > N) { 354 if (count > kCount) {
344 fPtr = (T*)sk_malloc_throw(count * sizeof(T)); 355 fPtr = (T*)sk_malloc_throw(count * sizeof(T));
345 } else { 356 } else {
346 fPtr = fTStorage; 357 fPtr = fTStorage;
347 } 358 }
348 return fPtr; 359 return fPtr;
349 } 360 }
350 361
351 T* get() const { return fPtr; } 362 T* get() const { return fPtr; }
352 363
353 operator T*() { 364 operator T*() {
354 return fPtr; 365 return fPtr;
355 } 366 }
356 367
357 operator const T*() const { 368 operator const T*() const {
358 return fPtr; 369 return fPtr;
359 } 370 }
360 371
361 T& operator[](int index) { 372 T& operator[](int index) {
362 return fPtr[index]; 373 return fPtr[index];
363 } 374 }
364 375
365 const T& operator[](int index) const { 376 const T& operator[](int index) const {
366 return fPtr[index]; 377 return fPtr[index];
367 } 378 }
368 379
369 // Reallocs the array, can be used to shrink the allocation. Makes no attem pt to be intelligent 380 // Reallocs the array, can be used to shrink the allocation. Makes no attem pt to be intelligent
370 void realloc(size_t count) { 381 void realloc(size_t count) {
371 if (count > N) { 382 if (count > kCount) {
372 if (fPtr == fTStorage) { 383 if (fPtr == fTStorage) {
373 fPtr = (T*)sk_malloc_throw(count * sizeof(T)); 384 fPtr = (T*)sk_malloc_throw(count * sizeof(T));
374 memcpy(fPtr, fTStorage, N * sizeof(T)); 385 memcpy(fPtr, fTStorage, kCount * sizeof(T));
375 } else { 386 } else {
376 fPtr = (T*)sk_realloc_throw(fPtr, count * sizeof(T)); 387 fPtr = (T*)sk_realloc_throw(fPtr, count * sizeof(T));
377 } 388 }
378 } else if (fPtr != fTStorage) { 389 } else if (fPtr != fTStorage) {
379 fPtr = (T*)sk_realloc_throw(fPtr, count * sizeof(T)); 390 fPtr = (T*)sk_realloc_throw(fPtr, count * sizeof(T));
380 } 391 }
381 } 392 }
382 393
383 private: 394 private:
395 // Since we use uint32_t storage, we might be able to get more elements for free.
396 static const size_t kCountWithPadding = SkAlign4(kCountRequested*sizeof(T)) / sizeof(T);
397 #if defined(GOOGLE3)
398 // Stack frame size is limited for GOOGLE3. 4k is less than the actual max, but some functions
399 // have multiple large stack allocations.
400 static const size_t kMaxBytes = 4 * 1024;
401 static const size_t kCount = kCountRequested * sizeof(T) > kMaxBytes
402 ? kMaxBytes / sizeof(T)
403 : kCountWithPadding;
404 #else
405 static const size_t kCount = kCountWithPadding;
406 #endif
407
384 T* fPtr; 408 T* fPtr;
385 union { 409 union {
386 uint32_t fStorage32[(N*sizeof(T) + 3) >> 2]; 410 uint32_t fStorage32[SkAlign4(kCount*sizeof(T)) >> 2];
387 T fTStorage[1]; // do NOT want to invoke T::T() 411 T fTStorage[1]; // do NOT want to invoke T::T()
388 }; 412 };
389 }; 413 };
390 414
391 //////////////////////////////////////////////////////////////////////////////// ////////////////// 415 //////////////////////////////////////////////////////////////////////////////// //////////////////
392 416
393 /** 417 /**
394 * Pass the object and the storage that was offered during SkInPlaceNewCheck, a nd this will 418 * Pass the object and the storage that was offered during SkInPlaceNewCheck, a nd this will
395 * safely destroy (and free if it was dynamically allocated) the object. 419 * safely destroy (and free if it was dynamically allocated) the object.
396 */ 420 */
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 * Returns void* because this object does not initialize the 473 * Returns void* because this object does not initialize the
450 * memory. Use placement new for types that require a cons. 474 * memory. Use placement new for types that require a cons.
451 */ 475 */
452 void* get() { return fStorage.get(); } 476 void* get() { return fStorage.get(); }
453 const void* get() const { return fStorage.get(); } 477 const void* get() const { return fStorage.get(); }
454 private: 478 private:
455 SkAlignedSStorage<sizeof(T)*N> fStorage; 479 SkAlignedSStorage<sizeof(T)*N> fStorage;
456 }; 480 };
457 481
458 #endif 482 #endif
OLDNEW
« no previous file with comments | « include/core/SkTypes.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698