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