зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1730534 - Part 2: Add an iterator for JSHolderMap's EntryVector r=mccr8
This replaces use of the ForEach method that takes an EntryVector with an iterator. Differential Revision: https://phabricator.services.mozilla.com/D125427
This commit is contained in:
Родитель
7ad0c5ec32
Коммит
91dff4dbce
|
@ -483,12 +483,30 @@ JSHolderMap::Entry::Entry(void* aHolder, nsScriptObjectTracer* aTracer,
|
|||
{
|
||||
}
|
||||
|
||||
void JSHolderMap::EntryVectorIter::Settle() {
|
||||
if (Done()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entry* entry = &mIter.Get();
|
||||
|
||||
// If the entry has been cleared, remove it and shrink the vector.
|
||||
if (!entry->mHolder && !mHolderMap.RemoveEntry(mVector, entry)) {
|
||||
// We removed the last entry, so reset the iterator to an empty one.
|
||||
mIter = EntryVector().Iter();
|
||||
MOZ_ASSERT(Done());
|
||||
}
|
||||
}
|
||||
|
||||
JSHolderMap::JSHolderMap() : mJSHolderMap(256) {}
|
||||
|
||||
template <typename F>
|
||||
inline void JSHolderMap::ForEach(F&& f, WhichHolders aWhich) {
|
||||
// Multi-zone JS holders must always be considered.
|
||||
ForEach(mAnyZoneJSHolders, f, nullptr);
|
||||
for (EntryVectorIter entry(*this, mAnyZoneJSHolders); !entry.Done();
|
||||
entry.Next()) {
|
||||
f(entry->mHolder, entry->mTracer, nullptr);
|
||||
}
|
||||
|
||||
for (auto i = mPerZoneJSHolders.modIter(); !i.done(); i.next()) {
|
||||
if (aWhich == HoldersInGrayMarkingZones &&
|
||||
|
@ -496,30 +514,19 @@ inline void JSHolderMap::ForEach(F&& f, WhichHolders aWhich) {
|
|||
continue;
|
||||
}
|
||||
|
||||
JS::Zone* zone = i.get().key();
|
||||
EntryVector* holders = i.get().value().get();
|
||||
ForEach(*holders, f, i.get().key());
|
||||
for (EntryVectorIter entry(*this, *holders); !entry.Done(); entry.Next()) {
|
||||
MOZ_ASSERT(entry->mZone == zone);
|
||||
f(entry->mHolder, entry->mTracer, zone);
|
||||
}
|
||||
|
||||
if (holders->IsEmpty()) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
inline void JSHolderMap::ForEach(EntryVector& aJSHolders, const F& f,
|
||||
JS::Zone* aZone) {
|
||||
for (auto iter = aJSHolders.Iter(); !iter.Done(); iter.Next()) {
|
||||
Entry* entry = &iter.Get();
|
||||
|
||||
// If the entry has been cleared, remove it and shrink the vector.
|
||||
if (!entry->mHolder && !RemoveEntry(aJSHolders, entry)) {
|
||||
break; // Removed the last entry.
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(aZone, entry->mZone == aZone);
|
||||
f(entry->mHolder, entry->mTracer, aZone);
|
||||
}
|
||||
}
|
||||
|
||||
bool JSHolderMap::RemoveEntry(EntryVector& aJSHolders, Entry* aEntry) {
|
||||
MOZ_ASSERT(aEntry);
|
||||
MOZ_ASSERT(!aEntry->mHolder);
|
||||
|
|
|
@ -124,8 +124,7 @@ class JSHolderMap {
|
|||
mozilla::HashMap<JS::Zone*, UniquePtr<EntryVector>,
|
||||
DefaultHasher<JS::Zone*>, InfallibleAllocPolicy>;
|
||||
|
||||
template <typename F>
|
||||
void ForEach(EntryVector& aJSHolders, const F& f, JS::Zone* aZone);
|
||||
class EntryVectorIter;
|
||||
|
||||
bool RemoveEntry(EntryVector& aJSHolders, Entry* aEntry);
|
||||
|
||||
|
@ -144,6 +143,35 @@ class JSHolderMap {
|
|||
EntryVectorMap mPerZoneJSHolders;
|
||||
};
|
||||
|
||||
// An iterator over an EntryVector that skips over removed entries and removes
|
||||
// them from the map.
|
||||
class JSHolderMap::EntryVectorIter {
|
||||
public:
|
||||
EntryVectorIter(JSHolderMap& aMap, EntryVector& aVector)
|
||||
: mHolderMap(aMap), mVector(aVector), mIter(aVector.Iter()) {
|
||||
Settle();
|
||||
}
|
||||
|
||||
const EntryVector& Vector() const { return mVector; }
|
||||
|
||||
bool Done() const { return mIter.Done(); }
|
||||
const Entry& Get() const { return mIter.Get(); }
|
||||
void Next() {
|
||||
mIter.Next();
|
||||
Settle();
|
||||
}
|
||||
|
||||
operator const Entry*() const { return &Get(); }
|
||||
const Entry* operator->() const { return &Get(); }
|
||||
|
||||
private:
|
||||
void Settle();
|
||||
|
||||
JSHolderMap& mHolderMap;
|
||||
EntryVector& mVector;
|
||||
EntryVector::IterImpl mIter;
|
||||
};
|
||||
|
||||
class CycleCollectedJSRuntime {
|
||||
friend class JSGCThingParticipant;
|
||||
friend class JSZoneParticipant;
|
||||
|
|
Загрузка…
Ссылка в новой задаче