bug 1498165 - Plumb the Scalar Store name down to the storage layer. r=janerik
authorChris H-C <chutten@mozilla.com>
Tue, 20 Nov 2018 19:57:48 +0000
changeset 503796 893aaa718e6fe4ba847498d65154cf1b961cf59e
parent 503795 5dabc51178c6ad0a4a83ca9c22387c49d645553f
child 503797 8db1d9f8025cc1b3b82134f7a6c59a6cfdeced2a
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjanerik
bugs1498165
milestone65.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 1498165 - Plumb the Scalar Store name down to the storage layer. r=janerik MozReview-Commit-ID: 5T9TZ5AgKci Differential Revision: https://phabricator.services.mozilla.com/D12127
toolkit/components/telemetry/core/ScalarInfo.h
toolkit/components/telemetry/core/Telemetry.cpp
toolkit/components/telemetry/core/TelemetryScalar.cpp
toolkit/components/telemetry/core/TelemetryScalar.h
toolkit/components/telemetry/core/nsITelemetry.idl
--- a/toolkit/components/telemetry/core/ScalarInfo.h
+++ b/toolkit/components/telemetry/core/ScalarInfo.h
@@ -61,16 +61,18 @@ struct ScalarInfo : BaseScalarInfo {
   ScalarInfo(uint32_t aKind, uint32_t aNameOffset, uint32_t aExpirationOffset,
              uint32_t aDataset,
              mozilla::Telemetry::Common::RecordedProcessType aRecordInProcess,
              bool aKeyed, mozilla::Telemetry::Common::SupportedProduct aProducts,
              uint32_t aStoreCount,  uint16_t aStoreOffset)
     : BaseScalarInfo(aKind, aDataset, aRecordInProcess, aKeyed, aProducts)
     , name_offset(aNameOffset)
     , expiration_offset(aExpirationOffset)
+    , store_count(aStoreCount)
+    , store_offset(aStoreOffset)
   {}
 
   const char *name() const override;
   const char *expiration() const override;
 };
 
 } // namespace
 
--- a/toolkit/components/telemetry/core/Telemetry.cpp
+++ b/toolkit/components/telemetry/core/Telemetry.cpp
@@ -651,30 +651,32 @@ TelemetryImpl::GetSnapshotForScalars(con
                                      bool aClearStore,
                                      bool aFilterTest,
                                      JSContext* aCx,
                                      JS::MutableHandleValue aResult)
 {
   unsigned int dataset = mCanRecordExtended ?
     nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN :
     nsITelemetry::DATASET_RELEASE_CHANNEL_OPTOUT;
-  return TelemetryScalar::CreateSnapshots(dataset, aClearStore, aCx, 1, aResult, aFilterTest);
+  return TelemetryScalar::CreateSnapshots(dataset, aClearStore, aCx, 1, aResult,
+                                          aFilterTest, aStoreName);
 }
 
 NS_IMETHODIMP
 TelemetryImpl::GetSnapshotForKeyedScalars(const nsACString& aStoreName,
                                           bool aClearStore,
                                           bool aFilterTest,
                                           JSContext* aCx,
                                           JS::MutableHandleValue aResult)
 {
   unsigned int dataset = mCanRecordExtended ?
     nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN :
     nsITelemetry::DATASET_RELEASE_CHANNEL_OPTOUT;
-  return TelemetryScalar::CreateKeyedSnapshots(dataset, aClearStore, aCx, 1, aResult, aFilterTest);
+  return TelemetryScalar::CreateKeyedSnapshots(dataset, aClearStore, aCx, 1,
+                                               aResult, aFilterTest, aStoreName);
 }
 
 NS_IMETHODIMP
 TelemetryImpl::SnapshotHistograms(unsigned int aDataset,
                                   bool aClearHistograms, JSContext* aCx,
                                   JS::MutableHandleValue aResult)
 {
   return TelemetryHistogram::CreateHistogramSnapshots(aCx, aResult, aDataset,
@@ -1721,17 +1723,19 @@ TelemetryImpl::ScalarSetMaximum(const ns
 {
   return TelemetryScalar::SetMaximum(aName, aVal, aCx);
 }
 
 NS_IMETHODIMP
 TelemetryImpl::SnapshotScalars(unsigned int aDataset, bool aClearScalars, JSContext* aCx,
                                uint8_t optional_argc, JS::MutableHandleValue aResult)
 {
-  return TelemetryScalar::CreateSnapshots(aDataset, aClearScalars, aCx, optional_argc, aResult);
+  return TelemetryScalar::CreateSnapshots(aDataset, aClearScalars, aCx,
+                                          optional_argc, aResult, false,
+                                          NS_LITERAL_CSTRING("main"));
 }
 
 NS_IMETHODIMP
 TelemetryImpl::KeyedScalarAdd(const nsACString& aName, const nsAString& aKey,
                               JS::HandleValue aVal, JSContext* aCx)
 {
   return TelemetryScalar::Add(aName, aKey, aVal, aCx);
 }
@@ -1750,17 +1754,18 @@ TelemetryImpl::KeyedScalarSetMaximum(con
   return TelemetryScalar::SetMaximum(aName, aKey, aVal, aCx);
 }
 
 NS_IMETHODIMP
 TelemetryImpl::SnapshotKeyedScalars(unsigned int aDataset, bool aClearScalars, JSContext* aCx,
                                     uint8_t optional_argc, JS::MutableHandleValue aResult)
 {
   return TelemetryScalar::CreateKeyedSnapshots(aDataset, aClearScalars, aCx, optional_argc,
-                                               aResult);
+                                               aResult, false,
+                                               NS_LITERAL_CSTRING("main"));
 }
 
 NS_IMETHODIMP
 TelemetryImpl::RegisterScalars(const nsACString& aCategoryName,
                                JS::Handle<JS::Value> aScalarData,
                                JSContext* cx)
 {
   return TelemetryScalar::RegisterScalars(aCategoryName, aScalarData, false, cx);
--- a/toolkit/components/telemetry/core/TelemetryScalar.cpp
+++ b/toolkit/components/telemetry/core/TelemetryScalar.cpp
@@ -341,17 +341,17 @@ public:
   // Convenience methods used by the C++ API.
   virtual void SetValue(uint32_t aValue) { mozilla::Unused << HandleUnsupported(); }
   virtual ScalarResult SetValue(const nsAString& aValue) { return HandleUnsupported(); }
   virtual void SetValue(bool aValue) { mozilla::Unused << HandleUnsupported(); }
   virtual void AddValue(uint32_t aValue) { mozilla::Unused << HandleUnsupported(); }
   virtual void SetMaximum(uint32_t aValue) { mozilla::Unused << HandleUnsupported(); }
 
   // GetValue is used to get the value of the scalar when persisting it to JS.
-  virtual nsresult GetValue(nsCOMPtr<nsIVariant>& aResult) const = 0;
+  virtual nsresult GetValue(const nsACString& aStoreName, nsCOMPtr<nsIVariant>& aResult) const = 0;
 
   // To measure the memory stats.
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const = 0;
 
 private:
   ScalarResult HandleUnsupported() const;
 };
 
@@ -374,17 +374,17 @@ public:
   ~ScalarUnsigned() override = default;
 
   ScalarResult SetValue(nsIVariant* aValue) final;
   void SetValue(uint32_t aValue) final;
   ScalarResult AddValue(nsIVariant* aValue) final;
   void AddValue(uint32_t aValue) final;
   ScalarResult SetMaximum(nsIVariant* aValue) final;
   void SetMaximum(uint32_t aValue) final;
-  nsresult GetValue(nsCOMPtr<nsIVariant>& aResult) const final;
+  nsresult GetValue(const nsACString& aStoreName, nsCOMPtr<nsIVariant>& aResult) const final;
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
 
 private:
   uint32_t mStorage;
 
   ScalarResult CheckInput(nsIVariant* aValue);
 
   // Prevent copying.
@@ -458,17 +458,17 @@ void
 ScalarUnsigned::SetMaximum(uint32_t aValue)
 {
   if (aValue > mStorage) {
     mStorage = aValue;
   }
 }
 
 nsresult
-ScalarUnsigned::GetValue(nsCOMPtr<nsIVariant>& aResult) const
+ScalarUnsigned::GetValue(const nsACString& aStoreName, nsCOMPtr<nsIVariant>& aResult) const
 {
   nsCOMPtr<nsIWritableVariant> outVar(new nsVariant());
   nsresult rv = outVar->SetAsUint32(mStorage);
   if (NS_FAILED(rv)) {
     return rv;
   }
   aResult = outVar.forget();
   return NS_OK;
@@ -509,17 +509,17 @@ class ScalarString : public ScalarBase
 public:
   using ScalarBase::SetValue;
 
   ScalarString() : mStorage(EmptyString()) {};
   ~ScalarString() override = default;
 
   ScalarResult SetValue(nsIVariant* aValue) final;
   ScalarResult SetValue(const nsAString& aValue) final;
-  nsresult GetValue(nsCOMPtr<nsIVariant>& aResult) const final;
+  nsresult GetValue(const nsACString& aStoreName, nsCOMPtr<nsIVariant>& aResult) const final;
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
 
 private:
   nsString mStorage;
 
   // Prevent copying.
   ScalarString(const ScalarString& aOther) = delete;
   void operator=(const ScalarString& aOther) = delete;
@@ -556,17 +556,17 @@ ScalarString::SetValue(const nsAString& 
   mStorage = Substring(aValue, 0, kMaximumStringValueLength);
   if (aValue.Length() > kMaximumStringValueLength) {
     return ScalarResult::StringTooLong;
   }
   return ScalarResult::Ok;
 }
 
 nsresult
-ScalarString::GetValue(nsCOMPtr<nsIVariant>& aResult) const
+ScalarString::GetValue(const nsACString& aStoreName, nsCOMPtr<nsIVariant>& aResult) const
 {
   nsCOMPtr<nsIWritableVariant> outVar(new nsVariant());
   nsresult rv = outVar->SetAsAString(mStorage);
   if (NS_FAILED(rv)) {
     return rv;
   }
   aResult = outVar.forget();
   return NS_OK;
@@ -588,17 +588,17 @@ class ScalarBoolean : public ScalarBase
 public:
   using ScalarBase::SetValue;
 
   ScalarBoolean() : mStorage(false) {};
   ~ScalarBoolean() override = default;
 
   ScalarResult SetValue(nsIVariant* aValue) final;
   void SetValue(bool aValue) final;
-  nsresult GetValue(nsCOMPtr<nsIVariant>& aResult) const final;
+  nsresult GetValue(const nsACString& aStoreName, nsCOMPtr<nsIVariant>& aResult) const final;
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
 
 private:
   bool mStorage;
 
   // Prevent copying.
   ScalarBoolean(const ScalarBoolean& aOther) = delete;
   void operator=(const ScalarBoolean& aOther) = delete;
@@ -629,17 +629,17 @@ ScalarBoolean::SetValue(nsIVariant* aVal
 
 void
 ScalarBoolean::SetValue(bool aValue)
 {
   mStorage = aValue;
 }
 
 nsresult
-ScalarBoolean::GetValue(nsCOMPtr<nsIVariant>& aResult) const
+ScalarBoolean::GetValue(const nsACString& aStoreName, nsCOMPtr<nsIVariant>& aResult) const
 {
   nsCOMPtr<nsIWritableVariant> outVar(new nsVariant());
   nsresult rv = outVar->SetAsBool(mStorage);
   if (NS_FAILED(rv)) {
     return rv;
   }
   aResult = outVar.forget();
   return NS_OK;
@@ -701,17 +701,17 @@ public:
   // Convenience methods used by the C++ API.
   void SetValue(const StaticMutexAutoLock& locker, const nsAString& aKey, uint32_t aValue);
   void SetValue(const StaticMutexAutoLock& locker, const nsAString& aKey, bool aValue);
   void AddValue(const StaticMutexAutoLock& locker, const nsAString& aKey, uint32_t aValue);
   void SetMaximum(const StaticMutexAutoLock& locker, const nsAString& aKey, uint32_t aValue);
 
   // GetValue is used to get the key-value pairs stored in the keyed scalar
   // when persisting it to JS.
-  nsresult GetValue(nsTArray<KeyValuePair>& aValues) const;
+  nsresult GetValue(const nsACString& aStoreName, nsTArray<KeyValuePair>& aValues) const;
 
   // To measure the memory stats.
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
   // To permit more keys than normal.
   void SetMaximumNumberOfKeys(uint32_t aMaximumNumberOfKeys)
   {
     mMaximumNumberOfKeys = aMaximumNumberOfKeys;
@@ -834,24 +834,24 @@ KeyedScalar::SetMaximum(const StaticMute
 /**
  * Get a key-value array with the values for the Keyed Scalar.
  * @param aValue The array that will hold the key-value pairs.
  * @return {nsresult} NS_OK or an error value as reported by the
  *         the specific scalar objects implementations (e.g.
  *         ScalarUnsigned).
  */
 nsresult
-KeyedScalar::GetValue(nsTArray<KeyValuePair>& aValues) const
+KeyedScalar::GetValue(const nsACString& aStoreName, nsTArray<KeyValuePair>& aValues) const
 {
   for (auto iter = mScalarKeys.ConstIter(); !iter.Done(); iter.Next()) {
     ScalarBase* scalar = static_cast<ScalarBase*>(iter.Data());
 
     // Get the scalar value.
     nsCOMPtr<nsIVariant> scalarValue;
-    nsresult rv = scalar->GetValue(scalarValue);
+    nsresult rv = scalar->GetValue(aStoreName, scalarValue);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     // Append it to value list.
     aValues.AppendElement(mozilla::MakePair(nsCString(iter.Key()), scalarValue));
   }
 
@@ -1786,17 +1786,19 @@ internal_RegisterScalars(const StaticMut
  * @param {aIsBuiltinDynamic} Whether or not the storage is for dynamic builtin scalars.
  * @return NS_OK or the error code describing the failure reason.
  */
 nsresult
 internal_ScalarSnapshotter(const StaticMutexAutoLock& aLock,
                            ScalarSnapshotTable& aScalarsToReflect,
                            unsigned int aDataset,
                            ProcessesScalarsMapType& aProcessStorage,
-                           bool aIsBuiltinDynamic)
+                           bool aIsBuiltinDynamic,
+                           bool aClearScalars,
+                           const nsACString& aStoreName)
 {
   // Iterate the scalars in aProcessStorage. The storage may contain empty or yet to be
   // initialized scalars from all the supported processes.
   for (auto iter = aProcessStorage.Iter(); !iter.Done(); iter.Next()) {
     ScalarStorageMapType* scalarStorage = static_cast<ScalarStorageMapType*>(iter.Data());
     ScalarTupleArray& processScalars = aScalarsToReflect.GetOrInsert(iter.Key());
 
     // Are we in the "Dynamic" process?
@@ -1810,17 +1812,17 @@ internal_ScalarSnapshotter(const StaticM
       const BaseScalarInfo& info =
         internal_GetScalarInfo(aLock, ScalarKey{childIter.Key(),
                                aIsBuiltinDynamic ? true : isDynamicProcess});
 
       // Serialize the scalar if it's in the desired dataset.
       if (IsInDataset(info.dataset, aDataset)) {
         // Get the scalar value.
         nsCOMPtr<nsIVariant> scalarValue;
-        nsresult rv = scalar->GetValue(scalarValue);
+        nsresult rv = scalar->GetValue(aStoreName, scalarValue);
         if (NS_FAILED(rv)) {
           return rv;
         }
         // Append it to our list.
         processScalars.AppendElement(mozilla::MakeTuple(info.name(), scalarValue, info.kind));
       }
     }
   }
@@ -1836,17 +1838,19 @@ internal_ScalarSnapshotter(const StaticM
  * @param {aIsBuiltinDynamic} Whether or not the storage is for dynamic builtin scalars.
  * @return NS_OK or the error code describing the failure reason.
  */
 nsresult
 internal_KeyedScalarSnapshotter(const StaticMutexAutoLock& aLock,
                                 KeyedScalarSnapshotTable& aScalarsToReflect,
                                 unsigned int aDataset,
                                 ProcessesKeyedScalarsMapType& aProcessStorage,
-                                bool aIsBuiltinDynamic)
+                                bool aIsBuiltinDynamic,
+                                bool aClearScalars,
+                                const nsACString& aStoreName)
 {
   // Iterate the scalars in aProcessStorage. The storage may contain empty or yet
   // to be initialized scalars from all the supported processes.
   for (auto iter = aProcessStorage.Iter(); !iter.Done(); iter.Next()) {
     KeyedScalarStorageMapType* scalarStorage =
       static_cast<KeyedScalarStorageMapType*>(iter.Data());
     KeyedScalarTupleArray& processScalars = aScalarsToReflect.GetOrInsert(iter.Key());
 
@@ -1860,17 +1864,17 @@ internal_KeyedScalarSnapshotter(const St
       const BaseScalarInfo& info =
         internal_GetScalarInfo(aLock, ScalarKey{childIter.Key(),
                                aIsBuiltinDynamic ? true : isDynamicProcess});
 
       // Serialize the scalar if it's in the desired dataset.
       if (IsInDataset(info.dataset, aDataset)) {
         // Get the keys for this scalar.
         nsTArray<KeyedScalar::KeyValuePair> scalarKeyedData;
-        nsresult rv = scalar->GetValue(scalarKeyedData);
+        nsresult rv = scalar->GetValue(aStoreName, scalarKeyedData);
         if (NS_FAILED(rv)) {
           return rv;
         }
         // Append it to our list.
         processScalars.AppendElement(
           mozilla::MakeTuple(info.name(), scalarKeyedData, info.kind));
       }
     }
@@ -1880,39 +1884,45 @@ internal_KeyedScalarSnapshotter(const St
 
 /**
  * Helper function to get a snapshot of the scalars.
  *
  * @param {aLock} The proof of lock to access scalar data.
  * @param {aScalarsToReflect} The table that will contain the snapshot.
  * @param {aDataset} The dataset we're asking the snapshot for.
  * @param {aClearScalars} Whether or not to clear the scalar storage.
+ * @param {aStoreName} The name of the store to snapshot.
  * @return NS_OK or the error code describing the failure reason.
  */
 nsresult
 internal_GetScalarSnapshot(const StaticMutexAutoLock& aLock,
                            ScalarSnapshotTable& aScalarsToReflect,
-                           unsigned int aDataset, bool aClearScalars)
+                           unsigned int aDataset, bool aClearScalars,
+                           const nsACString& aStoreName)
 {
   // Take a snapshot of the scalars.
   nsresult rv = internal_ScalarSnapshotter(aLock,
                                            aScalarsToReflect,
                                            aDataset,
                                            gScalarStorageMap,
-                                           false /*aIsBuiltinDynamic*/);
+                                           false, /*aIsBuiltinDynamic*/
+                                           aClearScalars,
+                                           aStoreName);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // And a snapshot of the dynamic builtin ones.
   rv = internal_ScalarSnapshotter(aLock,
                                   aScalarsToReflect,
                                   aDataset,
                                   gDynamicBuiltinScalarStorageMap,
-                                  true /*aIsBuiltinDynamic*/);
+                                  true, /*aIsBuiltinDynamic*/
+                                  aClearScalars,
+                                  aStoreName);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (aClearScalars) {
     // The map already takes care of freeing the allocated memory.
     gScalarStorageMap.Clear();
     gDynamicBuiltinScalarStorageMap.Clear();
@@ -1923,39 +1933,45 @@ internal_GetScalarSnapshot(const StaticM
 
 /**
  * Helper function to get a snapshot of the keyed scalars.
  *
  * @param {aLock} The proof of lock to access scalar data.
  * @param {aScalarsToReflect} The table that will contain the snapshot.
  * @param {aDataset} The dataset we're asking the snapshot for.
  * @param {aClearScalars} Whether or not to clear the scalar storage.
+ * @param {aStoreName} The name of the store to snapshot.
  * @return NS_OK or the error code describing the failure reason.
  */
 nsresult
 internal_GetKeyedScalarSnapshot(const StaticMutexAutoLock& aLock,
                                 KeyedScalarSnapshotTable& aScalarsToReflect,
-                                unsigned int aDataset, bool aClearScalars)
+                                unsigned int aDataset, bool aClearScalars,
+                                const nsACString& aStoreName)
 {
   // Take a snapshot of the scalars.
   nsresult rv = internal_KeyedScalarSnapshotter(aLock,
                                                 aScalarsToReflect,
                                                 aDataset,
                                                 gKeyedScalarStorageMap,
-                                                false /*aIsBuiltinDynamic*/);
+                                                false, /*aIsBuiltinDynamic*/
+                                                aClearScalars,
+                                                aStoreName);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // And a snapshot of the dynamic builtin ones.
   rv = internal_KeyedScalarSnapshotter(aLock,
                                        aScalarsToReflect,
                                        aDataset,
                                        gDynamicBuiltinKeyedScalarStorageMap,
-                                       true /*aIsBuiltinDynamic*/);
+                                       true, /*aIsBuiltinDynamic*/
+                                       aClearScalars,
+                                       aStoreName);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (aClearScalars) {
     // The map already takes care of freeing the allocated memory.
     gKeyedScalarStorageMap.Clear();
     gDynamicBuiltinKeyedScalarStorageMap.Clear();
@@ -2962,27 +2978,20 @@ TelemetryScalar::SetMaximum(mozilla::Tel
                                               &scalar);
   if (NS_FAILED(rv)) {
     return;
   }
 
   scalar->SetMaximum(locker, aKey, aValue);
 }
 
-/**
- * Serializes the scalars from the given dataset to a json-style object and resets them.
- * The returned structure looks like:
- *    {"process": {"category1.probe":1,"category1.other_probe":false,...}, ... }.
- *
- * @param aDataset DATASET_RELEASE_CHANNEL_OPTOUT or DATASET_RELEASE_CHANNEL_OPTIN.
- * @param aClear Whether to clear out the scalars after snapshotting.
- */
 nsresult
 TelemetryScalar::CreateSnapshots(unsigned int aDataset, bool aClearScalars, JSContext* aCx,
-                                 uint8_t optional_argc, JS::MutableHandle<JS::Value> aResult, bool aFilterTest)
+                                 uint8_t optional_argc, JS::MutableHandle<JS::Value> aResult,
+                                 bool aFilterTest, const nsACString& aStoreName)
 {
   MOZ_ASSERT(XRE_IsParentProcess(),
              "Snapshotting scalars should only happen in the parent processes.");
   // If no arguments were passed in, apply the default value.
   if (!optional_argc) {
     aClearScalars = false;
   }
 
@@ -2998,17 +3007,18 @@ TelemetryScalar::CreateSnapshots(unsigne
   }
 
   // Only lock the mutex while accessing our data, without locking any JS related code.
   ScalarSnapshotTable scalarsToReflect;
   {
     StaticMutexAutoLock locker(gTelemetryScalarsMutex);
 
     nsresult rv =
-      internal_GetScalarSnapshot(locker, scalarsToReflect, aDataset, aClearScalars);
+      internal_GetScalarSnapshot(locker, scalarsToReflect, aDataset,
+                                 aClearScalars, aStoreName);
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
 
   // Reflect it to JS.
   for (auto iter = scalarsToReflect.Iter(); !iter.Done(); iter.Next()) {
     ScalarTupleArray& processScalars = iter.Data();
@@ -3043,28 +3053,20 @@ TelemetryScalar::CreateSnapshots(unsigne
         return NS_ERROR_FAILURE;
       }
     }
   }
 
   return NS_OK;
 }
 
-/**
- * Serializes the scalars from the given dataset to a json-style object and resets them.
- * The returned structure looks like:
- *   { "process": { "category1.probe": { "key_1": 2, "key_2": 1, ... }, ... }, ... }
- *
- * @param aDataset DATASET_RELEASE_CHANNEL_OPTOUT or DATASET_RELEASE_CHANNEL_OPTIN.
- * @param aClear Whether to clear out the keyed scalars after snapshotting.
- */
 nsresult
 TelemetryScalar::CreateKeyedSnapshots(unsigned int aDataset, bool aClearScalars, JSContext* aCx,
                                       uint8_t optional_argc, JS::MutableHandle<JS::Value> aResult,
-                                      bool aFilterTest)
+                                      bool aFilterTest, const nsACString& aStoreName)
 {
   MOZ_ASSERT(XRE_IsParentProcess(),
              "Snapshotting scalars should only happen in the parent processes.");
   // If no arguments were passed in, apply the default value.
   if (!optional_argc) {
     aClearScalars = false;
   }
 
@@ -3080,17 +3082,18 @@ TelemetryScalar::CreateKeyedSnapshots(un
   }
 
   // Only lock the mutex while accessing our data, without locking any JS related code.
   KeyedScalarSnapshotTable scalarsToReflect;
   {
     StaticMutexAutoLock locker(gTelemetryScalarsMutex);
 
     nsresult rv =
-      internal_GetKeyedScalarSnapshot(locker, scalarsToReflect, aDataset, aClearScalars);
+      internal_GetKeyedScalarSnapshot(locker, scalarsToReflect, aDataset,
+                                      aClearScalars, aStoreName);
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
 
   // Reflect it to JS.
   for (auto iter = scalarsToReflect.Iter(); !iter.Done(); iter.Next()) {
     KeyedScalarTupleArray& processScalars = iter.Data();
@@ -3536,17 +3539,18 @@ TelemetryScalar::SerializeScalars(mozill
   ScalarSnapshotTable scalarsToReflect;
   {
     StaticMutexAutoLock locker(gTelemetryScalarsMutex);
     // For persistence, we care about all the datasets. Worst case, they
     // will be empty.
     nsresult rv = internal_GetScalarSnapshot(locker,
                                              scalarsToReflect,
                                              nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN,
-                                             false /*aClearScalars*/);
+                                             false, /*aClearScalars*/
+                                             NS_LITERAL_CSTRING("main"));
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
 
   // Persist the scalars to the JSON object.
   for (auto iter = scalarsToReflect.Iter(); !iter.Done(); iter.Next()) {
     ScalarTupleArray& processScalars = iter.Data();
@@ -3587,17 +3591,18 @@ TelemetryScalar::SerializeKeyedScalars(m
   KeyedScalarSnapshotTable keyedScalarsToReflect;
   {
     StaticMutexAutoLock locker(gTelemetryScalarsMutex);
     // For persistence, we care about all the datasets. Worst case, they
     // will be empty.
     nsresult rv = internal_GetKeyedScalarSnapshot(locker,
                                          keyedScalarsToReflect,
                                          nsITelemetry::DATASET_RELEASE_CHANNEL_OPTIN,
-                                         false /*aClearScalars*/);
+                                         false, /*aClearScalars*/
+                                         NS_LITERAL_CSTRING("main"));
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
 
   // Persist the scalars to the JSON object.
   for (auto iter = keyedScalarsToReflect.Iter(); !iter.Done(); iter.Next()) {
     KeyedScalarTupleArray& processScalars = iter.Data();
--- a/toolkit/components/telemetry/core/TelemetryScalar.h
+++ b/toolkit/components/telemetry/core/TelemetryScalar.h
@@ -36,28 +36,30 @@ void SetCanRecordBase(bool b);
 void SetCanRecordExtended(bool b);
 
 // JS API Endpoints.
 nsresult Add(const nsACString& aName, JS::HandleValue aVal, JSContext* aCx);
 nsresult Set(const nsACString& aName, JS::HandleValue aVal, JSContext* aCx);
 nsresult SetMaximum(const nsACString& aName, JS::HandleValue aVal, JSContext* aCx);
 nsresult CreateSnapshots(unsigned int aDataset, bool aClearScalars,
                          JSContext* aCx, uint8_t optional_argc,
-                         JS::MutableHandle<JS::Value> aResult, bool aFilterTest=false);
+                         JS::MutableHandle<JS::Value> aResult, bool aFilterTest,
+                         const nsACString& aStoreName);
 
 // Keyed JS API Endpoints.
 nsresult Add(const nsACString& aName, const nsAString& aKey, JS::HandleValue aVal,
              JSContext* aCx);
 nsresult Set(const nsACString& aName, const nsAString& aKey, JS::HandleValue aVal,
              JSContext* aCx);
 nsresult SetMaximum(const nsACString& aName, const nsAString& aKey, JS::HandleValue aVal,
                     JSContext* aCx);
 nsresult CreateKeyedSnapshots(unsigned int aDataset, bool aClearScalars,
                               JSContext* aCx, uint8_t optional_argc,
-                              JS::MutableHandle<JS::Value> aResult, bool aFilterTest=false);
+                              JS::MutableHandle<JS::Value> aResult, bool aFilterTest,
+                              const nsACString& aStoreName);
 
 // C++ API Endpoints.
 void Add(mozilla::Telemetry::ScalarID aId, uint32_t aValue);
 void Set(mozilla::Telemetry::ScalarID aId, uint32_t aValue);
 void Set(mozilla::Telemetry::ScalarID aId, const nsAString& aValue);
 void Set(mozilla::Telemetry::ScalarID aId, bool aValue);
 void SetMaximum(mozilla::Telemetry::ScalarID aId, uint32_t aValue);
 
--- a/toolkit/components/telemetry/core/nsITelemetry.idl
+++ b/toolkit/components/telemetry/core/nsITelemetry.idl
@@ -87,31 +87,31 @@ interface nsITelemetry : nsISupports
   [implicit_jscontext]
   jsval getSnapshotForKeyedHistograms(in ACString aStoreName, in boolean aClearStore, [optional] in boolean aFilterTest);
 
   /**
    * Serializes the scalars from the given store to a JSON-style object.
    * The returned structure looks like:
    *   { "process": { "category1.probe": 1,"category1.other_probe": false, ... }, ... }.
    *
-   * @param aStoreName The name of the store to snapshot. Ignored at the moment.
+   * @param aStoreName The name of the store to snapshot. Something like "main".
    * @param aClearStore Whether to clear out the scalars in the named store after snapshotting.
    * @param aFilterTest If true, `telemetry.test` scalars will be filtered out.
                         Filtered scalars are still cleared if `aClearStore` is true.
    *                    Defaults to false.
    */
   [implicit_jscontext]
   jsval getSnapshotForScalars(in ACString aStoreName, in boolean aClearStore, [optional] in boolean aFilterTest);
 
   /**
    * Serializes the keyed scalars from the given store to a JSON-style object.
    * The returned structure looks like:
    *   { "process": { "category1.probe": { "key_1": 2, "key_2": 1, ... }, ... }, ... }
    *
-   * @param aStoreName The name of the store to snapshot. Ignored at the moment.
+   * @param aStoreName The name of the store to snapshot. Something like "main".
    * @param aClearStore Whether to clear out the keyed scalars in the named store after snapshotting.
    * @param aFilterTest If true, `telemetry.test` scalars will be filtered out.
                         Filtered scalars are still cleared if `aClearStore` is true.
    *                    Defaults to false.
    */
   [implicit_jscontext]
   jsval getSnapshotForKeyedScalars(in ACString aStoreName, in boolean aClearStore, [optional] in boolean aFilterTest);