Bug 1527673 - Implement name method on JS histogram objects r=chutten
☠☠ backed out by 8fd4c4971830 ☠ ☠
authorJan-Erik Rediger <jrediger@mozilla.com>
Thu, 28 Feb 2019 15:40:30 +0000
changeset 519644 083231da85284342d357e9dd57cd834db51ebb02
parent 519643 e865352417c9483eaf6d8e1315a49e33d12c9391
child 519645 c30839448f54026c2167e5a0c1a1826e127a3b4b
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerschutten
bugs1527673
milestone67.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 1527673 - Implement name method on JS histogram objects r=chutten Differential Revision: https://phabricator.services.mozilla.com/D21531
toolkit/components/telemetry/core/TelemetryHistogram.cpp
toolkit/components/telemetry/tests/unit/test_TelemetryHistograms.js
--- a/toolkit/components/telemetry/core/TelemetryHistogram.cpp
+++ b/toolkit/components/telemetry/core/TelemetryHistogram.cpp
@@ -1609,16 +1609,17 @@ void internal_ClearHistogram(const Stati
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //
 // PRIVATE: JSHistogram_* functions
 
 // NOTE: the functions in this section:
 //
 //   internal_JSHistogram_Add
+//   internal_JSHistogram_Name
 //   internal_JSHistogram_Snapshot
 //   internal_JSHistogram_Clear
 //   internal_WrapAndReturnHistogram
 //
 // all run without protection from |gTelemetryHistogramMutex|.  If they
 // held |gTelemetryHistogramMutex|, there would be the possibility of
 // deadlock because the JS_ calls that they make may call back into the
 // TelemetryHistogram interface, hence trying to re-acquire the mutex.
@@ -1817,16 +1818,38 @@ bool internal_JSHistogram_Add(JSContext*
     StaticMutexAutoLock locker(gTelemetryHistogramMutex);
     for (uint32_t aValue : values) {
       internal_Accumulate(locker, id, aValue);
     }
   }
   return true;
 }
 
+bool internal_JSHistogram_Name(JSContext* cx, unsigned argc, JS::Value* vp) {
+  JS::CallArgs args = CallArgsFromVp(argc, vp);
+
+  if (!args.thisv().isObject() ||
+      JS_GetClass(&args.thisv().toObject()) != &sJSHistogramClass) {
+    JS_ReportErrorASCII(cx, "Wrong JS class, expected JSHistogram class");
+    return false;
+  }
+
+  JSObject* obj = &args.thisv().toObject();
+  JSHistogramData* data = static_cast<JSHistogramData*>(JS_GetPrivate(obj));
+  MOZ_ASSERT(data);
+  HistogramID id = data->histogramId;
+  MOZ_ASSERT(internal_IsHistogramEnumId(id));
+  const char* name = gHistogramInfos[id].name();
+
+  auto cname = NS_ConvertASCIItoUTF16(name);
+  args.rval().setString(ToJSString(cx, cname));
+
+  return true;
+}
+
 /**
  * Extract the store name from JavaScript function arguments.
  * The first and only argument needs to be an object with a "store" property.
  * If no arguments are given it defaults to "main".
  */
 nsresult internal_JS_StoreFromObjectArgument(JSContext* cx,
                                              const JS::CallArgs& args,
                                              nsAutoString& aStoreName) {
@@ -1973,16 +1996,17 @@ nsresult internal_WrapAndReturnHistogram
   JS::Rooted<JSObject*> obj(cx, JS_NewObject(cx, &sJSHistogramClass));
   if (!obj) {
     return NS_ERROR_FAILURE;
   }
 
   // The 3 functions that are wrapped up here are eventually called
   // by the same thread that runs this function.
   if (!(JS_DefineFunction(cx, obj, "add", internal_JSHistogram_Add, 1, 0) &&
+        JS_DefineFunction(cx, obj, "name", internal_JSHistogram_Name, 1, 0) &&
         JS_DefineFunction(cx, obj, "snapshot", internal_JSHistogram_Snapshot, 1,
                           0) &&
         JS_DefineFunction(cx, obj, "clear", internal_JSHistogram_Clear, 1,
                           0))) {
     return NS_ERROR_FAILURE;
   }
 
   JSHistogramData* data = new JSHistogramData{id};
@@ -2008,16 +2032,17 @@ void internal_JSHistogram_finalize(JSFre
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //
 // PRIVATE: JSKeyedHistogram_* functions
 
 // NOTE: the functions in this section:
 //
 //   internal_JSKeyedHistogram_Add
+//   internal_JSKeyedHistogram_Name
 //   internal_JSKeyedHistogram_Keys
 //   internal_JSKeyedHistogram_Snapshot
 //   internal_JSKeyedHistogram_Clear
 //   internal_WrapAndReturnKeyedHistogram
 //
 // Same comments as above, at the JSHistogram_* section, regarding
 // deadlock avoidance, apply.
 
@@ -2163,16 +2188,39 @@ bool internal_JSKeyedHistogram_Add(JSCon
     StaticMutexAutoLock locker(gTelemetryHistogramMutex);
     for (uint32_t aValue : values) {
       internal_Accumulate(locker, id, NS_ConvertUTF16toUTF8(key), aValue);
     }
   }
   return true;
 }
 
+bool internal_JSKeyedHistogram_Name(JSContext* cx, unsigned argc,
+                                    JS::Value* vp) {
+  JS::CallArgs args = CallArgsFromVp(argc, vp);
+
+  if (!args.thisv().isObject() ||
+      JS_GetClass(&args.thisv().toObject()) != &sJSKeyedHistogramClass) {
+    JS_ReportErrorASCII(cx, "Wrong JS class, expected JSKeyedHistogram class");
+    return false;
+  }
+
+  JSObject* obj = &args.thisv().toObject();
+  JSHistogramData* data = static_cast<JSHistogramData*>(JS_GetPrivate(obj));
+  MOZ_ASSERT(data);
+  HistogramID id = data->histogramId;
+  MOZ_ASSERT(internal_IsHistogramEnumId(id));
+  const char* name = gHistogramInfos[id].name();
+
+  auto cname = NS_ConvertASCIItoUTF16(name);
+  args.rval().setString(ToJSString(cx, cname));
+
+  return true;
+}
+
 bool internal_JSKeyedHistogram_Keys(JSContext* cx, unsigned argc,
                                     JS::Value* vp) {
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
 
   if (!args.thisv().isObject() ||
       JS_GetClass(&args.thisv().toObject()) != &sJSKeyedHistogramClass) {
     JS_ReportErrorASCII(cx, "Wrong JS class, expected JSKeyedHistogram class");
     return false;
@@ -2291,16 +2339,18 @@ bool internal_JSKeyedHistogram_Clear(JSC
 nsresult internal_WrapAndReturnKeyedHistogram(
     HistogramID id, JSContext* cx, JS::MutableHandle<JS::Value> ret) {
   JS::Rooted<JSObject*> obj(cx, JS_NewObject(cx, &sJSKeyedHistogramClass));
   if (!obj) return NS_ERROR_FAILURE;
   // The 6 functions that are wrapped up here are eventually called
   // by the same thread that runs this function.
   if (!(JS_DefineFunction(cx, obj, "add", internal_JSKeyedHistogram_Add, 2,
                           0) &&
+        JS_DefineFunction(cx, obj, "name", internal_JSKeyedHistogram_Name, 1,
+                          0) &&
         JS_DefineFunction(cx, obj, "snapshot",
                           internal_JSKeyedHistogram_Snapshot, 1, 0) &&
         JS_DefineFunction(cx, obj, "keys", internal_JSKeyedHistogram_Keys, 1,
                           0) &&
         JS_DefineFunction(cx, obj, "clear", internal_JSKeyedHistogram_Clear, 1,
                           0))) {
     return NS_ERROR_FAILURE;
   }
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryHistograms.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryHistograms.js
@@ -1626,8 +1626,37 @@ add_task(async function test_can_record_
   // The socket and gpu processes should not have any histograms.
   // Flag and count histograms have defaults, so if we're accidentally recording them
   // in these processes they'd show up even immediately after being cleared.
   let snapshot = Telemetry.getSnapshotForHistograms("main", true);
 
   Assert.deepEqual(snapshot.gpu, {}, "No histograms should have been recorded for the gpu process");
   Assert.deepEqual(snapshot.socket, {}, "No histograms should have been recorded for the socket process");
 });
+
+add_task(function test_knows_its_name() {
+  let h;
+
+  // Plain histograms
+  const histNames = [
+    "TELEMETRY_TEST_FLAG",
+    "TELEMETRY_TEST_COUNT",
+    "TELEMETRY_TEST_CATEGORICAL",
+    "TELEMETRY_TEST_EXPIRED"
+  ];
+
+  for (let name of histNames) {
+    h = Telemetry.getHistogramById(name);
+    Assert.equal(name, h.name());
+  }
+
+  // Keyed histograms
+  const keyedHistNames = [
+    "TELEMETRY_TEST_KEYED_EXPONENTIAL",
+    "TELEMETRY_TEST_KEYED_BOOLEAN",
+    "TELEMETRY_TEST_EXPIRED_KEYED",
+  ];
+
+  for (let name of keyedHistNames) {
+    h = Telemetry.getKeyedHistogramById(name);
+    Assert.equal(name, h.name());
+  }
+})