Bug 1342070 - Part 0: Add API to tell Profile Timeline Recording state to JS engine. r=till,tromey
authorTooru Fujisawa <arai_a@mac.com>
Tue, 17 Apr 2018 14:59:56 +0200
changeset 414098 8ebe4719c2414dc32568d67a2889c48adb686031
parent 414097 a5aa0c6be992161aa110cfe91ad813a81a81767f
child 414099 c2d33789539668305c1e8ac2d65a05a590c8a548
push id33858
push userncsoregi@mozilla.com
push dateTue, 17 Apr 2018 21:55:44 +0000
treeherdermozilla-central@d6eb5597d744 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill, tromey
bugs1342070
milestone61.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 1342070 - Part 0: Add API to tell Profile Timeline Recording state to JS engine. r=till,tromey
docshell/base/timeline/TimelineConsumers.cpp
js/src/jsapi.cpp
js/src/jsapi.h
--- a/docshell/base/timeline/TimelineConsumers.cpp
+++ b/docshell/base/timeline/TimelineConsumers.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "TimelineConsumers.h"
 
 #include "mozilla/ClearOnShutdown.h"
+#include "jsapi.h"
 #include "nsAppRunner.h" // for XRE_IsContentProcess, XRE_IsParentProcess
 #include "nsDocShell.h"
 
 namespace mozilla {
 
 NS_IMPL_ISUPPORTS(TimelineConsumers, nsIObserver);
 
 StaticMutex TimelineConsumers::sMutex;
@@ -121,16 +122,19 @@ void
 TimelineConsumers::AddConsumer(nsDocShell* aDocShell)
 {
   MOZ_ASSERT(NS_IsMainThread());
   StaticMutexAutoLock lock(sMutex); // for `mActiveConsumers` and `mMarkersStores`.
 
   UniquePtr<ObservedDocShell>& observed = aDocShell->mObserved;
   MOZ_ASSERT(!observed);
 
+  if (mActiveConsumers == 0) {
+    JS::SetProfileTimelineRecordingEnabled(true);
+  }
   mActiveConsumers++;
 
   ObservedDocShell* obsDocShell = new ObservedDocShell(aDocShell);
   MarkersStorage* storage = static_cast<MarkersStorage*>(obsDocShell);
 
   observed.reset(obsDocShell);
   mMarkersStores.insertFront(storage);
 }
@@ -140,16 +144,19 @@ TimelineConsumers::RemoveConsumer(nsDocS
 {
   MOZ_ASSERT(NS_IsMainThread());
   StaticMutexAutoLock lock(sMutex); // for `mActiveConsumers` and `mMarkersStores`.
 
   UniquePtr<ObservedDocShell>& observed = aDocShell->mObserved;
   MOZ_ASSERT(observed);
 
   mActiveConsumers--;
+  if (mActiveConsumers == 0) {
+    JS::SetProfileTimelineRecordingEnabled(false);
+  }
 
   // Clear all markers from the `mTimelineMarkers` store.
   observed.get()->ClearMarkers();
   // Remove self from the `mMarkersStores` store.
   observed.get()->remove();
   // Prepare for becoming a consumer later.
   observed.reset(nullptr);
 }
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1334,16 +1334,30 @@ JS::detail::ComputeThis(JSContext* cx, V
     MutableHandleValue thisv = MutableHandleValue::fromMarkedLocation(&vp[1]);
     if (!BoxNonStrictThis(cx, thisv, thisv))
         return false;
 
     thisObject.set(&thisv.toObject());
     return true;
 }
 
+static bool gProfileTimelineRecordingEnabled = false;
+
+JS_PUBLIC_API(void)
+JS::SetProfileTimelineRecordingEnabled(bool enabled)
+{
+    gProfileTimelineRecordingEnabled = enabled;
+}
+
+JS_PUBLIC_API(bool)
+JS::IsProfileTimelineRecordingEnabled()
+{
+    return gProfileTimelineRecordingEnabled;
+}
+
 JS_PUBLIC_API(void*)
 JS_malloc(JSContext* cx, size_t nbytes)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     return static_cast<void*>(cx->zone()->pod_malloc<uint8_t>(nbytes));
 }
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1497,16 +1497,32 @@ JS_InitReflectParse(JSContext* cx, JS::H
  */
 extern JS_PUBLIC_API(bool)
 JS_DefineProfilingFunctions(JSContext* cx, JS::HandleObject obj);
 
 /* Defined in vm/Debugger.cpp. */
 extern JS_PUBLIC_API(bool)
 JS_DefineDebuggerObject(JSContext* cx, JS::HandleObject obj);
 
+namespace JS {
+
+/**
+ * Tell JS engine whether Profile Timeline Recording is enabled or not.
+ * If Profile Timeline Recording is enabled, data shown there like stack won't
+ * be optimized out.
+ * This is global state and not associated with specific runtime or context.
+ */
+extern JS_PUBLIC_API(void)
+SetProfileTimelineRecordingEnabled(bool enabled);
+
+extern JS_PUBLIC_API(bool)
+IsProfileTimelineRecordingEnabled();
+
+} // namespace JS
+
 #ifdef JS_HAS_CTYPES
 /**
  * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
  * object will be sealed.
  */
 extern JS_PUBLIC_API(bool)
 JS_InitCTypesClass(JSContext* cx, JS::HandleObject global);