author | Valentin Gosu <valentin.gosu@gmail.com> |
Fri, 13 Nov 2020 13:48:00 +0000 | |
changeset 557256 | f8ce8da605a894697914a0e780fda51f54d47abd |
parent 557255 | 4b5ac6fbe89662c0fc8d58efa241dd3edd13f09d |
child 557257 | cc70ff610a7edf4cc4eb19a97d301292ef8ce04f |
push id | 37950 |
push user | btara@mozilla.com |
push date | Sun, 15 Nov 2020 09:34:18 +0000 |
treeherder | mozilla-central@25b666d6e2ab [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nika, necko-reviewers, dragana |
bugs | 1658097 |
milestone | 84.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -191,16 +191,17 @@ #endif #include "IHistory.h" #include "ReferrerInfo.h" #include "base/message_loop.h" #include "base/process_util.h" #include "base/task.h" #include "mozilla/dom/BlobURLProtocolHandler.h" #include "mozilla/dom/PCycleCollectWithLogsChild.h" +#include "mozilla/dom/PerformanceStorage.h" #include "nsChromeRegistryContent.h" #include "nsFrameMessageManager.h" #include "nsIScriptSecurityManager.h" #include "nsNetUtil.h" #include "nsWindowMemoryReporter.h" #ifdef MOZ_WEBRTC # include "jsapi/WebrtcGlobalChild.h" @@ -4073,16 +4074,34 @@ mozilla::ipc::IPCResult ContentChild::Re aColNumber, aFlags, aCategory, aInnerWindowId, aFromChromeContext); rv = consoleService->LogMessage(scriptError); NS_ENSURE_SUCCESS(rv, IPC_FAIL(this, "Failed to log script error")); return IPC_OK(); } +mozilla::ipc::IPCResult ContentChild::RecvReportFrameTimingData( + uint64_t innerWindowId, const nsString& entryName, + const nsString& initiatorType, UniquePtr<PerformanceTimingData>&& aData) { + auto* innerWindow = nsGlobalWindowInner::GetInnerWindowWithId(innerWindowId); + if (!innerWindow) { + return IPC_OK(); + } + + mozilla::dom::Performance* performance = innerWindow->GetPerformance(); + if (!performance) { + return IPC_OK(); + } + + performance->AsPerformanceStorage()->AddEntry(entryName, initiatorType, + std::move(aData)); + return IPC_OK(); +} + mozilla::ipc::IPCResult ContentChild::RecvLoadURI( const MaybeDiscarded<BrowsingContext>& aContext, nsDocShellLoadState* aLoadState, bool aSetNavigating, LoadURIResolver&& aResolve) { auto resolveOnExit = MakeScopeExit([&] { aResolve(true); }); if (aContext.IsNullOrDiscarded()) { return IPC_OK();
--- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -758,16 +758,20 @@ class ContentChild final : public PConte mozilla::ipc::IPCResult RecvScriptError( const nsString& aMessage, const nsString& aSourceName, const nsString& aSourceLine, const uint32_t& aLineNumber, const uint32_t& aColNumber, const uint32_t& aFlags, const nsCString& aCategory, const bool& aFromPrivateWindow, const uint64_t& aInnerWindowId, const bool& aFromChromeContext); + mozilla::ipc::IPCResult RecvReportFrameTimingData( + uint64_t innerWindowId, const nsString& entryName, + const nsString& initiatorType, UniquePtr<PerformanceTimingData>&& aData); + mozilla::ipc::IPCResult RecvLoadURI( const MaybeDiscarded<BrowsingContext>& aContext, nsDocShellLoadState* aLoadState, bool aSetNavigating, LoadURIResolver&& aResolve); mozilla::ipc::IPCResult RecvInternalLoad(nsDocShellLoadState* aLoadState, bool aTakeFocus);
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -4499,16 +4499,33 @@ mozilla::ipc::IPCResult ContentParent::R return IPC_OK(); } RefPtr<nsConsoleMessage> msg(new nsConsoleMessage(aMessage.get())); consoleService->LogMessageWithMode(msg, nsConsoleService::SuppressLog); return IPC_OK(); } +mozilla::ipc::IPCResult ContentParent::RecvReportFrameTimingData( + uint64_t aInnerWindowId, const nsString& entryName, + const nsString& initiatorType, UniquePtr<PerformanceTimingData>&& aData) { + RefPtr<WindowGlobalParent> parent = + WindowGlobalParent::GetByInnerWindowId(aInnerWindowId); + if (!parent || !parent->GetContentParent()) { + return IPC_OK(); + } + + MOZ_ASSERT(parent->GetContentParent() != this, + "No need to bounce around if in the same process"); + + Unused << parent->GetContentParent()->SendReportFrameTimingData( + aInnerWindowId, entryName, initiatorType, std::move(aData)); + return IPC_OK(); +} + mozilla::ipc::IPCResult ContentParent::RecvScriptError( const nsString& aMessage, const nsString& aSourceName, const nsString& aSourceLine, const uint32_t& aLineNumber, const uint32_t& aColNumber, const uint32_t& aFlags, const nsCString& aCategory, const bool& aFromPrivateWindow, const uint64_t& aInnerWindowId, const bool& aFromChromeContext) { return RecvScriptErrorInternal(aMessage, aSourceName, aSourceLine, aLineNumber, aColNumber, aFlags, aCategory,
--- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -1092,16 +1092,20 @@ class ContentParent final mozilla::ipc::IPCResult RecvScriptError( const nsString& aMessage, const nsString& aSourceName, const nsString& aSourceLine, const uint32_t& aLineNumber, const uint32_t& aColNumber, const uint32_t& aFlags, const nsCString& aCategory, const bool& aIsFromPrivateWindow, const uint64_t& aInnerWindowId, const bool& aIsFromChromeContext); + mozilla::ipc::IPCResult RecvReportFrameTimingData( + uint64_t innerWindowId, const nsString& entryName, + const nsString& initiatorType, UniquePtr<PerformanceTimingData>&& aData); + mozilla::ipc::IPCResult RecvScriptErrorWithStack( const nsString& aMessage, const nsString& aSourceName, const nsString& aSourceLine, const uint32_t& aLineNumber, const uint32_t& aColNumber, const uint32_t& aFlags, const nsCString& aCategory, const bool& aIsFromPrivateWindow, const bool& aIsFromChromeContext, const ClonedMessageData& aStack); private:
--- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -128,16 +128,17 @@ using mozilla::ContentBlocking::StorageA using JSActorMessageKind from "mozilla/dom/JSActor.h"; using JSActorMessageMeta from "mozilla/dom/PWindowGlobal.h"; using mozilla::PermissionDelegateHandler::DelegatedPermissionList from "mozilla/PermissionDelegateIPCUtils.h"; using refcounted class nsILayoutHistoryState from "nsILayoutHistoryState.h"; using class mozilla::dom::SessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h"; using nsPoint from "mozilla/GfxMessageUtils.h"; using struct mozilla::dom::LoadingSessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h"; using mozilla::PDMFactory::MediaCodecsSupported from "PDMFactory.h"; +using mozilla::dom::PerformanceTimingData from "mozilla/dom/PerformanceTiming.h"; union ChromeRegistryItem { ChromePackage; OverrideMapping; SubstitutionMapping; }; @@ -1703,16 +1704,26 @@ parent: MaybeDiscardedBrowsingContext aContext); both: async ScriptError(nsString message, nsString sourceName, nsString sourceLine, uint32_t lineNumber, uint32_t colNumber, uint32_t flags, nsCString category, bool privateWindow, uint64_t innerWindowId, bool fromChromeContext); + /** + * Used in fission to report timing data when the parent window is in + * another process. Child frame will send data to its ContentParent which + * will then identify the ContentParent for the innerWindowId and pass + * the data to the correct process. + */ + async ReportFrameTimingData(uint64_t innerWindowId, nsString entryName, + nsString initiatorType, + UniquePtr<PerformanceTimingData> aData); + async CommitBrowsingContextTransaction(MaybeDiscardedBrowsingContext aContext, BrowsingContextTransaction aTransaction, uint64_t aEpoch); async AsyncMessage(nsString aMessage, ClonedMessageData aData); /** * Notify `push-subscription-modified` observers in the parent and child.
--- a/dom/performance/PerformanceMainThread.cpp +++ b/dom/performance/PerformanceMainThread.cpp @@ -149,16 +149,22 @@ void PerformanceMainThread::AddEntry(nsI PerformanceTimingData::Create(timedChannel, channel, 0, initiatorType, entryName)); if (!performanceTimingData) { return; } AddRawEntry(std::move(performanceTimingData), initiatorType, entryName); } +void PerformanceMainThread::AddEntry(const nsString& entryName, + const nsString& initiatorType, + UniquePtr<PerformanceTimingData>&& aData) { + AddRawEntry(std::move(aData), initiatorType, entryName); +} + void PerformanceMainThread::AddRawEntry(UniquePtr<PerformanceTimingData> aData, const nsAString& aInitiatorType, const nsAString& aEntryName) { // The PerformanceResourceTiming object will use the PerformanceTimingData // object to get all the required timings. auto entry = MakeRefPtr<PerformanceResourceTiming>(std::move(aData), this, aEntryName); entry->SetInitiatorType(aInitiatorType);
--- a/dom/performance/PerformanceMainThread.h +++ b/dom/performance/PerformanceMainThread.h @@ -29,16 +29,19 @@ class PerformanceMainThread final : publ PerformanceStorage* AsPerformanceStorage() override { return this; } virtual PerformanceTiming* Timing() override; virtual PerformanceNavigation* Navigation() override; virtual void AddEntry(nsIHttpChannel* channel, nsITimedChannel* timedChannel) override; + virtual void AddEntry(const nsString& entryName, + const nsString& initiatorType, + UniquePtr<PerformanceTimingData>&& aData) override; void AddRawEntry(UniquePtr<PerformanceTimingData>, const nsAString& aInitiatorType, const nsAString& aEntryName); virtual void SetFCPTimingEntry(PerformancePaintTiming* aEntry) override; TimeStamp CreationTimeStamp() const override;
--- a/dom/performance/PerformanceStorage.h +++ b/dom/performance/PerformanceStorage.h @@ -18,16 +18,19 @@ namespace dom { class PerformanceTimingData; class PerformanceStorage { public: NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING virtual void AddEntry(nsIHttpChannel* aChannel, nsITimedChannel* aTimedChannel) = 0; + virtual void AddEntry(const nsString& entryName, + const nsString& initiatorType, + UniquePtr<PerformanceTimingData>&& aData) = 0; protected: virtual ~PerformanceStorage() = default; }; } // namespace dom } // namespace mozilla
--- a/dom/performance/PerformanceStorageWorker.h +++ b/dom/performance/PerformanceStorageWorker.h @@ -24,17 +24,19 @@ class PerformanceStorageWorker final : p static already_AddRefed<PerformanceStorageWorker> Create( WorkerPrivate* aWorkerPrivate); void ShutdownOnWorker(); void AddEntry(nsIHttpChannel* aChannel, nsITimedChannel* aTimedChannel) override; - + virtual void AddEntry(const nsString& entryName, + const nsString& initiatorType, + UniquePtr<PerformanceTimingData>&& aData) override {} void AddEntryOnWorker(UniquePtr<PerformanceProxyData>&& aData); private: PerformanceStorageWorker(); ~PerformanceStorageWorker(); Mutex mMutex;
--- a/dom/performance/PerformanceTiming.h +++ b/dom/performance/PerformanceTiming.h @@ -11,28 +11,34 @@ #include "mozilla/BasePrincipal.h" #include "mozilla/StaticPrefs_dom.h" #include "nsContentUtils.h" #include "nsDOMNavigationTiming.h" #include "nsRFPService.h" #include "nsWrapperCache.h" #include "Performance.h" #include "nsITimedChannel.h" +#include "mozilla/ipc/IPDLParamTraits.h" +#include "ipc/IPCMessageUtils.h" +#include "mozilla/net/nsServerTiming.h" class nsIHttpChannel; namespace mozilla { namespace dom { class PerformanceTiming; class PerformanceTimingData final { friend class PerformanceTiming; + friend struct mozilla::ipc::IPDLParamTraits< + mozilla::dom::PerformanceTimingData>; public: + PerformanceTimingData() = default; // For deserialization // This can return null. static PerformanceTimingData* Create(nsITimedChannel* aChannel, nsIHttpChannel* aHttpChannel, DOMHighResTimeStamp aZeroTime, nsAString& aInitiatorType, nsAString& aEntryName); PerformanceTimingData(nsITimedChannel* aChannel, nsIHttpChannel* aHttpChannel, @@ -176,38 +182,38 @@ class PerformanceTimingData final { TimeStamp mWorkerStart; TimeStamp mWorkerRequestStart; TimeStamp mWorkerResponseEnd; // This is an offset that will be added to each timing ([ms] resolution). // There are only 2 possible values: (1) logicaly equal to navigationStart // TimeStamp (results are absolute timstamps - wallclock); (2) "0" (results // are relative to the navigation start). - DOMHighResTimeStamp mZeroTime; + DOMHighResTimeStamp mZeroTime = 0; - DOMHighResTimeStamp mFetchStart; + DOMHighResTimeStamp mFetchStart = 0; - uint64_t mEncodedBodySize; - uint64_t mTransferSize; - uint64_t mDecodedBodySize; + uint64_t mEncodedBodySize = 0; + uint64_t mTransferSize = 0; + uint64_t mDecodedBodySize = 0; - uint8_t mRedirectCount; + uint8_t mRedirectCount = 0; - bool mAllRedirectsSameOrigin; + bool mAllRedirectsSameOrigin = false; // If the resourceTiming object should have non-zero redirectStart and // redirectEnd attributes. It is false if there were no redirects, or if any // of the responses didn't pass the timing-allow-check - bool mReportCrossOriginRedirect; + bool mReportCrossOriginRedirect = false; - bool mSecureConnection; + bool mSecureConnection = false; - bool mTimingAllowed; + bool mTimingAllowed = false; - bool mInitialized; + bool mInitialized = false; }; // Script "performance.timing" object class PerformanceTiming final : public nsWrapperCache { public: /** * @param aPerformance * The performance object (the JS parent). @@ -403,9 +409,186 @@ class PerformanceTiming final : public n RefPtr<Performance> mPerformance; UniquePtr<PerformanceTimingData> mTimingData; }; } // namespace dom } // namespace mozilla +namespace mozilla { +namespace ipc { + +template <> +struct IPDLParamTraits<mozilla::dom::PerformanceTimingData> { + typedef mozilla::dom::PerformanceTimingData paramType; + static void Write(IPC::Message* aMsg, IProtocol* aActor, + const paramType& aParam) { + WriteIPDLParam(aMsg, aActor, aParam.mServerTiming); + WriteIPDLParam(aMsg, aActor, aParam.mNextHopProtocol); + WriteIPDLParam(aMsg, aActor, aParam.mAsyncOpen); + WriteIPDLParam(aMsg, aActor, aParam.mRedirectStart); + WriteIPDLParam(aMsg, aActor, aParam.mRedirectEnd); + WriteIPDLParam(aMsg, aActor, aParam.mDomainLookupStart); + WriteIPDLParam(aMsg, aActor, aParam.mDomainLookupEnd); + WriteIPDLParam(aMsg, aActor, aParam.mConnectStart); + WriteIPDLParam(aMsg, aActor, aParam.mSecureConnectionStart); + WriteIPDLParam(aMsg, aActor, aParam.mConnectEnd); + WriteIPDLParam(aMsg, aActor, aParam.mRequestStart); + WriteIPDLParam(aMsg, aActor, aParam.mResponseStart); + WriteIPDLParam(aMsg, aActor, aParam.mCacheReadStart); + WriteIPDLParam(aMsg, aActor, aParam.mResponseEnd); + WriteIPDLParam(aMsg, aActor, aParam.mCacheReadEnd); + WriteIPDLParam(aMsg, aActor, aParam.mWorkerStart); + WriteIPDLParam(aMsg, aActor, aParam.mWorkerRequestStart); + WriteIPDLParam(aMsg, aActor, aParam.mWorkerResponseEnd); + WriteIPDLParam(aMsg, aActor, aParam.mZeroTime); + WriteIPDLParam(aMsg, aActor, aParam.mFetchStart); + WriteIPDLParam(aMsg, aActor, aParam.mEncodedBodySize); + WriteIPDLParam(aMsg, aActor, aParam.mTransferSize); + WriteIPDLParam(aMsg, aActor, aParam.mDecodedBodySize); + WriteIPDLParam(aMsg, aActor, aParam.mRedirectCount); + WriteIPDLParam(aMsg, aActor, aParam.mAllRedirectsSameOrigin); + WriteIPDLParam(aMsg, aActor, aParam.mReportCrossOriginRedirect); + WriteIPDLParam(aMsg, aActor, aParam.mSecureConnection); + WriteIPDLParam(aMsg, aActor, aParam.mTimingAllowed); + WriteIPDLParam(aMsg, aActor, aParam.mInitialized); + } + + static bool Read(const IPC::Message* aMsg, PickleIterator* aIter, + IProtocol* aActor, paramType* aResult) { + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mServerTiming)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mNextHopProtocol)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mAsyncOpen)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRedirectStart)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRedirectEnd)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDomainLookupStart)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDomainLookupEnd)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mConnectStart)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSecureConnectionStart)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mConnectEnd)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRequestStart)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mResponseStart)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mCacheReadStart)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mResponseEnd)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mCacheReadEnd)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mWorkerStart)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mWorkerRequestStart)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mWorkerResponseEnd)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mZeroTime)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mFetchStart)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mEncodedBodySize)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mTransferSize)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDecodedBodySize)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRedirectCount)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, + &aResult->mAllRedirectsSameOrigin)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, + &aResult->mReportCrossOriginRedirect)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSecureConnection)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mTimingAllowed)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mInitialized)) { + return false; + } + return true; + } +}; + +template <> +struct IPDLParamTraits<nsCOMPtr<nsIServerTiming>> { + typedef nsCOMPtr<nsIServerTiming> paramType; + static void Write(IPC::Message* aMsg, IProtocol* aActor, + const paramType& aParam) { + nsAutoCString name; + Unused << aParam->GetName(name); + double duration = 0; + Unused << aParam->GetDuration(&duration); + nsAutoCString description; + Unused << aParam->GetDescription(description); + WriteIPDLParam(aMsg, aActor, name); + WriteIPDLParam(aMsg, aActor, duration); + WriteIPDLParam(aMsg, aActor, description); + } + + static bool Read(const IPC::Message* aMsg, PickleIterator* aIter, + IProtocol* aActor, paramType* aResult) { + nsAutoCString name; + double duration; + nsAutoCString description; + if (!ReadIPDLParam(aMsg, aIter, aActor, &name)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &duration)) { + return false; + } + if (!ReadIPDLParam(aMsg, aIter, aActor, &description)) { + return false; + } + + RefPtr<nsServerTiming> timing = new nsServerTiming(); + timing->SetName(name); + timing->SetDuration(duration); + timing->SetDescription(description); + *aResult = timing; + return true; + } +}; + +} // namespace ipc +} // namespace mozilla + #endif // mozilla_dom_PerformanceTiming_h
--- a/dom/tests/mochitest/general/mochitest.ini +++ b/dom/tests/mochitest/general/mochitest.ini @@ -114,17 +114,16 @@ skip-if = verify [test_picture_apng.html] [test_picture_mutations.html] [test_pointerPreserves3D.html] [test_pointerPreserves3DClip.html] [test_pointerPreserves3DPerspective.html] [test_resource_timing.html] skip-if = verify [test_resource_timing_cross_origin.html] -skip-if = fission # bug 1658097 [test_resource_timing_frameset.html] [test_selectevents.html] skip-if = toolkit == 'android' # bug 1627523 [test_showModalDialog_removed.html] [test_storagePermissionsAccept.html] [test_storagePermissionsLimitForeign.html] [test_storagePermissionsReject.html] [test_storagePermissionsRejectForeign.html]
--- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -83,16 +83,17 @@ #include "nsServerTiming.h" #include "nsStreamListenerWrapper.h" #include "nsStreamUtils.h" #include "nsThreadUtils.h" #include "nsURLHelper.h" #include "mozilla/RemoteLazyInputStreamChild.h" #include "mozilla/RemoteLazyInputStreamUtils.h" #include "mozilla/net/SFVService.h" +#include "mozilla/dom/ContentChild.h" namespace mozilla { namespace net { static bool IsHeaderBlacklistedForRedirectCopy(nsHttpAtom const& aHeader) { // IMPORTANT: keep this list ASCII-code sorted static nsHttpAtom const* blackList[] = {&nsHttp::Accept, &nsHttp::Accept_Encoding, @@ -4826,20 +4827,47 @@ mozilla::dom::PerformanceStorage* HttpBa // performance. if (XRE_IsE10sParentProcess()) { return nullptr; } return mLoadInfo->GetPerformanceStorage(); } void HttpBaseChannel::MaybeReportTimingData() { + if (XRE_IsE10sParentProcess()) { + return; + } + mozilla::dom::PerformanceStorage* documentPerformance = GetPerformanceStorage(); if (documentPerformance) { documentPerformance->AddEntry(this, this); + return; + } + + if (!nsGlobalWindowInner::GetInnerWindowWithId( + mLoadInfo->GetInnerWindowID())) { + // The inner window is in a different process. + dom::ContentChild* child = dom::ContentChild::GetSingleton(); + + if (!child) { + return; + } + nsAutoString initiatorType; + nsAutoString entryName; + + UniquePtr<dom::PerformanceTimingData> performanceTimingData( + dom::PerformanceTimingData::Create(this, this, 0, initiatorType, + entryName)); + if (!performanceTimingData) { + return; + } + child->SendReportFrameTimingData(mLoadInfo->GetInnerWindowID(), entryName, + initiatorType, + std::move(performanceTimingData)); } } NS_IMETHODIMP HttpBaseChannel::SetReportResourceTiming(bool enabled) { mReportTiming = enabled; return NS_OK; }