diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp index c04d54e02e34..50ff84f67e0a 100644 --- a/tools/profiler/core/platform.cpp +++ b/tools/profiler/core/platform.cpp @@ -1027,6 +1027,33 @@ void mozilla_sampler_free_backtrace(ProfilerBacktrace* aBacktrace) delete aBacktrace; } +// Fill the output buffer with the following pattern: +// "Lable 1" "\0" "Label 2" "\0" ... "Label N" "\0" "\0" +// TODO: use the unwinder instead of pseudo stack. +void mozilla_sampler_get_backtrace_noalloc(char *output, size_t outputSize) +{ + MOZ_ASSERT(outputSize >= 2); + char *bound = output + outputSize - 2; + output[0] = output[1] = '\0'; + PseudoStack *pseudoStack = tlsPseudoStack.get(); + if (!pseudoStack) { + return; + } + + volatile StackEntry *pseudoFrames = pseudoStack->mStack; + uint32_t pseudoCount = pseudoStack->stackSize(); + + for (uint32_t i = 0; i < pseudoCount; i++) { + size_t len = strlen(pseudoFrames[i].label()); + if (output + len >= bound) + break; + strcpy(output, pseudoFrames[i].label()); + output += len; + *output++ = '\0'; + *output = '\0'; + } +} + void mozilla_sampler_tracing(const char* aCategory, const char* aInfo, TracingMetadata aMetaData) { diff --git a/tools/profiler/public/GeckoProfiler.h b/tools/profiler/public/GeckoProfiler.h index 64bf3132d9c7..f8ec8c736927 100644 --- a/tools/profiler/public/GeckoProfiler.h +++ b/tools/profiler/public/GeckoProfiler.h @@ -149,6 +149,7 @@ static inline void profiler_resume() {} // Immediately capture the current thread's call stack and return it static inline ProfilerBacktrace* profiler_get_backtrace() { return nullptr; } +static inline void profiler_get_backtrace_noalloc(char *output, size_t outputSize) { return; } // Free a ProfilerBacktrace returned by profiler_get_backtrace() static inline void profiler_free_backtrace(ProfilerBacktrace* aBacktrace) {} diff --git a/tools/profiler/public/GeckoProfilerFunc.h b/tools/profiler/public/GeckoProfilerFunc.h index 0bf6d1509577..4a19b874b959 100644 --- a/tools/profiler/public/GeckoProfilerFunc.h +++ b/tools/profiler/public/GeckoProfilerFunc.h @@ -48,6 +48,7 @@ void mozilla_sampler_resume(); ProfilerBacktrace* mozilla_sampler_get_backtrace(); void mozilla_sampler_free_backtrace(ProfilerBacktrace* aBacktrace); +void mozilla_sampler_get_backtrace_noalloc(char *output, size_t outputSize); bool mozilla_sampler_is_active(); diff --git a/tools/profiler/public/GeckoProfilerImpl.h b/tools/profiler/public/GeckoProfilerImpl.h index 0d81b7d425e5..e27d5c20140f 100644 --- a/tools/profiler/public/GeckoProfilerImpl.h +++ b/tools/profiler/public/GeckoProfilerImpl.h @@ -121,6 +121,12 @@ void profiler_free_backtrace(ProfilerBacktrace* aBacktrace) mozilla_sampler_free_backtrace(aBacktrace); } +static inline +void profiler_get_backtrace_noalloc(char *output, size_t outputSize) +{ + return mozilla_sampler_get_backtrace_noalloc(output, outputSize); +} + static inline bool profiler_is_active() {