SkVarAlloc.cpp revision 35f55764b81390a085fb90f624082c196fbd6229
1#include "SkVarAlloc.h" 2 3// We use non-standard malloc diagnostic methods to make sure our allocations are sized well. 4#if defined(SK_BUILD_FOR_MAC) 5 #include <malloc/malloc.h> 6#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN32) 7 #include <malloc.h> 8#endif 9 10struct SkVarAlloc::Block { 11 Block* prev; 12 char* data() { return (char*)(this + 1); } 13 14 static Block* Alloc(Block* prev, size_t size, unsigned flags) { 15 SkASSERT(size >= sizeof(Block)); 16 Block* b = (Block*)sk_malloc_flags(size, flags); 17 b->prev = prev; 18 return b; 19 } 20}; 21 22SkVarAlloc::SkVarAlloc(size_t minLgSize) 23 : fByte(NULL) 24 , fRemaining(0) 25 , fLgSize(minLgSize) 26 , fBlock(NULL) {} 27 28SkVarAlloc::~SkVarAlloc() { 29 Block* b = fBlock; 30 while (b) { 31 Block* prev = b->prev; 32 sk_free(b); 33 b = prev; 34 } 35} 36 37void SkVarAlloc::makeSpace(size_t bytes, unsigned flags) { 38 SkASSERT(SkIsAlignPtr(bytes)); 39 40 size_t alloc = 1<<fLgSize++; 41 while (alloc < bytes + sizeof(Block)) { 42 alloc *= 2; 43 } 44 fBlock = Block::Alloc(fBlock, alloc, flags); 45 fByte = fBlock->data(); 46 fRemaining = alloc - sizeof(Block); 47 48#if defined(SK_BUILD_FOR_MAC) 49 SkASSERT(alloc == malloc_good_size(alloc)); 50#elif defined(SK_BUILD_FOR_UNIX) && !defined(__UCLIBC__) 51 // TODO(mtklein): tune so we can assert something like this 52 //SkASSERT(alloc == malloc_usable_size(fBlock)); 53#endif 54} 55 56static size_t heap_size(void* p) { 57#if defined(SK_BUILD_FOR_MAC) 58 return malloc_size(p); 59#elif defined(SK_BUILD_FOR_UNIX) && !defined(__UCLIBC__) 60 return malloc_usable_size(p); 61#elif defined(SK_BUILD_FOR_WIN32) 62 return _msize(p); 63#else 64 return 0; // Tough luck. 65#endif 66} 67 68size_t SkVarAlloc::approxBytesAllocated() const { 69 size_t sum = 0; 70 for (Block* b = fBlock; b; b = b->prev) { 71 sum += heap_size(b); 72 } 73 return sum; 74} 75