mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 916255 - Allow script loaders to have multiple in flight off thread parses (r=bz)
This commit is contained in:
parent
ffa4f41c94
commit
f0abb0946d
@ -717,62 +717,64 @@ namespace {
|
|||||||
|
|
||||||
class NotifyOffThreadScriptLoadCompletedRunnable : public nsRunnable
|
class NotifyOffThreadScriptLoadCompletedRunnable : public nsRunnable
|
||||||
{
|
{
|
||||||
nsRefPtr<nsScriptLoader> mLoader;
|
nsRefPtr<nsScriptLoadRequest> mRequest;
|
||||||
void *mToken;
|
nsRefPtr<nsScriptLoader> mLoader;
|
||||||
|
void *mToken;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NotifyOffThreadScriptLoadCompletedRunnable(already_AddRefed<nsScriptLoader> aLoader,
|
NotifyOffThreadScriptLoadCompletedRunnable(nsScriptLoadRequest* aRequest,
|
||||||
void *aToken)
|
nsScriptLoader* aLoader)
|
||||||
: mLoader(aLoader), mToken(aToken)
|
: mRequest(aRequest), mLoader(aLoader), mToken(NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
NS_DECL_NSIRUNNABLE
|
void SetToken(void* aToken) {
|
||||||
|
MOZ_ASSERT(aToken && !mToken);
|
||||||
|
mToken = aToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_DECL_NSIRUNNABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* anonymous namespace */
|
} /* anonymous namespace */
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsScriptLoader::ProcessOffThreadRequest(void **aOffThreadToken)
|
nsScriptLoader::ProcessOffThreadRequest(nsScriptLoadRequest* aRequest, void **aOffThreadToken)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsScriptLoadRequest> request = mOffThreadScriptRequest;
|
nsresult rv = ProcessRequest(aRequest, aOffThreadToken);
|
||||||
mOffThreadScriptRequest = nullptr;
|
mDocument->UnblockOnload(false);
|
||||||
nsresult rv = ProcessRequest(request, aOffThreadToken);
|
return rv;
|
||||||
mDocument->UnblockOnload(false);
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
NotifyOffThreadScriptLoadCompletedRunnable::Run()
|
NotifyOffThreadScriptLoadCompletedRunnable::Run()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
nsresult rv = mLoader->ProcessOffThreadRequest(&mToken);
|
nsresult rv = mLoader->ProcessOffThreadRequest(mRequest, &mToken);
|
||||||
|
|
||||||
if (mToken) {
|
if (mToken) {
|
||||||
// The result of the off thread parse was not actually needed to process
|
// The result of the off thread parse was not actually needed to process
|
||||||
// the request (disappearing window, some other error, ...). Finish the
|
// the request (disappearing window, some other error, ...). Finish the
|
||||||
// request to avoid leaks in the JS engine.
|
// request to avoid leaks in the JS engine.
|
||||||
nsCOMPtr<nsIJSRuntimeService> svc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
|
nsCOMPtr<nsIJSRuntimeService> svc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
|
||||||
NS_ENSURE_TRUE(svc, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(svc, NS_ERROR_FAILURE);
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
svc->GetRuntime(&rt);
|
svc->GetRuntime(&rt);
|
||||||
NS_ENSURE_TRUE(rt, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(rt, NS_ERROR_FAILURE);
|
||||||
JS::FinishOffThreadScript(nullptr, rt, mToken);
|
JS::FinishOffThreadScript(nullptr, rt, mToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
OffThreadScriptLoaderCallback(void *aToken, void *aCallbackData)
|
OffThreadScriptLoaderCallback(void *aToken, void *aCallbackData)
|
||||||
{
|
{
|
||||||
// Be careful not to adjust the refcount on the loader, as this callback
|
NotifyOffThreadScriptLoadCompletedRunnable* aRunnable =
|
||||||
// may be invoked off the main thread.
|
static_cast<NotifyOffThreadScriptLoadCompletedRunnable*>(aCallbackData);
|
||||||
nsScriptLoader* aLoader = static_cast<nsScriptLoader*>(aCallbackData);
|
aRunnable->SetToken(aToken);
|
||||||
nsRefPtr<NotifyOffThreadScriptLoadCompletedRunnable> notify =
|
NS_DispatchToMainThread(aRunnable);
|
||||||
new NotifyOffThreadScriptLoadCompletedRunnable(
|
NS_RELEASE(aRunnable);
|
||||||
already_AddRefed<nsScriptLoader>(aLoader), aToken);
|
|
||||||
NS_DispatchToMainThread(notify);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
@ -782,10 +784,6 @@ nsScriptLoader::AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest)
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mOffThreadScriptRequest) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSObject *unrootedGlobal;
|
JSObject *unrootedGlobal;
|
||||||
nsCOMPtr<nsIScriptContext> context = GetScriptContext(&unrootedGlobal);
|
nsCOMPtr<nsIScriptContext> context = GetScriptContext(&unrootedGlobal);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
@ -801,17 +799,19 @@ nsScriptLoader::AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest)
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mOffThreadScriptRequest = aRequest;
|
NotifyOffThreadScriptLoadCompletedRunnable* runnable =
|
||||||
|
new NotifyOffThreadScriptLoadCompletedRunnable(aRequest, this);
|
||||||
|
|
||||||
|
// This reference will be consumed by OffThreadScriptLoaderCallback.
|
||||||
|
NS_ADDREF(runnable);
|
||||||
|
|
||||||
if (!JS::CompileOffThread(cx, global, options,
|
if (!JS::CompileOffThread(cx, global, options,
|
||||||
aRequest->mScriptText.get(), aRequest->mScriptText.Length(),
|
aRequest->mScriptText.get(), aRequest->mScriptText.Length(),
|
||||||
OffThreadScriptLoaderCallback,
|
OffThreadScriptLoaderCallback,
|
||||||
static_cast<void*>(this))) {
|
static_cast<void*>(runnable))) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This reference will be consumed by the NotifyOffThreadScriptLoadCompletedRunnable.
|
|
||||||
NS_ADDREF(this);
|
|
||||||
|
|
||||||
mDocument->BlockOnload();
|
mDocument->BlockOnload();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -211,7 +211,8 @@ public:
|
|||||||
* Process a request that was deferred so that the script could be compiled
|
* Process a request that was deferred so that the script could be compiled
|
||||||
* off thread.
|
* off thread.
|
||||||
*/
|
*/
|
||||||
nsresult ProcessOffThreadRequest(void **aOffThreadToken);
|
nsresult ProcessOffThreadRequest(nsScriptLoadRequest *aRequest,
|
||||||
|
void **aOffThreadToken);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@ -316,7 +317,6 @@ private:
|
|||||||
};
|
};
|
||||||
nsTArray<PreloadInfo> mPreloads;
|
nsTArray<PreloadInfo> mPreloads;
|
||||||
|
|
||||||
nsCOMPtr<nsScriptLoadRequest> mOffThreadScriptRequest;
|
|
||||||
nsCOMPtr<nsIScriptElement> mCurrentScript;
|
nsCOMPtr<nsIScriptElement> mCurrentScript;
|
||||||
nsCOMPtr<nsIScriptElement> mCurrentParserInsertedScript;
|
nsCOMPtr<nsIScriptElement> mCurrentParserInsertedScript;
|
||||||
// XXXbz do we want to cycle-collect these or something? Not sure.
|
// XXXbz do we want to cycle-collect these or something? Not sure.
|
||||||
|
Loading…
Reference in New Issue
Block a user