From 053d97db1b283ca2548dc1f64756ddfc5166158f Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 25 Sep 2013 19:12:35 -0700
Subject: [PATCH] better memory usage for LLTrace (tighter packing of recording
 arrays) removed complicated and unnecessary fast timer gapless handoff logic
 (it should be gapless anyway) improved MemTrackable API, better separation of
 shadow and footprint added memory usage stats to floater_stats.xml

---
 indra/llcommon/llfasttimer.cpp                |  20 +-
 indra/llcommon/llfasttimer.h                  |   4 +-
 indra/llcommon/llmemory.h                     |  49 ++-
 indra/llcommon/lltrace.h                      | 299 ++++++++----------
 indra/llcommon/lltraceaccumulators.h          |  23 +-
 indra/llcommon/lltracerecording.cpp           |   6 +-
 indra/llcommon/lltracethreadrecorder.cpp      |   5 +-
 indra/llimage/llimage.cpp                     |   9 +-
 indra/llui/llfolderview.cpp                   |   2 +-
 indra/llui/llfolderviewitem.cpp               |  16 +-
 indra/llui/lltextbase.cpp                     |  26 +-
 indra/llui/lltextbase.h                       |   2 -
 indra/llui/lluictrl.cpp                       |  22 +-
 indra/llui/llview.cpp                         |   1 -
 indra/llui/llview.h                           |   1 -
 indra/llui/llviewmodel.cpp                    |  18 +-
 indra/llui/llviewmodel.h                      |   2 -
 indra/newview/lldrawable.cpp                  |   1 -
 indra/newview/lldrawable.h                    |   1 -
 indra/newview/lltexturecache.h                |   4 +-
 indra/newview/lltextureview.cpp               |   8 +-
 indra/newview/llviewerobject.cpp              |   1 -
 indra/newview/llviewerobject.h                |   1 -
 indra/newview/llvieweroctree.h                |   2 +-
 indra/newview/llviewerprecompiledheaders.cpp  |   2 +-
 indra/newview/llvocache.cpp                   |   1 -
 indra/newview/llvocache.h                     |   1 -
 .../skins/default/xui/en/floater_stats.xml    |  16 +
 28 files changed, 270 insertions(+), 273 deletions(-)

diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 52b3bb39b20..32ef01b2b68 100755
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -259,15 +259,12 @@ void TimeBlock::updateTimes()
 		&& cur_timer->mParentTimerData.mActiveTimer != cur_timer) // root defined by parent pointing to self
 	{
 		U64 cumulative_time_delta = cur_time - cur_timer->mStartTime;
-		accumulator->mTotalTimeCounter += cumulative_time_delta 
-			- (accumulator->mTotalTimeCounter 
-			- cur_timer->mBlockStartTotalTimeCounter);
+		cur_timer->mStartTime = cur_time;
+
+		accumulator->mTotalTimeCounter += cumulative_time_delta;
 		accumulator->mSelfTimeCounter += cumulative_time_delta - stack_record->mChildTime;
 		stack_record->mChildTime = 0;
 
-		cur_timer->mStartTime = cur_time;
-		cur_timer->mBlockStartTotalTimeCounter = accumulator->mTotalTimeCounter;
-
 		stack_record = &cur_timer->mParentTimerData;
 		accumulator  = &stack_record->mTimeBlock->getCurrentAccumulator();
 		cur_timer    = stack_record->mActiveTimer;
@@ -423,7 +420,6 @@ void TimeBlock::writeLog(std::ostream& os)
 TimeBlockAccumulator::TimeBlockAccumulator() 
 :	mTotalTimeCounter(0),
 	mSelfTimeCounter(0),
-	mStartTotalTimeCounter(0),
 	mCalls(0),
 	mLastCaller(NULL),
 	mActiveCount(0),
@@ -436,7 +432,7 @@ void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other, EBuffe
 	// we can't merge two unrelated time block samples, as that will screw with the nested timings
 	// due to the call hierarchy of each thread
 	llassert(append_type == SEQUENTIAL);
-	mTotalTimeCounter += other.mTotalTimeCounter - other.mStartTotalTimeCounter;
+	mTotalTimeCounter += other.mTotalTimeCounter;
 	mSelfTimeCounter += other.mSelfTimeCounter;
 	mCalls += other.mCalls;
 	mLastCaller = other.mLastCaller;
@@ -449,21 +445,15 @@ void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other )
 {
 	mCalls = 0;
 	mSelfTimeCounter = 0;
+	mTotalTimeCounter = 0;
 
 	if (other)
 	{
-		mStartTotalTimeCounter = other->mTotalTimeCounter;
-		mTotalTimeCounter = mStartTotalTimeCounter;
-
 		mLastCaller = other->mLastCaller;
 		mActiveCount = other->mActiveCount;
 		mMoveUpTree = other->mMoveUpTree;
 		mParent = other->mParent;
 	}
-	else
-	{
-		mStartTotalTimeCounter = mTotalTimeCounter;
-	}
 }
 
 F64Seconds BlockTimer::getElapsedTime()
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 53c61734e58..4eb12907dca 100755
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -71,7 +71,6 @@ class BlockTimer
 
 private:
 	U64						mStartTime;
-	U64						mBlockStartTotalTimeCounter;
 	BlockTimerStackRecord	mParentTimerData;
 };
 
@@ -287,7 +286,6 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer)
 	if (!cur_timer_data) return;
 	TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator();
 	accumulator.mActiveCount++;
-	mBlockStartTotalTimeCounter = accumulator.mTotalTimeCounter;
 	// keep current parent as long as it is active when we are
 	accumulator.mMoveUpTree |= (accumulator.mParent->getCurrentAccumulator().mActiveCount == 0);
 
@@ -312,7 +310,7 @@ LL_FORCE_INLINE BlockTimer::~BlockTimer()
 	TimeBlockAccumulator& accumulator = cur_timer_data->mTimeBlock->getCurrentAccumulator();
 
 	accumulator.mCalls++;
-	accumulator.mTotalTimeCounter += total_time - (accumulator.mTotalTimeCounter - mBlockStartTotalTimeCounter);
+	accumulator.mTotalTimeCounter += total_time;
 	accumulator.mSelfTimeCounter += total_time - cur_timer_data->mChildTime;
 	accumulator.mActiveCount--;
 
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index d3c5e5235d5..2330bfb8eae 100755
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -54,7 +54,7 @@ class LLMutex ;
 #define LL_DEFAULT_HEAP_ALIGN 8
 #endif
 
-inline void* ll_aligned_malloc( size_t size, int align )
+inline void* ll_aligned_malloc_fallback( size_t size, int align )
 {
 	void* mem = malloc( size + (align - 1) + sizeof(void*) );
 	char* aligned = ((char*)mem) + sizeof(void*);
@@ -64,7 +64,7 @@ inline void* ll_aligned_malloc( size_t size, int align )
 	return aligned;
 }
 
-inline void ll_aligned_free( void* ptr )
+inline void ll_aligned_free_fallback( void* ptr )
 {
 	free( ((void**)ptr)[-1] );
 }
@@ -130,7 +130,7 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi
 #if defined(LL_WINDOWS)
 	return _aligned_malloc(size, 32);
 #elif defined(LL_DARWIN)
-	return ll_aligned_malloc( size, 32 );
+	return ll_aligned_malloc_fallback( size, 32 );
 #else
 	void *rtn;
 	if (LL_LIKELY(0 == posix_memalign(&rtn, 32, size)))
@@ -151,6 +151,49 @@ inline void ll_aligned_free_32(void *p)
 #endif
 }
 
+// general purpose dispatch functions that are forced inline so they can compile down to a single call
+LL_FORCE_INLINE void* ll_aligned_malloc(size_t alignment, size_t size)
+{
+	if (LL_DEFAULT_HEAP_ALIGN % alignment == 0)
+	{
+		return malloc(size);
+	}
+	else if (alignment == 16)
+	{
+		return ll_aligned_malloc_16(size);
+	}
+	else if (alignment == 32)
+	{
+		return ll_aligned_malloc_32(size);
+	}
+	else
+	{
+		return ll_aligned_malloc_fallback(size, alignment);
+	}
+}
+
+LL_FORCE_INLINE void ll_aligned_free(size_t alignment, void* ptr)
+{
+	if (alignment == LL_DEFAULT_HEAP_ALIGN)
+	{
+		free(ptr);
+	}
+	else if (alignment == 16)
+	{
+		ll_aligned_free_16(ptr);
+	}
+	else if (alignment == 32)
+	{
+		return ll_aligned_free_32(ptr);
+	}
+	else
+	{
+		return ll_aligned_free_fallback(ptr);
+	}
+}
+
+
+
 #ifndef __DEBUG_PRIVATE_MEM__
 #define __DEBUG_PRIVATE_MEM__  0
 #endif
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 5c833ea2877..355617a8982 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -161,21 +161,6 @@ void sample(SampleStatHandle<T>& measurement, VALUE_T value)
 	measurement.getCurrentAccumulator().sample(storage_value(converted_value));
 }
 
-template<typename T, typename VALUE_T>
-void add(SampleStatHandle<T>& measurement, VALUE_T value)
-{
-	T converted_value(value);
-	SampleAccumulator& acc = measurement.getCurrentAccumulator();
-	if (acc.hasValue())
-	{
-		acc.sample(acc.getLastValue() + converted_value);
-	}
-	else
-	{
-		acc.sample(converted_value);
-	}
-}
-
 template <typename T = F64>
 class CountStatHandle
 :	public TraceType<CountAccumulator>
@@ -296,28 +281,28 @@ class MemStatHandle : public TraceType<MemStatAccumulator>
 	}
 };
 
-inline void claim_mem(MemStatHandle& measurement, size_t size)
+inline void claim_footprint(MemStatHandle& measurement, S32 size)
 {
 	MemStatAccumulator& accumulator = measurement.getCurrentAccumulator();
 	accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size);
 	accumulator.mAllocated.add(1);
 }
 
-inline void disclaim_mem(MemStatHandle& measurement, size_t size)
+inline void disclaim_footprint(MemStatHandle& measurement, S32 size)
 {
 	MemStatAccumulator& accumulator = measurement.getCurrentAccumulator();
 	accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size);
 	accumulator.mDeallocated.add(1);
 }
 
-inline void claim_shadow_mem(MemStatHandle& measurement, size_t size)
+inline void claim_shadow(MemStatHandle& measurement, S32 size)
 {
 	MemStatAccumulator& accumulator = measurement.getCurrentAccumulator();
 	accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size);
 	accumulator.mShadowAllocated.add(1);
 }
 
-inline void disclaim_shadow_mem(MemStatHandle& measurement, size_t size)
+inline void disclaim_shadow(MemStatHandle& measurement, S32 size)
 {
 	MemStatAccumulator& accumulator = measurement.getCurrentAccumulator();
 	accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size);
@@ -327,94 +312,122 @@ inline void disclaim_shadow_mem(MemStatHandle& measurement, size_t size)
 // measures effective memory footprint of specified type
 // specialize to cover different types
 
-template<typename T>
-struct MemFootprint
+template<typename T, typename IS_MEM_TRACKABLE = void>
+struct MeasureMem
 {
-	static size_t measure(const T& value)
+	static size_t measureFootprint(const T& value)
 	{
 		return sizeof(T);
 	}
 
-	static size_t measure()
+	static size_t measureFootprint()
 	{
 		return sizeof(T);
 	}
+
+	static size_t measureShadow(const T& value)
+	{
+		return 0;
+	}
+
+	static size_t measureShadow()
+	{
+		return 0;
+	}
 };
 
 template<typename T>
-struct MemFootprint<T*>
+struct MeasureMem<T, typename T::mem_trackable_tag_t>
 {
-	static size_t measure(const T* value)
+	static size_t measureFootprint(const T& value)
+	{
+		return sizeof(T) + value.getMemFootprint();
+	}
+
+	static size_t measureFootprint()
+	{
+		return sizeof(T);
+	}
+
+	static size_t measureShadow(const T& value)
+	{
+		return value.getMemShadow();
+	}
+
+	static size_t measureShadow()
+	{
+		return MeasureMem<T>::measureShadow();
+	}
+};
+
+
+template<typename T, typename IS_MEM_TRACKABLE>
+struct MeasureMem<T*, IS_MEM_TRACKABLE>
+{
+	static size_t measureFootprint(const T* value)
 	{
 		if (!value)
 		{
 			return 0;
 		}
-		return MemFootprint<T>::measure(*value);
+		return MeasureMem<T>::measureFootprint(*value);
 	}
 
-	static size_t measure()
+	static size_t measureFootprint()
 	{
-		return MemFootprint<T>::measure();
+		return MeasureMem<T>::measureFootprint();
 	}
-};
 
-template<typename T>
-struct MemFootprint<std::basic_string<T> >
-{
-	static size_t measure(const std::basic_string<T>& value)
+	static size_t measureShadow(const T* value)
 	{
-		return value.capacity() * sizeof(T);
+		return MeasureMem<T>::measureShadow(*value);
 	}
 
-	static size_t measure()
+	static size_t measureShadow()
 	{
-		return sizeof(std::basic_string<T>);
+		return MeasureMem<T>::measureShadow();
 	}
 };
 
-template<typename T>
-struct MemFootprint<std::vector<T> >
+template<typename T, typename IS_MEM_TRACKABLE>
+struct MeasureMem<std::basic_string<T>, IS_MEM_TRACKABLE>
 {
-	static size_t measure(const std::vector<T>& value)
+	static size_t measureFootprint(const std::basic_string<T>& value)
 	{
-		return value.capacity() * MemFootprint<T>::measure();
+		return value.capacity() * sizeof(T);
 	}
 
-	static size_t measure()
+	static size_t measureFootprint()
 	{
-		return sizeof(std::vector<T>);
+		return sizeof(std::basic_string<T>);
 	}
-};
 
-template<typename T>
-struct MemFootprint<std::list<T> >
-{
-	static size_t measure(const std::list<T>& value)
+	static size_t measureShadow(const std::basic_string<T>& value)
 	{
-		return value.size() * (MemFootprint<T>::measure() + sizeof(void*) * 2);
+		return 0;
 	}
 
-	static size_t measure()
+	static size_t measureShadow()
 	{
-		return sizeof(std::list<T>);
+		return 0;
 	}
 };
 
 template<typename DERIVED, size_t ALIGNMENT = LL_DEFAULT_HEAP_ALIGN>
 class MemTrackable
 {
-	template<typename TRACKED, typename TRACKED_IS_TRACKER>
-	struct TrackMemImpl;
-
-	typedef MemTrackable<DERIVED, ALIGNMENT> mem_trackable_t;
-	static	MemStatHandle	sMemStat;
-
 public:
 	typedef void mem_trackable_tag_t;
 
+	enum EMemType
+	{
+		MEM_FOOTPRINT, 
+		MEM_SHADOW
+	};
+
 	MemTrackable()
-	:	mMemFootprint(0)
+	:	mMemFootprint(0),
+		mMemShadow(0)
 	{
 		static bool name_initialized = false;
 		if (!name_initialized)
@@ -426,7 +439,8 @@ class MemTrackable
 
 	virtual ~MemTrackable()
 	{
-		memDisclaim(mMemFootprint);
+		disclaimMem(mMemFootprint, MEM_FOOTPRINT);
+		disclaimMem(mMemShadow, MEM_SHADOW);
 	}
 
 	static MemStatHandle& getMemStatHandle()
@@ -434,186 +448,129 @@ class MemTrackable
 		return sMemStat;
 	}
 
+	S32 getMemFootprint() const	{ return mMemFootprint; }
+	S32 getMemShadow() const	{ return mMemShadow; }
+
 	void* operator new(size_t size) 
 	{
-		claim_mem(sMemStat, size);
-
-		if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN)
-		{
-			return ::operator new(size);
-		}
-		else if (ALIGNMENT == 16)
-		{
-			return ll_aligned_malloc_16(size);
-		}
-		else if (ALIGNMENT == 32)
-		{
-			return ll_aligned_malloc_32(size);
-		}
-		else
-		{
-			return ll_aligned_malloc(size, ALIGNMENT);
-		}
+		claim_footprint(sMemStat, size);
+		return ll_aligned_malloc(ALIGNMENT, size);
 	}
 
 	void operator delete(void* ptr, size_t size)
 	{
-		disclaim_mem(sMemStat, size);
-
-		if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN)
-		{
-			::operator delete(ptr);
-		}
-		else if (ALIGNMENT == 16)
-		{
-			ll_aligned_free_16(ptr);
-		}
-		else if (ALIGNMENT == 32)
-		{
-			return ll_aligned_free_32(ptr);
-		}
-		else
-		{
-			return ll_aligned_free(ptr);
-		}
+		disclaim_footprint(sMemStat, size);
+		ll_aligned_free(ALIGNMENT, ptr);
 	}
 
 	void *operator new [](size_t size)
 	{
-		claim_mem(sMemStat, size);
-
-		if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN)
-		{
-			return ::operator new[](size);
-		}
-		else if (ALIGNMENT == 16)
-		{
-			return ll_aligned_malloc_16(size);
-		}
-		else if (ALIGNMENT == 32)
-		{
-			return ll_aligned_malloc_32(size);
-		}
-		else
-		{
-			return ll_aligned_malloc(size, ALIGNMENT);
-		}
+		claim_footprint(sMemStat, size);
+		return ll_aligned_malloc(ALIGNMENT, size);
 	}
 
 	void operator delete[](void* ptr, size_t size)
 	{
-		disclaim_mem(sMemStat, size);
-
-		if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN)
-		{
-			::operator delete[](ptr);
-		}
-		else if (ALIGNMENT == 16)
-		{
-			ll_aligned_free_16(ptr);
-		}
-		else if (ALIGNMENT == 32)
-		{
-			return ll_aligned_free_32(ptr);
-		}
-		else
-		{
-			return ll_aligned_free(ptr);
-		}
+		disclaim_footprint(sMemStat, size);
+		ll_aligned_free(ALIGNMENT, ptr);
 	}
 
 	// claim memory associated with other objects/data as our own, adding to our calculated footprint
 	template<typename CLAIM_T>
-	CLAIM_T& memClaim(CLAIM_T& value)
+	CLAIM_T& claimMem(CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT)
 	{
-		TrackMemImpl<CLAIM_T>::claim(*this, value);
+		trackAlloc(MeasureMem<CLAIM_T>::measureFootprint(value), mem_type);
+		trackAlloc(MeasureMem<CLAIM_T>::measureShadow(value), MEM_SHADOW);
 		return value;
 	}
 
 	template<typename CLAIM_T>
-	const CLAIM_T& memClaim(const CLAIM_T& value)
+	const CLAIM_T& claimMem(const CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT)
 	{
-		TrackMemImpl<CLAIM_T>::claim(*this, value);
+		trackAlloc(MeasureMem<CLAIM_T>::measureFootprint(value), mem_type);
+		trackAlloc(MeasureMem<CLAIM_T>::measureShadow(value), MEM_SHADOW);
 		return value;
 	}
 
-	size_t& memClaim(size_t& size)
+	size_t& claimMem(size_t& size, EMemType mem_type = MEM_FOOTPRINT)
 	{
-		claim_mem(sMemStat, size);
-		mMemFootprint += size;
+		trackAlloc(size, mem_type);
 		return size;
 	}
 
-	int& memClaim(int& size)
+	S32& claimMem(S32& size, EMemType mem_type = MEM_FOOTPRINT)
 	{
-		claim_mem(sMemStat, size);
-		mMemFootprint += size;
+		trackAlloc(size, mem_type);
 		return size;
 	}
 
 	// remove memory we had claimed from our calculated footprint
 	template<typename CLAIM_T>
-	CLAIM_T& memDisclaim(CLAIM_T& value)
+	CLAIM_T& disclaimMem(CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT)
 	{
-		TrackMemImpl<CLAIM_T>::disclaim(*this, value);
+		trackDealloc(MeasureMem<CLAIM_T>::measureFootprint(value), mem_type);
+		trackDealloc(MeasureMem<CLAIM_T>::measureShadow(value), MEM_SHADOW);
 		return value;
 	}
 
 	template<typename CLAIM_T>
-	const CLAIM_T& memDisclaim(const CLAIM_T& value)
+	const CLAIM_T& disclaimMem(const CLAIM_T& value, EMemType mem_type = MEM_FOOTPRINT)
 	{
-		TrackMemImpl<CLAIM_T>::disclaim(*this, value);
+		trackDealloc(MeasureMem<CLAIM_T>::measureFootprint(value), mem_type);
+		trackDealloc(MeasureMem<CLAIM_T>::measureShadow(value), MEM_SHADOW);
 		return value;
 	}
 
-	size_t& memDisclaim(size_t& size)
+	size_t& disclaimMem(size_t& size, EMemType mem_type = MEM_FOOTPRINT)
 	{
-		disclaim_mem(sMemStat, size);
-		mMemFootprint -= size;
+		trackDealloc(size, mem_type);
 		return size;
 	}
 
-	int& memDisclaim(int& size)
+	S32& disclaimMem(S32& size, EMemType mem_type = MEM_FOOTPRINT)
 	{
-		disclaim_mem(sMemStat, size);
-		mMemFootprint -= size;
+		trackDealloc(size, mem_type);
 		return size;
 	}
 
 private:
-	size_t mMemFootprint;
 
-	template<typename TRACKED, typename TRACKED_IS_TRACKER = void>
-	struct TrackMemImpl
+	void trackAlloc(S32 size, EMemType mem_type)
 	{
-		static void claim(mem_trackable_t& tracker, const TRACKED& tracked)
+		if (mem_type == MEM_FOOTPRINT)
 		{
-			size_t footprint = MemFootprint<TRACKED>::measure(tracked);
-			claim_mem(sMemStat, footprint);
-			tracker.mMemFootprint += footprint;
+			claim_footprint(sMemStat, size);
+			mMemFootprint += size;
 		}
-
-		static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked)
+		else
 		{
-			size_t footprint = MemFootprint<TRACKED>::measure(tracked);
-			disclaim_mem(sMemStat, footprint);
-			tracker.mMemFootprint -= footprint;
+			claim_shadow(sMemStat, size);
+			mMemShadow += size;
 		}
-	};
+	}
 
-	template<typename TRACKED>
-	struct TrackMemImpl<TRACKED, typename TRACKED::mem_trackable_tag_t>
+	void trackDealloc(S32 size, EMemType mem_type)
 	{
-		static void claim(mem_trackable_t& tracker, TRACKED& tracked)
+		if (mem_type == MEM_FOOTPRINT)
 		{
-			claim_shadow_mem( sMemStat, MemFootprint<TRACKED>::measure(tracked));
+			disclaim_footprint(sMemStat, size);
+			mMemFootprint -= size;
 		}
-
-		static void disclaim(mem_trackable_t& tracker, TRACKED& tracked)
+		else
 		{
-			disclaim_shadow_mem(sMemStat, MemFootprint<TRACKED>::measure(tracked));
+			disclaim_shadow(sMemStat, size);
+			mMemShadow -= size;
 		}
-	};
+	}
+
+private:
+	// use signed values so that we can temporarily go negative
+	// and reconcile in destructor
+	// NB: this assumes that no single class is responsible for > 2GB of allocations
+	S32 mMemFootprint,
+		mMemShadow;
+	
+	static	MemStatHandle	sMemStat;
 };
 
 template<typename DERIVED, size_t ALIGNMENT>
diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h
index 37a35f4e238..4fe84455a61 100644
--- a/indra/llcommon/lltraceaccumulators.h
+++ b/indra/llcommon/lltraceaccumulators.h
@@ -35,6 +35,7 @@
 #include "lltimer.h"
 #include "llrefcount.h"
 #include "llthreadlocalstorage.h"
+#include "llmemory.h"
 #include <limits>
 
 namespace LLTrace
@@ -51,7 +52,7 @@ namespace LLTrace
 	class AccumulatorBuffer : public LLRefCount
 	{
 		typedef AccumulatorBuffer<ACCUMULATOR> self_t;
-		static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64;
+		static const U32 ACCUMULATOR_BUFFER_SIZE_INCREMENT = 16;
 	private:
 		struct StaticAllocationMarker { };
 
@@ -149,7 +150,9 @@ namespace LLTrace
 			size_t next_slot = sNextStorageSlot++;
 			if (next_slot >= mStorageSize)
 			{
-				resize(mStorageSize + (mStorageSize >> 2));
+				// don't perform doubling, as this should only happen during startup
+				// want to keep a tight bounds as we will have a lot of these buffers
+				resize(mStorageSize + ACCUMULATOR_BUFFER_SIZE_INCREMENT);
 			}
 			llassert(mStorage && next_slot < mStorageSize);
 			return next_slot;
@@ -199,7 +202,7 @@ namespace LLTrace
 				// so as not to trigger an access violation
 				sDefaultBuffer = new AccumulatorBuffer(StaticAllocationMarker());
 				sInitialized = true;
-				sDefaultBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE);
+				sDefaultBuffer->resize(ACCUMULATOR_BUFFER_SIZE_INCREMENT);
 			}
 			return sDefaultBuffer;
 		}
@@ -427,6 +430,17 @@ namespace LLTrace
 			typedef F64Seconds value_t;
 		};
 
+		// arrays are allocated with 32 byte alignment
+		void *operator new [](size_t size)
+		{
+			return ll_aligned_malloc(32, size);
+		}
+
+		void operator delete[](void* ptr, size_t size)
+		{
+			ll_aligned_free(32, ptr);
+		}
+
 		TimeBlockAccumulator();
 		void addSamples(const self_t& other, EBufferAppendType append_type);
 		void reset(const self_t* other);
@@ -435,8 +449,7 @@ namespace LLTrace
 		//
 		// members
 		//
-		U64					mStartTotalTimeCounter,
-							mTotalTimeCounter,
+		U64					mTotalTimeCounter,
 							mSelfTimeCounter;
 		U32					mCalls;
 		class TimeBlock*	mParent;		// last acknowledged parent of this time block
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index c606007d891..c16d02216d2 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -131,7 +131,7 @@ void Recording::appendRecording( Recording& other )
 F64Seconds Recording::getSum(const TraceType<TimeBlockAccumulator>& stat)
 {
 	const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
-	return F64Seconds((F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter) 
+	return F64Seconds((F64)(accumulator.mTotalTimeCounter) 
 				/ (F64)LLTrace::TimeBlock::countsPerSecond());
 }
 
@@ -151,7 +151,7 @@ F64Seconds Recording::getPerSec(const TraceType<TimeBlockAccumulator>& stat)
 {
 	const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()];
 
-	return F64Seconds((F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter) 
+	return F64Seconds((F64)(accumulator.mTotalTimeCounter) 
 				/ ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds.value()));
 }
 
@@ -935,7 +935,7 @@ void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& oth
 
 PeriodicRecording& get_frame_recording()
 {
-	static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(1000, PeriodicRecording::STARTED));
+	static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED));
 	return *sRecording;
 }
 
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index d3d9eb5ca70..e131af5f160 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -127,10 +127,7 @@ void ThreadRecorder::activate( AccumulatorBufferGroup* recording, bool from_hand
 	{
 		AccumulatorBufferGroup& prev_active_recording = mActiveRecordings.back()->mPartialRecording;
 		prev_active_recording.sync();
-		if (!from_handoff)
-		{
-			TimeBlock::updateTimes();
-		}
+		TimeBlock::updateTimes();
 		prev_active_recording.handOffTo(active_recording->mPartialRecording);
 	}
 	mActiveRecordings.push_back(active_recording);
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 34e0e202b60..326f4775041 100755
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -50,7 +50,6 @@ LLMutex* LLImage::sMutex = NULL;
 bool LLImage::sUseNewByteRange = false;
 S32  LLImage::sMinimalReverseByteRangePercent = 75;
 LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;
-//LLTrace::MemStatHandle	LLImageBase::sMemStat("LLImage");
 
 //static
 void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
@@ -159,7 +158,7 @@ void LLImageBase::sanityCheck()
 void LLImageBase::deleteData()
 {
 	FREE_MEM(sPrivatePoolp, mData) ;
-	memDisclaim(mDataSize) = 0;
+	disclaimMem(mDataSize) = 0;
 	mData = NULL;
 }
 
@@ -202,7 +201,7 @@ U8* LLImageBase::allocateData(S32 size)
 			mBadBufferAllocation = true ;
 		}
 		mDataSize = size;
-		memClaim(mDataSize);
+		claimMem(mDataSize);
 	}
 
 	return mData;
@@ -224,7 +223,7 @@ U8* LLImageBase::reallocateData(S32 size)
 		FREE_MEM(sPrivatePoolp, mData) ;
 	}
 	mData = new_datap;
-	memClaim(memDisclaim(mDataSize) = size);
+	claimMem(disclaimMem(mDataSize) = size);
 	return mData;
 }
 
@@ -1619,7 +1618,7 @@ void LLImageBase::setDataAndSize(U8 *data, S32 size)
 { 
 	ll_assert_aligned(data, 16);
 	mData = data; 
-	memClaim(memDisclaim(mDataSize) = size); 
+	claimMem(disclaimMem(mDataSize) = size); 
 }	
 
 //static
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index f0caba3e133..e6582a7ae95 100755
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -174,7 +174,7 @@ LLFolderView::LLFolderView(const Params& p)
 	mShowItemLinkOverlays(p.show_item_link_overlays),
 	mViewModel(p.view_model)
 {
-	memClaim(mViewModel);
+	claimMem(mViewModel);
 	mViewModel->setFolderView(this);
 	mRoot = this;
 
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 26ea9651b5f..802cb783ed1 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1496,16 +1496,16 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
 		ft = std::find(mFolders.begin(), mFolders.end(), f);
 		if (ft != mFolders.end())
 		{
-			memDisclaim(mFolders);
+			disclaimMem(mFolders);
 			mFolders.erase(ft);
-			memClaim(mFolders);
+			claimMem(mFolders);
 		}
 	}
 	else
 	{
-		memDisclaim(mItems);
+		disclaimMem(mItems);
 		mItems.erase(it);
-		memClaim(mItems);
+		claimMem(mItems);
 	}
 	//item has been removed, need to update filter
 	getViewModelItem()->removeChild(item->getViewModelItem());
@@ -1582,9 +1582,9 @@ void LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	}
 	item->setParentFolder(this);
 
-	memDisclaim(mItems);
+	disclaimMem(mItems);
 	mItems.push_back(item);
-	memClaim(mItems);
+	claimMem(mItems);
 	
 	item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
 	item->setVisible(FALSE);
@@ -1607,9 +1607,9 @@ void LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 		folder->mParentFolder->extractItem(folder);
 	}
 	folder->mParentFolder = this;
-	memDisclaim(mFolders);
+	disclaimMem(mFolders);
 	mFolders.push_back(folder);
-	memClaim(mFolders);
+	claimMem(mFolders);
 	folder->setOrigin(0, 0);
 	folder->reshape(getRect().getWidth(), 0);
 	folder->setVisible(FALSE);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 975f9df3823..5c221edea7e 100755
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -48,8 +48,6 @@ const F32	CURSOR_FLASH_DELAY = 1.0f;  // in seconds
 const S32	CURSOR_THICKNESS = 2;
 const F32	TRIPLE_CLICK_INTERVAL = 0.3f;	// delay between double and triple click.
 
-//LLTrace::MemStatHandle	LLTextSegment::sMemStat("LLTextSegment");
-
 LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num) 
 :	mDocIndexStart(index_start), 
 	mDocIndexEnd(index_end),
@@ -578,7 +576,7 @@ void LLTextBase::drawText()
 		if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) )
 		{
 			const LLWString& wstrText = getWText(); 
-			memDisclaim(mMisspellRanges).clear();
+			disclaimMem(mMisspellRanges).clear();
 
 			segment_set_t::const_iterator seg_it = getSegIterContaining(start);
 			while (mSegments.end() != seg_it)
@@ -654,7 +652,7 @@ void LLTextBase::drawText()
 
 			mSpellCheckStart = start;
 			mSpellCheckEnd = end;
-			memClaim(mMisspellRanges);
+			claimMem(mMisspellRanges);
 		}
 	}
 	else
@@ -924,11 +922,11 @@ void LLTextBase::createDefaultSegment()
 	if (mSegments.empty())
 	{
 		LLStyleConstSP sp(new LLStyle(getStyleParams()));
-		memDisclaim(mSegments);
+		disclaimMem(mSegments);
 		LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this);
 		mSegments.insert(default_segment);
 		default_segment->linkToDocument(this);
-		memClaim(mSegments);
+		claimMem(mSegments);
 	}
 }
 
@@ -939,7 +937,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
 		return;
 	}
 
-	memDisclaim(mSegments);
+	disclaimMem(mSegments);
 
 	segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart());
 	S32 reflow_start_index = 0;
@@ -1013,7 +1011,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
 
 	// layout potentially changed
 	needsReflow(reflow_start_index);
-	memClaim(mSegments);
+	claimMem(mSegments);
 }
 
 BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -1324,10 +1322,10 @@ void LLTextBase::replaceWithSuggestion(U32 index)
 			removeStringNoUndo(it->first, it->second - it->first);
 
 			// Insert the suggestion in its place
-			memDisclaim(mSuggestionList);
+			disclaimMem(mSuggestionList);
 			LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
 			insertStringNoUndo(it->first, utf8str_to_wstring(mSuggestionList[index]));
-			memClaim(mSuggestionList);
+			claimMem(mSuggestionList);
 
 			setCursorPos(it->first + (S32)suggestion.length());
 
@@ -1390,7 +1388,7 @@ bool LLTextBase::isMisspelledWord(U32 pos) const
 void LLTextBase::onSpellCheckSettingsChange()
 {
 	// Recheck the spelling on every change
-	memDisclaim(mMisspellRanges).clear();
+	disclaimMem(mMisspellRanges).clear();
 	mSpellCheckStart = mSpellCheckEnd = -1;
 }
 
@@ -1668,7 +1666,7 @@ LLRect LLTextBase::getTextBoundingRect()
 
 void LLTextBase::clearSegments()
 {
-	memDisclaim(mSegments).clear();
+	disclaimMem(mSegments).clear();
 	createDefaultSegment();
 }
 
@@ -3212,9 +3210,9 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)
 		LL_WARNS() << "LLTextSegment::setToolTip: cannot replace keyword tooltip." << LL_ENDL;
 		return;
 	}
-	memDisclaim(mTooltip);
+	disclaimMem(mTooltip);
 	mTooltip = tooltip;
-	memClaim(mTooltip);
+	claimMem(mTooltip);
 }
 
 bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 8925ec9e452..b1558a7abe1 100755
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -100,8 +100,6 @@ class LLTextSegment
 	S32						getEnd() const						{ return mEnd; }
 	void					setEnd( S32 end )					{ mEnd = end; }
 
-	//static LLTrace::MemStatHandle sMemStat;
-
 protected:
 	S32				mStart;
 	S32				mEnd;
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 9a1a0e06774..9a81c91e0d9 100755
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -118,7 +118,7 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
 	mDoubleClickSignal(NULL),
 	mTransparencyType(TT_DEFAULT)
 {
-	memClaim(viewmodel.get());
+	claimMem(viewmodel.get());
 }
 
 void LLUICtrl::initFromParams(const Params& p)
@@ -941,7 +941,7 @@ boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (L
 }
 boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb )
 {
-	if (!mValidateSignal) mValidateSignal = memClaim(new enable_signal_t());
+	if (!mValidateSignal) mValidateSignal = claimMem(new enable_signal_t());
 	return mValidateSignal->connect(boost::bind(cb, _2));
 }
 
@@ -1004,55 +1004,55 @@ boost::signals2::connection LLUICtrl::setValidateCallback(const EnableCallbackPa
 
 boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb ) 
 { 
-	if (!mCommitSignal) mCommitSignal = memClaim(new commit_signal_t());
+	if (!mCommitSignal) mCommitSignal = claimMem(new commit_signal_t());
 	return mCommitSignal->connect(cb); 
 }
 
 boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t::slot_type& cb ) 
 { 
-	if (!mValidateSignal) mValidateSignal = memClaim(new enable_signal_t());
+	if (!mValidateSignal) mValidateSignal = claimMem(new enable_signal_t());
 	return mValidateSignal->connect(cb); 
 }
 
 boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal_t::slot_type& cb ) 
 { 
-	if (!mMouseEnterSignal) mMouseEnterSignal = memClaim(new commit_signal_t());
+	if (!mMouseEnterSignal) mMouseEnterSignal = claimMem(new commit_signal_t());
 	return mMouseEnterSignal->connect(cb); 
 }
 
 boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal_t::slot_type& cb ) 
 { 
-	if (!mMouseLeaveSignal) mMouseLeaveSignal = memClaim(new commit_signal_t());
+	if (!mMouseLeaveSignal) mMouseLeaveSignal = claimMem(new commit_signal_t());
 	return mMouseLeaveSignal->connect(cb); 
 }
 
 boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t::slot_type& cb ) 
 { 
-	if (!mMouseDownSignal) mMouseDownSignal = memClaim(new mouse_signal_t());
+	if (!mMouseDownSignal) mMouseDownSignal = claimMem(new mouse_signal_t());
 	return mMouseDownSignal->connect(cb); 
 }
 
 boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t::slot_type& cb ) 
 { 
-	if (!mMouseUpSignal) mMouseUpSignal = memClaim(new mouse_signal_t());
+	if (!mMouseUpSignal) mMouseUpSignal = claimMem(new mouse_signal_t());
 	return mMouseUpSignal->connect(cb); 
 }
 
 boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ) 
 { 
-	if (!mRightMouseDownSignal) mRightMouseDownSignal = memClaim(new mouse_signal_t());
+	if (!mRightMouseDownSignal) mRightMouseDownSignal = claimMem(new mouse_signal_t());
 	return mRightMouseDownSignal->connect(cb); 
 }
 
 boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ) 
 { 
-	if (!mRightMouseUpSignal) mRightMouseUpSignal = memClaim(new mouse_signal_t());
+	if (!mRightMouseUpSignal) mRightMouseUpSignal = claimMem(new mouse_signal_t());
 	return mRightMouseUpSignal->connect(cb); 
 }
 
 boost::signals2::connection LLUICtrl::setDoubleClickCallback( const mouse_signal_t::slot_type& cb ) 
 { 
-	if (!mDoubleClickSignal) mDoubleClickSignal = memClaim(new mouse_signal_t());
+	if (!mDoubleClickSignal) mDoubleClickSignal = claimMem(new mouse_signal_t());
 	return mDoubleClickSignal->connect(cb); 
 }
 
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 22461083a6c..e81d19ae3a0 100755
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -69,7 +69,6 @@ LLView* LLView::sPreviewClickedElement = NULL;
 BOOL	LLView::sDrawPreviewHighlights = FALSE;
 S32		LLView::sLastLeftXML = S32_MIN;
 S32		LLView::sLastBottomXML = S32_MIN;
-//LLTrace::MemStatHandle	LLView::sMemStat("LLView");
 std::vector<LLViewDrawContext*> LLViewDrawContext::sDrawContextStack;
 
 LLView::DrilldownFunc LLView::sDrilldown =
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index f6799d8cd91..3a0dfb5f429 100755
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -675,7 +675,6 @@ class LLView
 	static S32 sLastLeftXML;
 	static S32 sLastBottomXML;
 	static BOOL sForceReshape;
-	//static LLTrace::MemStatHandle sMemStat;
 };
 
 namespace LLInitParam
diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp
index 21c4e0fcac0..6459ade0276 100755
--- a/indra/llui/llviewmodel.cpp
+++ b/indra/llui/llviewmodel.cpp
@@ -35,8 +35,6 @@
 // external library headers
 // other Linden headers
 
-//LLTrace::MemStatHandle	LLViewModel::sMemStat("LLViewModel");
-
 ///
 LLViewModel::LLViewModel()
  : mDirty(false)
@@ -83,11 +81,11 @@ void LLTextViewModel::setValue(const LLSD& value)
 {
 	LLViewModel::setValue(value);
 	// approximate LLSD storage usage
-	memDisclaim(mDisplay.size());
-	memDisclaim(mDisplay);
+	disclaimMem(mDisplay.size());
+	disclaimMem(mDisplay);
     mDisplay = utf8str_to_wstring(value.asString());
-	memClaim(mDisplay);
-	memClaim(mDisplay.size());
+	claimMem(mDisplay);
+	claimMem(mDisplay.size());
 
     // mDisplay and mValue agree
     mUpdateFromDisplay = false;
@@ -99,11 +97,11 @@ void LLTextViewModel::setDisplay(const LLWString& value)
     // and do the utf8str_to_wstring() to get the corresponding mDisplay
     // value. But a text editor might want to edit the display string
     // directly, then convert back to UTF8 on commit.
-	memDisclaim(mDisplay.size());
-	memDisclaim(mDisplay);
+	disclaimMem(mDisplay.size());
+	disclaimMem(mDisplay);
     mDisplay = value;
-	memClaim(mDisplay);
-	memClaim(mDisplay.size());
+	claimMem(mDisplay);
+	claimMem(mDisplay.size());
     mDirty = true;
     // Don't immediately convert to UTF8 -- do it lazily -- we expect many
     // more setDisplay() calls than getValue() calls. Just flag that it needs
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
index f329201b9f7..49d7c322a3d 100755
--- a/indra/llui/llviewmodel.h
+++ b/indra/llui/llviewmodel.h
@@ -83,8 +83,6 @@ class LLViewModel
 	// 
     void setDirty() { mDirty = true; }
 
-	//static LLTrace::MemStatHandle sMemStat;
-
 protected:
     LLSD mValue;
     bool mDirty;
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 1837974604f..5baebab5a33 100755
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -59,7 +59,6 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;
 static LLTrace::TimeBlock FTM_CULL_REBOUND("Cull Rebound");
 
 extern bool gShiftFrame;
-//LLTrace::MemStatHandle	LLDrawable::sMemStat("LLDrawable");
 
 
 ////////////////////////
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 3dab496a20f..a0ac417b243 100755
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -291,7 +291,6 @@ class LLDrawable
 	F32				mDistanceWRTCamera;
 
 	static F32 sCurPixelAngle; //current pixels per radian
-	//static LLTrace::MemStatHandle sMemStat;
 
 private:
 	typedef std::vector<LLFace*> face_list_t;
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index c2a5cf94057..6ff4c445682 100755
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -131,8 +131,8 @@ class LLTextureCache : public LLWorkerThread
 	// debug
 	S32 getNumReads() { return mReaders.size(); }
 	S32 getNumWrites() { return mWriters.size(); }
-	S64 getUsage() { return mTexturesSizeTotal; }
-	S64 getMaxUsage() { return sCacheMaxTexturesSize; }
+	S64Bytes getUsage() { return S64Bytes(mTexturesSizeTotal); }
+	S64Bytes getMaxUsage() { return S64Bytes(sCacheMaxTexturesSize); }
 	U32 getEntries() { return mHeaderEntriesInfo.mEntries; }
 	U32 getMaxEntries() { return sCacheMaxEntries; };
 	BOOL isInCache(const LLUUID& id) ;
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 3974668d099..17aebebd921 100755
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -512,8 +512,8 @@ void LLGLTexMemBar::draw()
 	S32Megabytes total_mem = LLViewerTexture::sTotalTextureMemory;
 	S32Megabytes max_total_mem = LLViewerTexture::sMaxTotalTextureMem;
 	F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
-	F32 cache_usage = (F32)F32Megabytes(LLAppViewer::getTextureCache()->getUsage()).value() ;
-	F32 cache_max_usage = (F32)F32Megabytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ;
+	F32 cache_usage = F32Megabytes(LLAppViewer::getTextureCache()->getUsage()).value();
+	F32 cache_max_usage = F32Megabytes(LLAppViewer::getTextureCache()->getMaxUsage()).value();
 	S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
 	S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
 	F32Bytes total_texture_downloaded = gTotalTextureData;
@@ -555,8 +555,8 @@ void LLGLTexMemBar::draw()
 	LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait);
 	
 	text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB #Objs/#Cached: %d/%d Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u",
-					total_texture_downloaded.value(),
-					total_object_downloaded.value(),
+					total_texture_downloaded.valueInUnits<LLUnits::Megabytes>(),
+					total_object_downloaded.valueInUnits<LLUnits::Megabytes>(),
 					total_objects, 
 					total_active_cached_objects,
 					total_http_requests,
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 2c1ab3a73b4..394b11b7596 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -112,7 +112,6 @@ BOOL		LLViewerObject::sMapDebug = TRUE;
 LLColor4	LLViewerObject::sEditSelectColor(	1.0f, 1.f, 0.f, 0.3f);	// Edit OK
 LLColor4	LLViewerObject::sNoEditSelectColor(	1.0f, 0.f, 0.f, 0.3f);	// Can't edit
 S32			LLViewerObject::sAxisArrowLength(50);
-//LLTrace::MemStatHandle	LLViewerObject::sMemStat("LLViewerObject");
 
 
 BOOL		LLViewerObject::sPulseEnabled(FALSE);
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index e3972ccae89..56518cca69b 100755
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -661,7 +661,6 @@ class LLViewerObject
 	LLPointer<class LLHUDIcon> mIcon;
 
 	static			BOOL		sUseSharedDrawables;
-	//static	LLTrace::MemStatHandle	sMemStat;
 
 protected:
 	// delete an item in the inventory, but don't tell the
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index bc3c7cbfa29..6ebd1d6da11 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -135,7 +135,7 @@ class LLViewerOctreeEntry : public LLRefCount
 class LLViewerOctreeEntryData : public LLRefCount
 {
 protected:
-	~LLViewerOctreeEntryData();
+	virtual ~LLViewerOctreeEntryData();
 
 public:
 	LLViewerOctreeEntryData(const LLViewerOctreeEntryData& rhs)
diff --git a/indra/newview/llviewerprecompiledheaders.cpp b/indra/newview/llviewerprecompiledheaders.cpp
index 307e9037269..768f1f33877 100755
--- a/indra/newview/llviewerprecompiledheaders.cpp
+++ b/indra/newview/llviewerprecompiledheaders.cpp
@@ -26,7 +26,7 @@
 
 // source file that includes just the standard includes
 // newview.pch will be the pre-compiled header
-// llviewerprecompiledheaders.obj will contain the pre-compiled type information
+// llviewerprecompiledheaders.obj will contain the pre-compllviewiled type information
 
 #include "llviewerprecompiledheaders.h"
 
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index dfc9ee57d81..25dd1f4d07b 100755
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -38,7 +38,6 @@
 F32 LLVOCacheEntry::sBackDistanceSquared = 0.f;
 F32 LLVOCacheEntry::sBackAngleTanSquared = 0.f;
 BOOL LLVOCachePartition::sNeedsOcclusionCheck = FALSE;
-//LLTrace::MemStatHandle	LLVOCachePartition::sMemStat("LLVOCachePartition");
 
 BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) 
 {
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 867f9ab93c4..70900a7e222 100755
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -176,7 +176,6 @@ class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTr
 
 public:
 	static BOOL sNeedsOcclusionCheck;
-	//static	LLTrace::MemStatHandle	sMemStat;
 
 private:
 	U32   mCullHistory[LLViewerCamera::NUM_CAMERAS];
diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml
index 2291f81fcc8..f0a464dfc98 100755
--- a/indra/newview/skins/default/xui/en/floater_stats.xml
+++ b/indra/newview/skins/default/xui/en/floater_stats.xml
@@ -113,6 +113,22 @@
 				 <stat_bar name="LLView"
                     label="LLView Memory"
                     stat="class LLView"
+                    show_history="true"/>
+				 <stat_bar name="LLViewerObject"
+                    label="LLViewerObject Memory"
+                    stat="class LLViewerObject"
+                    show_history="true"/>
+					<stat_bar name="LLVOCacheEntry"
+                    label="LLVOCacheEntry Memory"
+                    stat="class LLVOCacheEntry"
+                    show_history="true"/>
+				 <stat_bar name="LLDrawable"
+                    label="LLDrawable Memory"
+                    stat="class LLDrawable"
+                    show_history="true"/>
+				 <stat_bar name="LLImage"
+                    label="LLImage Memory"
+                    stat="class LLImageBase"
                     show_history="true"/>
 			 </stat_view>
         <stat_view name="network"
-- 
GitLab