Bug 1646776 - Move the preloader for stylesheets to SheetLoadData rather than StreamLoader. r=mayhemer

So as to make sense in a world where we can coalesce loads across
documents. The per-load object is the SheetLoadData, so this way we
guarantee that we fire the right events in presence of the load
coalescing that the SharedStyleSheetCache does.

Differential Revision: https://phabricator.services.mozilla.com/D80380
This commit is contained in:
Emilio Cobos Álvarez 2020-06-22 18:10:07 +00:00
Родитель 8c691e51cb
Коммит e696ebbe20
4 изменённых файлов: 39 добавлений и 40 удалений

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

@ -21,6 +21,7 @@
#include "mozilla/SchedulerGroup.h"
#include "mozilla/URLPreloader.h"
#include "nsIRunnable.h"
#include "nsISupportsPriority.h"
#include "nsITimedChannel.h"
#include "nsICachingChannel.h"
#include "nsSyncLoadService.h"
@ -412,6 +413,14 @@ SheetLoadData::AfterProcessNextEvent(nsIThreadInternal* aThread,
return NS_OK;
}
void SheetLoadData::PrioritizeAsPreload(nsIChannel* aChannel) {
if (nsCOMPtr<nsISupportsPriority> sp = do_QueryInterface(aChannel)) {
sp->AdjustPriority(nsISupportsPriority::PRIORITY_HIGHEST);
}
}
void SheetLoadData::PrioritizeAsPreload() { PrioritizeAsPreload(Channel()); }
void SheetLoadData::FireLoadEvent(nsIThreadInternal* aThread) {
// First remove ourselves as a thread observer. But we need to keep
// ourselves alive while doing that!
@ -1239,6 +1248,9 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState) {
SheetLoadDataHashKey key(aLoadData);
mLoadsPerformed.PutEntry(key);
auto preloadKey = PreloadHashKey::CreateAsStyle(aLoadData);
bool coalescedLoad = false;
if (mSheets) {
// If we have at least one other load ongoing, then we can defer it until
// all non-pending loads are done.
@ -1249,17 +1261,23 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState) {
mSheets->DeferSheetLoad(aLoadData);
return NS_OK;
}
if (mSheets->CoalesceLoad(key, aLoadData, aSheetState)) {
if ((coalescedLoad = mSheets->CoalesceLoad(key, aLoadData, aSheetState))) {
if (aSheetState == SheetState::Pending) {
++mPendingLoadCount;
return NS_OK;
}
// All done here; once the load completes we'll be marked complete
// automatically
return NS_OK;
}
}
aLoadData.NotifyOpen(preloadKey, mDocument,
aLoadData.mIsPreload == IsPreload::FromLink);
if (coalescedLoad) {
// All done here; once the load completes we'll be marked complete
// automatically.
return NS_OK;
}
nsCOMPtr<nsILoadGroup> loadGroup;
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
if (mDocument) {
@ -1339,8 +1357,8 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState) {
cos->AddClassFlags(nsIClassOfService::Leader);
}
if (aLoadData.mIsPreload == IsPreload::FromLink) {
StreamLoader::PrioritizeAsPreload(channel);
StreamLoader::AddLoadBackgroundFlag(channel);
SheetLoadData::PrioritizeAsPreload(channel);
SheetLoadData::AddLoadBackgroundFlag(channel);
}
}
@ -1414,16 +1432,12 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState) {
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, mDocument);
}
auto preloadKey = PreloadHashKey::CreateAsStyle(aLoadData);
streamLoader->NotifyOpen(preloadKey, channel, mDocument,
aLoadData.mIsPreload == IsPreload::FromLink);
rv = channel->AsyncOpen(streamLoader);
if (NS_FAILED(rv)) {
LOG_ERROR((" Failed to create stream loader"));
// ChannelOpenFailed makes sure that <link preload> nodes will get the
// proper notification about not being able to load this resource.
streamLoader->ChannelOpenFailed(rv);
// NOTE: NotifyStop will be done in SheetComplete -> NotifyObservers.
aLoadData.NotifyStart(channel);
SheetComplete(aLoadData, rv);
return rv;
}
@ -1497,6 +1511,7 @@ void Loader::NotifyObservers(SheetLoadData& aData, nsresult aStatus) {
if (aData.mURI) {
MOZ_DIAGNOSTIC_ASSERT(mOngoingLoadCount);
--mOngoingLoadCount;
aData.NotifyStop(aStatus);
}
if (aData.mMustNotify) {

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

@ -10,6 +10,7 @@
#include "mozilla/css/Loader.h"
#include "mozilla/css/SheetParsingMode.h"
#include "mozilla/Encoding.h"
#include "mozilla/PreloaderBase.h"
#include "mozilla/NotNull.h"
#include "mozilla/UniquePtr.h"
#include "nsIThreadInternal.h"
@ -37,7 +38,9 @@ static_assert(eAuthorSheetFeatures == 0 && eUserSheetFeatures == 1 &&
"sheet parsing mode constants won't fit "
"in SheetLoadData::mParsingMode");
class SheetLoadData final : public nsIRunnable, public nsIThreadObserver {
class SheetLoadData final : public PreloaderBase,
public nsIRunnable,
public nsIThreadObserver {
using MediaMatched = dom::LinkStyle::MediaMatched;
using IsAlternate = dom::LinkStyle::IsAlternate;
using IsPreload = Loader::IsPreload;
@ -47,6 +50,10 @@ class SheetLoadData final : public nsIRunnable, public nsIThreadObserver {
virtual ~SheetLoadData();
public:
// PreloaderBase
static void PrioritizeAsPreload(nsIChannel* aChannel);
void PrioritizeAsPreload() final;
// Data for loading a sheet linked from a document
SheetLoadData(Loader* aLoader, const nsAString& aTitle, nsIURI* aURI,
StyleSheet* aSheet, bool aSyncLoad, nsINode* aOwningNode,

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

@ -11,7 +11,6 @@
#include "nsContentUtils.h"
#include "nsIChannel.h"
#include "nsIInputStream.h"
#include "nsISupportsPriority.h"
#include <limits>
@ -31,19 +30,11 @@ StreamLoader::~StreamLoader() {
NS_IMPL_ISUPPORTS(StreamLoader, nsIStreamListener)
// static
void StreamLoader::PrioritizeAsPreload(nsIChannel* aChannel) {
if (nsCOMPtr<nsISupportsPriority> sp = do_QueryInterface(aChannel)) {
sp->AdjustPriority(nsISupportsPriority::PRIORITY_HIGHEST);
}
}
void StreamLoader::PrioritizeAsPreload() { PrioritizeAsPreload(Channel()); }
/* nsIRequestObserver implementation */
NS_IMETHODIMP
StreamLoader::OnStartRequest(nsIRequest* aRequest) {
NotifyStart(aRequest);
MOZ_ASSERT(aRequest);
mSheetLoadData->NotifyStart(aRequest);
// It's kinda bad to let Web content send a number that results
// in a potentially large allocation directly, but efficiency of
@ -72,8 +63,6 @@ StreamLoader::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
#endif
nsresult rv = mStatus;
auto notifyStop = MakeScopeExit([&] { NotifyStop(aRequest, rv); });
// Decoded data
nsCString utf8String;
{
@ -93,11 +82,6 @@ StreamLoader::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
rv = mSheetLoadData->VerifySheetReadyToParse(aStatus, mBOMBytes, bytes,
channel);
if (rv != NS_OK_PARSE_SHEET) {
// VerifySheetReadyToParse returns `NS_OK` when there was something wrong
// with the script. We need to override the result so that any <link
// preload> tags associted to this load will be notified the "error"
// event. It's fine because this error goes no where.
rv = NS_ERROR_NOT_AVAILABLE;
return rv;
}

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

@ -11,31 +11,24 @@
#include "nsString.h"
#include "mozilla/css/SheetLoadData.h"
#include "mozilla/Assertions.h"
#include "mozilla/PreloaderBase.h"
class nsIInputStream;
namespace mozilla {
namespace css {
class StreamLoader : public PreloaderBase, public nsIStreamListener {
class StreamLoader : public nsIStreamListener {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
// PreloaderBase
static void PrioritizeAsPreload(nsIChannel* aChannel);
virtual void PrioritizeAsPreload() override;
explicit StreamLoader(SheetLoadData&);
void ChannelOpenFailed(nsresult rv) {
#ifdef NIGHTLY_BUILD
mChannelOpenFailed = true;
#endif
NotifyStart(Channel());
NotifyStop(Channel(), rv);
}
private: