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