Bug 1429904 - Use a Variant to split the FrameKey members into two groups. r=njn
authorMarkus Stange <mstange@themasta.com>
Tue, 27 Feb 2018 23:44:02 -0500
changeset 461206 5438aa8b248a59a16e14c961bb32f33d90c218d7
parent 461205 c072bfec3cd0e6edc11c7b17ea0a73f45487d4e5
child 461207 099e70b23f74d675e95df652d74a1dbaf29339e2
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1429904
milestone60.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 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)