Bug 1527673 - Implement name method on JS histogram objects r=chutten
authorJan-Erik Rediger <jrediger@mozilla.com>
Thu, 28 Feb 2019 18:44:43 +0000
changeset 519689 26e37344a1d9fb6f579c38e82e04341577ead9ad
parent 519688 f8e41c1ad7bab8f5586e6a910c08a114af8619a2
child 519690 f89aa19d37be3281be2ac835f1704746dfa68b2e
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());
+  }
+});