Bug 1429904 - Use a Variant to split the FrameKey members into two groups. r?njn draft
authorMarkus Stange <mstange@themasta.com>
Tue, 27 Feb 2018 23:44:02 -0500
changeset 762105 77f286312bdedb30404b79a03e7a2305d60988f5
parent 762104 2597f6b7180d88b46e79460c8557ca2445bd8566
child 762106 6b145704aed3deaafa8460c6f4067f6547613f4d
push id101088
push userbmo:mstange@themasta.com
push dateThu, 01 Mar 2018 20:52:26 +0000
reviewersnjn
bugs1429904
milestone60.0a1
Bug 1429904 - Use a Variant to split the FrameKey members into two groups. r?njn This makes it clear which combinations of fields are possible. MozReview-Commit-ID: C3PriO7nWsJ
tools/profiler/core/ProfileBufferEntry.cpp
tools/profiler/core/ProfileBufferEntry.h
--- a/tools/profiler/core/ProfileBufferEntry.cpp
+++ b/tools/profiler/core/ProfileBufferEntry.cpp
@@ -256,25 +256,16 @@ UniqueJSONStrings::GetOrAddIndex(const c
   }
 
   index = mStringToIndexMap.Count();
   mStringToIndexMap.Put(str, index);
   mStringTableWriter.StringElement(aStr);
   return index;
 }
 
-bool UniqueStacks::FrameKey::operator==(const FrameKey& aOther) const
-{
-  return mLocation == aOther.mLocation &&
-         mLine == aOther.mLine &&
-         mCategory == aOther.mCategory &&
-         mJITAddress == aOther.mJITAddress &&
-         mJITDepth == aOther.mJITDepth;
-}
-
 UniqueStacks::StackKey
 UniqueStacks::BeginStack(const FrameKey& aFrame)
 {
   return StackKey(GetOrAddFrameIndex(aFrame));
 }
 
 UniqueStacks::StackKey
 UniqueStacks::AppendFrame(const StackKey& aStack, const FrameKey& aFrame)
@@ -286,33 +277,50 @@ uint32_t
 UniqueStacks::JITAddress::Hash() const
 {
   uint32_t hash = 0;
   hash = AddToHash(hash, mAddress);
   hash = AddToHash(hash, mStreamingGen);
   return hash;
 }
 
-uint32_t UniqueStacks::FrameKey::Hash() const
+bool
+UniqueStacks::FrameKey::NormalFrameData::operator==(const NormalFrameData& aOther) const
+{
+  return mLocation == aOther.mLocation &&
+         mLine == aOther.mLine &&
+         mCategory == aOther.mCategory;
+}
+
+bool
+UniqueStacks::FrameKey::JITFrameData::operator==(const JITFrameData& aOther) const
+{
+  return mAddress == aOther.mAddress &&
+         mDepth == aOther.mDepth;
+}
+
+uint32_t
+UniqueStacks::FrameKey::Hash() const
 {
   uint32_t hash = 0;
-  if (!mLocation.IsEmpty()) {
-    hash = HashString(mLocation.get());
-  }
-  if (mLine.isSome()) {
-    hash = AddToHash(hash, *mLine);
-  }
-  if (mCategory.isSome()) {
-    hash = AddToHash(hash, *mCategory);
-  }
-  if (mJITAddress.isSome()) {
-    hash = AddToHash(hash, mJITAddress->Hash());
-    if (mJITDepth.isSome()) {
-      hash = AddToHash(hash, *mJITDepth);
+  if (mData.is<NormalFrameData>()) {
+    const NormalFrameData& data = mData.as<NormalFrameData>();
+    if (!data.mLocation.IsEmpty()) {
+      hash = AddToHash(hash, HashString(data.mLocation.get()));
+    }
+    if (data.mLine.isSome()) {
+      hash = AddToHash(hash, *data.mLine);
     }
+    if (data.mCategory.isSome()) {
+      hash = AddToHash(hash, *data.mCategory);
+    }
+  } else {
+    const JITFrameData& data = mData.as<JITFrameData>();
+    hash = AddToHash(hash, data.mAddress.Hash());
+    hash = AddToHash(hash, data.mDepth);
   }
   return hash;
 }
 
 UniqueStacks::UniqueStacks()
 {
   mFrameTableWriter.StartBareList();
   mStackTableWriter.StartBareList();
@@ -412,32 +420,35 @@ void UniqueStacks::StreamStack(const Sta
     writer.IntElement(PREFIX, *aStack.mPrefixStackIndex);
   }
   writer.IntElement(FRAME, aStack.mFrameIndex);
 }
 
 void
 UniqueStacks::StreamNonJITFrame(const FrameKey& aFrame)
 {
+  using NormalFrameData = FrameKey::NormalFrameData;
+
   enum Schema : uint32_t {
     LOCATION = 0,
     IMPLEMENTATION = 1,
     OPTIMIZATIONS = 2,
     LINE = 3,
     CATEGORY = 4
   };
 
   AutoArraySchemaWriter writer(mFrameTableWriter, mUniqueStrings);
 
-  writer.StringElement(LOCATION, aFrame.mLocation.get());
-  if (aFrame.mLine.isSome()) {
-    writer.IntElement(LINE, *aFrame.mLine);
+  const NormalFrameData& data = aFrame.mData.as<NormalFrameData>();
+  writer.StringElement(LOCATION, data.mLocation.get());
+  if (data.mLine.isSome()) {
+    writer.IntElement(LINE, *data.mLine);
   }
-  if (aFrame.mCategory.isSome()) {
-    writer.IntElement(CATEGORY, *aFrame.mCategory);
+  if (data.mCategory.isSome()) {
+    writer.IntElement(CATEGORY, *data.mCategory);
   }
 }
 
 static void
 StreamJITFrameOptimizations(SpliceableJSONWriter& aWriter,
                             UniqueJSONStrings& aUniqueStrings,
                             JSContext* aContext,
                             const JS::ProfiledFrameHandle& aJITFrame)
--- a/tools/profiler/core/ProfileBufferEntry.h
+++ b/tools/profiler/core/ProfileBufferEntry.h
@@ -20,16 +20,17 @@
 #include "nsHashKeys.h"
 #include "nsDataHashtable.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/Vector.h"
 #include "gtest/MozGtestFriend.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/UniquePtr.h"
 #include "nsClassHashtable.h"
+#include "mozilla/Variant.h"
 
 class ProfilerMarker;
 
 #define FOR_EACH_PROFILE_BUFFER_ENTRY_KIND(macro) \
   macro(Category,              int) \
   macro(CollectionStart,       double) \
   macro(CollectionEnd,         double) \
   macro(Label,                 const char*) \
@@ -165,45 +166,52 @@ public:
     bool operator==(const JITAddress& aRhs) const
     {
       return mAddress == aRhs.mAddress && mStreamingGen == aRhs.mStreamingGen;
     }
     bool operator!=(const JITAddress& aRhs) const { return !(*this == aRhs); }
   };
 
   struct FrameKey {
-    const nsCString mLocation;
-    const mozilla::Maybe<unsigned> mLine;
-    const mozilla::Maybe<unsigned> mCategory;
-    const mozilla::Maybe<JITAddress> mJITAddress;
-    const mozilla::Maybe<uint32_t> mJITDepth;
-
     explicit FrameKey(const char* aLocation)
-     : mLocation(aLocation)
+      : mData(NormalFrameData{
+                nsCString(aLocation), mozilla::Nothing(), mozilla::Nothing() })
     {
     }
 
     FrameKey(const char* aLocation, const mozilla::Maybe<unsigned>& aLine,
              const mozilla::Maybe<unsigned>& aCategory)
-     : mLocation(aLocation)
-     , mLine(aLine)
-     , mCategory(aCategory)
+      : mData(NormalFrameData{ nsCString(aLocation), aLine, aCategory })
     {
     }
 
     FrameKey(const JITAddress& aJITAddress, uint32_t aJITDepth)
-     : mJITAddress(mozilla::Some(aJITAddress))
-     , mJITDepth(mozilla::Some(aJITDepth))
+      : mData(JITFrameData{ aJITAddress, aJITDepth })
     {
     }
 
     FrameKey(const FrameKey& aToCopy) = default;
 
     uint32_t Hash() const;
-    bool operator==(const FrameKey& aOther) const;
+    bool operator==(const FrameKey& aOther) const { return mData == aOther.mData; }
+
+    struct NormalFrameData {
+      bool operator==(const NormalFrameData& aOther) const;
+
+      nsCString mLocation;
+      mozilla::Maybe<unsigned> mLine;
+      mozilla::Maybe<unsigned> mCategory;
+    };
+    struct JITFrameData {
+      bool operator==(const JITFrameData& aOther) const;
+
+      JITAddress mAddress;
+      uint32_t mDepth;
+    };
+    mozilla::Variant<NormalFrameData, JITFrameData> mData;
   };
 
   struct StackKey {
     mozilla::Maybe<uint32_t> mPrefixStackIndex;
     uint32_t mFrameIndex;
 
     explicit StackKey(uint32_t aFrame)
      : mFrameIndex(aFrame)