2015-06-30 22:03:45 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef MOZ_THREAD_INFO_H
|
|
|
|
#define MOZ_THREAD_INFO_H
|
|
|
|
|
2017-01-06 17:21:01 +03:00
|
|
|
#include "mozilla/UniquePtrExtensions.h"
|
|
|
|
|
Bug 1335595 (part 4) - Merge ThreadProfile into ThreadInfo. r=mstange.
ThreadInfo and ThreadProfile are hopelessly intertwined.
- ThreadInfo has an owning pointer to ThreadProfile. ThreadProfile has a raw
back pointer to ThreadInfo. A reference to one is as good as a reference to
the other, and references to one frequently reach into the other.
- An exception is SyncProfile, a sub-class of ThreadProfile, which instead has
an owning pointer to its ThreadInfo. (This makes the SyncProfile's destructor
dubious, because it deletes the ThreadInfo, which could conceivably re-call
into SyncProfile's destructor.)
- ThreadProfile also has copies of five ThreadInfo fields (mThreadId,
mIsMainThread, mPlatformData, mStackTop, mPseudoStack) even though it also
has direct ThreadInfo access via the back pointer.
The only good reason for having the two classes separate is that some
ThreadInfo objects have a null ThreadProfile pointer. But this doesn't justify
the entanglement.
So this patch merges ThreadProfile into ThreadInfo. It visually separates the
methods and fields related to profiles to partially preserve the original
meaning of the split. The new ThreadInfo::hasProfile() method replaces
ThreadInfo::Profile() as the indicator of whether a ThreadInfo has associated
profile data.
Notable points of simplification:
- The five duplicated fields are no longer duplicated.
- NewSyncProfile(), RegisterThread() no longer create ThreadProfile objects.
- ~SyncProfile() becomes trivial.
- ThreadInfo::SetPendingDelete() is simpler.
- Overall it removes ~80 lines of code.
Much of the rest is just plumbing changes.
--HG--
extra : rebase_source : 2e8c4cc46aa15943ffdc1fa19d9c829587267ee9
2017-02-02 03:07:13 +03:00
|
|
|
#include "ProfileBuffer.h"
|
2015-06-30 22:03:45 +03:00
|
|
|
#include "platform.h"
|
|
|
|
|
|
|
|
class ThreadInfo {
|
|
|
|
public:
|
|
|
|
ThreadInfo(const char* aName, int aThreadId, bool aIsMainThread, PseudoStack* aPseudoStack, void* aStackTop);
|
|
|
|
|
|
|
|
virtual ~ThreadInfo();
|
|
|
|
|
2017-01-06 17:21:01 +03:00
|
|
|
const char* Name() const { return mName.get(); }
|
2015-06-30 22:03:45 +03:00
|
|
|
int ThreadId() const { return mThreadId; }
|
|
|
|
|
|
|
|
bool IsMainThread() const { return mIsMainThread; }
|
|
|
|
PseudoStack* Stack() const { return mPseudoStack; }
|
|
|
|
|
Bug 1335595 (part 4) - Merge ThreadProfile into ThreadInfo. r=mstange.
ThreadInfo and ThreadProfile are hopelessly intertwined.
- ThreadInfo has an owning pointer to ThreadProfile. ThreadProfile has a raw
back pointer to ThreadInfo. A reference to one is as good as a reference to
the other, and references to one frequently reach into the other.
- An exception is SyncProfile, a sub-class of ThreadProfile, which instead has
an owning pointer to its ThreadInfo. (This makes the SyncProfile's destructor
dubious, because it deletes the ThreadInfo, which could conceivably re-call
into SyncProfile's destructor.)
- ThreadProfile also has copies of five ThreadInfo fields (mThreadId,
mIsMainThread, mPlatformData, mStackTop, mPseudoStack) even though it also
has direct ThreadInfo access via the back pointer.
The only good reason for having the two classes separate is that some
ThreadInfo objects have a null ThreadProfile pointer. But this doesn't justify
the entanglement.
So this patch merges ThreadProfile into ThreadInfo. It visually separates the
methods and fields related to profiles to partially preserve the original
meaning of the split. The new ThreadInfo::hasProfile() method replaces
ThreadInfo::Profile() as the indicator of whether a ThreadInfo has associated
profile data.
Notable points of simplification:
- The five duplicated fields are no longer duplicated.
- NewSyncProfile(), RegisterThread() no longer create ThreadProfile objects.
- ~SyncProfile() becomes trivial.
- ThreadInfo::SetPendingDelete() is simpler.
- Overall it removes ~80 lines of code.
Much of the rest is just plumbing changes.
--HG--
extra : rebase_source : 2e8c4cc46aa15943ffdc1fa19d9c829587267ee9
2017-02-02 03:07:13 +03:00
|
|
|
void SetProfile(ProfileBuffer* aBuffer) { mBuffer = aBuffer; }
|
2015-06-30 22:03:45 +03:00
|
|
|
|
2017-01-06 17:21:01 +03:00
|
|
|
PlatformData* GetPlatformData() const { return mPlatformData.get(); }
|
2015-06-30 22:03:45 +03:00
|
|
|
void* StackTop() const { return mStackTop; }
|
|
|
|
|
|
|
|
virtual void SetPendingDelete();
|
|
|
|
bool IsPendingDelete() const { return mPendingDelete; }
|
|
|
|
|
2016-09-16 07:35:14 +03:00
|
|
|
bool CanInvokeJS() const;
|
|
|
|
|
2017-01-30 04:37:26 +03:00
|
|
|
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
|
|
|
|
2015-06-30 22:03:45 +03:00
|
|
|
private:
|
2017-01-06 17:21:01 +03:00
|
|
|
mozilla::UniqueFreePtr<char> mName;
|
2015-06-30 22:03:45 +03:00
|
|
|
int mThreadId;
|
|
|
|
const bool mIsMainThread;
|
|
|
|
PseudoStack* mPseudoStack;
|
2017-02-09 07:04:36 +03:00
|
|
|
UniquePlatformData mPlatformData;
|
2015-08-26 01:03:32 +03:00
|
|
|
void* mStackTop;
|
2017-02-02 03:07:13 +03:00
|
|
|
|
|
|
|
// May be null for the main thread if the profiler was started during startup.
|
2015-06-30 22:03:45 +03:00
|
|
|
nsCOMPtr<nsIThread> mThread;
|
2017-02-02 03:07:13 +03:00
|
|
|
|
2015-06-30 22:03:45 +03:00
|
|
|
bool mPendingDelete;
|
Bug 1335595 (part 4) - Merge ThreadProfile into ThreadInfo. r=mstange.
ThreadInfo and ThreadProfile are hopelessly intertwined.
- ThreadInfo has an owning pointer to ThreadProfile. ThreadProfile has a raw
back pointer to ThreadInfo. A reference to one is as good as a reference to
the other, and references to one frequently reach into the other.
- An exception is SyncProfile, a sub-class of ThreadProfile, which instead has
an owning pointer to its ThreadInfo. (This makes the SyncProfile's destructor
dubious, because it deletes the ThreadInfo, which could conceivably re-call
into SyncProfile's destructor.)
- ThreadProfile also has copies of five ThreadInfo fields (mThreadId,
mIsMainThread, mPlatformData, mStackTop, mPseudoStack) even though it also
has direct ThreadInfo access via the back pointer.
The only good reason for having the two classes separate is that some
ThreadInfo objects have a null ThreadProfile pointer. But this doesn't justify
the entanglement.
So this patch merges ThreadProfile into ThreadInfo. It visually separates the
methods and fields related to profiles to partially preserve the original
meaning of the split. The new ThreadInfo::hasProfile() method replaces
ThreadInfo::Profile() as the indicator of whether a ThreadInfo has associated
profile data.
Notable points of simplification:
- The five duplicated fields are no longer duplicated.
- NewSyncProfile(), RegisterThread() no longer create ThreadProfile objects.
- ~SyncProfile() becomes trivial.
- ThreadInfo::SetPendingDelete() is simpler.
- Overall it removes ~80 lines of code.
Much of the rest is just plumbing changes.
--HG--
extra : rebase_source : 2e8c4cc46aa15943ffdc1fa19d9c829587267ee9
2017-02-02 03:07:13 +03:00
|
|
|
|
|
|
|
//
|
|
|
|
// The following code is only used for threads that are being profiled, i.e.
|
|
|
|
// for which SetProfile() has been called.
|
|
|
|
//
|
|
|
|
|
|
|
|
public:
|
|
|
|
bool hasProfile() { return !!mBuffer; }
|
|
|
|
|
|
|
|
void addTag(const ProfileEntry& aTag);
|
|
|
|
|
|
|
|
// Track a marker which has been inserted into the thread profile.
|
|
|
|
// This marker can safely be deleted once the generation has
|
|
|
|
// expired.
|
|
|
|
void addStoredMarker(ProfilerMarker* aStoredMarker);
|
|
|
|
mozilla::Mutex& GetMutex();
|
|
|
|
void StreamJSON(SpliceableJSONWriter& aWriter, double aSinceTime = 0);
|
|
|
|
|
|
|
|
// Call this method when the JS entries inside the buffer are about to
|
|
|
|
// become invalid, i.e., just before JS shutdown.
|
|
|
|
void FlushSamplesAndMarkers();
|
|
|
|
|
|
|
|
void BeginUnwind();
|
|
|
|
virtual void EndUnwind();
|
|
|
|
|
|
|
|
void DuplicateLastSample();
|
|
|
|
|
|
|
|
ThreadResponsiveness* GetThreadResponsiveness() { return &mRespInfo; }
|
|
|
|
|
2017-02-02 03:07:13 +03:00
|
|
|
void UpdateThreadResponsiveness() {
|
|
|
|
mRespInfo.Update(mIsMainThread, mThread);
|
|
|
|
}
|
|
|
|
|
Bug 1335595 (part 4) - Merge ThreadProfile into ThreadInfo. r=mstange.
ThreadInfo and ThreadProfile are hopelessly intertwined.
- ThreadInfo has an owning pointer to ThreadProfile. ThreadProfile has a raw
back pointer to ThreadInfo. A reference to one is as good as a reference to
the other, and references to one frequently reach into the other.
- An exception is SyncProfile, a sub-class of ThreadProfile, which instead has
an owning pointer to its ThreadInfo. (This makes the SyncProfile's destructor
dubious, because it deletes the ThreadInfo, which could conceivably re-call
into SyncProfile's destructor.)
- ThreadProfile also has copies of five ThreadInfo fields (mThreadId,
mIsMainThread, mPlatformData, mStackTop, mPseudoStack) even though it also
has direct ThreadInfo access via the back pointer.
The only good reason for having the two classes separate is that some
ThreadInfo objects have a null ThreadProfile pointer. But this doesn't justify
the entanglement.
So this patch merges ThreadProfile into ThreadInfo. It visually separates the
methods and fields related to profiles to partially preserve the original
meaning of the split. The new ThreadInfo::hasProfile() method replaces
ThreadInfo::Profile() as the indicator of whether a ThreadInfo has associated
profile data.
Notable points of simplification:
- The five duplicated fields are no longer duplicated.
- NewSyncProfile(), RegisterThread() no longer create ThreadProfile objects.
- ~SyncProfile() becomes trivial.
- ThreadInfo::SetPendingDelete() is simpler.
- Overall it removes ~80 lines of code.
Much of the rest is just plumbing changes.
--HG--
extra : rebase_source : 2e8c4cc46aa15943ffdc1fa19d9c829587267ee9
2017-02-02 03:07:13 +03:00
|
|
|
uint32_t bufferGeneration() const { return mBuffer->mGeneration; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void StreamSamplesAndMarkers(SpliceableJSONWriter& aWriter, double aSinceTime,
|
|
|
|
UniqueStacks& aUniqueStacks);
|
|
|
|
|
|
|
|
private:
|
|
|
|
FRIEND_TEST(ThreadProfile, InsertOneTag);
|
|
|
|
FRIEND_TEST(ThreadProfile, InsertOneTagWithTinyBuffer);
|
|
|
|
FRIEND_TEST(ThreadProfile, InsertTagsNoWrap);
|
|
|
|
FRIEND_TEST(ThreadProfile, InsertTagsWrap);
|
|
|
|
FRIEND_TEST(ThreadProfile, MemoryMeasure);
|
|
|
|
|
|
|
|
RefPtr<ProfileBuffer> mBuffer;
|
|
|
|
|
|
|
|
// JS frames in the buffer may require a live JSRuntime to stream (e.g.,
|
|
|
|
// stringifying JIT frames). In the case of JSRuntime destruction,
|
|
|
|
// FlushSamplesAndMarkers should be called to save them. These are spliced
|
|
|
|
// into the final stream.
|
|
|
|
mozilla::UniquePtr<char[]> mSavedStreamedSamples;
|
|
|
|
mozilla::UniquePtr<char[]> mSavedStreamedMarkers;
|
|
|
|
mozilla::Maybe<UniqueStacks> mUniqueStacks;
|
|
|
|
|
|
|
|
mozilla::UniquePtr<mozilla::Mutex> mMutex;
|
|
|
|
ThreadResponsiveness mRespInfo;
|
|
|
|
|
|
|
|
#ifdef XP_LINUX
|
|
|
|
// Only Linux is using a signal sender, instead of stopping the thread, so we
|
|
|
|
// need some space to store the data which cannot be collected in the signal
|
|
|
|
// handler code.
|
|
|
|
public:
|
|
|
|
int64_t mRssMemory;
|
|
|
|
int64_t mUssMemory;
|
|
|
|
#endif
|
2015-06-30 22:03:45 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|