diff options
| -rw-r--r-- | indra/llcommon/llmemory.h | 14 | ||||
| -rw-r--r-- | indra/llcommon/lltrace.h | 85 | ||||
| -rw-r--r-- | indra/newview/lldrawable.h | 44 |
3 files changed, 103 insertions, 40 deletions
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 4ead45679f..95500753e4 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -39,6 +39,20 @@ class LLMutex ; #define LL_CHECK_MEMORY #endif +#if LL_WINDOWS +#define LL_ALIGN_OF __alignof +#else +#define LL_ALIGN_OF __align_of__ +#endif + +#if LL_WINDOWS +#define LL_DEFAULT_HEAP_ALIGN 8 +#elif LL_DARWIN +#define LL_DEFAULT_HEAP_ALIGN 16 +#elif LL_LINUX +#define LL_DEFAULT_HEAP_ALIGN 8 +#endif + inline void* ll_aligned_malloc( size_t size, int align ) { void* mem = malloc( size + (align - 1) + sizeof(void*) ); diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1a156e583e..8ec0cdc4dc 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -660,7 +660,57 @@ struct MemFootprint<std::list<T> > } }; -template<typename DERIVED> +template <size_t ALIGNMENT, size_t RESERVE> +void* allocAligned(size_t size) +{ + llstatic_assert((ALIGNMENT > 0) && (ALIGNMENT & (ALIGNMENT - 1)) == 0, "Alignment must be a power of 2"); + + void* padded_allocation; + const size_t aligned_reserve = (RESERVE / ALIGNMENT) + + ((RESERVE % ALIGNMENT) ? ALIGNMENT : 0); + const size_t size_with_reserve = size + aligned_reserve; + if (ALIGNMENT <= LL_DEFAULT_HEAP_ALIGN) + { + padded_allocation = malloc(size_with_reserve); + } + else + { +#if LL_WINDOWS + padded_allocation = _aligned_malloc(size_with_reserve, ALIGNMENT); +#elif LL_DARWIN + padded_allocation = ll_aligned_malloc(size_with_reserve, ALIGNMENT); +#else + posix_memalign(&padded_allocation, ALIGNMENT, size_with_reserve); +#endif + } + return (char*)padded_allocation + aligned_reserve; +} + +template<size_t ALIGNMENT, size_t RESERVE> +void deallocAligned(void* ptr) +{ + const size_t aligned_reserve = (RESERVE / ALIGNMENT) + + ((RESERVE % ALIGNMENT) ? ALIGNMENT : 0); + + void* original_allocation = (char*)ptr - aligned_reserve; + + if (ALIGNMENT <= LL_DEFAULT_HEAP_ALIGN) + { + free(original_allocation); + } + else + { +#if LL_WINDOWS + _aligned_free(original_allocation); +#elif LL_DARWIN + ll_aligned_free(original_allocation); +#else + free(original_allocation); +#endif + } +} + +template<typename DERIVED, size_t ALIGNMENT = LL_DEFAULT_HEAP_ALIGN> class MemTrackable { template<typename TRACKED, typename TRACKED_IS_TRACKER> @@ -676,44 +726,49 @@ public: memDisclaim(mMemFootprint); } - void* operator new(size_t allocation_size) + void* operator new(size_t size) { - // reserve 8 bytes for allocation size (and preserving 8 byte alignment of structs) - void* allocation = ::operator new(allocation_size + 8); - *(size_t*)allocation = allocation_size; MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize += allocation_size; + accumulator->mSize += size; accumulator->mAllocatedCount++; } - return (void*)((char*)allocation + 8); + + // reserve 4 bytes for allocation size (and preserving requested alignment) + void* allocation = allocAligned<ALIGNMENT, sizeof(size_t)>(size); + ((size_t*)allocation)[-1] = size; + + return allocation; } void operator delete(void* ptr) { - size_t* allocation_size = (size_t*)((char*)ptr - 8); + size_t allocation_size = ((size_t*)ptr)[-1]; MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize -= *allocation_size; + accumulator->mSize -= allocation_size; accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } - ::delete((char*)ptr - 8); + deallocAligned<ALIGNMENT, sizeof(size_t)>(ptr); } void *operator new [](size_t size) { - size_t* result = (size_t*)malloc(size + 8); - *result = size; MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize += size; accumulator->mAllocatedCount++; } - return (void*)((char*)result + 8); + + // reserve 4 bytes for allocation size (and preserving requested alignment) + void* allocation = allocAligned<ALIGNMENT, sizeof(size_t)>(size); + ((size_t*)allocation)[-1] = size; + + return allocation; } void operator delete[](void* ptr) @@ -726,7 +781,7 @@ public: accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } - ::delete[]((char*)ptr - 8); + deallocAligned<ALIGNMENT, sizeof(size_T)>(ptr); } // claim memory associated with other objects/data as our own, adding to our calculated footprint @@ -783,6 +838,8 @@ public: private: size_t mMemFootprint; + + template<typename TRACKED, typename TRACKED_IS_TRACKER = void> struct TrackMemImpl { diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 9521287a45..161f550bb6 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -60,7 +60,9 @@ const U32 SILHOUETTE_HIGHLIGHT = 0; // All data for new renderer goes into this class. LL_ALIGN_PREFIX(16) -class LLDrawable : public LLViewerOctreeEntryData, public LLTrace::MemTrackable<LLDrawable> +class LLDrawable +: public LLViewerOctreeEntryData, + public LLTrace::MemTrackable<LLDrawable> { public: LLDrawable(const LLDrawable& rhs) : LLViewerOctreeEntryData(rhs) @@ -76,16 +78,6 @@ public: static void initClass(); - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - LLDrawable(LLViewerObject *vobj, bool new_entry = false); void markDead(); // Mark this drawable as dead @@ -93,7 +85,7 @@ public: BOOL isNew() const { return !isState(BUILT); } BOOL isLight() const; - + virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE); LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();} @@ -115,7 +107,7 @@ public: const LLQuaternion& getRotation() const { return mXform.getRotation(); } F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); } S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; } - + void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } LLXformMatrix* getXform() { return &mXform; } @@ -290,33 +282,33 @@ public: ANIMATED_CHILD = 0x20000000, ACTIVE_CHILD = 0x40000000, } EDrawableFlags; - + public: LLXformMatrix mXform; // vis data LLPointer<LLDrawable> mParent; - F32 mDistanceWRTCamera; - + F32 mDistanceWRTCamera; + static F32 sCurPixelAngle; //current pixels per radian static LLTrace::MemStat sMemStat; private: typedef std::vector<LLFace*> face_list_t; - U32 mState; - S32 mRenderType; - LLPointer<LLViewerObject> mVObjp; - face_list_t mFaces; - LLPointer<LLDrawable> mSpatialBridge; - - F32 mRadius; - S32 mGeneration; + U32 mState; + S32 mRenderType; + LLPointer<LLViewerObject> mVObjp; + face_list_t mFaces; + LLPointer<LLDrawable> mSpatialBridge; - LLVector3 mCurrentScale; + F32 mRadius; + S32 mGeneration; - static U32 sNumZombieDrawables; + LLVector3 mCurrentScale; + + static U32 sNumZombieDrawables; static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList; } LL_ALIGN_POSTFIX(16); |
