зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 8f99f3809630 (bug 1683220) for performance regression (bug 1684434). CLOSED TREE
This commit is contained in:
Родитель
f2d5237921
Коммит
6565293451
|
@ -10429,6 +10429,11 @@ nsresult nsDocShell::OpenInitializedChannel(nsIChannel* aChannel,
|
|||
rv = aURILoader->OpenURI(aChannel, aOpenFlags, this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We're about to load a new page and it may take time before necko
|
||||
// gives back any data, so main thread might have a chance to process a
|
||||
// collector slice
|
||||
nsJSContext::MaybeRunNextCollectorSlice(this, JS::GCReason::DOCSHELL);
|
||||
|
||||
// Success. Keep the initial ClientSource if it exists.
|
||||
cleanupInitialClient.release();
|
||||
|
||||
|
|
|
@ -1738,6 +1738,64 @@ void nsJSContext::RunNextCollectorTimer(JS::GCReason aReason,
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void nsJSContext::MaybeRunNextCollectorSlice(nsIDocShell* aDocShell,
|
||||
JS::GCReason aReason) {
|
||||
if (!aDocShell || !XRE_IsContentProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BrowsingContext* bc = aDocShell->GetBrowsingContext();
|
||||
if (!bc) {
|
||||
return;
|
||||
}
|
||||
|
||||
BrowsingContext* root = bc->Top();
|
||||
if (bc == root) {
|
||||
// We don't want to run collectors when loading the top level page.
|
||||
return;
|
||||
}
|
||||
|
||||
nsIDocShell* rootDocShell = root->GetDocShell();
|
||||
if (!rootDocShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
Document* rootDocument = rootDocShell->GetDocument();
|
||||
if (!rootDocument ||
|
||||
rootDocument->GetReadyStateEnum() != Document::READYSTATE_COMPLETE ||
|
||||
rootDocument->IsInBackgroundWindow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PresShell* presShell = rootDocument->GetPresShell();
|
||||
if (!presShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsViewManager* vm = presShell->GetViewManager();
|
||||
if (!vm) {
|
||||
return;
|
||||
}
|
||||
|
||||
// GetLastUserEventTime returns microseconds.
|
||||
uint32_t lastEventTime = 0;
|
||||
vm->GetLastUserEventTime(lastEventTime);
|
||||
uint32_t currentTime = PR_IntervalToMicroseconds(PR_IntervalNow());
|
||||
// Only try to trigger collectors more often if user hasn't interacted with
|
||||
// the page for awhile.
|
||||
if ((currentTime - lastEventTime) >
|
||||
(StaticPrefs::dom_events_user_interaction_interval() *
|
||||
PR_USEC_PER_MSEC)) {
|
||||
Maybe<TimeStamp> next = nsRefreshDriver::GetNextTickHint();
|
||||
// Try to not delay the next RefreshDriver tick, so give a reasonable
|
||||
// deadline for collectors.
|
||||
if (next.isSome()) {
|
||||
nsJSContext::RunNextCollectorTimer(aReason, next.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void nsJSContext::PokeGC(JS::GCReason aReason, JSObject* aObj,
|
||||
uint32_t aDelay) {
|
||||
|
|
|
@ -94,6 +94,11 @@ class nsJSContext : public nsIScriptContext {
|
|||
static void RunNextCollectorTimer(
|
||||
JS::GCReason aReason,
|
||||
mozilla::TimeStamp aDeadline = mozilla::TimeStamp());
|
||||
// If user has been idle and aDocShell is for an iframe being loaded in an
|
||||
// already loaded top level docshell, this will run a CC or GC
|
||||
// timer/runner if there is such pending.
|
||||
static void MaybeRunNextCollectorSlice(nsIDocShell* aDocShell,
|
||||
JS::GCReason aReason);
|
||||
|
||||
// The GC should probably run soon, in the zone of object aObj (if given).
|
||||
static void PokeGC(JS::GCReason aReason, JSObject* aObj, uint32_t aDelay = 0);
|
||||
|
|
|
@ -999,6 +999,20 @@ void nsHtml5StreamParser::CommitLocalFileToEncoding() {
|
|||
}
|
||||
}
|
||||
|
||||
class MaybeRunCollector : public Runnable {
|
||||
public:
|
||||
explicit MaybeRunCollector(nsIDocShell* aDocShell)
|
||||
: Runnable("MaybeRunCollector"), mDocShell(aDocShell) {}
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
nsJSContext::MaybeRunNextCollectorSlice(mDocShell,
|
||||
JS::GCReason::HTML_PARSER);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
};
|
||||
|
||||
nsresult nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest) {
|
||||
MOZ_RELEASE_ASSERT(STREAM_NOT_STARTED == mStreamState,
|
||||
"Got OnStartRequest when the stream had already started.");
|
||||
|
@ -1150,6 +1164,16 @@ nsresult nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest) {
|
|||
do_QueryInterface(mRequest, &rv);
|
||||
if (threadRetargetableRequest) {
|
||||
rv = threadRetargetableRequest->RetargetDeliveryTo(mEventTarget);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Parser thread should be now ready to get data from necko and parse it
|
||||
// and main thread might have a chance to process a collector slice.
|
||||
// We need to do this asynchronously so that necko may continue processing
|
||||
// the request.
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
new MaybeRunCollector(mExecutor->GetDocument()->GetDocShell());
|
||||
mozilla::SchedulerGroup::Dispatch(
|
||||
mozilla::TaskCategory::GarbageCollection, runnable.forget());
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче