Bug 1392408 Part 3 - Report stacks to net monitor when loading worker scripts, r=bzbarsky.

--HG--
extra : rebase_source : c4b52354dc9c71bb86cd157f0f710d01b78659e5
This commit is contained in:
Brian Hackett 2019-05-02 08:34:27 -10:00
parent d5333b6d62
commit ab337aa92c
7 changed files with 58 additions and 19 deletions

View File

@ -1556,7 +1556,7 @@ DOMInterfaces = {
'WorkerGlobalScope': {
'headerFile': 'mozilla/dom/WorkerScope.h',
'implicitJSContext': [ 'createImageBitmap' ],
'implicitJSContext': [ 'createImageBitmap', 'importScripts' ],
'concrete': False,
# Rename a few things so we don't have both classes and methods
# with the same name

View File

@ -549,6 +549,8 @@ class ScriptLoaderRunnable final : public nsIRunnable, public nsINamed {
friend class LoaderListener;
WorkerPrivate* mWorkerPrivate;
UniquePtr<SerializedStackHolder> mOriginStack;
nsString mOriginStackJSON;
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
nsTArray<ScriptLoadInfo> mLoadInfos;
RefPtr<CacheCreator> mCacheCreator;
@ -563,6 +565,7 @@ class ScriptLoaderRunnable final : public nsIRunnable, public nsINamed {
NS_DECL_THREADSAFE_ISUPPORTS
ScriptLoaderRunnable(WorkerPrivate* aWorkerPrivate,
UniquePtr<SerializedStackHolder> aOriginStack,
nsIEventTarget* aSyncLoopTarget,
nsTArray<ScriptLoadInfo>& aLoadInfos,
const Maybe<ClientInfo>& aClientInfo,
@ -570,6 +573,7 @@ class ScriptLoaderRunnable final : public nsIRunnable, public nsINamed {
bool aIsMainScript, WorkerScriptType aWorkerScriptType,
ErrorResult& aRv)
: mWorkerPrivate(aWorkerPrivate),
mOriginStack(std::move(aOriginStack)),
mSyncLoopTarget(aSyncLoopTarget),
mClientInfo(aClientInfo),
mController(aController),
@ -836,6 +840,14 @@ class ScriptLoaderRunnable final : public nsIRunnable, public nsINamed {
mWorkerPrivate->SetLoadingWorkerScript(true);
}
// Convert the origin stack to JSON (which must be done on the main
// thread) explicitly, so that we can use the stack to notify the net
// monitor about every script we load.
if (mOriginStack) {
ConvertSerializedStackToJSON(std::move(mOriginStack),
mOriginStackJSON);
}
if (!mWorkerPrivate->IsServiceWorker() || IsDebuggerScript()) {
for (uint32_t index = 0, len = mLoadInfos.Length(); index < len;
++index) {
@ -962,6 +974,11 @@ class ScriptLoaderRunnable final : public nsIRunnable, public nsINamed {
}
}
// Associate any originating stack with the channel.
if (!mOriginStackJSON.IsEmpty()) {
NotifyNetworkMonitorAlternateStack(channel, mOriginStackJSON);
}
// We need to know which index we're on in OnStreamComplete so we know
// where to put the result.
RefPtr<LoaderListener> listener = new LoaderListener(this, aIndex);
@ -2081,6 +2098,7 @@ void ScriptExecutorRunnable::LogExceptionToConsole(
}
void LoadAllScripts(WorkerPrivate* aWorkerPrivate,
UniquePtr<SerializedStackHolder> aOriginStack,
nsTArray<ScriptLoadInfo>& aLoadInfos, bool aIsMainScript,
WorkerScriptType aWorkerScriptType, ErrorResult& aRv) {
aWorkerPrivate->AssertIsOnWorkerThread();
@ -2101,8 +2119,8 @@ void LoadAllScripts(WorkerPrivate* aWorkerPrivate,
}
RefPtr<ScriptLoaderRunnable> loader = new ScriptLoaderRunnable(
aWorkerPrivate, syncLoopTarget, aLoadInfos, clientInfo, controller,
aIsMainScript, aWorkerScriptType, aRv);
aWorkerPrivate, std::move(aOriginStack), syncLoopTarget, aLoadInfos, clientInfo,
controller, aIsMainScript, aWorkerScriptType, aRv);
NS_ASSERTION(aLoadInfos.IsEmpty(), "Should have swapped!");
@ -2222,7 +2240,9 @@ void ReportLoadError(ErrorResult& aRv, nsresult aLoadResult,
NS_LITERAL_CSTRING("\""));
}
void LoadMainScript(WorkerPrivate* aWorkerPrivate, const nsAString& aScriptURL,
void LoadMainScript(WorkerPrivate* aWorkerPrivate,
UniquePtr<SerializedStackHolder> aOriginStack,
const nsAString& aScriptURL,
WorkerScriptType aWorkerScriptType, ErrorResult& aRv) {
nsTArray<ScriptLoadInfo> loadInfos;
@ -2234,10 +2254,13 @@ void LoadMainScript(WorkerPrivate* aWorkerPrivate, const nsAString& aScriptURL,
// reserved.
info->mReservedClientInfo = aWorkerPrivate->GetClientInfo();
LoadAllScripts(aWorkerPrivate, loadInfos, true, aWorkerScriptType, aRv);
LoadAllScripts(aWorkerPrivate, std::move(aOriginStack), loadInfos, true,
aWorkerScriptType, aRv);
}
void Load(WorkerPrivate* aWorkerPrivate, const nsTArray<nsString>& aScriptURLs,
void Load(WorkerPrivate* aWorkerPrivate,
UniquePtr<SerializedStackHolder> aOriginStack,
const nsTArray<nsString>& aScriptURLs,
WorkerScriptType aWorkerScriptType, ErrorResult& aRv) {
const uint32_t urlCount = aScriptURLs.Length();
@ -2258,7 +2281,8 @@ void Load(WorkerPrivate* aWorkerPrivate, const nsTArray<nsString>& aScriptURLs,
loadInfos[index].mLoadFlags = aWorkerPrivate->GetLoadFlags();
}
LoadAllScripts(aWorkerPrivate, loadInfos, false, aWorkerScriptType, aRv);
LoadAllScripts(aWorkerPrivate, std::move(aOriginStack), loadInfos, false,
aWorkerScriptType, aRv);
}
} // namespace workerinternals

View File

@ -26,6 +26,7 @@ namespace dom {
struct WorkerLoadInfo;
class WorkerPrivate;
class SerializedStackHolder;
enum WorkerScriptType { WorkerScript, DebuggerScript };
@ -45,10 +46,14 @@ nsresult ChannelFromScriptURLWorkerThread(JSContext* aCx,
void ReportLoadError(ErrorResult& aRv, nsresult aLoadResult,
const nsAString& aScriptURL);
void LoadMainScript(WorkerPrivate* aWorkerPrivate, const nsAString& aScriptURL,
void LoadMainScript(WorkerPrivate* aWorkerPrivate,
UniquePtr<SerializedStackHolder> aOriginStack,
const nsAString& aScriptURL,
WorkerScriptType aWorkerScriptType, ErrorResult& aRv);
void Load(WorkerPrivate* aWorkerPrivate, const nsTArray<nsString>& aScriptURLs,
void Load(WorkerPrivate* aWorkerPrivate,
UniquePtr<SerializedStackHolder> aOriginStack,
const nsTArray<nsString>& aScriptURLs,
WorkerScriptType aWorkerScriptType, ErrorResult& aRv);
} // namespace workerinternals

View File

@ -103,8 +103,8 @@ class CompileDebuggerScriptRunnable final : public WorkerDebuggerRunnable {
ErrorResult rv;
JSAutoRealm ar(aCx, global);
workerinternals::LoadMainScript(aWorkerPrivate, mScriptURL, DebuggerScript,
rv);
workerinternals::LoadMainScript(aWorkerPrivate, nullptr, mScriptURL,
DebuggerScript, rv);
rv.WouldReportJSException();
// Explicitly ignore NS_BINDING_ABORTED on rv. Or more precisely, still
// return false and don't SetWorkerScriptExecutedSuccessfully() in that

View File

@ -302,12 +302,14 @@ class ModifyBusyCountRunnable final : public WorkerControlRunnable {
class CompileScriptRunnable final : public WorkerDebuggeeRunnable {
nsString mScriptURL;
UniquePtr<SerializedStackHolder> mOriginStack;
public:
explicit CompileScriptRunnable(WorkerPrivate* aWorkerPrivate,
UniquePtr<SerializedStackHolder> aOriginStack,
const nsAString& aScriptURL)
: WorkerDebuggeeRunnable(aWorkerPrivate, WorkerThreadModifyBusyCount),
mScriptURL(aScriptURL) {}
mScriptURL(aScriptURL), mOriginStack(aOriginStack.release()) {}
private:
// We can't implement PreRun effectively, because at the point when that would
@ -337,8 +339,8 @@ class CompileScriptRunnable final : public WorkerDebuggeeRunnable {
}
ErrorResult rv;
workerinternals::LoadMainScript(aWorkerPrivate, mScriptURL, WorkerScript,
rv);
workerinternals::LoadMainScript(aWorkerPrivate, std::move(mOriginStack),
mScriptURL, WorkerScript, rv);
rv.WouldReportJSException();
// Explicitly ignore NS_BINDING_ABORTED on rv. Or more precisely, still
// return false and don't SetWorkerScriptExecutedSuccessfully() in that
@ -2256,8 +2258,10 @@ already_AddRefed<WorkerPrivate> WorkerPrivate::Constructor(
MOZ_DIAGNOSTIC_ASSERT(worker->PrincipalIsValid());
UniquePtr<SerializedStackHolder> stack = GetCurrentStackForNetMonitor(aCx);
RefPtr<CompileScriptRunnable> compiler =
new CompileScriptRunnable(worker, aScriptURL);
new CompileScriptRunnable(worker, std::move(stack), aScriptURL);
if (!compiler->Dispatch()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;

View File

@ -235,10 +235,15 @@ void WorkerGlobalScope::SetOnerror(OnErrorEventHandlerNonNull* aHandler) {
}
}
void WorkerGlobalScope::ImportScripts(const Sequence<nsString>& aScriptURLs,
void WorkerGlobalScope::ImportScripts(JSContext* aCx,
const Sequence<nsString>& aScriptURLs,
ErrorResult& aRv) {
mWorkerPrivate->AssertIsOnWorkerThread();
workerinternals::Load(mWorkerPrivate, aScriptURLs, WorkerScript, aRv);
UniquePtr<SerializedStackHolder> stack = GetCurrentStackForNetMonitor(aCx);
workerinternals::Load(mWorkerPrivate, std::move(stack), aScriptURLs,
WorkerScript, aRv);
}
int32_t WorkerGlobalScope::SetTimeout(JSContext* aCx, Function& aHandler,
@ -906,7 +911,7 @@ void WorkerDebuggerGlobalScope::LoadSubScript(
nsTArray<nsString> urls;
urls.AppendElement(aURL);
workerinternals::Load(mWorkerPrivate, urls, DebuggerScript, aRv);
workerinternals::Load(mWorkerPrivate, nullptr, urls, DebuggerScript, aRv);
}
void WorkerDebuggerGlobalScope::EnterEventLoop() {

View File

@ -105,7 +105,8 @@ class WorkerGlobalScope : public DOMEventTargetHelper,
OnErrorEventHandlerNonNull* GetOnerror();
void SetOnerror(OnErrorEventHandlerNonNull* aHandler);
void ImportScripts(const Sequence<nsString>& aScriptURLs, ErrorResult& aRv);
void ImportScripts(JSContext* aCx, const Sequence<nsString>& aScriptURLs,
ErrorResult& aRv);
int32_t SetTimeout(JSContext* aCx, Function& aHandler, const int32_t aTimeout,
const Sequence<JS::Value>& aArguments, ErrorResult& aRv);