From cc1fb7bcac2924674763d917f66d84fbadb11623 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 17 Nov 2011 08:06:31 -0500 Subject: LLSD-14: Bring over llsd.{h,cpp} enhancements from server-trunk. Because new enum values have been added to the LLSD type field, a few external switch statements must be adjusted to suppress fatal warnings, even though we never expect to encounter an LLSD instance containing any of the new values. --- indra/llcommon/llsd.cpp | 194 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 162 insertions(+), 32 deletions(-) (limited to 'indra/llcommon/llsd.cpp') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 6ca0737445..862b6b5ebc 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -31,6 +31,7 @@ #include "../llmath/llmath.h" #include "llformat.h" #include "llsdserialize.h" +#include "stringize.h" #ifndef LL_RELEASE_FOR_DOWNLOAD #define NAME_UNNAMED_NAMESPACE @@ -50,6 +51,24 @@ namespace using namespace LLSDUnnamedNamespace; #endif + +// Normally undefined +#ifdef LLSD_DEBUG_INFO + +// statics +S32 LLSD::sLLSDAllocationCount = 0; +S32 LLSD::sLLSDNetObjects = 0; + +#define ALLOC_LLSD_OBJECT { sLLSDNetObjects++; sLLSDAllocationCount++; } +#define FREE_LLSD_OBJECT { sLLSDNetObjects--; } + +#else + +#define ALLOC_LLSD_OBJECT +#define FREE_LLSD_OBJECT + +#endif + class LLSD::Impl /**< This class is the abstract base class of the implementation of LLSD It provides the reference counting implementation, and the default @@ -58,13 +77,10 @@ class LLSD::Impl */ { -private: - U32 mUseCount; - protected: Impl(); - enum StaticAllocationMarker { STATIC }; + enum StaticAllocationMarker { STATIC_USAGE_COUNT = 0xFFFFFFFF }; Impl(StaticAllocationMarker); ///< This constructor is used for static objects and causes the // suppresses adjusting the debugging counters when they are @@ -72,7 +88,9 @@ protected: virtual ~Impl(); - bool shared() const { return mUseCount > 1; } + bool shared() const { return (mUseCount > 1) && (mUseCount != STATIC_USAGE_COUNT); } + + U32 mUseCount; public: static void reset(Impl*& var, Impl* impl); @@ -128,6 +146,9 @@ public: virtual LLSD::array_const_iterator beginArray() const { return endArray(); } virtual LLSD::array_const_iterator endArray() const { static const std::vector empty; return empty.end(); } + virtual void dumpStats() const; + virtual void calcStats(S32 type_counts[], S32 share_counts[]) const; + static const LLSD& undef(); static U32 sAllocationCount; @@ -360,6 +381,9 @@ namespace LLSD::map_iterator endMap() { return mData.end(); } virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); } virtual LLSD::map_const_iterator endMap() const { return mData.end(); } + + virtual void dumpStats() const; + virtual void calcStats(S32 type_counts[], S32 share_counts[]) const; }; ImplMap& ImplMap::makeMap(LLSD::Impl*& var) @@ -414,6 +438,36 @@ namespace return i->second; } + void ImplMap::dumpStats() const + { + std::cout << "Map size: " << mData.size() << std::endl; + + #ifdef LLSD_DEBUG_INFO + std::cout << "LLSD Net Objects: " << LLSD::sLLSDNetObjects << std::endl; + std::cout << "LLSD allocations: " << LLSD::sLLSDAllocationCount << std::endl; + #endif + + std::cout << "LLSD::Impl Net Objects: " << sOutstandingCount << std::endl; + std::cout << "LLSD::Impl allocations: " << sAllocationCount << std::endl; + + Impl::dumpStats(); + } + + void ImplMap::calcStats(S32 type_counts[], S32 share_counts[]) const + { + LLSD::map_const_iterator iter = beginMap(); + while (iter != endMap()) + { + //std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl; + (*iter).second.calcStats(type_counts, share_counts); + iter++; + } + + // Add in the values for this map + Impl::calcStats(type_counts, share_counts); + } + + class ImplArray : public LLSD::Impl { private: @@ -449,6 +503,8 @@ namespace LLSD::array_iterator endArray() { return mData.end(); } virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); } virtual LLSD::array_const_iterator endArray() const { return mData.end(); } + + virtual void calcStats(S32 type_counts[], S32 share_counts[]) const; }; ImplArray& ImplArray::makeArray(Impl*& var) @@ -490,12 +546,13 @@ namespace void ImplArray::insert(LLSD::Integer i, const LLSD& v) { - if (i < 0) { + if (i < 0) + { return; } DataVector::size_type index = i; - if (index >= mData.size()) + if (index >= mData.size()) // tbd - sanity check limit for index ? { mData.resize(index + 1); } @@ -543,6 +600,19 @@ namespace return mData[index]; } + + void ImplArray::calcStats(S32 type_counts[], S32 share_counts[]) const + { + LLSD::array_const_iterator iter = beginArray(); + while (iter != endArray()) + { // Add values for all items held in the array + (*iter).calcStats(type_counts, share_counts); + iter++; + } + + // Add in the values for this array + Impl::calcStats(type_counts, share_counts); + } } LLSD::Impl::Impl() @@ -564,8 +634,11 @@ LLSD::Impl::~Impl() void LLSD::Impl::reset(Impl*& var, Impl* impl) { - if (impl) ++impl->mUseCount; - if (var && --var->mUseCount == 0) + if (impl && impl->mUseCount != STATIC_USAGE_COUNT) + { + ++impl->mUseCount; + } + if (var && var->mUseCount != STATIC_USAGE_COUNT && --var->mUseCount == 0) { delete var; } @@ -574,13 +647,13 @@ void LLSD::Impl::reset(Impl*& var, Impl* impl) LLSD::Impl& LLSD::Impl::safe(Impl* impl) { - static Impl theUndefined(STATIC); + static Impl theUndefined(STATIC_USAGE_COUNT); return impl ? *impl : theUndefined; } const LLSD::Impl& LLSD::Impl::safe(const Impl* impl) { - static Impl theUndefined(STATIC); + static Impl theUndefined(STATIC_USAGE_COUNT); return impl ? *impl : theUndefined; } @@ -656,6 +729,39 @@ const LLSD& LLSD::Impl::undef() return immutableUndefined; } +void LLSD::Impl::dumpStats() const +{ + S32 type_counts[LLSD::TypeLLSDNumTypes + 1]; + memset(&type_counts, 0, LLSD::TypeLLSDNumTypes * sizeof(S32)); + + S32 share_counts[LLSD::TypeLLSDNumTypes + 1]; + memset(&share_counts, 0, LLSD::TypeLLSDNumTypes * sizeof(S32)); + + // Add info from all the values this object has + calcStats(type_counts, share_counts); + + S32 type_index = LLSD::TypeLLSDTypeBegin; + while (type_index != LLSD::TypeLLSDTypeEnd) + { + std::cout << LLSD::typeString((LLSD::Type)type_index) << " type " + << type_counts[type_index] << " objects, " + << share_counts[type_index] << " shared" + << std::endl; + type_index++; + } +} + + +void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const +{ + type_counts[(S32) type()]++; + if (shared()) + { + share_counts[(S32) type()]++; + } +} + + U32 LLSD::Impl::sAllocationCount = 0; U32 LLSD::Impl::sOutstandingCount = 0; @@ -681,10 +787,10 @@ namespace } -LLSD::LLSD() : impl(0) { } -LLSD::~LLSD() { Impl::reset(impl, 0); } +LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; } +LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); } -LLSD::LLSD(const LLSD& other) : impl(0) { assign(other); } +LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); } void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); } @@ -693,17 +799,17 @@ void LLSD::clear() { Impl::assignUndefined(impl); } LLSD::Type LLSD::type() const { return safe(impl).type(); } // Scaler Constructors -LLSD::LLSD(Boolean v) : impl(0) { assign(v); } -LLSD::LLSD(Integer v) : impl(0) { assign(v); } -LLSD::LLSD(Real v) : impl(0) { assign(v); } -LLSD::LLSD(const UUID& v) : impl(0) { assign(v); } -LLSD::LLSD(const String& v) : impl(0) { assign(v); } -LLSD::LLSD(const Date& v) : impl(0) { assign(v); } -LLSD::LLSD(const URI& v) : impl(0) { assign(v); } -LLSD::LLSD(const Binary& v) : impl(0) { assign(v); } +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); } +LLSD::LLSD(const UUID& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } +LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } // Convenience Constructors -LLSD::LLSD(F32 v) : impl(0) { assign((Real)v); } +LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); } // Scalar Assignment void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); } @@ -726,7 +832,7 @@ LLSD::URI LLSD::asURI() const { return safe(impl).asURI(); } LLSD::Binary LLSD::asBinary() const { return safe(impl).asBinary(); } // const char * helpers -LLSD::LLSD(const char* v) : impl(0) { assign(v); } +LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } void LLSD::assign(const char* v) { if(v) assign(std::string(v)); @@ -801,15 +907,9 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat) { std::ostringstream out; if (useXMLFormat) - { - LLSDXMLStreamer xml_streamer(llsd); - out << xml_streamer; - } + out << LLSDXMLStreamer(llsd); else - { - LLSDNotationStreamer notation_streamer(llsd); - out << notation_streamer; - } + out << LLSDNotationStreamer(llsd); out_string = out.str(); } int len = out_string.length(); @@ -840,3 +940,33 @@ LLSD::array_iterator LLSD::beginArray() { return makeArray(impl).beginArray(); LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); } LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); } LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); } + + +// Diagnostic dump of contents in an LLSD object +void LLSD::dumpStats() const { safe(impl).dumpStats(); } +void LLSD::calcStats(S32 type_counts[], S32 share_counts[]) const + { safe(impl).calcStats(type_counts, share_counts); } + +// static +std::string LLSD::typeString(Type type) +{ + static const char * sTypeNameArray[] = { + "Undefined", + "Boolean", + "Integer", + "Real", + "String", + "UUID", + "Date", + "URI", + "Binary", + "Map", + "Array" + }; + + if (0 <= type < (sizeof(sTypeNameArray)/sizeof(sTypeNameArray[0]))) + { + return sTypeNameArray[type]; + } + return STRINGIZE("** invalid type value " << type); +} -- cgit v1.2.3 From e62c691aab36b50d3eecb99310d5652d0b8e6f23 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 17 Nov 2011 10:02:05 -0500 Subject: LLSD-14: Fix silly syntax error in subscript bounds check. --- indra/llcommon/llsd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/llsd.cpp') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 862b6b5ebc..b0801745d7 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -964,7 +964,7 @@ std::string LLSD::typeString(Type type) "Array" }; - if (0 <= type < (sizeof(sTypeNameArray)/sizeof(sTypeNameArray[0]))) + if (0 <= type && type < (sizeof(sTypeNameArray)/sizeof(sTypeNameArray[0]))) { return sTypeNameArray[type]; } -- cgit v1.2.3 From bd5b1ed713506d365793c7f9cb49d506ce392e7a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 17 Nov 2011 13:55:11 -0500 Subject: LLSD-14: Make dumpStats()/calcStats() implementation more robust per Monty code review --- indra/llcommon/llsd.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'indra/llcommon/llsd.cpp') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index b0801745d7..39d1f3e35f 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -732,10 +732,10 @@ const LLSD& LLSD::Impl::undef() void LLSD::Impl::dumpStats() const { S32 type_counts[LLSD::TypeLLSDNumTypes + 1]; - memset(&type_counts, 0, LLSD::TypeLLSDNumTypes * sizeof(S32)); + memset(&type_counts, 0, sizeof(type_counts)); S32 share_counts[LLSD::TypeLLSDNumTypes + 1]; - memset(&share_counts, 0, LLSD::TypeLLSDNumTypes * sizeof(S32)); + memset(&share_counts, 0, sizeof(share_counts)); // Add info from all the values this object has calcStats(type_counts, share_counts); @@ -753,11 +753,15 @@ void LLSD::Impl::dumpStats() const void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const -{ - type_counts[(S32) type()]++; - if (shared()) +{ + S32 type = S32(type()); + if (0 <= type && type < LLSD::TypeLLSDNumTypes) { - share_counts[(S32) type()]++; + type_counts[type]++; + if (shared()) + { + share_counts[type]++; + } } } -- cgit v1.2.3 From b49c934bd913c0973630abf32ea566eefa1aa973 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 17 Nov 2011 15:03:25 -0500 Subject: LLSD-14: fixed way-too-overloaded local variable. --- indra/llcommon/llsd.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/llsd.cpp') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 39d1f3e35f..3fa08aee8d 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -754,13 +754,13 @@ void LLSD::Impl::dumpStats() const void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const { - S32 type = S32(type()); - if (0 <= type && type < LLSD::TypeLLSDNumTypes) + S32 tp = S32(type()); + if (0 <= tp && tp < LLSD::TypeLLSDNumTypes) { - type_counts[type]++; + type_counts[tp]++; if (shared()) { - share_counts[type]++; + share_counts[tp]++; } } } -- cgit v1.2.3 From e97fb23218734d1fbda87eedd7659235777a69ae Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 19 Nov 2011 10:02:20 -0500 Subject: Make LLSD diagnostic methods conditional on LLSD_DEBUG_INFO. This establishes that there are no viewer-side unit tests relying on these methods. The point is to try to clean up the LLSD public API. In the same vein, remove from LLSD public API a diagnostic method which is nothing more than an implementation detail for the corresponding LLSD::Impl method. The same effect can be achieved by making LLSD::Impl a friend of LLSD, moving the method with the messy signature (classic-C arrays!) into LLSD::Impl itself. --- indra/llcommon/llsd.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'indra/llcommon/llsd.cpp') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 3fa08aee8d..1bd5d06d29 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -148,6 +148,13 @@ public: 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) -- cgit v1.2.3 From 95fb0249e9f43d907608cc5840d1f8c0e49981d0 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 1 Dec 2011 16:50:27 -0500 Subject: LLSD-14: Move LLSD::(outstanding|allocation)Count() to free functions. Free functions can be unconditionally compiled into the .o file, but conditionally hidden in the header file. Static class methods don't have that flexibility: without a declaration in the header file, you can't compile a function definition in the .cpp file. That makes it awkward to use the same llcommon build for production and for unit tests. Why make the function declarations conditional at all? These are debugging functions. They break the abstraction, they peek under the covers. Production code should not use them. Making them conditional on an #ifdef symbol in the unit-test source file means the compiler would reject any use by production code. Put differently, it allows us to assert with confidence that only unit tests do use them. Put new free functions in (lowercase) llsd namespace so as not to clutter global namespace. Tweak the one known consumer (llsd_new_tut.cpp) accordingly. --- indra/llcommon/llsd.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'indra/llcommon/llsd.cpp') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 1bd5d06d29..08cb7bd2a8 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -91,7 +91,7 @@ protected: bool shared() const { return (mUseCount > 1) && (mUseCount != STATIC_USAGE_COUNT); } U32 mUseCount; - + public: static void reset(Impl*& var, Impl* impl); ///< safely set var to refer to the new impl (possibly shared) @@ -901,11 +901,6 @@ 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) { // sStorage is used to hold the string representation of the llsd last @@ -954,6 +949,13 @@ LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); } LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); } LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); } +namespace llsd +{ + +U32 allocationCount() { return LLSD::Impl::sAllocationCount; } +U32 outstandingCount() { return LLSD::Impl::sOutstandingCount; } + +} // namespace llsd // Diagnostic dump of contents in an LLSD object #ifdef LLSD_DEBUG_INFO -- cgit v1.2.3 From 1a6846444f35a89001dffa33d1f76067193165f7 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 5 Dec 2011 09:26:10 -0500 Subject: LLSD-14: Optional entry points need conditional decls turned on. Changeset 07cd70e75473 moved LLSD::outstandingCount() and allocationCount() to free functions so we could turn their visibility on/off via LLSD_DEBUG_INFO. But on some platforms, without proper LL_COMMON_API declarations visible when we compile llsd.cpp, those free functions lack proper linkage directives. Declare LLSD_DEBUG_INFO in llsd.cpp so that when the llcommon library is built, the free functions get proper linkage -- independent of compilations of LLSD consumers. --- indra/llcommon/llsd.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indra/llcommon/llsd.cpp') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 08cb7bd2a8..151eb4084a 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -24,6 +24,9 @@ * $/LicenseInfo$ */ +// Must turn on conditional declarations in header file so definitions end up +// with proper linkage. +#define LLSD_DEBUG_INFO #include "linden_common.h" #include "llsd.h" -- cgit v1.2.3 From 3e6c522084385e5c40796849b9cefa69e95c981f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 6 Dec 2011 09:54:59 -0500 Subject: LLSD-14: Extract remaining conditional LLSD mbrs to namespace llsd. Per Monty's code review, it's dubious practice to have a class in which certain members are sometimes visible, other times not. If these were virtual methods, or non-static data members, the error would be obvious -- but even with static data members and non-virtual methods, it looks like an ODR violation. Extract conditional methods as free functions, as in changeset 07cd70e75473. --- indra/llcommon/llsd.cpp | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) (limited to 'indra/llcommon/llsd.cpp') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 151eb4084a..e295e3c621 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -54,23 +54,17 @@ namespace using namespace LLSDUnnamedNamespace; #endif - -// Normally undefined -#ifdef LLSD_DEBUG_INFO +namespace llsd +{ // statics -S32 LLSD::sLLSDAllocationCount = 0; -S32 LLSD::sLLSDNetObjects = 0; - -#define ALLOC_LLSD_OBJECT { sLLSDNetObjects++; sLLSDAllocationCount++; } -#define FREE_LLSD_OBJECT { sLLSDNetObjects--; } +S32 sLLSDAllocationCount = 0; +S32 sLLSDNetObjects = 0; -#else +} // namespace llsd -#define ALLOC_LLSD_OBJECT -#define FREE_LLSD_OBJECT - -#endif +#define ALLOC_LLSD_OBJECT { llsd::sLLSDNetObjects++; llsd::sLLSDAllocationCount++; } +#define FREE_LLSD_OBJECT { llsd::sLLSDNetObjects--; } class LLSD::Impl /**< This class is the abstract base class of the implementation of LLSD @@ -158,6 +152,8 @@ public: safe(llsd.impl).calcStats(type_counts, share_counts); } + static const Impl& getImpl(const LLSD& llsd) { return safe(llsd.impl); } + static Impl& getImpl(LLSD& llsd) { return safe(llsd.impl); } static const LLSD& undef(); @@ -452,10 +448,8 @@ namespace { std::cout << "Map size: " << mData.size() << std::endl; - #ifdef LLSD_DEBUG_INFO - std::cout << "LLSD Net Objects: " << LLSD::sLLSDNetObjects << std::endl; - std::cout << "LLSD allocations: " << LLSD::sLLSDAllocationCount << std::endl; - #endif + std::cout << "LLSD Net Objects: " << llsd::sLLSDNetObjects << std::endl; + std::cout << "LLSD allocations: " << llsd::sLLSDAllocationCount << std::endl; std::cout << "LLSD::Impl Net Objects: " << sOutstandingCount << std::endl; std::cout << "LLSD::Impl allocations: " << sAllocationCount << std::endl; @@ -958,12 +952,10 @@ namespace llsd U32 allocationCount() { return LLSD::Impl::sAllocationCount; } U32 outstandingCount() { return LLSD::Impl::sOutstandingCount; } -} // namespace llsd - // Diagnostic dump of contents in an LLSD object -#ifdef LLSD_DEBUG_INFO -void LLSD::dumpStats() const { safe(impl).dumpStats(); } -#endif +void dumpStats(const LLSD& llsd) { LLSD::Impl::getImpl(llsd).dumpStats(); } + +} // namespace llsd // static std::string LLSD::typeString(Type type) @@ -982,7 +974,7 @@ std::string LLSD::typeString(Type type) "Array" }; - if (0 <= type && type < (sizeof(sTypeNameArray)/sizeof(sTypeNameArray[0]))) + if (0 <= type && type < LL_ARRAY_SIZE(sTypeNameArray)) { return sTypeNameArray[type]; } -- cgit v1.2.3