mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-06-04 18:54:00 +08:00
Fix bug in handmade_aligned_realloc
This commit is contained in:
parent
6728683938
commit
044f3f6234
@ -101,12 +101,12 @@ inline void throw_std_bad_alloc()
|
|||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC inline void* handmade_aligned_malloc(std::size_t size, std::size_t alignment = EIGEN_DEFAULT_ALIGN_BYTES)
|
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_assert(alignment >= sizeof(void*) && alignment <= 128 && (alignment & (alignment-1)) == 0 && "Alignment must be at least sizeof(void*), less than or equal to 128, and a power of 2");
|
||||||
void* original = std::malloc(size + alignment);
|
void* original = std::malloc(size + alignment);
|
||||||
if (original == 0) return 0;
|
if (original == 0) return 0;
|
||||||
uint8_t offset = alignment - (reinterpret_cast<std::size_t>(original) & (alignment - 1));
|
uint8_t offset = static_cast<uint8_t>(alignment - (reinterpret_cast<std::size_t>(original) & (alignment - 1)));
|
||||||
void* aligned = static_cast<char*>(original) + offset;
|
void* aligned = static_cast<void*>(static_cast<uint8_t*>(original) + offset);
|
||||||
*(static_cast<char*>(aligned) - 1) = offset;
|
*(static_cast<uint8_t*>(aligned) - 1) = offset;
|
||||||
return aligned;
|
return aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +114,8 @@ EIGEN_DEVICE_FUNC inline void* handmade_aligned_malloc(std::size_t size, std::si
|
|||||||
EIGEN_DEVICE_FUNC inline void handmade_aligned_free(void *ptr)
|
EIGEN_DEVICE_FUNC inline void handmade_aligned_free(void *ptr)
|
||||||
{
|
{
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
uint8_t offset = *(static_cast<char*>(ptr) - 1);
|
uint8_t offset = static_cast<uint8_t>(*(static_cast<uint8_t*>(ptr) - 1));
|
||||||
void* original = static_cast<char*>(ptr) - offset;
|
void* original = static_cast<void*>(static_cast<uint8_t*>(ptr) - offset);
|
||||||
std::free(original);
|
std::free(original);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,21 +125,23 @@ EIGEN_DEVICE_FUNC inline void handmade_aligned_free(void *ptr)
|
|||||||
* Since we know that our handmade version is based on std::malloc
|
* Since we know that our handmade version is based on std::malloc
|
||||||
* we can use std::realloc to implement efficient reallocation.
|
* we can use std::realloc to implement efficient reallocation.
|
||||||
*/
|
*/
|
||||||
EIGEN_DEVICE_FUNC inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t alignment = EIGEN_DEFAULT_ALIGN_BYTES)
|
EIGEN_DEVICE_FUNC inline void* handmade_aligned_realloc(void* ptr, std::size_t new_size, std::size_t old_size, std::size_t alignment = EIGEN_DEFAULT_ALIGN_BYTES)
|
||||||
{
|
{
|
||||||
if (ptr == 0) return handmade_aligned_malloc(size, alignment);
|
if (ptr == 0) return handmade_aligned_malloc(new_size, alignment);
|
||||||
uint8_t previous_offset = *(static_cast<char*>(ptr) - 1);
|
uint8_t old_offset = *(static_cast<uint8_t*>(ptr) - 1);
|
||||||
void* previous_original = static_cast<char*>(ptr) - previous_offset;
|
void* old_original = static_cast<uint8_t*>(ptr) - old_offset;
|
||||||
void* original = std::realloc(previous_original, size + alignment);
|
void* original = std::realloc(old_original, new_size + alignment);
|
||||||
if (original == 0) return 0;
|
if (original == 0) return 0;
|
||||||
if (original != previous_original) {
|
if (original == old_original) return ptr;
|
||||||
uint8_t offset = alignment - (reinterpret_cast<std::size_t>(original) & (alignment - 1));
|
uint8_t offset = static_cast<uint8_t>(alignment - (reinterpret_cast<std::size_t>(original) & (alignment - 1)));
|
||||||
void* aligned = static_cast<char*>(original) + offset;
|
void* aligned = static_cast<void*>(static_cast<uint8_t*>(original) + offset);
|
||||||
std::memmove(aligned, ptr, size);
|
if (offset != old_offset) {
|
||||||
*(static_cast<char*>(aligned) - 1) = offset;
|
const void* src = static_cast<const void*>(static_cast<uint8_t*>(original) + old_offset);
|
||||||
return aligned;
|
std::size_t count = (std::min)(new_size, old_size);
|
||||||
|
std::memmove(aligned, src, count);
|
||||||
}
|
}
|
||||||
return ptr;
|
*(static_cast<uint8_t*>(aligned) - 1) = offset;
|
||||||
|
return aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -217,13 +219,12 @@ EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr)
|
|||||||
EIGEN_DEVICE_FUNC 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);
|
if (ptr == 0) return aligned_malloc(new_size);
|
||||||
EIGEN_UNUSED_VARIABLE(old_size)
|
|
||||||
|
|
||||||
void *result;
|
void *result;
|
||||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||||
|
EIGEN_UNUSED_VARIABLE(old_size)
|
||||||
result = std::realloc(ptr,new_size);
|
result = std::realloc(ptr,new_size);
|
||||||
#else
|
#else
|
||||||
result = handmade_aligned_realloc(ptr,new_size);
|
result = handmade_aligned_realloc(ptr,new_size,old_size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!result && new_size)
|
if (!result && new_size)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user