Bug 1339555 - Make various operator-news into a known-non-null pointer use a ::operator new overload that odesn't null-check. r=froydnj
authorJeff Walden <jwalden@mit.edu>
Tue, 14 Feb 2017 11:23:18 -0800
changeset 344428 83c513bf2e8843b445bfc5768bba6190543894bc
parent 344427 665bcbc8786275c50fb9b6b473a8f798e6f72e10
child 344429 01231e42dd09112c83c6dce35dd732136fb8154d
push id31408
push usercbook@mozilla.com
push dateThu, 23 Feb 2017 13:59:58 +0000
treeherdermozilla-central@c02dd6a7e9c1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1339555
milestone54.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 1339555 - Make various operator-news into a known-non-null pointer use a ::operator new overload that odesn't null-check. r=froydnj
mfbt/Maybe.h
mfbt/MaybeOneOf.h
mfbt/Variant.h
--- a/mfbt/Maybe.h
+++ b/mfbt/Maybe.h
@@ -8,16 +8,17 @@
 
 #ifndef mozilla_Maybe_h
 #define mozilla_Maybe_h
 
 #include "mozilla/Alignment.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Move.h"
+#include "mozilla/OperatorNewExtensions.h"
 #include "mozilla/TypeTraits.h"
 
 #include <new>  // for placement new
 #include <ostream>
 #include <type_traits>
 
 namespace mozilla {
 
@@ -453,17 +454,17 @@ 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 (mStorage.addr()) T(Forward<Args>(aArgs)...);
+    ::new (KnownNotNull, mStorage.addr()) T(Forward<Args>(aArgs)...);
     mIsSome = true;
   }
 
   friend std::ostream&
   operator<<(std::ostream& aStream, const Maybe<T>& aMaybe)
   {
     if (aMaybe) {
       aStream << aMaybe.ref();
--- a/mfbt/MaybeOneOf.h
+++ b/mfbt/MaybeOneOf.h
@@ -9,16 +9,17 @@
  * construction.
  */
 
 #ifndef mozilla_MaybeOneOf_h
 #define mozilla_MaybeOneOf_h
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Move.h"
+#include "mozilla/OperatorNewExtensions.h"
 #include "mozilla/TemplateLib.h"
 
 #include <new> // for placement new
 #include <stddef.h> // for size_t
 
 namespace mozilla {
 
 /*
@@ -100,17 +101,17 @@ public:
   template <class T>
   bool constructed() const { return state == Type2State<T>::result; }
 
   template <class T, class... Args>
   void construct(Args&&... aArgs)
   {
     MOZ_ASSERT(state == None);
     state = Type2State<T>::result;
-    ::new (data()) T(Forward<Args>(aArgs)...);
+    ::new (KnownNotNull, data()) T(Forward<Args>(aArgs)...);
   }
 
   template <class T>
   T& ref()
   {
     return as<T>();
   }
 
--- a/mfbt/Variant.h
+++ b/mfbt/Variant.h
@@ -6,16 +6,17 @@
 
 /* A template class for tagged unions. */
 
 #include <new>
 #include <stdint.h>
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Move.h"
+#include "mozilla/OperatorNewExtensions.h"
 #include "mozilla/TemplateLib.h"
 #include "mozilla/TypeTraits.h"
 
 #ifndef mozilla_Variant_h
 #define mozilla_Variant_h
 
 namespace mozilla {
 
@@ -174,22 +175,22 @@ struct VariantImplementation<Tag, N, T>
   static Tag tag() {
     static_assert(mozilla::IsSame<T, U>::value,
                   "mozilla::Variant: tag: bad type!");
     return Tag(N);
   }
 
   template<typename Variant>
   static void copyConstruct(void* aLhs, const Variant& aRhs) {
-    new (aLhs) T(aRhs.template as<T>());
+    ::new (KnownNotNull, aLhs) T(aRhs.template as<T>());
   }
 
   template<typename Variant>
   static void moveConstruct(void* aLhs, Variant&& aRhs) {
-    new (aLhs) T(aRhs.template extract<T>());
+    ::new (KnownNotNull, aLhs) T(aRhs.template extract<T>());
   }
 
   template<typename Variant>
   static void destroy(Variant& aV) {
     aV.template as<T>().~T();
   }
 
   template<typename Variant>
@@ -217,26 +218,26 @@ struct VariantImplementation<Tag, N, T, 
   template<typename U>
   static Tag tag() {
     return TagHelper<Tag, N, T, U, Next, IsSame<T, U>::value>::tag();
   }
 
   template<typename Variant>
   static void copyConstruct(void* aLhs, const Variant& aRhs) {
     if (aRhs.template is<T>()) {
-      new (aLhs) T(aRhs.template as<T>());
+      ::new (KnownNotNull, aLhs) T(aRhs.template as<T>());
     } else {
       Next::copyConstruct(aLhs, aRhs);
     }
   }
 
   template<typename Variant>
   static void moveConstruct(void* aLhs, Variant&& aRhs) {
     if (aRhs.template is<T>()) {
-      new (aLhs) T(aRhs.template extract<T>());
+      ::new (KnownNotNull, aLhs) T(aRhs.template extract<T>());
     } else {
       Next::moveConstruct(aLhs, aRhs);
     }
   }
 
   template<typename Variant>
   static void destroy(Variant& aV) {
     if (aV.template is<T>()) {
@@ -480,30 +481,30 @@ public:
            // RefT captures both const& as well as && (as intended, to support
            // perfect forwarding), so we have to remove those qualifiers here
            // when ensuring that T is a variant of this type, and getting T's
            // tag, etc.
            typename T = typename detail::SelectVariantType<RefT, Ts...>::Type>
   explicit Variant(RefT&& aT)
     : tag(Impl::template tag<T>())
   {
-    new (ptr()) T(Forward<RefT>(aT));
+    ::new (KnownNotNull, ptr()) T(Forward<RefT>(aT));
   }
 
   /**
    * Constructs this Variant from an AsVariantTemporary<T> such that T can be
    * stored in one of the types allowable in this Variant. This is used in the
    * implementation of AsVariant().
    */
   template<typename RefT,
            typename T = typename detail::SelectVariantType<RefT, Ts...>::Type>
   MOZ_IMPLICIT Variant(detail::AsVariantTemporary<RefT>&& aValue)
     : tag(Impl::template tag<T>())
   {
-    new (ptr()) T(Move(aValue.mValue));
+    ::new (KnownNotNull, ptr()) T(Move(aValue.mValue));
   }
 
   /** Copy construction. */
   Variant(const Variant& aRhs)
     : tag(aRhs.tag)
   {
     Impl::copyConstruct(ptr(), aRhs);
   }
@@ -514,34 +515,34 @@ public:
   {
     Impl::moveConstruct(ptr(), Move(aRhs));
   }
 
   /** Copy assignment. */
   Variant& operator=(const Variant& aRhs) {
     MOZ_ASSERT(&aRhs != this, "self-assign disallowed");
     this->~Variant();
-    new (this) Variant(aRhs);
+    ::new (KnownNotNull, this) Variant(aRhs);
     return *this;
   }
 
   /** Move assignment. */
   Variant& operator=(Variant&& aRhs) {
     MOZ_ASSERT(&aRhs != this, "self-assign disallowed");
     this->~Variant();
-    new (this) Variant(Move(aRhs));
+    ::new (KnownNotNull, this) Variant(Move(aRhs));
     return *this;
   }
 
   /** Move assignment from AsVariant(). */
   template <typename T>
   Variant& operator=(detail::AsVariantTemporary<T>&& aValue)
   {
     this->~Variant();
-    new (this) Variant(Move(aValue));
+    ::new (KnownNotNull, this) Variant(Move(aValue));
     return *this;
   }
 
   ~Variant()
   {
     Impl::destroy(*this);
   }