Mercurial > hg > CbC > CbC_llvm
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) { |