Bug 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum
authorGerald Squelart <gsquelart@mozilla.com>
Fri, 28 Jun 2019 07:12:54 +0000
changeset 543319 03db1aa367a2cfb3beca68cfcaecc1e1070108cd
parent 543318 9af3c0c1ede04cac77a598d0e0b1dcf991292610
child 543320 6f075fcdd821896ec9af08f65ca881a3c1dc524f
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgregtatum
bugs1552063
milestone69.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 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum PowerOfTwo stores a power of 2 value, i.e., 2^N. PowerOfTwoMask stores a mask corresponding to a power of 2, i.e., 2^N-1. These should be used in places where a power of 2 (or its mask) is stored or expected. `% PowerOfTwo{,Mask}` and `& PowerOfTwoMask` operations are optimal. MakePowerOfTwo{,Mask}<T, Value>() may be used to create statically-checked constants. {,Make}PowerOfTwo{,Mask}{32,64} shortcuts for common 32- and 64-bit types. Differential Revision: https://phabricator.services.mozilla.com/D36026
mozglue/baseprofiler/moz.build
mozglue/baseprofiler/public/PowerOfTwo.h
mozglue/tests/TestBaseProfiler.cpp
--- a/mozglue/baseprofiler/moz.build
+++ b/mozglue/baseprofiler/moz.build
@@ -78,16 +78,17 @@ if CONFIG['MOZ_GECKO_PROFILER']:
 # in non-MOZ_GECKO_PROFILER builds, and they only contains no-op macros in that
 # case.
 EXPORTS += [
     'public/BaseProfiler.h',
 ]
 
 EXPORTS.mozilla += [
     'public/BaseProfilerCounts.h',
+    'public/PowerOfTwo.h',
 ]
 
 if CONFIG['MOZ_VTUNE']:
     DEFINES['MOZ_VTUNE_INSTRUMENTATION'] = True
     UNIFIED_SOURCES += [
         'core/VTuneProfiler.cpp',
     ]
 
new file mode 100644
--- /dev/null
+++ b/mozglue/baseprofiler/public/PowerOfTwo.h
@@ -0,0 +1,322 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// PowerOfTwo is a value type that always hold a power of 2.
+// It has the same size as their underlying unsigned type, but offer the
+// guarantee of being a power of 2, which permits some optimizations when
+// involved in modulo operations (using masking instead of actual modulo).
+//
+// PowerOfTwoMask contains a mask corresponding to a power of 2.
+// E.g., 2^8 is 256 or 0x100, the corresponding mask is 2^8-1 or 255 or 0xFF.
+// It should be used instead of PowerOfTwo in situations where most operations
+// would be modulo, this saves having to recompute the mask from the stored
+// power of 2.
+//
+// One common use would be for ring-buffer containers with a power-of-2 size,
+// where an index is usually converted to an in-buffer offset by `i % size`.
+// Instead, the container could store a PowerOfTwo or PowerOfTwoMask, and do
+// `i % p2` or `i & p2m`, which is more efficient than for arbitrary sizes.
+//
+// Shortcuts for common 32- and 64-bit values: PowerOfTwo32, etc.
+//
+// To create constexpr constants, use MakePowerOfTwo<Type, Value>(), etc.
+
+#ifndef PowerOfTwo_h
+#define PowerOfTwo_h
+
+#include "mozilla/MathAlgorithms.h"
+
+#include <limits>
+
+namespace mozilla {
+
+// Compute the smallest power of 2 greater than or equal to aInput, except if
+// that would overflow in which case the highest possible power of 2 if chosen.
+// 0->1, 1->1, 2->2, 3->4, ... 2^31->2^31, 2^31+1->2^31 (for uint32_t), etc.
+template <typename T>
+T FriendlyRoundUpPow2(T aInput) {
+  // This is the same code as `RoundUpPow2()`, except we handle any type (that
+  // CeilingLog2 supports) and allow the greater-than-max-power case.
+  constexpr T max = T(1) << (sizeof(T) * CHAR_BIT - 1);
+  if (aInput >= max) {
+    return max;
+  }
+  return T(1) << CeilingLog2(aInput);
+}
+
+namespace detail {
+// Same function name `CountLeadingZeroes` with uint32_t and uint64_t overloads.
+inline uint_fast8_t CountLeadingZeroes(uint32_t aValue) {
+  MOZ_ASSERT(aValue != 0);
+  return detail::CountLeadingZeroes32(aValue);
+}
+inline uint_fast8_t CountLeadingZeroes(uint64_t aValue) {
+  MOZ_ASSERT(aValue != 0);
+  return detail::CountLeadingZeroes64(aValue);
+}
+// Refuse anything else.
+template <typename T>
+inline uint_fast8_t CountLeadingZeroes(T aValue) = delete;
+}  // namespace detail
+
+// Compute the smallest 2^N-1 mask where aInput can fit.
+// I.e., `x & mask == x`, but `x & (mask >> 1) != x`.
+// Or looking at binary, we want a mask with as many leading zeroes as the
+// input, by right-shifting a full mask: (8-bit examples)
+// input:          00000000    00000001   00000010  00010110  01111111 10000000
+// N leading 0s:   ^^^^^^^^ 8  ^^^^^^^ 7  ^^^^^^ 6  ^^^ 3     ^ 1      0
+// full mask:      11111111    11111111   11111111  11111111  11111111 11111111
+// full mask >> N: 00000000    00000001   00000011  00011111  01111111 11111111
+template <typename T>
+T RoundUpPow2Mask(T aInput) {
+  // Special case, as CountLeadingZeroes(0) is undefined. (And even if that was
+  // defined, shifting by the full type size is also undefined!)
+  if (aInput == 0) {
+    return 0;
+  }
+  return T(-1) >> detail::CountLeadingZeroes(aInput);
+}
+
+template <typename T>
+class PowerOfTwoMask;
+
+template <typename T, T Mask>
+constexpr PowerOfTwoMask<T> MakePowerOfTwoMask();
+
+template <typename T>
+class PowerOfTwo;
+
+template <typename T, T Value>
+constexpr PowerOfTwo<T> MakePowerOfTwo();
+
+// PowerOfTwoMask will always contain a mask for a power of 2, which is useful
+// for power-of-2 modulo operations (e.g., to keep an index inside a power-of-2
+// container).
+// Use this instead of PowerOfTwo if masking is the primary use of the value.
+//
+// Note that this class can store a "full" mask where all bits are set, so it
+// works for mask corresponding to the power of 2 that would overflow `T`
+// (e.g., 2^32 for uint32_t gives a mask of 2^32-1, which fits in a uint32_t).
+// For this reason there is no API that computes the power of 2 corresponding to
+// the mask; But this can be done explicitly with `MaskValue() + 1`, which may
+// be useful for computing things like distance-to-the-end by doing
+// `MaskValue() + 1 - offset`, which works fine with unsigned number types.
+template <typename T>
+class PowerOfTwoMask {
+  static_assert(!std::numeric_limits<T>::is_signed,
+                "PowerOfTwoMask must use an unsigned type");
+
+ public:
+  // Construct a power of 2 mask where the given value can fit.
+  // Cannot be constexpr because of `RoundUpPow2Mask()`.
+  explicit PowerOfTwoMask(T aInput) : mMask(RoundUpPow2Mask(aInput)) {}
+
+  // Compute the mask corresponding to a PowerOfTwo.
+  // This saves having to compute the nearest 2^N-1.
+  // Not a conversion constructor, as that could be ambiguous whether we'd want
+  // the mask corresponding to the power of 2 (2^N -> 2^N-1), or the mask that
+  // can *contain* the PowerOfTwo value (2^N -> 2^(N+1)-1).
+  // Note: Not offering reverse PowerOfTwoMark-to-PowerOfTwo conversion, because
+  // that could result in an unexpected 0 result for the largest possible mask.
+  template <typename U>
+  static constexpr PowerOfTwoMask<U> MaskForPowerOfTwo(
+      const PowerOfTwo<U>& aP2) {
+    return PowerOfTwoMask(aP2);
+  }
+
+  // Allow smaller unsigned types as input.
+  // Bigger or signed types must be explicitly converted by the caller.
+  template <typename U>
+  explicit constexpr PowerOfTwoMask(U aInput)
+      : mMask(RoundUpPow2Mask(static_cast<T>(aInput))) {
+    static_assert(!std::numeric_limits<T>::is_signed,
+                  "PowerOfTwoMask does not accept signed types");
+    static_assert(sizeof(U) <= sizeof(T),
+                  "PowerOfTwoMask does not accept bigger types");
+  }
+
+  constexpr T MaskValue() const { return mMask; }
+
+  // `x & aPowerOfTwoMask` just works.
+  template <typename U>
+  friend U operator&(U aNumber, PowerOfTwoMask aP2M) {
+    return static_cast<U>(aNumber & aP2M.MaskValue());
+  }
+
+  // `aPowerOfTwoMask & x` just works.
+  template <typename U>
+  friend constexpr U operator&(PowerOfTwoMask aP2M, U aNumber) {
+    return static_cast<U>(aP2M.MaskValue() & aNumber);
+  }
+
+  // `x % aPowerOfTwoMask(2^N-1)` is equivalent to `x % 2^N` but is more
+  // optimal by doing `x & (2^N-1)`.
+  // Useful for templated code doing modulo with a template argument type.
+  template <typename U>
+  friend constexpr U operator%(U aNumerator, PowerOfTwoMask aDenominator) {
+    return aNumerator & aDenominator.MaskValue();
+  }
+
+  constexpr bool operator==(const PowerOfTwoMask& aRhs) const {
+    return mMask == aRhs.mMask;
+  }
+  constexpr bool operator!=(const PowerOfTwoMask& aRhs) const {
+    return mMask != aRhs.mMask;
+  }
+
+ private:
+  // Trust `PowerOfTwo` to call the private Trusted constructor below.
+  friend class PowerOfTwo<T>;
+
+  // Trust `MakePowerOfTwoMask()` to call the private Trusted constructor below.
+  template <typename U, U Mask>
+  friend constexpr PowerOfTwoMask<U> MakePowerOfTwoMask();
+
+  struct Trusted {
+    T mMask;
+  };
+  // Construct the mask corresponding to a PowerOfTwo.
+  // This saves having to compute the nearest 2^N-1.
+  // Note: Not a public PowerOfTwo->PowerOfTwoMask conversion constructor, as
+  // that could be ambiguous whether we'd want the mask corresponding to the
+  // power of 2 (2^N -> 2^N-1), or the mask that can *contain* the PowerOfTwo
+  // value (2^N -> 2^(N+1)-1).
+  explicit constexpr PowerOfTwoMask(const Trusted& aP2) : mMask(aP2.mMask) {}
+
+  T mMask = 0;
+};
+
+// Make a PowerOfTwoMask constant, statically-checked.
+template <typename T, T Mask>
+constexpr PowerOfTwoMask<T> MakePowerOfTwoMask() {
+  static_assert(Mask == T(-1) || IsPowerOfTwo(Mask + 1),
+                "MakePowerOfTwoMask<T, Mask>: Mask must be 2^N-1");
+  using Trusted = typename PowerOfTwoMask<T>::Trusted;
+  return PowerOfTwoMask<T>(Trusted{Mask});
+}
+
+// PowerOfTwo will always contain a power of 2.
+template <typename T>
+class PowerOfTwo {
+  static_assert(!std::numeric_limits<T>::is_signed,
+                "PowerOfTwo must use an unsigned type");
+
+ public:
+  // Construct a power of 2 that can fit the given value, or the highest power
+  // of 2 possible.
+  // Caller should explicitly check/assert `Value() <= aInput` if they want to.
+  // Cannot be constexpr because of `FriendlyRoundUpPow2()`.
+  explicit PowerOfTwo(T aInput) : mValue(FriendlyRoundUpPow2(aInput)) {}
+
+  // Allow smaller unsigned types as input.
+  // Bigger or signed types must be explicitly converted by the caller.
+  template <typename U>
+  explicit PowerOfTwo(U aInput)
+      : mValue(FriendlyRoundUpPow2(static_cast<T>(aInput))) {
+    static_assert(!std::numeric_limits<T>::is_signed,
+                  "PowerOfTwo does not accept signed types");
+    static_assert(sizeof(U) <= sizeof(T),
+                  "PowerOfTwo does not accept bigger types");
+  }
+
+  constexpr T Value() const { return mValue; }
+
+  // Binary mask corresponding to the power of 2, useful for modulo.
+  // E.g., `x & powerOfTwo(y).Mask()` == `x % powerOfTwo(y)`.
+  // Consider PowerOfTwoMask class instead of PowerOfTwo if masking is the
+  // primary use case.
+  constexpr T MaskValue() const { return mValue - 1; }
+
+  // PowerOfTwoMask corresponding to this power of 2, useful for modulo.
+  constexpr PowerOfTwoMask<T> Mask() const {
+    using Trusted = typename PowerOfTwoMask<T>::Trusted;
+    return PowerOfTwoMask<T>(Trusted{MaskValue()});
+  }
+
+  // `x % aPowerOfTwo` works optimally.
+  // Useful for templated code doing modulo with a template argument type.
+  // Use PowerOfTwoMask class instead if masking is the primary use case.
+  template <typename U>
+  friend constexpr U operator%(U aNumerator, PowerOfTwo aDenominator) {
+    return aNumerator & aDenominator.MaskValue();
+  }
+
+  constexpr bool operator==(const PowerOfTwo& aRhs) const {
+    return mValue == aRhs.mValue;
+  }
+  constexpr bool operator!=(const PowerOfTwo& aRhs) const {
+    return mValue != aRhs.mValue;
+  }
+  constexpr bool operator<(const PowerOfTwo& aRhs) const {
+    return mValue < aRhs.mValue;
+  }
+  constexpr bool operator<=(const PowerOfTwo& aRhs) const {
+    return mValue <= aRhs.mValue;
+  }
+  constexpr bool operator>(const PowerOfTwo& aRhs) const {
+    return mValue > aRhs.mValue;
+  }
+  constexpr bool operator>=(const PowerOfTwo& aRhs) const {
+    return mValue >= aRhs.mValue;
+  }
+
+ private:
+  // Trust `MakePowerOfTwo()` to call the private Trusted constructor below.
+  template <typename U, U Value>
+  friend constexpr PowerOfTwo<U> MakePowerOfTwo();
+
+  struct Trusted {
+    T mValue;
+  };
+  // Construct a PowerOfTwo with the given trusted value.
+  // This saves having to compute the nearest 2^N.
+  // Note: Not offering PowerOfTwoMark-to-PowerOfTwo conversion, because that
+  // could result in an unexpected 0 result for the largest possible mask.
+  explicit constexpr PowerOfTwo(const Trusted& aP2) : mValue(aP2.mValue) {}
+
+  // The smallest power of 2 is 2^0 == 1.
+  T mValue = 1;
+};
+
+// Make a PowerOfTwo constant, statically-checked.
+template <typename T, T Value>
+constexpr PowerOfTwo<T> MakePowerOfTwo() {
+  static_assert(IsPowerOfTwo(Value),
+                "MakePowerOfTwo<T, Value>: Value must be 2^N");
+  using Trusted = typename PowerOfTwo<T>::Trusted;
+  return PowerOfTwo<T>(Trusted{Value});
+}
+
+// Shortcuts for the most common types and functions.
+
+using PowerOfTwoMask32 = PowerOfTwoMask<uint32_t>;
+using PowerOfTwo32 = PowerOfTwo<uint32_t>;
+using PowerOfTwoMask64 = PowerOfTwoMask<uint64_t>;
+using PowerOfTwo64 = PowerOfTwo<uint64_t>;
+
+template <uint32_t Mask>
+constexpr PowerOfTwoMask32 MakePowerOfTwoMask32() {
+  return MakePowerOfTwoMask<uint32_t, Mask>();
+}
+
+template <uint32_t Value>
+constexpr PowerOfTwo32 MakePowerOfTwo32() {
+  return MakePowerOfTwo<uint32_t, Value>();
+}
+
+template <uint64_t Mask>
+constexpr PowerOfTwoMask64 MakePowerOfTwoMask64() {
+  return MakePowerOfTwoMask<uint64_t, Mask>();
+}
+
+template <uint64_t Value>
+constexpr PowerOfTwo64 MakePowerOfTwo64() {
+  return MakePowerOfTwo<uint64_t, Value>();
+}
+
+}  // namespace mozilla
+
+#endif  // PowerOfTwo_h
--- a/mozglue/tests/TestBaseProfiler.cpp
+++ b/mozglue/tests/TestBaseProfiler.cpp
@@ -3,32 +3,158 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BaseProfiler.h"
 
 #ifdef MOZ_BASE_PROFILER
 
+#  include "mozilla/PowerOfTwo.h"
+
 #  include "mozilla/Attributes.h"
 #  include "mozilla/Vector.h"
 
 #  if defined(_MSC_VER)
 #    include <windows.h>
 #    include <mmsystem.h>
 #    include <process.h>
-#  elif defined(__linux__) || (defined(__APPLE__) && defined(__x86_64__))
+#  else
 #    include <time.h>
 #    include <unistd.h>
-#  else
-#    error
 #  endif
 
 using namespace mozilla;
 
+MOZ_MAYBE_UNUSED static void SleepMilli(unsigned aMilliseconds) {
+#  if defined(_MSC_VER)
+  Sleep(aMilliseconds);
+#  else
+  struct timespec ts;
+  ts.tv_sec = aMilliseconds / 1000;
+  ts.tv_nsec = long(aMilliseconds % 1000) * 1000000;
+  struct timespec tr;
+  while (nanosleep(&ts, &tr)) {
+    if (errno == EINTR) {
+      ts = tr;
+    } else {
+      printf("nanosleep() -> %s\n", strerror(errno));
+      exit(1);
+    }
+  }
+#  endif
+}
+
+void TestPowerOfTwoMask() {
+  printf("TestPowerOfTwoMask...\n");
+
+  static_assert(MakePowerOfTwoMask<uint32_t, 0>().MaskValue() == 0, "");
+  constexpr PowerOfTwoMask<uint32_t> c0 = MakePowerOfTwoMask<uint32_t, 0>();
+  MOZ_RELEASE_ASSERT(c0.MaskValue() == 0);
+
+  static_assert(MakePowerOfTwoMask<uint32_t, 0xFFu>().MaskValue() == 0xFFu, "");
+  constexpr PowerOfTwoMask<uint32_t> cFF =
+      MakePowerOfTwoMask<uint32_t, 0xFFu>();
+  MOZ_RELEASE_ASSERT(cFF.MaskValue() == 0xFFu);
+
+  static_assert(
+      MakePowerOfTwoMask<uint32_t, 0xFFFFFFFFu>().MaskValue() == 0xFFFFFFFFu,
+      "");
+  constexpr PowerOfTwoMask<uint32_t> cFFFFFFFF =
+      MakePowerOfTwoMask<uint32_t, 0xFFFFFFFFu>();
+  MOZ_RELEASE_ASSERT(cFFFFFFFF.MaskValue() == 0xFFFFFFFFu);
+
+  struct TestDataU32 {
+    uint32_t mInput;
+    uint32_t mMask;
+  };
+  // clang-format off
+  TestDataU32 tests[] = {
+    { 0, 0 },
+    { 1, 1 },
+    { 2, 3 },
+    { 3, 3 },
+    { 4, 7 },
+    { 5, 7 },
+    { (1u << 31) - 1, (1u << 31) - 1 },
+    { (1u << 31), uint32_t(-1) },
+    { (1u << 31) + 1, uint32_t(-1) },
+    { uint32_t(-1), uint32_t(-1) }
+  };
+  // clang-format on
+  for (const TestDataU32& test : tests) {
+    PowerOfTwoMask<uint32_t> p2m(test.mInput);
+    MOZ_RELEASE_ASSERT(p2m.MaskValue() == test.mMask);
+    for (const TestDataU32& inner : tests) {
+      if (p2m.MaskValue() != uint32_t(-1)) {
+        MOZ_RELEASE_ASSERT((inner.mInput % p2m) ==
+                           (inner.mInput % (p2m.MaskValue() + 1)));
+      }
+      MOZ_RELEASE_ASSERT((inner.mInput & p2m) == (inner.mInput % p2m));
+      MOZ_RELEASE_ASSERT((p2m & inner.mInput) == (inner.mInput & p2m));
+    }
+  }
+
+  printf("TestPowerOfTwoMask done\n");
+}
+
+void TestPowerOfTwo() {
+  printf("TestPowerOfTwo...\n");
+
+  static_assert(MakePowerOfTwo<uint32_t, 1>().Value() == 1, "");
+  constexpr PowerOfTwo<uint32_t> c1 = MakePowerOfTwo<uint32_t, 1>();
+  MOZ_RELEASE_ASSERT(c1.Value() == 1);
+  static_assert(MakePowerOfTwo<uint32_t, 1>().Mask().MaskValue() == 0, "");
+
+  static_assert(MakePowerOfTwo<uint32_t, 128>().Value() == 128, "");
+  constexpr PowerOfTwo<uint32_t> c128 = MakePowerOfTwo<uint32_t, 128>();
+  MOZ_RELEASE_ASSERT(c128.Value() == 128);
+  static_assert(MakePowerOfTwo<uint32_t, 128>().Mask().MaskValue() == 127, "");
+
+  static_assert(MakePowerOfTwo<uint32_t, 0x80000000u>().Value() == 0x80000000u,
+                "");
+  constexpr PowerOfTwo<uint32_t> cMax = MakePowerOfTwo<uint32_t, 0x80000000u>();
+  MOZ_RELEASE_ASSERT(cMax.Value() == 0x80000000u);
+  static_assert(
+      MakePowerOfTwo<uint32_t, 0x80000000u>().Mask().MaskValue() == 0x7FFFFFFFu,
+      "");
+
+  struct TestDataU32 {
+    uint32_t mInput;
+    uint32_t mValue;
+    uint32_t mMask;
+  };
+  // clang-format off
+  TestDataU32 tests[] = {
+    { 0, 1, 0 },
+    { 1, 1, 0 },
+    { 2, 2, 1 },
+    { 3, 4, 3 },
+    { 4, 4, 3 },
+    { 5, 8, 7 },
+    { (1u << 31) - 1, (1u << 31), (1u << 31) - 1 },
+    { (1u << 31), (1u << 31), (1u << 31) - 1 },
+    { (1u << 31) + 1, (1u << 31), (1u << 31) - 1 },
+    { uint32_t(-1), (1u << 31), (1u << 31) - 1 }
+  };
+  // clang-format on
+  for (const TestDataU32& test : tests) {
+    PowerOfTwo<uint32_t> p2(test.mInput);
+    MOZ_RELEASE_ASSERT(p2.Value() == test.mValue);
+    MOZ_RELEASE_ASSERT(p2.MaskValue() == test.mMask);
+    PowerOfTwoMask<uint32_t> p2m = p2.Mask();
+    MOZ_RELEASE_ASSERT(p2m.MaskValue() == test.mMask);
+    for (const TestDataU32& inner : tests) {
+      MOZ_RELEASE_ASSERT((inner.mInput % p2) == (inner.mInput % p2.Value()));
+    }
+  }
+
+  printf("TestPowerOfTwo done\n");
+}
+
 // Increase the depth, to a maximum (to avoid too-deep recursion).
 static constexpr size_t NextDepth(size_t aDepth) {
   constexpr size_t MAX_DEPTH = 128;
   return (aDepth < MAX_DEPTH) ? (aDepth + 1) : aDepth;
 }
 
 // Compute fibonacci the hard way (recursively: `f(n)=f(n-1)+f(n-2)`), and
 // prevent inlining.
@@ -45,51 +171,36 @@ MOZ_NEVER_INLINE unsigned long long Fibo
   unsigned long long f2 = Fibonacci<NextDepth(DEPTH)>(n - 2);
   if (DEPTH == 0) {
     BASE_PROFILER_ADD_MARKER("Half-way through Fibonacci", OTHER);
   }
   unsigned long long f1 = Fibonacci<NextDepth(DEPTH)>(n - 1);
   return f2 + f1;
 }
 
-static void SleepMilli(unsigned aMilliseconds) {
-#  if defined(_MSC_VER)
-  Sleep(aMilliseconds);
-#  else
-  struct timespec ts;
-  ts.tv_sec = aMilliseconds / 1000;
-  ts.tv_nsec = long(aMilliseconds % 1000) * 1000000;
-  struct timespec tr;
-  while (nanosleep(&ts, &tr)) {
-    if (errno == EINTR) {
-      ts = tr;
-    } else {
-      printf("nanosleep() -> %s\n", strerror(errno));
-      exit(1);
-    }
-  }
-#  endif
-}
-
 void TestProfiler() {
   printf("TestProfiler starting -- pid: %d, tid: %d\n",
          baseprofiler::profiler_current_process_id(),
          baseprofiler::profiler_current_thread_id());
-  // ::Sleep(10000);
+  // ::SleepMilli(10000);
+
+  // Test dependencies.
+  TestPowerOfTwoMask();
+  TestPowerOfTwo();
 
   {
     printf("profiler_init()...\n");
     AUTO_BASE_PROFILER_INIT;
 
     MOZ_RELEASE_ASSERT(!baseprofiler::profiler_is_active());
     MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_being_profiled());
     MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_sleeping());
 
     printf("profiler_start()...\n");
-    mozilla::Vector<const char*> filters;
+    Vector<const char*> filters;
     // Profile all registered threads.
     MOZ_RELEASE_ASSERT(filters.append(""));
     const uint32_t features = baseprofiler::ProfilerFeature::Leaf |
                               baseprofiler::ProfilerFeature::StackWalk |
                               baseprofiler::ProfilerFeature::Threads;
     baseprofiler::profiler_start(baseprofiler::BASE_PROFILER_DEFAULT_ENTRIES,
                                  BASE_PROFILER_DEFAULT_INTERVAL, features,
                                  filters.begin(), filters.length());