From a91565e4f58492b583e65acd705db902f3c16e67 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Tue, 30 Jan 2018 16:00:29 -0500 Subject: [PATCH] Bug 1433583 - Discard information about old dead threads that no longer have any samples in the buffer. r=mystor MozReview-Commit-ID: 5ThtN1H1ieA --HG-- extra : rebase_source : f853ff92147a4d57fd778723eda32c78847e8ca5 extra : source : 61ede7cb13a5de066601492ca34eb97e17e3e6fe --- tools/profiler/core/ThreadInfo.h | 8 +++++++- tools/profiler/core/platform.cpp | 21 ++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/tools/profiler/core/ThreadInfo.h b/tools/profiler/core/ThreadInfo.h index d225cd8d8065..59cbe4682992 100644 --- a/tools/profiler/core/ThreadInfo.h +++ b/tools/profiler/core/ThreadInfo.h @@ -193,7 +193,12 @@ public: void StopProfiling(); bool IsBeingProfiled() { return mIsBeingProfiled; } - void NotifyUnregistered() { mUnregisterTime = TimeStamp::Now(); } + void NotifyUnregistered(uint64_t aBufferPosition) + { + mUnregisterTime = TimeStamp::Now(); + mBufferPositionWhenUnregistered = mozilla::Some(aBufferPosition); + } + mozilla::Maybe BufferPositionWhenUnregistered() { return mBufferPositionWhenUnregistered; } PlatformData* GetPlatformData() const { return mPlatformData.get(); } void* StackTop() const { return mStackTop; } @@ -206,6 +211,7 @@ private: mozilla::UniqueFreePtr mName; mozilla::TimeStamp mRegisterTime; mozilla::TimeStamp mUnregisterTime; + mozilla::Maybe mBufferPositionWhenUnregistered; const bool mIsMainThread; nsCOMPtr mThread; diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp index 19fa881a8615..3b4c9430a73d 100644 --- a/tools/profiler/core/platform.cpp +++ b/tools/profiler/core/platform.cpp @@ -284,6 +284,22 @@ public: PS_GET(ThreadVector&, LiveThreads) PS_GET(ThreadVector&, DeadThreads) + static void DiscardExpiredDeadThreads(PSLockRef, uint64_t aBufferRangeStart) + { + // Discard any dead threads that were unregistered before aBufferRangeStart. + ThreadVector& deadThreads = sInstance->mDeadThreads; + for (size_t i = 0; i < deadThreads.size(); i++) { + Maybe bufferPosition = + deadThreads.at(i)->BufferPositionWhenUnregistered(); + MOZ_RELEASE_ASSERT(bufferPosition, "should have unregistered this thread"); + if (*bufferPosition < aBufferRangeStart) { + delete deadThreads.at(i); + deadThreads.erase(deadThreads.begin() + i); + i--; + } + } + } + #ifdef USE_LUL_STACKWALK static lul::LUL* Lul(PSLockRef) { return sInstance->mLul.get(); } static void SetLul(PSLockRef, UniquePtr aLul) @@ -1443,6 +1459,7 @@ StreamTaskTracer(PSLockRef aLock, SpliceableJSONWriter& aWriter) StreamNameAndThreadId(aWriter, info->Name(), info->ThreadId()); } + CorePS::DiscardExpiredDeadThreads(aLock, ActivePS::Buffer(aLock).mRangeStart); const CorePS::ThreadVector& deadThreads = CorePS::DeadThreads(aLock); for (size_t i = 0; i < deadThreads.size(); i++) { ThreadInfo* info = deadThreads.at(i); @@ -1688,6 +1705,7 @@ locked_profiler_stream_json_for_this_process(PSLockRef aLock, info->StreamJSON(buffer, aWriter, CorePS::ProcessStartTime(), aSinceTime); } + CorePS::DiscardExpiredDeadThreads(aLock, ActivePS::Buffer(aLock).mRangeStart); const CorePS::ThreadVector& deadThreads = CorePS::DeadThreads(aLock); for (size_t i = 0; i < deadThreads.size(); i++) { ThreadInfo* info = deadThreads.at(i); @@ -3095,8 +3113,9 @@ profiler_unregister_thread() if (info) { DEBUG_LOG("profiler_unregister_thread: %s", info->Name()); if (ActivePS::Exists(lock) && info->IsBeingProfiled()) { - info->NotifyUnregistered(); + info->NotifyUnregistered(ActivePS::Buffer(lock).mRangeEnd); CorePS::DeadThreads(lock).push_back(info); + CorePS::DiscardExpiredDeadThreads(lock, ActivePS::Buffer(lock).mRangeStart); } else { delete info; }