Bug 1586921 - Collect chrome function names in BHR stacks, r=dthayer.
authorFlorian Quèze <florian@queze.net>
Thu, 29 Apr 2021 10:16:30 +0000
changeset 577970 2d4979717658a7736dc3a649ae008a41bce32e2d
parent 577969 e3c38425f7bec2ed038ad035259595adc850b633
child 577971 62137fbc81cf8fcc9339a6ac4af4a887c2815ef6
push id142181
push userfqueze@mozilla.com
push dateThu, 29 Apr 2021 10:18:55 +0000
treeherderautoland@2d4979717658 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdthayer
bugs1586921
milestone90.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 1586921 - Collect chrome function names in BHR stacks, r=dthayer. Differential Revision: https://phabricator.services.mozilla.com/D113649
js/public/ProfilingStack.h
js/src/vm/GeckoProfiler.cpp
toolkit/components/backgroundhangmonitor/ThreadStackHelper.cpp
--- a/js/public/ProfilingStack.h
+++ b/js/public/ProfilingStack.h
@@ -323,16 +323,18 @@ class ProfilingStackFrame {
 
   void* stackAddress() const {
     MOZ_ASSERT(!isJsFrame());
     return spOrScript;
   }
 
   JS_PUBLIC_API JSScript* script() const;
 
+  JS_PUBLIC_API JSFunction* function() const;
+
   // Note that the pointer returned might be invalid.
   JSScript* rawScript() const {
     MOZ_ASSERT(isJsFrame());
     void* script = spOrScript;
     return static_cast<JSScript*>(script);
   }
 
   // We can't know the layout of JSScript, so look in vm/GeckoProfiler.cpp.
--- a/js/src/vm/GeckoProfiler.cpp
+++ b/js/src/vm/GeckoProfiler.cpp
@@ -455,16 +455,21 @@ JS_PUBLIC_API JSScript* ProfilingStackFr
   if (!cx->isProfilerSamplingEnabled()) {
     return nullptr;
   }
 
   MOZ_ASSERT(!IsForwarded(script));
   return script;
 }
 
+JS_PUBLIC_API JSFunction* ProfilingStackFrame::function() const {
+  JSScript* script = this->script();
+  return script ? script->function() : nullptr;
+}
+
 JS_FRIEND_API jsbytecode* ProfilingStackFrame::pc() const {
   MOZ_ASSERT(isJsFrame());
   if (pcOffsetIfJS_ == NullPCOffset) {
     return nullptr;
   }
 
   JSScript* script = this->script();
   return script ? script->offsetToPC(pcOffsetIfJS_) : nullptr;
--- a/toolkit/components/backgroundhangmonitor/ThreadStackHelper.cpp
+++ b/toolkit/components/backgroundhangmonitor/ThreadStackHelper.cpp
@@ -322,18 +322,29 @@ void ThreadStackHelper::CollectProfiling
   if (!IsChromeJSScript(aFrame.script())) {
     TryAppendFrame(HangEntryContent());
     return;
   }
 
   // Rather than using the profiler's dynamic string, we compute our own string.
   // This is because we want to do some size-saving strategies, and throw out
   // information which won't help us as much.
-  // XXX: We currently don't collect the function name which hung.
   const char* filename = JS_GetScriptFilename(aFrame.script());
+
+  nsAutoCString funcName;
+  JSFunction* func = aFrame.function();
+  if (func) {
+    JSString* str = JS_GetFunctionDisplayId(func);
+    if (str) {
+      JSLinearString* linear = JS_ASSERT_STRING_IS_LINEAR(str);
+      AssignJSLinearString(funcName, linear);
+      funcName.AppendLiteral(" ");
+    }
+  }
+
   unsigned lineno = JS_PCToLineNumber(aFrame.script(), aFrame.pc());
 
   // Some script names are in the form "foo -> bar -> baz".
   // Here we find the origin of these redirected scripts.
   const char* basename = GetPathAfterComponent(filename, " -> ");
   if (basename) {
     filename = basename;
   }
@@ -354,18 +365,19 @@ void ThreadStackHelper::CollectProfiling
     basename = basename ? basename + 1 : filename;
     // Look for Windows path separator as well.
     filename = strrchr(basename, '\\');
     if (filename) {
       basename = filename + 1;
     }
   }
 
-  char buffer[128];  // Enough to fit longest js file name from the tree
-  size_t len = SprintfLiteral(buffer, "%s:%u", basename, lineno);
+  char buffer[256];  // Enough to fit our longest js function and file names.
+  size_t len =
+      SprintfLiteral(buffer, "%s%s:%u", funcName.get(), basename, lineno);
   if (len > sizeof(buffer)) {
     buffer[sizeof(buffer) - 1] = kTruncationIndicator;
     len = sizeof(buffer);
   }
   if (MaybeAppendDynamicStackFrame(Span(buffer, len))) {
     return;
   }