Bug 810526 - Add stack top to Thread{Info,Profile}. r=bgirard
--- a/tools/profiler/ProfileEntry.cpp
+++ b/tools/profiler/ProfileEntry.cpp
@@ -133,27 +133,28 @@ std::ostream& operator<<(std::ostream& s
////////////////////////////////////////////////////////////////////////
// BEGIN ThreadProfile
#define DYNAMIC_MAX_STRING 512
ThreadProfile::ThreadProfile(const char* aName, int aEntrySize,
PseudoStack *aStack, int aThreadId,
PlatformData* aPlatform,
- bool aIsMainThread)
+ bool aIsMainThread, void *aStackTop)
: mWritePos(0)
, mLastFlushPos(0)
, mReadPos(0)
, mEntrySize(aEntrySize)
, mPseudoStack(aStack)
, mMutex("ThreadProfile::mMutex")
, mName(strdup(aName))
, mThreadId(aThreadId)
, mIsMainThread(aIsMainThread)
, mPlatformData(aPlatform)
+ , mStackTop(aStackTop)
{
mEntries = new ProfileEntry[mEntrySize];
}
ThreadProfile::~ThreadProfile()
{
free(mName);
delete[] mEntries;
--- a/tools/profiler/ProfileEntry.h
+++ b/tools/profiler/ProfileEntry.h
@@ -53,17 +53,17 @@ private:
typedef void (*IterateTagsCallback)(const ProfileEntry& entry, const char* tagStringData);
class ThreadProfile
{
public:
ThreadProfile(const char* aName, int aEntrySize, PseudoStack *aStack,
int aThreadId, PlatformData* aPlatformData,
- bool aIsMainThread);
+ bool aIsMainThread, void *aStackTop);
~ThreadProfile();
void addTag(ProfileEntry aTag);
void flush();
void erase();
char* processDynamicTag(int readPos, int* tagsConsumed, char* tagBuff);
void IterateTags(IterateTagsCallback aCallback);
friend std::ostream& operator<<(std::ostream& stream,
const ThreadProfile& profile);
@@ -73,27 +73,29 @@ public:
mozilla::Mutex* GetMutex();
void BuildJSObject(JSAObjectBuilder& b, JSCustomObject* profile);
bool IsMainThread() const { return mIsMainThread; }
const char* Name() const { return mName; }
int ThreadId() const { return mThreadId; }
PlatformData* GetPlatformData() { return mPlatformData; }
+ void* GetStackTop() const { return mStackTop; }
private:
// Circular buffer 'Keep One Slot Open' implementation
// for simplicity
ProfileEntry* mEntries;
int mWritePos; // points to the next entry we will write to
int mLastFlushPos; // points to the next entry since the last flush()
int mReadPos; // points to the next entry we will read to
int mEntrySize;
PseudoStack* mPseudoStack;
mozilla::Mutex mMutex;
char* mName;
int mThreadId;
bool mIsMainThread;
PlatformData* mPlatformData; // Platform specific data.
+ void* const mStackTop;
};
std::ostream& operator<<(std::ostream& stream, const ThreadProfile& profile);
#endif /* ndef MOZ_PROFILE_ENTRY_H */
--- a/tools/profiler/TableTicker.cpp
+++ b/tools/profiler/TableTicker.cpp
@@ -539,18 +539,23 @@ void mozilla_sampler_print_location1()
profiler_init(NULL);
PseudoStack *stack = tlsPseudoStack.get();
if (!stack) {
MOZ_ASSERT(false);
return;
}
+ // This won't allow unwinding past this function, but it will be safe.
+ void *stackTop = &stack;
+
ThreadProfile threadProfile("Temp", PROFILE_DEFAULT_ENTRY, stack,
- 0, Sampler::AllocPlatformData(0), false);
+ 0, Sampler::AllocPlatformData(0), false,
+ stackTop);
+
doSampleStackTrace(stack, threadProfile, NULL);
threadProfile.flush();
printf_stderr("Backtrace:\n");
threadProfile.IterateTags(print_callback);
}
--- a/tools/profiler/TableTicker.h
+++ b/tools/profiler/TableTicker.h
@@ -115,17 +115,18 @@ class TableTicker: public Sampler {
return;
}
ThreadProfile* profile = new ThreadProfile(aInfo->Name(),
EntrySize(),
aInfo->Stack(),
aInfo->ThreadId(),
aInfo->GetPlatformData(),
- aInfo->IsMainThread());
+ aInfo->IsMainThread(),
+ aInfo->StackTop());
profile->addTag(ProfileEntry('m', "Start"));
aInfo->SetProfile(profile);
}
// Called within a signal. This function must be reentrant
virtual void Tick(TickSample* sample);
--- a/tools/profiler/platform-linux.cc
+++ b/tools/profiler/platform-linux.cc
@@ -378,17 +378,17 @@ bool Sampler::RegisterCurrentThread(cons
bool aIsMainThread, void* stackTop)
{
if (!Sampler::sRegisteredThreadsMutex)
return false;
mozilla::MutexAutoLock lock(*Sampler::sRegisteredThreadsMutex);
ThreadInfo* info = new ThreadInfo(aName, gettid(),
- aIsMainThread, aPseudoStack);
+ aIsMainThread, aPseudoStack, stackTop);
if (sActiveSampler) {
sActiveSampler->RegisterThread(info);
}
sRegisteredThreads->push_back(info);
uwt__register_thread_for_profiling(stackTop);
--- a/tools/profiler/platform-macos.cc
+++ b/tools/profiler/platform-macos.cc
@@ -354,17 +354,17 @@ bool Sampler::RegisterCurrentThread(cons
bool aIsMainThread, void* stackTop)
{
if (!Sampler::sRegisteredThreadsMutex)
return false;
mozilla::MutexAutoLock lock(*Sampler::sRegisteredThreadsMutex);
ThreadInfo* info = new ThreadInfo(aName, gettid(),
- aIsMainThread, aPseudoStack);
+ aIsMainThread, aPseudoStack, stackTop);
if (sActiveSampler) {
sActiveSampler->RegisterThread(info);
}
sRegisteredThreads->push_back(info);
uwt__register_thread_for_profiling(stackTop);
--- a/tools/profiler/platform-win32.cc
+++ b/tools/profiler/platform-win32.cc
@@ -273,17 +273,17 @@ bool Sampler::RegisterCurrentThread(cons
bool aIsMainThread, void* stackTop)
{
if (!Sampler::sRegisteredThreadsMutex)
return false;
mozilla::MutexAutoLock lock(*Sampler::sRegisteredThreadsMutex);
ThreadInfo* info = new ThreadInfo(aName, GetCurrentThreadId(),
- aIsMainThread, aPseudoStack);
+ aIsMainThread, aPseudoStack, stackTop);
if (sActiveSampler) {
sActiveSampler->RegisterThread(info);
}
sRegisteredThreads->push_back(info);
uwt__register_thread_for_profiling(stackTop);
--- a/tools/profiler/platform.h
+++ b/tools/profiler/platform.h
@@ -373,38 +373,41 @@ class Sampler {
struct sigaction old_sigsave_signal_handler_;
bool signal_sender_launched_;
pthread_t signal_sender_thread_;
#endif
};
class ThreadInfo {
public:
- ThreadInfo(const char* aName, int aThreadId, bool aIsMainThread, PseudoStack* aPseudoStack)
+ ThreadInfo(const char* aName, int aThreadId, bool aIsMainThread, PseudoStack* aPseudoStack, void* aStackTop)
: mName(strdup(aName))
, mThreadId(aThreadId)
, mIsMainThread(aIsMainThread)
, mPseudoStack(aPseudoStack)
, mPlatformData(Sampler::AllocPlatformData(aThreadId))
- , mProfile(NULL) {}
+ , mProfile(NULL)
+ , mStackTop(aStackTop) {}
virtual ~ThreadInfo();
const char* Name() const { return mName; }
int ThreadId() const { return mThreadId; }
bool IsMainThread() const { return mIsMainThread; }
PseudoStack* Stack() const { return mPseudoStack; }
void SetProfile(ThreadProfile* aProfile) { mProfile = aProfile; }
ThreadProfile* Profile() const { return mProfile; }
PlatformData* GetPlatformData() const { return mPlatformData; }
+ void* StackTop() const { return mStackTop; }
private:
char* mName;
int mThreadId;
const bool mIsMainThread;
PseudoStack* mPseudoStack;
PlatformData* mPlatformData;
ThreadProfile* mProfile;
+ void* const mStackTop;
};
#endif /* ndef TOOLS_PLATFORM_H_ */