Bug 1410186 - turn Maybe assertions into diagnostic assertions; r=bkelly
authorNathan Froyd <froydnj@mozilla.com>
Mon, 21 May 2018 10:03:59 -0400
changeset 419164 aab1afd86d77b9088efcadba770d987d921169f6
parent 419163 e46cb2927af94344fd03989d336a06115f81d8e1
child 419165 63b24cc63ecaa5cde91b448d1b5066a1b1bad3aa
push id34029
push usershindli@mozilla.com
push dateMon, 21 May 2018 21:30:22 +0000
treeherdermozilla-central@51f2535c7974 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly
bugs1410186
milestone62.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 1410186 - turn Maybe assertions into diagnostic assertions; r=bkelly We out-of-line the relevant functions because assertions can generate quite a bit of code, and we'd rather let the compiler determine if these functions should be inlined now.
mfbt/Maybe.h
--- a/mfbt/Maybe.h
+++ b/mfbt/Maybe.h
@@ -310,21 +310,17 @@ public:
   }
 
   /* Methods that check whether this Maybe contains a value */
   explicit operator bool() const { return isSome(); }
   bool isSome() const { return mIsSome; }
   bool isNothing() const { return !mIsSome; }
 
   /* Returns the contents of this Maybe<T> by value. Unsafe unless |isSome()|. */
-  T value() const
-  {
-    MOZ_ASSERT(mIsSome);
-    return ref();
-  }
+  T value() const;
 
   /*
    * Returns the contents of this Maybe<T> by value. If |isNothing()|, returns
    * the default value provided.
    */
   template<typename V>
   T valueOr(V&& aDefault) const
   {
@@ -343,27 +339,18 @@ public:
   {
     if (isSome()) {
       return ref();
     }
     return aFunc();
   }
 
   /* Returns the contents of this Maybe<T> by pointer. Unsafe unless |isSome()|. */
-  T* ptr()
-  {
-    MOZ_ASSERT(mIsSome);
-    return &ref();
-  }
-
-  const T* ptr() const
-  {
-    MOZ_ASSERT(mIsSome);
-    return &ref();
-  }
+  T* ptr();
+  const T* ptr() const;
 
   /*
    * Returns the contents of this Maybe<T> by pointer. If |isNothing()|,
    * returns the default value provided.
    */
   T* ptrOr(T* aDefault)
   {
     if (isSome()) {
@@ -397,40 +384,22 @@ public:
   const T* ptrOrFrom(F&& aFunc) const
   {
     if (isSome()) {
       return ptr();
     }
     return aFunc();
   }
 
-  T* operator->()
-  {
-    MOZ_ASSERT(mIsSome);
-    return ptr();
-  }
-
-  const T* operator->() const
-  {
-    MOZ_ASSERT(mIsSome);
-    return ptr();
-  }
+  T* operator->();
+  const T* operator->() const;
 
   /* Returns the contents of this Maybe<T> by ref. Unsafe unless |isSome()|. */
-  T& ref()
-  {
-    MOZ_ASSERT(mIsSome);
-    return *static_cast<T*>(data());
-  }
-
-  const T& ref() const
-  {
-    MOZ_ASSERT(mIsSome);
-    return *static_cast<const T*>(data());
-  }
+  T& ref();
+  const T& ref() const;
 
   /*
    * Returns the contents of this Maybe<T> by ref. If |isNothing()|, returns
    * the default value provided.
    */
   T& refOr(T& aDefault)
   {
     if (isSome()) {
@@ -464,27 +433,18 @@ public:
   const T& refOrFrom(F&& aFunc) const
   {
     if (isSome()) {
       return ref();
     }
     return aFunc();
   }
 
-  T& operator*()
-  {
-    MOZ_ASSERT(mIsSome);
-    return ref();
-  }
-
-  const T& operator*() const
-  {
-    MOZ_ASSERT(mIsSome);
-    return ref();
-  }
+  T& operator*();
+  const T& operator*() const;
 
   /* If |isSome()|, runs the provided function or functor on the contents of
    * this Maybe. */
   template<typename Func>
   Maybe& apply(Func aFunc)
   {
     if (isSome()) {
       aFunc(ref());
@@ -539,35 +499,112 @@ public:
     }
   }
 
   /*
    * Constructs a T value in-place in this empty Maybe<T>'s storage. The
    * arguments to |emplace()| are the parameters to T's constructor.
    */
   template<typename... Args>
-  void emplace(Args&&... aArgs)
-  {
-    MOZ_ASSERT(!mIsSome);
-    ::new (KnownNotNull, data()) T(Forward<Args>(aArgs)...);
-    mIsSome = true;
-  }
+  void emplace(Args&&... aArgs);
 
   friend std::ostream&
   operator<<(std::ostream& aStream, const Maybe<T>& aMaybe)
   {
     if (aMaybe) {
       aStream << aMaybe.ref();
     } else {
       aStream << "<Nothing>";
     }
     return aStream;
   }
 };
 
+template<typename T>
+T
+Maybe<T>::value() const
+{
+  MOZ_DIAGNOSTIC_ASSERT(mIsSome);
+  return ref();
+}
+
+template<typename T>
+T*
+Maybe<T>::ptr()
+{
+  MOZ_DIAGNOSTIC_ASSERT(mIsSome);
+  return &ref();
+}
+
+template<typename T>
+const T*
+Maybe<T>::ptr() const
+{
+  MOZ_DIAGNOSTIC_ASSERT(mIsSome);
+  return &ref();
+}
+
+template<typename T>
+T*
+Maybe<T>::operator->()
+{
+  MOZ_DIAGNOSTIC_ASSERT(mIsSome);
+  return ptr();
+}
+
+template<typename T>
+const T*
+Maybe<T>::operator->() const
+{
+  MOZ_DIAGNOSTIC_ASSERT(mIsSome);
+  return ptr();
+}
+
+template<typename T>
+T&
+Maybe<T>::ref()
+{
+  MOZ_DIAGNOSTIC_ASSERT(mIsSome);
+  return *static_cast<T*>(data());
+}
+
+template<typename T>
+const T&
+Maybe<T>::ref() const
+{
+  MOZ_DIAGNOSTIC_ASSERT(mIsSome);
+  return *static_cast<const T*>(data());
+}
+
+template<typename T>
+T&
+Maybe<T>::operator*()
+{
+  MOZ_DIAGNOSTIC_ASSERT(mIsSome);
+  return ref();
+}
+
+template<typename T>
+const T&
+Maybe<T>::operator*() const
+{
+  MOZ_DIAGNOSTIC_ASSERT(mIsSome);
+  return ref();
+}
+
+template<typename T>
+template<typename... Args>
+void
+Maybe<T>::emplace(Args&&... aArgs)
+{
+  MOZ_DIAGNOSTIC_ASSERT(!mIsSome);
+  ::new (KnownNotNull, data()) T(Forward<Args>(aArgs)...);
+  mIsSome = true;
+}
+
 /*
  * Some() creates a Maybe<T> value containing the provided T value. If T has a
  * move constructor, it's used to make this as efficient as possible.
  *
  * Some() selects the type of Maybe it returns by removing any const, volatile,
  * or reference qualifiers from the type of the value you pass to it. This gives
  * it more intuitive behavior when used in expressions, but it also means that
  * if you need to construct a Maybe value that holds a const, volatile, or