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 373455 83c513bf2e8843b445bfc5768bba6190543894bc
parent 373454 665bcbc8786275c50fb9b6b473a8f798e6f72e10
child 373456 01231e42dd09112c83c6dce35dd732136fb8154d
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1339555
milestone54.0a1
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);
   }