diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 3fa08aee8d1b389274d81e2a28ce6bae29699ece..1bd5d06d299ee246d62beac64c58f2b9ede8e698 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -148,6 +148,13 @@ class LLSD::Impl
 
 	virtual void dumpStats() const;
 	virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
+	// Container subclasses contain LLSD objects, rather than directly
+	// containing Impl objects. This helper forwards through LLSD.
+	void calcStats(const LLSD& llsd, S32 type_counts[], S32 share_counts[]) const
+	{
+		safe(llsd.impl).calcStats(type_counts, share_counts);
+	}
+
 
 	static const LLSD& undef();
 	
@@ -459,7 +466,7 @@ namespace
 		while (iter != endMap())
 		{
 			//std::cout << "  " << (*iter).first << ": " << (*iter).second << std::endl;
-			(*iter).second.calcStats(type_counts, share_counts);
+			Impl::calcStats((*iter).second, type_counts, share_counts);
 			iter++;
 		}
 
@@ -606,7 +613,7 @@ namespace
 		LLSD::array_const_iterator iter = beginArray();
 		while (iter != endArray())
 		{	// Add values for all items held in the array
-			(*iter).calcStats(type_counts, share_counts);
+			Impl::calcStats((*iter), type_counts, share_counts);
 			iter++;
 		}
 
@@ -802,7 +809,7 @@ void LLSD::clear()						{ Impl::assignUndefined(impl); }
 
 LLSD::Type LLSD::type() const			{ return safe(impl).type(); }
 
-// Scaler Constructors
+// Scalar Constructors
 LLSD::LLSD(Boolean v) : impl(0)			{ ALLOC_LLSD_OBJECT;	assign(v); }
 LLSD::LLSD(Integer v) : impl(0)			{ ALLOC_LLSD_OBJECT;	assign(v); }
 LLSD::LLSD(Real v) : impl(0)			{ ALLOC_LLSD_OBJECT;	assign(v); }
@@ -894,8 +901,10 @@ LLSD&		LLSD::operator[](Integer i)
 const LLSD& LLSD::operator[](Integer i) const
 										{ return safe(impl).ref(i); }
 
+#ifdef LLSD_DEBUG_INFO
 U32 LLSD::allocationCount()				{ return Impl::sAllocationCount; }
 U32 LLSD::outstandingCount()			{ return Impl::sOutstandingCount; }
+#endif
 
 static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
 {
@@ -947,9 +956,9 @@ LLSD::array_const_iterator	LLSD::endArray() const	{ return safe(impl).endArray()
 
 
 // Diagnostic dump of contents in an LLSD object
+#ifdef LLSD_DEBUG_INFO
 void LLSD::dumpStats()	const						{ safe(impl).dumpStats();	}
-void LLSD::calcStats(S32 type_counts[], S32 share_counts[]) const
-													{ safe(impl).calcStats(type_counts, share_counts);	}
+#endif
 
 // static
 std::string		LLSD::typeString(Type type)
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index 80c3e9e7b582c6e8bb3415c8f6ae17f8b1db2687..3519b134c20a5102f62e7b3ea16341820c629ab3 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -387,13 +387,20 @@ class LL_COMMON_API LLSD
 		class Impl;
 private:
 		Impl* impl;
+		friend class LLSD::Impl;
 	//@}
 	
 	/** @name Unit Testing Interface */
 	//@{
 public:
+#ifdef LLSD_DEBUG_INFO
+		/// @warn THESE COUNTS WILL NOT BE ACCURATE IN A MULTI-THREADED
+		/// ENVIRONMENT.
+		///
+		/// These counts track LLSD::Impl (hidden) objects.
 		static U32 allocationCount();	///< how many Impls have been made
 		static U32 outstandingCount();	///< how many Impls are still alive
+#endif
 	//@}
 
 private:
@@ -407,12 +414,17 @@ class LL_COMMON_API LLSD
 	//@}
 
 public:
+#ifdef LLSD_DEBUG_INFO
 	void			dumpStats() const;					// Output information on object and usage
-	void			calcStats(S32 type_counts[], S32 share_counts[]) const;		// Calculate the number of LLSD objects used by this value
+#endif
 
 	static std::string		typeString(Type type);		// Return human-readable type as a string
 
 #ifdef LLSD_DEBUG_INFO
+	/// @warn THESE COUNTS WILL NOT BE ACCURATE IN A MULTI-THREADED
+	/// ENVIRONMENT.
+	///
+	/// These counts track LLSD (public) objects.
 	static S32		sLLSDAllocationCount;		// Number of LLSD objects ever created
 	static S32		sLLSDNetObjects;			// Number of LLSD objects that exist
 #endif