Bug 1013326 - Distinguish chrome and content scripts in pseudostack; r=snorp
authorJim Chen <nchen@mozilla.com>
Fri, 06 Jun 2014 18:39:40 -0400
changeset 206571 627405647ed00f6b0647426fe1545c1000253d2d
parent 206570 d904bd0d1cb5358eec4e5ac07b7ef4256c34012c
child 206572 9e19217a1042f52ce1f65f1d533911ac757b681d
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1013326
milestone32.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 1013326 - Distinguish chrome and content scripts in pseudostack; r=snorp
xpcom/threads/ThreadStackHelper.cpp
xpcom/threads/ThreadStackHelper.h
xpcom/threads/moz.build
--- a/xpcom/threads/ThreadStackHelper.cpp
+++ b/xpcom/threads/ThreadStackHelper.cpp
@@ -1,15 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ThreadStackHelper.h"
 #include "MainThreadUtils.h"
+#include "nsJSPrincipals.h"
+#include "nsScriptSecurityManager.h"
+#include "jsfriendapi.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Move.h"
 
 #ifdef XP_LINUX
 #include <unistd.h>
 #include <sys/syscall.h>
 #endif
@@ -203,16 +206,61 @@ ThreadStackHelper::PrepareStackBuffer(St
   mStackBuffer.clear();
   MOZ_ALWAYS_TRUE(mStackBuffer.reserve(mMaxStackSize));
   return true;
 #else
   return false;
 #endif
 }
 
+#ifdef MOZ_ENABLE_PROFILER_SPS
+
+namespace {
+
+bool
+IsChromeJSScript(JSScript* aScript)
+{
+  // May be called from another thread or inside a signal handler.
+  // We assume querying the script is safe but we must not manipulate it.
+
+  nsIScriptSecurityManager* const secman =
+    nsScriptSecurityManager::GetScriptSecurityManager();
+  NS_ENSURE_TRUE(secman, false);
+
+  JSPrincipals* const principals = JS_GetScriptPrincipals(aScript);
+  return secman->IsSystemPrincipal(nsJSPrincipals::get(principals));
+}
+
+} // namespace
+
+const char*
+ThreadStackHelper::AppendJSEntry(const volatile StackEntry* aEntry,
+                                 const char* aPrevLabel)
+{
+  // May be called from another thread or inside a signal handler.
+  // We assume querying the script is safe but we must not manupulate it.
+  MOZ_ASSERT(aEntry->isJs());
+  MOZ_ASSERT(aEntry->script());
+
+  const char* label;
+  if (IsChromeJSScript(aEntry->script())) {
+    label = "(chrome script)";
+  } else {
+    label = "(content script)";
+  }
+
+  if (label == aPrevLabel) {
+    return aPrevLabel;
+  }
+  mStackBuffer.infallibleAppend(label);
+  return label;
+}
+
+#endif // MOZ_ENABLE_PROFILER_SPS
+
 void
 ThreadStackHelper::FillStackBuffer()
 {
 #ifdef MOZ_ENABLE_PROFILER_SPS
   size_t reservedSize = mMaxStackSize;
 
   // Go from front to back
   const volatile StackEntry* entry = mPseudoStack->mStack;
@@ -220,16 +268,20 @@ ThreadStackHelper::FillStackBuffer()
   // Deduplicate identical, consecutive frames
   const char* prevLabel = nullptr;
   for (; reservedSize-- && entry != end; entry++) {
     /* We only accept non-copy labels, because
        we are unable to actually copy labels here */
     if (entry->isCopyLabel()) {
       continue;
     }
+    if (entry->isJs()) {
+      prevLabel = AppendJSEntry(entry, prevLabel);
+      continue;
+    }
     const char* const label = entry->label();
     if (label == prevLabel) {
       continue;
     }
     mStackBuffer.infallibleAppend(label);
     prevLabel = label;
   }
   // If we exited early due to buffer size, expand the buffer for next time
--- a/xpcom/threads/ThreadStackHelper.h
+++ b/xpcom/threads/ThreadStackHelper.h
@@ -43,16 +43,20 @@ private:
 #ifdef MOZ_ENABLE_PROFILER_SPS
   const PseudoStack* const mPseudoStack;
 #endif
   Stack mStackBuffer;
   size_t mMaxStackSize;
 
   bool PrepareStackBuffer(Stack& aStack);
   void FillStackBuffer();
+#ifdef MOZ_ENABLE_PROFILER_SPS
+  const char* AppendJSEntry(const volatile StackEntry* aEntry,
+                            const char* aPrevLabel);
+#endif
 
 public:
   /**
    * Initialize ThreadStackHelper. Must be called from main thread.
    */
   static void Startup();
   /**
    * Uninitialize ThreadStackHelper. Must be called from main thread.
--- a/xpcom/threads/moz.build
+++ b/xpcom/threads/moz.build
@@ -49,15 +49,16 @@ UNIFIED_SOURCES += [
     'ThreadStackHelper.cpp',
     'TimerThread.cpp',
 ]
 
 MSVC_ENABLE_PGO = True
 
 LOCAL_INCLUDES += [
     '../build',
+    '/caps/include',
 ]
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'xpcom_core'
 
 include('/ipc/chromium/chromium-config.mozbuild')