From e948329c74b4b3ca329d64cfbab8c195bc2d0eb4 Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Sun, 15 Sep 2024 16:08:46 -0700 Subject: [PATCH] remove static_assert checks on alignment Cleanup '//D' comments Improvements to new/delete debug logging --- cores/esp8266/abi.cpp | 13 +- cores/esp8266/heap.cpp | 285 ++++++++++++------------ cores/esp8266/umm_malloc/umm_malloc.cpp | 13 +- 3 files changed, 159 insertions(+), 152 deletions(-) diff --git a/cores/esp8266/abi.cpp b/cores/esp8266/abi.cpp index 6ee4878e5d..b1e6983d11 100644 --- a/cores/esp8266/abi.cpp +++ b/cores/esp8266/abi.cpp @@ -36,8 +36,8 @@ extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); #if DEV_DEBUG_ABI_CPP -extern "C" void _dbg_abi_print_pstr(const char* op, const char *function_name, const void* caller); -#define DEBUG_NEW_OP_PRINTF() _dbg_abi_print_pstr("new_op", __PRETTY_FUNCTION__, NULL) +extern "C" void _dbg_abi_print_pstr(const char* op, const char *function_name); +#define DEBUG_NEW_OP_PRINTF() _dbg_abi_print_pstr("new_op", __PRETTY_FUNCTION__) #else #define DEBUG_NEW_OP_PRINTF() do { } while (false) #endif @@ -351,9 +351,10 @@ void* operator new[] (size_t size, const std::nothrow_t&) #endif // #elif !defined(__cpp_exceptions) #if defined(UMM_ENABLE_MEMALIGN) #else /* - Using weaklink C++ Exception handlers in libstdc. The "new" operators that - express alignment should work through libstdc via memalign() in the umm_malloc - library. + The C++ Exception handlers in libstdc are using weaklinks. The "new" operators + that express alignment should work through libstdc via memalign() in the + umm_malloc library. While not likely to ever be needed, the Sketch can replace + the C++ "Replaceable allocation functions." Note that libstdc will fail errors in alignment value early. Thus, the UMM_STATS_FULL alignment error count will be zero. @@ -367,8 +368,8 @@ void* operator new[] (size_t size, const std::nothrow_t&) #pragma message("Using weaklink C++ Exception handlers in libstdc") #if UMM_ENABLE_MEMALIGN #pragma message("The \"new\" operators that express alignment should work through libstdc via memalign() in the umm_malloc library.") -//D >> #endif +//D >> #endif // #if defined(__cpp_exceptions) diff --git a/cores/esp8266/heap.cpp b/cores/esp8266/heap.cpp index 19349caa3c..5e98504309 100644 --- a/cores/esp8266/heap.cpp +++ b/cores/esp8266/heap.cpp @@ -107,9 +107,12 @@ * * DEV_DEBUG_ABI_CPP - Not normally needed. Its intended use is for module * code maintenance. Use DEV_DEBUG_ABI_CPP when debugging the new/delete - * overload wrappers in abi.cpp and heap.cpp. In the test Sketch, add "extern - * bool abi_new_print;" and set abi_new_print=true/false around test function - * calls. Also, set '-DDEV_DEBUG_ABI_CPP=1' in Sketch.ino.globals.h. + * overload wrappers in abi.cpp and heap.cpp. To use in a test Sketch, add + * "extern bool abi_new_print;" and set abi_new_print=true/false around test + * function calls. Also, set '-DDEV_DEBUG_ABI_CPP=1' in Sketch.ino.globals.h. + * With this option, using print functions in the test Sketch that performs + * allocs can create a confusing array of debug prints. For this reason, I + * often use ets_uart_printf in alloc test Sketches. */ #include @@ -155,7 +158,8 @@ inline bool withinISR(uint32_t ps) { #undef STATIC_ALWAYS_INLINE #undef ENABLE_THICK_DEBUG_WRAPPERS -// We want none of these redefined, possition these after all includes have finished. +// Whether using thick or thin wrappers, we want none of these redefined. +// Position these "#undefs" after all includes. #undef malloc #undef calloc #undef realloc @@ -174,9 +178,6 @@ inline bool withinISR(uint32_t ps) { #define UMM_REALLOC_FL(p,s,f,l,c) umm_poison_realloc_flc(p,s,f,l,c) #define UMM_FREE_FL(p,f,l,c) umm_poison_free_flc(p,f,l,c) #define ENABLE_THICK_DEBUG_WRAPPERS -//D -//D #undef realloc -//D #undef free #elif defined(UMM_POISON_CHECK) /* @@ -190,9 +191,6 @@ inline bool withinISR(uint32_t ps) { #define UMM_REALLOC_FL(p,s,f,l,c) umm_poison_realloc(p,s) #define UMM_FREE_FL(p,f,l,c) umm_poison_free(p) #define ENABLE_THICK_DEBUG_WRAPPERS -//D -//D #undef realloc -//D #undef free #elif defined(DEBUG_ESP_OOM) || defined(UMM_INTEGRITY_CHECK) || defined(DEBUG_ESP_WITHINISR) // All other debug wrappers that do not require handling poison @@ -202,9 +200,6 @@ inline bool withinISR(uint32_t ps) { #define UMM_REALLOC_FL(p,s,f,l,c) umm_realloc(p,s) #define UMM_FREE_FL(p,f,l,c) umm_free(p) #define ENABLE_THICK_DEBUG_WRAPPERS -//D -//D #undef realloc -//D #undef free #else // ! UMM_POISON_CHECK && ! DEBUG_ESP_OOM extern "C" void* memalign(size_t alignment, size_t size); @@ -403,12 +398,6 @@ static void isr_check__flash_not_safe(const void *caller) { // When selected, do Integrity Check first. Verifies the heap management // information is not corrupt. Followed by Full Poison Check before *alloc // operation. -//D -//D #undef malloc -//D #undef calloc -//D #undef realloc -//D #undef free -//D #undef memalign /////////////////////////////////////////////////////////////////////////////// // Common Heap debug helper functions for each alloc operation @@ -712,18 +701,114 @@ void system_show_malloc(void) #endif } +#if (NONOSDK >= (0x30000)) +//////////////////////////////////////////////////////////////////////////////// +/* + New for NON-OS SDK 3.0.0 and up + Needed for WPA2 Enterprise support. This was not present in SDK pre 3.0 + + The NON-OS SDK 3.0.x has breaking changes to pvPortMalloc. They added one more + argument for selecting a heap. To avoid breaking the build, I renamed their + breaking version to sdk3_pvPortMalloc. To complete the fix, the LIBS need to + be edited. + + Also in the release are low-level functions pvPortZallocIram and + pvPortCallocIram, which are not documented in the Espressif NONOS SDK manual. + No issues in providing replacements. For the non-Arduino ESP8266 applications, + pvPortZallocIram and pvPortCallocIram would have been selected through the + macros like os_malloc defined in `mem.h`. + + OOM - Implementation strategy - Native v3.0 SDK + * For functions `pvPortMalloc(,,,true);` and `pvPortMallocIram(,,,);` on a + failed IRAM alloc, try DRAM. + * For function `pvPortMalloc(,,,false);` use DRAM only - on fail, do not + try IRAM. + + WPA2 Enterprise connect crashing is fixed at v3.0.2 and up. +*/ +#ifdef UMM_HEAP_IRAM +void* IRAM_ATTR sdk3_pvPortMalloc(size_t size, const char* file, int line, bool iram) +{ + void* caller = __builtin_return_address(0); + if (iram) { + HeapSelectIram ephemeral; + void* ret = _heap_pvPortMalloc(size, file, line, caller); + if (ret) return ret; + } + { + HeapSelectDram ephemeral; + return _heap_pvPortMalloc(size, file, line, caller); + } +} + +void* IRAM_ATTR pvPortCallocIram(size_t count, size_t size, const char* file, int line) +{ + void* caller = __builtin_return_address(0); + { + HeapSelectIram ephemeral; + void* ret = _heap_pvPortCalloc(count, size, file, line, caller); + if (ret) return ret; + } + { + HeapSelectDram ephemeral; + return _heap_pvPortCalloc(count, size, file, line, caller); + } +} + +void* IRAM_ATTR pvPortZallocIram(size_t size, const char* file, int line) +{ + void* caller = __builtin_return_address(0); + { + HeapSelectIram ephemeral; + void* ret = _heap_pvPortCalloc(1, size, file, line, caller); + if (ret) return ret; + } + { + HeapSelectDram ephemeral; + return _heap_pvPortCalloc(1, size, file, line, caller); + } +} +#define CONFIG_IRAM_MEMORY 1 + +#else +// For sdk3_pvPortMalloc, the bool argument is ignored and intentionally omitted. +extern "C" void* sdk3_pvPortMalloc(size_t size, const char* file, int line) __attribute__ ((alloc_size(1), malloc, nothrow, alias("pvPortMalloc"))); +extern "C" void* pvPortCallocIram(size_t count, size_t size, const char* file, int line) __attribute__((alloc_size(1, 2), malloc, nothrow, alias("pvPortCalloc"))); +extern "C" void* pvPortZallocIram(size_t size, const char* file, int line) __attribute__((alloc_size(1), malloc, nothrow, alias("pvPortZalloc"))); +#define CONFIG_IRAM_MEMORY 0 +#endif // #ifdef UMM_HEAP_IRAM + +/* + We do not need the function user_iram_memory_is_enabled(). + 1. It was used by mem_manager.o which was replaced with this custom heap + implementation. IRAM memory selection is handled differently for + Arduino ESP8266. + 2. In libmain.a, Cache_Read_Enable_New uses it for cache size. However, When + using IRAM for memory or running with 48K IRAM for code, we use a + replacement Cache_Read_Enable to correct the cache size ignoring + Cache_Read_Enable_New's selected value. + 3. Create a linker conflicts in the event the sketch author tries to control + IRAM heap through this method. +*/ +uint32 IRAM_ATTR user_iram_memory_is_enabled(void) +{ + return CONFIG_IRAM_MEMORY; +} +#endif // #if (NONOSDK >= (0x30000)) + + /////////////////////////////////////////////////////////////////////////////// // heap allocator for "new" (ABI) - To support collecting OOM info, always defined #if DEV_DEBUG_ABI_CPP // In test Sketch, set abi_new_print=true/false around test function calls. bool abi_new_print = false; +#define DEBUG_ABI_CPP_PRINTF ets_uart_printf // _dbg_abi_print_pstr is shared (private) between abi.cpp and heap.cpp -extern "C" void _dbg_abi_print_pstr(const char* op, const char *function_name, const void* caller) { +extern "C" void _dbg_abi_print_pstr(const char* op, const char *function_name) { if (abi_new_print) { uint32_t saved_ps = xt_rsil(DEFAULT_CRITICAL_SECTION_INTLEVEL); DEBUG_HEAP_PRINTF("\nTrace %s: ", op); - if (caller) DEBUG_HEAP_PRINTF("caller(%p), ", caller); if (withinISR(saved_ps)) { DEBUG_HEAP_PRINTF("FN(%p)", function_name); } else { @@ -732,14 +817,15 @@ extern "C" void _dbg_abi_print_pstr(const char* op, const char *function_name, c strcpy_P(buf, function_name); DEBUG_HEAP_PRINTF("'%s'", buf); } - if (caller) DEBUG_HEAP_PRINTF("\n"); xt_wsr_ps(saved_ps); } } -#define DEBUG_DELETE_OP_PRINTF() do { _dbg_abi_print_pstr("delete_op", __PRETTY_FUNCTION__, __builtin_return_address(0)); } while (false) +// #define DEBUG_DELETE_OP_PRINT_FN() do { _dbg_abi_print_pstr("delete_op", __PRETTY_FUNCTION__, __builtin_return_address(0)); } while (false) +#define DEBUG_DELETE_OP_PRINT_FN() do { _dbg_abi_print_pstr("delete_op", __PRETTY_FUNCTION__); } while (false) #else -#define DEBUG_DELETE_OP_PRINTF(...) do { } while (false) +#define DEBUG_DELETE_OP_PRINT_FN(...) do { } while (false) +#define DEBUG_ABI_CPP_PRINTF(...) #endif @@ -767,7 +853,7 @@ extern "C" void _dbg_abi_print_pstr(const char* op, const char *function_name, c // "memalign" in the name will have the "alignment" argument before the "size". void* _heap_abi_memalign(size_t alignment, size_t size, bool unhandled, const void* const caller) { - DEBUG_HEAP_PRINTF(" _heap_abi_memalign(alignment(%u), size(%u), unhandled(%s), caller(%p))\n", alignment, size, (unhandled) ? "true" : "false", caller); + DEBUG_ABI_CPP_PRINTF(" _heap_abi_memalign(alignment(%u), size(%u), unhandled(%s), caller(%p))\n", alignment, size, (unhandled) ? "true" : "false", caller); // A comment from libstdc new_op.cc says: "malloc (0) is unpredictable; // avoid it." This behavoir is only done for the new operator. Our malloc is // happy to return a null pointer for a zero size allocation; however, the @@ -796,7 +882,7 @@ void* _heap_abi_memalign(size_t alignment, size_t size, bool unhandled, const vo #elif USE_HEAP_ABI_MALLOC void* _heap_abi_malloc(size_t size, bool unhandled, const void* const caller) { - DEBUG_HEAP_PRINTF(" _heap_abi_malloc(size(%u), unhandled(%s), caller(%p))\n", size, (unhandled) ? "true" : "false", caller); + DEBUG_ABI_CPP_PRINTF(" _heap_abi_malloc(size(%u), unhandled(%s), caller(%p))\n", size, (unhandled) ? "true" : "false", caller); /* malloc (0) is unpredictable; avoid it. */ if (__builtin_expect(0 == size, false)) { @@ -821,102 +907,9 @@ void* _heap_abi_malloc(size_t size, bool unhandled, const void* const caller) } #endif -#if (NONOSDK >= (0x30000)) -//////////////////////////////////////////////////////////////////////////////// -/* - New for NON-OS SDK 3.0.0 and up - Needed for WPA2 Enterprise support. This was not present in SDK pre 3.0 - - The NON-OS SDK 3.0.x has breaking changes to pvPortMalloc. They added one more - argument for selecting a heap. To avoid breaking the build, I renamed their - breaking version to sdk3_pvPortMalloc. To complete the fix, the LIBS need to - be edited. - - Also in the release are low-level functions pvPortZallocIram and - pvPortCallocIram, which are not documented in the Espressif NONOS SDK manual. - No issues in providing replacements. For the non-Arduino ESP8266 applications, - pvPortZallocIram and pvPortCallocIram would have been selected through the - macros like os_malloc defined in `mem.h`. - - OOM - Implementation strategy - Native v3.0 SDK - * For functions `pvPortMalloc(,,,true);` and `pvPortMallocIram(,,,);` on a - failed IRAM alloc, try DRAM. - * For function `pvPortMalloc(,,,false);` use DRAM only - on fail, do not - try IRAM. - - WPA2 Enterprise connect crashing is fixed at v3.0.2 and up. -*/ -#ifdef UMM_HEAP_IRAM -void* IRAM_ATTR sdk3_pvPortMalloc(size_t size, const char* file, int line, bool iram) -{ - void* caller = __builtin_return_address(0); - if (iram) { - HeapSelectIram ephemeral; - void* ret = _heap_pvPortMalloc(size, file, line, caller); - if (ret) return ret; - } - { - HeapSelectDram ephemeral; - return _heap_pvPortMalloc(size, file, line, caller); - } -} - -void* IRAM_ATTR pvPortCallocIram(size_t count, size_t size, const char* file, int line) -{ - void* caller = __builtin_return_address(0); - { - HeapSelectIram ephemeral; - void* ret = _heap_pvPortCalloc(count, size, file, line, caller); - if (ret) return ret; - } - { - HeapSelectDram ephemeral; - return _heap_pvPortCalloc(count, size, file, line, caller); - } -} - -void* IRAM_ATTR pvPortZallocIram(size_t size, const char* file, int line) -{ - void* caller = __builtin_return_address(0); - { - HeapSelectIram ephemeral; - void* ret = _heap_pvPortCalloc(1, size, file, line, caller); - if (ret) return ret; - } - { - HeapSelectDram ephemeral; - return _heap_pvPortCalloc(1, size, file, line, caller); - } -} -#define CONFIG_IRAM_MEMORY 1 - -#else -// For sdk3_pvPortMalloc, the bool argument is ignored and intentionally omitted. -extern "C" void* sdk3_pvPortMalloc(size_t size, const char* file, int line) __attribute__ ((alloc_size(1), malloc, nothrow, alias("pvPortMalloc"))); -extern "C" void* pvPortCallocIram(size_t count, size_t size, const char* file, int line) __attribute__((alloc_size(1, 2), malloc, nothrow, alias("pvPortCalloc"))); -extern "C" void* pvPortZallocIram(size_t size, const char* file, int line) __attribute__((alloc_size(1), malloc, nothrow, alias("pvPortZalloc"))); -#define CONFIG_IRAM_MEMORY 0 -#endif // #ifdef UMM_HEAP_IRAM - -/* - We do not need the function user_iram_memory_is_enabled(). - 1. It was used by mem_manager.o which was replaced with this custom heap - implementation. IRAM memory selection is handled differently for - Arduino ESP8266. - 2. In libmain.a, Cache_Read_Enable_New uses it for cache size. However, When - using IRAM for memory or running with 48K IRAM for code, we use a - replacement Cache_Read_Enable to correct the cache size ignoring - Cache_Read_Enable_New's selected value. - 3. Create a linker conflicts in the event the sketch author tries to control - IRAM heap through this method. -*/ -uint32 IRAM_ATTR user_iram_memory_is_enabled(void) -{ - return CONFIG_IRAM_MEMORY; -} -#endif // #if (NONOSDK >= (0x30000)) }; // extern "C" { + #if defined(ENABLE_THICK_DEBUG_WRAPPERS) /////////////////////////////////////////////////////////////////////////////// // Replacement C++ delete operator to capture callers address @@ -936,7 +929,8 @@ void _heap_delete(void* ptr, const void* caller) noexcept // del_op void operator delete (void* ptr) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), caller(%p)\n", ptr, __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } @@ -944,15 +938,17 @@ void operator delete (void* ptr) noexcept // del_opnt void operator delete (void *ptr, const std::nothrow_t&) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), std::nothrow_t&, caller(%p)\n", ptr, __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } // del_ops -void operator delete (void* ptr, std::size_t) noexcept +void operator delete (void* ptr, [[maybe_unused]]std::size_t size) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), size(%u), caller(%p)\n", ptr, size, __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } @@ -960,7 +956,8 @@ void operator delete (void* ptr, std::size_t) noexcept // del_opv void operator delete[] (void *ptr) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), caller(%p)\n", ptr, __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } @@ -968,15 +965,17 @@ void operator delete[] (void *ptr) noexcept // del_opvnt void operator delete[] (void *ptr, const std::nothrow_t&) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), std::nothrow_t, caller(%p)\n", ptr, __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } // del_opvs -void operator delete[] (void *ptr, std::size_t) noexcept +void operator delete[] (void *ptr,[[maybe_unused]]std::size_t size) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), size(%u), caller(%p)\n", ptr, size, __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } @@ -984,49 +983,55 @@ void operator delete[] (void *ptr, std::size_t) noexcept #if defined(__cpp_exceptions) #if defined(UMM_ENABLE_MEMALIGN) // del_opa -void operator delete (void* ptr, std::align_val_t) noexcept +void operator delete (void* ptr, [[maybe_unused]]std::align_val_t alignment) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), alignment(%u), caller(%p)\n", ptr, std::size_t(alignment), __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } // del_opant -void operator delete (void *ptr, std::align_val_t, const std::nothrow_t&) noexcept +void operator delete (void *ptr, [[maybe_unused]]std::align_val_t alignment, const std::nothrow_t&) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), alignment(%u), std::nothrow_t, caller(%p)\n", ptr, std::size_t(alignment), __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } // del_opsa -void operator delete (void* ptr, std::size_t, std::align_val_t) noexcept +void operator delete (void* ptr, [[maybe_unused]]std::size_t size, [[maybe_unused]]std::align_val_t alignment) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), size(%u), alignment(%u), caller(%p)\n", ptr, size, std::size_t(alignment), __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } // del_opva -void operator delete[] (void *ptr, std::align_val_t) noexcept +void operator delete[] (void *ptr, [[maybe_unused]]std::align_val_t alignment) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), alignment(%u), caller(%p)\n", ptr, std::size_t(alignment), __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } // del_opvant -void operator delete[] (void *ptr, std::align_val_t, const std::nothrow_t&) noexcept +void operator delete[] (void *ptr, [[maybe_unused]]std::align_val_t alignment, const std::nothrow_t&) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), alignment(%u), std::nothrow_t, caller(%p)\n", ptr, std::size_t(alignment), __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } // del_opvsa -void operator delete[] (void *ptr, std::size_t, std::align_val_t) noexcept +void operator delete[] (void *ptr, [[maybe_unused]]std::size_t size, [[maybe_unused]]std::align_val_t alignment) noexcept { - DEBUG_DELETE_OP_PRINTF(); + DEBUG_DELETE_OP_PRINT_FN(); + DEBUG_ABI_CPP_PRINTF(", ptr(%p), size(%u), alignment(%u), caller(%p)\n", ptr, size, std::size_t(alignment), __builtin_return_address(0)); _heap_delete(ptr, __builtin_return_address(0)); } diff --git a/cores/esp8266/umm_malloc/umm_malloc.cpp b/cores/esp8266/umm_malloc/umm_malloc.cpp index fb7763ecb1..60a9a2380c 100644 --- a/cores/esp8266/umm_malloc/umm_malloc.cpp +++ b/cores/esp8266/umm_malloc/umm_malloc.cpp @@ -969,14 +969,15 @@ void *umm_malloc(size_t size) } /* - * Allocations default to 8-byte alignment same as __STDCPP_DEFAULT_NEW_ALIGNMENT__ - * No need to execute extra alignment logic for small alignments. + * Allocations default to 8-byte alignment, same as __STDCPP_DEFAULT_NEW_ALIGNMENT__. + * There is no need to execute extra alignment logic for small alignments. + * + * Side note when you add '-faligned-new=4' or other non-8 values to the + * build the GCC compiler complains with: "cc1: warning: command-line option + * '-faligned-new=4' is valid for C++/ObjC++ but not for C." */ - - static_assert(__STDCPP_DEFAULT_NEW_ALIGNMENT__ == 8u); - static_assert(__STDCPP_DEFAULT_NEW_ALIGNMENT__ == sizeof(umm_block)); if (alignment <= sizeof(umm_block)) { - alignment = 0u; // Use implementation default, 8. + alignment = 0u; // Use implementation default/minimum, 8. } #endif