diff --git a/xpcom/ds/nsTArray-inl.h b/xpcom/ds/nsTArray-inl.h index 7103ead37ac4..9b8c093ca77d 100644 --- a/xpcom/ds/nsTArray-inl.h +++ b/xpcom/ds/nsTArray-inl.h @@ -267,6 +267,27 @@ void nsTArray_base::ShrinkCapacity( mHdr->mCapacity = length; } +template +void nsTArray_base::ShrinkCapacityToZero( + size_type aElemSize, size_t aElemAlign) { + MOZ_ASSERT(mHdr->mLength == 0); + + if (mHdr == EmptyHdr() || UsesAutoArrayBuffer()) { + return; + } + + const bool isAutoArray = IsAutoArray(); + + nsTArrayFallibleAllocator::Free(mHdr); + + if (isAutoArray) { + mHdr = GetAutoArrayBufferUnsafe(aElemAlign); + mHdr->mLength = 0; + } else { + mHdr = EmptyHdr(); + } +} + template template void nsTArray_base::ShiftData(index_type aStart, @@ -284,7 +305,7 @@ void nsTArray_base::ShiftData(index_type aStart, // Compute the resulting length of the array mHdr->mLength += aNewLen - aOldLen; if (mHdr->mLength == 0) { - ShrinkCapacity(aElemSize, aElemAlign); + ShrinkCapacityToZero(aElemSize, aElemAlign); } else { // Maybe nothing needs to be shifted if (num == 0) { @@ -320,7 +341,7 @@ void nsTArray_base::SwapFromEnd(index_type aStart, if (mHdr->mLength == 0) { // If we have no elements remaining in the array, we can free our buffer. - ShrinkCapacity(aElemSize, aElemAlign); + ShrinkCapacityToZero(aElemSize, aElemAlign); return; } diff --git a/xpcom/ds/nsTArray.h b/xpcom/ds/nsTArray.h index 2a640b61a23c..acd1865935d5 100644 --- a/xpcom/ds/nsTArray.h +++ b/xpcom/ds/nsTArray.h @@ -457,6 +457,12 @@ class nsTArray_base { // @param aElemAlign The alignment in bytes of an array element. void ShrinkCapacity(size_type aElemSize, size_t aElemAlign); + // Resizes the storage to 0. This may only be called when Length() is already + // 0. + // @param aElemSize The size of an array element. + // @param aElemAlign The alignment in bytes of an array element. + void ShrinkCapacityToZero(size_type aElemSize, size_t aElemAlign); + // This method may be called to resize a "gap" in the array by shifting // elements around. It updates mLength appropriately. If the resulting // array has zero elements, then the array's memory is free'd. @@ -1891,7 +1897,7 @@ class nsTArray_Impl void Clear() { ClearAndRetainStorage(); - Compact(); + base_type::ShrinkCapacityToZero(sizeof(elem_type), MOZ_ALIGNOF(elem_type)); } // This method removes elements based on the return value of the