Bug 1123237 - Part 6. A new API to get backtrace without allocating memory in profiler. r=mstange
authorKan-Ru Chen <kanru@kanru.info>
Fri, 08 May 2015 11:21:21 +0800
changeset 295333 ec9d11f8bfa172c43409da56bbe9d6cddd13476d
parent 295332 99ea1dafe05f7cb5f1b7a39ce479eed269433510
child 295334 660efe6d6e57ed63b2be2dcba3c70cc1d2b9c75d
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1123237
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1123237 - Part 6. A new API to get backtrace without allocating memory in profiler. r=mstange Based on patch from Ting-Yuan Huang <laszio.bugzilla@gmail.com>
tools/profiler/core/platform.cpp
tools/profiler/public/GeckoProfiler.h
tools/profiler/public/GeckoProfilerFunc.h
tools/profiler/public/GeckoProfilerImpl.h
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -1022,16 +1022,43 @@ ProfilerBacktrace* mozilla_sampler_get_b
   return new ProfilerBacktrace(t->GetBacktrace());
 }
 
 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)
 {
   mozilla_sampler_add_marker(aInfo, new ProfilerMarkerTracing(aCategory, aMetaData));
 }
 
 void mozilla_sampler_tracing(const char* aCategory, const char* aInfo,
                              ProfilerBacktrace* aCause,
--- a/tools/profiler/public/GeckoProfiler.h
+++ b/tools/profiler/public/GeckoProfiler.h
@@ -144,16 +144,17 @@ static inline void profiler_stop() {}
 // profiler without invalidating the JIT.
 static inline bool profiler_is_paused() { return false; }
 static inline void profiler_pause() {}
 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) {}
 
 static inline bool profiler_is_active() { return false; }
 
 // Check if an external profiler feature is active.
 // Supported:
--- a/tools/profiler/public/GeckoProfilerFunc.h
+++ b/tools/profiler/public/GeckoProfilerFunc.h
@@ -43,16 +43,17 @@ void mozilla_sampler_start(int aEntries,
 void mozilla_sampler_stop();
 
 bool mozilla_sampler_is_paused();
 void mozilla_sampler_pause();
 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();
 
 bool mozilla_sampler_feature_active(const char* aName);
 
 void mozilla_sampler_responsiveness(const mozilla::TimeStamp& time);
 
 void mozilla_sampler_frame_number(int frameNumber);
--- a/tools/profiler/public/GeckoProfilerImpl.h
+++ b/tools/profiler/public/GeckoProfilerImpl.h
@@ -117,16 +117,22 @@ ProfilerBacktrace* profiler_get_backtrac
 
 static inline
 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()
 {
   return mozilla_sampler_is_active();
 }
 
 static inline
 bool profiler_feature_active(const char* aName)
 {