diff --git a/layout/tables/SpanningCellSorter.cpp b/layout/tables/SpanningCellSorter.cpp index 8778c8cfdeb1..cb0cfc3bfa66 100644 --- a/layout/tables/SpanningCellSorter.cpp +++ b/layout/tables/SpanningCellSorter.cpp @@ -9,7 +9,7 @@ */ #include "SpanningCellSorter.h" -#include "nsQuickSort.h" +#include "nsTArray.h" #include "mozilla/HashFunctions.h" using namespace mozilla; @@ -17,13 +17,11 @@ using namespace mozilla; // #define DEBUG_SPANNING_CELL_SORTER SpanningCellSorter::SpanningCellSorter() - : mState(ADDING), - mHashTable(&HashTableOps, sizeof(HashTableEntry)), - mSortedHashTable(nullptr) { + : mState(ADDING), mHashTable(&HashTableOps, sizeof(HashTableEntry)) { memset(mArray, 0, sizeof(mArray)); } -SpanningCellSorter::~SpanningCellSorter() { delete[] mSortedHashTable; } +SpanningCellSorter::~SpanningCellSorter() = default; /* static */ const PLDHashTableOps SpanningCellSorter::HashTableOps = { HashTableHashKey, HashTableMatchEntry, PLDHashTable::MoveEntryStub, @@ -73,19 +71,20 @@ bool SpanningCellSorter::AddCell(int32_t aColSpan, int32_t aRow, int32_t aCol) { return true; } -/* static */ -int SpanningCellSorter::SortArray(const void* a, const void* b, void* closure) { - int32_t spanA = (*static_cast(a))->mColSpan; - int32_t spanB = (*static_cast(b))->mColSpan; - - if (spanA < spanB) return -1; - if (spanA == spanB) return 0; - return 1; -} - SpanningCellSorter::Item* SpanningCellSorter::GetNext(int32_t* aColSpan) { NS_ASSERTION(mState != DONE, "done enumerating, stop calling"); + // Our comparator needs the SpanningCellSorter private HashTableEntry + class HashTableEntryComparator { + public: + bool Equals(HashTableEntry* left, HashTableEntry* right) const { + return left->mColSpan == right->mColSpan; + } + bool LessThan(HashTableEntry* left, HashTableEntry* right) const { + return left->mColSpan < right->mColSpan; + } + }; + switch (mState) { case ADDING: /* prepare to enumerate the array */ @@ -112,14 +111,15 @@ SpanningCellSorter::Item* SpanningCellSorter::GetNext(int32_t* aColSpan) { mState = ENUMERATING_HASH; mEnumerationIndex = 0; if (mHashTable.EntryCount() > 0) { - HashTableEntry** sh = new HashTableEntry*[mHashTable.EntryCount()]; - int32_t j = 0; + // This clear is a no-op if the array is empty and it makes us + // resilient against re-entrance. + mSortedHashTable.ClearAndRetainStorage(); + mSortedHashTable.SetCapacity(mHashTable.EntryCount()); for (auto iter = mHashTable.ConstIter(); !iter.Done(); iter.Next()) { - sh[j++] = static_cast(iter.Get()); + mSortedHashTable.AppendElement( + static_cast(iter.Get())); } - NS_QuickSort(sh, mHashTable.EntryCount(), sizeof(sh[0]), SortArray, - nullptr); - mSortedHashTable = sh; + mSortedHashTable.Sort(HashTableEntryComparator()); } [[fallthrough]]; case ENUMERATING_HASH: diff --git a/layout/tables/SpanningCellSorter.h b/layout/tables/SpanningCellSorter.h index eac6c26b7c22..4de360497d1c 100644 --- a/layout/tables/SpanningCellSorter.h +++ b/layout/tables/SpanningCellSorter.h @@ -13,6 +13,7 @@ #include "PLDHashTable.h" #include "nsDebug.h" +#include "nsTArray.h" #include "StackArena.h" /** @@ -73,11 +74,11 @@ class MOZ_STACK_CLASS SpanningCellSorter { static PLDHashNumber HashTableHashKey(const void* key); static bool HashTableMatchEntry(const PLDHashEntryHdr* hdr, const void* key); - static int SortArray(const void* a, const void* b, void* closure); + static int CompareHashTableEntry(HashTableEntry* a, HashTableEntry* b); /* state used only during enumeration */ uint32_t mEnumerationIndex; // into mArray or mSortedHashTable - HashTableEntry** mSortedHashTable; + nsTArray mSortedHashTable; /* * operator new is forbidden since we use the pres shell's stack