mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1084009 - Part 1/3 - Parse sync scripts off the main thread. r=smaug
This commit is contained in:
parent
27860b35c5
commit
599f427f33
@ -597,7 +597,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
// loop gets a chance to spin.
|
||||
|
||||
// KVKV TODO: Instead of processing immediately, try off-thread-parsing
|
||||
// it and only schedule a ProcessRequest if that fails.
|
||||
// it and only schedule a pending ProcessRequest if that fails.
|
||||
ProcessPendingRequestsAsync();
|
||||
} else {
|
||||
mLoadingAsyncRequests.AppendElement(request);
|
||||
@ -646,6 +646,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (request->IsDoneLoading() && ReadyToExecuteScripts()) {
|
||||
// The request has already been loaded and there are no pending style
|
||||
// sheets. If the script comes from the network stream, cheat for
|
||||
@ -664,6 +665,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
ProcessPendingRequestsAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
// The script hasn't loaded yet or there's a style sheet blocking it.
|
||||
// The script will be run when it loads or the style sheet loads.
|
||||
NS_ASSERTION(!mParserBlockingRequest,
|
||||
@ -762,6 +764,23 @@ nsScriptLoader::ProcessOffThreadRequest(nsScriptLoadRequest* aRequest)
|
||||
{
|
||||
MOZ_ASSERT(aRequest->mProgress == nsScriptLoadRequest::Progress_Compiling);
|
||||
aRequest->mProgress = nsScriptLoadRequest::Progress_DoneCompiling;
|
||||
if (aRequest == mParserBlockingRequest) {
|
||||
if (!ReadyToExecuteScripts()) {
|
||||
// If not ready to execute scripts, schedule an async call to
|
||||
// ProcessPendingRequests to handle it.
|
||||
ProcessPendingRequestsAsync();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Same logic as in top of ProcessPendingRequests.
|
||||
mParserBlockingRequest = nullptr;
|
||||
UnblockParser(aRequest);
|
||||
ProcessRequest(aRequest);
|
||||
mDocument->UnblockOnload(false);
|
||||
ContinueParserAsync(aRequest);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = ProcessRequest(aRequest);
|
||||
mDocument->UnblockOnload(false);
|
||||
return rv;
|
||||
@ -810,9 +829,10 @@ OffThreadScriptLoaderCallback(void *aToken, void *aCallbackData)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScriptLoader::AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest)
|
||||
nsScriptLoader::AttemptAsyncScriptCompile(nsScriptLoadRequest* aRequest)
|
||||
{
|
||||
if (!aRequest->mElement->GetScriptAsync() || aRequest->mIsInline) {
|
||||
// Don't off-thread compile inline scripts.
|
||||
if (aRequest->mIsInline) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -853,7 +873,8 @@ nsScriptLoader::AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScriptLoader::CompileOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest)
|
||||
nsScriptLoader::CompileOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest,
|
||||
bool* oCompiledOffThread)
|
||||
{
|
||||
NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
|
||||
"Processing requests when running scripts is unsafe.");
|
||||
@ -862,8 +883,11 @@ nsScriptLoader::CompileOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest)
|
||||
NS_ASSERTION(!aRequest->InCompilingStage(),
|
||||
"Candidate for off-thread compile is already in compiling stage.");
|
||||
|
||||
nsresult rv = AttemptAsyncScriptParse(aRequest);
|
||||
nsresult rv = AttemptAsyncScriptCompile(aRequest);
|
||||
if (rv != NS_ERROR_FAILURE) {
|
||||
if (oCompiledOffThread && rv == NS_OK) {
|
||||
*oCompiledOffThread = true;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1154,8 +1178,12 @@ nsScriptLoader::ProcessPendingRequests()
|
||||
mParserBlockingRequest->IsReadyToRun() &&
|
||||
ReadyToExecuteScripts()) {
|
||||
request.swap(mParserBlockingRequest);
|
||||
bool offThreadCompiled = request->mProgress == nsScriptLoadRequest::Progress_DoneCompiling;
|
||||
UnblockParser(request);
|
||||
ProcessRequest(request);
|
||||
if (offThreadCompiled) {
|
||||
mDocument->UnblockOnload(false);
|
||||
}
|
||||
ContinueParserAsync(request);
|
||||
}
|
||||
|
||||
@ -1559,6 +1587,23 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
|
||||
// Mark this as loaded
|
||||
aRequest->mProgress = nsScriptLoadRequest::Progress_DoneLoading;
|
||||
|
||||
// If this is currently blocking the parser, attempt to compile it off-main-thread.
|
||||
if (aRequest == mParserBlockingRequest) {
|
||||
nsresult rv = AttemptAsyncScriptCompile(aRequest);
|
||||
if (rv == NS_OK) {
|
||||
NS_ASSERTION(aRequest->mProgress == nsScriptLoadRequest::Progress_Compiling,
|
||||
"Request should be off-thread compiling now.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If off-thread compile errored, return the error.
|
||||
if (rv != NS_ERROR_FAILURE) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// If off-thread compile was rejected, continue with regular processing.
|
||||
}
|
||||
|
||||
// And if it's async, move it to the loaded list. aRequest->mIsAsync really
|
||||
// _should_ be in a list, but the consequences if it's not are bad enough we
|
||||
// want to avoid trying to move it if it's not.
|
||||
|
@ -470,9 +470,10 @@ private:
|
||||
return mEnabled && !mBlockerCount;
|
||||
}
|
||||
|
||||
nsresult AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest);
|
||||
nsresult AttemptAsyncScriptCompile(nsScriptLoadRequest* aRequest);
|
||||
nsresult ProcessRequest(nsScriptLoadRequest* aRequest);
|
||||
nsresult CompileOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest);
|
||||
nsresult CompileOffThreadOrProcessRequest(nsScriptLoadRequest* aRequest,
|
||||
bool* oCompiledOffThread=nullptr);
|
||||
void FireScriptAvailable(nsresult aResult,
|
||||
nsScriptLoadRequest* aRequest);
|
||||
void FireScriptEvaluated(nsresult aResult,
|
||||
|
@ -4089,7 +4089,7 @@ JS::CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& opt
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length)
|
||||
{
|
||||
static const size_t TINY_LENGTH = 1000;
|
||||
static const size_t TINY_LENGTH = 5 * 1000;
|
||||
static const size_t HUGE_LENGTH = 100 * 1000;
|
||||
|
||||
// These are heuristics which the caller may choose to ignore (e.g., for
|
||||
|
Loading…
Reference in New Issue
Block a user