Closed Bug 206321 Opened 22 years ago Closed 21 years ago

Share event listeners between XBL event handlers

Categories

(Core :: XBL, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla1.6alpha

People

(Reporter: peterv, Assigned: peterv)

References

()

Details

Attachments

(3 files, 1 obsolete file)

Right now we create one event listener for every XBL event handler. This leads to bloat, especially with multiple key handlers per binding (see bug 148636). There's several ways we can share event listeners. First of all we can share the listener only for key handlers or for all handlers. Second we could share the listener per binding or we could share them across bindings. I tried implementing sharing for all listeners and per binding. However, thinking about this it seems suboptimal, since I doubt we have many non-key handlers per binding. A shared listener can be uniquely identified by 1) target 2) event type 3) use capture 4) is command Sharing listeners across bindings would probably mean having a mapping through a hashtable (in the binding manager?) with those 4 properties as key. If we implement the sharing per binding we can probably use an array since the target is constant and there wouldn't be that many variations of 2, 3 and 4 per binding. This does mean we end up with more listeners though. Anyone have thoughts on this?
Attached patch WIP (obsolete) (deleted) — Splinter Review
This makes us have one handler per nsXBLPrototypeHandler, except for key handlers which have one handler per type/capture/eventgroup per nsXBLPrototypeBinding (one per nsXBLPrototypeBinding in the most common case). Reduces bloat and seems to mostly improve performance, but I need to verify my testing.
Attachment #125043 - Flags: review?(jkeiser)
Attachment #125043 - Flags: superreview?(bryner)
Attached patch Files that can be removed (deleted) — Splinter Review
Comment on attachment 125043 [details] [diff] [review] WIP Sorry I haven't gotten to this yet... is the attachment description "WIP" accurate, or do you think this is functionally complete?
I originally marked it WIP because I wasn't sure about the approach I took. I still welcome comments on the ideas behind the patch, but I now feel more confident that this is the right way, I've been running with the patch for a while and so far I haven't run into regressions. One thing that worries me is the removal of nsXBLEventHandler::MarkForDeath, which used to null out mProtoHandler and mEventReceiver in nsXBLBinding::ChangeDocument. I don't do that anymore, since mEventReceiver is gone and mProtoHandler could be needed by another nsXBLBinding which uses the same handler object. Here's some performance test results (I haven't been able to get reliable startup times). New window open: * without patch avgOpenTime:593 minOpenTime:562 maxOpenTime:688 medOpenTime:572.5 * with patch avgOpenTime:589 minOpenTime:551 maxOpenTime:687 medOpenTime:573 Pageload: * without patch Avg. Median : 1589 msec Minimum : 407 msec Average : 1880 msec Maximum : 7601 msec * with patch Avg. Median : 1581 msec Minimum : 396 msec Average : 1870 msec Maximum : 7313 msec
Status: NEW → ASSIGNED
This is great! I really want this. If this is implemented then we can stop scrollbars from bubbling mouse events by just attaching the right <handler>s to the <scrollbar> XBL, without bloating.
Comment on attachment 125043 [details] [diff] [review] WIP >Index: src/nsXBLBinding.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/xbl/src/nsXBLBinding.cpp,v >retrieving revision 1.161 >diff -u -p -r1.161 nsXBLBinding.cpp >--- src/nsXBLBinding.cpp 21 May 2003 03:14:47 -0000 1.161 >+++ src/nsXBLBinding.cpp 5 Jun 2003 22:36:47 -0000 >@@ -1083,10 +869,71 @@ nsXBLBinding::ExecuteDetachedHandler() > NS_IMETHODIMP > nsXBLBinding::UnhookEventHandlers() > { >- if (mFirstHandler) { >- // Unhook our event handlers. >- mFirstHandler->RemoveEventHandlers(); >- mFirstHandler = nsnull; >+ nsXBLPrototypeHandler* handlerChain = mPrototypeBinding->GetPrototypeHandlers(); >+ >+ if (handlerChain) { >+ nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(mBoundElement); >+ nsCOMPtr<nsIDOM3EventTarget> target = do_QueryInterface(receiver); >+ nsCOMPtr<nsIDOMEventGroup> systemEventGroup; >+ >+ nsXBLPrototypeHandler* curr; >+ for (curr = handlerChain; curr; curr = curr->GetNextHandler()) { >+ nsXBLEventHandler* handler = curr->GetCachedEventHandler(); >+ if (handler) { >+ nsCOMPtr<nsIAtom> eventAtom = curr->GetEventName(); >+ if (!eventAtom) >+ continue; >+ >+ nsAutoString type; >+ eventAtom->ToString(type); >+ >+ // Figure out if we're using capturing or not. >+ PRBool useCapture = (curr->GetPhase() == NS_PHASE_CAPTURING); >+ >+ // If this is a command, remove it from the system event group, otherwise >+ // remove it from the standard event group. >+ >+ // This is a weak ref. systemEventGroup above is already a >+ // strong ref, so we are guaranteed it will not go away. >+ nsIDOMEventGroup* eventGroup = nsnull; >+ if (curr->GetType() & NS_HANDLER_TYPE_XBL_COMMAND) { >+ if (!systemEventGroup) >+ receiver->GetSystemEventGroup(getter_AddRefs(systemEventGroup)); >+ eventGroup = systemEventGroup; >+ } >+ >+ target->RemoveGroupedEventListener(type, handler, useCapture, >+ eventGroup); >+ } >+ } Won't the key handlers be in the list of prototype handlers? So you need to check that it's not a key handler before removing it here, like you do up in InstallEventHandlers()? >Index: src/nsXBLEventHandler.cpp >=================================================================== >RCS file: /cvsroot/mozilla/content/xbl/src/nsXBLEventHandler.cpp,v >retrieving revision 1.62 >diff -u -p -r1.62 nsXBLEventHandler.cpp >--- src/nsXBLEventHandler.cpp 24 Mar 2003 04:00:58 -0000 1.62 >+++ src/nsXBLEventHandler.cpp 5 Jun 2003 22:36:47 -0000 >@@ -40,127 +40,159 @@ >+nsresult >+nsXBLEventHandler::HandleEvent(nsIDOMEvent* aEvent) should be NS_IMETHODIMP, no? > nsresult >-nsXBLEventHandler::GetTextData(nsIContent *aParent, nsAString& aResult) >+nsXBLKeyEventHandler::HandleEvent(nsIDOMEvent* aEvent) Same here. Looks good otherwise. I don't anticipate any problems with the MarkForDeath() change you did. Thanks for cleaning this up!
Attachment #125043 - Flags: superreview?(bryner) → superreview+
Attached patch v1.1 (deleted) — Splinter Review
Attachment #125043 - Attachment is obsolete: true
Comment on attachment 130647 [details] [diff] [review] v1.1 Addressed bryner's comments.
Attachment #130647 - Flags: superreview+
Attachment #130647 - Flags: review?(john)
Attachment #130647 - Flags: review?(john) → review+
Priority: -- → P1
Target Milestone: --- → mozilla1.6alpha
Attachment #125043 - Flags: review?(john)
Blocks: 215928
It would be great if we can land this soon :-)
Looks like peterv already checked this in. Is this what made tinderbox leaks go up ? http://tinderbox.mozilla.org/showlog.cgi?log=SeaMonkey/1063289340.19217.gz Bloat/Leak Delta Report -------------------------------------------------------------------------------------- Current file: /mnt/4/tinderbox/brad/Linux_2.4.20abackupboy3_Clobber/bloat-cur.log Previous file: /mnt/4/tinderbox/brad/Linux_2.4.20abackupboy3_Clobber/bloat-prev.log ----------------------------------------------leaks------leaks%------bloat------bloat% TOTAL 584 121.21% 14755328 -0.33% --NEW-LEAKS-----------------------------------leaks------leaks%----------------------- nsVoidArray 80 - nsXBLKeyEventHandler 240 - TOTAL 320
Attached patch Fix leaks (deleted) — Splinter Review
Yeah, those leaks are mine, this patch should fix it but I'm still building to verify. I was double-addrefing by creating into a raw pointer (1st addref) and then calling AppendObject (2nd addref) and only releasing once (in the destructor of the nsCOMArray).
Attachment #131331 - Flags: superreview?(bryner)
Attachment #131331 - Flags: review?(keeda)
Comment on attachment 131331 [details] [diff] [review] Fix leaks Makes sense and it does fix the problem (I checked.)
Attachment #131331 - Flags: review?(keeda) → review+
Attachment #131331 - Flags: superreview?(bryner) → superreview+
Checked in leak fix too (bonsai didn't record that checkin or the removal of files from attachment 129309 [details] [diff] [review]). mZ (and Z) went down by about 15k on Linux, about 6k on Windows. Brad also recorded a reduction in Maximum Heap from 7.98M to 7.96M and a reduction in Allocations from 234K to 230K. No idea if those are reliable numbers and real reductions or not. Still, on the bloat test the number of nsXBLEventHandlers went down from 1530 to 38 nsXBLEventHandlers and 10 nsXBLKeyEventHandlers so I'm hoping for some good results for bug 148636.
Status: ASSIGNED → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
This checkin have added a warning on brad TBox: +content/xbl/src/nsXBLPrototypeBinding.cpp:1284 + `nsXBLKeyEventHandler*handler' might be used uninitialized in this function
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: