Bug 1555798 - Use a scalar name copy instead of a &BaseScalarInfo r=Dexter a=jcristau
authorChris H-C <chutten@mozilla.com>
Fri, 31 May 2019 13:36:27 +0000
changeset 533572 c18af2278a4d3027bdbfc07454e99c6611862377
parent 533571 3d9d20f173e3c76e1f4adfa703d2c3b09ddff7d8
child 533573 83245ccc42c043747164a97773095fd61632beae
push id11361
push usermalexandru@mozilla.com
push dateMon, 03 Jun 2019 15:38:07 +0000
treeherdermozilla-beta@b9e525d8b1aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersDexter, jcristau
bugs1555798
milestone68.0
Bug 1555798 - Use a scalar name copy instead of a &BaseScalarInfo r=Dexter a=jcristau References to ScalarInfo objects are stable for all scalars registered at compile-time, but not for those registered at runtime. Differential Revision: https://phabricator.services.mozilla.com/D33274
toolkit/components/telemetry/core/TelemetryScalar.cpp
--- a/toolkit/components/telemetry/core/TelemetryScalar.cpp
+++ b/toolkit/components/telemetry/core/TelemetryScalar.cpp
@@ -822,17 +822,17 @@ ScalarBase* internal_ScalarAllocate(cons
 /**
  * The implementation for the keyed scalar type.
  */
 class KeyedScalar {
  public:
   typedef mozilla::Pair<nsCString, nsCOMPtr<nsIVariant>> KeyValuePair;
 
   explicit KeyedScalar(const BaseScalarInfo& info)
-      : mScalarInfo(info), mMaximumNumberOfKeys(kMaximumNumberOfKeys){};
+      : mScalarName(info.name()), mMaximumNumberOfKeys(kMaximumNumberOfKeys){};
   ~KeyedScalar() = default;
 
   // Set, Add and SetMaximum functions as described in the Telemetry IDL.
   // These methods implicitly instantiate a Scalar[*] for each key.
   ScalarResult SetValue(const StaticMutexAutoLock& locker,
                         const nsAString& aKey, nsIVariant* aValue);
   ScalarResult AddValue(const StaticMutexAutoLock& locker,
                         const nsAString& aKey, nsIVariant* aValue);
@@ -860,18 +860,18 @@ class KeyedScalar {
   // To permit more keys than normal.
   void SetMaximumNumberOfKeys(uint32_t aMaximumNumberOfKeys) {
     mMaximumNumberOfKeys = aMaximumNumberOfKeys;
   };
 
  private:
   typedef nsClassHashtable<nsCStringHashKey, ScalarBase> ScalarKeysMapType;
 
+  const nsCString mScalarName;
   ScalarKeysMapType mScalarKeys;
-  const BaseScalarInfo& mScalarInfo;
   uint32_t mMaximumNumberOfKeys;
 
   ScalarResult GetScalarForKey(const StaticMutexAutoLock& locker,
                                const nsAString& aKey, ScalarBase** aRet);
 };
 
 ScalarResult KeyedScalar::SetValue(const StaticMutexAutoLock& locker,
                                    const nsAString& aKey, nsIVariant* aValue) {
@@ -1007,16 +1007,20 @@ nsresult KeyedScalar::GetValue(const nsA
 }
 
 // Forward declaration
 nsresult internal_GetKeyedScalarByEnum(const StaticMutexAutoLock& lock,
                                        const ScalarKey& aId,
                                        ProcessID aProcessStorage,
                                        KeyedScalar** aRet);
 
+// Forward declaration
+nsresult internal_GetEnumByScalarName(const StaticMutexAutoLock& lock,
+                                      const nsACString& aName, ScalarKey* aId);
+
 /**
  * Get the scalar for the referenced key.
  * If there's no such key, instantiate a new Scalar object with the
  * same type of the Keyed scalar and create the key.
  */
 ScalarResult KeyedScalar::GetScalarForKey(const StaticMutexAutoLock& locker,
                                           const nsAString& aKey,
                                           ScalarBase** aRet) {
@@ -1031,16 +1035,24 @@ ScalarResult KeyedScalar::GetScalarForKe
   NS_ConvertUTF16toUTF8 utf8Key(aKey);
 
   ScalarBase* scalar = nullptr;
   if (mScalarKeys.Get(utf8Key, &scalar)) {
     *aRet = scalar;
     return ScalarResult::Ok;
   }
 
+  ScalarKey uniqueId;
+  nsresult rv = internal_GetEnumByScalarName(locker, mScalarName, &uniqueId);
+  if (NS_FAILED(rv)) {
+    return (rv == NS_ERROR_FAILURE) ? ScalarResult::NotInitialized
+                                    : ScalarResult::UnknownScalar;
+  }
+
+  const BaseScalarInfo& info = internal_GetScalarInfo(locker, uniqueId);
   if (mScalarKeys.Count() >= mMaximumNumberOfKeys) {
     if (aKey.EqualsLiteral("telemetry.keyed_scalars_exceed_limit")) {
       return ScalarResult::TooManyKeys;
     }
 
     KeyedScalar* scalarExceed = nullptr;
 
     ScalarKey uniqueId{
@@ -1051,23 +1063,22 @@ ScalarResult KeyedScalar::GetScalarForKe
     ProcessID process = ProcessID::Parent;
     nsresult rv =
         internal_GetKeyedScalarByEnum(locker, uniqueId, process, &scalarExceed);
 
     if (NS_FAILED(rv)) {
       return ScalarResult::TooManyKeys;
     }
 
-    scalarExceed->AddValue(locker, NS_ConvertUTF8toUTF16(mScalarInfo.name()),
-                           1);
+    scalarExceed->AddValue(locker, NS_ConvertUTF8toUTF16(info.name()), 1);
 
     return ScalarResult::TooManyKeys;
   }
 
-  scalar = internal_ScalarAllocate(mScalarInfo);
+  scalar = internal_ScalarAllocate(info);
   if (!scalar) {
     return ScalarResult::InvalidType;
   }
 
   mScalarKeys.Put(utf8Key, scalar);
 
   *aRet = scalar;
   return ScalarResult::Ok;