MCPcopy Create free account
hub / github.com/emscripten-core/emscripten / fallback_malloc

Function fallback_malloc

system/lib/libcxxabi/src/fallback_malloc.cpp:132–185  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

130}
131
132void* fallback_malloc(size_t len) {
133 heap_node *p, *prev;
134 const size_t nelems = alloc_size(len);
135 mutexor mtx(&heap_mutex);
136
137 if (NULL == freelist)
138 init_heap();
139
140 // Walk the free list, looking for a "big enough" chunk
141 for (p = freelist, prev = 0; p && p != list_end;
142 prev = p, p = node_from_offset(p->next_node)) {
143
144 // Check the invariant that all heap_nodes pointers 'p' are aligned
145 // so that 'p + 1' has an alignment of at least RequiredAlignment
146 _LIBCXXABI_ASSERT(reinterpret_cast<size_t>(p + 1) % RequiredAlignment == 0, "");
147
148 // Calculate the number of extra padding elements needed in order
149 // to split 'p' and create a properly aligned heap_node from the tail
150 // of 'p'. We calculate aligned_nelems such that 'p->len - aligned_nelems'
151 // will be a multiple of NodesPerAlignment.
152 size_t aligned_nelems = nelems;
153 if (p->len > nelems) {
154 heap_size remaining_len = static_cast<heap_size>(p->len - nelems);
155 aligned_nelems += remaining_len % NodesPerAlignment;
156 }
157
158 // chunk is larger and we can create a properly aligned heap_node
159 // from the tail. In this case we shorten 'p' and return the tail.
160 if (p->len > aligned_nelems) {
161 heap_node* q;
162 p->len = static_cast<heap_size>(p->len - aligned_nelems);
163 q = p + p->len;
164 q->next_node = 0;
165 q->len = static_cast<heap_size>(aligned_nelems);
166 void* ptr = q + 1;
167 _LIBCXXABI_ASSERT(reinterpret_cast<size_t>(ptr) % RequiredAlignment == 0, "");
168 return ptr;
169 }
170
171 // The chunk is the exact size or the chunk is larger but not large
172 // enough to split due to alignment constraints.
173 if (p->len >= nelems) {
174 if (prev == 0)
175 freelist = node_from_offset(p->next_node);
176 else
177 prev->next_node = p->next_node;
178 p->next_node = 0;
179 void* ptr = p + 1;
180 _LIBCXXABI_ASSERT(reinterpret_cast<size_t>(ptr) % RequiredAlignment == 0, "");
181 return ptr;
182 }
183 }
184 return NULL; // couldn't find a spot big enough
185}
186
187// Return the start of the next block
188heap_node* after(struct heap_node* p) { return p + p->len; }

Callers 2

__calloc_with_fallbackFunction · 0.85

Calls 3

alloc_sizeFunction · 0.85
init_heapFunction · 0.85
node_from_offsetFunction · 0.85

Tested by

no test coverage detected