OLD | NEW |
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 SkTypes_DEFINED | 10 #ifndef SkTypes_DEFINED |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 * If the requested size is smaller than the current size, and the | 477 * If the requested size is smaller than the current size, and the |
478 * current block is dynamically allocated, just return the old | 478 * current block is dynamically allocated, just return the old |
479 * block. | 479 * block. |
480 */ | 480 */ |
481 kReuse_OnShrink | 481 kReuse_OnShrink |
482 }; | 482 }; |
483 | 483 |
484 /** | 484 /** |
485 * Reallocates the block to a new size. The ptr may or may not change. | 485 * Reallocates the block to a new size. The ptr may or may not change. |
486 */ | 486 */ |
487 void* reset(size_t size, OnShrink shrink = kAlloc_OnShrink) { | 487 void* reset(size_t size, OnShrink shrink = kAlloc_OnShrink, bool* didChange
Alloc = NULL) { |
488 if (size == fSize || (kReuse_OnShrink == shrink && size < fSize)) { | 488 if (size == fSize || (kReuse_OnShrink == shrink && size < fSize)) { |
| 489 if (NULL != didChangeAlloc) { |
| 490 *didChangeAlloc = false; |
| 491 } |
489 return fPtr; | 492 return fPtr; |
490 } | 493 } |
491 | 494 |
492 sk_free(fPtr); | 495 sk_free(fPtr); |
493 fPtr = size ? sk_malloc_throw(size) : NULL; | 496 fPtr = size ? sk_malloc_throw(size) : NULL; |
494 fSize = size; | 497 fSize = size; |
| 498 if (NULL != didChangeAlloc) { |
| 499 *didChangeAlloc = true; |
| 500 } |
495 | 501 |
496 return fPtr; | 502 return fPtr; |
497 } | 503 } |
498 | 504 |
499 /** | 505 /** |
500 * Releases the block back to the heap | 506 * Releases the block back to the heap |
501 */ | 507 */ |
502 void free() { | 508 void free() { |
503 this->reset(0); | 509 this->reset(0); |
504 } | 510 } |
(...skipping 28 matching lines...) Expand all Loading... |
533 */ | 539 */ |
534 template <size_t kSize> class SkAutoSMalloc : SkNoncopyable { | 540 template <size_t kSize> class SkAutoSMalloc : SkNoncopyable { |
535 public: | 541 public: |
536 /** | 542 /** |
537 * Creates initially empty storage. get() returns a ptr, but it is to | 543 * Creates initially empty storage. get() returns a ptr, but it is to |
538 * a zero-byte allocation. Must call reset(size) to return an allocated | 544 * a zero-byte allocation. Must call reset(size) to return an allocated |
539 * block. | 545 * block. |
540 */ | 546 */ |
541 SkAutoSMalloc() { | 547 SkAutoSMalloc() { |
542 fPtr = fStorage; | 548 fPtr = fStorage; |
543 fSize = 0; | 549 fSize = kSize; |
544 } | 550 } |
545 | 551 |
546 /** | 552 /** |
547 * Allocate a block of the specified size. If size <= kSize, then the | 553 * Allocate a block of the specified size. If size <= kSize, then the |
548 * allocation will come from the stack, otherwise it will be dynamically | 554 * allocation will come from the stack, otherwise it will be dynamically |
549 * allocated. | 555 * allocated. |
550 */ | 556 */ |
551 explicit SkAutoSMalloc(size_t size) { | 557 explicit SkAutoSMalloc(size_t size) { |
552 fPtr = fStorage; | 558 fPtr = fStorage; |
553 fSize = 0; | 559 fSize = kSize; |
554 this->reset(size); | 560 this->reset(size); |
555 } | 561 } |
556 | 562 |
557 /** | 563 /** |
558 * Free the allocated block (if any). If the block was small enought to | 564 * Free the allocated block (if any). If the block was small enought to |
559 * have been allocated on the stack (size <= kSize) then this does nothing. | 565 * have been allocated on the stack (size <= kSize) then this does nothing. |
560 */ | 566 */ |
561 ~SkAutoSMalloc() { | 567 ~SkAutoSMalloc() { |
562 if (fPtr != (void*)fStorage) { | 568 if (fPtr != (void*)fStorage) { |
563 sk_free(fPtr); | 569 sk_free(fPtr); |
564 } | 570 } |
565 } | 571 } |
566 | 572 |
567 /** | 573 /** |
568 * Return the allocated block. May return non-null even if the block is | 574 * Return the allocated block. May return non-null even if the block is |
569 * of zero size. Since this may be on the stack or dynamically allocated, | 575 * of zero size. Since this may be on the stack or dynamically allocated, |
570 * the caller must not call sk_free() on it, but must rely on SkAutoSMalloc | 576 * the caller must not call sk_free() on it, but must rely on SkAutoSMalloc |
571 * to manage it. | 577 * to manage it. |
572 */ | 578 */ |
573 void* get() const { return fPtr; } | 579 void* get() const { return fPtr; } |
574 | 580 |
575 /** | 581 /** |
576 * Return a new block of the requested size, freeing (as necessary) any | 582 * Return a new block of the requested size, freeing (as necessary) any |
577 * previously allocated block. As with the constructor, if size <= kSize | 583 * previously allocated block. As with the constructor, if size <= kSize |
578 * then the return block may be allocated locally, rather than from the | 584 * then the return block may be allocated locally, rather than from the |
579 * heap. | 585 * heap. |
580 */ | 586 */ |
581 void* reset(size_t size, | 587 void* reset(size_t size, |
582 SkAutoMalloc::OnShrink shrink = SkAutoMalloc::kAlloc_OnShrink) { | 588 SkAutoMalloc::OnShrink shrink = SkAutoMalloc::kAlloc_OnShrink, |
583 if (size == fSize || (SkAutoMalloc::kReuse_OnShrink == shrink && | 589 bool* didChangeAlloc = NULL) { |
584 size < fSize)) { | 590 size = (size < kSize) ? kSize : size; |
585 return fPtr; | 591 bool alloc = size != fSize && (SkAutoMalloc::kAlloc_OnShrink == shrink |
| size < fSize); |
| 592 if (NULL != didChangeAlloc) { |
| 593 *didChangeAlloc = alloc; |
586 } | 594 } |
| 595 if (alloc) { |
| 596 if (fPtr != (void*)fStorage) { |
| 597 sk_free(fPtr); |
| 598 } |
587 | 599 |
588 if (fPtr != (void*)fStorage) { | 600 if (size == kSize) { |
589 sk_free(fPtr); | 601 SkASSERT(fPtr != fStorage); // otherwise we lied when setting di
dChangeAlloc. |
| 602 fPtr = fStorage; |
| 603 } else { |
| 604 fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP); |
| 605 } |
| 606 |
| 607 fSize = size; |
590 } | 608 } |
591 | 609 SkASSERT(fSize >= size && fSize >= kSize); |
592 if (size <= kSize) { | 610 SkASSERT((fPtr == fStorage) || fSize > kSize); |
593 fPtr = fStorage; | |
594 } else { | |
595 fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP); | |
596 } | |
597 return fPtr; | 611 return fPtr; |
598 } | 612 } |
599 | 613 |
600 private: | 614 private: |
601 void* fPtr; | 615 void* fPtr; |
602 size_t fSize; // can be larger than the requested size (see kReuse) | 616 size_t fSize; // can be larger than the requested size (see kReuse) |
603 uint32_t fStorage[(kSize + 3) >> 2]; | 617 uint32_t fStorage[(kSize + 3) >> 2]; |
604 }; | 618 }; |
605 | 619 |
606 #endif /* C++ */ | 620 #endif /* C++ */ |
607 | 621 |
608 #endif | 622 #endif |
OLD | NEW |