Bug 1292699 - Add a small helper to deal with cases when native side needs to ensure that slow script dialog shows up, r=bholley

--HG--
extra : rebase_source : ab0fc332e5b54921d7a05e0c008c65b29947ee27
This commit is contained in:
Olli Pettay 2016-08-08 23:29:05 +03:00
parent bedc4de0a4
commit 06c2ac8e59
4 changed files with 39 additions and 7 deletions

View File

@ -812,4 +812,22 @@ AutoSafeJSContext::AutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMP
"returned null, and inited correctly otherwise!");
}
AutoSlowOperation::AutoSlowOperation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
: AutoJSAPI()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
Init();
}
void
AutoSlowOperation::CheckForInterrupt()
{
// JS_CheckForInterrupt expects us to be in a compartment.
JSAutoCompartment ac(cx(), xpc::UnprivilegedJunkScope());
JS_CheckForInterrupt(cx());
}
} // namespace mozilla

View File

@ -443,6 +443,23 @@ private:
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
/**
* Use AutoSlowOperation when native side calls many JS callbacks in a row
* and slow script dialog should be activated if too much time is spent going
* through those callbacks.
* AutoSlowOperation puts a JSAutoRequest on the stack so that we don't continue
* to reset the watchdog and CheckForInterrupt can be then used to check whether
* JS execution should be interrupted.
*/
class MOZ_RAII AutoSlowOperation : public dom::AutoJSAPI
{
public:
explicit AutoSlowOperation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
void CheckForInterrupt();
private:
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
} // namespace mozilla
#endif // mozilla_dom_ScriptSettings_h

View File

@ -885,10 +885,7 @@ nsDOMMutationObserver::HandleMutationsInternal()
return;
}
// We need the AutoSafeJSContext to ensure the slow script dialog is
// triggered. AutoSafeJSContext does that by pushing JSAutoRequest to stack.
// This needs to be outside the while loop.
AutoSafeJSContext cx;
AutoSlowOperation aso;
nsTArray<RefPtr<nsDOMMutationObserver> >* suppressedObservers = nullptr;
@ -910,7 +907,7 @@ nsDOMMutationObserver::HandleMutationsInternal()
}
}
delete observers;
JS_CheckForInterrupt(cx);
aso.CheckForInterrupt();
}
if (suppressedObservers) {

View File

@ -992,7 +992,7 @@ Promise::PerformMicroTaskCheckpoint()
return false;
}
AutoSafeJSContext cx;
AutoSlowOperation aso;
do {
nsCOMPtr<nsIRunnable> runnable = microtaskQueue.front().forget();
@ -1004,7 +1004,7 @@ Promise::PerformMicroTaskCheckpoint()
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
JS_CheckForInterrupt(cx);
aso.CheckForInterrupt();
runtime->AfterProcessMicrotask();
} while (!microtaskQueue.empty());