Backed out changeset 8f99f3809630 (bug 1683220) for performance regression (bug 1684434). CLOSED TREE

This commit is contained in:
Razvan Maries 2021-01-07 14:55:07 +02:00
Родитель f2d5237921
Коммит 6565293451
4 изменённых файлов: 92 добавлений и 0 удалений

Просмотреть файл

@ -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)) {