Closed
Bug 1203381
Opened 9 years ago
Closed 9 years ago
IMEContentObserver should not post new notification after it posts some notifications but some of them are not performed yet
Categories
(Core :: DOM: UI Events & Focus Handling, defect)
Core
DOM: UI Events & Focus Handling
Tracking
()
RESOLVED
FIXED
mozilla43
People
(Reporter: masayuki, Assigned: masayuki)
References
(Blocks 1 open bug)
Details
(Keywords: inputmethod, perf)
Attachments
(7 files, 5 obsolete files)
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
Currently, IMEContentObserver posts notifications as runnable. At this time, it clears the posted data. So, if the posted notifications are performed asynchronously, new notifications may post before performing the previous notifications.
This is bad for performance. widget should receive only the last notification because following notifications will cause querying content again. Querying content may be very expensive.
So, IMEContentObserver should know if posted notifications are actually sent to widget.
Assignee | ||
Comment 1•9 years ago
|
||
Assignee | ||
Comment 2•9 years ago
|
||
Assignee | ||
Comment 3•9 years ago
|
||
Assignee | ||
Comment 4•9 years ago
|
||
# This is a preparation, doesn't add any new job actually.
IMEContentObserver should be able to know if it already created runnable event for notifying IME.
Attachment #8660633 -
Flags: review?(bugs)
Assignee | ||
Comment 5•9 years ago
|
||
# This patch is also another preparation to fix this bug.
For detecting nested call of FlushMergeableNotifications(), IMEContentObserver should be able to check if it's sending notification to IME.
Attachment #8660634 -
Flags: review?(bugs)
Assignee | ||
Comment 6•9 years ago
|
||
# This patch is also preparation of the fix.
Currently, IMEContentObserver clears mTextChangeData when creating TextChangeEvent instance and the instance stores the change data. However, if new text change occurs before sending notification but after creating the event, the event will notify IME of old text change. This causes that IME tries to query content at receiving a text change notification, the result may be different from the expected content by IME.
So, until TextChangeEvent::Run() notifies IME of text change actually, IMEContentObserver should merge new text change data even after it created a TextChangeEvent instance. Then, expected content by IME and expected content by IMEContentObserver are always same.
Attachment #8660637 -
Flags: review?(bugs)
Assignee | ||
Comment 7•9 years ago
|
||
Let's fix this bug actually!
If IMEContentObserver has created runnable events but they have not actually run yet, IMEContentObserver shouldn't create redundant runnable events. Then, we can reduce to send unnecessary notifications. This also reduces redundant query content events from either IME or ContentCacheInChild.
Attachment #8660642 -
Flags: review?(bugs)
Assignee | ||
Comment 8•9 years ago
|
||
This is additional fix.
When IMEContentObserver uses ContentEventHandler which occurs during sending notification to IME, the result includes the latest layout information. So, even if ContentEventHandler causes flushing pending layout, IMEContentObserver doesn't need to notify position change anymore.
Attachment #8660647 -
Flags: review?(bugs)
Comment 9•9 years ago
|
||
Comment on attachment 8660633 [details] [diff] [review]
part.1 IMEContentObserver should manage if each notification was posted but not performed
>+ // mIsPosting*Event indicates that whether the runnable event class's
>+ // Run() method is not still performed yet.
...indicates whether the runnable event class' Run() method hasn't been executed yet.
But I wonder how much all of the patches in this bug will actually help, given that we're
using ScriptRunners here, not NS_DispatchToCurrent/MainThread or such.
ScriptRunners are run rather soon.
So please measure a bit how often we actually save anything with this new setup (which is a bit complicated).
Attachment #8660633 -
Flags: review?(bugs) → review+
Comment 10•9 years ago
|
||
Comment on attachment 8660634 [details] [diff] [review]
part.2 IMEContentObserver should manage if each notification was sent to widget
>+ // mIsSent*Notification indicates that the notification is being sent to
>+ // widget from the runnable event's Run().
>+ bool mIsSentFocusSetNotification;
>+ bool mIsSentTextChangeNotification;
>+ bool mIsSentSelectionChangeNotification;
>+ bool mIsSentPositionChangeNotification;
This naming is odd. I need to read the other patches still to understand what these are about, but
perhaps mIsSendingFocusSetNotification; etc.
Attachment #8660634 -
Flags: review?(bugs) → review+
Assignee | ||
Comment 11•9 years ago
|
||
> So please measure a bit how often we actually save anything with this new setup (which is a bit complicated).
Depends on the webpage. If <input> works with autocomplete implemented by the website, Reflow() is called much many times during typing a character. In that case, part.5 works well (the others are necessary for it).
Comment 12•9 years ago
|
||
Comment on attachment 8660637 [details] [diff] [review]
part.3 IMEContentObserver shouldn't clear mTextChangeData until immediately before sending a text change notification
>+IMEContentObserver::PostTextChangeNotification()
> {
> MOZ_LOG(sIMECOLog, LogLevel::Debug,
>- ("IMECO: 0x%p IMEContentObserver::PostTextChangeNotification("
>- "aTextChangeData=%s)",
>- this, TextChangeDataToString(aTextChangeData).get()));
>-
>- mTextChangeData += aTextChangeData;
>- MOZ_ASSERT(mTextChangeData.IsValid(),
>- "mTextChangeData must have text change data");
>-
>- MOZ_LOG(sIMECOLog, LogLevel::Debug,
> ("IMECO: 0x%p IMEContentObserver::PostTextChangeNotification(), "
> "mTextChangeData=%s)",
> this, TextChangeDataToString(mTextChangeData).get()));
>+
>+ MOZ_ASSERT(mTextChangeData.IsValid(),
>+ "mTextChangeData must have text change data");
>+ mIsTextChangeEventPending = true;
> }
IMEContentObserver::PostTextChangeNotification is now rather dummy method, but
I guess it is fine for that logging stuff.
>- if (mTextChangeData.IsValid()) {
>+ if (mIsTextChangeEventPending) {
> MOZ_LOG(sIMECOLog, LogLevel::Debug,
> ("IMECO: 0x%p IMEContentObserver::FlushMergeableNotifications(), "
> "creating TextChangeEvent...", this));
>+ mIsTextChangeEventPending = false;
> mIsPostingTextChangeEvent = true;
>- nsContentUtils::AddScriptRunner(new TextChangeEvent(this, mTextChangeData));
>+ nsContentUtils::AddScriptRunner(new TextChangeEvent(this));
Oh, the naming is like this...
mIsTextChangeEventPending sounds to me like something where we have TextChangeEvent waiting to be processed -
but mIsPostingTextChangeEvent is currently for that.
Could we call mIsTextChangeEventPending mNeedsTextChangeEvent
Attachment #8660637 -
Flags: review?(bugs) → review+
Assignee | ||
Comment 13•9 years ago
|
||
Oh, and I can say the another reason why this is necessary.
See bug 1202080. Current code may cause infinite recursive calls. Although, I cannot test it yet because I cannot reproduce the crash, the bug must be fixed by these patches as far as watching the log of IMEContentObserver.
Assignee | ||
Comment 14•9 years ago
|
||
> Could we call mIsTextChangeEventPending mNeedsTextChangeEvent
Sure. I'll add part.6 for that tomorrow. I'll go to bed soon. Thank you very much, I'm really happy you reviewed a lot of patches quickly!!
Updated•9 years ago
|
Attachment #8660647 -
Flags: review?(bugs) → review+
Comment 15•9 years ago
|
||
Comment on attachment 8660642 [details] [diff] [review]
part.4 IMEContentObserver shouldn't create redundant text/selection/position change event
I think I need the naming of the variables changed before reviewing this. So many different bool variables.
Hmm, would it even work if we didn't have bool variables but some enum?
So that states would be
eInitialState (something better would be good for this)
eNeedsEvent
eIsPostingEvent
or something like that, and then use that for different events/notifications?
Attachment #8660642 -
Flags: review?(bugs)
Assignee | ||
Comment 16•9 years ago
|
||
This is same as the old part.3 (attachment 8660637 [details] [diff] [review]). I think that we should merge FocusSetEvent, SelectionChangeEvent, TextChangeEvent and PositionChangeEvent. Then, we can reduce the flags and make the code simpler. Additionally, we can make notification order same always.
Attachment #8660633 -
Attachment is obsolete: true
Attachment #8660634 -
Attachment is obsolete: true
Attachment #8660637 -
Attachment is obsolete: true
Attachment #8660642 -
Attachment is obsolete: true
Attachment #8660647 -
Attachment is obsolete: true
Attachment #8661226 -
Flags: review?(bugs)
Assignee | ||
Comment 17•9 years ago
|
||
Let's merge the 3 runnable classes. Then, we can reduce the number of time to create runnable events and send all pending notifications synchronously when there is no script blocker.
Attachment #8661232 -
Flags: review?(bugs)
Assignee | ||
Comment 18•9 years ago
|
||
Then, we can manage if a runnable event is performed with only one bool preference which is already existing.
Attachment #8661234 -
Flags: review?(bugs)
Assignee | ||
Comment 19•9 years ago
|
||
s/bool preference/bool member
Assignee | ||
Comment 20•9 years ago
|
||
Although, this is different bug, we should keep the notification order (text change -> selection change -> position change) even if one of them causes new pending notification. E.g., without this patch, IME may receive the latest selection while IME caches older text.
Attachment #8661237 -
Flags: review?(bugs)
Assignee | ||
Comment 21•9 years ago
|
||
Let's fix the possibility of infinite recursive calls with |IMEMessage mSendingNotification| which stores the sending notification. If it's not NOTIFY_IME_OF_NOTHING, AChangeEvent should think that it's not safe to notify IME of anything.
Attachment #8661238 -
Flags: review?(bugs)
Assignee | ||
Comment 22•9 years ago
|
||
Let's prevent redundant position change notification if it's caused by flushing layout at querying the content and sending position change notification.
Attachment #8661239 -
Flags: review?(bugs)
Assignee | ||
Comment 23•9 years ago
|
||
Finally, rename the existing members whose names you don't like.
Attachment #8661240 -
Flags: review?(bugs)
Updated•9 years ago
|
Attachment #8661226 -
Flags: review?(bugs) → review+
Updated•9 years ago
|
Attachment #8661232 -
Flags: review?(bugs) → review+
Comment 24•9 years ago
|
||
Comment on attachment 8661232 [details] [diff] [review]
part.2 Merge all IME notification sending events of IMEContentObserver to a runnable class
>+IMEContentObserver::IMENotificationSender::Run()
>+{
>+ // NOTE: Reset each pending flag because sending notification may cause
>+ // another change.
>
>-NS_IMETHODIMP
>-IMEContentObserver::FocusSetEvent::Run()
>-{
>- if (!CanNotifyIME()) {
>- // If IMEContentObserver has already gone, we don't need to notify IME of
>- // focus.
>- MOZ_LOG(sIMECOLog, LogLevel::Debug,
>- ("IMECO: 0x%p IMEContentObserver::FocusSetEvent::Run(), FAILED, due to "
>- "impossible to notify IME of focus", this));
>+ if (mIMEContentObserver->mIsFocusEventPending) {
>+ mIMEContentObserver->mIsFocusEventPending = false;
>+ SendFocusSet();
>+ // This is the first notification to IME. So, we don't need to notify
>+ // anymore since IME starts to query content after it gets focus.
> mIMEContentObserver->ClearPendingNotifications();
> return NS_OK;
> }
Actually, I don't understand this. Why do we return NS_OK here?
What if there are other pending events, what guarantees those are run?
And then in the next patch there is explicit
mIMEContentObserver->mIsFlushingPendingNotifications = false;
here which makes the code a bit harder to read.
Please explain or fix, and re-ask review.
Attachment #8661232 -
Flags: review+ → review-
Comment 25•9 years ago
|
||
Comment on attachment 8661234 [details] [diff] [review]
part.3 IMEContentObserver::mIsFlushingPendingNotifications should be cleared when all pending notifications are sent to IME
> if (mIMEContentObserver->mIsFocusEventPending) {
> mIMEContentObserver->mIsFocusEventPending = false;
> SendFocusSet();
> // This is the first notification to IME. So, we don't need to notify
> // anymore since IME starts to query content after it gets focus.
> mIMEContentObserver->ClearPendingNotifications();
>+ mIMEContentObserver->mIsFlushingPendingNotifications = false;
> return NS_OK;
> }
r+ assuming this change is removed if there are changes to the previous patch (or not removed if it is explained why we need to return here.)
>+ // If notifications caused some new change, we should notify them now.
>+ mIMEContentObserver->mIsFlushingPendingNotifications =
>+ mIMEContentObserver->mIsTextChangeEventPending ||
>+ mIMEContentObserver->mIsSelectionChangeEventPending ||
>+ mIMEContentObserver->mIsPositionChangeEventPending;
In theory, and for consistency, shouldn't we add also || mIMEContentObserver->mIsFocusEventPending
here.
Attachment #8661234 -
Flags: review?(bugs) → review+
Updated•9 years ago
|
Attachment #8661237 -
Flags: review?(bugs) → review+
Assignee | ||
Comment 26•9 years ago
|
||
Comment on attachment 8661232 [details] [diff] [review]
part.2 Merge all IME notification sending events of IMEContentObserver to a runnable class
(In reply to Olli Pettay [:smaug] from comment #24)
> Comment on attachment 8661232 [details] [diff] [review]
> part.2 Merge all IME notification sending events of IMEContentObserver to a
> runnable class
>
> >+IMEContentObserver::IMENotificationSender::Run()
> >+{
> >+ // NOTE: Reset each pending flag because sending notification may cause
> >+ // another change.
> >
> >-NS_IMETHODIMP
> >-IMEContentObserver::FocusSetEvent::Run()
> >-{
> >- if (!CanNotifyIME()) {
> >- // If IMEContentObserver has already gone, we don't need to notify IME of
> >- // focus.
> >- MOZ_LOG(sIMECOLog, LogLevel::Debug,
> >- ("IMECO: 0x%p IMEContentObserver::FocusSetEvent::Run(), FAILED, due to "
> >- "impossible to notify IME of focus", this));
> >+ if (mIMEContentObserver->mIsFocusEventPending) {
> >+ mIMEContentObserver->mIsFocusEventPending = false;
> >+ SendFocusSet();
> >+ // This is the first notification to IME. So, we don't need to notify
> >+ // anymore since IME starts to query content after it gets focus.
> > mIMEContentObserver->ClearPendingNotifications();
> > return NS_OK;
> > }
> Actually, I don't understand this. Why do we return NS_OK here?
> What if there are other pending events, what guarantees those are run?
> And then in the next patch there is explicit
> mIMEContentObserver->mIsFlushingPendingNotifications = false;
> here which makes the code a bit harder to read.
>
> Please explain or fix, and re-ask review.
Because when IME receives focus set notification, IME doesn't know the content information. Therefore, it doesn't make sense to notify IME of previous change notifications before sending focus notification since IME doesn't need to query content with the notification (the query result should be same as the result at querying the content when IME gets focus). I explained it in the comment in the patch.
>+ // This is the first notification to IME. So, we don't need to notify
>+ // anymore since IME starts to query content after it gets focus.
Attachment #8661232 -
Flags: review- → review?(bugs)
Comment 27•9 years ago
|
||
Comment on attachment 8661238 [details] [diff] [review]
part.5 IMENotificationSender shouldn't send notification recursively
Couldn't we use AutoRestore for mSendingNotification?
Either way.
Attachment #8661238 -
Flags: review?(bugs) → review+
Comment 28•9 years ago
|
||
(In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #26)
> Because when IME receives focus set notification, IME doesn't know the
> content information. Therefore, it doesn't make sense to notify IME of
> previous change notifications before sending focus notification since IME
> doesn't need to query content with the notification (the query result should
> be same as the result at querying the content when IME gets focus). I
> explained it in the comment in the patch.
>
> >+ // This is the first notification to IME. So, we don't need to notify
> >+ // anymore since IME starts to query content after it gets focus.
But what guarantees we actually notify other pending events?
I would assume we don't in general actually have other pending events if mIsFocusEventPending is true.
Assignee | ||
Comment 29•9 years ago
|
||
(In reply to Olli Pettay [:smaug] from comment #27)
> Comment on attachment 8661238 [details] [diff] [review]
> part.5 IMENotificationSender shouldn't send notification recursively
>
> Couldn't we use AutoRestore for mSendingNotification?
> Either way.
At least for now, it makes same result. But I'm afraid that future change would break it by adding some code flushing layout or something.
Comment 30•9 years ago
|
||
Comment on attachment 8661239 [details] [diff] [review]
part.6 IMEContentObserver shouldn't post position change event if Reflow() is called during handling a query content event and sending NOTIFY_IME_OF_POSITION_CHANGE since the result of query content e
Ok, so this is purely an optimization.
Attachment #8661239 -
Flags: review?(bugs) → review+
Assignee | ||
Comment 31•9 years ago
|
||
(In reply to Olli Pettay [:smaug] from comment #28)
> (In reply to Masayuki Nakano (:masayuki) (Mozilla Japan) from comment #26)
> > Because when IME receives focus set notification, IME doesn't know the
> > content information. Therefore, it doesn't make sense to notify IME of
> > previous change notifications before sending focus notification since IME
> > doesn't need to query content with the notification (the query result should
> > be same as the result at querying the content when IME gets focus). I
> > explained it in the comment in the patch.
> >
> > >+ // This is the first notification to IME. So, we don't need to notify
> > >+ // anymore since IME starts to query content after it gets focus.
> But what guarantees we actually notify other pending events?
So, we don't need to guarantee that because IME doesn't need them. If they would be notified immediately after focus set notification, IME may query content again. But the result may odd. For example, if IME queries text at getting focus, then the result may be "ABC". However, if the content is generated with "ABXC" and removing X at setting focus, text change may be recorded as removing the third character. If text change notification is sent to IME after focus set notification, IME must assume that the content becomes "AB" (the new third character "C" is removed), but the actual result is "ABC". If IME doesn't query content, IME caches wrong content, that may cause odd behaviors.
> I would assume we don't in general actually have other pending events if
> mIsFocusEventPending is true.
Yes. That's the edge case. Basically, focus set should be sent to IME synchronously at an editable element gets focus. However, if it's not safe due to script blocker or reflowing, it may be put off. At this case, this scenario might occur.
Updated•9 years ago
|
Attachment #8661240 -
Flags: review?(bugs) → review+
Comment 32•9 years ago
|
||
Comment on attachment 8661232 [details] [diff] [review]
part.2 Merge all IME notification sending events of IMEContentObserver to a runnable class
Ok, fine. I assume IME does query new information when needed.
Attachment #8661232 -
Flags: review?(bugs) → review+
Updated•9 years ago
|
Blocks: e10s-perf
tracking-e10s:
--- → +
Assignee | ||
Comment 33•9 years ago
|
||
>>+ // If notifications caused some new change, we should notify them now.
>>+ mIMEContentObserver->mIsFlushingPendingNotifications =
>>+ mIMEContentObserver->mIsTextChangeEventPending ||
>>+ mIMEContentObserver->mIsSelectionChangeEventPending ||
>>+ mIMEContentObserver->mIsPositionChangeEventPending;
> In theory, and for consistency, shouldn't we add also || mIMEContentObserver->mIsFocusEventPending
> here.
Hmm, it's not necessary because focus set notification is sent to only once per instance of IMEContentObserver. So, if it's true, it's never come here since early return code in the case.
However, I think that adding IMEContentObserver::NeedsToNotifyIMEOfSomething() which checks all flags is useful since it can be shared and when we add a new notification, it's easier to do it.
Comment 34•9 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/bcfee08450fc
https://hg.mozilla.org/integration/mozilla-inbound/rev/6b69a6cadbe1
https://hg.mozilla.org/integration/mozilla-inbound/rev/11944d579d68
https://hg.mozilla.org/integration/mozilla-inbound/rev/b746528338fa
https://hg.mozilla.org/integration/mozilla-inbound/rev/3a37db144dcd
https://hg.mozilla.org/integration/mozilla-inbound/rev/46046fcbf40f
https://hg.mozilla.org/integration/mozilla-inbound/rev/34606afcc726
https://hg.mozilla.org/mozilla-central/rev/bcfee08450fc
https://hg.mozilla.org/mozilla-central/rev/6b69a6cadbe1
https://hg.mozilla.org/mozilla-central/rev/11944d579d68
https://hg.mozilla.org/mozilla-central/rev/b746528338fa
https://hg.mozilla.org/mozilla-central/rev/3a37db144dcd
https://hg.mozilla.org/mozilla-central/rev/46046fcbf40f
https://hg.mozilla.org/mozilla-central/rev/34606afcc726
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla43
Comment 36•9 years ago
|
||
Shouldn't this be uplifted to Beta 42?
Updated•9 years ago
|
Flags: needinfo?(masayuki)
Assignee | ||
Comment 37•9 years ago
|
||
(In reply to Vladan Djeric (:vladan) -- please needinfo! from comment #36)
> Shouldn't this be uplifted to Beta 42?
Hmm, this is pretty risky. And I don't have much reason to uplift to Beta since e10s mode isn't available on Beta. Why do you think so?
Flags: needinfo?(masayuki) → needinfo?(vladan.bugzilla)
Comment 38•9 years ago
|
||
There's a chance we'll be doing A/B experiments on Beta 42 where we force a small # of users into using e10s and then compare their Telemetry vs Telemetry from non-e10s users.
It's not a common crash though, so you can keep the fix on Aurora if you think it's risky.
Flags: needinfo?(vladan.bugzilla)
Assignee | ||
Comment 39•9 years ago
|
||
(In reply to Vladan Djeric (:vladan) -- please needinfo! from comment #38)
> There's a chance we'll be doing A/B experiments on Beta 42 where we force a
> small # of users into using e10s and then compare their Telemetry vs
> Telemetry from non-e10s users.
>
> It's not a common crash though, so you can keep the fix on Aurora if you
> think it's risky.
The crash bug depending on this bug doesn't have security risk and not a topcrash. So, I think that we should take safer way for this bug.
Updated•6 years ago
|
Component: Event Handling → User events and focus handling
You need to log in
before you can comment on or make changes to this bug.
Description
•