diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 3df06c5172934cb0e087766cd1a45eeff34c37fc..ef0a633c9ce030cb60c40c211441034c6b09278e 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -34,13 +34,13 @@
 namespace LLTrace
 {
 
+
 ///////////////////////////////////////////////////////////////////////
-// Recording
+// RecordingBuffers
 ///////////////////////////////////////////////////////////////////////
 
-Recording::Recording() 
-:	mElapsedSeconds(0),
-	mCountsFloat(new AccumulatorBuffer<CountAccumulator<F64> >()),
+RecordingBuffers::RecordingBuffers() 
+:	mCountsFloat(new AccumulatorBuffer<CountAccumulator<F64> >()),
 	mMeasurementsFloat(new AccumulatorBuffer<MeasurementAccumulator<F64> >()),
 	mCounts(new AccumulatorBuffer<CountAccumulator<S64> >()),
 	mMeasurements(new AccumulatorBuffer<MeasurementAccumulator<S64> >()),
@@ -48,71 +48,7 @@ Recording::Recording()
 	mMemStats(new AccumulatorBuffer<MemStatAccumulator>())
 {}
 
-Recording::Recording( const Recording& other )
-{
-	llassert(other.mCountsFloat.notNull());
-	mSamplingTimer     = other.mSamplingTimer;
-	mElapsedSeconds    = other.mElapsedSeconds;
-	mCountsFloat       = other.mCountsFloat;
-	mMeasurementsFloat = other.mMeasurementsFloat;
-	mCounts            = other.mCounts;
-	mMeasurements      = other.mMeasurements;
-	mStackTimers       = other.mStackTimers;
-	mMemStats		   = other.mMemStats;
-
-	LLStopWatchControlsMixin<Recording>::setPlayState(other.getPlayState());
-}
-
-
-Recording::~Recording()
-{
-	stop();
-	llassert(isStopped());
-}
-
-void Recording::update()
-{
-	if (isStarted())
-	{
-		LLTrace::get_thread_recorder()->update(this);
-		mSamplingTimer.reset();
-	}
-}
-
-void Recording::handleReset()
-{
-	mCountsFloat.write()->reset();
-	mMeasurementsFloat.write()->reset();
-	mCounts.write()->reset();
-	mMeasurements.write()->reset();
-	mStackTimers.write()->reset();
-	mMemStats.write()->reset();
-
-	mElapsedSeconds = 0.0;
-	mSamplingTimer.reset();
-}
-
-void Recording::handleStart()
-{
-	mSamplingTimer.reset();
-	LLTrace::get_thread_recorder()->activate(this);
-}
-
-void Recording::handleStop()
-{
-	mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
-	LLTrace::TimeBlock::processTimes();
-	LLTrace::get_thread_recorder()->deactivate(this);
-}
-
-void Recording::handleSplitTo(Recording& other)
-{
-	stop();
-	other.restart();
-	handOffTo(other);
-}
-
-void Recording::handOffTo(Recording& other)
+void RecordingBuffers::handOffTo(RecordingBuffers& other)
 {
 	other.mCountsFloat.write()->reset(mCountsFloat);
 	other.mMeasurementsFloat.write()->reset(mMeasurementsFloat);
@@ -122,7 +58,7 @@ void Recording::handOffTo(Recording& other)
 	other.mMemStats.write()->reset(mMemStats);
 }
 
-void Recording::makePrimary()
+void RecordingBuffers::makePrimary()
 {
 	mCountsFloat.write()->makePrimary();
 	mMeasurementsFloat.write()->makePrimary();
@@ -144,12 +80,12 @@ void Recording::makePrimary()
 	}
 }
 
-bool Recording::isPrimary() const
+bool RecordingBuffers::isPrimary() const
 {
 	return mCounts->isPrimary();
 }
 
-void Recording::makeUnique()
+void RecordingBuffers::makeUnique()
 {
 	mCountsFloat.makeUnique();
 	mMeasurementsFloat.makeUnique();
@@ -159,19 +95,17 @@ void Recording::makeUnique()
 	mMemStats.makeUnique();
 }
 
-void Recording::appendRecording( const Recording& other )
+void RecordingBuffers::appendBuffers( const RecordingBuffers& other )
 {
 	mCountsFloat.write()->addSamples(*other.mCountsFloat);
 	mMeasurementsFloat.write()->addSamples(*other.mMeasurementsFloat);
 	mCounts.write()->addSamples(*other.mCounts);
 	mMeasurements.write()->addSamples(*other.mMeasurements);
 	mMemStats.write()->addSamples(*other.mMemStats);
-
 	mStackTimers.write()->addSamples(*other.mStackTimers);
-	mElapsedSeconds += other.mElapsedSeconds;
 }
 
-void Recording::mergeRecording( const Recording& other)
+void RecordingBuffers::mergeBuffers( const RecordingBuffers& other)
 {
 	mCountsFloat.write()->addSamples(*other.mCountsFloat);
 	mMeasurementsFloat.write()->addSamples(*other.mMeasurementsFloat);
@@ -180,6 +114,84 @@ void Recording::mergeRecording( const Recording& other)
 	mMemStats.write()->addSamples(*other.mMemStats);
 }
 
+void RecordingBuffers::resetBuffers(RecordingBuffers* other)
+{
+	mCountsFloat.write()->reset(other ? other->mCountsFloat : NULL);
+	mMeasurementsFloat.write()->reset(other ? other->mMeasurementsFloat : NULL);
+	mCounts.write()->reset(other ? other->mCounts : NULL);
+	mMeasurements.write()->reset(other ? other->mMeasurements : NULL);
+	mStackTimers.write()->reset(other ? other->mStackTimers : NULL);
+	mMemStats.write()->reset(other ? other->mMemStats : NULL);
+}
+
+///////////////////////////////////////////////////////////////////////
+// Recording
+///////////////////////////////////////////////////////////////////////
+
+Recording::Recording() 
+:	mElapsedSeconds(0)
+{}
+
+Recording::Recording( const Recording& other )
+{
+	LLStopWatchControlsMixin<Recording>::setPlayState(other.getPlayState());
+}
+
+
+Recording::~Recording()
+{
+	stop();
+	llassert(isStopped());
+}
+
+void Recording::update()
+{
+	if (isStarted())
+	{
+		LLTrace::get_thread_recorder()->update(this);
+		mSamplingTimer.reset();
+	}
+}
+
+void Recording::handleReset()
+{
+	resetBuffers();
+
+	mElapsedSeconds = 0.0;
+	mSamplingTimer.reset();
+}
+
+void Recording::handleStart()
+{
+	mSamplingTimer.reset();
+	LLTrace::get_thread_recorder()->activate(this);
+}
+
+void Recording::handleStop()
+{
+	mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
+	LLTrace::TimeBlock::processTimes();
+	LLTrace::get_thread_recorder()->deactivate(this);
+}
+
+void Recording::handleSplitTo(Recording& other)
+{
+	stop();
+	other.restart();
+	handOffTo(other);
+}
+
+void Recording::appendRecording( const Recording& other )
+{
+	appendBuffers(other);
+	mElapsedSeconds += other.mElapsedSeconds;
+}
+
+void Recording::mergeRecording( const Recording& other)
+{
+	mergeBuffers(other);
+}
+
 LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator>& stat) const
 {
 	const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()];
@@ -356,8 +368,6 @@ U32 Recording::getSampleCount( const TraceType<MeasurementAccumulator<S64> >& st
 	return (*mMeasurements)[stat.getIndex()].getSampleCount();
 }
 
-
-
 ///////////////////////////////////////////////////////////////////////
 // PeriodicRecording
 ///////////////////////////////////////////////////////////////////////
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 7dd3b98187882f073f1d46d00c2bfbaa8e412f8d..a5edcb857a37f581b9c72468a5339d8bfe2c2f3b 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -100,19 +100,36 @@ class LLStopWatchControlsMixin
 
 namespace LLTrace
 {
-	class Recording : public LLStopWatchControlsMixin<Recording>
+	struct RecordingBuffers
 	{
-	public:
-		Recording();
-
-		Recording(const Recording& other);
-		~Recording();
+		RecordingBuffers();
+		LLCopyOnWritePointer<AccumulatorBuffer<CountAccumulator<F64> > >		mCountsFloat;
+		LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<F64> > >	mMeasurementsFloat;
+		LLCopyOnWritePointer<AccumulatorBuffer<CountAccumulator<S64> > >		mCounts;
+		LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<S64> > >	mMeasurements;
+		LLCopyOnWritePointer<AccumulatorBuffer<TimeBlockAccumulator> >			mStackTimers;
+		LLCopyOnWritePointer<AccumulatorBuffer<MemStatAccumulator> >			mMemStats;
 
+		void handOffTo(RecordingBuffers& other);
 		void makePrimary();
 		bool isPrimary() const;
 
 		void makeUnique();
 
+		void appendBuffers(const RecordingBuffers& other);
+		void mergeBuffers(const RecordingBuffers& other);
+		void resetBuffers(RecordingBuffers* other = NULL);
+
+	};
+
+	class Recording : public LLStopWatchControlsMixin<Recording>, public RecordingBuffers
+	{
+	public:
+		Recording();
+
+		Recording(const Recording& other);
+		~Recording();
+
 		// accumulate data from subsequent, non-overlapping recording
 		void appendRecording(const Recording& other);
 
@@ -218,8 +235,6 @@ namespace LLTrace
 
 		LLUnit<LLUnits::Seconds, F64> getDuration() const { return LLUnit<LLUnits::Seconds, F64>(mElapsedSeconds); }
 
-		void handOffTo(Recording& other);
-
 	private:
 		friend class ThreadRecorder;
 
@@ -232,13 +247,6 @@ namespace LLTrace
 		// returns data for current thread
 		class ThreadRecorder* getThreadRecorder(); 
 
-		LLCopyOnWritePointer<AccumulatorBuffer<CountAccumulator<F64> > >		mCountsFloat;
-		LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<F64> > >	mMeasurementsFloat;
-		LLCopyOnWritePointer<AccumulatorBuffer<CountAccumulator<S64> > >		mCounts;
-		LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<S64> > >	mMeasurements;
-		LLCopyOnWritePointer<AccumulatorBuffer<TimeBlockAccumulator> >			mStackTimers;
-		LLCopyOnWritePointer<AccumulatorBuffer<MemStatAccumulator> >			mMemStats;
-
 		LLTimer			mSamplingTimer;
 		F64				mElapsedSeconds;
 	};