From 0c742d59e58dd4c7a5a608e5d243d42319a7357a Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 25 Dec 2016 22:03:05 +0100 Subject: [PATCH] Fix crash due to incorrect alignment when building Eigen with AVX extensions Consequentially, we now use 32-byte alignment when building with eigen if __AVX__ is set. --- doc/ReleaseNotes | 1 + dtool/src/dtoolbase/deletedBufferChain.h | 4 ++++ dtool/src/dtoolbase/dlmalloc_src.cxx | 5 +++++ dtool/src/dtoolbase/dtoolbase.h | 2 +- dtool/src/dtoolbase/memoryHook.I | 12 +++++++++++- 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/doc/ReleaseNotes b/doc/ReleaseNotes index cd6bdf2f4c..74a0a9ea05 100644 --- a/doc/ReleaseNotes +++ b/doc/ReleaseNotes @@ -53,6 +53,7 @@ This issue fixes several bugs that were still found in 1.9.2. * Fix back-to-front sorting when gl-coordinate-system is changed * Now also compiles on older Linux distros (eg. CentOS 5 / manylinux1) * get_keyboard_map now includes keys on layouts with special characters +* Fix crash due to incorrect alignment when compiling Eigen with AVX ------------------------ RELEASE 1.9.2 ------------------------ diff --git a/dtool/src/dtoolbase/deletedBufferChain.h b/dtool/src/dtoolbase/deletedBufferChain.h index 301ee5d297..a71bc90b45 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.h +++ b/dtool/src/dtoolbase/deletedBufferChain.h @@ -105,7 +105,11 @@ private: #elif defined(LINMATH_ALIGN) // With SSE2 alignment, we need all 16 bytes to preserve alignment. +#ifdef __AVX__ + static const size_t flag_reserved_bytes = 32; +#else static const size_t flag_reserved_bytes = 16; +#endif #else // Otherwise, we only need enough space for the Integer itself. diff --git a/dtool/src/dtoolbase/dlmalloc_src.cxx b/dtool/src/dtoolbase/dlmalloc_src.cxx index 4e21f4c914..dcbb0daa25 100644 --- a/dtool/src/dtoolbase/dlmalloc_src.cxx +++ b/dtool/src/dtoolbase/dlmalloc_src.cxx @@ -453,8 +453,13 @@ DEFAULT_MMAP_THRESHOLD default: 256K // drose: We require 16-byte alignment of certain structures, to // support SSE2. We don't strictly have to align *everything*, but // it's just easier to do so. +#ifdef __AVX__ +// Eigen requires 32-byte alignment when using AVX instructions. +#define MALLOC_ALIGNMENT ((size_t)32U) +#else #define MALLOC_ALIGNMENT ((size_t)16U) #endif +#endif #ifndef WIN32 #ifdef _WIN32 diff --git a/dtool/src/dtoolbase/dtoolbase.h b/dtool/src/dtoolbase/dtoolbase.h index 2c883f8220..27add7c84d 100644 --- a/dtool/src/dtoolbase/dtoolbase.h +++ b/dtool/src/dtoolbase/dtoolbase.h @@ -372,7 +372,7 @@ // enforce alignment externally. #define MEMORY_HOOK_DO_ALIGN 1 -#elif defined(IS_OSX) || defined(_WIN64) +#elif (defined(IS_OSX) || defined(_WIN64)) && !defined(__AVX__) // The OS-provided malloc implementation will do the required // alignment. #undef MEMORY_HOOK_DO_ALIGN diff --git a/dtool/src/dtoolbase/memoryHook.I b/dtool/src/dtoolbase/memoryHook.I index 9286a18d7a..ecccf07d65 100644 --- a/dtool/src/dtoolbase/memoryHook.I +++ b/dtool/src/dtoolbase/memoryHook.I @@ -55,7 +55,12 @@ get_memory_alignment() { // We require 16-byte alignment of certain structures, to support // SSE2. We don't strictly have to align *everything*, but it's just // easier to do so. +#ifdef __AVX__ + // Eigen requires 32-byte alignment when using AVX instructions. + const size_t alignment_size = 32; +#else const size_t alignment_size = 16; +#endif #else // Otherwise, use word alignment. const size_t alignment_size = sizeof(void *); @@ -79,7 +84,12 @@ get_header_reserved_bytes() { #ifdef LINMATH_ALIGN // If we're doing SSE2 alignment, we must reserve a full 16-byte // block, since anything less than that will spoil the alignment. - static const size_t header_reserved_bytes = 16; +#ifdef __AVX__ + // Eigen requires 32-byte alignment when using AVX instructions. + const size_t header_reserved_bytes = 32; +#else + const size_t header_reserved_bytes = 16; +#endif #elif defined(MEMORY_HOOK_DO_ALIGN) // If we're just aligning to words, we reserve a block as big as two