Bug 1149235 part 3. Store async requests in the scriptloader in two lists, so we don't have to grovel about looking for loaded ones. r=sicking

This commit is contained in:
Boris Zbarsky 2015-04-08 22:50:46 -04:00
parent c932d1e3d9
commit f6342f9c1f
2 changed files with 29 additions and 20 deletions

View File

@ -132,7 +132,12 @@ nsScriptLoader::~nsScriptLoader()
req->FireScriptAvailable(NS_ERROR_ABORT);
}
for (nsScriptLoadRequest* req = mAsyncRequests.getFirst(); req;
for (nsScriptLoadRequest* req = mLoadingAsyncRequests.getFirst(); req;
req = req->getNext()) {
req->FireScriptAvailable(NS_ERROR_ABORT);
}
for (nsScriptLoadRequest* req = mLoadedAsyncRequests.getFirst(); req;
req = req->getNext()) {
req->FireScriptAvailable(NS_ERROR_ABORT);
}
@ -626,11 +631,13 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
if (aElement->GetScriptAsync()) {
request->mIsAsync = true;
mAsyncRequests.AppendElement(request);
if (!request->mLoading) {
mLoadedAsyncRequests.AppendElement(request);
// The script is available already. Run it ASAP when the event
// loop gets a chance to spin.
ProcessPendingRequestsAsync();
} else {
mLoadingAsyncRequests.AppendElement(request);
}
return false;
}
@ -1177,18 +1184,9 @@ nsScriptLoader::ProcessPendingRequests()
ProcessRequest(request);
}
// The refcounting here is dumb, but it's going away in the next
// patch in the queue.
nsRefPtr<nsScriptLoadRequest> req = mAsyncRequests.getFirst();
while (mEnabled && req && req->isInList()) {
if (!req->mLoading) {
nsRefPtr<nsScriptLoadRequest> next = req->getNext();
request = mAsyncRequests.Steal(req);
ProcessRequest(request);
req.swap(next);
continue;
}
req = req->getNext();
while (mEnabled && !mLoadedAsyncRequests.isEmpty()) {
request = mLoadedAsyncRequests.StealFirst();
ProcessRequest(request);
}
while (mEnabled && !mNonAsyncExternalScriptInsertedRequests.isEmpty() &&
@ -1215,7 +1213,8 @@ nsScriptLoader::ProcessPendingRequests()
}
if (mDocumentParsingDone && mDocument &&
!mParserBlockingRequest && mAsyncRequests.isEmpty() &&
!mParserBlockingRequest && mLoadingAsyncRequests.isEmpty() &&
mLoadedAsyncRequests.isEmpty() &&
mNonAsyncExternalScriptInsertedRequests.isEmpty() &&
mXSLTRequests.isEmpty() && mDeferRequests.isEmpty()) {
if (MaybeRemovedDeferRequests()) {
@ -1430,7 +1429,7 @@ nsScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader,
}
} else if (request->mIsAsync) {
if (request->isInList()) {
nsRefPtr<nsScriptLoadRequest> req = mAsyncRequests.Steal(request);
nsRefPtr<nsScriptLoadRequest> req = mLoadingAsyncRequests.Steal(request);
FireScriptAvailable(rv, req);
}
} else if (request->mIsNonAsyncScriptInserted) {
@ -1547,7 +1546,7 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
// so if you see this assertion it is likely something else that is
// wrong, especially if you see it more than once.
NS_ASSERTION(mDeferRequests.Contains(aRequest) ||
mAsyncRequests.Contains(aRequest) ||
mLoadingAsyncRequests.Contains(aRequest) ||
mNonAsyncExternalScriptInsertedRequests.Contains(aRequest) ||
mXSLTRequests.Contains(aRequest) ||
mPreloads.Contains(aRequest, PreloadRequestComparator()) ||
@ -1557,6 +1556,12 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
// Mark this as loaded
aRequest->mLoading = false;
// And if it's async, move it to the loaded list.
if (aRequest->mIsAsync) {
nsRefPtr<nsScriptLoadRequest> req = mLoadingAsyncRequests.Steal(aRequest);
mLoadedAsyncRequests.AppendElement(req);
}
return NS_OK;
}
@ -1571,7 +1576,8 @@ nsScriptLoader::ParsingComplete(bool aTerminated)
mDeferEnabled = false;
if (aTerminated) {
mDeferRequests.Clear();
mAsyncRequests.Clear();
mLoadingAsyncRequests.Clear();
mLoadedAsyncRequests.Clear();
mNonAsyncExternalScriptInsertedRequests.Clear();
mXSLTRequests.Clear();
mParserBlockingRequest = nullptr;

View File

@ -97,7 +97,7 @@ public:
bool mIsInline; // Is the script inline or loaded?
bool mHasSourceMapURL; // Does the HTTP header have a source map url?
bool mIsDefer; // True if we live in mDeferRequests.
bool mIsAsync; // True if we live in mAsyncRequests.
bool mIsAsync; // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
bool mIsNonAsyncScriptInserted; // True if we live in mNonAsyncExternalScriptInsertedRequests
bool mIsXSLT; // True if we live in mXSLTRequests.
nsString mSourceMapURL; // Holds source map url for loaded scripts
@ -455,7 +455,10 @@ private:
nsIDocument* mDocument; // [WEAK]
nsCOMArray<nsIScriptLoaderObserver> mObservers;
nsScriptLoadRequestList mNonAsyncExternalScriptInsertedRequests;
nsScriptLoadRequestList mAsyncRequests;
// mLoadingAsyncRequests holds async requests while they're loading; when they
// have been loaded they are moved to mLoadedAsyncRequests.
nsScriptLoadRequestList mLoadingAsyncRequests;
nsScriptLoadRequestList mLoadedAsyncRequests;
nsScriptLoadRequestList mDeferRequests;
nsScriptLoadRequestList mXSLTRequests;
nsRefPtr<nsScriptLoadRequest> mParserBlockingRequest;