From a226371371451577f484198457d1386bd6861600 Mon Sep 17 00:00:00 2001 From: Charles Schlosser Date: Sat, 22 Oct 2022 22:51:31 +0000 Subject: [PATCH] Change handmade_aligned_malloc/realloc/free to store a 1 byte offset instead of absolute address --- Eigen/src/Core/util/Memory.h | 54 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index 385f4f4e8..8a724ca47 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -96,19 +96,17 @@ inline void throw_std_bad_alloc() /* ----- Hand made implementations of aligned malloc/free and realloc ----- */ -/** \internal Like malloc, but the returned pointer is guaranteed to be 16-byte aligned. - * Fast, but wastes 16 additional bytes of memory. Does not throw any exception. +/** \internal Like malloc, but the returned pointer is guaranteed to be aligned to `alignment`. + * Fast, but wastes `alignment` additional bytes of memory. Does not throw any exception. */ EIGEN_DEVICE_FUNC inline void* handmade_aligned_malloc(std::size_t size, std::size_t alignment = EIGEN_DEFAULT_ALIGN_BYTES) { eigen_assert(alignment >= sizeof(void*) && (alignment & (alignment-1)) == 0 && "Alignment must be at least sizeof(void*) and a power of 2"); - - EIGEN_USING_STD(malloc) - void *original = malloc(size+alignment); - + void* original = std::malloc(size + alignment); if (original == 0) return 0; - void *aligned = reinterpret_cast((reinterpret_cast(original) & ~(std::size_t(alignment-1))) + alignment); - *(reinterpret_cast(aligned) - 1) = original; + uint8_t offset = alignment - reinterpret_cast(original) & (alignment - 1); + void* aligned = static_cast(original) + offset; + *(static_cast(aligned) - 1) = offset; return aligned; } @@ -116,8 +114,9 @@ EIGEN_DEVICE_FUNC inline void* handmade_aligned_malloc(std::size_t size, std::si EIGEN_DEVICE_FUNC inline void handmade_aligned_free(void *ptr) { if (ptr) { - EIGEN_USING_STD(free) - free(*(reinterpret_cast(ptr) - 1)); + uint8_t offset = *(static_cast(ptr) - 1); + void* original = static_cast(ptr) - offset; + std::free(original); } } @@ -126,20 +125,21 @@ EIGEN_DEVICE_FUNC inline void handmade_aligned_free(void *ptr) * Since we know that our handmade version is based on std::malloc * we can use std::realloc to implement efficient reallocation. */ -inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t = 0) +EIGEN_DEVICE_FUNC inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t alignment = EIGEN_DEFAULT_ALIGN_BYTES) { - if (ptr == 0) return handmade_aligned_malloc(size); - void *original = *(reinterpret_cast(ptr) - 1); - std::ptrdiff_t previous_offset = static_cast(ptr)-static_cast(original); - original = std::realloc(original,size+EIGEN_DEFAULT_ALIGN_BYTES); + if (ptr == 0) return handmade_aligned_malloc(size, alignment); + uint8_t previous_offset = *(static_cast(ptr) - 1); + void* previous_original = static_cast(ptr) - previous_offset; + void* original = std::realloc(previous_original, size + alignment); if (original == 0) return 0; - void *aligned = reinterpret_cast((reinterpret_cast(original) & ~(std::size_t(EIGEN_DEFAULT_ALIGN_BYTES-1))) + EIGEN_DEFAULT_ALIGN_BYTES); - void *previous_aligned = static_cast(original)+previous_offset; - if(aligned!=previous_aligned) - std::memmove(aligned, previous_aligned, size); - - *(reinterpret_cast(aligned) - 1) = original; - return aligned; + if (original != previous_original) { + uint8_t offset = alignment - reinterpret_cast(original) & (alignment - 1); + void* aligned = static_cast(original) + offset; + std::memmove(aligned, ptr, size); + *(static_cast(aligned) - 1) = offset; + return aligned; + } + return ptr; } /***************************************************************************** @@ -214,7 +214,7 @@ EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr) * \brief Reallocates an aligned block of memory. * \throws std::bad_alloc on allocation failure */ -inline void* aligned_realloc(void *ptr, std::size_t new_size, std::size_t old_size) +EIGEN_DEVICE_FUNC inline void* aligned_realloc(void *ptr, std::size_t new_size, std::size_t old_size) { if (ptr == 0) return aligned_malloc(new_size); EIGEN_UNUSED_VARIABLE(old_size) @@ -223,7 +223,7 @@ inline void* aligned_realloc(void *ptr, std::size_t new_size, std::size_t old_si #if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED result = std::realloc(ptr,new_size); #else - result = handmade_aligned_realloc(ptr,new_size,old_size); + result = handmade_aligned_realloc(ptr,new_size); #endif if (!result && new_size) @@ -273,12 +273,12 @@ template<> EIGEN_DEVICE_FUNC inline void conditional_aligned_free(void *p free(ptr); } -template inline void* conditional_aligned_realloc(void* ptr, std::size_t new_size, std::size_t old_size) +template EIGEN_DEVICE_FUNC inline void* conditional_aligned_realloc(void* ptr, std::size_t new_size, std::size_t old_size) { return aligned_realloc(ptr, new_size, old_size); } -template<> inline void* conditional_aligned_realloc(void* ptr, std::size_t new_size, std::size_t) +template<> EIGEN_DEVICE_FUNC inline void* conditional_aligned_realloc(void* ptr, std::size_t new_size, std::size_t) { return std::realloc(ptr, new_size); } @@ -471,7 +471,7 @@ template EIGEN_DEVICE_FUNC inline T* conditional_aligned return result; } -template inline T* conditional_aligned_realloc_new_auto(T* pts, std::size_t new_size, std::size_t old_size) +template EIGEN_DEVICE_FUNC inline T* conditional_aligned_realloc_new_auto(T* pts, std::size_t new_size, std::size_t old_size) { if (NumTraits::RequireInitialization) { return conditional_aligned_realloc_new(pts, new_size, old_size);