Closed Bug 1834370 Opened 1 year ago Closed 1 year ago

Optimize listener iteration in EventListenerManager::HandleEventInternal

Categories

(Core :: DOM: Events, task)

task

Tracking

()

RESOLVED FIXED
118 Branch
Tracking Status
firefox118 --- fixed

People

(Reporter: mstange, Assigned: mstange)

References

(Blocks 1 open bug)

Details

(Whiteboard: [sp3], [wptsync upstream])

Attachments

(7 files, 7 obsolete files)

(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
(deleted), text/x-phabricator-request
Details
No description provided.
Whiteboard: [sp3]

This is a 25% improvement on the microbenchmarks in bug 1834003 on my machine.

This patch optimizes the "stop immediate propagation" check, and it also seems
to be faster for other reasons which I don't fully understand. Somehow, with
the new iterator, the mIter < mEnd check is much faster than before.

Ah, the 25% improvement is already achieved by PGO. The patch just helps my local build to achieve the same performance as a regular Nightly.

I haven't understood how exactly the compiler's decisions can make such a big difference on this testcase.

This patch pulls out some code into a new method called HandleEventSingleListener.

It also optimizes the "stop immediate propagation" check to only happen
at the start of the loop and when a listener is found.

Furthermore, before this patch, my local arm64 build was 30% slower on the
microbenchmarks in bug 1834003 compared to a Nightly build, presumably
due to different compiler optimizations. With this patch, we seem to hit
the happy path even in the local build, and the local build now slightly
exceeds the performance of the Nightly build. I haven't fully understood how
exactly the generated code differs that it makes such a big difference.

Depends on D178738

This is a 25% improvement on the microbenchmarks in bug 1834003.

Unidentified events still have to search the entire list.
Maybe we can turn some unidentified events into identified events
(such as checkbox "input") so that these events can take advantage
of the fast path.

Depends on D178741

Attachment #9335287 - Attachment is obsolete: true

(In reply to Markus Stange [:mstange] from comment #2)

Without patch: https://share.firefox.dev/45l7Ry6
With patch: https://share.firefox.dev/3owfyAN

With binary search: https://share.firefox.dev/3q3TQom

mozilla::CompactPair doesn't seem appropriate because its base class optimization doesn't apply.

Depends on D178741

Chrome's implementation seems quite a bit simpler; they just have a Map<Atom, ListenerArray> (where the map is a HeapVector).
Here's a Chrome profile of the same testcase, with a working source view: https://share.firefox.dev/3opqvEg
The map lookup is in blink::EventTarget::FireEventListeners(blink::Event*).

Comment on attachment 9335503 [details]
WIP: Bug 1834370 - Make EqualRange return a std::pair.

Revision D178843 was moved to bug 1843181. Setting attachment 9335503 [details] to obsolete.

Attachment #9335503 - Attachment is obsolete: true

This considerably improves the testcase in bug 1834003, because it
reduces the amount of memory we need to look at when checking the
listeners at the nsWindowRoot. At the moment, nsWindowRoot has 156
listeners for 94 different event types, all from JSWindowActor event
listeners.

Having a separate array per event type also matches what Blink and Webkit do.

Depends on D178738

Attachment #9335357 - Attachment is obsolete: true
Attachment #9335358 - Attachment is obsolete: true
Attachment #9335359 - Attachment is obsolete: true
Attachment #9335360 - Attachment is obsolete: true
Attachment #9335355 - Attachment description: WIP: Bug 1834370 - Refactor EventListenerManager::HandleEventInternal a bit. → WIP: Bug 1834370 - Refactor EventListenerManager::HandleEventInternal a bit. r=smaug
Attachment #9335356 - Attachment description: WIP: Bug 1834370 - Use an iterator to iterate over just the listeners which match the event. → WIP: Bug 1834370 - Use an iterator to iterate over just the listeners which match the event. r=smaug
Attachment #9343595 - Attachment description: WIP: Bug 1834370 - Keep listeners for each event type in a separate array, and use binary search on the outer list. → WIP: Bug 1834370 - Keep listeners for each event type in a separate array, and use binary search on the outer list. r=smaug

The type atom is already stored on the ListenerMapEntry.

Depends on D183431

Attachment #9335355 - Attachment description: WIP: Bug 1834370 - Refactor EventListenerManager::HandleEventInternal a bit. r=smaug → Bug 1834370 - Refactor EventListenerManager::HandleEventInternal a bit. r=smaug
Attachment #9335356 - Attachment description: WIP: Bug 1834370 - Use an iterator to iterate over just the listeners which match the event. r=smaug → Bug 1834370 - Use an iterator to iterate over just the listeners which match the event. r=smaug
Attachment #9343595 - Attachment description: WIP: Bug 1834370 - Keep listeners for each event type in a separate array, and use binary search on the outer list. r=smaug → Bug 1834370 - Keep listeners for each event type in a separate array, and use binary search on the outer list. r=smaug
Attachment #9345456 - Attachment description: WIP: Bug 1834370 - Remove Listener::mTypeAtom to save memory. r=smaug → Bug 1834370 - Remove Listener::mTypeAtom to save memory. r=smaug
Attachment #9345457 - Attachment description: WIP: Bug 1834370 - Remove Listener::mEventMessage and ListenerSignalFollower::mEventMessage. r=smaug → Bug 1834370 - Remove Listener::mEventMessage and ListenerSignalFollower::mEventMessage. r=smaug
Depends on: 1845381
Attachment #9335356 - Attachment is obsolete: true
Pushed by opettay@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/fa5f05b1f6a1
Refactor EventListenerManager::HandleEventInternal a bit. r=smaug
https://hg.mozilla.org/integration/autoland/rev/6a8a7bccbfef
Keep listeners for each event type in a separate array, and use binary search on the outer list. r=smaug
https://hg.mozilla.org/integration/autoland/rev/00077ebdbfe6
Remove Listener::mTypeAtom to save memory. r=smaug
https://hg.mozilla.org/integration/autoland/rev/d279ac4c2c01
Remove Listener::mEventMessage and ListenerSignalFollower::mEventMessage. r=smaug
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/41267 for changes under testing/web-platform/tests
Whiteboard: [sp3] → [sp3], [wptsync upstream]

Backed out for causing assertion failures on EventListenerManager.cpp.
LATER EDIT: this appeared later mochitest-plain crash

[task 2023-08-01T03:41:14.650Z] 03:41:14     INFO - GECKO(4912) | [Child 5107, Main Thread] WARNING: NS_ENSURE_SUCCESS(rv, NS_OK) failed with result 0x80004005 (NS_ERROR_FAILURE): file /builds/worker/checkouts/gecko/caps/BasePrincipal.cpp:1150
[task 2023-08-01T03:41:14.830Z] 03:41:14     INFO - GECKO(4912) | Assertion failure: !listeners->IsEmpty(), at /builds/worker/checkouts/gecko/dom/events/EventListenerManager.cpp:1847
[task 2023-08-01T03:41:14.839Z] 03:41:14     INFO -  Initializing stack-fixing for the first stack frame, this may take a while...
[task 2023-08-01T03:41:43.021Z] 03:41:43     INFO - GECKO(4912) | #01: mozilla::EventListenerManager::HasListenersForInternal(nsAtom*, bool) const [dom/events/EventListenerManager.cpp:1847]
[task 2023-08-01T03:41:43.023Z] 03:41:43     INFO - GECKO(4912) | #02: nsGlobalWindowInner::EventListenerRemoved(nsAtom*) [dom/base/nsGlobalWindowInner.cpp:6585]
[task 2023-08-01T03:41:43.025Z] 03:41:43     INFO - GECKO(4912) | #03: mozilla::EventListenerManager::NotifyEventListenerRemoved(nsAtom*) [dom/events/EventListenerManager.cpp:814]
[task 2023-08-01T03:41:43.027Z] 03:41:43     INFO - GECKO(4912) | #04: mozilla::EventListenerManager::RemoveAllListeners() [dom/events/EventListenerManager.cpp:2258]
[task 2023-08-01T03:41:43.029Z] 03:41:43     INFO - GECKO(4912) | #05: nsGlobalWindowInner::FreeInnerObjects() [dom/base/nsGlobalWindowInner.cpp:1151]
[task 2023-08-01T03:41:43.030Z] 03:41:43     INFO - GECKO(4912) | #06: nsGlobalWindowOuter::DetachFromDocShell(bool) [dom/base/nsGlobalWindowOuter.cpp:2691]
[task 2023-08-01T03:41:43.031Z] 03:41:43     INFO - GECKO(4912) | #07: nsDocShell::Destroy() [docshell/base/nsDocShell.cpp:4574]
[task 2023-08-01T03:41:43.033Z] 03:41:43     INFO - GECKO(4912) | #08: nsWebBrowser::SetDocShell(nsDocShell*) [toolkit/components/browser/nsWebBrowser.cpp:1145]
[task 2023-08-01T03:41:43.036Z] 03:41:43     INFO - GECKO(4912) | #09: nsWebBrowser::InternalDestroy() [toolkit/components/browser/nsWebBrowser.cpp:177]
[task 2023-08-01T03:41:43.038Z] 03:41:43     INFO - GECKO(4912) | #10: {virtual override thunk({offset(-24)}, nsWebBrowser::Destroy())} [toolkit/components/browser/nsWebBrowser.cpp:0]
[task 2023-08-01T03:41:43.039Z] 03:41:43     INFO - GECKO(4912) | #11: mozilla::dom::BrowserChild::DestroyWindow() [dom/ipc/BrowserChild.cpp:761]
[task 2023-08-01T03:41:43.041Z] 03:41:43     INFO - GECKO(4912) | #12: mozilla::dom::BrowserChild::RecvDestroy() [dom/ipc/BrowserChild.cpp:2469]
[task 2023-08-01T03:41:43.042Z] 03:41:43     INFO - GECKO(4912) | #13: mozilla::dom::PBrowserChild::OnMessageReceived(IPC::Message const&) [s3:gecko-generated-sources:1f772eaeff40bf8b53eb5f538daa9ccf380923a3937d9cb5eead4dfc5fab7f296195e818ec9ed4568408861cf4cec0c483067a1d7ffd221dcb9bca8d8ec0d1d9/ipc/ipdl/PBrowserChild.cpp::0]
[task 2023-08-01T03:41:43.043Z] 03:41:43     INFO - GECKO(4912) | #14: mozilla::dom::PContentChild::OnMessageReceived(IPC::Message const&) [s3:gecko-generated-sources:f4ff06a727cd518f4bfa2957308e03321499387ed52f73ab59281475a3ed1b0f19916bbcfec6fe92671175751e43e7893997263f366ac17da5c0694ec63a00b8/ipc/ipdl/PContentChild.cpp::8671]
[task 2023-08-01T03:41:43.045Z] 03:41:43     INFO - GECKO(4912) | #15: mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) [ipc/glue/MessageChannel.cpp:1811]
[task 2023-08-01T03:41:43.046Z] 03:41:43     INFO - GECKO(4912) | #16: mozilla::ipc::MessageChannel::DispatchMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::UniquePtr<IPC::Message, mozilla::DefaultDelete<IPC::Message> >) [ipc/glue/MessageChannel.cpp:1739]
[task 2023-08-01T03:41:43.047Z] 03:41:43     INFO - GECKO(4912) | #17: mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::ipc::MessageChannel::MessageTask&) [ipc/glue/MessageChannel.cpp:1536]
[task 2023-08-01T03:41:43.048Z] 03:41:43     INFO - GECKO(4912) | #18: mozilla::ipc::MessageChannel::MessageTask::Run() [ipc/glue/MessageChannel.cpp:1643]
[task 2023-08-01T03:41:43.050Z] 03:41:43     INFO - GECKO(4912) | #19: mozilla::RunnableTask::Run() [xpcom/threads/TaskController.cpp:560]
[task 2023-08-01T03:41:43.051Z] 03:41:43     INFO - GECKO(4912) | #20: mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) [xpcom/threads/TaskController.cpp:886]
[task 2023-08-01T03:41:43.052Z] 03:41:43     INFO - GECKO(4912) | #21: mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) [xpcom/threads/TaskController.cpp:0]
[task 2023-08-01T03:41:43.054Z] 03:41:43     INFO - GECKO(4912) | #22: mozilla::TaskController::ProcessPendingMTTask(bool) [xpcom/threads/TaskController.cpp:495]
[task 2023-08-01T03:41:43.055Z] 03:41:43     INFO - GECKO(4912) | #23: mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_1>::Run() [xpcom/threads/nsThreadUtils.h:549]
[task 2023-08-01T03:41:43.056Z] 03:41:43     INFO - GECKO(4912) | #24: nsThread::ProcessNextEvent(bool, bool*) [xpcom/threads/nsThread.cpp:1203]
[task 2023-08-01T03:41:43.057Z] 03:41:43     INFO - GECKO(4912) | #25: NS_ProcessNextEvent(nsIThread*, bool) [xpcom/threads/nsThreadUtils.cpp:480]
[task 2023-08-01T03:41:43.059Z] 03:41:43     INFO - GECKO(4912) | #26: mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) [ipc/glue/MessagePump.cpp:0]
[task 2023-08-01T03:41:43.060Z] 03:41:43     INFO - GECKO(4912) | #27: MessageLoop::Run() [ipc/chromium/src/base/message_loop.cc:346]
[task 2023-08-01T03:41:43.061Z] 03:41:43     INFO - GECKO(4912) | #28: nsBaseAppShell::Run() [widget/nsBaseAppShell.cpp:150]
[task 2023-08-01T03:41:43.062Z] 03:41:43     INFO - GECKO(4912) | #29: XRE_RunAppShell() [toolkit/xre/nsEmbedFunctions.cpp:717]
[task 2023-08-01T03:41:43.063Z] 03:41:43     INFO - GECKO(4912) | #30: mozilla::ipc::MessagePumpForChildProcess::Run(base::MessagePump::Delegate*) [ipc/glue/MessagePump.cpp:235]
[task 2023-08-01T03:41:43.064Z] 03:41:43     INFO - GECKO(4912) | #31: MessageLoop::Run() [ipc/chromium/src/base/message_loop.cc:346]
[task 2023-08-01T03:41:43.066Z] 03:41:43     INFO - GECKO(4912) | #32: XRE_InitChildProcess(int, char**, XREChildData const*) [toolkit/xre/nsEmbedFunctions.cpp:0]
[task 2023-08-01T03:41:43.180Z] 03:41:43     INFO - GECKO(4912) | #33: content_process_main(mozilla::Bootstrap*, int, char**) [ipc/contentproc/plugin-container.cpp:58]
[task 2023-08-01T03:41:43.184Z] 03:41:43     INFO - GECKO(4912) | #34: main [browser/app/nsBrowserApp.cpp:375]
[task 2023-08-01T03:41:43.206Z] 03:41:43     INFO - GECKO(4912) | #35: __libc_start_main [/lib/x86_64-linux-gnu/libc.so.6 + 0x21b97]
[task 2023-08-01T03:41:43.208Z] 03:41:43     INFO - GECKO(4912) | #36: ??? [/builds/worker/workspace/build/application/firefox/firefox-bin + 0x455c9]
[task 2023-08-01T03:41:43.211Z] 03:41:43     INFO - GECKO(4912) | #37: ??? (???:???)
[task 2023-08-01T03:41:43.211Z] 03:41:43     INFO - GECKO(4912) | [Child 5107, Main Thread] WARNING: NS_ENSURE_SUCCESS(rv, NS_OK) failed with result 0x80004005 (NS_ERROR_FAILURE): file /builds/worker/checkouts/gecko/caps/BasePrincipal.cpp:1150
[task 2023-08-01T03:41:43.211Z] 03:41:43     INFO - GECKO(4912) | [Child 5107, Main Thread] WARNING: NS_ENSURE_SUCCESS(rv, NS_OK) failed with result 0x80004005 (NS_ERROR_FAILURE): file /builds/worker/checkouts/gecko/caps/BasePrincipal.cpp:1150
[task 2023-08-01T03:41:43.212Z] 03:41:43     INFO - GECKO(4912) | [Child 5107, Main Thread] WARNING: NS_ENSURE_SUCCESS(rv, NS_OK) failed with result 0x80004005 (NS_ERROR_FAILURE): file /builds/worker/checkouts/gecko/caps/BasePrincipal.cpp:1150
[task 2023-08-01T03:41:43.214Z] 03:41:43     INFO - GECKO(4912) | [Child 5107, Main Thread] WARNING: NS_ENSURE_SUCCESS(rv, NS_OK) failed with result 0x80004005 (NS_ERROR_FAILURE): file /builds/worker/checkouts/gecko/caps/BasePrincipal.cpp:1150
[task 2023-08-01T03:41:43.215Z] 03:41:43     INFO - GECKO(4912) | [Parent 4912, Compositor] WARNING: Possibly dropping task posted to updater thread: file /builds/worker/checkouts/gecko/gfx/layers/apz/src/APZUpdater.cpp:371
[task 2023-08-01T03:41:43.216Z] 03:41:43     INFO - GECKO(4912) | Assertion failure: !listeners->IsEmpty(), at /builds/worker/checkouts/gecko/dom/events/EventListenerManager.cpp:1847
<...>
Flags: needinfo?(mstange.moz)
Upstream PR was closed without merging

Ah, the assertion is just wrong

Pushed by opettay@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/70fea1f92e87
Refactor EventListenerManager::HandleEventInternal a bit. r=smaug
https://hg.mozilla.org/integration/autoland/rev/2cb41429ffea
Keep listeners for each event type in a separate array, and use binary search on the outer list. r=smaug
https://hg.mozilla.org/integration/autoland/rev/ad2415f36294
Remove Listener::mTypeAtom to save memory. r=smaug
https://hg.mozilla.org/integration/autoland/rev/0f6ca90bab38
Remove Listener::mEventMessage and ListenerSignalFollower::mEventMessage. r=smaug

Backed out for causing failures on pointerevent_mouse-on-object.html and hazard failures on EventListenerManager.cpp

[task 2023-08-01T17:10:57.257Z] 17:10:57     INFO - TEST-START | /pointerevents/compat/pointerevent_mouse-on-object.html
[task 2023-08-01T17:10:57.262Z] 17:10:57     INFO - Closing window b4168bf8-019c-4eb7-a763-f097c7f43409
[task 2023-08-01T17:10:57.727Z] 17:10:57     INFO - {'actions': [{'type': 'none', 'actions': [{'type': 'pause', 'duration': 16}, {'type': 'pause', 'duration': 16}, {'type': 'pause', 'duration': 16}], 'id': '0'}, {'type': 'pointer', 'actions': [{'type': 'pointerMove', 'x': 13, 'y': 331, 'origin': 'viewport'}, {'type': 'pointerDown', 'button': 0}, {'type': 'pointerUp', 'button': 0}], 'parameters': {'pointerType': 'mouse'}, 'id': '1'}]}
[task 2023-08-01T17:10:57.819Z] 17:10:57     INFO - {'actions': [{'type': 'none', 'actions': [{'type': 'pause', 'duration': 16}, {'type': 'pause', 'duration': 16}, {'type': 'pause', 'duration': 16}], 'id': '2'}, {'type': 'pointer', 'actions': [{'type': 'pointerMove', 'x': 0, 'y': 0, 'origin': {'element-6066-11e4-a52e-4f735466cecf': '8757b5fb-231e-431b-a7d4-58a09e1903a7'}}, {'type': 'pointerDown', 'button': 0}, {'type': 'pointerUp', 'button': 0}], 'parameters': {'pointerType': 'mouse'}, 'id': 'mousePointer1'}]}
[task 2023-08-01T17:10:57.913Z] 17:10:57     INFO - {'actions': [{'type': 'none', 'actions': [{'type': 'pause', 'duration': 16}, {'type': 'pause', 'duration': 16}, {'type': 'pause', 'duration': 16}, {'type': 'pause', 'duration': 16}], 'id': '3'}, {'type': 'pointer', 'actions': [{'type': 'pointerMove', 'x': 13, 'y': 331, 'origin': 'viewport'}, {'type': 'pointerDown', 'button': 0}, {'type': 'pointerMove', 'x': 3, 'y': 321, 'origin': 'viewport'}, {'type': 'pointerUp', 'button': 0}], 'parameters': {'pointerType': 'mouse'}, 'id': '4'}]}
[task 2023-08-01T17:10:58.014Z] 17:10:58     INFO - {'actions': [{'type': 'none', 'actions': [{'type': 'pause', 'duration': 16}, {'type': 'pause', 'duration': 16}, {'type': 'pause', 'duration': 16}], 'id': '5'}, {'type': 'pointer', 'actions': [{'type': 'pointerMove', 'x': 0, 'y': 0, 'origin': {'element-6066-11e4-a52e-4f735466cecf': '8757b5fb-231e-431b-a7d4-58a09e1903a7'}}, {'type': 'pointerDown', 'button': 0}, {'type': 'pointerUp', 'button': 0}], 'parameters': {'pointerType': 'mouse'}, 'id': 'mousePointer1'}]}
[task 2023-08-01T17:10:58.109Z] 17:10:58     INFO - 
[task 2023-08-01T17:10:58.109Z] 17:10:58     INFO - TEST-UNEXPECTED-FAIL | /pointerevents/compat/pointerevent_mouse-on-object.html | Normal click event sequence within object - assert_array_equals: Click on object should result in the correct sequence of mouse events lengths differ, expected array ["mousemove", "mousedown", "mouseup"] length 3, got ["mousemove"] length 1
[task 2023-08-01T17:10:58.109Z] 17:10:58     INFO - @http://web-platform.test:8000/pointerevents/compat/pointerevent_mouse-on-object.html:90:24
[task 2023-08-01T17:10:58.110Z] 17:10:58     INFO - .
[task 2023-08-01T17:10:58.110Z] 17:10:58     INFO - TEST-OK | /pointerevents/compat/pointerevent_mouse-on-object.html | took 854ms
Upstream PR was closed without merging

(In reply to Natalia Csoregi [:nataliaCs] from comment #24)

Backed out for causing failures on pointerevent_mouse-on-object.html

I found the cause for this failure. The test contains a call to preventDefault in a passive listener. Before these patches, we would ignore that call. With these patches, we honor it because the line aEvent->mFlags.mInPassiveListener = aListener->mFlags.mPassive is now setting aEvent->mFlags.mInPassiveListener to the wrong value, because aListener is a "once" listener, and we now read aListener->mFlags.mPassive on a move-constructed object. Before these patches, we would check the passive flag on the listener before we moved the "once" listener to the stack; now we do it after we move it to the stack. And the Listener move constructor does not copy over the flags, so aListener->mFlags.mPassive is always false.
I think that's an oversight. I'll fix the move constructor.

(In reply to Natalia Csoregi [:nataliaCs] from comment #24)

and hazard failures on EventListenerManager.cpp

This complains that EventListenerManager::GetListenerFor, which takes a raw JSObject* param, assigns a RefPtr<ListenerArray>. Assigning the RefPtr can destroy the previous ListenerArray object (but in this case that's always null), which could notify a signal follower, which could GC.

Flags: needinfo?(mstange.moz)

This allows us to keep the assert that there are no empty listener arrays in mListenerMap.

Depends on D184426

Without this fix, aListener->mFlags.mPassive would be incorrect for passive once listeners
if aListener is the move-constructed object. This is the value we use to initialize
aEvent->mFlags.mInPassiveListener.

Depends on D186268

Attachment #9349091 - Attachment description: Bug 1834370 - Change EventListenerManager::RemoveAllListeners() to clear mListenerMap immediately. r=smaug → Bug 1834370 - In EventListenerManager::RemoveAllListeners(), remove empty ListenerMap entries before calling NotifyEventListenerRemoved. r=smaug
Pushed by mstange@themasta.com:
https://hg.mozilla.org/integration/autoland/rev/69c277bbff5e
Refactor EventListenerManager::HandleEventInternal a bit. r=smaug
https://hg.mozilla.org/integration/autoland/rev/ef7fe556eb41
Keep listeners for each event type in a separate array, and use binary search on the outer list. r=smaug
https://hg.mozilla.org/integration/autoland/rev/ae82cdb2e236
Remove Listener::mTypeAtom to save memory. r=smaug
https://hg.mozilla.org/integration/autoland/rev/8a12b769befd
Remove Listener::mEventMessage and ListenerSignalFollower::mEventMessage. r=smaug
https://hg.mozilla.org/integration/autoland/rev/79c42762a119
In EventListenerManager::RemoveAllListeners(), remove empty ListenerMap entries before calling NotifyEventListenerRemoved. r=smaug
https://hg.mozilla.org/integration/autoland/rev/2f47efd7c14d
Copy over the flags in the Listener move constructor. r=smaug
https://hg.mozilla.org/integration/autoland/rev/875aa7a59557
Use a lambda in GetListenerFor to make it easier for rooting hazard analysis to see that we're not destroying a ListenerArray before the use of the JSObject* aListener parameter. r=smaug
Blocks: 1845633
Upstream PR merged by moz-wptsync-bot
Status: REOPENED → RESOLVED
Closed: 1 year ago1 year ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: