1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkVarAlloc.h"
9 
10 // We use non-standard malloc diagnostic methods to make sure our allocations are sized well.
11 #if defined(SK_BUILD_FOR_MAC)
12     #include <malloc/malloc.h>
13 #elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN32)
14     #include <malloc.h>
15 #endif
16 
17 struct SkVarAlloc::Block {
18     Block* prev;
dataSkVarAlloc::Block19     char* data() { return (char*)(this + 1); }
20 
AllocSkVarAlloc::Block21     static Block* Alloc(Block* prev, size_t size, unsigned flags) {
22         SkASSERT(size >= sizeof(Block));
23         Block* b = (Block*)sk_malloc_flags(size, flags);
24         b->prev = prev;
25         return b;
26     }
27 };
28 
SkVarAlloc(size_t minLgSize)29 SkVarAlloc::SkVarAlloc(size_t minLgSize)
30     : fBytesAllocated(0)
31     , fByte(NULL)
32     , fRemaining(0)
33     , fLgSize(minLgSize)
34     , fBlock(NULL) {}
35 
SkVarAlloc(size_t minLgSize,char * storage,size_t len)36 SkVarAlloc::SkVarAlloc(size_t minLgSize, char* storage, size_t len)
37     : fBytesAllocated(0)
38     , fByte(storage)
39     , fRemaining(len)
40     , fLgSize(minLgSize)
41     , fBlock(NULL) {}
42 
~SkVarAlloc()43 SkVarAlloc::~SkVarAlloc() {
44     Block* b = fBlock;
45     while (b) {
46         Block* prev = b->prev;
47         sk_free(b);
48         b = prev;
49     }
50 }
51 
makeSpace(size_t bytes,unsigned flags)52 void SkVarAlloc::makeSpace(size_t bytes, unsigned flags) {
53     SkASSERT(SkIsAlignPtr(bytes));
54 
55     size_t alloc = 1<<fLgSize++;
56     while (alloc < bytes + sizeof(Block)) {
57         alloc *= 2;
58     }
59     fBytesAllocated += alloc;
60     fBlock = Block::Alloc(fBlock, alloc, flags);
61     fByte = fBlock->data();
62     fRemaining = alloc - sizeof(Block);
63 
64 #if defined(SK_BUILD_FOR_MAC)
65     SkASSERT(alloc == malloc_good_size(alloc));
66 #elif defined(SK_BUILD_FOR_UNIX) && !defined(__UCLIBC__)
67     // TODO(mtklein): tune so we can assert something like this
68     //SkASSERT(alloc == malloc_usable_size(fBlock));
69 #endif
70 }
71