| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 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 SkTypes_DEFINED | 8 #ifndef SkTypes_DEFINED |
| 9 #define SkTypes_DEFINED | 9 #define SkTypes_DEFINED |
| 10 | 10 |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 return ptr; | 599 return ptr; |
| 600 } | 600 } |
| 601 | 601 |
| 602 private: | 602 private: |
| 603 void* fPtr; | 603 void* fPtr; |
| 604 size_t fSize; // can be larger than the requested size (see kReuse) | 604 size_t fSize; // can be larger than the requested size (see kReuse) |
| 605 }; | 605 }; |
| 606 #define SkAutoMalloc(...) SK_REQUIRE_LOCAL_VAR(SkAutoMalloc) | 606 #define SkAutoMalloc(...) SK_REQUIRE_LOCAL_VAR(SkAutoMalloc) |
| 607 | 607 |
| 608 /** | 608 /** |
| 609 * Manage an allocated block of memory. If the requested size is <= kSizeReques
ted (or slightly | 609 * Manage an allocated block of memory. If the requested size is <= kSize, then |
| 610 * more), then the allocation will come from the stack rather than the heap. Th
is object is the | 610 * the allocation will come from the stack rather than the heap. This object |
| 611 * sole manager of the lifetime of the block, so the caller must not call sk_fr
ee() or delete on | 611 * is the sole manager of the lifetime of the block, so the caller must not |
| 612 * the block. | 612 * call sk_free() or delete on the block. |
| 613 */ | 613 */ |
| 614 template <size_t kSizeRequested> class SkAutoSMalloc : SkNoncopyable { | 614 template <size_t kSize> class SkAutoSMalloc : SkNoncopyable { |
| 615 public: | 615 public: |
| 616 /** | 616 /** |
| 617 * Creates initially empty storage. get() returns a ptr, but it is to a zer
o-byte allocation. | 617 * Creates initially empty storage. get() returns a ptr, but it is to |
| 618 * Must call reset(size) to return an allocated block. | 618 * a zero-byte allocation. Must call reset(size) to return an allocated |
| 619 * block. |
| 619 */ | 620 */ |
| 620 SkAutoSMalloc() { | 621 SkAutoSMalloc() { |
| 621 fPtr = fStorage; | 622 fPtr = fStorage; |
| 622 fSize = kSize; | 623 fSize = kSize; |
| 623 } | 624 } |
| 624 | 625 |
| 625 /** | 626 /** |
| 626 * Allocate a block of the specified size. If size <= kSizeRequested (or sl
ightly more), then | 627 * Allocate a block of the specified size. If size <= kSize, then the |
| 627 * the allocation will come from the stack, otherwise it will be dynamicall
y allocated. | 628 * allocation will come from the stack, otherwise it will be dynamically |
| 629 * allocated. |
| 628 */ | 630 */ |
| 629 explicit SkAutoSMalloc(size_t size) { | 631 explicit SkAutoSMalloc(size_t size) { |
| 630 fPtr = fStorage; | 632 fPtr = fStorage; |
| 631 fSize = kSize; | 633 fSize = kSize; |
| 632 this->reset(size); | 634 this->reset(size); |
| 633 } | 635 } |
| 634 | 636 |
| 635 /** | 637 /** |
| 636 * Free the allocated block (if any). If the block was small enough to have
been allocated on | 638 * Free the allocated block (if any). If the block was small enought to |
| 637 * the stack, then this does nothing. | 639 * have been allocated on the stack (size <= kSize) then this does nothing. |
| 638 */ | 640 */ |
| 639 ~SkAutoSMalloc() { | 641 ~SkAutoSMalloc() { |
| 640 if (fPtr != (void*)fStorage) { | 642 if (fPtr != (void*)fStorage) { |
| 641 sk_free(fPtr); | 643 sk_free(fPtr); |
| 642 } | 644 } |
| 643 } | 645 } |
| 644 | 646 |
| 645 /** | 647 /** |
| 646 * Return the allocated block. May return non-null even if the block is of
zero size. Since | 648 * Return the allocated block. May return non-null even if the block is |
| 647 * this may be on the stack or dynamically allocated, the caller must not c
all sk_free() on it, | 649 * of zero size. Since this may be on the stack or dynamically allocated, |
| 648 * but must rely on SkAutoSMalloc to manage it. | 650 * the caller must not call sk_free() on it, but must rely on SkAutoSMalloc |
| 651 * to manage it. |
| 649 */ | 652 */ |
| 650 void* get() const { return fPtr; } | 653 void* get() const { return fPtr; } |
| 651 | 654 |
| 652 /** | 655 /** |
| 653 * Return a new block of the requested size, freeing (as necessary) any pre
viously allocated | 656 * Return a new block of the requested size, freeing (as necessary) any |
| 654 * block. As with the constructor, if size <= kSizeRequested (or slightly m
ore) then the return | 657 * previously allocated block. As with the constructor, if size <= kSize |
| 655 * block may be allocated locally, rather than from the heap. | 658 * then the return block may be allocated locally, rather than from the |
| 659 * heap. |
| 656 */ | 660 */ |
| 657 void* reset(size_t size, | 661 void* reset(size_t size, |
| 658 SkAutoMalloc::OnShrink shrink = SkAutoMalloc::kAlloc_OnShrink, | 662 SkAutoMalloc::OnShrink shrink = SkAutoMalloc::kAlloc_OnShrink, |
| 659 bool* didChangeAlloc = NULL) { | 663 bool* didChangeAlloc = NULL) { |
| 660 size = (size < kSize) ? kSize : size; | 664 size = (size < kSize) ? kSize : size; |
| 661 bool alloc = size != fSize && (SkAutoMalloc::kAlloc_OnShrink == shrink |
| size > fSize); | 665 bool alloc = size != fSize && (SkAutoMalloc::kAlloc_OnShrink == shrink |
| size > fSize); |
| 662 if (didChangeAlloc) { | 666 if (didChangeAlloc) { |
| 663 *didChangeAlloc = alloc; | 667 *didChangeAlloc = alloc; |
| 664 } | 668 } |
| 665 if (alloc) { | 669 if (alloc) { |
| 666 if (fPtr != (void*)fStorage) { | 670 if (fPtr != (void*)fStorage) { |
| 667 sk_free(fPtr); | 671 sk_free(fPtr); |
| 668 } | 672 } |
| 669 | 673 |
| 670 if (size == kSize) { | 674 if (size == kSize) { |
| 671 SkASSERT(fPtr != fStorage); // otherwise we lied when setting di
dChangeAlloc. | 675 SkASSERT(fPtr != fStorage); // otherwise we lied when setting di
dChangeAlloc. |
| 672 fPtr = fStorage; | 676 fPtr = fStorage; |
| 673 } else { | 677 } else { |
| 674 fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP); | 678 fPtr = sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_TEMP); |
| 675 } | 679 } |
| 676 | 680 |
| 677 fSize = size; | 681 fSize = size; |
| 678 } | 682 } |
| 679 SkASSERT(fSize >= size && fSize >= kSize); | 683 SkASSERT(fSize >= size && fSize >= kSize); |
| 680 SkASSERT((fPtr == fStorage) || fSize > kSize); | 684 SkASSERT((fPtr == fStorage) || fSize > kSize); |
| 681 return fPtr; | 685 return fPtr; |
| 682 } | 686 } |
| 683 | 687 |
| 684 private: | 688 private: |
| 685 // Align up to 32 bits. | |
| 686 static const size_t kSizeAlign4 = SkAlign4(kSizeRequested); | |
| 687 #if defined(GOOGLE3) | |
| 688 // Stack frame size is limited for GOOGLE3. 4k is less than the actual max,
but some functions | |
| 689 // have multiple large stack allocations. | |
| 690 static const size_t kMaxBytes = 4 * 1024; | |
| 691 static const size_t kSize = kSizeRequested > kMaxBytes ? kMaxBytes : kSizeAl
ign4; | |
| 692 #else | |
| 693 static const size_t kSize = kSizeAlign4; | |
| 694 #endif | |
| 695 | |
| 696 void* fPtr; | 689 void* fPtr; |
| 697 size_t fSize; // can be larger than the requested size (see kReuse) | 690 size_t fSize; // can be larger than the requested size (see kReuse) |
| 698 uint32_t fStorage[kSize >> 2]; | 691 uint32_t fStorage[(kSize + 3) >> 2]; |
| 699 }; | 692 }; |
| 700 // Can't guard the constructor because it's a template class. | 693 // Can't guard the constructor because it's a template class. |
| 701 | 694 |
| 702 #endif /* C++ */ | 695 #endif /* C++ */ |
| 703 | 696 |
| 704 #endif | 697 #endif |
| OLD | NEW |