Closed Bug 1372761 Opened 7 years ago Closed 7 years ago

nsCaret::NotifySelectionChanged() is too expensive due to timer thread lock grabbing

Categories

(Core :: Layout, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla56
Performance Impact ?
Tracking Status
firefox56 --- fixed

People

(Reporter: ehsan.akhgari, Assigned: ehsan.akhgari)

References

(Blocks 1 open bug)

Details

Attachments

(1 file, 1 obsolete file)

The selection listener notifications that we call under the input value setter in speedometer end up running this code: <http://searchfox.org/mozilla-central/rev/d67ef71097da4d1aa344c9d9c672e49a7228e765/layout/base/nsCaret.cpp#639> This code always cancels and resets the caret timer, but both of those operations need to grab the timer thread lock, which can be very expensive, and this shows up in profiles of speedometer. We actually don't need to do this every time. Technically we only need to do this once per caret, or when the rate is set to 0 (to turn the timer off) or when it changes. A patch that does that seems to buy 2 points overall on Speedometer on my fast machine, it may be even better on slower hardware. I'll post it after a try run.
Sorry, I mentioned the wrong function name before! I spent a bit too much time in the caret code today. :-)
Summary: nsCaret::IsMenuPopupHidingCaret() is too expensive due to timer thread lock grabbing → nsCaret::NotifySelectionChanged() is too expensive due to timer thread lock grabbing
Comment on attachment 8877376 [details] [diff] [review] Avoid needlessly grabbing the timer thread lock when selections change in order to reset the caret timer It looks like you've changed the semantics of blinkRate == 0. Previously we did not call InitWithNamedFuncCallback in that case, now we do. I think we can do the change you want a lot simpler, just add: uint32_t blinkRate = ...; if (mBlinkRate == blinkRate) { return; } here: http://searchfox.org/mozilla-central/rev/d67ef71097da4d1aa344c9d9c672e49a7228e765/layout/base/nsCaret.cpp#638 and add "mBlinkRate = blinkRate" at the end. Keep everything else the same (apart from the moved blinkRate assignment). I think this would be easier to follow than what you propose.
Attachment #8877376 - Flags: review?(mats) → review-
Oops, you're right. New patch coming up...
Attachment #8877376 - Attachment is obsolete: true
Comment on attachment 8877716 [details] [diff] [review] Avoid needlessly grabbing the timer thread lock when selections change in order to reset the caret timer I think the "mBlinkRate = blinkRate" should be after the if-statement. Otherwise, we'll do unnecessary Cancel() calls here since "mBlinkRate == blinkRate" is still false. Also, we might miss to re-enable the timer if we go back to the same value: 500ms -> 0 -> 500ms The first transition will Cancel(), but mBlinkRate is still 500. The second transition will hit "mBlinkRate == blinkRate" and thus not re-enable the timer. r=mats with that
Attachment #8877716 - Flags: review?(mats) → review+
Pushed by eakhgari@mozilla.com: https://hg.mozilla.org/integration/mozilla-inbound/rev/db8a48dae370 Avoid needlessly grabbing the timer thread lock when selections change in order to reset the caret timer; r=mats
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
Depends on: 1373788
Performance Impact: --- → ?
Whiteboard: [qf]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: