mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Bug 766579 - Part 2: Intertwine during sampling. r=jmuizelaar
--HG-- extra : rebase_source : e2ddcc188fcd6a2b3b6c35d3517fb7ec8ae7deab
This commit is contained in:
parent
325b77e999
commit
c8f0c7a400
@ -561,6 +561,33 @@ JSObject* TableTicker::ToJSObject(JSContext *aCx)
|
||||
return profile;
|
||||
}
|
||||
|
||||
static
|
||||
void addProfileEntry(ProfileStack *aStack, ThreadProfile &aProfile, int i)
|
||||
{
|
||||
// First entry has tagName 's' (start)
|
||||
// Check for magic pointer bit 1 to indicate copy
|
||||
const char* sampleLabel = aStack->mStack[i].mLabel;
|
||||
if (aStack->mStack[i].isCopyLabel()) {
|
||||
// Store the string using 1 or more 'd' (dynamic) tags
|
||||
// that will happen to the preceding tag
|
||||
|
||||
aProfile.addTag(ProfileEntry('c', ""));
|
||||
// Add one to store the null termination
|
||||
size_t strLen = strlen(sampleLabel) + 1;
|
||||
for (size_t j = 0; j < strLen;) {
|
||||
// Store as many characters in the void* as the platform allows
|
||||
char text[sizeof(void*)];
|
||||
for (size_t pos = 0; pos < sizeof(void*) && j+pos < strLen; pos++) {
|
||||
text[pos] = sampleLabel[j+pos];
|
||||
}
|
||||
j += sizeof(void*)/sizeof(char);
|
||||
// Cast to *((void**) to pass the text data to a void*
|
||||
aProfile.addTag(ProfileEntry('d', *((void**)(&text[0]))));
|
||||
}
|
||||
} else {
|
||||
aProfile.addTag(ProfileEntry('c', sampleLabel));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_BACKTRACE
|
||||
void TableTicker::doBacktrace(ThreadProfile &aProfile, TickSample* aSample)
|
||||
@ -581,6 +608,7 @@ void TableTicker::doBacktrace(ThreadProfile &aProfile, TickSample* aSample)
|
||||
#ifdef USE_NS_STACKWALK
|
||||
typedef struct {
|
||||
void** array;
|
||||
void** sp_array;
|
||||
size_t size;
|
||||
size_t count;
|
||||
} PCArray;
|
||||
@ -593,7 +621,9 @@ void StackWalkCallback(void* aPC, void* aSP, void* aClosure)
|
||||
// too many frames, ignore
|
||||
return;
|
||||
}
|
||||
array->array[array->count++] = aPC;
|
||||
array->sp_array[array->count] = aSP;
|
||||
array->array[array->count] = aPC;
|
||||
array->count++;
|
||||
}
|
||||
|
||||
void TableTicker::doBacktrace(ThreadProfile &aProfile, TickSample* aSample)
|
||||
@ -603,8 +633,10 @@ void TableTicker::doBacktrace(ThreadProfile &aProfile, TickSample* aSample)
|
||||
MOZ_ASSERT(thread);
|
||||
#endif
|
||||
void* pc_array[1000];
|
||||
void* sp_array[1000];
|
||||
PCArray array = {
|
||||
pc_array,
|
||||
sp_array,
|
||||
mozilla::ArrayLength(pc_array),
|
||||
0
|
||||
};
|
||||
@ -624,8 +656,39 @@ void TableTicker::doBacktrace(ThreadProfile &aProfile, TickSample* aSample)
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aProfile.addTag(ProfileEntry('s', "(root)"));
|
||||
|
||||
ProfileStack* stack = aProfile.GetStack();
|
||||
int pseudoStackPos = 0;
|
||||
|
||||
/* We have two stacks, the native C stack we extracted from unwinding,
|
||||
* and the pseudostack we managed during execution. We want to consolidate
|
||||
* the two in order. We do so by merging using the approximate stack address
|
||||
* when each entry was push. When pushing JS entry we may not now the stack
|
||||
* address in which case we have a NULL stack address in which case we assume
|
||||
* that it follows immediatly the previous element.
|
||||
*
|
||||
* C Stack | Address -- Pseudo Stack | Address
|
||||
* main() | 0x100 run_js() | 0x40
|
||||
* start() | 0x80 jsCanvas() | NULL
|
||||
* timer() | 0x50 drawLine() | NULL
|
||||
* azure() | 0x10
|
||||
*
|
||||
* Merged: main(), start(), timer(), run_js(), jsCanvas(), drawLine(), azure()
|
||||
*/
|
||||
// i is the index in C stack starting at main and decreasing
|
||||
// pseudoStackPos is the position in the Pseudo stack starting
|
||||
// at the first frame (run_js in the example) and increasing.
|
||||
for (size_t i = array.count; i > 0; --i) {
|
||||
aProfile.addTag(ProfileEntry('l', (void*)array.array[i - 1]));
|
||||
while (pseudoStackPos < stack->mStackPointer) {
|
||||
volatile StackEntry& entry = stack->mStack[pseudoStackPos];
|
||||
|
||||
if (entry.mStackAddress < array.sp_array[i-1] && entry.mStackAddress)
|
||||
break;
|
||||
|
||||
addProfileEntry(stack, aProfile, pseudoStackPos);
|
||||
pseudoStackPos++;
|
||||
}
|
||||
|
||||
aProfile.addTag(ProfileEntry('l', (void*)array.array[i-1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -689,29 +752,7 @@ void doSampleStackTrace(ProfileStack *aStack, ThreadProfile &aProfile, TickSampl
|
||||
for (mozilla::sig_safe_t i = 0;
|
||||
i < aStack->mStackPointer && i < mozilla::ArrayLength(aStack->mStack);
|
||||
i++) {
|
||||
// First entry has tagName 's' (start)
|
||||
// Check for magic pointer bit 1 to indicate copy
|
||||
const char* sampleLabel = aStack->mStack[i].mLabel;
|
||||
if (aStack->mStack[i].isCopyLabel()) {
|
||||
// Store the string using 1 or more 'd' (dynamic) tags
|
||||
// that will happen to the preceding tag
|
||||
|
||||
aProfile.addTag(ProfileEntry('c', ""));
|
||||
// Add one to store the null termination
|
||||
size_t strLen = strlen(sampleLabel) + 1;
|
||||
for (size_t j = 0; j < strLen;) {
|
||||
// Store as many characters in the void* as the platform allows
|
||||
char text[sizeof(void*)];
|
||||
for (size_t pos = 0; pos < sizeof(void*) && j+pos < strLen; pos++) {
|
||||
text[pos] = sampleLabel[j+pos];
|
||||
}
|
||||
j += sizeof(void*);
|
||||
// Take '*((void**)(&text[0]))' to pass the char[] as a single void*
|
||||
aProfile.addTag(ProfileEntry('d', *((void**)(&text[0]))));
|
||||
}
|
||||
} else {
|
||||
aProfile.addTag(ProfileEntry('c', sampleLabel));
|
||||
}
|
||||
addProfileEntry(aStack, aProfile, i);
|
||||
}
|
||||
#ifdef ENABLE_SPS_LEAF_DATA
|
||||
if (sample) {
|
||||
|
@ -44,7 +44,6 @@
|
||||
* application is responding to the event loop. Lower is better.
|
||||
* 't' - Elapse time since recording started.
|
||||
*
|
||||
* NOTE: File format is planned to be extended to include a dictionary to reduce size.
|
||||
*/
|
||||
|
||||
#ifndef SAMPLER_H
|
||||
|
@ -155,7 +155,7 @@ class NS_STACK_CLASS SamplerStackFrameRAII {
|
||||
public:
|
||||
// we only copy the strings at save time, so to take multiple parameters we'd need to copy them then.
|
||||
SamplerStackFrameRAII(const char *aInfo) {
|
||||
mHandle = mozilla_sampler_call_enter(aInfo);
|
||||
mHandle = mozilla_sampler_call_enter(aInfo, this, false);
|
||||
}
|
||||
~SamplerStackFrameRAII() {
|
||||
mozilla_sampler_call_exit(mHandle);
|
||||
|
Loading…
Reference in New Issue
Block a user