Bug 1278838 - Remove separate worker binding for Performance API, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 09 Jun 2016 19:04:42 +0200
changeset 301327 6b1139b4cbf5cd0574e548da0b5ae4dec5b7e367
parent 301326 74de882e1ddbeece3183a3569e89b90f811f261c
child 301328 cc09ba8c5e5fef04b164c281ddc3485609f91c7b
push id78292
push useramarchesini@mozilla.com
push dateThu, 09 Jun 2016 17:05:36 +0000
treeherdermozilla-inbound@cc09ba8c5e5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1278838
milestone50.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
Bug 1278838 - Remove separate worker binding for Performance API, r=smaug
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsPIDOMWindow.h
dom/bindings/Bindings.conf
dom/console/Console.cpp
dom/events/Event.cpp
dom/gamepad/Gamepad.cpp
dom/gamepad/Gamepad.h
dom/html/HTMLVideoElement.cpp
dom/performance/Performance.cpp
dom/performance/Performance.h
dom/performance/PerformanceMainThread.cpp
dom/performance/PerformanceMainThread.h
dom/performance/PerformanceNavigation.cpp
dom/performance/PerformanceNavigation.h
dom/performance/PerformanceObserver.cpp
dom/performance/PerformanceObserver.h
dom/performance/PerformanceObserverEntryList.cpp
dom/performance/PerformanceResourceTiming.cpp
dom/performance/PerformanceResourceTiming.h
dom/performance/PerformanceTiming.cpp
dom/performance/PerformanceTiming.h
dom/performance/PerformanceWorker.cpp
dom/performance/PerformanceWorker.h
dom/performance/moz.build
dom/performance/nsPerformance.cpp
dom/performance/nsPerformance.h
dom/webidl/Performance.webidl
dom/webidl/PerformanceObserver.webidl
dom/webidl/PerformanceObserverEntryList.webidl
dom/workers/Performance.cpp
dom/workers/Performance.h
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerScope.cpp
dom/workers/WorkerScope.h
dom/workers/moz.build
layout/base/nsPresShell.cpp
layout/base/nsRefreshDriver.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpTransaction.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -10,20 +10,20 @@
 
 #include "mozilla/MemoryReporting.h"
 
 // Local Includes
 #include "Navigator.h"
 #include "nsContentSecurityManager.h"
 #include "nsScreen.h"
 #include "nsHistory.h"
-#include "nsPerformance.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsIDOMStorageManager.h"
 #include "mozilla/dom/DOMStorage.h"
+#include "mozilla/dom/Performance.h"
 #include "mozilla/dom/StorageEvent.h"
 #include "mozilla/dom/StorageEventBinding.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
 #include "mozilla/dom/WindowOrientationObserver.h"
 #endif
 #include "nsDOMOfflineResourceList.h"
 #include "nsError.h"
@@ -2806,20 +2806,20 @@ nsGlobalWindow::SetNewDocument(nsIDocume
         }
 
         // Make a copy of the old window's performance object on document.open.
         // Note that we have to force eager creation of it here, because we need
         // to grab the current document channel and whatnot before that changes.
         currentInner->AsInner()->CreatePerformanceObjectIfNeeded();
         if (currentInner->mPerformance) {
           newInnerWindow->mPerformance =
-            new nsPerformance(newInnerWindow->AsInner(),
-                              currentInner->mPerformance->GetDOMTiming(),
-                              currentInner->mPerformance->GetChannel(),
-                              currentInner->mPerformance->GetParentPerformance());
+            Performance::CreateForMainThread(newInnerWindow->AsInner(),
+                                             currentInner->mPerformance->GetDOMTiming(),
+                                             currentInner->mPerformance->GetChannel(),
+                                             currentInner->mPerformance->GetParentPerformance());
         }
       }
 
       // Don't free objects on our current inner window if it's going to be
       // held in the bfcache.
       if (!currentInner->IsFrozen()) {
         currentInner->FreeInnerObjects();
       }
@@ -3827,25 +3827,25 @@ nsGlobalWindow::GetHistory(ErrorResult& 
 
   if (!mHistory) {
     mHistory = new nsHistory(AsInner());
   }
 
   return mHistory;
 }
 
-nsPerformance*
+Performance*
 nsPIDOMWindowInner::GetPerformance()
 {
   MOZ_ASSERT(IsInnerWindow());
   CreatePerformanceObjectIfNeeded();
   return mPerformance;
 }
 
-nsPerformance*
+Performance*
 nsGlobalWindow::GetPerformance()
 {
   return AsInner()->GetPerformance();
 }
 
 void
 nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded()
 {
@@ -3860,29 +3860,30 @@ nsPIDOMWindowInner::CreatePerformanceObj
   if (!timedChannel ||
       !NS_SUCCEEDED(timedChannel->GetTimingEnabled(&timingEnabled)) ||
       !timingEnabled) {
     timedChannel = nullptr;
   }
   if (timing) {
     // If we are dealing with an iframe, we will need the parent's performance
     // object (so we can add the iframe as a resource of that page).
-    nsPerformance* parentPerformance = nullptr;
+    Performance* parentPerformance = nullptr;
     nsCOMPtr<nsPIDOMWindowOuter> parentWindow = GetScriptableParentOrNull();
     if (parentWindow) {
       nsPIDOMWindowInner* parentInnerWindow = nullptr;
       if (parentWindow) {
         parentInnerWindow = parentWindow->GetCurrentInnerWindow();
       }
       if (parentInnerWindow) {
         parentPerformance = parentInnerWindow->GetPerformance();
       }
     }
     mPerformance =
-      new nsPerformance(this, timing, timedChannel, parentPerformance);
+      Performance::CreateForMainThread(this, timing, timedChannel,
+                                       parentPerformance);
   }
 }
 
 SuspendTypes
 nsPIDOMWindowOuter::GetMediaSuspend() const
 {
   if (IsInnerWindow()) {
     return mOuterWindow->GetMediaSuspend();
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -1252,17 +1252,18 @@ public:
                       mozilla::ErrorResult& aError);
 
   void GetInterface(JSContext* aCx, nsIJSID* aIID,
                     JS::MutableHandle<JS::Value> aRetval,
                     mozilla::ErrorResult& aError);
 
   already_AddRefed<nsWindowRoot> GetWindowRootOuter();
   already_AddRefed<nsWindowRoot> GetWindowRoot(mozilla::ErrorResult& aError);
-  nsPerformance* GetPerformance();
+
+  mozilla::dom::Performance* GetPerformance();
 
 protected:
   // Web IDL helpers
 
   // Redefine the property called aPropName on this window object to be a value
   // property with the value aValue, much like we would do for a [Replaceable]
   // property in IDL.
   void RedefineProperty(JSContext* aCx, const char* aPropName,
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -26,29 +26,29 @@ class nsGlobalWindow;
 class nsIArray;
 class nsIContent;
 class nsICSSDeclaration;
 class nsIDocShell;
 class nsIDocument;
 class nsIIdleObserver;
 class nsIScriptTimeoutHandler;
 class nsIURI;
-class nsPerformance;
 class nsPIDOMWindowInner;
 class nsPIDOMWindowOuter;
 class nsPIWindowRoot;
 class nsXBLPrototypeHandler;
 struct nsTimeout;
 
 typedef uint32_t SuspendTypes;
 
 namespace mozilla {
 namespace dom {
 class AudioContext;
 class Element;
+class Performance;
 class ServiceWorkerRegistrationMainThread;
 } // namespace dom
 namespace gfx {
 class VRDeviceProxy;
 } // namespace gfx
 } // namespace mozilla
 
 // Popup control state enum. The values in this enum must go from most
@@ -606,17 +606,17 @@ protected:
   // These members are only used on outer windows.
   nsCOMPtr<mozilla::dom::Element> mFrameElement;
   // This reference is used by the subclass nsGlobalWindow, and cleared in it's
   // DetachFromDocShell() method. This method is called by nsDocShell::Destroy(),
   // which is called before the nsDocShell is destroyed.
   nsIDocShell* MOZ_NON_OWNING_REF mDocShell;  // Weak Reference
 
   // mPerformance is only used on inner windows.
-  RefPtr<nsPerformance>       mPerformance;
+  RefPtr<mozilla::dom::Performance> mPerformance;
 
   typedef nsRefPtrHashtable<nsStringHashKey,
                             mozilla::dom::ServiceWorkerRegistrationMainThread>
           ServiceWorkerRegistrationTable;
   ServiceWorkerRegistrationTable mServiceWorkerRegistrationTable;
 
   uint32_t               mModalStateDepth;
 
@@ -736,17 +736,17 @@ public:
 
   bool GetAudioCaptured() const;
   nsresult SetAudioCapture(bool aCapture);
 
   already_AddRefed<mozilla::dom::ServiceWorkerRegistrationMainThread>
     GetServiceWorkerRegistration(const nsAString& aScope);
   void InvalidateServiceWorkerRegistration(const nsAString& aScope);
 
-  nsPerformance* GetPerformance();
+  mozilla::dom::Performance* GetPerformance();
 
   bool HasMutationListeners(uint32_t aMutationEventType) const
   {
     if (!mOuterWindow) {
       NS_ERROR("HasMutationListeners() called on orphan inner window!");
 
       return false;
     }
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -880,25 +880,16 @@ DOMInterfaces = {
 },
 
 'PeerConnectionImpl': {
     'nativeType': 'mozilla::PeerConnectionImpl',
     'headerFile': 'PeerConnectionImpl.h',
     'wrapperCache': False
 },
 
-'Performance': [{
-    'nativeType': 'nsPerformance',
-},
-{
-    'nativeType': 'mozilla::dom::workers::Performance',
-    'headerFile': 'mozilla/dom/workers/bindings/Performance.h',
-    'workers': True,
-}],
-
 'Plugin': {
     'headerFile' : 'nsPluginArray.h',
     'nativeType': 'nsPluginElement',
 },
 
 'PluginArray': {
     'nativeType': 'nsPluginArray',
 },
--- a/dom/console/Console.cpp
+++ b/dom/console/Console.cpp
@@ -6,26 +6,26 @@
 
 #include "mozilla/dom/Console.h"
 #include "mozilla/dom/ConsoleBinding.h"
 
 #include "mozilla/dom/BlobBinding.h"
 #include "mozilla/dom/Exceptions.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/FunctionBinding.h"
+#include "mozilla/dom/Performance.h"
 #include "mozilla/dom/StructuredCloneHolder.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/Maybe.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDocument.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsGlobalWindow.h"
 #include "nsJSUtils.h"
 #include "nsNetUtil.h"
-#include "nsPerformance.h"
 #include "ScriptSettings.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 #include "WorkerScope.h"
 #include "xpcprivate.h"
 #include "nsContentUtils.h"
 #include "nsDocShell.h"
 #include "nsProxyRelease.h"
@@ -1350,17 +1350,17 @@ Console::MethodInternal(JSContext* aCx, 
   // Monotonic timer for 'time' and 'timeEnd'
   if (aMethodName == MethodTime ||
       aMethodName == MethodTimeEnd ||
       aMethodName == MethodTimeStamp) {
     if (mWindow) {
       nsGlobalWindow *win = nsGlobalWindow::Cast(mWindow);
       MOZ_ASSERT(win);
 
-      RefPtr<nsPerformance> performance = win->GetPerformance();
+      RefPtr<Performance> performance = win->GetPerformance();
       if (!performance) {
         return;
       }
 
       monotonicTimer = performance->Now();
 
       nsDocShell* docShell = static_cast<nsDocShell*>(mWindow->GetDocShell());
       RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -8,16 +8,17 @@
 #include "base/basictypes.h"
 #include "ipc/IPCMessageUtils.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/InternalMutationEvent.h"
+#include "mozilla/dom/Performance.h"
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
 #include "nsContentUtils.h"
 #include "nsCOMPtr.h"
 #include "nsDeviceContext.h"
@@ -25,17 +26,16 @@
 #include "nsGlobalWindow.h"
 #include "nsIFrame.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIPresShell.h"
 #include "nsIScrollableFrame.h"
 #include "nsJSEnvironment.h"
 #include "nsLayoutUtils.h"
-#include "nsPerformance.h"
 #include "nsPIWindowRoot.h"
 #include "WorkerPrivate.h"
 
 namespace mozilla {
 namespace dom {
 
 namespace workers {
 extern bool IsCurrentThreadRunningChromeWorker();
@@ -1091,17 +1091,18 @@ Event::TimeStamp() const
     if (NS_WARN_IF(!mOwner)) {
       return 0.0;
     }
 
     nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(mOwner);
     if (NS_WARN_IF(!win)) {
       return 0.0;
     }
-    nsPerformance* perf = win->GetPerformance();
+
+    Performance* perf = win->GetPerformance();
     if (NS_WARN_IF(!perf)) {
       return 0.0;
     }
 
     return perf->GetDOMTiming()->TimeStampToDOMHighRes(mEvent->mTimeStamp);
   }
 
   // For dedicated workers, we should make times relative to the navigation
--- a/dom/gamepad/Gamepad.cpp
+++ b/dom/gamepad/Gamepad.cpp
@@ -24,17 +24,17 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Gamepad, mParent, mButtons)
 
 void
 Gamepad::UpdateTimestamp()
 {
   nsCOMPtr<nsPIDOMWindowInner> newWindow(do_QueryInterface(mParent));
   if(newWindow) {
-    nsPerformance* perf = newWindow->GetPerformance();
+    Performance* perf = newWindow->GetPerformance();
     if (perf) {
       mTimestamp =  perf->Now();
     }
   }
 }
 
 Gamepad::Gamepad(nsISupports* aParent,
                  const nsAString& aID, uint32_t aIndex,
--- a/dom/gamepad/Gamepad.h
+++ b/dom/gamepad/Gamepad.h
@@ -5,22 +5,22 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_gamepad_Gamepad_h
 #define mozilla_dom_gamepad_Gamepad_h
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/GamepadBinding.h"
 #include "mozilla/dom/GamepadButton.h"
+#include "mozilla/dom/Performance.h"
 #include <stdint.h>
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsWrapperCache.h"
-#include "nsPerformance.h"
 
 namespace mozilla {
 namespace dom {
 
 // Per spec:
 // https://dvcs.w3.org/hg/gamepad/raw-file/default/gamepad.html#remapping
 const int kStandardGamepadButtons = 17;
 const int kStandardGamepadAxes = 4;
--- a/dom/html/HTMLVideoElement.cpp
+++ b/dom/html/HTMLVideoElement.cpp
@@ -23,17 +23,17 @@
 
 #include "nsITimer.h"
 
 #include "MediaError.h"
 #include "MediaDecoder.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/WakeLock.h"
 #include "mozilla/dom/power/PowerManagerService.h"
-#include "nsPerformance.h"
+#include "mozilla/dom/Performance.h"
 #include "mozilla/dom/VideoPlaybackQuality.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Video)
 
 namespace mozilla {
 namespace dom {
 
 static bool sVideoStatsEnabled;
@@ -230,17 +230,17 @@ HTMLVideoElement::GetVideoPlaybackQualit
 {
   DOMHighResTimeStamp creationTime = 0;
   uint64_t totalFrames = 0;
   uint64_t droppedFrames = 0;
   uint64_t corruptedFrames = 0;
 
   if (sVideoStatsEnabled) {
     if (nsPIDOMWindowInner* window = OwnerDoc()->GetInnerWindow()) {
-      nsPerformance* perf = window->GetPerformance();
+      Performance* perf = window->GetPerformance();
       if (perf) {
         creationTime = perf->Now();
       }
     }
 
     if (mDecoder) {
       FrameStatistics& stats = mDecoder->GetFrameStatistics();
       totalFrames = stats.GetParsedFrames();
rename from dom/performance/nsPerformance.cpp
rename to dom/performance/Performance.cpp
--- a/dom/performance/nsPerformance.cpp
+++ b/dom/performance/Performance.cpp
@@ -1,327 +1,44 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsPerformance.h"
-#include "nsCOMPtr.h"
-#include "nsIHttpChannel.h"
-#include "nsITimedChannel.h"
-#include "nsDOMNavigationTiming.h"
-#include "nsContentUtils.h"
-#include "nsIScriptSecurityManager.h"
-#include "nsIDOMWindow.h"
-#include "nsILoadInfo.h"
-#include "nsIURI.h"
-#include "nsThreadUtils.h"
+#include "Performance.h"
+
+#include "GeckoProfiler.h"
 #include "PerformanceEntry.h"
+#include "PerformanceMainThread.h"
 #include "PerformanceMark.h"
 #include "PerformanceMeasure.h"
 #include "PerformanceObserver.h"
 #include "PerformanceResourceTiming.h"
+#include "PerformanceWorker.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/PerformanceBinding.h"
 #include "mozilla/dom/PerformanceEntryEvent.h"
 #include "mozilla/dom/PerformanceNavigationBinding.h"
 #include "mozilla/dom/PerformanceObserverBinding.h"
+#include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Preferences.h"
-#include "mozilla/IntegerPrintfMacros.h"
-#include "mozilla/TimeStamp.h"
-#include "js/HeapAPI.h"
-#include "GeckoProfiler.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 
 #ifdef MOZ_WIDGET_GONK
 #define PERFLOG(msg, ...)  __android_log_print(ANDROID_LOG_INFO, "PerformanceTiming", msg, ##__VA_ARGS__)
 #else
 #define PERFLOG(msg, ...) printf_stderr(msg, ##__VA_ARGS__)
 #endif
 
-using namespace mozilla;
-using namespace mozilla::dom;
-using namespace mozilla::dom::workers;
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsPerformance)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsPerformance, PerformanceBase)
-NS_IMPL_CYCLE_COLLECTION_UNLINK(mTiming,
-                                mNavigation,
-                                mParentPerformance)
-  tmp->mMozMemory = nullptr;
-  mozilla::DropJSObjects(this);
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsPerformance, PerformanceBase)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTiming,
-                                    mNavigation,
-                                    mParentPerformance)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsPerformance, PerformanceBase)
-  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mMozMemory)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_ADDREF_INHERITED(nsPerformance, PerformanceBase)
-NS_IMPL_RELEASE_INHERITED(nsPerformance, PerformanceBase)
-
-nsPerformance::nsPerformance(nsPIDOMWindowInner* aWindow,
-                             nsDOMNavigationTiming* aDOMTiming,
-                             nsITimedChannel* aChannel,
-                             nsPerformance* aParentPerformance)
-  : PerformanceBase(aWindow),
-    mDOMTiming(aDOMTiming),
-    mChannel(aChannel),
-    mParentPerformance(aParentPerformance)
-{
-  MOZ_ASSERT(aWindow, "Parent window object should be provided");
-}
-
-nsPerformance::~nsPerformance()
-{
-  mozilla::DropJSObjects(this);
-}
-
-// QueryInterface implementation for nsPerformance
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPerformance)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
-
-void
-nsPerformance::GetMozMemory(JSContext *aCx, JS::MutableHandle<JSObject*> aObj)
-{
-  if (!mMozMemory) {
-    mMozMemory = js::gc::NewMemoryInfoObject(aCx);
-    if (mMozMemory) {
-      mozilla::HoldJSObjects(this);
-    }
-  }
-
-  aObj.set(mMozMemory);
-}
-
-PerformanceTiming*
-nsPerformance::Timing()
-{
-  if (!mTiming) {
-    // For navigation timing, the third argument (an nsIHtttpChannel) is null
-    // since the cross-domain redirect were already checked.
-    // The last argument (zero time) for performance.timing is the navigation
-    // start value.
-    mTiming = new PerformanceTiming(this, mChannel, nullptr,
-        mDOMTiming->GetNavigationStart());
-  }
-  return mTiming;
-}
-
-void
-nsPerformance::DispatchBufferFullEvent()
-{
-  RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
-  // it bubbles, and it isn't cancelable
-  event->InitEvent(NS_LITERAL_STRING("resourcetimingbufferfull"), true, false);
-  event->SetTrusted(true);
-  DispatchDOMEvent(nullptr, event, nullptr, nullptr);
-}
-
-PerformanceNavigation*
-nsPerformance::Navigation()
-{
-  if (!mNavigation) {
-    mNavigation = new PerformanceNavigation(this);
-  }
-  return mNavigation;
-}
-
-DOMHighResTimeStamp
-nsPerformance::Now() const
-{
-  return RoundTime(GetDOMTiming()->TimeStampToDOMHighRes(TimeStamp::Now()));
-}
-
-JSObject*
-nsPerformance::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
-{
-  return PerformanceBinding::Wrap(cx, this, aGivenProto);
-}
-
-/**
- * An entry should be added only after the resource is loaded.
- * This method is not thread safe and can only be called on the main thread.
- */
-void
-nsPerformance::AddEntry(nsIHttpChannel* channel,
-                        nsITimedChannel* timedChannel)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  // Check if resource timing is prefed off.
-  if (!nsContentUtils::IsResourceTimingEnabled()) {
-    return;
-  }
-
-  // Don't add the entry if the buffer is full
-  if (IsResourceEntryLimitReached()) {
-    return;
-  }
-
-  if (channel && timedChannel) {
-    nsAutoCString name;
-    nsAutoString initiatorType;
-    nsCOMPtr<nsIURI> originalURI;
-
-    timedChannel->GetInitiatorType(initiatorType);
+namespace mozilla {
+namespace dom {
 
-    // According to the spec, "The name attribute must return the resolved URL
-    // of the requested resource. This attribute must not change even if the
-    // fetch redirected to a different URL."
-    channel->GetOriginalURI(getter_AddRefs(originalURI));
-    originalURI->GetSpec(name);
-    NS_ConvertUTF8toUTF16 entryName(name);
-
-    // The nsITimedChannel argument will be used to gather all the timings.
-    // The nsIHttpChannel argument will be used to check if any cross-origin
-    // redirects occurred.
-    // The last argument is the "zero time" (offset). Since we don't want
-    // any offset for the resource timing, this will be set to "0" - the
-    // resource timing returns a relative timing (no offset).
-    RefPtr<PerformanceTiming> performanceTiming =
-        new PerformanceTiming(this, timedChannel, channel,
-            0);
-
-    // The PerformanceResourceTiming object will use the PerformanceTiming
-    // object to get all the required timings.
-    RefPtr<PerformanceResourceTiming> performanceEntry =
-      new PerformanceResourceTiming(performanceTiming, this, entryName);
-
-    nsAutoCString protocol;
-    channel->GetProtocolVersion(protocol);
-    performanceEntry->SetNextHopProtocol(NS_ConvertUTF8toUTF16(protocol));
-
-    uint64_t encodedBodySize = 0;
-    channel->GetEncodedBodySize(&encodedBodySize);
-    performanceEntry->SetEncodedBodySize(encodedBodySize);
-
-    uint64_t transferSize = 0;
-    channel->GetTransferSize(&transferSize);
-    performanceEntry->SetTransferSize(transferSize);
-
-    uint64_t decodedBodySize = 0;
-    channel->GetDecodedBodySize(&decodedBodySize);
-    if (decodedBodySize == 0) {
-      decodedBodySize = encodedBodySize;
-    }
-    performanceEntry->SetDecodedBodySize(decodedBodySize);
-
-    // If the initiator type had no valid value, then set it to the default
-    // ("other") value.
-    if (initiatorType.IsEmpty()) {
-      initiatorType = NS_LITERAL_STRING("other");
-    }
-    performanceEntry->SetInitiatorType(initiatorType);
-    InsertResourceEntry(performanceEntry);
-  }
-}
-
-// To be removed once bug 1124165 lands
-bool
-nsPerformance::IsPerformanceTimingAttribute(const nsAString& aName)
-{
-  // Note that toJSON is added to this list due to bug 1047848
-  static const char* attributes[] =
-    {"navigationStart", "unloadEventStart", "unloadEventEnd", "redirectStart",
-     "redirectEnd", "fetchStart", "domainLookupStart", "domainLookupEnd",
-     "connectStart", "connectEnd", "requestStart", "responseStart",
-     "responseEnd", "domLoading", "domInteractive", "domContentLoadedEventStart",
-     "domContentLoadedEventEnd", "domComplete", "loadEventStart",
-     "loadEventEnd", nullptr};
-
-  for (uint32_t i = 0; attributes[i]; ++i) {
-    if (aName.EqualsASCII(attributes[i])) {
-      return true;
-    }
-  }
-  return false;
-}
-
-DOMHighResTimeStamp
-nsPerformance::GetPerformanceTimingFromString(const nsAString& aProperty)
-{
-  if (!IsPerformanceTimingAttribute(aProperty)) {
-    return 0;
-  }
-  if (aProperty.EqualsLiteral("navigationStart")) {
-    // DOMHighResTimeStamp is in relation to navigationStart, so this will be
-    // zero.
-    return GetDOMTiming()->GetNavigationStart();
-  }
-  if (aProperty.EqualsLiteral("unloadEventStart")) {
-    return GetDOMTiming()->GetUnloadEventStart();
-  }
-  if (aProperty.EqualsLiteral("unloadEventEnd")) {
-    return GetDOMTiming()->GetUnloadEventEnd();
-  }
-  if (aProperty.EqualsLiteral("redirectStart")) {
-    return Timing()->RedirectStart();
-  }
-  if (aProperty.EqualsLiteral("redirectEnd")) {
-    return Timing()->RedirectEnd();
-  }
-  if (aProperty.EqualsLiteral("fetchStart")) {
-    return Timing()->FetchStart();
-  }
-  if (aProperty.EqualsLiteral("domainLookupStart")) {
-    return Timing()->DomainLookupStart();
-  }
-  if (aProperty.EqualsLiteral("domainLookupEnd")) {
-    return Timing()->DomainLookupEnd();
-  }
-  if (aProperty.EqualsLiteral("connectStart")) {
-    return Timing()->ConnectStart();
-  }
-  if (aProperty.EqualsLiteral("connectEnd")) {
-    return Timing()->ConnectEnd();
-  }
-  if (aProperty.EqualsLiteral("requestStart")) {
-    return Timing()->RequestStart();
-  }
-  if (aProperty.EqualsLiteral("responseStart")) {
-    return Timing()->ResponseStart();
-  }
-  if (aProperty.EqualsLiteral("responseEnd")) {
-    return Timing()->ResponseEnd();
-  }
-  if (aProperty.EqualsLiteral("domLoading")) {
-    return GetDOMTiming()->GetDomLoading();
-  }
-  if (aProperty.EqualsLiteral("domInteractive")) {
-    return GetDOMTiming()->GetDomInteractive();
-  }
-  if (aProperty.EqualsLiteral("domContentLoadedEventStart")) {
-    return GetDOMTiming()->GetDomContentLoadedEventStart();
-  }
-  if (aProperty.EqualsLiteral("domContentLoadedEventEnd")) {
-    return GetDOMTiming()->GetDomContentLoadedEventEnd();
-  }
-  if (aProperty.EqualsLiteral("domComplete")) {
-    return GetDOMTiming()->GetDomComplete();
-  }
-  if (aProperty.EqualsLiteral("loadEventStart")) {
-    return GetDOMTiming()->GetLoadEventStart();
-  }
-  if (aProperty.EqualsLiteral("loadEventEnd"))  {
-    return GetDOMTiming()->GetLoadEventEnd();
-  }
-  MOZ_CRASH("IsPerformanceTimingAttribute and GetPerformanceTimingFromString are out of sync");
-  return 0;
-}
+using namespace workers;
 
 namespace {
 
 // Helper classes
 class MOZ_STACK_CLASS PerformanceEntryComparator final
 {
 public:
   bool Equals(const PerformanceEntry* aElem1,
@@ -336,17 +53,18 @@ public:
                 const PerformanceEntry* aElem2) const
   {
     MOZ_ASSERT(aElem1 && aElem2,
                "Trying to compare null performance entries");
     return aElem1->StartTime() < aElem2->StartTime();
   }
 };
 
-class PrefEnabledRunnable final : public WorkerCheckAPIExposureOnMainThreadRunnable
+class PrefEnabledRunnable final
+  : public WorkerCheckAPIExposureOnMainThreadRunnable
 {
 public:
   PrefEnabledRunnable(WorkerPrivate* aWorkerPrivate,
                       const nsCString& aPrefName)
     : WorkerCheckAPIExposureOnMainThreadRunnable(aWorkerPrivate)
     , mEnabled(false)
     , mPrefName(aPrefName)
   { }
@@ -363,141 +81,88 @@ public:
     return mEnabled;
   }
 
 private:
   bool mEnabled;
   nsCString mPrefName;
 };
 
-} // namespace
-
-/* static */ bool
-nsPerformance::IsEnabled(JSContext* aCx, JSObject* aGlobal)
-{
-  if (NS_IsMainThread()) {
-    return Preferences::GetBool("dom.enable_user_timing", false);
-  }
-
-  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
-  MOZ_ASSERT(workerPrivate);
-  workerPrivate->AssertIsOnWorkerThread();
-
-  RefPtr<PrefEnabledRunnable> runnable =
-    new PrefEnabledRunnable(workerPrivate,
-                            NS_LITERAL_CSTRING("dom.enable_user_timing"));
-  return runnable->Dispatch() && runnable->IsEnabled();
-}
-
-/* static */ bool
-nsPerformance::IsObserverEnabled(JSContext* aCx, JSObject* aGlobal)
-{
-  if (NS_IsMainThread()) {
-    return Preferences::GetBool("dom.enable_performance_observer", false);
-  }
-
-  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
-  MOZ_ASSERT(workerPrivate);
-  workerPrivate->AssertIsOnWorkerThread();
-
-  RefPtr<PrefEnabledRunnable> runnable =
-    new PrefEnabledRunnable(workerPrivate,
-                            NS_LITERAL_CSTRING("dom.enable_performance_observer"));
-
-  return runnable->Dispatch() && runnable->IsEnabled();
-}
-
-void
-nsPerformance::InsertUserEntry(PerformanceEntry* aEntry)
-{
-  MOZ_ASSERT(NS_IsMainThread());
+} // anonymous namespace
 
-  nsAutoCString uri;
-  uint64_t markCreationEpoch = 0;
-
-  if (nsContentUtils::IsUserTimingLoggingEnabled() ||
-      nsContentUtils::SendPerformanceTimingNotifications()) {
-    nsresult rv = NS_ERROR_FAILURE;
-    nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
-    if (owner && owner->GetDocumentURI()) {
-      rv = owner->GetDocumentURI()->GetHost(uri);
-    }
-
-    if(NS_FAILED(rv)) {
-      // If we have no URI, just put in "none".
-      uri.AssignLiteral("none");
-    }
-    markCreationEpoch = static_cast<uint64_t>(PR_Now() / PR_USEC_PER_MSEC);
-
-    if (nsContentUtils::IsUserTimingLoggingEnabled()) {
-      PerformanceBase::LogEntry(aEntry, uri);
-    }
-  }
-
-  if (nsContentUtils::SendPerformanceTimingNotifications()) {
-    TimingNotification(aEntry, uri, markCreationEpoch);
-  }
-
-  PerformanceBase::InsertUserEntry(aEntry);
-}
-
-TimeStamp
-nsPerformance::CreationTimeStamp() const
-{
-  return GetDOMTiming()->GetNavigationStartTimeStamp();
-}
-
-DOMHighResTimeStamp
-nsPerformance::CreationTime() const
-{
-  return GetDOMTiming()->GetNavigationStart();
-}
-
-// PerformanceBase
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PerformanceBase)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Performance)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
-NS_IMPL_CYCLE_COLLECTION_INHERITED(PerformanceBase,
+NS_IMPL_CYCLE_COLLECTION_INHERITED(Performance,
                                    DOMEventTargetHelper,
                                    mUserEntries,
                                    mResourceEntries);
 
-NS_IMPL_ADDREF_INHERITED(PerformanceBase, DOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(PerformanceBase, DOMEventTargetHelper)
+NS_IMPL_ADDREF_INHERITED(Performance, DOMEventTargetHelper)
+NS_IMPL_RELEASE_INHERITED(Performance, DOMEventTargetHelper)
+
+/* static */ already_AddRefed<Performance>
+Performance::CreateForMainThread(nsPIDOMWindowInner* aWindow,
+                                 nsDOMNavigationTiming* aDOMTiming,
+                                 nsITimedChannel* aChannel,
+                                 Performance* aParentPerformance)
+{
+  MOZ_ASSERT(NS_IsMainThread());
 
-PerformanceBase::PerformanceBase()
+  RefPtr<Performance> performance =
+    new PerformanceMainThread(aWindow, aDOMTiming, aChannel,
+                              aParentPerformance);
+  return performance.forget();
+}
+
+/* static */ already_AddRefed<Performance>
+Performance::CreateForWorker(workers::WorkerPrivate* aWorkerPrivate)
+{
+  MOZ_ASSERT(aWorkerPrivate);
+  aWorkerPrivate->AssertIsOnWorkerThread();
+
+  RefPtr<Performance> performance = new PerformanceWorker(aWorkerPrivate);
+  return performance.forget();
+}
+
+Performance::Performance()
   : mResourceTimingBufferSize(kDefaultResourceTimingBufferSize)
   , mPendingNotificationObserversTask(false)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 }
 
-PerformanceBase::PerformanceBase(nsPIDOMWindowInner* aWindow)
+Performance::Performance(nsPIDOMWindowInner* aWindow)
   : DOMEventTargetHelper(aWindow)
   , mResourceTimingBufferSize(kDefaultResourceTimingBufferSize)
   , mPendingNotificationObserversTask(false)
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
-PerformanceBase::~PerformanceBase()
+Performance::~Performance()
 {}
 
+JSObject*
+Performance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return PerformanceBinding::Wrap(aCx, this, aGivenProto);
+}
+
 void
-PerformanceBase::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
+Performance::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
 {
   aRetval = mResourceEntries;
   aRetval.AppendElements(mUserEntries);
   aRetval.Sort(PerformanceEntryComparator());
 }
 
 void
-PerformanceBase::GetEntriesByType(const nsAString& aEntryType,
-                                  nsTArray<RefPtr<PerformanceEntry>>& aRetval)
+Performance::GetEntriesByType(const nsAString& aEntryType,
+                              nsTArray<RefPtr<PerformanceEntry>>& aRetval)
 {
   if (aEntryType.EqualsLiteral("resource")) {
     aRetval = mResourceEntries;
     return;
   }
 
   aRetval.Clear();
 
@@ -507,19 +172,19 @@ PerformanceBase::GetEntriesByType(const 
       if (entry->GetEntryType().Equals(aEntryType)) {
         aRetval.AppendElement(entry);
       }
     }
   }
 }
 
 void
-PerformanceBase::GetEntriesByName(const nsAString& aName,
-                                  const Optional<nsAString>& aEntryType,
-                                  nsTArray<RefPtr<PerformanceEntry>>& aRetval)
+Performance::GetEntriesByName(const nsAString& aName,
+                              const Optional<nsAString>& aEntryType,
+                              nsTArray<RefPtr<PerformanceEntry>>& aRetval)
 {
   aRetval.Clear();
 
   for (PerformanceEntry* entry : mResourceEntries) {
     if (entry->GetName().Equals(aName) &&
         (!aEntryType.WasPassed() ||
          entry->GetEntryType().Equals(aEntryType.Value()))) {
       aRetval.AppendElement(entry);
@@ -533,51 +198,51 @@ PerformanceBase::GetEntriesByName(const 
       aRetval.AppendElement(entry);
     }
   }
 
   aRetval.Sort(PerformanceEntryComparator());
 }
 
 void
-PerformanceBase::ClearUserEntries(const Optional<nsAString>& aEntryName,
-                                  const nsAString& aEntryType)
+Performance::ClearUserEntries(const Optional<nsAString>& aEntryName,
+                              const nsAString& aEntryType)
 {
   for (uint32_t i = 0; i < mUserEntries.Length();) {
     if ((!aEntryName.WasPassed() ||
          mUserEntries[i]->GetName().Equals(aEntryName.Value())) &&
         (aEntryType.IsEmpty() ||
          mUserEntries[i]->GetEntryType().Equals(aEntryType))) {
       mUserEntries.RemoveElementAt(i);
     } else {
       ++i;
     }
   }
 }
 
 void
-PerformanceBase::ClearResourceTimings()
+Performance::ClearResourceTimings()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mResourceEntries.Clear();
 }
 
 DOMHighResTimeStamp
-PerformanceBase::RoundTime(double aTime) const
+Performance::RoundTime(double aTime) const
 {
   // Round down to the nearest 5us, because if the timer is too accurate people
   // can do nasty timing attacks with it.  See similar code in the worker
   // Performance implementation.
   const double maxResolutionMs = 0.005;
   return floor(aTime / maxResolutionMs) * maxResolutionMs;
 }
 
 
 void
-PerformanceBase::Mark(const nsAString& aName, ErrorResult& aRv)
+Performance::Mark(const nsAString& aName, ErrorResult& aRv)
 {
   // Don't add the entry if the buffer is full. XXX should be removed by bug 1159003.
   if (mUserEntries.Length() >= mResourceTimingBufferSize) {
     return;
   }
 
   if (IsPerformanceTimingAttribute(aName)) {
     aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
@@ -589,23 +254,23 @@ PerformanceBase::Mark(const nsAString& a
   InsertUserEntry(performanceMark);
 
   if (profiler_is_active()) {
     PROFILER_MARKER(NS_ConvertUTF16toUTF8(aName).get());
   }
 }
 
 void
-PerformanceBase::ClearMarks(const Optional<nsAString>& aName)
+Performance::ClearMarks(const Optional<nsAString>& aName)
 {
   ClearUserEntries(aName, NS_LITERAL_STRING("mark"));
 }
 
 DOMHighResTimeStamp
-PerformanceBase::ResolveTimestampFromName(const nsAString& aName,
+Performance::ResolveTimestampFromName(const nsAString& aName,
                                           ErrorResult& aRv)
 {
   AutoTArray<RefPtr<PerformanceEntry>, 1> arr;
   DOMHighResTimeStamp ts;
   Optional<nsAString> typeParam;
   nsAutoString str;
   str.AssignLiteral("mark");
   typeParam = &str;
@@ -624,20 +289,20 @@ PerformanceBase::ResolveTimestampFromNam
     aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
     return 0;
   }
 
   return ts - CreationTime();
 }
 
 void
-PerformanceBase::Measure(const nsAString& aName,
-                         const Optional<nsAString>& aStartMark,
-                         const Optional<nsAString>& aEndMark,
-                         ErrorResult& aRv)
+Performance::Measure(const nsAString& aName,
+                     const Optional<nsAString>& aStartMark,
+                     const Optional<nsAString>& aEndMark,
+                     ErrorResult& aRv)
 {
   // Don't add the entry if the buffer is full. XXX should be removed by bug
   // 1159003.
   if (mUserEntries.Length() >= mResourceTimingBufferSize) {
     return;
   }
 
   DOMHighResTimeStamp startTime;
@@ -670,35 +335,36 @@ PerformanceBase::Measure(const nsAString
   }
 
   RefPtr<PerformanceMeasure> performanceMeasure =
     new PerformanceMeasure(GetAsISupports(), aName, startTime, endTime);
   InsertUserEntry(performanceMeasure);
 }
 
 void
-PerformanceBase::ClearMeasures(const Optional<nsAString>& aName)
+Performance::ClearMeasures(const Optional<nsAString>& aName)
 {
   ClearUserEntries(aName, NS_LITERAL_STRING("measure"));
 }
 
 void
-PerformanceBase::LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const
+Performance::LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const
 {
   PERFLOG("Performance Entry: %s|%s|%s|%f|%f|%" PRIu64 "\n",
           aOwner.BeginReading(),
           NS_ConvertUTF16toUTF8(aEntry->GetEntryType()).get(),
           NS_ConvertUTF16toUTF8(aEntry->GetName()).get(),
           aEntry->StartTime(),
           aEntry->Duration(),
           static_cast<uint64_t>(PR_Now() / PR_USEC_PER_MSEC));
 }
 
 void
-PerformanceBase::TimingNotification(PerformanceEntry* aEntry, const nsACString& aOwner, uint64_t aEpoch)
+Performance::TimingNotification(PerformanceEntry* aEntry,
+                                const nsACString& aOwner, uint64_t aEpoch)
 {
   PerformanceEntryEventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
   init.mName = aEntry->GetName();
   init.mEntryType = aEntry->GetEntryType();
   init.mStartTime = aEntry->StartTime();
   init.mDuration = aEntry->Duration();
@@ -711,32 +377,32 @@ PerformanceBase::TimingNotification(Perf
   nsCOMPtr<EventTarget> et = do_QueryInterface(GetOwner());
   if (et) {
     bool dummy = false;
     et->DispatchEvent(perfEntryEvent, &dummy);
   }
 }
 
 void
-PerformanceBase::InsertUserEntry(PerformanceEntry* aEntry)
+Performance::InsertUserEntry(PerformanceEntry* aEntry)
 {
   mUserEntries.InsertElementSorted(aEntry,
                                    PerformanceEntryComparator());
 
   QueueEntry(aEntry);
 }
 
 void
-PerformanceBase::SetResourceTimingBufferSize(uint64_t aMaxSize)
+Performance::SetResourceTimingBufferSize(uint64_t aMaxSize)
 {
   mResourceTimingBufferSize = aMaxSize;
 }
 
 void
-PerformanceBase::InsertResourceEntry(PerformanceEntry* aEntry)
+Performance::InsertResourceEntry(PerformanceEntry* aEntry)
 {
   MOZ_ASSERT(aEntry);
   MOZ_ASSERT(mResourceEntries.Length() < mResourceTimingBufferSize);
   if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
     return;
   }
 
   mResourceEntries.InsertElementSorted(aEntry,
@@ -744,46 +410,46 @@ PerformanceBase::InsertResourceEntry(Per
   if (mResourceEntries.Length() == mResourceTimingBufferSize) {
     // call onresourcetimingbufferfull
     DispatchBufferFullEvent();
   }
   QueueEntry(aEntry);
 }
 
 void
-PerformanceBase::AddObserver(PerformanceObserver* aObserver)
+Performance::AddObserver(PerformanceObserver* aObserver)
 {
   mObservers.AppendElementUnlessExists(aObserver);
 }
 
 void
-PerformanceBase::RemoveObserver(PerformanceObserver* aObserver)
+Performance::RemoveObserver(PerformanceObserver* aObserver)
 {
   mObservers.RemoveElement(aObserver);
 }
 
 void
-PerformanceBase::NotifyObservers()
+Performance::NotifyObservers()
 {
   mPendingNotificationObserversTask = false;
   NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers,
                                            PerformanceObserver,
                                            Notify, ());
 }
 
 void
-PerformanceBase::CancelNotificationObservers()
+Performance::CancelNotificationObservers()
 {
   mPendingNotificationObserversTask = false;
 }
 
 class NotifyObserversTask final : public CancelableRunnable
 {
 public:
-  explicit NotifyObserversTask(PerformanceBase* aPerformance)
+  explicit NotifyObserversTask(Performance* aPerformance)
     : mPerformance(aPerformance)
   {
     MOZ_ASSERT(mPerformance);
   }
 
   NS_IMETHOD Run() override
   {
     MOZ_ASSERT(mPerformance);
@@ -798,36 +464,74 @@ public:
     return NS_OK;
   }
 
 private:
   ~NotifyObserversTask()
   {
   }
 
-  RefPtr<PerformanceBase> mPerformance;
+  RefPtr<Performance> mPerformance;
 };
 
 void
-PerformanceBase::RunNotificationObserversTask()
+Performance::RunNotificationObserversTask()
 {
   mPendingNotificationObserversTask = true;
   nsCOMPtr<nsIRunnable> task = new NotifyObserversTask(this);
   nsresult rv = NS_DispatchToCurrentThread(task);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     mPendingNotificationObserversTask = false;
   }
 }
 
 void
-PerformanceBase::QueueEntry(PerformanceEntry* aEntry)
+Performance::QueueEntry(PerformanceEntry* aEntry)
 {
   if (mObservers.IsEmpty()) {
     return;
   }
   NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers,
                                            PerformanceObserver,
                                            QueueEntry, (aEntry));
 
   if (!mPendingNotificationObserversTask) {
     RunNotificationObserversTask();
   }
 }
+
+/* static */ bool
+Performance::IsEnabled(JSContext* aCx, JSObject* aGlobal)
+{
+  if (NS_IsMainThread()) {
+    return Preferences::GetBool("dom.enable_user_timing", false);
+  }
+
+  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
+  MOZ_ASSERT(workerPrivate);
+  workerPrivate->AssertIsOnWorkerThread();
+
+  RefPtr<PrefEnabledRunnable> runnable =
+    new PrefEnabledRunnable(workerPrivate,
+                            NS_LITERAL_CSTRING("dom.enable_user_timing"));
+  return runnable->Dispatch() && runnable->IsEnabled();
+}
+
+/* static */ bool
+Performance::IsObserverEnabled(JSContext* aCx, JSObject* aGlobal)
+{
+  if (NS_IsMainThread()) {
+    return Preferences::GetBool("dom.enable_performance_observer", false);
+  }
+
+  WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
+  MOZ_ASSERT(workerPrivate);
+  workerPrivate->AssertIsOnWorkerThread();
+
+  RefPtr<PrefEnabledRunnable> runnable =
+    new PrefEnabledRunnable(workerPrivate,
+                            NS_LITERAL_CSTRING("dom.enable_performance_observer"));
+
+  return runnable->Dispatch() && runnable->IsEnabled();
+}
+
+} // dom namespace
+} // mozilla namespace
rename from dom/performance/nsPerformance.h
rename to dom/performance/Performance.h
--- a/dom/performance/nsPerformance.h
+++ b/dom/performance/Performance.h
@@ -1,117 +1,149 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef nsPerformance_h___
-#define nsPerformance_h___
 
-#include "nsCOMPtr.h"
-#include "nsAutoPtr.h"
+#ifndef mozilla_dom_Performance_h
+#define mozilla_dom_Performance_h
+
 #include "mozilla/Attributes.h"
-#include "nsWrapperCache.h"
+#include "mozilla/DOMEventTargetHelper.h"
+#include "nsCOMPtr.h"
 #include "nsDOMNavigationTiming.h"
-#include "nsContentUtils.h"
-#include "nsPIDOMWindow.h"
-#include "js/TypeDecls.h"
-#include "js/RootingAPI.h"
-#include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/DOMEventTargetHelper.h"
 
 class nsITimedChannel;
-class nsPerformance;
 class nsIHttpChannel;
 
 namespace mozilla {
 
 class ErrorResult;
 
 namespace dom {
 
 class PerformanceEntry;
 class PerformanceNavigation;
 class PerformanceObserver;
 class PerformanceTiming;
 
-} // namespace dom
-} // namespace mozilla
+namespace workers {
+class WorkerPrivate;
+}
 
 // Base class for main-thread and worker Performance API
-class PerformanceBase : public mozilla::DOMEventTargetHelper 
+class Performance : public DOMEventTargetHelper
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PerformanceBase,
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Performance,
                                            DOMEventTargetHelper)
 
-  PerformanceBase();
-  explicit PerformanceBase(nsPIDOMWindowInner* aWindow);
+  static bool IsEnabled(JSContext* aCx, JSObject* aGlobal);
+
+  static bool IsObserverEnabled(JSContext* aCx, JSObject* aGlobal);
 
-  typedef mozilla::dom::PerformanceEntry PerformanceEntry;
-  typedef mozilla::dom::PerformanceObserver PerformanceObserver;
+  static already_AddRefed<Performance>
+  CreateForMainThread(nsPIDOMWindowInner* aWindow,
+                      nsDOMNavigationTiming* aDOMTiming,
+                      nsITimedChannel* aChannel,
+                      Performance* aParentPerformance);
+
+  static already_AddRefed<Performance>
+  CreateForWorker(workers::WorkerPrivate* aWorkerPrivate);
+
+  JSObject* WrapObject(JSContext *cx,
+                       JS::Handle<JSObject*> aGivenProto) override;
 
   void GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval);
+
   void GetEntriesByType(const nsAString& aEntryType,
                         nsTArray<RefPtr<PerformanceEntry>>& aRetval);
+
   void GetEntriesByName(const nsAString& aName,
-                        const mozilla::dom::Optional<nsAString>& aEntryType,
+                        const Optional<nsAString>& aEntryType,
                         nsTArray<RefPtr<PerformanceEntry>>& aRetval);
+
+  virtual void AddEntry(nsIHttpChannel* channel,
+                        nsITimedChannel* timedChannel) = 0;
+
   void ClearResourceTimings();
 
   virtual DOMHighResTimeStamp Now() const = 0;
 
-  void Mark(const nsAString& aName, mozilla::ErrorResult& aRv);
-  void ClearMarks(const mozilla::dom::Optional<nsAString>& aName);
+  void Mark(const nsAString& aName, ErrorResult& aRv);
+
+  void ClearMarks(const Optional<nsAString>& aName);
+
   void Measure(const nsAString& aName,
-               const mozilla::dom::Optional<nsAString>& aStartMark,
-               const mozilla::dom::Optional<nsAString>& aEndMark,
-               mozilla::ErrorResult& aRv);
-  void ClearMeasures(const mozilla::dom::Optional<nsAString>& aName);
+               const Optional<nsAString>& aStartMark,
+               const Optional<nsAString>& aEndMark,
+               ErrorResult& aRv);
+
+  void ClearMeasures(const Optional<nsAString>& aName);
 
   void SetResourceTimingBufferSize(uint64_t aMaxSize);
 
   void AddObserver(PerformanceObserver* aObserver);
   void RemoveObserver(PerformanceObserver* aObserver);
   void NotifyObservers();
   void CancelNotificationObservers();
 
+  virtual PerformanceTiming* Timing() = 0;
+
+  virtual PerformanceNavigation* Navigation() = 0;
+
+  IMPL_EVENT_HANDLER(resourcetimingbufferfull)
+
+  virtual void GetMozMemory(JSContext *aCx,
+                            JS::MutableHandle<JSObject*> aObj) = 0;
+
+  virtual nsDOMNavigationTiming* GetDOMTiming() const = 0;
+
+  virtual nsITimedChannel* GetChannel() const = 0;
+
+  virtual Performance* GetParentPerformance() const = 0;
+
 protected:
-  virtual ~PerformanceBase();
+  Performance();
+  explicit Performance(nsPIDOMWindowInner* aWindow);
+
+  virtual ~Performance();
 
   virtual void InsertUserEntry(PerformanceEntry* aEntry);
   void InsertResourceEntry(PerformanceEntry* aEntry);
 
-  void ClearUserEntries(const mozilla::dom::Optional<nsAString>& aEntryName,
+  void ClearUserEntries(const Optional<nsAString>& aEntryName,
                         const nsAString& aEntryType);
 
   DOMHighResTimeStamp ResolveTimestampFromName(const nsAString& aName,
-                                               mozilla::ErrorResult& aRv);
+                                               ErrorResult& aRv);
 
   virtual nsISupports* GetAsISupports() = 0;
 
   virtual void DispatchBufferFullEvent() = 0;
 
-  virtual mozilla::TimeStamp CreationTimeStamp() const = 0;
+  virtual TimeStamp CreationTimeStamp() const = 0;
 
   virtual DOMHighResTimeStamp CreationTime() const = 0;
 
   virtual bool IsPerformanceTimingAttribute(const nsAString& aName) = 0;
 
   virtual DOMHighResTimeStamp
   GetPerformanceTimingFromString(const nsAString& aTimingName) = 0;
 
   bool IsResourceEntryLimitReached() const
   {
     return mResourceEntries.Length() >= mResourceTimingBufferSize;
   }
 
   void LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const;
-  void TimingNotification(PerformanceEntry* aEntry, const nsACString& aOwner, uint64_t epoch);
+  void TimingNotification(PerformanceEntry* aEntry, const nsACString& aOwner,
+                          uint64_t epoch);
 
   void RunNotificationObserversTask();
   void QueueEntry(PerformanceEntry* aEntry);
 
   DOMHighResTimeStamp RoundTime(double aTime) const;
 
   nsTObserverArray<PerformanceObserver*> mObservers;
 
@@ -119,97 +151,12 @@ private:
   nsTArray<RefPtr<PerformanceEntry>> mUserEntries;
   nsTArray<RefPtr<PerformanceEntry>> mResourceEntries;
 
   uint64_t mResourceTimingBufferSize;
   static const uint64_t kDefaultResourceTimingBufferSize = 150;
   bool mPendingNotificationObserversTask;
 };
 
-// Script "performance" object
-class nsPerformance final : public PerformanceBase
-{
-public:
-  nsPerformance(nsPIDOMWindowInner* aWindow,
-                nsDOMNavigationTiming* aDOMTiming,
-                nsITimedChannel* aChannel,
-                nsPerformance* aParentPerformance);
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsPerformance,
-                                                         PerformanceBase)
-
-  static bool IsEnabled(JSContext* aCx, JSObject* aGlobal);
-
-  static bool IsObserverEnabled(JSContext* aCx, JSObject* aGlobal);
-
-  nsDOMNavigationTiming* GetDOMTiming() const
-  {
-    return mDOMTiming;
-  }
-
-  nsITimedChannel* GetChannel() const
-  {
-    return mChannel;
-  }
-
-  nsPerformance* GetParentPerformance() const
-  {
-    return mParentPerformance;
-  }
-
-  JSObject* WrapObject(JSContext *cx,
-                       JS::Handle<JSObject*> aGivenProto) override;
-
-  // Performance WebIDL methods
-  DOMHighResTimeStamp Now() const override;
-
-  mozilla::dom::PerformanceTiming* Timing();
-  mozilla::dom::PerformanceNavigation* Navigation();
-
-  void AddEntry(nsIHttpChannel* channel,
-                nsITimedChannel* timedChannel);
+} // namespace dom
+} // namespace mozilla
 
-  using PerformanceBase::GetEntries;
-  using PerformanceBase::GetEntriesByType;
-  using PerformanceBase::GetEntriesByName;
-  using PerformanceBase::ClearResourceTimings;
-
-  using PerformanceBase::Mark;
-  using PerformanceBase::ClearMarks;
-  using PerformanceBase::Measure;
-  using PerformanceBase::ClearMeasures;
-  using PerformanceBase::SetResourceTimingBufferSize;
-
-  void GetMozMemory(JSContext *aCx, JS::MutableHandle<JSObject*> aObj);
-
-  IMPL_EVENT_HANDLER(resourcetimingbufferfull)
-
-  mozilla::TimeStamp CreationTimeStamp() const override;
-
-  DOMHighResTimeStamp CreationTime() const override;
-
-protected:
-  ~nsPerformance();
-
-  nsISupports* GetAsISupports() override
-  {
-    return this;
-  }
-
-  void InsertUserEntry(PerformanceEntry* aEntry) override;
-
-  bool IsPerformanceTimingAttribute(const nsAString& aName) override;
-
-  DOMHighResTimeStamp
-  GetPerformanceTimingFromString(const nsAString& aTimingName) override;
-
-  void DispatchBufferFullEvent() override;
-
-  RefPtr<nsDOMNavigationTiming> mDOMTiming;
-  nsCOMPtr<nsITimedChannel> mChannel;
-  RefPtr<mozilla::dom::PerformanceTiming> mTiming;
-  RefPtr<mozilla::dom::PerformanceNavigation> mNavigation;
-  RefPtr<nsPerformance> mParentPerformance;
-  JS::Heap<JSObject*> mMozMemory;
-};
-
-#endif /* nsPerformance_h___ */
+#endif // mozilla_dom_Performance_h
new file mode 100644
--- /dev/null
+++ b/dom/performance/PerformanceMainThread.cpp
@@ -0,0 +1,336 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "PerformanceMainThread.h"
+#include "PerformanceNavigation.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(PerformanceMainThread)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PerformanceMainThread,
+                                                Performance)
+NS_IMPL_CYCLE_COLLECTION_UNLINK(mTiming,
+                                mNavigation,
+                                mParentPerformance)
+  tmp->mMozMemory = nullptr;
+  mozilla::DropJSObjects(this);
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PerformanceMainThread,
+                                                  Performance)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTiming,
+                                    mNavigation,
+                                    mParentPerformance)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceMainThread,
+                                                Performance)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mMozMemory)
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+NS_IMPL_ADDREF_INHERITED(PerformanceMainThread, Performance)
+NS_IMPL_RELEASE_INHERITED(PerformanceMainThread, Performance)
+
+// QueryInterface implementation for PerformanceMainThread
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PerformanceMainThread)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END_INHERITING(Performance)
+
+PerformanceMainThread::PerformanceMainThread(nsPIDOMWindowInner* aWindow,
+                                             nsDOMNavigationTiming* aDOMTiming,
+                                             nsITimedChannel* aChannel,
+                                             Performance* aParentPerformance)
+  : Performance(aWindow)
+  , mDOMTiming(aDOMTiming)
+  , mChannel(aChannel)
+  , mParentPerformance(aParentPerformance)
+{
+  MOZ_ASSERT(aWindow, "Parent window object should be provided");
+}
+
+PerformanceMainThread::~PerformanceMainThread()
+{
+  mozilla::DropJSObjects(this);
+}
+
+void
+PerformanceMainThread::GetMozMemory(JSContext *aCx,
+                                    JS::MutableHandle<JSObject*> aObj)
+{
+  if (!mMozMemory) {
+    mMozMemory = js::gc::NewMemoryInfoObject(aCx);
+    if (mMozMemory) {
+      mozilla::HoldJSObjects(this);
+    }
+  }
+
+  aObj.set(mMozMemory);
+}
+
+PerformanceTiming*
+PerformanceMainThread::Timing()
+{
+  if (!mTiming) {
+    // For navigation timing, the third argument (an nsIHtttpChannel) is null
+    // since the cross-domain redirect were already checked.  The last argument
+    // (zero time) for performance.timing is the navigation start value.
+    mTiming = new PerformanceTiming(this, mChannel, nullptr,
+                                    mDOMTiming->GetNavigationStart());
+  }
+
+  return mTiming;
+}
+
+void
+PerformanceMainThread::DispatchBufferFullEvent()
+{
+  RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
+  // it bubbles, and it isn't cancelable
+  event->InitEvent(NS_LITERAL_STRING("resourcetimingbufferfull"), true, false);
+  event->SetTrusted(true);
+  DispatchDOMEvent(nullptr, event, nullptr, nullptr);
+}
+
+PerformanceNavigation*
+PerformanceMainThread::Navigation()
+{
+  if (!mNavigation) {
+    mNavigation = new PerformanceNavigation(this);
+  }
+
+  return mNavigation;
+}
+
+DOMHighResTimeStamp
+PerformanceMainThread::Now() const
+{
+  return RoundTime(GetDOMTiming()->TimeStampToDOMHighRes(TimeStamp::Now()));
+}
+
+/**
+ * An entry should be added only after the resource is loaded.
+ * This method is not thread safe and can only be called on the main thread.
+ */
+void
+PerformanceMainThread::AddEntry(nsIHttpChannel* channel,
+                                nsITimedChannel* timedChannel)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // Check if resource timing is prefed off.
+  if (!nsContentUtils::IsResourceTimingEnabled()) {
+    return;
+  }
+
+  // Don't add the entry if the buffer is full
+  if (IsResourceEntryLimitReached()) {
+    return;
+  }
+
+  if (channel && timedChannel) {
+    nsAutoCString name;
+    nsAutoString initiatorType;
+    nsCOMPtr<nsIURI> originalURI;
+
+    timedChannel->GetInitiatorType(initiatorType);
+
+    // According to the spec, "The name attribute must return the resolved URL
+    // of the requested resource. This attribute must not change even if the
+    // fetch redirected to a different URL."
+    channel->GetOriginalURI(getter_AddRefs(originalURI));
+    originalURI->GetSpec(name);
+    NS_ConvertUTF8toUTF16 entryName(name);
+
+    // The nsITimedChannel argument will be used to gather all the timings.
+    // The nsIHttpChannel argument will be used to check if any cross-origin
+    // redirects occurred.
+    // The last argument is the "zero time" (offset). Since we don't want
+    // any offset for the resource timing, this will be set to "0" - the
+    // resource timing returns a relative timing (no offset).
+    RefPtr<PerformanceTiming> performanceTiming =
+        new PerformanceTiming(this, timedChannel, channel,
+            0);
+
+    // The PerformanceResourceTiming object will use the PerformanceTiming
+    // object to get all the required timings.
+    RefPtr<PerformanceResourceTiming> performanceEntry =
+      new PerformanceResourceTiming(performanceTiming, this, entryName);
+
+    nsAutoCString protocol;
+    channel->GetProtocolVersion(protocol);
+    performanceEntry->SetNextHopProtocol(NS_ConvertUTF8toUTF16(protocol));
+
+    uint64_t encodedBodySize = 0;
+    channel->GetEncodedBodySize(&encodedBodySize);
+    performanceEntry->SetEncodedBodySize(encodedBodySize);
+
+    uint64_t transferSize = 0;
+    channel->GetTransferSize(&transferSize);
+    performanceEntry->SetTransferSize(transferSize);
+
+    uint64_t decodedBodySize = 0;
+    channel->GetDecodedBodySize(&decodedBodySize);
+    if (decodedBodySize == 0) {
+      decodedBodySize = encodedBodySize;
+    }
+    performanceEntry->SetDecodedBodySize(decodedBodySize);
+
+    // If the initiator type had no valid value, then set it to the default
+    // ("other") value.
+    if (initiatorType.IsEmpty()) {
+      initiatorType = NS_LITERAL_STRING("other");
+    }
+    performanceEntry->SetInitiatorType(initiatorType);
+    InsertResourceEntry(performanceEntry);
+  }
+}
+
+// To be removed once bug 1124165 lands
+bool
+PerformanceMainThread::IsPerformanceTimingAttribute(const nsAString& aName)
+{
+  // Note that toJSON is added to this list due to bug 1047848
+  static const char* attributes[] =
+    {"navigationStart", "unloadEventStart", "unloadEventEnd", "redirectStart",
+     "redirectEnd", "fetchStart", "domainLookupStart", "domainLookupEnd",
+     "connectStart", "connectEnd", "requestStart", "responseStart",
+     "responseEnd", "domLoading", "domInteractive",
+     "domContentLoadedEventStart", "domContentLoadedEventEnd", "domComplete",
+     "loadEventStart", "loadEventEnd", nullptr};
+
+  for (uint32_t i = 0; attributes[i]; ++i) {
+    if (aName.EqualsASCII(attributes[i])) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+DOMHighResTimeStamp
+PerformanceMainThread::GetPerformanceTimingFromString(const nsAString& aProperty)
+{
+  if (!IsPerformanceTimingAttribute(aProperty)) {
+    return 0;
+  }
+  if (aProperty.EqualsLiteral("navigationStart")) {
+    // DOMHighResTimeStamp is in relation to navigationStart, so this will be
+    // zero.
+    return GetDOMTiming()->GetNavigationStart();
+  }
+  if (aProperty.EqualsLiteral("unloadEventStart")) {
+    return GetDOMTiming()->GetUnloadEventStart();
+  }
+  if (aProperty.EqualsLiteral("unloadEventEnd")) {
+    return GetDOMTiming()->GetUnloadEventEnd();
+  }
+  if (aProperty.EqualsLiteral("redirectStart")) {
+    return Timing()->RedirectStart();
+  }
+  if (aProperty.EqualsLiteral("redirectEnd")) {
+    return Timing()->RedirectEnd();
+  }
+  if (aProperty.EqualsLiteral("fetchStart")) {
+    return Timing()->FetchStart();
+  }
+  if (aProperty.EqualsLiteral("domainLookupStart")) {
+    return Timing()->DomainLookupStart();
+  }
+  if (aProperty.EqualsLiteral("domainLookupEnd")) {
+    return Timing()->DomainLookupEnd();
+  }
+  if (aProperty.EqualsLiteral("connectStart")) {
+    return Timing()->ConnectStart();
+  }
+  if (aProperty.EqualsLiteral("connectEnd")) {
+    return Timing()->ConnectEnd();
+  }
+  if (aProperty.EqualsLiteral("requestStart")) {
+    return Timing()->RequestStart();
+  }
+  if (aProperty.EqualsLiteral("responseStart")) {
+    return Timing()->ResponseStart();
+  }
+  if (aProperty.EqualsLiteral("responseEnd")) {
+    return Timing()->ResponseEnd();
+  }
+  if (aProperty.EqualsLiteral("domLoading")) {
+    return GetDOMTiming()->GetDomLoading();
+  }
+  if (aProperty.EqualsLiteral("domInteractive")) {
+    return GetDOMTiming()->GetDomInteractive();
+  }
+  if (aProperty.EqualsLiteral("domContentLoadedEventStart")) {
+    return GetDOMTiming()->GetDomContentLoadedEventStart();
+  }
+  if (aProperty.EqualsLiteral("domContentLoadedEventEnd")) {
+    return GetDOMTiming()->GetDomContentLoadedEventEnd();
+  }
+  if (aProperty.EqualsLiteral("domComplete")) {
+    return GetDOMTiming()->GetDomComplete();
+  }
+  if (aProperty.EqualsLiteral("loadEventStart")) {
+    return GetDOMTiming()->GetLoadEventStart();
+  }
+  if (aProperty.EqualsLiteral("loadEventEnd"))  {
+    return GetDOMTiming()->GetLoadEventEnd();
+  }
+  MOZ_CRASH("IsPerformanceTimingAttribute and GetPerformanceTimingFromString are out of sync");
+  return 0;
+}
+
+void
+PerformanceMainThread::InsertUserEntry(PerformanceEntry* aEntry)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoCString uri;
+  uint64_t markCreationEpoch = 0;
+
+  if (nsContentUtils::IsUserTimingLoggingEnabled() ||
+      nsContentUtils::SendPerformanceTimingNotifications()) {
+    nsresult rv = NS_ERROR_FAILURE;
+    nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
+    if (owner && owner->GetDocumentURI()) {
+      rv = owner->GetDocumentURI()->GetHost(uri);
+    }
+
+    if(NS_FAILED(rv)) {
+      // If we have no URI, just put in "none".
+      uri.AssignLiteral("none");
+    }
+    markCreationEpoch = static_cast<uint64_t>(PR_Now() / PR_USEC_PER_MSEC);
+
+    if (nsContentUtils::IsUserTimingLoggingEnabled()) {
+      Performance::LogEntry(aEntry, uri);
+    }
+  }
+
+  if (nsContentUtils::SendPerformanceTimingNotifications()) {
+    TimingNotification(aEntry, uri, markCreationEpoch);
+  }
+
+  Performance::InsertUserEntry(aEntry);
+}
+
+TimeStamp
+PerformanceMainThread::CreationTimeStamp() const
+{
+  return GetDOMTiming()->GetNavigationStartTimeStamp();
+}
+
+DOMHighResTimeStamp
+PerformanceMainThread::CreationTime() const
+{
+  return GetDOMTiming()->GetNavigationStart();
+}
+
+} // dom namespace
+} // mozilla namespace
new file mode 100644
--- /dev/null
+++ b/dom/performance/PerformanceMainThread.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_PerformanceMainThread_h
+#define mozilla_dom_PerformanceMainThread_h
+
+#include "Performance.h"
+
+namespace mozilla {
+namespace dom {
+
+class PerformanceMainThread final : public Performance
+{
+public:
+  PerformanceMainThread(nsPIDOMWindowInner* aWindow,
+                        nsDOMNavigationTiming* aDOMTiming,
+                        nsITimedChannel* aChannel,
+                        Performance* aParentPerformance);
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(PerformanceMainThread,
+                                                         Performance)
+
+  // Performance WebIDL methods
+  DOMHighResTimeStamp Now() const override;
+
+  virtual PerformanceTiming* Timing() override;
+
+  virtual PerformanceNavigation* Navigation() override;
+
+  virtual void AddEntry(nsIHttpChannel* channel,
+                        nsITimedChannel* timedChannel) override;
+
+  TimeStamp CreationTimeStamp() const override;
+
+  DOMHighResTimeStamp CreationTime() const override;
+
+  virtual void GetMozMemory(JSContext *aCx,
+                            JS::MutableHandle<JSObject*> aObj) override;
+
+  virtual nsDOMNavigationTiming* GetDOMTiming() const override
+  {
+    return mDOMTiming;
+  }
+
+  virtual nsITimedChannel* GetChannel() const override
+  {
+    return mChannel;
+  }
+
+  virtual Performance* GetParentPerformance() const override
+  {
+    return mParentPerformance;
+  }
+
+protected:
+  ~PerformanceMainThread();
+
+  nsISupports* GetAsISupports() override
+  {
+    return this;
+  }
+
+  void InsertUserEntry(PerformanceEntry* aEntry) override;
+
+  bool IsPerformanceTimingAttribute(const nsAString& aName) override;
+
+  DOMHighResTimeStamp
+  GetPerformanceTimingFromString(const nsAString& aTimingName) override;
+
+  void DispatchBufferFullEvent() override;
+
+  RefPtr<nsDOMNavigationTiming> mDOMTiming;
+  nsCOMPtr<nsITimedChannel> mChannel;
+  RefPtr<PerformanceTiming> mTiming;
+  RefPtr<PerformanceNavigation> mNavigation;
+  RefPtr<Performance> mParentPerformance;
+  JS::Heap<JSObject*> mMozMemory;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_PerformanceMainThread_h
--- a/dom/performance/PerformanceNavigation.cpp
+++ b/dom/performance/PerformanceNavigation.cpp
@@ -11,17 +11,17 @@
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PerformanceNavigation, mPerformance)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PerformanceNavigation, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PerformanceNavigation, Release)
 
-PerformanceNavigation::PerformanceNavigation(nsPerformance* aPerformance)
+PerformanceNavigation::PerformanceNavigation(Performance* aPerformance)
   : mPerformance(aPerformance)
 {
   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
 }
 
 PerformanceNavigation::~PerformanceNavigation()
 {
 }
--- a/dom/performance/PerformanceNavigation.h
+++ b/dom/performance/PerformanceNavigation.h
@@ -3,50 +3,50 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_PerformanceNavigation_h
 #define mozilla_dom_PerformanceNavigation_h
 
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/Performance.h"
 #include "nsDOMNavigationTiming.h"
-#include "nsPerformance.h"
 #include "nsWrapperCache.h"
 
 namespace mozilla {
 namespace dom {
 
 // Script "performance.navigation" object
 class PerformanceNavigation final : public nsWrapperCache
 {
 public:
   enum PerformanceNavigationType {
     TYPE_NAVIGATE = 0,
     TYPE_RELOAD = 1,
     TYPE_BACK_FORWARD = 2,
     TYPE_RESERVED = 255,
   };
 
-  explicit PerformanceNavigation(nsPerformance* aPerformance);
+  explicit PerformanceNavigation(Performance* aPerformance);
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PerformanceNavigation)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(PerformanceNavigation)
 
   nsDOMNavigationTiming* GetDOMTiming() const
   {
     return mPerformance->GetDOMTiming();
   }
 
   PerformanceTiming* GetPerformanceTiming() const
   {
     return mPerformance->Timing();
   }
 
-  nsPerformance* GetParentObject() const
+  Performance* GetParentObject() const
   {
     return mPerformance;
   }
 
   virtual JSObject* WrapObject(JSContext *cx,
                                JS::Handle<JSObject*> aGivenProto) override;
 
   // PerformanceNavigation WebIDL methods
@@ -54,15 +54,15 @@ public:
   {
     return GetDOMTiming()->GetType();
   }
 
   uint16_t RedirectCount() const;
 
 private:
   ~PerformanceNavigation();
-  RefPtr<nsPerformance> mPerformance;
+  RefPtr<Performance> mPerformance;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_PerformanceNavigation_h
--- a/dom/performance/PerformanceObserver.cpp
+++ b/dom/performance/PerformanceObserver.cpp
@@ -1,21 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PerformanceObserver.h"
 
+#include "mozilla/dom/Performance.h"
 #include "mozilla/dom/PerformanceBinding.h"
 #include "mozilla/dom/PerformanceEntryBinding.h"
 #include "mozilla/dom/PerformanceObserverBinding.h"
-#include "mozilla/dom/workers/bindings/Performance.h"
-#include "nsPerformance.h"
 #include "nsPIDOMWindow.h"
 #include "nsQueryObject.h"
 #include "nsString.h"
 #include "PerformanceEntry.h"
 #include "PerformanceObserverEntryList.h"
 #include "WorkerPrivate.h"
 #include "WorkerScope.h"
 
--- a/dom/performance/PerformanceObserver.h
+++ b/dom/performance/PerformanceObserver.h
@@ -10,25 +10,25 @@
 #include "nsCOMPtr.h"
 #include "nsISupports.h"
 #include "mozilla/RefPtr.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsWrapperCache.h"
 
 class nsPIDOMWindowInner;
-class PerformanceBase;
 
 namespace mozilla {
 
 class ErrorResult;
 
 namespace dom {
 
 class GlobalObject;
+class Performance;
 class PerformanceEntry;
 class PerformanceObserverCallback;
 struct PerformanceObserverInit;
 namespace workers {
 class WorkerPrivate;
 } // namespace workers
 
 class PerformanceObserver final : public nsISupports,
@@ -62,17 +62,17 @@ public:
   void Notify();
   void QueueEntry(PerformanceEntry* aEntry);
 
 private:
   ~PerformanceObserver();
 
   nsCOMPtr<nsISupports> mOwner;
   RefPtr<PerformanceObserverCallback> mCallback;
-  RefPtr<PerformanceBase> mPerformance;
+  RefPtr<Performance> mPerformance;
   nsTArray<nsString> mEntryTypes;
   bool mConnected;
   nsTArray<RefPtr<PerformanceEntry>> mQueuedEntries;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/performance/PerformanceObserverEntryList.cpp
+++ b/dom/performance/PerformanceObserverEntryList.cpp
@@ -1,18 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PerformanceObserverEntryList.h"
 
+#include "mozilla/dom/Performance.h"
 #include "mozilla/dom/PerformanceObserverEntryListBinding.h"
-#include "nsPerformance.h"
 #include "nsString.h"
 #include "PerformanceResourceTiming.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PerformanceObserverEntryList,
                                       mOwner,
--- a/dom/performance/PerformanceResourceTiming.cpp
+++ b/dom/performance/PerformanceResourceTiming.cpp
@@ -19,17 +19,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PerformanceResourceTiming)
 NS_INTERFACE_MAP_END_INHERITING(PerformanceEntry)
 
 NS_IMPL_ADDREF_INHERITED(PerformanceResourceTiming, PerformanceEntry)
 NS_IMPL_RELEASE_INHERITED(PerformanceResourceTiming, PerformanceEntry)
 
 PerformanceResourceTiming::PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming,
-                                                     nsPerformance* aPerformance,
+                                                     Performance* aPerformance,
                                                      const nsAString& aName)
 : PerformanceEntry(aPerformance, aName, NS_LITERAL_STRING("resource")),
   mTiming(aPerformanceTiming),
   mEncodedBodySize(0),
   mTransferSize(0),
   mDecodedBodySize(0)
 {
   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
--- a/dom/performance/PerformanceResourceTiming.h
+++ b/dom/performance/PerformanceResourceTiming.h
@@ -3,20 +3,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_PerformanceResourceTiming_h___
 #define mozilla_dom_PerformanceResourceTiming_h___
 
 #include "nsCOMPtr.h"
-#include "nsPerformance.h"
 #include "nsIChannel.h"
 #include "nsITimedChannel.h"
-#include "nsDOMNavigationTiming.h"
+#include "Performance.h"
 #include "PerformanceEntry.h"
 #include "PerformanceTiming.h"
 
 namespace mozilla {
 namespace dom {
 
 // http://www.w3.org/TR/resource-timing/#performanceresourcetiming
 class PerformanceResourceTiming final : public PerformanceEntry
@@ -25,17 +24,17 @@ public:
   typedef mozilla::TimeStamp TimeStamp;
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
       PerformanceResourceTiming,
       PerformanceEntry)
 
   PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming,
-                            nsPerformance* aPerformance,
+                            Performance* aPerformance,
                             const nsAString& aName);
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 
   virtual DOMHighResTimeStamp StartTime() const override;
 
   virtual DOMHighResTimeStamp Duration() const override
--- a/dom/performance/PerformanceTiming.cpp
+++ b/dom/performance/PerformanceTiming.cpp
@@ -10,17 +10,17 @@
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PerformanceTiming, mPerformance)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PerformanceTiming, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PerformanceTiming, Release)
 
-PerformanceTiming::PerformanceTiming(nsPerformance* aPerformance,
+PerformanceTiming::PerformanceTiming(Performance* aPerformance,
                                      nsITimedChannel* aChannel,
                                      nsIHttpChannel* aHttpChannel,
                                      DOMHighResTimeStamp aZeroTime)
   : mPerformance(aPerformance),
     mFetchStart(0.0),
     mZeroTime(aZeroTime),
     mRedirectCount(0),
     mTimingAllowed(true),
--- a/dom/performance/PerformanceTiming.h
+++ b/dom/performance/PerformanceTiming.h
@@ -5,18 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_PerformanceTiming_h
 #define mozilla_dom_PerformanceTiming_h
 
 #include "mozilla/Attributes.h"
 #include "nsContentUtils.h"
 #include "nsDOMNavigationTiming.h"
-#include "nsPerformance.h"
 #include "nsWrapperCache.h"
+#include "Performance.h"
 
 class nsIHttpChannel;
 class nsITimedChannel;
 
 namespace mozilla {
 namespace dom {
 
 // Script "performance.timing" object
@@ -37,29 +37,29 @@ public:
  *          algorithm.
  *          Argument is null for the navigation timing (navigation timing uses
  *          another algorithm for the cross-domain redirects).
  * @param   aZeroTime
  *          The offset that will be added to the timestamp of each event. This
  *          argument should be equal to performance.navigationStart for
  *          navigation timing and "0" for the resource timing.
  */
-  PerformanceTiming(nsPerformance* aPerformance,
+  PerformanceTiming(Performance* aPerformance,
                     nsITimedChannel* aChannel,
                     nsIHttpChannel* aHttpChannel,
                     DOMHighResTimeStamp aZeroTime);
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PerformanceTiming)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(PerformanceTiming)
 
   nsDOMNavigationTiming* GetDOMTiming() const
   {
     return mPerformance->GetDOMTiming();
   }
 
-  nsPerformance* GetParentObject() const
+  Performance* GetParentObject() const
   {
     return mPerformance;
   }
 
   /**
    * @param   aStamp
    *          The TimeStamp recorded for a specific event. This TimeStamp can
    *          be null.
@@ -235,17 +235,17 @@ public:
   }
 
 private:
   ~PerformanceTiming();
 
   bool IsInitialized() const;
   void InitializeTimingInfo(nsITimedChannel* aChannel);
 
-  RefPtr<nsPerformance> mPerformance;
+  RefPtr<Performance> mPerformance;
   DOMHighResTimeStamp mFetchStart;
 
   // 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;
 
rename from dom/workers/Performance.cpp
rename to dom/performance/PerformanceWorker.cpp
--- a/dom/workers/Performance.cpp
+++ b/dom/performance/PerformanceWorker.cpp
@@ -1,97 +1,85 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "Performance.h"
-#include "mozilla/dom/PerformanceBinding.h"
-
+#include "PerformanceWorker.h"
 #include "WorkerPrivate.h"
 
-BEGIN_WORKERS_NAMESPACE
+namespace mozilla {
+namespace dom {
 
-Performance::Performance(WorkerPrivate* aWorkerPrivate)
+using namespace workers;
+
+PerformanceWorker::PerformanceWorker(WorkerPrivate* aWorkerPrivate)
   : mWorkerPrivate(aWorkerPrivate)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
 }
 
-Performance::~Performance()
+PerformanceWorker::~PerformanceWorker()
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
 }
 
-JSObject*
-Performance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return PerformanceBinding_workers::Wrap(aCx, this, aGivenProto);
-}
-
 DOMHighResTimeStamp
-Performance::Now() const
+PerformanceWorker::Now() const
 {
   TimeDuration duration =
     TimeStamp::Now() - mWorkerPrivate->NowBaseTimeStamp();
   return RoundTime(duration.ToMilliseconds());
 }
 
 // To be removed once bug 1124165 lands
 bool
-Performance::IsPerformanceTimingAttribute(const nsAString& aName)
+PerformanceWorker::IsPerformanceTimingAttribute(const nsAString& aName)
 {
   // In workers we just support navigationStart.
   return aName.EqualsASCII("navigationStart");
 }
 
 DOMHighResTimeStamp
-Performance::GetPerformanceTimingFromString(const nsAString& aProperty)
+PerformanceWorker::GetPerformanceTimingFromString(const nsAString& aProperty)
 {
   if (!IsPerformanceTimingAttribute(aProperty)) {
     return 0;
   }
 
   if (aProperty.EqualsLiteral("navigationStart")) {
     return mWorkerPrivate->NowBaseTime();
   }
 
   MOZ_CRASH("IsPerformanceTimingAttribute and GetPerformanceTimingFromString are out of sync");
   return 0;
 }
 
 void
-Performance::InsertUserEntry(PerformanceEntry* aEntry)
+PerformanceWorker::InsertUserEntry(PerformanceEntry* aEntry)
 {
   if (mWorkerPrivate->PerformanceLoggingEnabled()) {
     nsAutoCString uri;
     nsCOMPtr<nsIURI> scriptURI = mWorkerPrivate->GetResolvedScriptURI();
     if (!scriptURI || NS_FAILED(scriptURI->GetHost(uri))) {
       // If we have no URI, just put in "none".
       uri.AssignLiteral("none");
     }
-    PerformanceBase::LogEntry(aEntry, uri);
+    Performance::LogEntry(aEntry, uri);
   }
-  PerformanceBase::InsertUserEntry(aEntry);
+  Performance::InsertUserEntry(aEntry);
 }
 
 TimeStamp
-Performance::CreationTimeStamp() const
+PerformanceWorker::CreationTimeStamp() const
 {
   return mWorkerPrivate->NowBaseTimeStamp();
 }
 
 DOMHighResTimeStamp
-Performance::CreationTime() const
+PerformanceWorker::CreationTime() const
 {
   return mWorkerPrivate->NowBaseTime();
 }
 
-void
-Performance::DispatchBufferFullEvent()
-{
-  // This method is needed just for InsertResourceEntry, but this method is not
-  // exposed to workers.
-  MOZ_CRASH("This should not be called.");
-}
-
-END_WORKERS_NAMESPACE
+} // dom namespace
+} // mozilla namespace
rename from dom/workers/Performance.h
rename to dom/performance/PerformanceWorker.h
--- a/dom/workers/Performance.h
+++ b/dom/performance/PerformanceWorker.h
@@ -1,65 +1,100 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef mozilla_dom_workers_performance_h__
-#define mozilla_dom_workers_performance_h__
+#ifndef mozilla_dom_PerformanceWorker_h
+#define mozilla_dom_PerformanceWorker_h
+
+#include "Performance.h"
 
-#include "nsWrapperCache.h"
-#include "js/TypeDecls.h"
-#include "Workers.h"
-#include "nsISupportsImpl.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsPerformance.h"
+namespace mozilla {
+namespace dom {
 
-BEGIN_WORKERS_NAMESPACE
-
+namespace workers {
 class WorkerPrivate;
+}
 
-class Performance final : public PerformanceBase
+class PerformanceWorker final : public Performance
 {
 public:
-  explicit Performance(WorkerPrivate* aWorkerPrivate);
-
-private:
-  ~Performance();
-
-  void InsertUserEntry(PerformanceEntry* aEntry) override;
+  PerformanceWorker(workers::WorkerPrivate* aWorkerPrivate);
 
-  WorkerPrivate* mWorkerPrivate;
-
-public:
-  JSObject*
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-  // WebIDL (public APIs)
+  // Performance WebIDL methods
   DOMHighResTimeStamp Now() const override;
 
-  using PerformanceBase::Mark;
-  using PerformanceBase::ClearMarks;
-  using PerformanceBase::Measure;
-  using PerformanceBase::ClearMeasures;
+  virtual PerformanceTiming* Timing() override
+  {
+    MOZ_CRASH("This should not be called on workers.");
+    return nullptr;
+  }
+
+  virtual PerformanceNavigation* Navigation() override
+  {
+    MOZ_CRASH("This should not be called on workers.");
+    return nullptr;
+  }
+
+  virtual void AddEntry(nsIHttpChannel* channel,
+                        nsITimedChannel* timedChannel) override
+  {
+    MOZ_CRASH("This should not be called on workers.");
+  }
+
+  TimeStamp CreationTimeStamp() const override;
+
+  DOMHighResTimeStamp CreationTime() const override;
 
-private:
+  virtual void GetMozMemory(JSContext *aCx,
+                            JS::MutableHandle<JSObject*> aObj) override
+  {
+    MOZ_CRASH("This should not be called on workers.");
+  }
+
+  virtual nsDOMNavigationTiming* GetDOMTiming() const override
+  {
+    MOZ_CRASH("This should not be called on workers.");
+    return nullptr;
+  }
+
+  virtual nsITimedChannel* GetChannel() const override
+  {
+    MOZ_CRASH("This should not be called on workers.");
+    return nullptr;
+  }
+
+  virtual Performance* GetParentPerformance() const override
+  {
+    MOZ_CRASH("This should not be called on workers.");
+    return nullptr;
+  }
+
+protected:
+  ~PerformanceWorker();
+
   nsISupports* GetAsISupports() override
   {
     return nullptr;
   }
 
-  void DispatchBufferFullEvent() override;
+  void InsertUserEntry(PerformanceEntry* aEntry) override;
 
   bool IsPerformanceTimingAttribute(const nsAString& aName) override;
 
   DOMHighResTimeStamp
   GetPerformanceTimingFromString(const nsAString& aTimingName) override;
 
-  TimeStamp CreationTimeStamp() const override;
+  void DispatchBufferFullEvent() override
+  {
+    MOZ_CRASH("This should not be called on workers.");
+  }
 
-  DOMHighResTimeStamp CreationTime() const override;
+private:
+  workers::WorkerPrivate* mWorkerPrivate;
 };
 
-END_WORKERS_NAMESPACE
+} // namespace dom
+} // namespace mozilla
 
-#endif // mozilla_dom_workers_performance_h__
+#endif // mozilla_dom_PerformanceWorker_h
--- a/dom/performance/moz.build
+++ b/dom/performance/moz.build
@@ -1,39 +1,38 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-EXPORTS += [
-    'nsPerformance.h',
-]
-
 EXPORTS.mozilla.dom += [
+    'Performance.h',
     'PerformanceEntry.h',
     'PerformanceMark.h',
     'PerformanceMeasure.h',
     'PerformanceNavigation.h',
     'PerformanceObserver.h',
     'PerformanceObserverEntryList.h',
     'PerformanceResourceTiming.h',
     'PerformanceTiming.h',
 ]
 
 UNIFIED_SOURCES += [
-    'nsPerformance.cpp',
+    'Performance.cpp',
     'PerformanceEntry.cpp',
+    'PerformanceMainThread.cpp',
     'PerformanceMark.cpp',
     'PerformanceMeasure.cpp',
     'PerformanceNavigation.cpp',
     'PerformanceObserver.cpp',
     'PerformanceObserverEntryList.cpp',
     'PerformanceResourceTiming.cpp',
     'PerformanceTiming.cpp',
+    'PerformanceWorker.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/dom/workers',
 ]
 
 MOCHITEST_MANIFESTS += [ 'tests/mochitest.ini' ]
 
--- a/dom/webidl/Performance.webidl
+++ b/dom/webidl/Performance.webidl
@@ -27,48 +27,48 @@ partial interface Performance {
   readonly attribute PerformanceNavigation navigation;
 
   jsonifier;
 };
 
 // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
 [Exposed=(Window,Worker)]
 partial interface Performance {
-  [Func="nsPerformance::IsEnabled"]
+  [Func="Performance::IsEnabled"]
   PerformanceEntryList getEntries();
-  [Func="nsPerformance::IsEnabled"]
+  [Func="Performance::IsEnabled"]
   PerformanceEntryList getEntriesByType(DOMString entryType);
-  [Func="nsPerformance::IsEnabled"]
+  [Func="Performance::IsEnabled"]
   PerformanceEntryList getEntriesByName(DOMString name, optional DOMString
     entryType);
 };
 
 // http://www.w3.org/TR/resource-timing/#extensions-performance-interface
 [Exposed=Window]
 partial interface Performance {
-  [Func="nsPerformance::IsEnabled"]
+  [Func="Performance::IsEnabled"]
   void clearResourceTimings();
-  [Func="nsPerformance::IsEnabled"]
+  [Func="Performance::IsEnabled"]
   void setResourceTimingBufferSize(unsigned long maxSize);
-  [Func="nsPerformance::IsEnabled"]
+  [Func="Performance::IsEnabled"]
   attribute EventHandler onresourcetimingbufferfull;
 };
 
 // GC microbenchmarks, pref-guarded, not for general use (bug 1125412)
 [Exposed=Window]
 partial interface Performance {
   [Pref="dom.enable_memory_stats"]
   readonly attribute object mozMemory;
 };
 
 // http://www.w3.org/TR/user-timing/
 [Exposed=(Window,Worker)]
 partial interface Performance {
-  [Func="nsPerformance::IsEnabled", Throws]
+  [Func="Performance::IsEnabled", Throws]
   void mark(DOMString markName);
-  [Func="nsPerformance::IsEnabled"]
+  [Func="Performance::IsEnabled"]
   void clearMarks(optional DOMString markName);
-  [Func="nsPerformance::IsEnabled", Throws]
+  [Func="Performance::IsEnabled", Throws]
   void measure(DOMString measureName, optional DOMString startMark, optional DOMString endMark);
-  [Func="nsPerformance::IsEnabled"]
+  [Func="Performance::IsEnabled"]
   void clearMeasures(optional DOMString measureName);
 };
 
--- a/dom/webidl/PerformanceObserver.webidl
+++ b/dom/webidl/PerformanceObserver.webidl
@@ -8,16 +8,16 @@
  */
 
 dictionary PerformanceObserverInit {
   required sequence<DOMString> entryTypes;
 };
 
 callback PerformanceObserverCallback = void (PerformanceObserverEntryList entries, PerformanceObserver observer);
 
-[Func="nsPerformance::IsObserverEnabled",
+[Func="Performance::IsObserverEnabled",
  Constructor(PerformanceObserverCallback callback),
  Exposed=(Window,Worker)]
 interface PerformanceObserver {
   [Throws]
   void observe(PerformanceObserverInit options);
   void disconnect();
 };
--- a/dom/webidl/PerformanceObserverEntryList.webidl
+++ b/dom/webidl/PerformanceObserverEntryList.webidl
@@ -9,16 +9,16 @@
 
 // XXX should be moved into Performance.webidl.
 dictionary PerformanceEntryFilterOptions {
   DOMString name;
   DOMString entryType;
   DOMString initiatorType;
 };
 
-[Func="nsPerformance::IsObserverEnabled", Exposed=(Window,Worker)]
+[Func="Performance::IsObserverEnabled", Exposed=(Window,Worker)]
 interface PerformanceObserverEntryList {
   PerformanceEntryList getEntries(optional PerformanceEntryFilterOptions filter);
   PerformanceEntryList getEntriesByType(DOMString entryType);
   PerformanceEntryList getEntriesByName(DOMString name,
                                         optional DOMString entryType);
 };
 
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -25,17 +25,16 @@
 #include "nsITextToSubURI.h"
 #include "nsIThreadInternal.h"
 #include "nsITimer.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsIWorkerDebugger.h"
 #include "nsIXPConnect.h"
-#include "nsPerformance.h"
 #include "nsPIDOMWindow.h"
 
 #include <algorithm>
 #include "ImageContainer.h"
 #include "jsfriendapi.h"
 #include "js/MemoryMetrics.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
@@ -51,16 +50,17 @@
 #include "mozilla/dom/ExtendableMessageEventBinding.h"
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/IndexedDatabaseManager.h"
 #include "mozilla/dom/MessageEvent.h"
 #include "mozilla/dom/MessageEventBinding.h"
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/MessagePortBinding.h"
 #include "mozilla/dom/MessagePortList.h"
+#include "mozilla/dom/Performance.h"
 #include "mozilla/dom/PMessagePort.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseDebugging.h"
 #include "mozilla/dom/SimpleGlobalObject.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/StructuredCloneHolder.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/WorkerBinding.h"
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -11,16 +11,17 @@
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/Console.h"
 #include "mozilla/dom/DedicatedWorkerGlobalScopeBinding.h"
 #include "mozilla/dom/Fetch.h"
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/IDBFactory.h"
 #include "mozilla/dom/ImageBitmap.h"
 #include "mozilla/dom/ImageBitmapBinding.h"
+#include "mozilla/dom/Performance.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseWorkerProxy.h"
 #include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
 #include "mozilla/dom/SharedWorkerGlobalScopeBinding.h"
 #include "mozilla/dom/SimpleGlobalObject.h"
 #include "mozilla/dom/WorkerDebuggerGlobalScopeBinding.h"
 #include "mozilla/dom/WorkerGlobalScopeBinding.h"
 #include "mozilla/dom/WorkerLocation.h"
@@ -37,17 +38,16 @@
 #endif
 
 #include "Crypto.h"
 #include "Principal.h"
 #include "RuntimeService.h"
 #include "ScriptLoader.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
-#include "Performance.h"
 #include "ServiceWorkerClients.h"
 #include "ServiceWorkerManager.h"
 #include "ServiceWorkerRegistration.h"
 
 #ifdef XP_WIN
 #undef PostMessage
 #endif
 
@@ -354,17 +354,17 @@ WorkerGlobalScope::Dump(const Optional<n
 }
 
 Performance*
 WorkerGlobalScope::GetPerformance()
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
 
   if (!mPerformance) {
-    mPerformance = new Performance(mWorkerPrivate);
+    mPerformance = Performance::CreateForWorker(mWorkerPrivate);
   }
 
   return mPerformance;
 }
 
 already_AddRefed<Promise>
 WorkerGlobalScope::Fetch(const RequestOrUSVString& aInput,
                          const RequestInit& aInit, ErrorResult& aRv)
--- a/dom/workers/WorkerScope.h
+++ b/dom/workers/WorkerScope.h
@@ -19,16 +19,17 @@ namespace dom {
 
 class AnyCallback;
 struct ChannelPixelLayout;
 class Console;
 class Crypto;
 class Function;
 class IDBFactory;
 enum class ImageBitmapFormat : uint32_t;
+class Performance;
 class Promise;
 class RequestOrUSVString;
 class ServiceWorkerRegistrationWorkerThread;
 class WorkerLocation;
 class WorkerNavigator;
 
 namespace cache {
 
@@ -37,17 +38,16 @@ class CacheStorage;
 } // namespace cache
 } // namespace dom
 } // namespace mozilla
 
 BEGIN_WORKERS_NAMESPACE
 
 class ServiceWorkerClients;
 class WorkerPrivate;
-class Performance;
 
 class WorkerGlobalScope : public DOMEventTargetHelper,
                           public nsIGlobalObject,
                           public nsSupportsWeakReference
 {
   typedef mozilla::dom::IDBFactory IDBFactory;
 
   RefPtr<Console> mConsole;
--- a/dom/workers/moz.build
+++ b/dom/workers/moz.build
@@ -27,17 +27,16 @@ EXPORTS.mozilla.dom.workers += [
     'ServiceWorkerManager.h',
     'ServiceWorkerRegistrationInfo.h',
     'WorkerDebuggerManager.h',
     'Workers.h',
 ]
 
 # Stuff needed for the bindings, not really public though.
 EXPORTS.mozilla.dom.workers.bindings += [
-    'Performance.h',
     'ServiceWorker.h',
     'ServiceWorkerClient.h',
     'ServiceWorkerClients.h',
     'ServiceWorkerWindowClient.h',
     'SharedWorker.h',
     'URL.h',
     'WorkerFeature.h',
     'XMLHttpRequest.h',
@@ -49,17 +48,16 @@ XPIDL_MODULE = 'dom_workers'
 XPIDL_SOURCES += [
     'nsIWorkerDebugger.idl',
     'nsIWorkerDebuggerManager.idl',
 ]
 
 UNIFIED_SOURCES += [
     'ChromeWorkerScope.cpp',
     'FileReaderSync.cpp',
-    'Performance.cpp',
     'Principal.cpp',
     'RegisterBindings.cpp',
     'RuntimeService.cpp',
     'ScriptLoader.cpp',
     'ServiceWorker.cpp',
     'ServiceWorkerClient.cpp',
     'ServiceWorkerClients.cpp',
     'ServiceWorkerContainer.cpp',
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -123,17 +123,17 @@
 #include "gfxUtils.h"
 #include "nsSMILAnimationController.h"
 #include "SVGContentUtils.h"
 #include "nsSVGEffects.h"
 #include "SVGFragmentIdentifier.h"
 #include "nsArenaMemoryStats.h"
 #include "nsFrameSelection.h"
 
-#include "nsPerformance.h"
+#include "mozilla/dom/Performance.h"
 #include "nsRefreshDriver.h"
 #include "nsDOMNavigationTiming.h"
 
 // Drag & Drop, Clipboard
 #include "nsIDocShellTreeItem.h"
 #include "nsIURI.h"
 #include "nsIScrollableFrame.h"
 #include "nsITimer.h"
@@ -9412,17 +9412,17 @@ PresShell::DidDoReflow(bool aInterruptib
 }
 
 DOMHighResTimeStamp
 PresShell::GetPerformanceNow()
 {
   DOMHighResTimeStamp now = 0;
 
   if (nsPIDOMWindowInner* window = mDocument->GetInnerWindow()) {
-    nsPerformance* perf = window->GetPerformance();
+    Performance* perf = window->GetPerformance();
 
     if (perf) {
       now = perf->Now();
     }
   }
 
   return now;
 }
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -39,17 +39,17 @@
 #include "nsIDocument.h"
 #include "jsapi.h"
 #include "nsContentUtils.h"
 #include "mozilla/PendingAnimationTracker.h"
 #include "mozilla/Preferences.h"
 #include "nsViewManager.h"
 #include "GeckoProfiler.h"
 #include "nsNPAPIPluginInstance.h"
-#include "nsPerformance.h"
+#include "mozilla/dom/Performance.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "mozilla/RestyleManager.h"
 #include "mozilla/RestyleManagerHandle.h"
 #include "mozilla/RestyleManagerHandleInlines.h"
 #include "Layers.h"
 #include "imgIContainer.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "nsDocShell.h"
@@ -1600,17 +1600,17 @@ nsRefreshDriver::RunFrameRequestCallback
     profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_START);
     for (const DocumentFrameCallbacks& docCallbacks : frameRequestCallbacks) {
       // XXXbz Bug 863140: GetInnerWindow can return the outer
       // window in some cases.
       nsPIDOMWindowInner* innerWindow =
         docCallbacks.mDocument->GetInnerWindow();
       DOMHighResTimeStamp timeStamp = 0;
       if (innerWindow && innerWindow->IsInnerWindow()) {
-        nsPerformance* perf = innerWindow->GetPerformance();
+        mozilla::dom::Performance* perf = innerWindow->GetPerformance();
         if (perf) {
           timeStamp = perf->GetDOMTiming()->TimeStampToDOMHighRes(aNowTime);
         }
         // else window is partially torn down already
       }
       for (auto& callback : docCallbacks.mCallbacks) {
         callback->Call(timeStamp);
       }
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -50,19 +50,19 @@
 #ifdef XP_WIN
 // We need to undef the MS macro for nsIDocument::CreateEvent
 #ifdef CreateEvent
 #undef CreateEvent
 #endif
 #endif // XP_WIN
 
 #include "nsIDocument.h"
-#include "nsPerformance.h"
 #include "nsGlobalWindow.h"
 #include "nsDOMDataChannel.h"
+#include "mozilla/dom/Performance.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/PublicSSL.h"
 #include "nsXULAppAPI.h"
 #include "nsContentUtils.h"
 #include "nsDOMJSUtils.h"
 #include "nsIScriptError.h"
@@ -2088,17 +2088,17 @@ PeerConnectionImpl::SetRemoteDescription
 }
 
 // WebRTC uses highres time relative to the UNIX epoch (Jan 1, 1970, UTC).
 
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
 nsresult
 PeerConnectionImpl::GetTimeSinceEpoch(DOMHighResTimeStamp *result) {
   MOZ_ASSERT(NS_IsMainThread());
-  nsPerformance *perf = mWindow->GetPerformance();
+  Performance *perf = mWindow->GetPerformance();
   NS_ENSURE_TRUE(perf && perf->Timing(), NS_ERROR_UNEXPECTED);
   *result = perf->Now() + perf->Timing()->NavigationStart();
   return NS_OK;
 }
 
 class RTCStatsReportInternalConstruct : public RTCStatsReportInternal {
 public:
   RTCStatsReportInternalConstruct(const nsString &pcid, DOMHighResTimeStamp now) {
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -33,18 +33,18 @@
 #include "nsIStreamConverterService.h"
 #include "nsCRT.h"
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIObserverService.h"
 #include "nsProxyRelease.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDocShell.h"
-#include "nsPerformance.h"
 #include "nsINetworkInterceptController.h"
+#include "mozilla/dom/Performance.h"
 #include "mozIThirdPartyUtil.h"
 #include "nsStreamUtils.h"
 #include "nsContentSecurityManager.h"
 #include "nsIChannelEventSink.h"
 #include "nsILoadGroupChild.h"
 #include "mozilla/ConsoleReportCollector.h"
 #include "LoadInfo.h"
 #include "nsISSLSocketControl.h"
@@ -3335,20 +3335,20 @@ IMPL_TIMING_ATTR(ResponseStart)
 IMPL_TIMING_ATTR(ResponseEnd)
 IMPL_TIMING_ATTR(CacheReadStart)
 IMPL_TIMING_ATTR(CacheReadEnd)
 IMPL_TIMING_ATTR(RedirectStart)
 IMPL_TIMING_ATTR(RedirectEnd)
 
 #undef IMPL_TIMING_ATTR
 
-nsPerformance*
+mozilla::dom::Performance*
 HttpBaseChannel::GetPerformance()
 {
-  // If performance timing is disabled, there is no need for the nsPerformance
+  // If performance timing is disabled, there is no need for the Performance
   // object anymore.
   if (!mTimingEnabled) {
     return nullptr;
   }
 
   // There is no point in continuing, since the performance object in the parent
   // isn't the same as the one in the child which will be reporting resource performance.
   if (XRE_IsParentProcess() && BrowserTabsRemoteAutostart()) {
@@ -3375,17 +3375,17 @@ HttpBaseChannel::GetPerformance()
     return nullptr;
   }
 
   nsCOMPtr<nsPIDOMWindowInner> innerWindow = loadingDocument->GetInnerWindow();
   if (!innerWindow) {
     return nullptr;
   }
 
-  nsPerformance* docPerformance = innerWindow->GetPerformance();
+  mozilla::dom::Performance* docPerformance = innerWindow->GetPerformance();
   if (!docPerformance) {
     return nullptr;
   }
 
   return docPerformance;
 }
 
 nsIURI*
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -39,22 +39,25 @@
 #include "PrivateBrowsingChannel.h"
 #include "mozilla/net/DNS.h"
 #include "nsITimedChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsISecurityConsoleMessage.h"
 #include "nsCOMArray.h"
 #include "mozilla/net/ChannelEventQueue.h"
 
-class nsPerformance;
 class nsISecurityConsoleMessage;
 class nsIPrincipal;
 
 namespace mozilla {
 
+namespace dom {
+class Performance;
+}
+
 class LogCollector;
 
 namespace net {
 extern mozilla::LazyLogModule gHttpLog;
 
 /*
  * This class is a partial implementation of nsIHttpChannel.  It contains code
  * shared by nsHttpChannel and HttpChannelChild.
@@ -316,17 +319,17 @@ protected:
 
   // Handle notifying listener, removing from loadgroup if request failed.
   void     DoNotifyListener();
   virtual void DoNotifyListenerCleanup() = 0;
 
   // drop reference to listener, its callbacks, and the progress sink
   void ReleaseListeners();
 
-  nsPerformance* GetPerformance();
+  mozilla::dom::Performance* GetPerformance();
   nsIURI* GetReferringPage();
   nsPIDOMWindowInner* GetInnerDOMWindow();
 
   void AddCookiesToRequest();
   virtual nsresult SetupReplacementChannel(nsIURI *,
                                            nsIChannel *,
                                            bool preserveMethod,
                                            uint32_t redirectFlags);
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -19,25 +19,25 @@
 
 #include "nsISupportsPrimitives.h"
 #include "nsChannelClassifier.h"
 #include "nsStringStream.h"
 #include "nsHttpHandler.h"
 #include "nsNetUtil.h"
 #include "nsSerializationHelper.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/dom/Performance.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/net/ChannelDiverterChild.h"
 #include "mozilla/net/DNS.h"
 #include "SerializedLoadContext.h"
 #include "nsInputStreamPump.h"
 #include "InterceptedChannel.h"
-#include "nsPerformance.h"
 #include "mozIThirdPartyUtil.h"
 #include "nsContentSecurityManager.h"
 #include "nsIDeprecationWarner.h"
 #include "nsICompressConvStats.h"
 #include "nsStreamUtils.h"
 
 #ifdef OS_POSIX
 #include "chrome/common/file_descriptor_set_posix.h"
@@ -884,17 +884,17 @@ HttpChannelChild::OnStopRequest(const ns
   mRedirectEndTimeStamp = timing.redirectEnd;
   mTransferSize = timing.transferSize;
   mEncodedBodySize = timing.encodedBodySize;
   mProtocolVersion = timing.protocolVersion;
 
   mCacheReadStart = timing.cacheReadStart;
   mCacheReadEnd = timing.cacheReadEnd;
 
-  nsPerformance* documentPerformance = GetPerformance();
+  Performance* documentPerformance = GetPerformance();
   if (documentPerformance) {
       documentPerformance->AddEntry(this, this);
   }
 
   DoPreOnStopRequest(channelStatus);
 
   { // We must flush the queue before we Send__delete__
     // (although we really shouldn't receive any msgs after OnStop),
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -74,18 +74,18 @@
 #include "nsIPrompt.h"
 #include "nsInputStreamPump.h"
 #include "nsURLHelper.h"
 #include "nsISocketTransport.h"
 #include "nsIStreamConverterService.h"
 #include "nsISiteSecurityService.h"
 #include "nsString.h"
 #include "nsCRT.h"
-#include "nsPerformance.h"
 #include "CacheObserver.h"
+#include "mozilla/dom/Performance.h"
 #include "mozilla/Telemetry.h"
 #include "AlternateServices.h"
 #include "InterceptedChannel.h"
 #include "nsIHttpPushListener.h"
 #include "nsIX509Cert.h"
 #include "ScopedNSSTypes.h"
 #include "nsNullPrincipal.h"
 #include "nsIPackagedAppService.h"
@@ -6388,17 +6388,17 @@ nsHttpChannel::OnStopRequest(nsIRequest 
         // Old implementation checks on nsICache::ACCESS_WRITE flag.
         mCacheEntry->HasWriteAccess(!mCacheEntryIsReadOnly, &writeAccess);
         if (writeAccess) {
             FinalizeCacheEntry();
         }
     }
 
     // Register entry to the Performance resource timing
-    nsPerformance* documentPerformance = GetPerformance();
+    mozilla::dom::Performance* documentPerformance = GetPerformance();
     if (documentPerformance) {
         documentPerformance->AddEntry(this, this);
     }
 
     if (mListener) {
         LOG(("  calling OnStopRequest\n"));
         MOZ_ASSERT(!mOnStopRequestCalled,
                    "We should not call OnStopRequest twice");
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -533,17 +533,17 @@ nsHttpTransaction::OnTransportStatus(nsI
             socketTransport->GetPeerAddr(&mPeerAddr);
         }
     }
 
     // If the timing is enabled, and we are not using a persistent connection
     // then the requestStart timestamp will be null, so we mark the timestamps
     // for domainLookupStart/End and connectStart/End
     // If we are using a persistent connection they will remain null,
-    // and the correct value will be returned in nsPerformance.
+    // and the correct value will be returned in Performance.
     if (TimingEnabled() && GetRequestStart().IsNull()) {
         if (status == NS_NET_STATUS_RESOLVING_HOST) {
             SetDomainLookupStart(TimeStamp::Now(), true);
         } else if (status == NS_NET_STATUS_RESOLVED_HOST) {
             SetDomainLookupEnd(TimeStamp::Now());
         } else if (status == NS_NET_STATUS_CONNECTING_TO) {
             SetConnectStart(TimeStamp::Now());
         } else if (status == NS_NET_STATUS_CONNECTED_TO) {