Bug 1722261 - RegisteredThread is now effectively unused, remove all remaining traces - r=canaltinova
authorGerald Squelart <gsquelart@mozilla.com>
Tue, 24 Aug 2021 04:47:24 +0000
changeset 589677 12796ed8484e8fd56b5c87d7a11fb0dda3f01492
parent 589676 48dde63f0b08ab652050aa58c248498e0689d779
child 589678 0f2b8fd64be8154200861cfeb6a95479c8347e47
push id38731
push usercbrindusan@mozilla.com
push dateTue, 24 Aug 2021 09:47:24 +0000
treeherdermozilla-central@7857f4c37a92 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscanaltinova
bugs1722261
milestone93.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 1722261 - RegisteredThread is now effectively unused, remove all remaining traces - r=canaltinova Differential Revision: https://phabricator.services.mozilla.com/D121978
tools/profiler/core/RegisteredThread.cpp
tools/profiler/core/RegisteredThread.h
tools/profiler/core/platform.cpp
tools/profiler/moz.build
tools/profiler/public/ProfilerThreadRegistration.h
tools/profiler/public/ProfilerThreadRegistrationData.h
deleted file mode 100644
--- a/tools/profiler/core/RegisteredThread.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; 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 "RegisteredThread.h"
-
-#include "mozilla/ProfilerMarkers.h"
-#include "js/AllocationRecording.h"
-#include "js/ProfilingStack.h"
-#include "js/TraceLoggerAPI.h"
-#include "mozilla/ProfilerThreadRegistrationData.h"
-
-RacyRegisteredThread::RacyRegisteredThread(
-    mozilla::profiler::ThreadRegistration& aThreadRegistration)
-    : mThreadRegistration(aThreadRegistration) {
-  MOZ_COUNT_CTOR(RacyRegisteredThread);
-}
-
-RegisteredThread::RegisteredThread(
-    mozilla::profiler::ThreadRegistration& aThreadRegistration)
-    : mRacyRegisteredThread(aThreadRegistration) {
-  MOZ_COUNT_CTOR(RegisteredThread);
-
-  // NOTE: aThread can be null for the first thread, before the ThreadManager
-  // is initialized.
-}
-
-RegisteredThread::~RegisteredThread() { MOZ_COUNT_DTOR(RegisteredThread); }
-
-size_t RegisteredThread::SizeOfIncludingThis(
-    mozilla::MallocSizeOf aMallocSizeOf) const {
-  size_t n = aMallocSizeOf(this);
-
-  // The following members are not measured:
-  // - mThreadInfo: because it is non-owning
-
-  return n;
-}
-
-const RacyRegisteredThread& mozilla::profiler::
-    ThreadRegistrationUnlockedConstReader::RacyRegisteredThreadCRef() const {
-  MOZ_ASSERT(mRegisteredThread);
-  return mRegisteredThread->RacyRegisteredThread();
-}
-
-RacyRegisteredThread&
-mozilla::profiler::ThreadRegistrationUnlockedConstReaderAndAtomicRW::
-    RacyRegisteredThreadRef() {
-  MOZ_ASSERT(mRegisteredThread);
-  return mRegisteredThread->RacyRegisteredThread();
-}
-
-RegisteredThread& mozilla::profiler::ThreadRegistrationLockedRWFromAnyThread::
-    RegisteredThreadRef() {
-  MOZ_ASSERT(mRegisteredThread);
-  return *mRegisteredThread;
-}
-
-void mozilla::profiler::ThreadRegistrationLockedRWOnThread::SetRegisteredThread(
-    RegisteredThread* aRegisteredThread) {
-  mRegisteredThread = aRegisteredThread;
-}
deleted file mode 100644
--- a/tools/profiler/core/RegisteredThread.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; 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 RegisteredThread_h
-#define RegisteredThread_h
-
-#include "platform.h"
-
-#include "mozilla/NotNull.h"
-#include "mozilla/ProfilerThreadRegistration.h"
-#include "mozilla/RefPtr.h"
-#include "nsIEventTarget.h"
-#include "nsIThread.h"
-
-class ProfilingStack;
-
-// This class contains the state for a single thread that is accessible without
-// protection from gPSMutex in platform.cpp. Because there is no external
-// protection against data races, it must provide internal protection. Hence
-// the "Racy" prefix.
-//
-class RacyRegisteredThread final {
- public:
-  explicit RacyRegisteredThread(
-      mozilla::profiler::ThreadRegistration& aThreadRegistration);
-
-  MOZ_COUNTED_DTOR(RacyRegisteredThread)
-
-  mozilla::profiler::ThreadRegistration& mThreadRegistration;
-};
-
-// This class contains information that's relevant to a single thread only
-// while that thread is running and registered with the profiler, but
-// regardless of whether the profiler is running. All accesses to it are
-// protected by the profiler state lock.
-class RegisteredThread final {
- public:
-  explicit RegisteredThread(
-      mozilla::profiler::ThreadRegistration& aThreadRegistration);
-  ~RegisteredThread();
-
-  class RacyRegisteredThread& RacyRegisteredThread() {
-    return mRacyRegisteredThread;
-  }
-  const class RacyRegisteredThread& RacyRegisteredThread() const {
-    return mRacyRegisteredThread;
-  }
-
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
-
- private:
-  class RacyRegisteredThread mRacyRegisteredThread;
-};
-
-#endif  // RegisteredThread_h
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -33,17 +33,16 @@
 #include "PageInformation.h"
 #include "ProfileBuffer.h"
 #include "ProfiledThreadData.h"
 #include "ProfilerBacktrace.h"
 #include "ProfilerChild.h"
 #include "ProfilerCodeAddressService.h"
 #include "ProfilerIOInterposeObserver.h"
 #include "ProfilerParent.h"
-#include "RegisteredThread.h"
 #include "shared-libraries.h"
 #include "VTuneProfiler.h"
 
 #include "js/TraceLoggerAPI.h"
 #include "js/ProfilingFrameIterator.h"
 #include "memory_hooks.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Atomics.h"
@@ -354,19 +353,16 @@ using JsFrameBuffer = JS::ProfilingFrame
 // locked. This makes it clear when gPSMutex is locked and helps avoid
 // accidental unlocked accesses to global state. There are ways to circumvent
 // this mechanism, but please don't do so without *very* good reason and a
 // detailed explanation.
 //
 // The exceptions to this rule:
 //
 // - mProcessStartTime, because it's immutable;
-//
-// - each thread's RacyRegisteredThread object is accessible without locking via
-//   TLSRegisteredThread::RacyRegisteredThread().
 class CorePS {
  private:
   CorePS()
       : mProcessStartTime(TimeStamp::ProcessCreation()),
         // This needs its own mutex, because it is used concurrently from
         // functions guarded by gPSMutex as well as others without safety (e.g.,
         // profiler_add_marker). It is *not* used inside the critical section of
         // the sampler, because mutexes cannot be used there.
@@ -402,28 +398,22 @@ class CorePS {
   static void AddSizeOf(PSLockRef, MallocSizeOf aMallocSizeOf,
                         size_t& aProfSize, size_t& aLulSize) {
     MOZ_ASSERT(sInstance);
 
     aProfSize += aMallocSizeOf(sInstance);
 
     aProfSize += ThreadRegistry::SizeOfIncludingThis(aMallocSizeOf);
 
-    for (auto& registeredThread : sInstance->mRegisteredThreads) {
-      aProfSize += registeredThread->SizeOfIncludingThis(aMallocSizeOf);
-    }
-
     for (auto& registeredPage : sInstance->mRegisteredPages) {
       aProfSize += registeredPage->SizeOfIncludingThis(aMallocSizeOf);
     }
 
     // Measurement of the following things may be added later if DMD finds it
     // is worthwhile:
-    // - CorePS::mRegisteredThreads itself (its elements' children are
-    // measured above)
     // - CorePS::mRegisteredPages itself (its elements' children are
     // measured above)
     // - CorePS::mInterposeObserver
 
 #if defined(USE_LUL_STACKWALK)
     if (sInstance->mLul) {
       aLulSize += sInstance->mLul->SizeOfIncludingThis(aMallocSizeOf);
     }
@@ -431,39 +421,18 @@ class CorePS {
   }
 
   // No PSLockRef is needed for this field because it's immutable.
   PS_GET_LOCKLESS(TimeStamp, ProcessStartTime)
 
   // No PSLockRef is needed for this field because it's thread-safe.
   PS_GET_LOCKLESS(ProfileChunkedBuffer&, CoreBuffer)
 
-  PS_GET(const Vector<UniquePtr<RegisteredThread>>&, RegisteredThreads)
-
   PS_GET(JsFrameBuffer&, JsFrames)
 
-  static void AppendRegisteredThread(
-      PSLockRef, UniquePtr<RegisteredThread>&& aRegisteredThread) {
-    MOZ_ASSERT(sInstance);
-    MOZ_RELEASE_ASSERT(
-        sInstance->mRegisteredThreads.append(std::move(aRegisteredThread)));
-  }
-
-  static void RemoveRegisteredThread(PSLockRef,
-                                     RegisteredThread* aRegisteredThread) {
-    MOZ_ASSERT(sInstance);
-    // Remove aRegisteredThread from mRegisteredThreads.
-    for (UniquePtr<RegisteredThread>& rt : sInstance->mRegisteredThreads) {
-      if (rt.get() == aRegisteredThread) {
-        sInstance->mRegisteredThreads.erase(&rt);
-        return;
-      }
-    }
-  }
-
   PS_GET(Vector<RefPtr<PageInformation>>&, RegisteredPages)
 
   static void AppendRegisteredPage(PSLockRef,
                                    RefPtr<PageInformation>&& aRegisteredPage) {
     MOZ_ASSERT(sInstance);
     struct RegisteredPageComparator {
       PageInformation* aA;
       bool operator()(PageInformation* aB) const { return aA->Equals(aB); }
@@ -550,20 +519,16 @@ class CorePS {
   // ActivePS does not exist, mCoreBuffer is empty and rejects all reads&writes;
   // see ActivePS for further details.
   // Note: This needs to live here outside of ActivePS, because some producers
   // are indirectly controlled (e.g., by atomic flags) and therefore may still
   // attempt to write some data shortly after ActivePS has shutdown and deleted
   // the underlying buffer in memory.
   ProfileChunkedBuffer mCoreBuffer;
 
-  // Info on all the registered threads.
-  // ThreadIds in mRegisteredThreads are unique.
-  Vector<UniquePtr<RegisteredThread>> mRegisteredThreads;
-
   // Info on all the registered pages.
   // InnerWindowIDs in mRegisteredPages are unique.
   Vector<RefPtr<PageInformation>> mRegisteredPages;
 
   // Non-owning pointers to all active counters
   Vector<BaseProfilerCount*> mCounters;
 
 #ifdef USE_LUL_STACKWALK
@@ -1443,92 +1408,16 @@ static void invoke_profiler_state_change
     if (idedCallback->mProfilingStateSet.contains(aProfilingState)) {
       idedCallback->mProfilingStateChangeCallback(aProfilingState);
     }
   }
 }
 
 Atomic<uint32_t, MemoryOrdering::Relaxed> RacyFeatures::sActiveAndFeatures(0);
 
-// Each live thread has a RegisteredThread, and we store a reference to it in
-// TLS. This class encapsulates that TLS, and also handles the associated
-// profiling stack used by AutoProfilerLabel.
-class TLSRegisteredThread {
- public:
-  // This should only be called once before any other access.
-  // In this case it's called from `profiler_init()` on the main thread, before
-  // the main thread registers itself.
-  static void Init() {
-    MOZ_ASSERT(sState == State::Uninitialized, "Already initialized");
-    sState = sRegisteredThread.init() ? State::Initialized : State::Unavailable;
-  }
-
-  static bool IsTLSInited() {
-    MOZ_ASSERT(sState != State::Uninitialized,
-               "TLSRegisteredThread should only be accessed after Init()");
-    return sState == State::Initialized;
-  }
-
-  // Get the entire RegisteredThread. Accesses are guarded by gPSMutex.
-  static class RegisteredThread* RegisteredThread(PSLockRef) {
-    if (!IsTLSInited()) {
-      return nullptr;
-    }
-    return sRegisteredThread.get();
-  }
-
-  // Get only the RacyRegisteredThread. Accesses are not guarded by gPSMutex.
-  static class RacyRegisteredThread* RacyRegisteredThread() {
-    if (!IsTLSInited()) {
-      return nullptr;
-    }
-    class RegisteredThread* registeredThread = sRegisteredThread.get();
-    return registeredThread ? &registeredThread->RacyRegisteredThread()
-                            : nullptr;
-  }
-
-  static void SetRegisteredThread(PSLockRef,
-                                  class RegisteredThread* aRegisteredThread) {
-    if (!IsTLSInited()) {
-      return;
-    }
-    MOZ_RELEASE_ASSERT(
-        aRegisteredThread,
-        "Use ResetRegisteredThread() instead of SetRegisteredThread(nullptr)");
-    sRegisteredThread.set(aRegisteredThread);
-  }
-
-  static void ResetRegisteredThread(PSLockRef) {
-    if (!IsTLSInited()) {
-      return;
-    }
-    sRegisteredThread.set(nullptr);
-  }
-
- private:
-  // Only written once from `profiler_init` calling
-  // `TLSRegisteredThread::Init()`; all reads should only happen after `Init()`,
-  // so there is no need to make it atomic.
-  enum class State { Uninitialized = 0, Initialized, Unavailable };
-  static State sState;
-
-  // This is a non-owning reference to the RegisteredThread;
-  // CorePS::mRegisteredThreads is the owning reference. On thread
-  // deregistration, this reference is cleared and the RegisteredThread is
-  // destroyed.
-  static MOZ_THREAD_LOCAL(class RegisteredThread*) sRegisteredThread;
-};
-
-// Zero-initialized to State::Uninitialized.
-/* static */
-TLSRegisteredThread::State TLSRegisteredThread::sState;
-
-/* static */
-MOZ_THREAD_LOCAL(RegisteredThread*) TLSRegisteredThread::sRegisteredThread;
-
 // The name of the main thread.
 static const char* const kMainThreadName = "GeckoMain";
 
 ////////////////////////////////////////////////////////////////////////
 // BEGIN sampling/unwinding code
 
 // The registers used for stack unwinding and a few other sampling purposes.
 // The ctor does nothing; users are responsible for filling in the fields.
@@ -4085,95 +3974,53 @@ uint32_t ParseFeaturesFromStringArray(co
                                       bool aIsStartup /* = false */) {
   uint32_t features = 0;
   for (size_t i = 0; i < aFeatureCount; i++) {
     features |= ParseFeature(aFeatures[i], aIsStartup);
   }
   return features;
 }
 
-static bool IsRegisteredThreadInRegisteredThreadsList(
-    PSLockRef aLock, RegisteredThread* aThread) {
-  const auto& registeredThreads = CorePS::RegisteredThreads(aLock);
-  for (const auto& registeredThread : registeredThreads) {
-    if (registeredThread.get() == aThread) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
 static ProfilingStack* locked_register_thread(
     PSLockRef aLock, ThreadRegistry::OffThreadRef aOffThreadRef) {
   MOZ_RELEASE_ASSERT(CorePS::Exists());
 
   VTUNE_REGISTER_THREAD(aOffThreadRef.UnlockedConstReaderCRef().Info().Name());
 
-  if (!TLSRegisteredThread::IsTLSInited()) {
-    return nullptr;
-  }
-
-  // Temporary hack: Ugly-copy ThreadRegistration* from inside aOffThreadRef!
-  ThreadRegistration* tr;
-  static_assert(sizeof(tr) == sizeof(aOffThreadRef));
-  memcpy(&tr, &aOffThreadRef, sizeof(tr));
-  UniquePtr<RegisteredThread> registeredThread =
-      MakeUnique<RegisteredThread>(*tr);
-
-  TLSRegisteredThread::SetRegisteredThread(aLock, registeredThread.get());
-
-  ThreadRegistry::OffThreadRef::RWFromAnyThreadWithLock lockedRWFromAnyThread =
-      aOffThreadRef.LockedRWFromAnyThread();
-
-  ThreadRegistration::LockedRWOnThread* lockedRWOnThread =
-      lockedRWFromAnyThread.GetLockedRWOnThread();
-  MOZ_RELEASE_ASSERT(
-      lockedRWOnThread,
-      "At the moment, we should only get here when registering the current "
-      "thread (either through profiler_register_thread or from profiler_init "
-      "on the main thread registering that main thread). But in the future "
-      "this may be done for other already-registered threads, so we need to "
-      "null-check the pointer in long-term code below.");
-  lockedRWOnThread->SetRegisteredThread(registeredThread.get());
-
   if (ActivePS::Exists(aLock) &&
       ActivePS::ShouldProfileThread(
           aLock, aOffThreadRef.UnlockedConstReaderCRef().Info())) {
+    ThreadRegistry::OffThreadRef::RWFromAnyThreadWithLock
+        lockedRWFromAnyThread = aOffThreadRef.LockedRWFromAnyThread();
+
     nsCOMPtr<nsIEventTarget> eventTarget =
         lockedRWFromAnyThread->GetEventTarget();
     ProfiledThreadData* profiledThreadData = ActivePS::AddLiveProfiledThread(
         aLock,
         MakeUnique<ProfiledThreadData>(
             aOffThreadRef.UnlockedConstReaderCRef().Info(), eventTarget));
     lockedRWFromAnyThread->SetIsBeingProfiledWithProfiledThreadData(
         profiledThreadData, aLock);
 
     if (ActivePS::FeatureJS(aLock)) {
       lockedRWFromAnyThread->StartJSSampling(ActivePS::JSFlags(aLock));
-      if (lockedRWOnThread) {
+      if (ThreadRegistration::LockedRWOnThread* lockedRWOnThread =
+              lockedRWFromAnyThread.GetLockedRWOnThread();
+          lockedRWOnThread) {
         // We can manually poll the current thread so it starts sampling
         // immediately.
         lockedRWOnThread->PollJSSampling();
       }
       if (lockedRWFromAnyThread->GetJSContext()) {
         profiledThreadData->NotifyReceivedJSContext(
             ActivePS::Buffer(aLock).BufferRangeEnd());
       }
     }
   }
 
-  MOZ_RELEASE_ASSERT(TLSRegisteredThread::RegisteredThread(aLock),
-                     "TLS should be set when registering thread");
-  MOZ_RELEASE_ASSERT(
-      registeredThread == TLSRegisteredThread::RegisteredThread(aLock),
-      "TLS should be set as expected when registering thread");
-
-  CorePS::AppendRegisteredThread(aLock, std::move(registeredThread));
-
   return &aOffThreadRef.UnlockedConstReaderAndAtomicRWRef().ProfilingStackRef();
 }
 
 static void NotifyObservers(const char* aTopic,
                             nsISupports* aSubject = nullptr) {
   if (!NS_IsMainThread()) {
     // Dispatch a task to the main thread that notifies observers.
     // If NotifyObservers is called both on and off the main thread within a
@@ -4283,19 +4130,16 @@ void profiler_init(void* aStackTop) {
   VTUNE_INIT();
 
   MOZ_RELEASE_ASSERT(!CorePS::Exists());
 
   if (getenv("MOZ_PROFILER_HELP")) {
     PrintUsageThenExit(1);  // terminates execution
   }
 
-  // This must be before any TLS access (e.g.: Thread registration, labels...).
-  TLSRegisteredThread::Init();
-
   SharedLibraryInfo::Initialize();
 
   uint32_t features = DefaultFeatures() & AvailableFeatures();
 
   UniquePtr<char[]> filterStorage;
 
   Vector<const char*> filters;
   MOZ_RELEASE_ASSERT(filters.append("GeckoMain"));
@@ -5444,67 +5288,41 @@ void ThreadRegistry::Register(ThreadRegi
 
 void profiler_unregister_thread() {
   // This will call `ThreadRegistry::Unregister()` (see below).
   ThreadRegistration::UnregisterThread();
 }
 
 static void locked_unregister_thread(
     PSLockRef lock, ThreadRegistration::OnThreadRef aOnThreadRef) {
-  if (!TLSRegisteredThread::IsTLSInited()) {
-    return;
-  }
-
   if (!CorePS::Exists()) {
     // This function can be called after the main thread has already shut
     // down.
     return;
   }
 
-  // We don't call RegisteredThread::StopJSSampling() here; there's no point
-  // doing that for a JS thread that is in the process of disappearing.
+  // We don't call StopJSSampling() here; there's no point doing that for a JS
+  // thread that is in the process of disappearing.
 
   ThreadRegistration::OnThreadRef::RWOnThreadWithLock lockedThreadData =
       aOnThreadRef.LockedRWOnThread();
 
-  RegisteredThread* registeredThread = &lockedThreadData->RegisteredThreadRef();
-
   ProfiledThreadData* profiledThreadData =
       lockedThreadData->GetProfiledThreadData(lock);
   lockedThreadData->ClearIsBeingProfiledAndProfiledThreadData(lock);
-  lockedThreadData->SetRegisteredThread(nullptr);
-
-  MOZ_RELEASE_ASSERT(
-      IsRegisteredThreadInRegisteredThreadsList(lock, registeredThread),
-      "Thread being unregistered is not in registered thread list even "
-      "though its TLS is non-null");
+
   MOZ_RELEASE_ASSERT(
       lockedThreadData->Info().ThreadId() == profiler_current_thread_id(),
       "Thread being unregistered has changed its TID");
 
   DEBUG_LOG("profiler_unregister_thread: %s", lockedThreadData->Info().Name());
 
   if (profiledThreadData && ActivePS::Exists(lock)) {
     ActivePS::UnregisterThread(lock, profiledThreadData);
   }
-
-  // Clear the pointer to the RegisteredThread object that we're about to
-  // destroy.
-  TLSRegisteredThread::ResetRegisteredThread(lock);
-
-  // Remove the thread from the list of registered threads. This deletes the
-  // registeredThread object.
-  CorePS::RemoveRegisteredThread(lock, registeredThread);
-
-  MOZ_RELEASE_ASSERT(
-      !IsRegisteredThreadInRegisteredThreadsList(lock, registeredThread),
-      "After unregistering, thread should no longer be in the registered "
-      "thread list");
-  MOZ_RELEASE_ASSERT(!TLSRegisteredThread::RegisteredThread(lock),
-                     "TLS should have been reset after un-registering thread");
 }
 
 /* static */
 void ThreadRegistry::Unregister(ThreadRegistration::OnThreadRef aOnThreadRef) {
   PSAutoLock psLock;
   locked_unregister_thread(psLock, aOnThreadRef);
 
   LockedRegistry registryLock;
--- a/tools/profiler/moz.build
+++ b/tools/profiler/moz.build
@@ -20,17 +20,16 @@ if CONFIG["MOZ_GECKO_PROFILER"]:
         "core/PageInformation.cpp",
         "core/platform.cpp",
         "core/ProfileBuffer.cpp",
         "core/ProfileBufferEntry.cpp",
         "core/ProfiledThreadData.cpp",
         "core/ProfilerBacktrace.cpp",
         "core/ProfilerCodeAddressService.cpp",
         "core/ProfilerMarkers.cpp",
-        "core/RegisteredThread.cpp",
         "gecko/ChildProfilerController.cpp",
         "gecko/nsProfilerStartParams.cpp",
         "gecko/ProfilerChild.cpp",
         "gecko/ProfilerIOInterposeObserver.cpp",
     ]
     if CONFIG["MOZ_REPLACE_MALLOC"] and CONFIG["MOZ_PROFILER_MEMORY"]:
         SOURCES += [
             "core/memory_hooks.cpp",  # Non-unified because of order of #includes
--- a/tools/profiler/public/ProfilerThreadRegistration.h
+++ b/tools/profiler/public/ProfilerThreadRegistration.h
@@ -319,21 +319,16 @@ class ThreadRegistration {
     // allocations and static objects are not counted.
     return (mIsOnHeap ? aMallocSizeOf(this) : 0) +
            SizeOfExcludingThis(aMallocSizeOf);
   }
 
  private:
   friend class ThreadRegistry;
 
-  // Trust these to access mData.
-  // TODO: Remove when {,Racy}RegisteredThread are removed in a later patch.
-  friend class ::RacyRegisteredThread;
-  friend class ::RegisteredThread;
-
   // This is what is embedded inside ThreadRegistration.
   // References to sub-classes will be provided, to limit access as appropriate.
   class EmbeddedData final : public LockedRWOnThread {
    private:
     // Only ThreadRegistration can construct (its embedded) `mData`.
     friend class ThreadRegistration;
     EmbeddedData(const char* aName, const void* aStackTop)
         : LockedRWOnThread(aName, aStackTop) {}
--- a/tools/profiler/public/ProfilerThreadRegistrationData.h
+++ b/tools/profiler/public/ProfilerThreadRegistrationData.h
@@ -44,20 +44,16 @@
 #include "mozilla/ProfilerThreadRegistrationInfo.h"
 #include "nsCOMPtr.h"
 #include "nsIThread.h"
 
 class ProfiledThreadData;
 class PSAutoLock;
 struct JSContext;
 
-// TODO: Remove when {,Racy}RegisteredThread are removed in a later patch.
-class RacyRegisteredThread;
-class RegisteredThread;
-
 namespace mozilla::profiler {
 
 // All data members related to thread profiling are stored here.
 // See derived classes below, which give limited unlocked/locked read/write
 // access in different situations, and will be available through
 // ThreadRegistration and ThreadRegistry.
 class ThreadRegistrationData {
  public:
@@ -82,21 +78,16 @@ class ThreadRegistrationData {
   ~ThreadRegistrationData() {
     MOZ_ASSERT(mIsBeingProfiled == !!mProfiledThreadData);
     MOZ_ASSERT(!mProfiledThreadData,
                "mProfiledThreadData pointer should have been reset before "
                "~ThreadRegistrationData");
   }
 #endif  // DEBUG
 
-  // Trust these to access mData.
-  // TODO: Remove when {,Racy}RegisteredThread are removed in a later patch.
-  friend class ::RacyRegisteredThread;
-  friend class ::RegisteredThread;
-
   // Permanent thread information.
   // Set at construction, read from anywhere, moved-from at destruction.
   ThreadRegistrationInfo mInfo;
 
   // Contains profiler labels and JS frames.
   // Deep-written on thread only, deep-read from thread and suspended thread.
   ProfilingStack mProfilingStack;
 
@@ -226,35 +217,29 @@ class ThreadRegistrationData {
   // Read&written from thread and suspended thread.
   Atomic<int> mSleep{AWAKE};
 
   // If the profiler is active and this thread is selected for profiling, this
   // points at the relevant ProfiledThreadData.
   // Fully controlled by the profiler.
   // Invariant: `mIsBeingProfiled == !!mProfiledThreadData` (set together.)
   ProfiledThreadData* mProfiledThreadData = nullptr;
-
-  // TODO: Remove when {,Racy}RegisteredThread are removed in a later patch.
-  RegisteredThread* mRegisteredThread;
 };
 
 // Accessing const data from any thread.
 class ThreadRegistrationUnlockedConstReader : public ThreadRegistrationData {
  public:
   [[nodiscard]] const ThreadRegistrationInfo& Info() const { return mInfo; }
 
   [[nodiscard]] const PlatformData& PlatformDataCRef() const {
     return mPlatformData;
   }
 
   [[nodiscard]] const void* StackTop() const { return mStackTop; }
 
-  // TODO: Remove when {,Racy}RegisteredThread are removed in a later patch.
-  [[nodiscard]] const RacyRegisteredThread& RacyRegisteredThreadCRef() const;
-
  protected:
   ThreadRegistrationUnlockedConstReader(const char* aName,
                                         const void* aStackTop)
       : ThreadRegistrationData(aName, aStackTop) {}
 };
 
 // Accessing atomic data from any thread.
 class ThreadRegistrationUnlockedConstReaderAndAtomicRW
@@ -313,19 +298,16 @@ class ThreadRegistrationUnlockedConstRea
     if (mSleep.compareExchange(SLEEPING_NOT_OBSERVED, SLEEPING_OBSERVED)) {
       return false;
     }
     return true;
   }
 
   [[nodiscard]] bool IsSleeping() const { return mSleep != AWAKE; }
 
-  // TODO: Remove when {,Racy}RegisteredThread are removed in a later patch.
-  [[nodiscard]] RacyRegisteredThread& RacyRegisteredThreadRef();
-
  protected:
   ThreadRegistrationUnlockedConstReaderAndAtomicRW(const char* aName,
                                                    const void* aStackTop)
       : ThreadRegistrationUnlockedConstReader(aName, aStackTop) {}
 };
 
 // Like above, with special PSAutoLock-guarded accessors.
 class ThreadRegistrationUnlockedRWForLockedProfiler
@@ -435,19 +417,16 @@ class ThreadRegistrationLockedRWFromAnyT
   void StopJSSampling() {
     // This function runs on-thread or off-thread.
 
     MOZ_RELEASE_ASSERT(mJSSampling == ACTIVE ||
                        mJSSampling == ACTIVE_REQUESTED);
     mJSSampling = INACTIVE_REQUESTED;
   }
 
-  // TODO: Remove when {,Racy}RegisteredThread are removed in a later patch.
-  [[nodiscard]] RegisteredThread& RegisteredThreadRef();
-
  protected:
   ThreadRegistrationLockedRWFromAnyThread(const char* aName,
                                           const void* aStackTop)
       : ThreadRegistrationUnlockedReaderAndAtomicRWOnThread(aName, aStackTop) {}
 };
 
 // Accessing data, locked, from the thread.
 // If any non-atomic data is readable from UnlockedReaderAndAtomicRWOnThread,
@@ -459,19 +438,16 @@ class ThreadRegistrationLockedRWOnThread
     : public ThreadRegistrationLockedRWFromAnyThread {
  public:
   void SetJSContext(JSContext* aJSContext);
   void ClearJSContext();
 
   // Poll to see if JS sampling should be started/stopped.
   void PollJSSampling();
 
-  // TODO: Remove when {,Racy}RegisteredThread are removed in a later patch.
-  void SetRegisteredThread(RegisteredThread* aRegisteredThread);
-
  public:
   ThreadRegistrationLockedRWOnThread(const char* aName, const void* aStackTop)
       : ThreadRegistrationLockedRWFromAnyThread(aName, aStackTop) {}
 };
 
 }  // namespace mozilla::profiler
 
 #endif  // ProfilerThreadRegistrationData_h