Bug 1462784 - Change the enum ProfilingStackFrame::Category from a bitfield to a regular enum. r?njn draft
authorMarkus Stange <mstange@themasta.com>
Fri, 18 May 2018 17:06:13 -0400
changeset 803058 b2df33d865690da1decbadc4748729d06d2b190d
parent 803057 66f87c551f18e83f5b04f34c42d2feddbe4fd88c
child 803059 2202d40edc66466ba0a00bd2d585bfc7563cf755
push id112022
push userbmo:mstange@themasta.com
push dateFri, 01 Jun 2018 21:00:49 +0000
reviewersnjn
bugs1462784
milestone62.0a1
Bug 1462784 - Change the enum ProfilingStackFrame::Category from a bitfield to a regular enum. r?njn MozReview-Commit-ID: HmDu8Rri5AF
js/public/ProfilingStack.h
--- a/js/public/ProfilingStack.h
+++ b/js/public/ProfilingStack.h
@@ -140,18 +140,17 @@ class ProfilingStackFrame
     mozilla::Atomic<const char*, mozilla::ReleaseAcquire> dynamicString_;
 
     // Stack pointer for non-JS stack frames, the script pointer otherwise.
     mozilla::Atomic<void*, mozilla::ReleaseAcquire> spOrScript;
 
     // Line number for non-JS stack frames, the bytecode offset otherwise.
     mozilla::Atomic<int32_t, mozilla::ReleaseAcquire> lineOrPcOffset;
 
-    // Bits 0...1 hold the Kind. Bits 2...3 are unused. Bits 4...12 hold the
-    // Category.
+    // Bits 0...1 hold the Kind. Bits 2...31 hold the category.
     mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> kindAndCategory_;
 
     static int32_t pcToOffset(JSScript* aScript, jsbytecode* aPc);
 
   public:
     ProfilingStackFrame() = default;
     ProfilingStackFrame& operator=(const ProfilingStackFrame& other)
     {
@@ -180,39 +179,38 @@ class ProfilingStackFrame
         // A normal JS frame.
         JS_NORMAL = 2,
 
         // An interpreter JS frame that has OSR-ed into baseline. JS_NORMAL
         // frames can be converted to JS_OSR and back. JS_OSR frames are
         // ignored.
         JS_OSR = 3,
 
-        KIND_MASK = 0x3,
+        KIND_BITCOUNT = 2,
+        KIND_MASK = (1 << KIND_BITCOUNT) - 1
     };
 
     // Keep these in sync with devtools/client/performance/modules/categories.js
     enum class Category : uint32_t {
-        OTHER    = 1u << 4,
-        CSS      = 1u << 5,
-        JS       = 1u << 6,
-        GC       = 1u << 7,
-        CC       = 1u << 8,
-        NETWORK  = 1u << 9,
-        GRAPHICS = 1u << 10,
-        STORAGE  = 1u << 11,
-        EVENTS   = 1u << 12,
+        OTHER,
+        CSS,
+        JS,
+        GC,
+        CC,
+        NETWORK,
+        GRAPHICS,
+        STORAGE,
+        EVENTS,
 
         FIRST    = OTHER,
         LAST     = EVENTS,
-
-        CATEGORY_MASK = ~uint32_t(Kind::KIND_MASK),
     };
 
-    static_assert((uint32_t(Category::FIRST) & uint32_t(Kind::KIND_MASK)) == 0,
-                  "Category overlaps with Kind");
+    static_assert(uint32_t(Category::LAST) <= (UINT32_MAX >> uint32_t(Kind::KIND_BITCOUNT)),
+                  "Too many categories to fit into u32 with two bits reserved for the kind");
 
     bool isLabelFrame() const
     {
         return kind() == Kind::LABEL;
     }
 
     bool isSpMarkerFrame() const
     {
@@ -232,51 +230,51 @@ class ProfilingStackFrame
 
     void initLabelFrame(const char* aLabel, const char* aDynamicString, void* sp,
                         uint32_t aLine, Category aCategory)
     {
         label_ = aLabel;
         dynamicString_ = aDynamicString;
         spOrScript = sp;
         lineOrPcOffset = static_cast<int32_t>(aLine);
-        kindAndCategory_ = uint32_t(Kind::LABEL) | uint32_t(aCategory);
+        kindAndCategory_ = uint32_t(Kind::LABEL) | (uint32_t(aCategory) << uint32_t(Kind::KIND_BITCOUNT));
         MOZ_ASSERT(isLabelFrame());
     }
 
     void initSpMarkerFrame(void* sp)
     {
         label_ = "";
         dynamicString_ = nullptr;
         spOrScript = sp;
         lineOrPcOffset = 0;
-        kindAndCategory_ = uint32_t(Kind::SP_MARKER) | uint32_t(ProfilingStackFrame::Category::OTHER);
+        kindAndCategory_ = uint32_t(Kind::SP_MARKER) | (uint32_t(Category::OTHER) << uint32_t(Kind::KIND_BITCOUNT));
         MOZ_ASSERT(isSpMarkerFrame());
     }
 
     void initJsFrame(const char* aLabel, const char* aDynamicString, JSScript* aScript,
                      jsbytecode* aPc)
     {
         label_ = aLabel;
         dynamicString_ = aDynamicString;
         spOrScript = aScript;
         lineOrPcOffset = pcToOffset(aScript, aPc);
-        kindAndCategory_ = uint32_t(Kind::JS_NORMAL) | uint32_t(Category::JS);
+        kindAndCategory_ = uint32_t(Kind::JS_NORMAL) | (uint32_t(Category::JS) << uint32_t(Kind::KIND_BITCOUNT));
         MOZ_ASSERT(isJsFrame());
     }
 
     void setKind(Kind aKind) {
-        kindAndCategory_ = uint32_t(aKind) | uint32_t(category());
+        kindAndCategory_ = uint32_t(aKind) | (uint32_t(category()) << uint32_t(Kind::KIND_BITCOUNT));
     }
 
     Kind kind() const {
         return Kind(kindAndCategory_ & uint32_t(Kind::KIND_MASK));
     }
 
     Category category() const {
-        return Category(kindAndCategory_ & uint32_t(Category::CATEGORY_MASK));
+        return Category(kindAndCategory_ >> uint32_t(Kind::KIND_BITCOUNT));
     }
 
     void* stackAddress() const {
         MOZ_ASSERT(!isJsFrame());
         return spOrScript;
     }
 
     JS_PUBLIC_API(JSScript*) script() const;