diff options
author | 2008-12-15 20:14:59 +0000 | |
---|---|---|
committer | 2008-12-15 20:14:59 +0000 | |
commit | 55b603e4573711ff33a293ed9706c33e92b834fc (patch) | |
tree | c836bb314f6a78d069ebff5c0383fd3d13a6f667 /Eigen/src | |
parent | 763f0a24344139969990009aec018c54bb97b4da (diff) |
* fix a bug I introduced in WithAlignedOperatorNew
* add an important comment
Diffstat (limited to 'Eigen/src')
-rw-r--r-- | Eigen/src/Core/util/Memory.h | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index ab2b87bc5..7dbc8dbd3 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -52,12 +52,21 @@ template <typename T, int Size> struct ei_aligned_array<T,Size,false> T array[Size]; }; -/** \internal allocates \a size * sizeof(\a T) bytes with 16 bytes alignment */ +struct ei_byte_forcing_aligned_malloc +{ + unsigned char c; // sizeof must be 1. +}; + +template<typename T> struct ei_force_aligned_malloc { enum { ret = 0 }; }; +template<> struct ei_force_aligned_malloc<ei_byte_forcing_aligned_malloc> { enum { ret = 1 }; }; + +/** \internal allocates \a size * sizeof(\a T) bytes with 16 bytes alignment. + * */ template<typename T> inline T* ei_aligned_malloc(size_t size) { #ifdef EIGEN_VECTORIZE - if(ei_packet_traits<T>::size>1) + if(ei_packet_traits<T>::size>1 || ei_force_aligned_malloc<T>::ret) { #ifdef _MSC_VER return static_cast<T*>(_aligned_malloc(size*sizeof(T), 16)); @@ -71,7 +80,11 @@ inline T* ei_aligned_malloc(size_t size) } else #endif - return new T[size]; + return new T[size]; // here we really want a new, not a malloc. Justification: if the user uses Eigen on + // some fancy scalar type such as multiple-precision numbers, and this type has a custom operator new, + // then we want to honor this operator new! Anyway this type won't have vectorization so the vectorizing path + // is irrelevant here. Yes, we should say somewhere in the docs that if the user uses a custom scalar type then + // he can't have both vectorization and a custom operator new on his scalar type. } /** \internal free memory allocated with ei_aligned_malloc */ @@ -79,7 +92,7 @@ template<typename T> inline void ei_aligned_free(T* ptr) { #ifdef EIGEN_VECTORIZE - if (ei_packet_traits<T>::size>1) + if (ei_packet_traits<T>::size>1 || ei_force_aligned_malloc<T>::ret) #ifdef _MSC_VER _aligned_free(ptr); #else @@ -167,16 +180,16 @@ struct WithAlignedOperatorNew void *operator new(size_t size) throw() { - return ei_aligned_malloc<char>(size); + return ei_aligned_malloc<ei_byte_forcing_aligned_malloc>(size); } void *operator new[](size_t size) throw() { - return ei_aligned_malloc<char>(size); + return ei_aligned_malloc<ei_byte_forcing_aligned_malloc>(size); } - void operator delete(void * ptr) { ei_aligned_free(static_cast<char *>(ptr)); } - void operator delete[](void * ptr) { ei_aligned_free(static_cast<char *>(ptr)); } + void operator delete(void * ptr) { ei_aligned_free(static_cast<ei_byte_forcing_aligned_malloc *>(ptr)); } + void operator delete[](void * ptr) { ei_aligned_free(static_cast<ei_byte_forcing_aligned_malloc *>(ptr)); } #endif }; |