From 7b4d55d37591986753fc973e16fb43f762cdf7b4 Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Wed, 11 Sep 2019 15:33:00 +0000 Subject: [PATCH] Bug 1548373: Report Open stacks for XHR responses. r=mayhemer,julienw Differential Revision: https://phabricator.services.mozilla.com/D42831 --HG-- extra : moz-landing-system : lando --- dom/xhr/XMLHttpRequestMainThread.cpp | 13 +++++++++++++ dom/xhr/XMLHttpRequestMainThread.h | 2 ++ dom/xhr/XMLHttpRequestWorker.cpp | 18 ++++++++++++++---- netwerk/protocol/http/HttpBaseChannel.h | 6 ++++++ netwerk/protocol/http/HttpChannelChild.cpp | 16 ++++++++-------- netwerk/protocol/http/nsHttpChannel.cpp | 11 ++++++----- netwerk/protocol/http/nsIHttpChannel.idl | 4 ++++ tools/profiler/core/platform.cpp | 5 +++-- tools/profiler/public/GeckoProfiler.h | 6 +++--- tools/profiler/public/ProfilerMarkerPayload.h | 6 ++++-- 10 files changed, 63 insertions(+), 24 deletions(-) diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index ce06a9340de1..8ee08fa758fc 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -2404,6 +2404,8 @@ nsresult XMLHttpRequestMainThread::CreateChannel() { rv = httpChannel->SetRequestMethod(mRequestMethod); NS_ENSURE_SUCCESS(rv, rv); + httpChannel->SetSource(profiler_get_backtrace()); + // Set the initiator type nsCOMPtr timedChannel(do_QueryInterface(httpChannel)); if (timedChannel) { @@ -3120,6 +3122,17 @@ void XMLHttpRequestMainThread::SetOriginStack( mOriginStack = std::move(aOriginStack); } +void XMLHttpRequestMainThread::SetSource(UniqueProfilerBacktrace aSource) { + if (!mChannel) { + return; + } + nsCOMPtr httpChannel = do_QueryInterface(mChannel); + + if (httpChannel) { + httpChannel->SetSource(std::move(aSource)); + } +} + bool XMLHttpRequestMainThread::WithCredentials() const { return mFlagACwithCredentials; } diff --git a/dom/xhr/XMLHttpRequestMainThread.h b/dom/xhr/XMLHttpRequestMainThread.h index 0b6581f7b466..aae79e82979e 100644 --- a/dom/xhr/XMLHttpRequestMainThread.h +++ b/dom/xhr/XMLHttpRequestMainThread.h @@ -391,6 +391,8 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest, void SetOriginStack(UniquePtr aOriginStack); + void SetSource(UniqueProfilerBacktrace aSource); + virtual uint16_t ErrorCode() const override { return static_cast(mErrorLoad); } diff --git a/dom/xhr/XMLHttpRequestWorker.cpp b/dom/xhr/XMLHttpRequestWorker.cpp index bd4b122b6474..140ab5c38fd0 100644 --- a/dom/xhr/XMLHttpRequestWorker.cpp +++ b/dom/xhr/XMLHttpRequestWorker.cpp @@ -671,6 +671,10 @@ class OpenRunnable final : public WorkerThreadProxySyncRunnable { // be passed on to the net monitor. UniquePtr mOriginStack; + // Remember the worker thread's stack when the XHR was opened for profiling + // purposes. + UniqueProfilerBacktrace mSource; + public: OpenRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy, const nsACString& aMethod, const nsAString& aURL, @@ -679,7 +683,8 @@ class OpenRunnable final : public WorkerThreadProxySyncRunnable { bool aWithCredentials, uint32_t aTimeout, XMLHttpRequestResponseType aResponseType, const nsString& aMimeTypeOverride, - UniquePtr aOriginStack) + UniquePtr aOriginStack, + UniqueProfilerBacktrace aSource = nullptr) : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mMethod(aMethod), mURL(aURL), @@ -688,7 +693,8 @@ class OpenRunnable final : public WorkerThreadProxySyncRunnable { mTimeout(aTimeout), mResponseType(aResponseType), mMimeTypeOverride(aMimeTypeOverride), - mOriginStack(std::move(aOriginStack)) { + mOriginStack(std::move(aOriginStack)), + mSource(std::move(aSource)) { if (aUser.WasPassed()) { mUserStr = aUser.Value(); mUser = &mUserStr; @@ -1322,6 +1328,10 @@ nsresult OpenRunnable::MainThreadRunInternal() { return rv.StealNSResult(); } + if (mSource) { + mProxy->mXHR->SetSource(std::move(mSource)); + } + mProxy->mXHR->SetResponseType(mResponseType, rv); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); @@ -1796,8 +1806,8 @@ void XMLHttpRequestWorker::Open(const nsACString& aMethod, RefPtr runnable = new OpenRunnable( mWorkerPrivate, mProxy, aMethod, aUrl, aUser, aPassword, mBackgroundRequest, mWithCredentials, mTimeout, mResponseType, - alsoOverrideMimeType ? mMimeTypeOverride : VoidString(), - std::move(stack)); + alsoOverrideMimeType ? mMimeTypeOverride : VoidString(), std::move(stack), + profiler_get_backtrace()); ++mProxy->mOpenCount; runnable->Dispatch(Canceling, aRv); diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index 46d3fd586bcd..06100252a31d 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -249,6 +249,10 @@ class HttpBaseChannel : public nsHashPropertyBag, using nsIHttpChannel::IsThirdPartyTrackingResource; + virtual void SetSource(UniqueProfilerBacktrace aSource) override { + mSource = std::move(aSource); + } + // nsIHttpChannelInternal NS_IMETHOD GetDocumentURI(nsIURI** aDocumentURI) override; NS_IMETHOD SetDocumentURI(nsIURI* aDocumentURI) override; @@ -721,6 +725,8 @@ class HttpBaseChannel : public nsHashPropertyBag, Atomic mThirdPartyClassificationFlags; Atomic mFlashPluginState; + UniqueProfilerBacktrace mSource; + uint32_t mLoadFlags; uint32_t mCaps; uint32_t mClassOfService; diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index 97568d6c6515..7116028d5418 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -1117,10 +1117,10 @@ void HttpChannelChild::OnStopRequest( if (profiler_is_active()) { int32_t priority = PRIORITY_NORMAL; GetPriority(&priority); - profiler_add_network_marker(mURI, priority, mChannelId, - NetworkLoadType::LOAD_STOP, mLastStatusReported, - TimeStamp::Now(), mTransferSize, kCacheUnknown, - &mTransactionTimings); + profiler_add_network_marker( + mURI, priority, mChannelId, NetworkLoadType::LOAD_STOP, + mLastStatusReported, TimeStamp::Now(), mTransferSize, kCacheUnknown, + &mTransactionTimings, nullptr, std::move(mSource)); } #endif @@ -1785,10 +1785,10 @@ void HttpChannelChild::Redirect1Begin( nsCOMPtr uri = DeserializeURI(newOriginalURI); mTransactionTimings = timing; - PROFILER_ADD_NETWORK_MARKER(mURI, mPriority, mChannelId, - NetworkLoadType::LOAD_REDIRECT, - mLastStatusReported, TimeStamp::Now(), 0, - kCacheUnknown, &mTransactionTimings, uri); + PROFILER_ADD_NETWORK_MARKER( + mURI, mPriority, mChannelId, NetworkLoadType::LOAD_REDIRECT, + mLastStatusReported, TimeStamp::Now(), 0, kCacheUnknown, + &mTransactionTimings, uri, std::move(mSource)); if (!securityInfoSerialization.IsEmpty()) { rv = NS_DeserializeObject(securityInfoSerialization, diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 65e7314b75b3..2693ec960fe9 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -5932,7 +5932,7 @@ nsresult nsHttpChannel::ContinueProcessRedirectionAfterFallback(nsresult rv) { profiler_add_network_marker( mURI, priority, mChannelId, NetworkLoadType::LOAD_REDIRECT, mLastStatusReported, TimeStamp::Now(), mLogicalOffset, - mCacheDisposition, &timings, mRedirectURI); + mCacheDisposition, &timings, mRedirectURI, std::move(mSource)); } #endif @@ -6361,9 +6361,10 @@ nsHttpChannel::AsyncOpen(nsIStreamListener* aListener) { mLastStatusReported = TimeStamp::Now(); // in case we enable the profiler after AsyncOpen() if (profiler_is_active()) { - profiler_add_network_marker( - mURI, mPriority, mChannelId, NetworkLoadType::LOAD_START, - mChannelCreationTimestamp, mLastStatusReported, 0, mCacheDisposition); + profiler_add_network_marker(mURI, mPriority, mChannelId, + NetworkLoadType::LOAD_START, + mChannelCreationTimestamp, mLastStatusReported, + 0, mCacheDisposition, nullptr, nullptr); } #endif @@ -8245,7 +8246,7 @@ nsresult nsHttpChannel::ContinueOnStopRequest(nsresult aStatus, bool aIsFromNet, profiler_add_network_marker( uri, priority, mChannelId, NetworkLoadType::LOAD_STOP, mLastStatusReported, TimeStamp::Now(), mLogicalOffset, - mCacheDisposition, &mTransactionTimings, nullptr); + mCacheDisposition, &mTransactionTimings, nullptr, std::move(mSource)); } #endif diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl index beaee4aecd4e..01e39d995a35 100644 --- a/netwerk/protocol/http/nsIHttpChannel.idl +++ b/netwerk/protocol/http/nsIHttpChannel.idl @@ -625,4 +625,8 @@ interface nsIHttpChannel : nsIIdentChannel in boolean aWarning, in AString aURL, in AString aContentType); + +%{ C++ + virtual void SetSource(UniqueProfilerBacktrace aSource) {} +%} }; diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp index e3f1561a67ab..07a2dc4f13f2 100644 --- a/tools/profiler/core/platform.cpp +++ b/tools/profiler/core/platform.cpp @@ -4053,7 +4053,8 @@ void profiler_add_network_marker( nsIURI* aURI, int32_t aPriority, uint64_t aChannelId, NetworkLoadType aType, mozilla::TimeStamp aStart, mozilla::TimeStamp aEnd, int64_t aCount, mozilla::net::CacheDisposition aCacheDisposition, - const mozilla::net::TimingStruct* aTimings, nsIURI* aRedirectURI) { + const mozilla::net::TimingStruct* aTimings, nsIURI* aRedirectURI, + UniqueProfilerBacktrace aSource) { if (!profiler_is_active()) { return; } @@ -4076,7 +4077,7 @@ void profiler_add_network_marker( MakeUnique( static_cast(aChannelId), PromiseFlatCString(spec).get(), aType, aStart, aEnd, aPriority, aCount, aCacheDisposition, aTimings, - PromiseFlatCString(redirect_spec).get())); + PromiseFlatCString(redirect_spec).get(), std::move(aSource))); } // This logic needs to add a marker for a different thread, so we actually need diff --git a/tools/profiler/public/GeckoProfiler.h b/tools/profiler/public/GeckoProfiler.h index e4fedb549907..0278b59c013c 100644 --- a/tools/profiler/public/GeckoProfiler.h +++ b/tools/profiler/public/GeckoProfiler.h @@ -715,16 +715,16 @@ void profiler_add_marker_for_thread( enum class NetworkLoadType { LOAD_START, LOAD_STOP, LOAD_REDIRECT }; # define PROFILER_ADD_NETWORK_MARKER(uri, pri, channel, type, start, end, \ - count, cache, timings, redirect) \ + count, cache, timings, redirect, ...) \ profiler_add_network_marker(uri, pri, channel, type, start, end, count, \ - cache, timings, redirect) + cache, timings, redirect, ##__VA_ARGS__) void profiler_add_network_marker( nsIURI* aURI, int32_t aPriority, uint64_t aChannelId, NetworkLoadType aType, mozilla::TimeStamp aStart, mozilla::TimeStamp aEnd, int64_t aCount, mozilla::net::CacheDisposition aCacheDisposition, const mozilla::net::TimingStruct* aTimings = nullptr, - nsIURI* aRedirectURI = nullptr); + nsIURI* aRedirectURI = nullptr, UniqueProfilerBacktrace aSource = nullptr); enum TracingKind { TRACING_EVENT, diff --git a/tools/profiler/public/ProfilerMarkerPayload.h b/tools/profiler/public/ProfilerMarkerPayload.h index 7d655711b36a..57e31e056223 100644 --- a/tools/profiler/public/ProfilerMarkerPayload.h +++ b/tools/profiler/public/ProfilerMarkerPayload.h @@ -251,8 +251,10 @@ class NetworkMarkerPayload : public ProfilerMarkerPayload { int64_t aCount, mozilla::net::CacheDisposition aCacheDisposition, const mozilla::net::TimingStruct* aTimings = nullptr, - const char* aRedirectURI = nullptr) - : ProfilerMarkerPayload(aStartTime, aEndTime, mozilla::Nothing()), + const char* aRedirectURI = nullptr, + UniqueProfilerBacktrace aSource = nullptr) + : ProfilerMarkerPayload(aStartTime, aEndTime, mozilla::Nothing(), + mozilla::Nothing(), std::move(aSource)), mID(aID), mURI(aURI ? strdup(aURI) : nullptr), mRedirectURI(aRedirectURI && (strlen(aRedirectURI) > 0)