diff options
-rw-r--r-- | indra/llcommon/llmemory.cpp | 170 | ||||
-rw-r--r-- | indra/llcommon/llmemory.h | 46 | ||||
-rw-r--r-- | indra/llcommon/llmemtype.cpp | 1 | ||||
-rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 15 | ||||
-rw-r--r-- | indra/newview/llmemoryview.cpp | 51 | ||||
-rw-r--r-- | indra/newview/llviewerwindow.cpp | 8 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_viewer.xml | 10 |
8 files changed, 304 insertions, 8 deletions
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index a502d1a7eb..e4ece78d53 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -26,6 +26,12 @@ #include "linden_common.h" +#include "llmemory.h" + +#if MEM_TRACK_MEM +#include "llthread.h" +#endif + #if defined(LL_WINDOWS) # include <windows.h> # include <psapi.h> @@ -37,8 +43,6 @@ # include <unistd.h> #endif -#include "llmemory.h" - //---------------------------------------------------------------------------- //static @@ -105,6 +109,20 @@ U64 LLMemory::getCurrentRSS() return counters.WorkingSetSize; } +//static +U32 LLMemory::getWorkingSetSize() +{ + PROCESS_MEMORY_COUNTERS pmc ; + U32 ret = 0 ; +
+ if (GetProcessMemoryInfo( GetCurrentProcess(), &pmc, sizeof(pmc)) ) + { + ret = pmc.WorkingSetSize ; + } + + return ret ; +} + #elif defined(LL_DARWIN) /* @@ -151,6 +169,11 @@ U64 LLMemory::getCurrentRSS() return residentSize; } +U32 LLMemory::getWorkingSetSize() +{ + return 0 ; +} + #elif defined(LL_LINUX) U64 LLMemory::getCurrentRSS() @@ -185,6 +208,11 @@ bail: return rss; } +U32 LLMemory::getWorkingSetSize() +{ + return 0 ; +} + #elif LL_SOLARIS #include <sys/types.h> #include <sys/stat.h> @@ -213,6 +241,12 @@ U64 LLMemory::getCurrentRSS() return((U64)proc_psinfo.pr_rssize * 1024); } + +U32 LLMemory::getWorkingSetSize() +{ + return 0 ; +} + #else U64 LLMemory::getCurrentRSS() @@ -220,4 +254,136 @@ U64 LLMemory::getCurrentRSS() return 0; } +U32 LLMemory::getWorkingSetSize() +{ + return 0 ; +} + #endif + +//-------------------------------------------------------------------------------------------------- +#if MEM_TRACK_MEM +#include "llframetimer.h" + +//static +LLMemTracker* LLMemTracker::sInstance = NULL ; + +LLMemTracker::LLMemTracker() +{ + mLastAllocatedMem = LLMemory::getWorkingSetSize() ; + mCapacity = 128 ; + mCurIndex = 0 ; + mCounter = 0 ; + mDrawnIndex = 0 ; + + mMutexp = new LLMutex(NULL) ; + mStringBuffer = new char*[128] ; + mStringBuffer[0] = new char[mCapacity * 128] ; + for(S32 i = 1 ; i < mCapacity ; i++) + { + mStringBuffer[i] = mStringBuffer[i-1] + 128 ; + } +} + +LLMemTracker::~LLMemTracker() +{ + delete[] mStringBuffer[0] ; + delete[] mStringBuffer; + delete mMutexp ; +} + +//static +LLMemTracker* LLMemTracker::getInstance() +{ + if(!sInstance) + { + sInstance = new LLMemTracker() ; + } + return sInstance ; +} + +//static +void LLMemTracker::release() +{ + if(sInstance) + { + delete sInstance ; + sInstance = NULL ; + } +} + +//static +void LLMemTracker::track(const char* function, const int line) +{ + static const S32 MIN_ALLOCATION = 1024 ; //1KB + + U32 allocated_mem = LLMemory::getWorkingSetSize() ; + + LLMutexLock lock(mMutexp) ; + + if(allocated_mem <= mLastAllocatedMem) + { + return ; //occupied memory does not grow + } + + S32 delta_mem = allocated_mem - mLastAllocatedMem ; + mLastAllocatedMem = allocated_mem ; + if(delta_mem < MIN_ALLOCATION) + { + return ; + } + + char* buffer = mStringBuffer[mCurIndex++] ; + F32 time = (F32)LLFrameTimer::getElapsedSeconds() ; + S32 hours = (S32)(time / (60*60)); + S32 mins = (S32)((time - hours*(60*60)) / 60); + S32 secs = (S32)((time - hours*(60*60) - mins*60)); + strcpy(buffer, function) ; + sprintf(buffer + strlen(function), " line: %d DeltaMem: %d (bytes) Time: %d:%02d:%02d", line, delta_mem, hours,mins,secs) ; + + if(mCounter < mCapacity) + { + mCounter++ ; + } + if(mCurIndex >= mCapacity) + { + mCurIndex = 0 ; + } +} + + +//static +void LLMemTracker::preDraw() +{ + mMutexp->lock() ; + + mDrawnIndex = mCurIndex - 1; + mNumOfDrawn = 0 ; +} + +//static +void LLMemTracker::postDraw() +{ + mMutexp->unlock() ; +} + +//static +const char* LLMemTracker::getNextLine() +{ + if(mNumOfDrawn >= mCounter) + { + return NULL ; + } + mNumOfDrawn++; + + if(mDrawnIndex < 0) + { + mDrawnIndex = mCapacity - 1 ; + } + + return mStringBuffer[mDrawnIndex--] ; +} + +#endif //MEM_TRACK_MEM +//-------------------------------------------------------------------------------------------------- + diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 9bf4248bb7..e6a6a8c3da 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -26,7 +26,7 @@ #ifndef LLMEMORY_H #define LLMEMORY_H - +#include "llmemtype.h" extern S32 gTotalDAlloc; extern S32 gTotalDAUse; @@ -44,10 +44,54 @@ public: // Return the resident set size of the current process, in bytes. // Return value is zero if not known. static U64 getCurrentRSS(); + static U32 getWorkingSetSize(); private: static char* reserveMem; }; +//---------------------------------------------------------------------------- +#if MEM_TRACK_MEM +class LLMutex ; +class LL_COMMON_API LLMemTracker +{ +private: + LLMemTracker() ; + ~LLMemTracker() ; + +public: + static void release() ; + static LLMemTracker* getInstance() ; + + void track(const char* function, const int line) ; + void preDraw() ; + void postDraw() ; + const char* getNextLine() ; + +private: + static LLMemTracker* sInstance ; + + char** mStringBuffer ; + S32 mCapacity ; + U32 mLastAllocatedMem ; + S32 mCurIndex ; + S32 mCounter; + S32 mDrawnIndex; + S32 mNumOfDrawn; + LLMutex* mMutexp ; +}; + +#define MEM_TRACK_RELEASE LLMemTracker::release() ; +#define MEM_TRACK LLMemTracker::getInstance()->track(__FUNCTION__, __LINE__) ; + +#else // MEM_TRACK_MEM + +#define MEM_TRACK_RELEASE +#define MEM_TRACK + +#endif // MEM_TRACK_MEM + +//---------------------------------------------------------------------------- + // LLRefCount moved to llrefcount.h // LLPointer moved to llpointer.h diff --git a/indra/llcommon/llmemtype.cpp b/indra/llcommon/llmemtype.cpp index fe83f87d4b..6290a7158f 100644 --- a/indra/llcommon/llmemtype.cpp +++ b/indra/llcommon/llmemtype.cpp @@ -229,3 +229,4 @@ char const * LLMemType::getNameFromID(S32 id) return DeclareMemType::mNameList[id]; } +//-------------------------------------------------------------------------------------------------- diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ced46c7294..72d83ad024 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1852,6 +1852,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DebugShowMemory</key> + <map> + <key>Comment</key> + <string>Show Total Allocated Memory</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DebugShowRenderInfo</key> <map> <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6a9dfaf21b..87c0085226 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1057,6 +1057,8 @@ bool LLAppViewer::mainLoop() //clear call stack records llclearcallstacks; + MEM_TRACK + //check memory availability information { if(memory_check_interval < memCheckTimer.getElapsedTimeF32()) @@ -1101,6 +1103,8 @@ bool LLAppViewer::mainLoop() } #endif + MEM_TRACK + //memory leaking simulation LLFloaterMemLeak* mem_leak_instance = LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); @@ -1162,6 +1166,8 @@ bool LLAppViewer::mainLoop() resumeMainloopTimeout(); } + MEM_TRACK + if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) { pauseMainloopTimeout(); @@ -1183,6 +1189,8 @@ bool LLAppViewer::mainLoop() } + MEM_TRACK + pingMainloopTimeout("Main:Sleep"); pauseMainloopTimeout(); @@ -1296,7 +1304,10 @@ bool LLAppViewer::mainLoop() resumeMainloopTimeout(); pingMainloopTimeout("Main:End"); - } + } + + MEM_TRACK + } catch(std::bad_alloc) { @@ -1779,6 +1790,8 @@ bool LLAppViewer::cleanup() ll_close_fail_log(); + MEM_TRACK_RELEASE + llinfos << "Goodbye!" << llendflush; // return 0; diff --git a/indra/newview/llmemoryview.cpp b/indra/newview/llmemoryview.cpp index 9a244e2562..397a77c4e3 100644 --- a/indra/newview/llmemoryview.cpp +++ b/indra/newview/llmemoryview.cpp @@ -37,6 +37,7 @@ #include <sstream> #include <boost/algorithm/string/split.hpp> +#include "llmemory.h" LLMemoryView::LLMemoryView(const LLMemoryView::Params& p) : LLView(p), @@ -148,13 +149,14 @@ void LLMemoryView::draw() // cut off lines on bottom U32 max_lines = U32((height - 2 * line_height) / line_height); - std::vector<LLWString>::const_iterator end = mLines.end(); + y_pos = height - MARGIN_AMT - line_height; + y_off = 0.f; + +#if !MEM_TRACK_MEM + std::vector<LLWString>::const_iterator end = mLines.end(); if(mLines.size() > max_lines) { end = mLines.begin() + max_lines; } - - y_pos = height - MARGIN_AMT - line_height; - y_off = 0.f; for (std::vector<LLWString>::const_iterator i = mLines.begin(); i != end; ++i) { font->render(*i, 0, MARGIN_AMT, y_pos - y_off, @@ -169,6 +171,47 @@ void LLMemoryView::draw() y_off += line_height; } +#else + LLMemTracker::getInstance()->preDraw() ; + + { + F32 x_pos = MARGIN_AMT ; + U32 lines = 0 ; + const char* str = LLMemTracker::getInstance()->getNextLine() ; + while(str != NULL) + { + lines++ ; + font->renderUTF8(str, 0, x_pos, y_pos - y_off, + LLColor4::white, + LLFontGL::LEFT, + LLFontGL::BASELINE, + LLFontGL::NORMAL, + LLFontGL::DROP_SHADOW, + S32_MAX, + target_width, + NULL, FALSE); + + str = LLMemTracker::getInstance()->getNextLine() ; + y_off += line_height; + + if(lines >= max_lines) + { + lines = 0 ; + x_pos += 512.f ; + if(x_pos + 512.f > target_width) + { + break ; + } + + y_pos = height - MARGIN_AMT - line_height; + y_off = 0.f; + } + } + } + + LLMemTracker::getInstance()->postDraw() ; +#endif + #if MEM_TRACK_TYPE S32 left, top, right, bottom; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 166b110412..ca0478ee0c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -351,6 +351,14 @@ public: addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc; } +#if LL_WINDOWS + if (gSavedSettings.getBOOL("DebugShowMemory")) + { + addText(xpos, ypos, llformat("Memory: %d (KB)", LLMemory::getWorkingSetSize() / 1024)); + ypos += y_inc; + } +#endif + if (gDisplayCameraPos) { std::string camera_view_text; diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index c2735c85e4..08ae0c233e 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1990,6 +1990,16 @@ function="ToggleControl" parameter="DebugShowColor" /> </menu_item_check> + <menu_item_check + label="Show Memory" + name="Show Memory"> + <menu_item_check.on_check + function="CheckControl" + parameter="DebugShowMemory" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="DebugShowMemory" /> + </menu_item_check> <menu_item_separator/> |