Bug 1828862 - Improve caching of knowledge of listeners which the event listener manager does not have, r=masayuki

Differential Revision: https://phabricator.services.mozilla.com/D175855
This commit is contained in:
Olli Pettay 2023-04-19 10:25:26 +00:00
Родитель a71dc7a55b
Коммит b8255ea4a6
2 изменённых файлов: 27 добавлений и 12 удалений

Просмотреть файл

@ -100,8 +100,7 @@ static uint32_t MutationBitForEventType(EventMessage aEventType) {
uint32_t EventListenerManager::sMainThreadCreatedCount = 0;
EventListenerManagerBase::EventListenerManagerBase()
: mNoListenerForEvent(eVoidEvent),
mMayHavePaintEventListener(false),
: mMayHavePaintEventListener(false),
mMayHaveMutationListeners(false),
mMayHaveCapturingListeners(false),
mMayHaveSystemGroupListeners(false),
@ -117,7 +116,8 @@ EventListenerManagerBase::EventListenerManagerBase()
mIsMainThreadELM(NS_IsMainThread()),
mHasNonPrivilegedClickListeners(false),
mUnknownNonPrivilegedClickListeners(false) {
static_assert(sizeof(EventListenerManagerBase) == sizeof(uint32_t),
ClearNoListenersForEvents();
static_assert(sizeof(EventListenerManagerBase) == sizeof(uint64_t),
"Keep the size of EventListenerManagerBase size compact!");
}
@ -238,7 +238,7 @@ void EventListenerManager::AddEventListenerInternal(
}
}
mNoListenerForEvent = eVoidEvent;
ClearNoListenersForEvents();
mNoListenerForEventAtom = nullptr;
listener =
@ -789,7 +789,7 @@ void EventListenerManager::DisableDevice(EventMessage aEventMessage) {
void EventListenerManager::NotifyEventListenerRemoved(nsAtom* aUserType) {
// If the following code is changed, other callsites of EventListenerRemoved
// and NotifyAboutMainThreadListenerChange should be changed too.
mNoListenerForEvent = eVoidEvent;
ClearNoListenersForEvents();
mNoListenerForEventAtom = nullptr;
if (mTarget) {
mTarget->EventListenerRemoved(aUserType);
@ -1566,8 +1566,13 @@ void EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
}
if (mIsMainThreadELM && !hasListener) {
mNoListenerForEvent = aEvent->mMessage;
mNoListenerForEventAtom = aEvent->mSpecifiedEventType;
if (aEvent->mMessage != eUnidentifiedEvent) {
mNoListenerForEvents[2] = mNoListenerForEvents[1];
mNoListenerForEvents[1] = mNoListenerForEvents[0];
mNoListenerForEvents[0] = aEvent->mMessage;
} else {
mNoListenerForEventAtom = aEvent->mSpecifiedEventType;
}
}
if (aEvent->DefaultPrevented()) {
@ -1849,7 +1854,7 @@ nsresult EventListenerManager::SetListenerEnabled(
if (aEnabled) {
// We may have enabled some listener, clear the cache for which events
// we don't have listeners.
mNoListenerForEvent = eVoidEvent;
ClearNoListenersForEvents();
mNoListenerForEventAtom = nullptr;
}
return NS_OK;

Просмотреть файл

@ -145,7 +145,13 @@ class EventListenerManagerBase {
protected:
EventListenerManagerBase();
EventMessage mNoListenerForEvent;
void ClearNoListenersForEvents() {
mNoListenerForEvents[0] = eVoidEvent;
mNoListenerForEvents[1] = eVoidEvent;
mNoListenerForEvents[2] = eVoidEvent;
}
EventMessage mNoListenerForEvents[3];
uint16_t mMayHavePaintEventListener : 1;
uint16_t mMayHaveMutationListeners : 1;
uint16_t mMayHaveCapturingListeners : 1;
@ -387,9 +393,13 @@ class EventListenerManager final : public EventListenerManagerBase {
}
// Check if we already know that there is no event listener for the event.
if (mNoListenerForEvent == aEvent->mMessage &&
(mNoListenerForEvent != eUnidentifiedEvent ||
mNoListenerForEventAtom == aEvent->mSpecifiedEventType)) {
if (aEvent->mMessage == eUnidentifiedEvent) {
if (mNoListenerForEventAtom == aEvent->mSpecifiedEventType) {
return;
}
} else if (mNoListenerForEvents[0] == aEvent->mMessage ||
mNoListenerForEvents[1] == aEvent->mMessage ||
mNoListenerForEvents[2] == aEvent->mMessage) {
return;
}
HandleEventInternal(aPresContext, aEvent, aDOMEvent, aCurrentTarget,