summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Linden <none@none>2012-12-18 00:58:26 -0800
committerRichard Linden <none@none>2012-12-18 00:58:26 -0800
commit1f56e57008f5a50c9e75fc0b4512c483ac359a52 (patch)
tree6631b12beaf3cf64e093730e9c93df34b883472c
parent8c2e3bea71ea15b805a9e2a288744f10d195d803 (diff)
SH-3468 WIP add memory tracking base class
created memory tracking trace type instrumented a few classes with memory tracking
-rw-r--r--indra/llcommon/lltrace.h270
-rw-r--r--indra/llimage/llimage.cpp8
-rw-r--r--indra/llimage/llimage.h5
-rw-r--r--indra/llui/lltextbase.cpp17
-rw-r--r--indra/llui/lltextbase.h5
-rw-r--r--indra/llui/lluictrl.cpp21
-rw-r--r--indra/llui/llview.h3
-rw-r--r--indra/llui/llviewmodel.cpp5
-rw-r--r--indra/llui/llviewmodel.h4
-rw-r--r--indra/newview/lldrawable.h35
-rw-r--r--indra/newview/llface.h10
-rw-r--r--indra/newview/llviewerobject.h6
12 files changed, 344 insertions, 45 deletions
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index d29d43a92c..d4fc93342d 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -424,9 +424,9 @@ namespace LLTrace
//
// members
//
- U64 mSelfTimeCounter,
- mTotalTimeCounter;
- U32 mCalls;
+ U64 mSelfTimeCounter,
+ mTotalTimeCounter;
+ U32 mCalls;
};
@@ -509,6 +509,268 @@ namespace LLTrace
trace_t::getPrimaryAccumulator().add(LLUnits::rawValue(converted_value));
}
};
-}
+struct MemStatAccumulator
+{
+ MemStatAccumulator()
+ : mSize(0),
+ mChildSize(0),
+ mAllocatedCount(0),
+ mDeallocatedCount(0)
+ {}
+
+ void addSamples(const MemStatAccumulator& other)
+ {
+ mSize += other.mSize;
+ mChildSize += other.mChildSize;
+ mAllocatedCount += other.mAllocatedCount;
+ mDeallocatedCount += other.mDeallocatedCount;
+ }
+
+ void reset(const MemStatAccumulator* other)
+ {
+ mSize = 0;
+ mChildSize = 0;
+ mAllocatedCount = 0;
+ mDeallocatedCount = 0;
+ }
+
+ size_t mSize,
+ mChildSize;
+ int mAllocatedCount,
+ mDeallocatedCount;
+};
+
+class MemStat : public TraceType<MemStatAccumulator>
+{
+public:
+ typedef TraceType<MemStatAccumulator> trace_t;
+ MemStat(const char* name)
+ : trace_t(name)
+ {}
+};
+
+// measures effective memory footprint of specified type
+// specialize to cover different types
+
+template<typename T>
+struct MemFootprint
+{
+ static size_t measure(const T& value)
+ {
+ return sizeof(T);
+ }
+
+ static size_t measure()
+ {
+ return sizeof(T);
+ }
+};
+
+template<typename T>
+struct MemFootprint<T*>
+{
+ static size_t measure(const T* value)
+ {
+ if (!value)
+ {
+ return 0;
+ }
+ return MemFootprint<T>::measure(*value);
+ }
+
+ static size_t measure()
+ {
+ return MemFootPrint<T>::measure();
+ }
+};
+
+template<typename T>
+struct MemFootprint<std::basic_string<T> >
+{
+ static size_t measure(const std::basic_string<T>& value)
+ {
+ return value.capacity() * sizeof(T);
+ }
+
+ static size_t measure()
+ {
+ return sizeof(std::basic_string<T>);
+ }
+};
+
+template<typename T>
+struct MemFootprint<std::vector<T> >
+{
+ static size_t measure(const std::vector<T>& value)
+ {
+ return value.capacity() * MemFootPrint<T>::measure();
+ }
+
+ static size_t measure()
+ {
+ return sizeof(std::vector<T>);
+ }
+};
+
+template<typename T>
+struct MemFootprint<std::list<T> >
+{
+ static size_t measure(const std::list<T>& value)
+ {
+ return value.size() * (MemFootPrint<T>::measure() + sizeof(void*) * 2);
+ }
+
+ static size_t measure()
+ {
+ return sizeof(std::list<T>);
+ }
+};
+
+template<typename T>
+class MemTrackable
+{
+ template<typename TRACKED, typename TRACKED_IS_TRACKER>
+ struct TrackMemImpl;
+
+ typedef MemTrackable<T> mem_trackable_t;
+
+public:
+ typedef void mem_trackable_tag_t;
+
+ ~MemTrackable()
+ {
+ memDisclaim(mMemFootprint);
+ }
+
+ void* operator new(size_t allocation_size)
+ {
+ // reserve 8 bytes for allocation size (and preserving 8 byte alignment of structs)
+ void* allocation = ::operator new(allocation_size + 8);
+ *(size_t*)allocation = allocation_size;
+ MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator();
+ accumulator.mSize += allocation_size;
+ accumulator.mAllocatedCount++;
+ return (void*)((char*)allocation + 8);
+ }
+
+ void operator delete(void* ptr)
+ {
+ size_t* allocation_size = (size_t*)((char*)ptr - 8);
+ MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator();
+ accumulator.mSize -= *allocation_size;
+ accumulator.mAllocatedCount--;
+ accumulator.mDeallocatedCount++;
+ ::delete((char*)ptr - 8);
+ }
+
+ void *operator new [](size_t size)
+ {
+ size_t* result = (size_t*)malloc(size + 8);
+ *result = size;
+ MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator();
+ accumulator.mSize += size;
+ accumulator.mAllocatedCount++;
+ return (void*)((char*)result + 8);
+ }
+
+ void operator delete[](void* ptr)
+ {
+ size_t* allocation_size = (size_t*)((char*)ptr - 8);
+ MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator();
+ accumulator.mSize -= *allocation_size;
+ accumulator.mAllocatedCount--;
+ accumulator.mDeallocatedCount++;
+ ::delete[]((char*)ptr - 8);
+ }
+
+ // claim memory associated with other objects/data as our own, adding to our calculated footprint
+ template<typename T>
+ T& memClaim(T& value)
+ {
+ TrackMemImpl<T>::claim(*this, value);
+ return value;
+ }
+
+ template<typename T>
+ const T& memClaim(const T& value)
+ {
+ TrackMemImpl<T>::claim(*this, value);
+ return value;
+ }
+
+
+ void memClaim(size_t size)
+ {
+ MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator();
+ mMemFootprint += size;
+ accumulator.mSize += size;
+ }
+
+ // remove memory we had claimed from our calculated footprint
+ template<typename T>
+ T& memDisclaim(T& value)
+ {
+ TrackMemImpl<T>::disclaim(*this, value);
+ return value;
+ }
+
+ template<typename T>
+ const T& memDisclaim(const T& value)
+ {
+ TrackMemImpl<T>::disclaim(*this, value);
+ return value;
+ }
+
+ void memDisclaim(size_t size)
+ {
+ MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator();
+ accumulator.mSize -= size;
+ mMemFootprint -= size;
+ }
+
+private:
+ size_t mMemFootprint;
+
+ template<typename TRACKED, typename TRACKED_IS_TRACKER = void>
+ struct TrackMemImpl
+ {
+ static void claim(mem_trackable_t& tracker, const TRACKED& tracked)
+ {
+ MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator();
+ size_t footprint = MemFootprint<TRACKED>::measure(tracked);
+ accumulator.mSize += footprint;
+ tracker.mMemFootprint += footprint;
+ }
+
+ static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked)
+ {
+ MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator();
+ size_t footprint = MemFootprint<TRACKED>::measure(tracked);
+ accumulator.mSize -= footprint;
+ tracker.mMemFootprint -= footprint;
+ }
+ };
+
+ template<typename TRACKED>
+ struct TrackMemImpl<TRACKED, typename TRACKED::mem_trackable_tag_t>
+ {
+ static void claim(mem_trackable_t& tracker, TRACKED& tracked)
+ {
+ MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator();
+ accumulator.mChildSize += MemFootprint<TRACKED>::measure(tracked);
+ }
+
+ static void disclaim(mem_trackable_t& tracker, TRACKED& tracked)
+ {
+ MemStatAccumulator& accumulator = sStat.getPrimaryAccumulator();
+ accumulator.mChildSize -= MemFootprint<TRACKED>::measure(tracked);
+ }
+ };
+ static MemStat sStat;
+};
+
+template<typename T> MemStat MemTrackable<T>::sStat(typeid(T).name());
+
+}
#endif // LL_LLTRACE_H
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 914bf836c1..22dd809ef3 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -157,7 +157,8 @@ void LLImageBase::sanityCheck()
// virtual
void LLImageBase::deleteData()
{
- FREE_MEM(sPrivatePoolp, mData) ;
+ FREE_MEM(sPrivatePoolp, mData);
+ memDisclaim(mDataSize);
mData = NULL;
mDataSize = 0;
}
@@ -201,6 +202,7 @@ U8* LLImageBase::allocateData(S32 size)
mBadBufferAllocation = true ;
}
mDataSize = size;
+ memClaim(mDataSize);
}
return mData;
@@ -222,7 +224,9 @@ U8* LLImageBase::reallocateData(S32 size)
FREE_MEM(sPrivatePoolp, mData) ;
}
mData = new_datap;
+ memDisclaim(mDataSize);
mDataSize = size;
+ memClaim(mDataSize);
return mData;
}
@@ -1584,7 +1588,9 @@ 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);
+ memDisclaim(mDataSize);
mData = data; mDataSize = size;
+ memClaim(mDataSize);
}
//static
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index b87ce6f060..d945d54404 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -30,6 +30,7 @@
#include "lluuid.h"
#include "llstring.h"
#include "llthread.h"
+#include "lltrace.h"
const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
const S32 MAX_IMAGE_MIP = 11; // 2048x2048
@@ -110,7 +111,9 @@ protected:
//============================================================================
// Image base class
-class LLImageBase : public LLThreadSafeRefCount
+class LLImageBase
+: public LLThreadSafeRefCount,
+ public LLTrace::MemTrackable<LLImageBase>
{
protected:
virtual ~LLImageBase();
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 3815eec447..31d67a9e08 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -561,7 +561,7 @@ void LLTextBase::drawText()
if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) )
{
const LLWString& wstrText = getWText();
- mMisspellRanges.clear();
+ memDisclaim(mMisspellRanges).clear();
segment_set_t::const_iterator seg_it = getSegIterContaining(start);
while (mSegments.end() != seg_it)
@@ -632,6 +632,7 @@ void LLTextBase::drawText()
mSpellCheckStart = start;
mSpellCheckEnd = end;
+ memClaim(mMisspellRanges);
}
}
@@ -890,10 +891,12 @@ void LLTextBase::createDefaultSegment()
// ensures that there is always at least one segment
if (mSegments.empty())
{
+ memDisclaim(mSegments);
LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this);
mSegments.insert(default_segment);
default_segment->linkToDocument(this);
+ memClaim(mSegments);
}
}
@@ -904,6 +907,8 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
return;
}
+ memDisclaim(mSegments);
+
segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart());
S32 reflow_start_index = 0;
@@ -976,6 +981,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
// layout potentially changed
needsReflow(reflow_start_index);
+ memClaim(mSegments);
}
BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -1271,8 +1277,11 @@ void LLTextBase::replaceWithSuggestion(U32 index)
removeStringNoUndo(it->first, it->second - it->first);
// Insert the suggestion in its place
+ memDisclaim(mSuggestionList);
LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
insertStringNoUndo(it->first, utf8str_to_wstring(mSuggestionList[index]));
+ memClaim(mSuggestionList);
+
setCursorPos(it->first + (S32)suggestion.length());
break;
@@ -1334,7 +1343,7 @@ bool LLTextBase::isMisspelledWord(U32 pos) const
void LLTextBase::onSpellCheckSettingsChange()
{
// Recheck the spelling on every change
- mMisspellRanges.clear();
+ memDisclaim(mMisspellRanges).clear();
mSpellCheckStart = mSpellCheckEnd = -1;
}
@@ -1593,7 +1602,7 @@ LLRect LLTextBase::getTextBoundingRect()
void LLTextBase::clearSegments()
{
- mSegments.clear();
+ memDisclaim(mSegments).clear();
createDefaultSegment();
}
@@ -3057,7 +3066,9 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)
llwarns << "LLTextSegment::setToolTip: cannot replace keyword tooltip." << llendl;
return;
}
+ memDisclaim(mTooltip);
mTooltip = tooltip;
+ memClaim(mTooltip);
}
bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 90b147cee1..966dd93888 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -50,7 +50,10 @@ class LLUrlMatch;
/// includes a start/end offset from the start of the string, a
/// style to render with, an optional tooltip, etc.
///
-class LLTextSegment : public LLRefCount, public LLMouseHandler
+class LLTextSegment
+: public LLRefCount,
+ public LLMouseHandler,
+ public LLTrace::MemTrackable<LLTextSegment>
{
public:
LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){};
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index b9c843e931..08358484ef 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -118,6 +118,7 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
mDoubleClickSignal(NULL),
mTransparencyType(TT_DEFAULT)
{
+ memClaim(viewmodel.get());
}
void LLUICtrl::initFromParams(const Params& p)
@@ -940,7 +941,7 @@ boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (L
}
boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb )
{
- if (!mValidateSignal) mValidateSignal = new enable_signal_t();
+ if (!mValidateSignal) mValidateSignal = memClaim(new enable_signal_t());
return mValidateSignal->connect(boost::bind(cb, _2));
}
@@ -1003,55 +1004,55 @@ boost::signals2::connection LLUICtrl::setValidateCallback(const EnableCallbackPa
boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb )
{
- if (!mCommitSignal) mCommitSignal = new commit_signal_t();
+ if (!mCommitSignal) mCommitSignal = memClaim(new commit_signal_t());
return mCommitSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t::slot_type& cb )
{
- if (!mValidateSignal) mValidateSignal = new enable_signal_t();
+ if (!mValidateSignal) mValidateSignal = memClaim(new enable_signal_t());
return mValidateSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal_t::slot_type& cb )
{
- if (!mMouseEnterSignal) mMouseEnterSignal = new commit_signal_t();
+ if (!mMouseEnterSignal) mMouseEnterSignal = memClaim(new commit_signal_t());
return mMouseEnterSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal_t::slot_type& cb )
{
- if (!mMouseLeaveSignal) mMouseLeaveSignal = new commit_signal_t();
+ if (!mMouseLeaveSignal) mMouseLeaveSignal = memClaim(new commit_signal_t());
return mMouseLeaveSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t::slot_type& cb )
{
- if (!mMouseDownSignal) mMouseDownSignal = new mouse_signal_t();
+ if (!mMouseDownSignal) mMouseDownSignal = memClaim(new mouse_signal_t());
return mMouseDownSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t::slot_type& cb )
{
- if (!mMouseUpSignal) mMouseUpSignal = new mouse_signal_t();
+ if (!mMouseUpSignal) mMouseUpSignal = memClaim(new mouse_signal_t());
return mMouseUpSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_signal_t::slot_type& cb )
{
- if (!mRightMouseDownSignal) mRightMouseDownSignal = new mouse_signal_t();
+ if (!mRightMouseDownSignal) mRightMouseDownSignal = memClaim(new mouse_signal_t());
return mRightMouseDownSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signal_t::slot_type& cb )
{
- if (!mRightMouseUpSignal) mRightMouseUpSignal = new mouse_signal_t();
+ if (!mRightMouseUpSignal) mRightMouseUpSignal = memClaim(new mouse_signal_t());
return mRightMouseUpSignal->connect(cb);
}
boost::signals2::connection LLUICtrl::setDoubleClickCallback( const mouse_signal_t::slot_type& cb )
{
- if (!mDoubleClickSignal) mDoubleClickSignal = new mouse_signal_t();
+ if (!mDoubleClickSignal) mDoubleClickSignal = memClaim(new mouse_signal_t());
return mDoubleClickSignal->connect(cb);
}
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 1c35349510..29ee2125f9 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -101,7 +101,8 @@ class LLView
: public LLMouseHandler, // handles mouse events
public LLFocusableElement, // handles keyboard events
public LLMortician, // lazy deletion
- public LLHandleProvider<LLView> // passes out weak references to self
+ public LLHandleProvider<LLView>, // passes out weak references to self
+ public LLTrace::MemTrackable<LLView> // track memory usage
{
public:
struct Follows : public LLInitParam::ChoiceBlock<Follows>
diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp
index a9f8acc440..dff0dcb2fd 100644
--- a/indra/llui/llviewmodel.cpp
+++ b/indra/llui/llviewmodel.cpp
@@ -80,7 +80,10 @@ LLTextViewModel::LLTextViewModel(const LLSD& value)
void LLTextViewModel::setValue(const LLSD& value)
{
LLViewModel::setValue(value);
+ memDisclaim(mDisplay);
mDisplay = utf8str_to_wstring(value.asString());
+ memClaim(mDisplay);
+
// mDisplay and mValue agree
mUpdateFromDisplay = false;
}
@@ -91,7 +94,9 @@ void LLTextViewModel::setDisplay(const LLWString& value)
// and do the utf8str_to_wstring() to get the corresponding mDisplay
// value. But a text editor might want to edit the display string
// directly, then convert back to UTF8 on commit.
+ memDisclaim(mDisplay);
mDisplay = value;
+ memClaim(mDisplay);
mDirty = true;
// Don't immediately convert to UTF8 -- do it lazily -- we expect many
// more setDisplay() calls than getValue() calls. Just flag that it needs
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
index ef2e314799..cec0368460 100644
--- a/indra/llui/llviewmodel.h
+++ b/indra/llui/llviewmodel.h
@@ -60,7 +60,9 @@ typedef LLPointer<LLListViewModel> LLListViewModelPtr;
* LLViewModel data. This way, the LLViewModel is quietly deleted when the
* last referencing widget is destroyed.
*/
-class LLViewModel: public LLRefCount
+class LLViewModel
+: public LLRefCount,
+ public LLTrace::MemTrackable<LLViewModel>
{
public:
LLViewModel();
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 4608d16fec..f15090fb87 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -59,7 +59,9 @@ const U32 SILHOUETTE_HIGHLIGHT = 0;
// All data for new renderer goes into this class.
LL_ALIGN_PREFIX(16)
-class LLDrawable : public LLRefCount
+class LLDrawable
+: public LLRefCount,
+ public LLTrace::MemTrackable<LLDrawable>
{
public:
LLDrawable(const LLDrawable& rhs)
@@ -316,24 +318,23 @@ public:
private:
typedef std::vector<LLFace*> face_list_t;
- U32 mState;
- S32 mRenderType;
- LLPointer<LLViewerObject> mVObjp;
- face_list_t mFaces;
- LLSpatialGroup* mSpatialGroupp;
- LLPointer<LLDrawable> mSpatialBridge;
+ U32 mState;
+ S32 mRenderType;
+ LLPointer<LLViewerObject> mVObjp;
+ face_list_t mFaces;
+ LLSpatialGroup* mSpatialGroupp;
+ LLPointer<LLDrawable> mSpatialBridge;
- mutable U32 mVisible;
- F32 mRadius;
- F32 mBinRadius;
- mutable S32 mBinIndex;
- S32 mGeneration;
-
- LLVector3 mCurrentScale;
-
- static U32 sCurVisible; // Counter for what value of mVisible means currently visible
+ mutable U32 mVisible;
+ F32 mRadius;
+ F32 mBinRadius;
+ mutable S32 mBinIndex;
+ S32 mGeneration;
- static U32 sNumZombieDrawables;
+ LLVector3 mCurrentScale;
+
+ static U32 sCurVisible; // Counter for what value of mVisible means currently visible
+ static U32 sNumZombieDrawables;
static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList;
} LL_ALIGN_POSTFIX(16);
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index de4d03351c..15c9e7856f 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -262,11 +262,11 @@ public:
LLVector2 mTexExtents[2];
F32 mDistance;
- F32 mLastUpdateTime;
- F32 mLastSkinTime;
- F32 mLastMoveTime;
- LLMatrix4* mTextureMatrix;
- LLDrawInfo* mDrawInfo;
+ F32 mLastUpdateTime;
+ F32 mLastSkinTime;
+ F32 mLastMoveTime;
+ LLMatrix4* mTextureMatrix;
+ LLDrawInfo* mDrawInfo;
private:
LLPointer<LLVertexBuffer> mVertexBuffer;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 97cf0a4850..14ea8ded38 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -107,7 +107,11 @@ struct PotentialReturnableObject
//============================================================================
-class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
+class LLViewerObject
+: public LLPrimitive,
+ public LLRefCount,
+ public LLGLUpdate,
+ public LLTrace::MemTrackable<LLViewerObject>
{
protected:
~LLViewerObject(); // use unref()