diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index c149a1fe5ccab0053ad68c734a3e84cf9bb66330..c720df755509e35392297756e59f3984bd625032 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -29,6 +29,7 @@
 
 #include "llmemory.h"
 #include "llthread.h"
+#include "lltrace.h"
 
 //static
 BOOL LLCommon::sAprInitialized = FALSE;
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index a741d342d30d072bfdef97bb9b0232f88f87921c..0a35474b7fd79d203654b0b1d26a3db1648fa681 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -28,6 +28,7 @@
 
 #include "llstl.h"
 #include "lltimer.h"	// ms_sleep()
+#include "lltrace.h"
 
 //============================================================================
 
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 2ff524d9bab7b368f340749fd531750ce3ce2fee..738484262710b274af96e3810c5c05084a2d8b87 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -32,6 +32,7 @@
 #include "llmutex.h"
 
 #include "lltimer.h"
+#include "lltrace.h"
 
 #if LL_LINUX || LL_SOLARIS
 #include <sched.h>
@@ -85,7 +86,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
 {
 	LLThread *threadp = (LLThread *)datap;
 
-	sTraceData = new LLTrace::SlaveThreadTrace();
+	setTraceData(new LLTrace::SlaveThreadTrace());
 
 #if !LL_DARWIN
 	sThreadIndex = threadp->mID;
@@ -100,6 +101,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
 	threadp->mStatus = STOPPED;
 
 	delete sTraceData.get();
+	sTraceData = NULL;
 
 	return NULL;
 }
@@ -311,3 +313,13 @@ void LLThread::wakeLocked()
 		mRunCondition->signal();
 	}
 }
+
+LLTrace::ThreadTrace* LLThread::getTraceData()
+{
+	return sTraceData.get();
+}
+
+void LLThread::setTraceData( LLTrace::ThreadTrace* data )
+{
+	sTraceData = data;
+}
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 5cd287ec39f6c3f0f0185240223f1a9216a84b0b..334ea2f0da6fc72c5d92dec0e61bf58126a7ad3f 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -30,8 +30,12 @@
 #include "llapp.h"
 #include "llapr.h"
 #include "apr_thread_cond.h"
-#include "lltrace.h"
+#include "llmutex.h"
 
+namespace LLTrace
+{
+	class ThreadTrace;
+}
 class LL_COMMON_API LLThread
 {
 private:
@@ -87,8 +91,8 @@ class LL_COMMON_API LLThread
 
 	U32 getID() const { return mID; }
 
-	static LLTrace::ThreadTrace* getTraceData() { return sTraceData.get(); }
-	static void setTraceData(LLTrace::ThreadTrace* data) { sTraceData = data;}
+	static LLTrace::ThreadTrace* getTraceData();
+	static void setTraceData(LLTrace::ThreadTrace* data);
 
 private:
 	BOOL				mPaused;
diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp
index 24a2b33a5f1addc271c802a3f6eb6a8662f381b1..2da4363b1d024dbb188a574d4c09f9ffea3b0f4c 100644
--- a/indra/llcommon/lltrace.cpp
+++ b/indra/llcommon/lltrace.cpp
@@ -55,40 +55,97 @@ MasterThreadTrace& getMasterThreadTrace()
 	return *gMasterThreadTrace;
 }
 
-
-
 ///////////////////////////////////////////////////////////////////////
 // Sampler
 ///////////////////////////////////////////////////////////////////////
 
+Sampler::Sampler(ThreadTrace* thread_trace) 
+:	mElapsedSeconds(0),
+	mIsStarted(false),
+	mThreadTrace(thread_trace)
+{
+}
 
-void Sampler::stop()
+Sampler::~Sampler()
 {
-	getThreadTrace()->deactivate(this);
+}
+
+void Sampler::start()
+{
+	reset();
+	resume();
+}
+
+void Sampler::reset()
+{
+	mF32Stats.reset();
+	mS32Stats.reset();
+	mStackTimers.reset();
+
+	mElapsedSeconds = 0.0;
+	mSamplingTimer.reset();
 }
 
 void Sampler::resume()
 {
-	getThreadTrace()->activate(this);
+	if (!mIsStarted)
+	{
+		mSamplingTimer.reset();
+		getThreadTrace()->activate(this);
+		mIsStarted = true;
+	}
+}
+
+void Sampler::stop()
+{
+	if (mIsStarted)
+	{
+		mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
+		getThreadTrace()->deactivate(this);
+		mIsStarted = false;
+	}
+}
+
+ThreadTrace* Sampler::getThreadTrace()
+{
+	return mThreadTrace;
+}
+
+void Sampler::makePrimary()
+{
+	mF32Stats.makePrimary();
+	mS32Stats.makePrimary();
+	mStackTimers.makePrimary();
 }
 
-class ThreadTrace* Sampler::getThreadTrace()
+void Sampler::mergeFrom( const Sampler* other )
 {
-	return LLThread::getTraceData();
+	mF32Stats.mergeFrom(other->mF32Stats);
+	mS32Stats.mergeFrom(other->mS32Stats);
+	mStackTimers.mergeFrom(other->mStackTimers);
 }
 
+
 ///////////////////////////////////////////////////////////////////////
 // MasterThreadTrace
 ///////////////////////////////////////////////////////////////////////
 
 ThreadTrace::ThreadTrace()
 {
-	mPrimarySampler.makePrimary();
+	mPrimarySampler = createSampler();
+	mPrimarySampler->makePrimary();
+	mPrimarySampler->start();
 }
 
-ThreadTrace::ThreadTrace( const ThreadTrace& other ) :	mPrimarySampler(other.mPrimarySampler)
+ThreadTrace::ThreadTrace( const ThreadTrace& other ) 
+:	mPrimarySampler(new Sampler(*(other.mPrimarySampler)))
 {
-	mPrimarySampler.makePrimary();
+	mPrimarySampler->makePrimary();
+}
+
+ThreadTrace::~ThreadTrace()
+{
+	delete mPrimarySampler;
 }
 
 void ThreadTrace::activate( Sampler* sampler )
@@ -117,11 +174,13 @@ void ThreadTrace::flushPrimary()
 	{
 		(*it)->mergeFrom(mPrimarySampler);
 	}
-	mPrimarySampler.reset();
+	mPrimarySampler->reset();
 }
 
-
-
+Sampler* ThreadTrace::createSampler()
+{
+	return new Sampler(this);
+}
 
 
 
@@ -129,12 +188,23 @@ void ThreadTrace::flushPrimary()
 // SlaveThreadTrace
 ///////////////////////////////////////////////////////////////////////
 
+SlaveThreadTrace::SlaveThreadTrace()
+:	ThreadTrace(getMasterThreadTrace()),
+	mSharedData(createSampler())
+{
+	getMasterThreadTrace().addSlaveThread(this);
+}
+
+SlaveThreadTrace::~SlaveThreadTrace()
+{
+	getMasterThreadTrace().removeSlaveThread(this);
+}
+
 void SlaveThreadTrace::pushToMaster()
 {
 	mSharedData.copyFrom(mPrimarySampler);
 }
 
-
 ///////////////////////////////////////////////////////////////////////
 // MasterThreadTrace
 ///////////////////////////////////////////////////////////////////////
@@ -155,7 +225,7 @@ void MasterThreadTrace::addSlaveThread( class SlaveThreadTrace* child )
 {
 	LLMutexLock lock(&mSlaveListMutex);
 
-	mSlaveThreadTraces.push_back(SlaveThreadTraceProxy(child));
+	mSlaveThreadTraces.push_back(SlaveThreadTraceProxy(child, createSampler()));
 }
 
 void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child )
@@ -175,15 +245,26 @@ void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child )
 }
 
 void MasterThreadTrace::pushToMaster()
-{
-
-}
+{}
 
 MasterThreadTrace::MasterThreadTrace()
 {
 	LLThread::setTraceData(this);
 }
 
+///////////////////////////////////////////////////////////////////////
+// MasterThreadTrace::SlaveThreadTraceProxy
+///////////////////////////////////////////////////////////////////////
+
+MasterThreadTrace::SlaveThreadTraceProxy::SlaveThreadTraceProxy( class SlaveThreadTrace* trace, Sampler* storage ) 
+:	mSlaveTrace(trace),
+	mSamplerStorage(storage)
+{}
 
+MasterThreadTrace::SlaveThreadTraceProxy::~SlaveThreadTraceProxy()
+{
+	delete mSamplerStorage;
 }
 
+
+}
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 601b5ed182faf46a6ec1286cfbc67f50c2779c4b..a443735e6980df321b990c385e4fd637a3a55063 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -32,6 +32,7 @@
 
 #include "llmutex.h"
 #include "llmemory.h"
+#include "lltimer.h"
 
 #include <list>
 
@@ -39,6 +40,7 @@
 #define TOKEN_PASTE(x, y) TOKEN_PASTE_ACTUAL(x, y)
 #define RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer);
 
+
 namespace LLTrace
 {
 	void init();
@@ -135,7 +137,7 @@ namespace LLTrace
 
 		static AccumulatorBuffer<ACCUMULATOR>& getDefaultBuffer()
 		{
-			static AccumulatorBuffer sBuffer;
+			static AccumulatorBuffer sBuffer(STATIC_ALLOC);
 			return sBuffer;
 		}
 
@@ -354,54 +356,38 @@ namespace LLTrace
 	class Sampler
 	{
 	public:
-		Sampler() {}
-		Sampler(const Sampler& other)
-		:	mF32Stats(other.mF32Stats),
-			mS32Stats(other.mS32Stats),
-			mTimers(other.mTimers)
-		{}
-
-		~Sampler()
-		{}
+		~Sampler();
 
-		void makePrimary()
-		{
-			mF32Stats.makePrimary();
-			mS32Stats.makePrimary();
-			mTimers.makePrimary();
-		}
-
-		void start()
-		{
-			reset();
-			resume();
-		}
+		void makePrimary();
 
+		void start();
 		void stop();
 		void resume();
 
-		void mergeFrom(const Sampler& other)
-		{
-			mF32Stats.mergeFrom(other.mF32Stats);
-			mS32Stats.mergeFrom(other.mS32Stats);
-			mTimers.mergeFrom(other.mTimers);
-		}
+		void mergeFrom(const Sampler* other);
 
-		void reset()
-		{
-			mF32Stats.reset();
-			mS32Stats.reset();
-			mTimers.reset();
-		}
+		void reset();
+
+		bool isStarted() { return mIsStarted; }
 
 	private:
+		friend class ThreadTrace;
+		Sampler(class ThreadTrace* thread_trace);
+
+		// no copy
+		Sampler(const Sampler& other) {}
 		// returns data for current thread
 		class ThreadTrace* getThreadTrace(); 
 
 		AccumulatorBuffer<StatAccumulator<F32> >	mF32Stats;
 		AccumulatorBuffer<StatAccumulator<S32> >	mS32Stats;
 
-		AccumulatorBuffer<TimerAccumulator>			mTimers;
+		AccumulatorBuffer<TimerAccumulator>			mStackTimers;
+
+		bool										mIsStarted;
+		LLTimer										mSamplingTimer;
+		F64											mElapsedSeconds;
+		ThreadTrace*								mThreadTrace;
 	};
 
 	class ThreadTrace
@@ -410,17 +396,19 @@ namespace LLTrace
 		ThreadTrace();
 		ThreadTrace(const ThreadTrace& other);
 
-		virtual ~ThreadTrace() {}
+		virtual ~ThreadTrace();
 
 		void activate(Sampler* sampler);
 		void deactivate(Sampler* sampler);
 		void flushPrimary();
 
+		Sampler* createSampler();
+
 		virtual void pushToMaster() = 0;
 
-		Sampler* getPrimarySampler() { return &mPrimarySampler; }
+		Sampler* getPrimarySampler() { return mPrimarySampler; }
 	protected:
-		Sampler					mPrimarySampler;
+		Sampler*				mPrimarySampler;
 		std::list<Sampler*>		mActiveSamplers;
 	};
 
@@ -440,11 +428,11 @@ namespace LLTrace
 	private:
 		struct SlaveThreadTraceProxy
 		{
-			SlaveThreadTraceProxy(class SlaveThreadTrace* trace)
-				:	mSlaveTrace(trace)
-			{}
+			SlaveThreadTraceProxy(class SlaveThreadTrace* trace, Sampler* storage);
+
+			~SlaveThreadTraceProxy();
 			class SlaveThreadTrace*	mSlaveTrace;
-			Sampler				mSamplerStorage;
+			Sampler*				mSamplerStorage;
 		};
 		typedef std::list<SlaveThreadTraceProxy> slave_thread_trace_list_t;
 
@@ -455,18 +443,8 @@ namespace LLTrace
 	class SlaveThreadTrace : public ThreadTrace
 	{
 	public:
-		explicit 
-		SlaveThreadTrace()
-		:	ThreadTrace(getMasterThreadTrace()),
-			mSharedData(mPrimarySampler)
-		{
-			getMasterThreadTrace().addSlaveThread(this);
-		}
-
-		~SlaveThreadTrace()
-		{
-			getMasterThreadTrace().removeSlaveThread(this);
-		}
+		SlaveThreadTrace();
+		~SlaveThreadTrace();
 
 		// call this periodically to gather stats data for master thread to consume
 		/*virtual*/ void pushToMaster();
@@ -479,29 +457,35 @@ namespace LLTrace
 		{
 		public:
 			explicit 
-			SharedData(const Sampler& other_sampler) 
-			:	mSampler(other_sampler)
-			{}
+			SharedData(Sampler* sampler) 
+			:	mSampler(sampler)
+			{
+			}
+
+			~SharedData()
+			{
+				delete mSampler;
+			}
 
-			void copyFrom(Sampler& source)
+			void copyFrom(Sampler* source)
 			{
 				LLMutexLock lock(&mSamplerMutex);
 				{	
-					mSampler.mergeFrom(source);
+					mSampler->mergeFrom(source);
 				}
 			}
 
-			void copyTo(Sampler& sink)
+			void copyTo(Sampler* sink)
 			{
 				LLMutexLock lock(&mSamplerMutex);
 				{
-					sink.mergeFrom(mSampler);
+					sink->mergeFrom(mSampler);
 				}
 			}
 		private:
 			// add a cache line's worth of unused space to avoid any potential of false sharing
 			LLMutex					mSamplerMutex;
-			Sampler					mSampler;
+			Sampler*				mSampler;
 		};
 		SharedData					mSharedData;
 	};
diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp
index be7aae4eb7d31b2339bfea4ed9514c2c67de44d8..29497257ac7951a7ed062550855fb1f76176cafd 100644
--- a/indra/llimage/tests/llimageworker_test.cpp
+++ b/indra/llimage/tests/llimageworker_test.cpp
@@ -31,6 +31,8 @@
 #include "../llimageworker.h"
 // For timer class
 #include "../llcommon/lltimer.h"
+// for lltrace class
+#include "../llcommon/lltrace.h"
 // Tut header
 #include "../test/lltut.h"
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index fcbef491fef7095e5f6c445f8b395d9e07c06bda..0bb87dfa6ca79d4809eeedbc35d564ee7255256e 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -60,7 +60,7 @@
 #include "llcurl.h"
 #include "llcalc.h"
 #include "lltexturestats.h"
-#include "lltexturestats.h"
+#include "lltrace.h"
 #include "llviewerwindow.h"
 #include "llviewerdisplay.h"
 #include "llviewermedia.h"