Closed Bug 1111412 Opened 10 years ago Closed 10 years ago

Slow script timer relies on Ion to trigger on time

Categories

(Core :: XPConnect, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla37
Tracking Status
firefox37 --- wontfix
firefox38 --- fixed

People

(Reporter: billm, Assigned: billm)

References

Details

Attachments

(2 files)

I was looking at the slow script code today and I found something strange. Let's assume the slow script timeout is set to 10 seconds. The watchdog code triggers the JS interrupt callback when we've been in a request for 10 seconds or more. However, that's not enough to get a slow script dialog. Instead, we need to wait for another timer, mSlowScriptCheckpoint, to exceed 10 seconds. In the worst case, we can wait 20 seconds to get the dialog. Typically, the worst case doesn't happen for an odd reason. Most "slow" scripts will enter Ion pretty quickly. And whenever an off-thread Ion compilation completes, we trigger the interrupt callback. We rely on that first interrupt callback, near when the script starts, to set mSlowScriptCheckpoint to the current time. Then, once the watchdog timer fires, mSlowScriptCheckpoint will already have been about 10 seconds ago. However, it's possible that the slow script won't cause Ion compilation, in which case we'll have to wait 20 seconds to see the dialog: first we wait 10 seconds to trigger the watchdog timer and set mSlowScriptCheckpoint to the current time, and then another 10 seconds until the current time is > mSlowScriptCheckpoint+(10 seconds). Anyway, this sucks and we should fix it. It's pretty easy to reproduce this by disabling Ion (or just off-thread compilation) and running a JS loop that waits 15 seconds. You won't see the dialog.
OK. So this wasn't much of an issue back when we set up the watchdog for 1s because we'd worst case put up the dialog after 11s instead of 10s. But once we started setting the watchdog for the time we actually want to get the interrupt at we can end up with an actual run time anywhere from "about the pref time" to "twice the pref time"... I agree this is not great. Could we somehow set mSlowScriptCheckpoint from something other than an interrupt (e.g. from an AutoEntryScript)?
What about setting it in nsXPConnect::OnProcessNextEvent? That has a nice symmetry with clearing it in AfterProcessNextEvent.
I can confirm what you're seeing but, until recently, if I put a printf in JS_RequestInterruptCallback, it would fire every second, starting after 1 the first second spent in JS call. I guess this changed recently?
(In reply to Luke Wagner [:luke] from comment #3) > I can confirm what you're seeing but, until recently, if I put a printf in > JS_RequestInterruptCallback, it would fire every second, starting after 1 > the first second spent in JS call. I guess this changed recently? I haven't looked at the patches, but it sounds like something happened in bug 870043 that affected this.
(In reply to Luke Wagner [:luke] from comment #3) > I can confirm what you're seeing but, until recently, if I put a printf in > JS_RequestInterruptCallback, it would fire every second, starting after 1 > the first second spent in JS call. I guess this changed recently? This changed recently in bug 1091459. Triggering the interrupt every second was causing regular expression execution to bail out before it was necessary (we can't handle interrupts with regexp jitcode on the stack). I guess bug 1091459 should have done something with mSlowScriptCheckpoint but this problem didn't show up in testing and I don't see any real comments on what mSlowScriptCheckpoint is supposed to mean and how it is set. It seems like there is a lot of overlap between mSlowScriptCheckpoint and TimestampRuntimeStateChange, except when the user hits 'continue' on the slow script dialog?
(In reply to Bill McCloskey (:billm) from comment #2) > What about setting it in nsXPConnect::OnProcessNextEvent? That has a nice > symmetry with clearing it in AfterProcessNextEvent. I think it should live in AutoEntryScript/~AutoEntryScript, since that's a tighter bound on where we enter/exit script.
Don't we want the loosest possible bound? If we reset the timer too often, we won't get the slow script dialog. For example, if we use ~AutoEntryScript, we would have to keep track of the nesting depth. We should only reset the timer if the depth is zero.
(In reply to Bill McCloskey (:billm) from comment #7) > Don't we want the loosest possible bound? If we reset the timer too often, > we won't get the slow script dialog. Hm, I guess that's true in the case of a page having a zillion event listeners for an event, each of which takes 5 seconds. > For example, if we use > ~AutoEntryScript, we would have to keep track of the nesting depth. We > should only reset the timer if the depth is zero. It depends on what you're trying to do. Both AutoEntryScript and event processing can be nested - it's just a question of where you're interested in resetting the timer. But yes, I agree that event processing is probably better here.
I considered doing the timer stuff only when mEventDepth==0. However, I'm concerned that we might get spurious slow script warnings when we're showing a modal dialog or something.
Assignee: nobody → wmccloskey
Status: NEW → ASSIGNED
Attachment #8537975 - Flags: review?(bobbyholley)
Comment on attachment 8537975 [details] [diff] [review] fix-slow-script-timer Review of attachment 8537975 [details] [diff] [review]: ----------------------------------------------------------------- r=me modulo that. ::: js/xpconnect/src/xpcprivate.h @@ +633,1 @@ > void OnAfterProcessNextEvent() { mSlowScriptCheckpoint = mozilla::TimeStamp(); } Is there any reason for the asymmetry in Now vs NowLoRes? Seems like we should do one or the other.
Attachment #8537975 - Flags: review?(bobbyholley) → review+
Don't we use NowLowRes() everywhere in the slow script code?
(In reply to Bill McCloskey (:billm) from comment #11) > Don't we use NowLowRes() everywhere in the slow script code? Oh, I guess mozilla::TimeStamp() creates a sentinel timestamp rather than Now. Nevermind.
Status: ASSIGNED → RESOLVED
Closed: 10 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla37
I'm going to back this out on 37 since I'm running into a little bit of trouble getting the patch in bug 1114345 to pass tests.
Flags: needinfo?(wmccloskey)
Attached patch backoutSplinter Review
Do I need approval to back out a bug? Approval Request Comment [Feature/regressing bug #]: this one [User impact if declined]: slow script dialog may appear supriously when laptop wakes up [Describe test coverage new/current, TreeHerder]: none [Risks and why]: very low; this just reverts some simple code to a previous state [String/UUID change made/needed]: none
Flags: needinfo?(wmccloskey)
Attachment #8552107 - Flags: approval-mozilla-aurora?
Attachment #8552107 - Flags: approval-mozilla-aurora? → approval-mozilla-aurora+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: