Open Bug 901753 Opened 12 years ago Updated 1 year ago

Switch nsObserverList to use mozilla::MaybeWeakMultiset

Categories

(Core :: XPCOM, defect)

defect

Tracking

()

People

(Reporter: justin.lebar+bug, Unassigned)

References

(Depends on 1 open bug)

Details

(Whiteboard: [MemShrink:P3])

Attachments

(1 file, 1 obsolete file)

Right now nsObserverList implements weak observers by adding nsIWeakReference objects to a list and, when the observer fires, removing those weakrefs from the list. This is not optimal when the observer in question fires infrequently. For example, if you register a weak xpcom-shutdown observer, that nsIWeakReference object is leaked essentially forever. mozilla::WeakSet solves this problem, and as proof-of-concept, I've converted nsObserverList to use it.
I don't expect this will save a ton of memory, but it might be more relevant change elsewhere.
Whiteboard: [MemShrink]
Attached patch Patch, v1 (obsolete) — Splinter Review
Attachment #786022 - Flags: review?(benjamin)
Assignee: nobody → justin.lebar+bug
Whiteboard: [MemShrink] → [MemShrink:P3]
Comment on attachment 786022 [details] [diff] [review] Patch, v1 Observers must fire in FILO order for compatibility. We can't use a hashset for them.
Attachment #786022 - Flags: review?(benjamin) → review-
That's a bummer. I'll have to implement a linked hashset then, because I'm /sick and tired/ of us using O(n) algorithms where O(1) is easy. http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html
Sounds like I should just write a class which lets you add strong or weak refs and iterate over them in order. We could use this in the observer service and in the message manager.
(In reply to Benjamin Smedberg) > Observers must fire in FILO order for compatibility. We can't use a hashset > for them. Right now the observer list allows duplicate observers. Do we have to keep that behavior as well? Doing so essentially forces us to use a list, which would be unfortunate from an asymptotic PoV. (With a list, a weakref being destroyed could cause an O(n) operation in the observer service. This seems like a pretty bad footgun.)
dbaron, do you know if we need to preserve the current behavior of the observer service, where it allows you to register the same observer multiple times? This is doable, but I don't want to write the data structure if we don't need it.
Flags: needinfo?(dbaron)
I don't know. I guess if you wanted to try not preserving it, you could at least add assertions to catch cases where we were depending on it.
Flags: needinfo?(dbaron)
I guess I could add assertions to catch when we add a duplicate observer, but of course that assertion may trip for places where we don't depend on getting duplicate notifications.
I guess the better question is, do we feel like this behavior is something we need to preserve for add-ons? We can fix instances in the tree... Given that add-ons have committed every bug conceivable, I suppose we probably do want to preserve the current behavior for add-ons. Duplicate notifications might not be as big an issue as the fact that, if we only store one ref to a given observer, then the first remove() call will remove the observer, while before you'd have to remove() an observer once for every time you added it.
I don't have a good answer about how likely it is that addons register the same observer multiple times. Options are: A. add telemetry for multiply-registered observers and see what it says (low risk, high lead time) B. assert/fail if an observer is registered multiple times (medium risk) C. register with a counter so that multiple registrations continue to work (with slightly different ordering, but I highly doubt that matters) (low risk, low lead time, slightly more complex) Given lack of data, I'm more comfortable with A or C (both would be ok also).
Summary: Switch nsObserverList to use mozilla::WeakSet → Switch nsObserverList to use mozilla::MaybeWeakMultiset
Attached patch Patch, v2Splinter Review
This is ready for review, but I want to get at least preliminary f+ on the patches this depends on before asking someone to look at it. This patch should not affect the externally-observable behavior of the observer service in any way.
Attachment #786022 - Attachment is obsolete: true
khuey, you want this one too?
Flags: needinfo?(khuey)
See Also: → 1052138
While this would be nice, I don't think I'm going to have time to work on it, seeing as I haven't in the last year :/
Flags: needinfo?(khuey)
Assignee: justin.lebar+bug → nobody
I'm going to assume Justin is not actively working on this either...
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: