Closed Bug 1181445 Opened 10 years ago Closed 10 years ago

Implement iterators for nsTHashtable and nsBaseHashtable and use them in xpcom/

Categories

(Core :: XPCOM, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla42
Tracking Status
firefox42 --- fixed

People

(Reporter: n.nethercote, Assigned: n.nethercote)

References

Details

Attachments

(13 files, 2 obsolete files)

6.40 KB, patch
froydnj
: review+
Details | Diff | Splinter Review
2.75 KB, patch
froydnj
: review+
Details | Diff | Splinter Review
1.82 KB, patch
froydnj
: review+
Details | Diff | Splinter Review
2.46 KB, patch
mccr8
: review+
Details | Diff | Splinter Review
10.01 KB, patch
froydnj
: review+
Details | Diff | Splinter Review
6.45 KB, patch
froydnj
: review+
Details | Diff | Splinter Review
2.44 KB, patch
froydnj
: review+
Details | Diff | Splinter Review
2.94 KB, patch
froydnj
: review+
Details | Diff | Splinter Review
7.32 KB, patch
mccr8
: review+
Details | Diff | Splinter Review
3.24 KB, patch
froydnj
: review+
Details | Diff | Splinter Review
2.14 KB, patch
froydnj
: review+
Details | Diff | Splinter Review
3.67 KB, patch
froydnj
: review+
Details | Diff | Splinter Review
8.48 KB, patch
n.nethercote
: review+
Details | Diff | Splinter Review
PLDHashTable got an iterator; its subclasses nsTHashtable and nsBaseHashtable deserve one too. As part of this bug I'll also convert the Enumerate()-style calls in xpcom/ to use the new iterators. This will give the new iterators a good workout to make sure they're designed reasonably.
nsBaseHashtable has both EnumerateRead() and Enumerate(). A comment claims that the latter locks the table, but this is false, so I removed the comment. Other than that the only notable difference between them is that they have slightly different types for dealing with values (|UserDataType| vs |DataType&|) so I've implemented both GetUserData() and GetData(), allowing either type to be used.
Attachment #8631418 - Flags: review?(nfroyd)
This is a particularly nice example of how iterators can be so much nicer than Enumerate()-style functions: 1 file changed, 4 insertions(+), 33 deletions(-)
Attachment #8631428 - Flags: review?(continuation)
Note that enumfunc_pentries and persistent_userstruct are unused, and so could be removed.
Attachment #8631436 - Flags: review?(nfroyd)
froydnj: apologies for the review dump. There's no rush on this. For parts 2--13, the diffstats are as follows: > 20 files changed, 253 insertions(+), 521 deletions(-)
I tweaked some variable names.
Attachment #8631451 - Flags: review?(nfroyd)
Attachment #8631421 - Attachment is obsolete: true
Attachment #8631421 - Flags: review?(nfroyd)
Comment on attachment 8631418 [details] [diff] [review] (part 1) - Implement iterators for nsTHashtable and nsBaseHashtable Review of attachment 8631418 [details] [diff] [review]: ----------------------------------------------------------------- I wonder if future patches could make the UserData/Data distinction go away...
Attachment #8631418 - Flags: review?(nfroyd) → review+
Comment on attachment 8631419 [details] [diff] [review] (part 2) - Use nsTHashTable::Iterator in nsMemoryReporterManager Review of attachment 8631419 [details] [diff] [review]: ----------------------------------------------------------------- ::: xpcom/base/nsMemoryReporterManager.cpp @@ +1434,5 @@ > { > mozilla::MutexAutoLock autoLock(mMutex); > + for (auto iter = mStrongReporters->Iter(); !iter.Done(); iter.Next()) { > + nsRefPtrHashKey<nsIMemoryReporter>* entry = iter.Get(); > + allReporters.AppendElement(entry->GetKey()); I have sometimes wondered whether we shouldn't have: nsTArray<T> Items(); or similar in our hash table classes...
Attachment #8631419 - Flags: review?(nfroyd) → review+
Comment on attachment 8631451 [details] [diff] [review] (part 3) - Use nsTHashTable::Iterator in nsObserverService Review of attachment 8631451 [details] [diff] [review]: ----------------------------------------------------------------- ::: xpcom/ds/nsObserverService.cpp @@ +75,5 @@ > NS_IMETHODIMP > nsObserverService::CollectReports(nsIHandleReportCallback* aHandleReport, > nsISupports* aData, bool aAnonymize) > { > ObserverServiceReferentCount referentCount; Maybe file a followup for turning this into a collection of local variables? I think that would consolidate the num{Strong,WeakAlive,WeakDead} handling below...
Attachment #8631451 - Flags: review?(nfroyd) → review+
Attachment #8631422 - Flags: review?(nfroyd) → review+
Attachment #8631436 - Flags: review?(nfroyd) → review+
Attachment #8631439 - Flags: review?(nfroyd) → review+
Attachment #8631440 - Flags: review?(nfroyd) → review+
Attachment #8631442 - Flags: review?(nfroyd) → review+
Attachment #8631445 - Flags: review?(nfroyd) → review+
Attachment #8631447 - Flags: review?(nfroyd) → review+
Attachment #8631449 - Flags: review?(nfroyd) → review+
Comment on attachment 8631428 [details] [diff] [review] (part 5) - Use nsTHashTable::Iterator in nsTHashtable.h Review of attachment 8631428 [details] [diff] [review]: ----------------------------------------------------------------- Nice.
Attachment #8631428 - Flags: review?(continuation) → review+
Comment on attachment 8631443 [details] [diff] [review] (part 10) - Use nsBaseHashTable::Iterator in CycleCollectedJSRuntime Review of attachment 8631443 [details] [diff] [review]: ----------------------------------------------------------------- Hooray. ::: xpcom/base/CycleCollectedJSRuntime.cpp @@ +477,5 @@ > CycleCollectedJSRuntime::UnmarkSkippableJSHolders() > { > + for (auto iter = mJSHolders.Iter(); !iter.Done(); iter.Next()) { > + void* holder = iter.GetKey(); > + nsScriptObjectTracer*& tracer = iter.GetData(); No real need for these intermediate variables, but this is fine, too. @@ +657,5 @@ > // NB: This is here just to preserve the existing XPConnect order. I doubt it > // would hurt to do this after the JS holders. > TraverseAdditionalNativeRoots(aCb); > > Closure closure(&aCb); This closure can be disentangled more but I can file a followup for that if you don't want to bother. In short: closure.mCb is aCb and the closure for TraceCallbackFunc can just become bool*. I just mashed together two different closures for convenience. @@ +817,5 @@ > > + for (auto iter = mJSHolders.Iter(); !iter.Done(); iter.Next()) { > + void* holder = iter.GetKey(); > + nsScriptObjectTracer*& tracer = iter.GetData(); > + tracer->Trace(holder, JsGcTracer(), aTracer); As above, the intermediate variables don't add much in my mind, but this is fine, too.
Attachment #8631443 - Flags: review?(continuation) → review+
Thank you for the fast reviews. > I wonder if future patches could make the UserData/Data distinction go > away... I don't know. The UserData/Data distinction is baked deeply into nsBaseHashtable: > template<class KeyClass, class DataType, class UserDataType> > class nsBaseHashtable; And GetData() returns a reference, while GetUserData() does not. My experiences with PLDHashTable refactoring has led me to be conservative with these kinds of changes, which is why I maintained the split. > Maybe file a followup for turning this into a collection of local variables? > I think that would consolidate the num{Strong,WeakAlive,WeakDead} handling > below... Good idea. I'll do it here, because this kind of unnecessary struct removal is very much in line with other changes made in this bug.
Blocks: 1182318
> > + for (auto iter = mJSHolders.Iter(); !iter.Done(); iter.Next()) { > > + void* holder = iter.GetKey(); > > + nsScriptObjectTracer*& tracer = iter.GetData(); > > No real need for these intermediate variables, but this is fine, too. I started off not using intermediates all that much. But then the more of these changes I made, the more I thought having the intermediates was a good idea -- in order to make the key/data types obvious, as is the case in the enumerate functions -- and I actually went back and added some intermediates in where I didn't have them previously. And this is doubly true for the GetData() cases where it's actually a reference being returned, which is not obvious. > > Closure closure(&aCb); > > This closure can be disentangled more but I can file a followup for that if > you don't want to bother. I filed bug 1182318.
Attachment #8631451 - Attachment is obsolete: true
Comment on attachment 8631886 [details] [diff] [review] (part 3) - Use nsTHashTable::Iterator in nsObserverService Review of attachment 8631886 [details] [diff] [review]: ----------------------------------------------------------------- Here's the version of part 3 that removes ObserverServiceReferentCount. Carrying over r+ because it's not a big change (though it is a nice one).
Attachment #8631886 - Flags: review+
Was it an intentional decision to make the iterators not support ranged-based for loops? It would be nice if we could replace for (auto iter = mTagged.Iter(); !iter.Done(); iter.Next()) { with for (auto iter : mTagged) {
> Here's the version of part 3 that removes ObserverServiceReferentCount. > Carrying over r+ because it's not a big change (though it is a nice one). ... and I messed that up and caused bug 1182926, alas.
(In reply to Markus Stange [:mstange] from comment #28) > Was it an intentional decision to make the iterators not support > ranged-based for loops? It would be nice if we could replace > for (auto iter = mTagged.Iter(); !iter.Done(); iter.Next()) { > with > for (auto iter : mTagged) { Bug 1180122 is going to reinstate Chaos Mode support for PLDHashTable::Iterator. This means that the starting point for hash table iteration is potentially randomized, and with that in place I don't see how the required begin(), end() and operator!=() methods can be made to work as required for range-based for loops. This doesn't worry me that much. Going from enumerate-style functions to iteration is a big improvement. Going from traditional iterator loops to range-based loops is a much smaller improvement.
(In reply to Nicholas Nethercote [:njn] from comment #30) > (In reply to Markus Stange [:mstange] from comment #28) > > Was it an intentional decision to make the iterators not support > > ranged-based for loops? It would be nice if we could replace > > for (auto iter = mTagged.Iter(); !iter.Done(); iter.Next()) { > > with > > for (auto iter : mTagged) { > > Bug 1180122 is going to reinstate Chaos Mode support for > PLDHashTable::Iterator. This means that the starting point for hash table > iteration is potentially randomized, and with that in place I don't see how > the required begin(), end() and operator!=() methods can be made to work as > required for range-based for loops. > > This doesn't worry me that much. Going from enumerate-style functions to > iteration is a big improvement. Going from traditional iterator loops to > range-based loops is a much smaller improvement. That makes sense. I agree that having iterators at all is a much bigger improvement. Thanks!
FWIW, bug 1149833 is open for doing range-based iterators for the hash tables. It's probably possible, it'll just require some thinking.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: