SkVarAlloc.cpp revision 8113dd13692bc2e1fe804141d04b2cc5f03a55be
1#include "SkVarAlloc.h"
2#include "SkScalar.h"
3
4// We use non-standard malloc diagnostic methods to make sure our allocations are sized well.
5#if defined(SK_BUILD_FOR_MAC)
6    #include <malloc/malloc.h>
7#elif defined(SK_BUILD_FOR_LINUX)
8    #include <malloc.h>
9#endif
10
11struct SkVarAlloc::Block {
12    Block* prev;
13    char* data() { return (char*)(this + 1); }
14
15    static Block* Alloc(Block* prev, size_t size, unsigned flags) {
16        SkASSERT(size >= sizeof(Block));
17        Block* b = (Block*)sk_malloc_flags(size, flags);
18        b->prev = prev;
19        return b;
20    }
21};
22
23SkVarAlloc::SkVarAlloc(size_t smallest, float growth)
24    : fByte(NULL)
25    , fLimit(NULL)
26    , fSmallest(SkToUInt(smallest))
27    , fGrowth(growth)
28    , fBlock(NULL) {}
29
30SkVarAlloc::~SkVarAlloc() {
31    Block* b = fBlock;
32    while (b) {
33        Block* prev = b->prev;
34        sk_free(b);
35        b = prev;
36    }
37}
38
39void SkVarAlloc::makeSpace(size_t bytes, unsigned flags) {
40    SkASSERT(SkIsAlignPtr(bytes));
41
42    size_t alloc = fSmallest;
43    while (alloc < bytes + sizeof(Block)) {
44        alloc *= 2;
45    }
46    fBlock = Block::Alloc(fBlock, alloc, flags);
47    fByte = fBlock->data();
48    fLimit = fByte + alloc - sizeof(Block);
49    fSmallest = SkToUInt(SkScalarTruncToInt(fSmallest * fGrowth));
50
51#if defined(SK_BUILD_FOR_MAC)
52    SkASSERT(alloc == malloc_good_size(alloc));
53#elif defined(SK_BUILD_FOR_LINUX)
54    SkASSERT(alloc == malloc_usable_size(fByte - sizeof(Block)));
55#endif
56}
57