comparison libcxxabi/src/fallback_malloc.cpp @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents 1d019706d866
children c4bab56944e8
comparison
equal deleted inserted replaced
173:0572611fdcc8 207:2e18cbf3894f
4 // See https://llvm.org/LICENSE.txt for license information. 4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 // 6 //
7 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
8 8
9 // Define _LIBCPP_BUILDING_LIBRARY to ensure _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
10 // is only defined when libc aligned allocation is not available.
11 #define _LIBCPP_BUILDING_LIBRARY
12 #include "fallback_malloc.h" 9 #include "fallback_malloc.h"
13 10
14 #include <__threading_support> 11 #include <__threading_support>
15 #ifndef _LIBCXXABI_HAS_NO_THREADS 12 #ifndef _LIBCXXABI_HAS_NO_THREADS
16 #if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB) 13 #if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB)
18 #endif 15 #endif
19 #endif 16 #endif
20 17
21 #include <stdlib.h> // for malloc, calloc, free 18 #include <stdlib.h> // for malloc, calloc, free
22 #include <string.h> // for memset 19 #include <string.h> // for memset
20 #include <new> // for std::__libcpp_aligned_{alloc,free}
23 21
24 // A small, simple heap manager based (loosely) on 22 // A small, simple heap manager based (loosely) on
25 // the startup heap manager from FreeBSD, optimized for space. 23 // the startup heap manager from FreeBSD, optimized for space.
26 // 24 //
27 // Manages a fixed-size memory pool, supports malloc and free only. 25 // Manages a fixed-size memory pool, supports malloc and free only.
142 struct heap_node *p, *prev; 140 struct heap_node *p, *prev;
143 141
144 mutexor mtx(&heap_mutex); 142 mutexor mtx(&heap_mutex);
145 143
146 #ifdef DEBUG_FALLBACK_MALLOC 144 #ifdef DEBUG_FALLBACK_MALLOC
147 std::cout << "Freeing item at " << offset_from_node(cp) << " of size " 145 std::printf("Freeing item at %d of size %d\n", offset_from_node(cp), cp->len);
148 << cp->len << std::endl;
149 #endif 146 #endif
150 147
151 for (p = freelist, prev = 0; p && p != list_end; 148 for (p = freelist, prev = 0; p && p != list_end;
152 prev = p, p = node_from_offset(p->next_node)) { 149 prev = p, p = node_from_offset(p->next_node)) {
153 #ifdef DEBUG_FALLBACK_MALLOC 150 #ifdef DEBUG_FALLBACK_MALLOC
154 std::cout << " p, cp, after (p), after(cp) " << offset_from_node(p) << ' ' 151 std::printf(" p=%d, cp=%d, after(p)=%d, after(cp)=%d\n",
155 << offset_from_node(cp) << ' ' << offset_from_node(after(p)) 152 offset_from_node(p), offset_from_node(cp),
156 << ' ' << offset_from_node(after(cp)) << std::endl; 153 offset_from_node(after(p)), offset_from_node(after(cp)));
157 #endif 154 #endif
158 if (after(p) == cp) { 155 if (after(p) == cp) {
159 #ifdef DEBUG_FALLBACK_MALLOC 156 #ifdef DEBUG_FALLBACK_MALLOC
160 std::cout << " Appending onto chunk at " << offset_from_node(p) 157 std::printf(" Appending onto chunk at %d\n", offset_from_node(p));
161 << std::endl;
162 #endif 158 #endif
163 p->len = static_cast<heap_size>( 159 p->len = static_cast<heap_size>(
164 p->len + cp->len); // make the free heap_node larger 160 p->len + cp->len); // make the free heap_node larger
165 return; 161 return;
166 } else if (after(cp) == p) { // there's a free heap_node right after 162 } else if (after(cp) == p) { // there's a free heap_node right after
167 #ifdef DEBUG_FALLBACK_MALLOC 163 #ifdef DEBUG_FALLBACK_MALLOC
168 std::cout << " Appending free chunk at " << offset_from_node(p) 164 std::printf(" Appending free chunk at %d\n", offset_from_node(p));
169 << std::endl;
170 #endif 165 #endif
171 cp->len = static_cast<heap_size>(cp->len + p->len); 166 cp->len = static_cast<heap_size>(cp->len + p->len);
172 if (prev == 0) { 167 if (prev == 0) {
173 freelist = cp; 168 freelist = cp;
174 cp->next_node = p->next_node; 169 cp->next_node = p->next_node;
177 return; 172 return;
178 } 173 }
179 } 174 }
180 // Nothing to merge with, add it to the start of the free list 175 // Nothing to merge with, add it to the start of the free list
181 #ifdef DEBUG_FALLBACK_MALLOC 176 #ifdef DEBUG_FALLBACK_MALLOC
182 std::cout << " Making new free list entry " << offset_from_node(cp) 177 std::printf(" Making new free list entry %d\n", offset_from_node(cp));
183 << std::endl;
184 #endif 178 #endif
185 cp->next_node = offset_from_node(freelist); 179 cp->next_node = offset_from_node(freelist);
186 freelist = cp; 180 freelist = cp;
187 } 181 }
188 182
193 if (NULL == freelist) 187 if (NULL == freelist)
194 init_heap(); 188 init_heap();
195 189
196 for (p = freelist, prev = 0; p && p != list_end; 190 for (p = freelist, prev = 0; p && p != list_end;
197 prev = p, p = node_from_offset(p->next_node)) { 191 prev = p, p = node_from_offset(p->next_node)) {
198 std::cout << (prev == 0 ? "" : " ") << "Offset: " << offset_from_node(p) 192 std::printf("%sOffset: %d\tsize: %d Next: %d\n",
199 << "\tsize: " << p->len << " Next: " << p->next_node << std::endl; 193 (prev == 0 ? "" : " "), offset_from_node(p), p->len, p->next_node);
200 total_free += p->len; 194 total_free += p->len;
201 } 195 }
202 std::cout << "Total Free space: " << total_free << std::endl; 196 std::printf("Total Free space: %d\n", total_free);
203 return total_free; 197 return total_free;
204 } 198 }
205 #endif 199 #endif
206 } // end unnamed namespace 200 } // end unnamed namespace
207 201
209 203
210 struct __attribute__((aligned)) __aligned_type {}; 204 struct __attribute__((aligned)) __aligned_type {};
211 205
212 void* __aligned_malloc_with_fallback(size_t size) { 206 void* __aligned_malloc_with_fallback(size_t size) {
213 #if defined(_WIN32) 207 #if defined(_WIN32)
214 if (void* dest = _aligned_malloc(size, alignof(__aligned_type))) 208 if (void* dest = std::__libcpp_aligned_alloc(alignof(__aligned_type), size))
215 return dest; 209 return dest;
216 #elif defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) 210 #elif defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
217 if (void* dest = ::malloc(size)) 211 if (void* dest = ::malloc(size))
218 return dest; 212 return dest;
219 #else 213 #else
220 if (size == 0) 214 if (size == 0)
221 size = 1; 215 size = 1;
222 void* dest; 216 if (void* dest = std::__libcpp_aligned_alloc(__alignof(__aligned_type), size))
223 if (::posix_memalign(&dest, __alignof(__aligned_type), size) == 0)
224 return dest; 217 return dest;
225 #endif 218 #endif
226 return fallback_malloc(size); 219 return fallback_malloc(size);
227 } 220 }
228 221
239 232
240 void __aligned_free_with_fallback(void* ptr) { 233 void __aligned_free_with_fallback(void* ptr) {
241 if (is_fallback_ptr(ptr)) 234 if (is_fallback_ptr(ptr))
242 fallback_free(ptr); 235 fallback_free(ptr);
243 else { 236 else {
244 #if defined(_WIN32) 237 #if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
245 ::_aligned_free(ptr);
246 #else
247 ::free(ptr); 238 ::free(ptr);
239 #else
240 std::__libcpp_aligned_free(ptr);
248 #endif 241 #endif
249 } 242 }
250 } 243 }
251 244
252 void __free_with_fallback(void* ptr) { 245 void __free_with_fallback(void* ptr) {