Flutter Engine
The Flutter Engine
SkAutoMalloc.h
Go to the documentation of this file.
1/*
2 * Copyright 2016 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#ifndef SkAutoMalloc_DEFINED
9#define SkAutoMalloc_DEFINED
10
15
16#include <cstddef>
17#include <cstdint>
18#include <memory>
19
20/**
21 * Manage an allocated block of heap memory. This object is the sole manager of
22 * the lifetime of the block, so the caller must not call sk_free() or delete
23 * on the block, unless release() was called.
24 */
26public:
27 explicit SkAutoMalloc(size_t size = 0)
28 : fPtr(size ? sk_malloc_throw(size) : nullptr), fSize(size) {}
29
30 /**
31 * Passed to reset to specify what happens if the requested size is smaller
32 * than the current size (and the current block was dynamically allocated).
33 */
34 enum OnShrink {
35 /**
36 * If the requested size is smaller than the current size, and the
37 * current block is dynamically allocated, free the old block and
38 * malloc a new block of the smaller size.
39 */
41
42 /**
43 * If the requested size is smaller than the current size, and the
44 * current block is dynamically allocated, just return the old
45 * block.
46 */
48 };
49
50 /**
51 * Reallocates the block to a new size. The ptr may or may not change.
52 */
53 void* reset(size_t size = 0, OnShrink shrink = kAlloc_OnShrink) {
54 if (size != fSize && (size > fSize || kReuse_OnShrink != shrink)) {
55 fPtr.reset(size ? sk_malloc_throw(size) : nullptr);
56 fSize = size;
57 }
58 return fPtr.get();
59 }
60
61 /**
62 * Return the allocated block.
63 */
64 void* get() { return fPtr.get(); }
65 const void* get() const { return fPtr.get(); }
66
67 /** Transfer ownership of the current ptr to the caller, setting the
68 internal reference to null. Note the caller is reponsible for calling
69 sk_free on the returned address.
70 */
71 void* release() {
72 fSize = 0;
73 return fPtr.release();
74 }
75
76private:
77 struct WrapFree {
78 void operator()(void* p) { sk_free(p); }
79 };
80 std::unique_ptr<void, WrapFree> fPtr;
81 size_t fSize; // can be larger than the requested size (see kReuse)
82};
83
84/**
85 * Manage an allocated block of memory. If the requested size is <= kSizeRequested (or slightly
86 * more), then the allocation will come from the stack rather than the heap. This object is the
87 * sole manager of the lifetime of the block, so the caller must not call sk_free() or delete on
88 * the block.
89 */
90template <size_t kSizeRequested> class SkAutoSMalloc : SkNoncopyable {
91public:
92 /**
93 * Creates initially empty storage. get() returns a ptr, but it is to a zero-byte allocation.
94 * Must call reset(size) to return an allocated block.
95 */
97 fPtr = fStorage;
98 fSize = kSize;
99 }
100
101 /**
102 * Allocate a block of the specified size. If size <= kSizeRequested (or slightly more), then
103 * the allocation will come from the stack, otherwise it will be dynamically allocated.
104 */
105 explicit SkAutoSMalloc(size_t size) {
106 fPtr = fStorage;
107 fSize = kSize;
108 this->reset(size);
109 }
110
111 /**
112 * Free the allocated block (if any). If the block was small enough to have been allocated on
113 * the stack, then this does nothing.
114 */
116 if (fPtr != (void*)fStorage) {
117 sk_free(fPtr);
118 }
119 }
120
121 /**
122 * Return the allocated block. May return non-null even if the block is of zero size. Since
123 * this may be on the stack or dynamically allocated, the caller must not call sk_free() on it,
124 * but must rely on SkAutoSMalloc to manage it.
125 */
126 void* get() const { return fPtr; }
127
128 /**
129 * Return a new block of the requested size, freeing (as necessary) any previously allocated
130 * block. As with the constructor, if size <= kSizeRequested (or slightly more) then the return
131 * block may be allocated locally, rather than from the heap.
132 */
133 void* reset(size_t size,
135 bool* didChangeAlloc = nullptr) {
136 size = (size < kSize) ? kSize : size;
137 bool alloc = size != fSize && (SkAutoMalloc::kAlloc_OnShrink == shrink || size > fSize);
138 if (didChangeAlloc) {
139 *didChangeAlloc = alloc;
140 }
141 if (alloc) {
142 if (fPtr != (void*)fStorage) {
143 sk_free(fPtr);
144 }
145
146 if (size == kSize) {
147 SkASSERT(fPtr != fStorage); // otherwise we lied when setting didChangeAlloc.
148 fPtr = fStorage;
149 } else {
150 fPtr = sk_malloc_throw(size);
151 }
152
153 fSize = size;
154 }
155 SkASSERT(fSize >= size && fSize >= kSize);
156 SkASSERT((fPtr == fStorage) || fSize > kSize);
157 return fPtr;
158 }
159
160private:
161 // Align up to 32 bits.
162 static const size_t kSizeAlign4 = SkAlign4(kSizeRequested);
163#if defined(SK_BUILD_FOR_GOOGLE3)
164 // Stack frame size is limited for SK_BUILD_FOR_GOOGLE3. 4k is less than the actual max, but some functions
165 // have multiple large stack allocations.
166 static const size_t kMaxBytes = 4 * 1024;
167 static const size_t kSize = kSizeRequested > kMaxBytes ? kMaxBytes : kSizeAlign4;
168#else
169 static const size_t kSize = kSizeAlign4;
170#endif
171
172 void* fPtr;
173 size_t fSize; // can be larger than the requested size (see kReuse)
174 uint32_t fStorage[kSize >> 2];
175};
176// Can't guard the constructor because it's a template class.
177
178#endif
static constexpr T SkAlign4(T x)
Definition: SkAlign.h:16
#define SkASSERT(cond)
Definition: SkAssert.h:116
SK_API void sk_free(void *)
static void * sk_malloc_throw(size_t size)
Definition: SkMalloc.h:67
void * release()
Definition: SkAutoMalloc.h:71
const void * get() const
Definition: SkAutoMalloc.h:65
void * reset(size_t size=0, OnShrink shrink=kAlloc_OnShrink)
Definition: SkAutoMalloc.h:53
void * get()
Definition: SkAutoMalloc.h:64
SkAutoMalloc(size_t size=0)
Definition: SkAutoMalloc.h:27
SkAutoSMalloc(size_t size)
Definition: SkAutoMalloc.h:105
void * get() const
Definition: SkAutoMalloc.h:126
void * reset(size_t size, SkAutoMalloc::OnShrink shrink=SkAutoMalloc::kAlloc_OnShrink, bool *didChangeAlloc=nullptr)
Definition: SkAutoMalloc.h:133
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259