diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index c720df755509e35392297756e59f3984bd625032..96ec0cdefefe955ca0bcb622625743915ee82579 100755
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -30,10 +30,13 @@
 #include "llmemory.h"
 #include "llthread.h"
 #include "lltrace.h"
+#include "lltracethreadrecorder.h"
 
 //static
 BOOL LLCommon::sAprInitialized = FALSE;
 
+static LLTrace::ThreadRecorder* sMasterThreadRecorder = NULL;
+
 //static
 void LLCommon::initClass()
 {
@@ -45,13 +48,20 @@ void LLCommon::initClass()
 	}
 	LLTimer::initClass();
 	LLThreadSafeRefCount::initThreadSafeRefCount();
-	LLTrace::init();
+
+	if (!sMasterThreadRecorder)
+	{
+		sMasterThreadRecorder = new LLTrace::ThreadRecorder();
+		LLTrace::set_master_thread_recorder(sMasterThreadRecorder);
+	}
 }
 
 //static
 void LLCommon::cleanupClass()
 {
-	LLTrace::cleanup();
+	delete sMasterThreadRecorder;
+	sMasterThreadRecorder = NULL;
+	LLTrace::set_master_thread_recorder(NULL);
 	LLThreadSafeRefCount::cleanupThreadSafeRefCount();
 	LLTimer::cleanupClass();
 	if (sAprInitialized)
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 7a7f1c79c15e889050b74b0ed6c48f0b45de5f12..a72f16d38517116de12bd3e61f50727a2212c308 100755
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -250,7 +250,7 @@ void TimeBlock::updateTimes()
 {
 	// walk up stack of active timers and accumulate current time while leaving timing structures active
 	BlockTimerStackRecord* stack_record	= LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance();
-	if (stack_record) return;
+	if (!stack_record) return;
 
 	U64 cur_time = getCPUClockCount64();
 	BlockTimer* cur_timer				= stack_record->mActiveTimer;
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index d07cccdf15291ab68c0175a8bc45e36ceaa6e856..166a4eb26d2bd5d80f09f99e0d6060f85f27405f 100755
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -93,7 +93,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
 {
 	LLThread *threadp = (LLThread *)datap;
 
-	LLTrace::ThreadRecorder thread_recorder(LLTrace::getUIThreadRecorder());
+	LLTrace::ThreadRecorder thread_recorder(*LLTrace::get_master_thread_recorder());
 
 #if !LL_DARWIN
 	sThreadID = threadp->mID;
diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp
index 26c19e5121fd9e5753401bfcc86df9082f2d2c7b..3dffbe6d4a5c7f624d4d21c216f618a28099f6c9 100644
--- a/indra/llcommon/lltrace.cpp
+++ b/indra/llcommon/lltrace.cpp
@@ -30,34 +30,26 @@
 #include "lltracethreadrecorder.h"
 #include "llfasttimer.h"
 
-static S32 sInitializationCount = 0;
-
 namespace LLTrace
 {
 
-void init()
+TraceBase::TraceBase( const char* name, const char* description ) 
+:	mName(name),
+	mDescription(description ? description : "")
 {
-	if (sInitializationCount++ == 0)
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+	if (LLTrace::get_master_thread_recorder() != NULL)
 	{
-		gUIThreadRecorder = new ThreadRecorder();
+		llerrs << "Attempting to declare trace object after program initialization.  Trace objects should be statically initialized." << llendl;
 	}
+#endif
 }
 
-bool isInitialized()
+const char* TraceBase::getUnitLabel()
 {
-	return sInitializationCount > 0; 
+	return "";
 }
 
-void cleanup()
-{
-	if (--sInitializationCount == 0)
-	{
-		delete gUIThreadRecorder;
-		gUIThreadRecorder = NULL;
-	}
-}
-
-
 TimeBlockTreeNode::TimeBlockTreeNode() 
 :	mBlock(NULL),
 	mParent(NULL),
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 72ef51c232250c49bc3dd57872eb1001e2251bbb..1cde450dc25839c23c990c609b1d6cc7002fcdee 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -53,19 +53,29 @@ STORAGE_TYPE storage_value(LLUnit<STORAGE_TYPE, UNIT_TYPE> val) { return val.val
 template<typename UNIT_TYPE, typename STORAGE_TYPE> 
 STORAGE_TYPE storage_value(LLUnitImplicit<STORAGE_TYPE, UNIT_TYPE> val) { return val.value(); }
 
-void init();
-void cleanup();
-bool isInitialized();
+class TraceBase
+{
+public:
+	TraceBase(const char* name, const char* description);
+	virtual ~TraceBase() {};
+	virtual const char* getUnitLabel();
+
+	const std::string& getName() const { return mName; }
+
+protected:
+	const std::string	mName;
+	const std::string	mDescription;
+};
 
 template<typename ACCUMULATOR>
 class TraceType 
-:	 public LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>
+:	public TraceBase,
+	public LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>
 {
 public:
 	TraceType(const char* name, const char* description = NULL)
 	:	LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>(name),
-		mName(name),
-		mDescription(description ? description : ""),
+		TraceBase(name, description),
 		mAccumulatorIndex(AccumulatorBuffer<ACCUMULATOR>::getDefaultBuffer()->reserveSlot())
 	{}
 
@@ -78,13 +88,7 @@ class TraceType
 	size_t getIndex() const { return mAccumulatorIndex; }
 	static size_t getNumIndices() { return AccumulatorBuffer<ACCUMULATOR>::getNumIndices(); }
 
-	virtual const char* getUnitLabel() { return ""; }
-
-	const std::string& getName() const { return mName; }
-
-protected:
-	const std::string	mName;
-	const std::string	mDescription;
+private:
 	const size_t		mAccumulatorIndex;
 };
 
@@ -320,7 +324,7 @@ class MemTrackable
 	template<typename TRACKED, typename TRACKED_IS_TRACKER>
 	struct TrackMemImpl;
 
-	typedef MemTrackable<DERIVED> mem_trackable_t;
+	typedef MemTrackable<DERIVED, ALIGNMENT> mem_trackable_t;
 
 public:
 	typedef void mem_trackable_tag_t;
@@ -332,7 +336,7 @@ class MemTrackable
 
 	void* operator new(size_t size) 
 	{
-		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator();
 		if (accumulator)
 		{
 			accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size);
@@ -344,7 +348,7 @@ class MemTrackable
 
 	void operator delete(void* ptr, size_t size)
 	{
-		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator();
 		if (accumulator)
 		{
 			accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size);
@@ -356,7 +360,7 @@ class MemTrackable
 
 	void *operator new [](size_t size)
 	{
-		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator();
 		if (accumulator)
 		{
 			accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size);
@@ -368,7 +372,7 @@ class MemTrackable
 
 	void operator delete[](void* ptr, size_t size)
 	{
-		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator* accumulator = mem_trackable_t::sMemStat.getPrimaryAccumulator();
 		if (accumulator)
 		{
 			accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size);
@@ -394,14 +398,16 @@ class MemTrackable
 	}
 
 
-	void memClaimAmount(size_t size)
+	template<typename AMOUNT_T>
+	AMOUNT_T& memClaimAmount(AMOUNT_T& size)
 	{
-		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
-		mMemFootprint += size;
+		MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator();
+		mMemFootprint += (size_t)size;
 		if (accumulator)
 		{
 			accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size);
 		}
+		return size;
 	}
 
 	// remove memory we had claimed from our calculated footprint
@@ -419,24 +425,28 @@ class MemTrackable
 		return value;
 	}
 
-	void memDisclaimAmount(size_t size)
+	template<typename AMOUNT_T>
+	AMOUNT_T& memDisclaimAmount(AMOUNT_T& size)
 	{
-		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+		MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator();
 		if (accumulator)
 		{
 			accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size);
 		}
+		return size;
 	}
 
 private:
 	size_t mMemFootprint;
+	static MemStatHandle sMemStat;
+
 
 	template<typename TRACKED, typename TRACKED_IS_TRACKER = void>
 	struct TrackMemImpl
 	{
 		static void claim(mem_trackable_t& tracker, const TRACKED& tracked)
 		{
-			MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+			MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator();
 			if (accumulator)
 			{
 				size_t footprint = MemFootprint<TRACKED>::measure(tracked);
@@ -447,7 +457,7 @@ class MemTrackable
 
 		static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked)
 		{
-			MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+			MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator();
 			if (accumulator)
 			{
 				size_t footprint = MemFootprint<TRACKED>::measure(tracked);
@@ -462,7 +472,7 @@ class MemTrackable
 	{
 		static void claim(mem_trackable_t& tracker, TRACKED& tracked)
 		{
-			MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+			MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator();
 			if (accumulator)
 			{
 				accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() + (F64)MemFootprint<TRACKED>::measure(tracked));
@@ -471,7 +481,7 @@ class MemTrackable
 
 		static void disclaim(mem_trackable_t& tracker, TRACKED& tracked)
 		{
-			MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator();
+			MemStatAccumulator* accumulator = sMemStat.getPrimaryAccumulator();
 			if (accumulator)
 			{
 				accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() - (F64)MemFootprint<TRACKED>::measure(tracked));
@@ -480,5 +490,9 @@ class MemTrackable
 	};
 };
 
+template<typename DERIVED, size_t ALIGNMENT>
+MemStatHandle MemTrackable<DERIVED, ALIGNMENT>::sMemStat(typeid(DERIVED).name());
+
+
 }
 #endif // LL_LLTRACE_H
diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h
index 825cc9e3a8ea370a198d4d85aa17d1e00203e4e1..fac6347ff91e32eb7754680e5c1f5ccd73271de2 100644
--- a/indra/llcommon/lltraceaccumulators.h
+++ b/indra/llcommon/lltraceaccumulators.h
@@ -33,6 +33,7 @@
 #include "llunit.h"
 #include "lltimer.h"
 #include "llrefcount.h"
+#include "llthreadlocalstorage.h"
 
 namespace LLTrace
 {
@@ -142,12 +143,6 @@ namespace LLTrace
 		// NOTE: this is not thread-safe.  We assume that slots are reserved in the main thread before any child threads are spawned
 		size_t reserveSlot()
 		{
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-			if (LLTrace::isInitialized())
-			{
-				llerrs << "Attempting to declare trace object after program initialization.  Trace objects should be statically initialized." << llendl;
-			}
-#endif
 			size_t next_slot = sNextStorageSlot++;
 			if (next_slot >= mStorageSize)
 			{
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index e88c5bf177cd9dfdb495cc0504eadca35ad9cd64..7ac0e7515464013a15bff78730379f79934366f0 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -31,13 +31,14 @@
 namespace LLTrace
 {
 
-ThreadRecorder* gUIThreadRecorder = NULL;
+static ThreadRecorder* sMasterThreadRecorder = NULL;
 
 ///////////////////////////////////////////////////////////////////////
 // ThreadRecorder
 ///////////////////////////////////////////////////////////////////////
 
 ThreadRecorder::ThreadRecorder()
+:	mMasterRecorder(NULL)
 {
 	init();
 }
@@ -268,10 +269,15 @@ void ThreadRecorder::pullFromChildren()
 }
 
 
-ThreadRecorder& getUIThreadRecorder()
+void set_master_thread_recorder(ThreadRecorder* recorder)
 {
-	llassert(gUIThreadRecorder != NULL);
-	return *gUIThreadRecorder;
+	sMasterThreadRecorder = recorder;
+}
+
+
+ThreadRecorder* get_master_thread_recorder()
+{
+	return sMasterThreadRecorder;
 }
 
 LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr()
diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h
index b5ed77416c14ad9d0bc086e7635b984439db9a51..535f8552008536f65f0346aa90ecbd3456d3983a 100644
--- a/indra/llcommon/lltracethreadrecorder.h
+++ b/indra/llcommon/lltracethreadrecorder.h
@@ -92,13 +92,11 @@ namespace LLTrace
 
 	};
 
-	//FIXME: let user code set up thread recorder topology
-	extern ThreadRecorder* gUIThreadRecorder ;
-
-	const LLThreadLocalPointer<class ThreadRecorder>& get_thread_recorder();
-	void set_thread_recorder(class ThreadRecorder*);
-	ThreadRecorder& getUIThreadRecorder();
+	const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder();
+	void set_thread_recorder(ThreadRecorder*);
 
+	void set_master_thread_recorder(ThreadRecorder*);
+	ThreadRecorder* get_master_thread_recorder();
 }
 
 #endif // LL_LLTRACETHREADRECORDER_H
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 50df2ebe55f805ecf97098d0c856549aac2e1265..395e6a6cc503c928cb70c00e652306507f71c697 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,9 +158,8 @@ void LLImageBase::sanityCheck()
 void LLImageBase::deleteData()
 {
 	FREE_MEM(sPrivatePoolp, mData) ;
-	memDisclaimAmount(mDataSize);
+	memDisclaimAmount(mDataSize) = 0;
 	mData = NULL;
-	mDataSize = 0;
 }
 
 // virtual
@@ -225,9 +223,7 @@ U8* LLImageBase::reallocateData(S32 size)
 		FREE_MEM(sPrivatePoolp, mData) ;
 	}
 	mData = new_datap;
-	memDisclaimAmount(mDataSize);
-	mDataSize = size;
-	memClaimAmount(mDataSize);
+	memClaimAmount(memDisclaimAmount(mDataSize) = size);
 	return mData;
 }
 
@@ -1612,9 +1608,8 @@ static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8*
 void LLImageBase::setDataAndSize(U8 *data, S32 size)
 { 
 	ll_assert_aligned(data, 16);
-	memDisclaimAmount(mDataSize);
-	mData = data; mDataSize = size; 
-	memClaimAmount(mDataSize);
+	mData = data; 
+	memClaimAmount(memDisclaimAmount(mDataSize) = size); 
 }	
 
 //static
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 504b7e4795ca7b9477cbf822da5e58be66fd479f..b2bfdba3f84c20b66f234976265ae324f4c70927 100755
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -165,8 +165,6 @@ class LLImageBase
 	static void destroyPrivatePool() ;
 	static LLPrivateMemoryPool* getPrivatePool() {return sPrivatePoolp;}
 
-	static LLTrace::MemStatHandle sMemStat;
-
 private:
 	U8 *mData;
 	S32 mDataSize;
diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp
index b6f2694742cbefaaa1deb75365c582b44d415ccd..7d7e9e036e2bfc199e8cd71528d202502132299d 100755
--- a/indra/llimage/tests/llimageworker_test.cpp
+++ b/indra/llimage/tests/llimageworker_test.cpp
@@ -44,9 +44,6 @@
 // * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
 // * A simulator for a class can be implemented here. Please comment and document thoroughly.
 
-LLTrace::MemStatHandle	LLImageBase::sMemStat("LLImage");
-
-
 LLImageBase::LLImageBase() 
 : mData(NULL),
 mDataSize(0),
@@ -115,17 +112,14 @@ namespace tut
 	{
 		// Instance to be tested
 		LLImageDecodeThread* mThread;
-
 		// Constructor and destructor of the test wrapper
 		imagedecodethread_test()
 		{
-			LLTrace::init();
 			mThread = NULL;
 		}
 		~imagedecodethread_test()
 		{
 			delete mThread;
-			LLTrace::cleanup();
 		}
 	};
 
@@ -143,7 +137,6 @@ namespace tut
 		imagerequest_test()
 		{
 			done = false;
-			LLTrace::init();
 
 			mRequest = new LLImageDecodeThread::ImageRequest(0, 0,
 											 LLQueuedThread::PRIORITY_NORMAL, 0, FALSE,
@@ -154,7 +147,6 @@ namespace tut
 			// We should delete the object *but*, because its destructor is protected, that cannot be
 			// done from outside an LLImageDecodeThread instance... So we leak memory here... It's fine...
 			//delete mRequest;
-			LLTrace::cleanup();
 		}
 	};
 
diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp
index 14fbf344abf6294f690a82a2b2673a6dd3680b37..0e73f33e0476d4345ed3f2ba0f645c6c81772a11 100755
--- a/indra/llkdu/tests/llimagej2ckdu_test.cpp
+++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp
@@ -44,8 +44,6 @@
 // End Stubbing
 // -------------------------------------------------------------------------------------------
 // Stub the LL Image Classes
-LLTrace::MemStatHandle	LLImageBase::sMemStat("LLImage");
-
 LLImageRaw::LLImageRaw() { }
 LLImageRaw::~LLImageRaw() { }
 U8* LLImageRaw::allocateData(S32 ) { return NULL; }
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index d3cc2733e66f196a9127f52d9dae63300c5a3865..fd88565de47abee36d227c6eb6c9d4fabe91a311 100755
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -345,9 +345,9 @@ void LLStatBar::draw()
 					else if (mSampleFloatp)
 					{
 						//rate isn't defined for sample stats, so use mean
-						begin       = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale);
-						end         = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale) + 1;
-						num_samples = recording.getSampleCount(*mEventFloatp);
+						begin       = ((recording.getMean(*mSampleFloatp)  - mMinBar) * value_scale);
+						end         = ((recording.getMean(*mSampleFloatp)  - mMinBar) * value_scale) + 1;
+						num_samples = recording.getSampleCount(*mSampleFloatp);
 					}
 				}
 				else
@@ -366,9 +366,9 @@ void LLStatBar::draw()
 					}
 					else if (mSampleFloatp)
 					{
-						begin       = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale);
-						end         = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale) + 1;
-						num_samples = recording.getSampleCount(*mEventFloatp);
+						begin       = ((recording.getMean(*mSampleFloatp)  - mMinBar) * value_scale);
+						end         = ((recording.getMean(*mSampleFloatp)  - mMinBar) * value_scale) + 1;
+						num_samples = recording.getSampleCount(*mSampleFloatp);
 					}
  				}
 				
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7243931dbbd435cf30e543f7ed89de9f63ce333e..984594177807d20124fb28ea957644e479903bd9 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),
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 74dc7f969313d40292a698c831c3f6af999cc7e3..3e93b7de65bb0da493ee552dc999c6e8a5421ef9 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/llview.cpp b/indra/llui/llview.cpp
index daeb4d79399f5f2578ba5943974d6ca20f5c3548..b2805a32e854736c6c34e06123d752251b52b07a 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 0568fa889a34aa8901ac22b4266edcd9d4ff2e2b..62bfb5456648817746e0d4df3a5729b1f834f53d 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 901260bec85aaf687b4f3ef7edd5f9c212c74d1a..dff0dcb2fd6af6c87dbcf681eff94ebbb0f9951e 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)
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
index 2c016d2560669373ad832b0a9aad9f678f88732f..a2ca20c739c49bcacc5d94875889ad1d2529bd78 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/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 348eb43b5e82aa3d8134f4abd3a12a76f2c4f962..e77f793a4386223ff08d7e61da986a1ccfbe7e81 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1297,7 +1297,7 @@ bool LLAppViewer::mainLoop()
 		LLTrace::get_frame_recording().nextPeriod();
 		LLTrace::TimeBlock::logStats();
 
-		LLTrace::getUIThreadRecorder().pullFromChildren();
+		LLTrace::get_master_thread_recorder()->pullFromChildren();
 
 		//clear call stack records
 		llclearcallstacks;
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 628f7f7bfb14ab659dbcc1a5665f3472b484140b..3dddf4b55454163d566520c96965ec07947e897c 100755
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -59,7 +59,6 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;
 static LLFastTimer::DeclareTimer 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 b7c5aeb5a87b331e591caba870fbf3228b23e558..4558597d89b4b3ed3a298427be4c3face8de7123 100755
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -293,7 +293,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/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 7a5e1dcad0705f1db6fbe6fc84ace556147814ee..d9226594351a6243159f3be511eddeb69cba706a 100755
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -430,18 +430,18 @@ void LLFastTimerView::draw()
 					}
 
 void LLFastTimerView::onOpen(const LLSD& key)
-				{
+{
 	setPauseState(false);
 	mRecording.reset();
 	mRecording.appendPeriodicRecording(LLTrace::get_frame_recording());
 	for(std::deque<TimerBarRow>::iterator it = mTimerBarRows.begin(), end_it = mTimerBarRows.end();
 		it != end_it; 
-				++it)
-			{
+		++it)
+	{
 		delete []it->mBars;
 		it->mBars = NULL;
-					}
-					}
+	}
+}
 										
 
 void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch)
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 4e514ddfd16891640fdcbde2307ccd311149bf66..c633e3acdde9d04aa37426065de895936d9fb5be 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -114,8 +114,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);
 BOOL		LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 5556a4c7d3a1f63af73c89d7c9f108752dd718df..63da7152b38edec9046723a3716159347b6399e8 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/llvocache.cpp b/indra/newview/llvocache.cpp
index 60d78890b5f59f2807155ecd296d83e01d634582..d87eb5d3db915717d438e5bc0c288d4d6f3f37c1 100755
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -34,8 +34,6 @@
 #include "llviewerregion.h"
 #include "pipeline.h"
 
-LLTrace::MemStatHandle	LLVOCachePartition::sMemStat("LLVOCachePartition");
-
 BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes) 
 {
 	return apr_file->read(src, n_bytes) == n_bytes ;
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index bf75cafac5bd67c447b3691ba98d307a90c7bc0e..c43c42908f4e331e74ad85de41448d318aa0f852 100755
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -35,7 +35,6 @@
 
 //---------------------------------------------------------------------------
 // Cache entries
-class LLVOCacheEntry;
 class LLCamera;
 
 class LLVOCacheEntry : public LLViewerOctreeEntryData
@@ -158,8 +157,6 @@ class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTr
 	/*virtual*/ S32 cull(LLCamera &camera);
 	void addOccluders(LLviewerOctreeGroup* gp);
 
-	static	LLTrace::MemStatHandle	sMemStat;
-
 private:	
 	void processOccluders(LLCamera* camera, const LLVector3* region_agent);
 
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
index b9712e5e9cd73460613561f16a28642f983e2df2..bd42b59df2855b8e3796d8342280bdcd80076ffc 100755
--- a/indra/newview/tests/llviewerassetstats_test.cpp
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -35,6 +35,7 @@
 #include "lluuid.h"
 #include "llsdutil.h"
 #include "llregionhandle.h"
+#include "lltracethreadrecorder.h"
 #include "../llvoavatar.h"
 
 namespace LLStatViewer
@@ -231,14 +232,15 @@ namespace tut
 	{
 		tst_viewerassetstats_index()
 		{
-			LLTrace::init();
+			LLTrace::set_master_thread_recorder(&mThreadRecorder);
 		}
 
 		~tst_viewerassetstats_index()
 		{
-			LLTrace::cleanup();
+			LLTrace::set_master_thread_recorder(NULL);
 		}
 
+		LLTrace::ThreadRecorder mThreadRecorder;
 	};
 	typedef test_group<tst_viewerassetstats_index> tst_viewerassetstats_index_t;
 	typedef tst_viewerassetstats_index_t::object tst_viewerassetstats_index_object_t;
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index 28de88201c2db1bfd3ee43c0a1af78028b276742..10f71a2843ef69fa42bfcbaad6229beb9aefed96 100755
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -41,6 +41,7 @@
 #include "stringize.h"
 #include "namedtempfile.h"
 #include "lltrace.h"
+#include "lltracethreadrecorder.h"
 
 #include "apr_pools.h"
 #include "apr_getopt.h"
@@ -483,6 +484,8 @@ void wouldHaveCrashed(const std::string& message)
 	tut::fail("llerrs message: " + message);
 }
 
+static LLTrace::ThreadRecorder* sMasterThreadRecorder = NULL;
+
 int main(int argc, char **argv)
 {
 	// The following line must be executed to initialize Google Mock
@@ -515,7 +518,11 @@ int main(int argc, char **argv)
 
 	ll_init_apr();
 	
-	LLTrace::init();
+	if (!sMasterThreadRecorder)
+	{
+		sMasterThreadRecorder = new LLTrace::ThreadRecorder();
+		LLTrace::set_master_thread_recorder(sMasterThreadRecorder);
+	}
 	apr_getopt_t* os = NULL;
 	if(APR_SUCCESS != apr_getopt_init(&os, gAPRPoolp, argc, argv))
 	{