diff --git a/xpcom/glue/nsTArray-inl.h b/xpcom/glue/nsTArray-inl.h index 5ac5329e465..ba54cf31788 100644 --- a/xpcom/glue/nsTArray-inl.h +++ b/xpcom/glue/nsTArray-inl.h @@ -32,7 +32,7 @@ nsTArray_base::GetAutoArrayBufferUnsafe(size_t aElemAlign) const // mAutoBuf. So just cast |this| to nsAutoArray* and read &mAutoBuf! const void* autoBuf = - &reinterpret_cast, 1>*>(this)->mAutoBuf; + &reinterpret_cast, 1>*>(this)->mAutoBuf; // If we're on a 32-bit system and aElemAlign is 8, we need to adjust our // pointer to take into account the extra alignment in the auto array. @@ -89,7 +89,7 @@ nsTArray_base::UsesAutoArrayBuffer() const // Note that this means that we can't store elements with alignment 16 in an // nsTArray, because GetAutoArrayBuffer(16) could lie outside the memory // owned by this AutoTArray. We statically assert that elem_type's - // alignment is 8 bytes or less in nsAutoArrayBase. + // alignment is 8 bytes or less in AutoTArray. static_assert(sizeof(nsTArrayHeader) > 4, "see comment above"); @@ -403,7 +403,7 @@ nsTArray_base::SwapArrayElements(nsTArray_base, 64> temp; + AutoTArray, 64> temp; if (!ActualAlloc::Successful(temp.template EnsureCapacity(smallerLength, aElemSize))) { return ActualAlloc::FailureResult(); diff --git a/xpcom/glue/nsTArray.h b/xpcom/glue/nsTArray.h index ade58ab6d40..75c8ed3794c 100644 --- a/xpcom/glue/nsTArray.h +++ b/xpcom/glue/nsTArray.h @@ -2201,19 +2201,55 @@ public: }; // -// nsAutoArrayBase is a base class for AutoTArray. -// You shouldn't use this class directly. +// AutoTArray is like nsTArray, but with N elements of inline storage. +// Storing more than N elements is fine, but it will cause a heap allocation. // -template -class MOZ_NON_MEMMOVABLE nsAutoArrayBase : public TArrayBase +template +class MOZ_NON_MEMMOVABLE AutoTArray : public nsTArray { - static_assert(N != 0, "nsAutoArrayBase should be specialized"); + static_assert(N != 0, "AutoTArray should be specialized"); public: - typedef nsAutoArrayBase self_type; - typedef TArrayBase base_type; + typedef AutoTArray self_type; + typedef nsTArray base_type; typedef typename base_type::Header Header; typedef typename base_type::elem_type elem_type; + AutoTArray() + { + Init(); + } + + AutoTArray(const self_type& aOther) + { + Init(); + this->AppendElements(aOther); + } + + explicit AutoTArray(const base_type& aOther) + { + Init(); + this->AppendElements(aOther); + } + + explicit AutoTArray(base_type&& aOther) + { + Init(); + this->SwapElements(aOther); + } + + template + explicit AutoTArray(nsTArray_Impl&& aOther) + { + Init(); + this->SwapElements(aOther); + } + + self_type& operator=(const self_type& aOther) + { + base_type::operator=(aOther); + return *this; + } + template self_type& operator=(const nsTArray_Impl& aOther) { @@ -2221,32 +2257,6 @@ public: return *this; } -protected: - nsAutoArrayBase() { Init(); } - - // We need this constructor because AutoTArray and friends all have - // implicit copy-constructors. If we don't have this method, those - // copy-constructors will call nsAutoArrayBase's implicit copy-constructor, - // which won't call Init() and set up the auto buffer! - nsAutoArrayBase(const self_type& aOther) - { - Init(); - this->AppendElements(aOther); - } - - explicit nsAutoArrayBase(const TArrayBase &aOther) - { - Init(); - this->AppendElements(aOther); - } - - template - explicit nsAutoArrayBase(nsTArray_Impl&& aOther) - { - Init(); - this->SwapElements(aOther); - } - private: // nsTArray_base casts itself as an nsAutoArrayBase in order to get a pointer // to mAutoBuf. @@ -2284,57 +2294,24 @@ private: }; // -// Specialization of nsAutoArrayBase for the case where N == 0. -// nsAutoArrayBase behaves exactly like TArrayBase, but without -// this specialization, it stores a useless inline header. +// Specialization of AutoTArray for the case where N == 0. +// AutoTArray behaves exactly like nsTArray, but without this +// specialization, it stores a useless inline header. // -// We do have many nsAutoArrayBase objects in memory: about -// 2,000 per tab as of May 2014. These are typically not explicitly -// nsAutoArrayBase but rather nsAutoArrayBase -// for some value N depending on template parameters, in generic code. +// We do have many AutoTArray objects in memory: about 2,000 per tab as +// of May 2014. These are typically not explicitly AutoTArray but rather +// AutoTArray for some value N depending on template parameters, in +// generic code. // // For that reason, we optimize this case with the below partial specialization, -// which ensures that nsAutoArrayBase is just like TArrayBase, -// without any inline header overhead. +// which ensures that AutoTArray is just like nsTArray, without any +// inline header overhead. // -template -class nsAutoArrayBase : public TArrayBase +template +class AutoTArray : public nsTArray { }; -// -// AutoTArray is an infallible vector class with N elements of inline -// storage. If you try to store more than N elements inside an -// AutoTArray, we'll call malloc() and store them all on the heap. -// -template -class AutoTArray : public nsAutoArrayBase, N> -{ - typedef AutoTArray self_type; - typedef nsAutoArrayBase, N> Base; - -public: - AutoTArray() {} - - template - explicit AutoTArray(const nsTArray_Impl& aOther) - { - Base::AppendElements(aOther); - } - template - explicit AutoTArray(nsTArray_Impl&& aOther) - : Base(mozilla::Move(aOther)) - { - } - - template - self_type& operator=(const nsTArray_Impl& other) - { - Base::operator=(other); - return *this; - } -}; - template struct nsTArray_CopyChooser> {