Closed Bug 1626802 Opened 4 years ago Closed 4 years ago

Avoid cross-thread QueryInterface calls for interfaces we know aren't supported

Categories

(Core :: Disability Access APIs, enhancement, P2)

Desktop
Windows
enhancement

Tracking

()

VERIFIED FIXED
mozilla76
Tracking Status
firefox76 --- verified

People

(Reporter: Jamie, Assigned: Jamie)

References

(Blocks 1 open bug)

Details

(Keywords: perf)

Attachments

(2 files)

I discovered that when marshaling a11y calls from the content process, there are quite a lot of cross-thread QueryInterface calls (ipc::mscom::Interceptor::QueryInterfaceTarget). Some of these are for special COM interfaces like IAgileObject and IFastRundown, which we could just special case in Interceptor::QueryInterface like we do for INoMarshal. However, it seems there are a lot of other interfaces being queried and it's not clear why. I counted 16 before I gave up. I can't find any documentation on most of them, and for some, I can't even find names. Many of them are being queried by some COM function called CarefullyQueryNewInterfaceContext::QueryInterface. I've included a list of the ones I bothered to catch at the bottom of this comment.

We could track down all of these and special case them in Interceptor::QueryInterface. However, my suspicion is that even if we managed to capture them all, more would be introduced in future. The number of interfaces and the curiously unrelated nature of some of them (IEUserBroker, IAudioDeviceGraph) makes me wonder if there is a certain category of interfaces which are all queried, rather than it being a hard-coded list.

Instead, I propose that we maintain an interface allow list. This can be done in the HandlerProvider, which allows us to maintain the lists in the relevant module; e.g. a11y maintains its list in mozilla::a11y::HandlerProvider. This is a more future proof solution.

Rendering an NVDA virtual buffer for Wikipedia World War I takes 3.890 sec in Nightly. With this change, that time goes down to 2.739 sec. That's a 29.59% improvement.

Here are the interfaces I found before I gave up. The names mostly come from obscure sources found by Googling.

  • ? 2132B005-C604-4354-85BD-8F2E24181B0C
  • CLSID_IdentityUnmarshal 0000001B-0000-0000-C000-000000000046
  • ? 334D391F-0E79-3B15-C9FF-EAC65DD07C42
  • IFastRundown 00000040-0000-0000-C000-000000000046
  • ? 77DD1250-139C-2BC3-BD95-900ACED61BE5
  • ? BFD60505-5A1F-4E41-88BA-A6FB07202DA9
  • IApplicationFrame 143715D9-A015-40EA-B695-D5CC267E36EE
  • IApplicationFrameManager D6DEFAB3-DBB9-4413-8AF9-554586FDFF94
  • IApplicationFrameEventHandler EA5D0DE4-770D-4DA0-A9F8-D7F9A140FF79
  • IStreamGroup 816E5B3E-5523-4EFC-9223-98EC4214C3A0
  • IAudioDeviceGraph 3C169FF7-37B2-484C-B199-C3155590F316
  • ? 4F4F92B5-6DED-4E9B-A93F-013891B3A8B7
  • ? 9BC79C93-2289-4BB5-ABF4-3287FD9CAE39
  • IPimcContext2 1868091E-AB5A-415F-A02F-5C4DD0CF901D
  • ? 11456F96-09D1-4909-8F36-4EB74E42B93E
  • IEUserBroker 1AC7516E-E6BB-4A69-B63F-E841904DC5A6

When marshaling a11y calls from the content process, there are quite a lot of cross-thread QueryInterface calls (ipc::mscom::Interceptor::QueryInterfaceTarget).
Some of these are for special COM interfaces like IAgileObject and IFastRundown, which we could just special case in Interceptor::QueryInterface like we do for INoMarshal.
However, it seems there are a lot of other interfaces being queried and it's not clear why.
This patch adds a new HandlerProvider method: IsInterfaceMaybeSupported.
This allows implementations to indicate when there are interfaces which they definitely don't support, allowing the call to be answered without a cross-thread call.

Pushed by mzehe@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/36d97bd2feaa
part 1: mscom: Provide a way for Interceptors to avoid unnecessary cross-thread QueryInterface calls. r=aklotz
https://hg.mozilla.org/integration/autoland/rev/523e9e4e336c
part 2: Implement HandlerProvider::IsInterfaceMaybeSupported for a11y. r=aklotz,MarcoZ
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla76

Verified this fixed in the 2020-04-02 nightly build. Loading pages like the World War I article on Wikipedia is about 30% faster, measured using the NVDA buffer load debug log entries when loading the already loaded buffer again with NVDA+F5.

On many smaller pages I've tried, NVDA now no longer says "Loading document", which means that more buffer loads are below the 500 MS threshold.

Status: RESOLVED → VERIFIED
Keywords: perf
Blocks: 1365655
Blocks: 1473310
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: