From c7d1a411df4d01010620519a51821d56b5333cc5 Mon Sep 17 00:00:00 2001 From: Nicholas Donaldson Date: Sun, 28 Jun 2020 12:01:36 -0700 Subject: [PATCH] once again I forget to include new files :) --- include/EXTLLVM.h | 49 +-------------------- include/EXTZONES.h | 50 +++++++++++++++++++++ src/EXTLLVM.cpp | 72 +----------------------------- src/EXTZONES.cpp | 107 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 118 deletions(-) create mode 100644 include/EXTZONES.h create mode 100644 src/EXTZONES.cpp diff --git a/include/EXTLLVM.h b/include/EXTLLVM.h index e2e548217..d566eabae 100644 --- a/include/EXTLLVM.h +++ b/include/EXTLLVM.h @@ -64,53 +64,8 @@ extern "C" // this added for dodgy continuations support -namespace extemp -{ - -namespace EXTLLVM -{ - -const unsigned LLVM_ZONE_ALIGN = 32; // MUST BE POWER OF 2! -const unsigned LLVM_ZONE_ALIGNPAD = LLVM_ZONE_ALIGN - 1; - -inline llvm_zone_t* llvm_zone_create(uint64_t size) -{ - auto zone(static_cast(malloc(sizeof(llvm_zone_t)))); - if (unlikely(!zone)) { - abort(); // in case a leak can be analyzed post-mortem - } -#ifdef _WIN32 - if (size == 0) { - zone->memory = NULL; - } - else { - // this crashes extempore but I have no idea why???? - // zone->memory = _aligned_malloc((size_t)size, (size_t)LLVM_ZONE_ALIGN); - zone->memory = malloc(size_t(size)); - } -#else - posix_memalign(&zone->memory, LLVM_ZONE_ALIGN, size_t(size)); -#endif - zone->mark = 0; - zone->offset = 0; - if (unlikely(!zone->memory)) { - size = 0; - } - zone->size = size; - zone->cleanup_hooks = nullptr; - zone->memories = nullptr; - return zone; -} - -EXPORT void llvm_zone_destroy(llvm_zone_t* Zone); - -inline llvm_zone_t* llvm_zone_reset(llvm_zone_t* Zone) -{ - Zone->offset = 0; - return Zone; -} - -EXPORT void* llvm_zone_malloc(llvm_zone_t* zone, uint64_t size); +namespace extemp { +namespace EXTLLVM { inline llvm_zone_stack* llvm_threads_get_zone_stack() { diff --git a/include/EXTZONES.h b/include/EXTZONES.h new file mode 100644 index 000000000..37ad8fb0d --- /dev/null +++ b/include/EXTZONES.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +#define DEBUG_ZONE_STACK 0 +#define DEBUG_ZONE_ALLOC 0 + +struct zone_hooks_t { + uint64_t space; // here just so we don't get + void* hook; // xtlang closure of type [void]* + zone_hooks_t* hooks; +}; + +// WARNING WARNING WARNING - HERE BE DRAGONS +// THIS STRUCTURE IS REFERENCED FROM GENERATED CODE +// DO NOT ALTER IT!!! + +struct llvm_zone_t { + void* memory; + uint64_t offset; + uint64_t mark; + uint64_t size; + zone_hooks_t* cleanup_hooks; + llvm_zone_t* memories; +}; + +struct llvm_zone_stack +{ + llvm_zone_t* head; + llvm_zone_stack* tail; +}; + +struct closure_address_table; + +extern THREAD_LOCAL llvm_zone_stack* tls_llvm_zone_stack; +extern THREAD_LOCAL uint64_t tls_llvm_zone_stacksize; + +namespace extemp { +namespace EXTLLVM { +const unsigned LLVM_ZONE_ALIGN = 32; // MUST BE POWER OF 2! +const unsigned LLVM_ZONE_ALIGNPAD = LLVM_ZONE_ALIGN - 1; + +llvm_zone_t* llvm_zone_create(uint64_t size); +EXPORT void llvm_zone_destroy(llvm_zone_t* Zone); +llvm_zone_t* llvm_zone_reset(llvm_zone_t* Zone); +EXPORT void* llvm_zone_malloc(llvm_zone_t* zone, uint64_t size); + +} +} diff --git a/src/EXTLLVM.cpp b/src/EXTLLVM.cpp index 14fe80920..2bb8acf0e 100644 --- a/src/EXTLLVM.cpp +++ b/src/EXTLLVM.cpp @@ -99,8 +99,6 @@ #define DEBUG_ZONE_STACK 0 #define DEBUG_ZONE_ALLOC 0 -#define LEAKY_ZONES 1 -#define EXTENSIBLE_ZONES 1 EXPORT void* malloc16(size_t Size) { @@ -664,17 +662,7 @@ EXPORT void free_after_delay(char* Data, double Delay) &FreeWithDelayCM, Data)); } -EXPORT void llvm_zone_destroy(llvm_zone_t* Zone) -{ -#if DEBUG_ZONE_ALLOC - printf("DestroyZone: %p:%p:%lld:%lld\n", Zone, Zone->memory, Zone->offset, Zone->size); -#endif - if (Zone->memories) { - llvm_zone_destroy(Zone->memories); - } - free(Zone->memory); - free(Zone); -} + EXPORT llvm_zone_t* llvm_pop_zone_stack() { @@ -700,64 +688,6 @@ EXPORT llvm_zone_t* llvm_pop_zone_stack() return head; } -EXPORT void* llvm_zone_malloc(llvm_zone_t* zone, uint64_t size) -{ - static extemp::EXTMutex alloc_mutex("alloc mutex"); - // TODO: is this thread-safe? - if (!alloc_mutex.initialised()) { - alloc_mutex.init(); - } - - extemp::EXTMutex::ScopedLock lock(alloc_mutex); -#if DEBUG_ZONE_ALLOC - printf("MallocZone: %p:%p:%lld:%lld:%lld\n",zone,zone->memory,zone->offset,zone->size,size); -#endif - size += LLVM_ZONE_ALIGN; // for storing size information - if (unlikely(zone->offset + size >= zone->size)) { -#if EXTENSIBLE_ZONES // if extensible_zones is true then extend zone size by zone->size - int old_zone_size = zone->size; - bool iszero(!zone->size); - if (size > zone->size) { - zone->size = size; - } - zone->size *= 2; // keep doubling zone size for each new allocation // TODO: 1.5??? - if (zone->size < 1024) { - zone->size = 1024; // allocate a min size of 1024 bytes - } - llvm_zone_t* newzone = llvm_zone_create(zone->size); - void* tmp = newzone->memory; - if (iszero) { // if initial zone is 0 - then replace don't extend - zone->memory = tmp; - free(newzone); - } else { - // printf("adding new memory %p:%lld to existing %p:%lld\n",newzone,newzone->size,zone,zone->size); - newzone->memories = zone->memories; - newzone->memory = zone->memory; - newzone->size = old_zone_size; - zone->memory = tmp; - zone->memories = newzone; - } - llvm_zone_reset(zone); -#elif LEAKY_ZONES // if LEAKY ZONE is TRUE then just print a warning and just leak the memory - printf("\nZone:%p size:%lld is full ... leaking %lld bytes\n",zone,zone->size,size); - printf("Leaving a leaky zone can be dangerous ... particularly for concurrency\n"); - fflush(NULL); - return malloc((size_t)size); // TODO: what about the stored size???? -#else - printf("\nZone:%p size:%lld is full ... exiting!\n",zone,zone->size,size); - fflush(NULL); - exit(1); -#endif - } - size = (size + LLVM_ZONE_ALIGNPAD) & ~LLVM_ZONE_ALIGNPAD; - auto newptr = reinterpret_cast(reinterpret_cast(zone->memory) + zone->offset); - memset(newptr, 0, size); // clear memory - newptr = reinterpret_cast(newptr) + LLVM_ZONE_ALIGN; // skip past size - *(reinterpret_cast(newptr) - 1) = size; - zone->offset += size; - return newptr; -} - EXPORT void* llvm_zone_malloc_from_current_zone(uint64_t size) { return llvm_zone_malloc(llvm_peek_zone_stack(), size); diff --git a/src/EXTZONES.cpp b/src/EXTZONES.cpp new file mode 100644 index 000000000..ee4ab2e05 --- /dev/null +++ b/src/EXTZONES.cpp @@ -0,0 +1,107 @@ +#include "EXTZONES.h" + +#include + +#include + +namespace extemp { +namespace EXTLLVM { + +llvm_zone_t* llvm_zone_create(uint64_t size) +{ + auto zone(static_cast(malloc(sizeof(llvm_zone_t)))); + if (unlikely(!zone)) { + abort(); // in case a leak can be analyzed post-mortem + } +#ifdef _WIN32 + if (size == 0) { + zone->memory = NULL; + } + else { + // this crashes extempore but I have no idea why???? + // zone->memory = _aligned_malloc((size_t)size, (size_t)LLVM_ZONE_ALIGN); + zone->memory = malloc(size_t(size)); + } +#else + posix_memalign(&zone->memory, LLVM_ZONE_ALIGN, size_t(size)); +#endif + zone->mark = 0; + zone->offset = 0; + if (unlikely(!zone->memory)) { + size = 0; + } + zone->size = size; + zone->cleanup_hooks = nullptr; + zone->memories = nullptr; + return zone; +} + +EXPORT void llvm_zone_destroy(llvm_zone_t* Zone) +{ +#if DEBUG_ZONE_ALLOC + printf("DestroyZone: %p:%p:%lld:%lld\n", Zone, Zone->memory, Zone->offset, Zone->size); +#endif + if (Zone->memories) { + llvm_zone_destroy(Zone->memories); + } + free(Zone->memory); + free(Zone); +} + +llvm_zone_t* llvm_zone_reset(llvm_zone_t* Zone) +{ + Zone->offset = 0; + return Zone; +} + +EXPORT void* llvm_zone_malloc(llvm_zone_t* zone, uint64_t size) +{ + static extemp::EXTMutex alloc_mutex("alloc mutex"); + // TODO: is this thread-safe? + if (!alloc_mutex.initialised()) { + alloc_mutex.init(); + } + + extemp::EXTMutex::ScopedLock lock(alloc_mutex); + +#if DEBUG_ZONE_ALLOC + printf("MallocZone: %p:%p:%lld:%lld:%lld\n", zone, zone->memory, zone->offset, zone->size, size); +#endif + + size += LLVM_ZONE_ALIGN; // for storing size information + if (unlikely(zone->offset + size >= zone->size)) { + int old_zone_size = zone->size; + bool iszero(!zone->size); + if (size > zone->size) { + zone->size = size; + } + zone->size *= 2; // keep doubling zone size for each new allocation // TODO: 1.5??? + if (zone->size < 1024) { + zone->size = 1024; // allocate a min size of 1024 bytes + } + llvm_zone_t* newzone = llvm_zone_create(zone->size); + void* tmp = newzone->memory; + if (iszero) { // if initial zone is 0 - then replace don't extend + zone->memory = tmp; + free(newzone); + } else { + // printf("adding new memory %p:%lld to existing %p:%lld\n",newzone,newzone->size,zone,zone->size); + newzone->memories = zone->memories; + newzone->memory = zone->memory; + newzone->size = old_zone_size; + zone->memory = tmp; + zone->memories = newzone; + } + llvm_zone_reset(zone); + } + size = (size + LLVM_ZONE_ALIGNPAD) & ~LLVM_ZONE_ALIGNPAD; + auto newptr = reinterpret_cast(reinterpret_cast(zone->memory) + zone->offset); + memset(newptr, 0, size); // clear memory + newptr = reinterpret_cast(newptr) + LLVM_ZONE_ALIGN; // skip past size + *(reinterpret_cast(newptr) - 1) = size; + zone->offset += size; + return newptr; +} + +} // namespace EXTLLVM +} // namespace extemp