From 9c2e0d84f84fe7c38b1e9f7a127efc540b43f5aa Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 19 Dec 2011 18:17:18 -0500 Subject: SH-2789 WIP - various fixes to force 16-byte alignment --- indra/llcommon/llmemory.cpp | 9 +++++ indra/llcommon/llmemory.h | 9 +++-- indra/llmath/lloctree.h | 4 +- indra/llmath/llvector4a.cpp | 7 +++- indra/llmath/llvolumeoctree.h | 14 ++++++- indra/llmath/tests/alignment_test.cpp | 74 +++++++++++++++-------------------- indra/newview/lldrawable.h | 10 +++++ indra/newview/lldynamictexture.h | 12 +++++- indra/newview/llface.h | 11 ++++++ indra/newview/llspatialpartition.cpp | 2 +- indra/newview/llspatialpartition.h | 24 +++++++++++- indra/newview/llviewercamera.h | 9 +++++ indra/newview/llvoavatar.h | 10 +++++ indra/newview/llvoavatarself.h | 10 +++++ 14 files changed, 151 insertions(+), 54 deletions(-) mode change 100644 => 100755 indra/llmath/llvector4a.cpp mode change 100644 => 100755 indra/llmath/llvolumeoctree.h mode change 100644 => 100755 indra/newview/lldynamictexture.h mode change 100644 => 100755 indra/newview/llface.h mode change 100644 => 100755 indra/newview/llvoavatarself.h diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 3b9758f996..22204e756a 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -61,6 +61,15 @@ BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE; LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker; #endif +void ll_assert_aligned_func(uintptr_t ptr,U32 alignment) +{ + if (ptr%alignment!=0) + { + llwarns << "alignment check failed" << llendl; + } + llassert(ptr%alignment==0); +} + //static void LLMemory::initClass() { diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index baf91bb96d..c61d06e924 100755 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -27,7 +27,7 @@ #define LLMEMORY_H #include "llmemtype.h" -#if LL_DEBUG +#if !LL_USE_TCMALLOC inline void* ll_aligned_malloc( size_t size, int align ) { void* mem = malloc( size + (align - 1) + sizeof(void*) ); @@ -94,7 +94,8 @@ inline void ll_aligned_free_32(void *p) free(p); // posix_memalign() is compatible with heap deallocator #endif } -#else // LL_DEBUG + +#else // USE_TCMALLOC // ll_aligned_foo are noops now that we use tcmalloc everywhere (tcmalloc aligns automatically at appropriate intervals) #define ll_aligned_malloc( size, align ) malloc(size) #define ll_aligned_free( ptr ) free(ptr) @@ -514,8 +515,10 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr) #define CHECK_ALIGNMENT +LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); + #ifdef CHECK_ALIGNMENT -#define ll_assert_aligned(ptr,alignment) llassert((reinterpret_cast(ptr))%(alignment) == 0) +#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast(ptr),((U32)alignment)) #else #define ll_assert_aligned(ptr,alignment) #endif diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 3c1ae45d68..374858be51 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -88,7 +88,7 @@ public: typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; - /*void* operator new(size_t size) + void* operator new(size_t size) { return ll_aligned_malloc_16(size); } @@ -96,7 +96,7 @@ public: void operator delete(void* ptr) { ll_aligned_free_16(ptr); - }*/ + } LLOctreeNode( const LLVector4a& center, const LLVector4a& size, diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp old mode 100644 new mode 100755 index 49b8754cd0..7602ef0cb2 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -41,11 +41,15 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast ( F /*static */void LLVector4a::memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes) { + memcpy((void*)dst,(const void*)src,bytes); +#if 0 assert(src != NULL); assert(dst != NULL); assert(bytes > 0); assert((bytes % sizeof(F32))== 0); - + ll_assert_aligned(src,16); + ll_assert_aligned(dst,16); + F32* end = dst + (bytes / sizeof(F32) ); if (bytes > 64) @@ -87,6 +91,7 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast ( F dst += 4; src += 4; } +#endif } void LLVector4a::setRotated( const LLRotation& rot, const LLVector4a& vec ) diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h old mode 100644 new mode 100755 index 688d91dc40..6de7b223be --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -73,6 +73,16 @@ class LLVolumeOctreeListener : public LLOctreeListener { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVolumeOctreeListener(LLOctreeNode* node); ~LLVolumeOctreeListener(); @@ -99,8 +109,8 @@ public: public: - LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector4a mExtents[2]; // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children }; class LLOctreeTriangleRayIntersect : public LLOctreeTraveler diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp index 6b4a454fd2..51a7051e69 100755 --- a/indra/llmath/tests/alignment_test.cpp +++ b/indra/llmath/tests/alignment_test.cpp @@ -34,10 +34,21 @@ #include "../llsimdmath.h" #include "../llvector4a.h" +void* operator new(size_t size) +{ + return ll_aligned_malloc_16(size); +} + +void operator delete(void *p) +{ + ll_aligned_free_16(p); +} + namespace tut { #define is_aligned(ptr,alignment) ((reinterpret_cast(ptr))%(alignment)==0) +#define is_aligned_relative(ptr,base_ptr,alignment) ((reinterpret_cast(ptr)-reinterpret_cast(base_ptr))%(alignment)==0) struct alignment_test {}; @@ -51,38 +62,40 @@ class MyVector4a LLQuad mQ; } LL_ALIGN_POSTFIX(16); -LL_ALIGN_PREFIX(64) -class MyBigBlob +// Verify that aligned allocators perform as advertised. +template<> template<> +void alignment_test_object_t::test<1>() { -public: - ~MyBigBlob() {} -private: - LLQuad mQ[4]; -} LL_ALIGN_POSTFIX(64); + const int num_tests = 7; + void *align_ptr; + for (int i=0; i template<> -void alignment_test_object_t::test<1>() +void alignment_test_object_t::test<2>() { ensure("LLAlignment reality is broken: ", (1==1)); MyVector4a vec1; ensure("LLAlignment vec1 unaligned", is_aligned(&vec1,16)); - MyBigBlob bb1; - ensure("LLAlignment bb1 unaligned", is_aligned(&bb1,64)); - - MyVector4a veca[12]; ensure("LLAlignment veca unaligned", is_aligned(veca,16)); - - MyBigBlob bba[12]; - ensure("LLAlignment bba unaligned", is_aligned(bba,64)); } // Heap allocation of objects and arrays. template<> template<> -void alignment_test_object_t::test<2>() +void alignment_test_object_t::test<3>() { const int ARR_SIZE = 7; for(int i=0; i() } MyVector4a *veca = new MyVector4a[ARR_SIZE]; + ensure("LLAligment veca base", is_aligned(veca,16)); for(int i=0; i~MyBigBlob(); - _aligned_free(aligned_addr); - } - - ensure("LLAlignment big blob size",sizeof(MyBigBlob)==64); - void *aligned_addr = _aligned_malloc(ARR_SIZE*sizeof(MyBigBlob),64); - MyBigBlob *bba = new(aligned_addr) MyBigBlob[ARR_SIZE]; - std::cout << "aligned_addr " << aligned_addr << std::endl; - std::cout << "bba " << bba << std::endl; - for(int i=0; i instance_list_t; static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; diff --git a/indra/newview/llface.h b/indra/newview/llface.h old mode 100644 new mode 100755 index 82e4ab61b7..feb6244f72 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -59,6 +59,17 @@ class LLFace { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + + LLFace(const LLFace& rhs) { *this = rhs; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index a8b5ee47d1..4c45ac6b47 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1196,7 +1196,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mCurUpdatingSlotp(NULL), mCurUpdatingTexture (NULL) { - ll_assert_aligned(this,64); + ll_assert_aligned(this,16); sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index cbd4507f84..22bea69df3 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -68,6 +68,16 @@ protected: ~LLDrawInfo(); public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLDrawInfo(const LLDrawInfo& rhs) { @@ -106,7 +116,7 @@ public: F32 mPartSize; F32 mVSize; LLSpatialGroup* mGroup; - LLFace* mFace; //associated face + LL_ALIGN_16(LLFace* mFace); //associated face F32 mDistance; U32 mDrawMode; @@ -181,7 +191,7 @@ public: }; }; -LL_ALIGN_PREFIX(64) +LL_ALIGN_PREFIX(16) class LLSpatialGroup : public LLOctreeListener { friend class LLSpatialPartition; @@ -193,6 +203,16 @@ public: *this = rhs; } + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + const LLSpatialGroup& operator=(const LLSpatialGroup& rhs) { llerrs << "Illegal operation!" << llendl; diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index 7257297cfd..d2624ba14e 100755 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -55,6 +55,15 @@ LL_ALIGN_PREFIX(16) class LLViewerCamera : public LLCamera, public LLSingleton { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } typedef enum { diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 82157436b9..20ea3686d6 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -90,6 +90,16 @@ protected: **/ public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual void markDead(); static void initClass(); // Initialize data that's only init'd once per class. diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h old mode 100644 new mode 100755 index 74ff47a3e4..23a2025e70 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -48,6 +48,16 @@ class LLVOAvatarSelf : **/ public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVOAvatarSelf(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual ~LLVOAvatarSelf(); virtual void markDead(); -- cgit v1.2.3