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
--- 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)