#include "fallback_malloc.h"
#include "abort_message.h"
#include <__thread/support.h>
#ifndef _LIBCXXABI_HAS_NO_THREADS
#if defined(__ELF__) && defined(_LIBCXXABI_LINK_PTHREAD_LIB)
#pragma comment(lib, "pthread")
#endif
#endif
#include <__memory/aligned_alloc.h>
#include <__assert>
#include <stdlib.h>
#include <string.h>
namespace {
#ifndef _LIBCXXABI_HAS_NO_THREADS
static _LIBCPP_CONSTINIT std::__libcpp_mutex_t heap_mutex = …;
#else
static _LIBCPP_CONSTINIT void* heap_mutex = 0;
#endif
class mutexor { … };
static const size_t HEAP_SIZE = …;
char heap[HEAP_SIZE] __attribute__((aligned …));
heap_offset;
heap_size;
struct heap_node { … };
struct FallbackMaxAlignType { … } __attribute__((aligned …));
const size_t RequiredAlignment = …;
static_assert …;
const size_t NodesPerAlignment = …;
static const heap_node* list_end = …;
static heap_node* freelist = …;
heap_node* node_from_offset(const heap_offset offset) { … }
heap_offset offset_from_node(const heap_node* ptr) { … }
heap_node* getFirstAlignedNodeInHeap() { … }
void init_heap() { … }
size_t alloc_size(size_t len) { … }
bool is_fallback_ptr(void* ptr) { … }
void* fallback_malloc(size_t len) { … }
heap_node* after(struct heap_node* p) { … }
void fallback_free(void* ptr) { … }
#ifdef INSTRUMENT_FALLBACK_MALLOC
size_t print_free_list() {
struct heap_node *p, *prev;
heap_size total_free = 0;
if (NULL == freelist)
init_heap();
for (p = freelist, prev = 0; p && p != list_end;
prev = p, p = node_from_offset(p->next_node)) {
std::printf("%sOffset: %d\tsize: %d Next: %d\n",
(prev == 0 ? "" : " "), offset_from_node(p), p->len, p->next_node);
total_free += p->len;
}
std::printf("Total Free space: %d\n", total_free);
return total_free;
}
#endif
}
namespace __cxxabiv1 {
struct __attribute__((aligned)) __aligned_type { … };
void* __aligned_malloc_with_fallback(size_t size) { … }
void* __calloc_with_fallback(size_t count, size_t size) { … }
void __aligned_free_with_fallback(void* ptr) { … }
void __free_with_fallback(void* ptr) { … }
}