Bug 1017790 - Expose category information in the profiler data, r=djvj

This commit is contained in:
Victor Porof 2014-06-04 14:37:49 -04:00
parent 90e774e163
commit b3b4be1879
5 changed files with 36 additions and 12 deletions

View File

@ -59,7 +59,10 @@ class ProfileEntry
// Indicate that copying the frame label is not necessary when taking a
// sample of the pseudostack.
FRAME_LABEL_COPY = 0x02
FRAME_LABEL_COPY = 0x02,
// Mask for removing all flags except the category information.
CATEGORY_MASK = ~IS_CPP_ENTRY & ~FRAME_LABEL_COPY
};
MOZ_BEGIN_NESTED_ENUM_CLASS(Category, uint32_t)
@ -112,9 +115,13 @@ class ProfileEntry
bool hasFlag(uint32_t flag) const volatile {
return bool(flags_ & flag);
}
uint32_t flags() const volatile {
return flags_;
}
uint32_t category() const volatile {
return flags_ & CATEGORY_MASK;
}
void *stackAddress() const volatile {
MOZ_ASSERT(!isJs());

View File

@ -59,8 +59,8 @@ ProfileEntry::ProfileEntry(char aTagName, Address aTagAddress)
, mTagName(aTagName)
{ }
ProfileEntry::ProfileEntry(char aTagName, int aTagLine)
: mTagLine(aTagLine)
ProfileEntry::ProfileEntry(char aTagName, int aTagInt)
: mTagInt(aTagInt)
, mTagName(aTagName)
{ }
@ -94,7 +94,7 @@ void ProfileEntry::log()
// mTagMarker (ProfilerMarker*) m
// mTagData (const char*) c,s
// mTagPtr (void*) d,l,L,B (immediate backtrace), S(start-of-stack)
// mTagLine (int) n,f
// mTagInt (int) n,f,y
// mTagChar (char) h
// mTagFloat (double) r,t,p,R (resident memory)
switch (mTagName) {
@ -104,8 +104,8 @@ void ProfileEntry::log()
LOGF("%c \"%s\"", mTagName, mTagData); break;
case 'd': case 'l': case 'L': case 'B': case 'S':
LOGF("%c %p", mTagName, mTagPtr); break;
case 'n': case 'f':
LOGF("%c %d", mTagName, mTagLine); break;
case 'n': case 'f': case 'y':
LOGF("%c %d", mTagName, mTagInt); break;
case 'h':
LOGF("%c \'%c\'", mTagName, mTagChar); break;
case 'r': case 't': case 'p': case 'R':
@ -362,7 +362,7 @@ void ThreadProfile::StreamJSObject(JSStreamWriter& b)
case 'f':
{
if (sample) {
b.NameValue("frameNumber", entry.mTagLine);
b.NameValue("frameNumber", entry.mTagInt);
}
}
break;
@ -399,6 +399,7 @@ void ThreadProfile::StreamJSObject(JSStreamWriter& b)
while (framePos != mLastFlushPos && frame.mTagName != 's') {
int incBy = 1;
frame = mEntries[framePos];
// Read ahead to the next tag, if it's a 'd' tag process it now
const char* tagStringData = frame.mTagData;
int readAheadPos = (framePos + 1) % mEntrySize;
@ -413,7 +414,8 @@ void ThreadProfile::StreamJSObject(JSStreamWriter& b)
// Write one frame. It can have either
// 1. only location - 'l' containing a memory address
// 2. location and line number - 'c' followed by 'd's and an optional 'n'
// 2. location and line number - 'c' followed by 'd's,
// an optional 'n' and an optional 'y'
if (frame.mTagName == 'l') {
b.BeginObject();
// Bug 753041
@ -429,7 +431,13 @@ void ThreadProfile::StreamJSObject(JSStreamWriter& b)
readAheadPos = (framePos + incBy) % mEntrySize;
if (readAheadPos != mLastFlushPos &&
mEntries[readAheadPos].mTagName == 'n') {
b.NameValue("line", mEntries[readAheadPos].mTagLine);
b.NameValue("line", mEntries[readAheadPos].mTagInt);
incBy++;
}
readAheadPos = (framePos + incBy) % mEntrySize;
if (readAheadPos != mLastFlushPos &&
mEntries[readAheadPos].mTagName == 'y') {
b.NameValue("category", mEntries[readAheadPos].mTagInt);
incBy++;
}
b.EndObject();

View File

@ -61,7 +61,7 @@ private:
float mTagFloat;
Address mTagAddress;
uintptr_t mTagOffset;
int mTagLine;
int mTagInt;
char mTagChar;
};
char mTagName;

View File

@ -374,9 +374,18 @@ void addProfileEntry(volatile StackEntry &entry, ThreadProfile &aProfile,
lineno = entry.line();
}
}
if (lineno != -1) {
aProfile.addTag(ProfileEntry('n', lineno));
}
uint32_t category = entry.category();
MOZ_ASSERT(!(category & StackEntry::IS_CPP_ENTRY));
MOZ_ASSERT(!(category & StackEntry::FRAME_LABEL_COPY));
if (category) {
aProfile.addTag(ProfileEntry('y', (int)category));
}
}
#if defined(USE_NS_STACKWALK) || defined(USE_EHABI_STACKWALK)

View File

@ -38,7 +38,7 @@ TEST(ThreadProfile, InsertTagsNoWrap) {
int readPos = tp.mReadPos;
while (readPos != tp.mWritePos) {
ASSERT_TRUE(tp.mEntries[readPos].mTagName == 't');
ASSERT_TRUE(tp.mEntries[readPos].mTagLine == readPos);
ASSERT_TRUE(tp.mEntries[readPos].mTagInt == readPos);
readPos = (readPos + 1) % tp.mEntrySize;
}
}
@ -61,7 +61,7 @@ TEST(ThreadProfile, InsertTagsWrap) {
while (readPos != tp.mWritePos) {
ASSERT_TRUE(tp.mEntries[readPos].mTagName == 't');
// the first few tags were discarded when we wrapped
ASSERT_TRUE(tp.mEntries[readPos].mTagLine == ctr + (test_size - tags));
ASSERT_TRUE(tp.mEntries[readPos].mTagInt == ctr + (test_size - tags));
ctr++;
readPos = (readPos + 1) % tp.mEntrySize;
}