mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Bug 1180122 - Make Chaos Mode affect PLDHashTable's iterators. r=froydnj.
This makes the code less elegant, but that's unavoidable. --HG-- extra : rebase_source : 585034bcd8383102669caf2378d705234410d8a9
This commit is contained in:
parent
5a141756bd
commit
4aa7305199
@ -792,30 +792,49 @@ PL_DHashTableSizeOfIncludingThis(
|
||||
|
||||
PLDHashTable::Iterator::Iterator(Iterator&& aOther)
|
||||
: mTable(aOther.mTable)
|
||||
, mCurrent(aOther.mCurrent)
|
||||
, mStart(aOther.mStart)
|
||||
, mLimit(aOther.mLimit)
|
||||
, mCurrent(aOther.mCurrent)
|
||||
, mNexts(aOther.mNexts)
|
||||
, mNextsLimit(aOther.mNextsLimit)
|
||||
, mHaveRemoved(aOther.mHaveRemoved)
|
||||
{
|
||||
// No need to change |mChecker| here.
|
||||
aOther.mTable = nullptr;
|
||||
aOther.mCurrent = nullptr;
|
||||
aOther.mStart = nullptr;
|
||||
aOther.mLimit = nullptr;
|
||||
aOther.mCurrent = nullptr;
|
||||
aOther.mNexts = 0;
|
||||
aOther.mNextsLimit = 0;
|
||||
aOther.mHaveRemoved = false;
|
||||
}
|
||||
|
||||
PLDHashTable::Iterator::Iterator(PLDHashTable* aTable)
|
||||
: mTable(aTable)
|
||||
, mCurrent(mTable->mEntryStore)
|
||||
, mStart(mTable->mEntryStore)
|
||||
, mLimit(mTable->mEntryStore + mTable->Capacity() * mTable->mEntrySize)
|
||||
, mCurrent(mTable->mEntryStore)
|
||||
, mNexts(0)
|
||||
, mNextsLimit(mTable->EntryCount())
|
||||
, mHaveRemoved(false)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
mTable->mChecker.StartReadOp();
|
||||
#endif
|
||||
|
||||
// Advance to the first live entry, or to the end if there are none.
|
||||
while (IsOnNonLiveEntry()) {
|
||||
mCurrent += mTable->mEntrySize;
|
||||
if (ChaosMode::isActive(ChaosMode::HashTableIteration) &&
|
||||
mTable->Capacity() > 0) {
|
||||
// Start iterating at a random entry. It would be even more chaotic to
|
||||
// iterate in fully random order, but that's harder.
|
||||
mCurrent += ChaosMode::randomUint32LessThan(mTable->Capacity()) *
|
||||
mTable->mEntrySize;
|
||||
}
|
||||
|
||||
// Advance to the first live entry, if there is one.
|
||||
if (!Done()) {
|
||||
while (IsOnNonLiveEntry()) {
|
||||
MoveToNextEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -834,13 +853,23 @@ PLDHashTable::Iterator::~Iterator()
|
||||
bool
|
||||
PLDHashTable::Iterator::Done() const
|
||||
{
|
||||
return mCurrent == mLimit;
|
||||
return mNexts == mNextsLimit;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
PLDHashTable::Iterator::IsOnNonLiveEntry() const
|
||||
{
|
||||
return !Done() && !ENTRY_IS_LIVE(reinterpret_cast<PLDHashEntryHdr*>(mCurrent));
|
||||
MOZ_ASSERT(!Done());
|
||||
return !ENTRY_IS_LIVE(reinterpret_cast<PLDHashEntryHdr*>(mCurrent));
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void
|
||||
PLDHashTable::Iterator::MoveToNextEntry()
|
||||
{
|
||||
mCurrent += mTable->mEntrySize;
|
||||
if (mCurrent == mLimit) {
|
||||
mCurrent = mStart; // Wrap-around. Possible due to Chaos Mode.
|
||||
}
|
||||
}
|
||||
|
||||
PLDHashEntryHdr*
|
||||
@ -858,9 +887,14 @@ PLDHashTable::Iterator::Next()
|
||||
{
|
||||
MOZ_ASSERT(!Done());
|
||||
|
||||
do {
|
||||
mCurrent += mTable->mEntrySize;
|
||||
} while (IsOnNonLiveEntry());
|
||||
mNexts++;
|
||||
|
||||
// Advance to the next live entry, if there is one.
|
||||
if (!Done()) {
|
||||
do {
|
||||
MoveToNextEntry();
|
||||
} while (IsOnNonLiveEntry());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -393,12 +393,16 @@ public:
|
||||
PLDHashTable* mTable; // Main table pointer.
|
||||
|
||||
private:
|
||||
char* mCurrent; // Pointer to the current entry.
|
||||
char* mStart; // The first entry.
|
||||
char* mLimit; // One past the last entry.
|
||||
char* mCurrent; // Pointer to the current entry.
|
||||
uint32_t mNexts; // Number of Next() calls.
|
||||
uint32_t mNextsLimit; // Next() call limit.
|
||||
|
||||
bool mHaveRemoved; // Have any elements been removed?
|
||||
|
||||
bool IsOnNonLiveEntry() const;
|
||||
void MoveToNextEntry();
|
||||
|
||||
Iterator() = delete;
|
||||
Iterator(const Iterator&) = delete;
|
||||
|
Loading…
Reference in New Issue
Block a user