Bug 1410186 - turn Maybe assertions into diagnostic assertions; r=bkelly
authorNathan Froyd <froydnj@mozilla.com>
Tue, 15 May 2018 16:34:59 -0400
changeset 418358 c82274a23aeaa6be8b7509de05822cb4bfa7729e
parent 418357 3b78d37d61ae46ae3fc35305b27655b80fa06155
child 418359 6ddc3b915c342eb051333a33285fbdd49d9b7fbb
push id103296
push usernfroyd@mozilla.com
push dateTue, 15 May 2018 20:35:14 +0000
treeherdermozilla-inbound@c82274a23aea [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