/* static */ void
nsWindowMemoryReporter::UnlinkGhostWindows()
{
  if (!sWindowReporter) {
    return;
  }

  nsGlobalWindow::WindowByIdTable* windowsById =
    nsGlobalWindow::GetWindowsTable();
  if (!windowsById) {
    return;
  }

  // Hold on to every window in memory so that window objects can't be
  // destroyed while we're calling the UnlinkGhostWindows callback.
  WindowArray windows;
  windowsById->Enumerate(GetWindows, &windows);

  // Get the IDs of all the "ghost" windows, and unlink them all.
  nsTHashtable<nsUint64HashKey> ghostWindows;
  sWindowReporter->CheckForGhostWindows(&ghostWindows);
  for (auto iter = ghostWindows.ConstIter(); !iter.Done(); iter.Next()) {
    nsGlobalWindow::WindowByIdTable* windowsById =
      nsGlobalWindow::GetWindowsTable();
    if (!windowsById) {
      continue;
    }

    RefPtr<nsGlobalWindow> window = windowsById->Get(iter.Get()->GetKey());
    if (window) {
      window->RiskyUnlink();
    }
  }
}
/* static */ int64_t
nsWindowMemoryReporter::GhostWindowsReporter::DistinguishedAmount()
{
  nsTHashtable<nsUint64HashKey> ghostWindows;
  sWindowReporter->CheckForGhostWindows(&ghostWindows);
  return ghostWindows.Count();
}
// static
void
nsWindowMemoryReporter::CheckTimerFired(nsITimer* aTimer, void* aClosure)
{
  if (sWindowReporter) {
    MOZ_ASSERT(!sWindowReporter->mCycleCollectorIsRunning);
    sWindowReporter->CheckForGhostWindows();
  }
}
/* static */ void
nsWindowMemoryReporter::UnlinkGhostWindows()
{
  if (!sWindowReporter) {
    return;
  }

  nsGlobalWindow::WindowByIdTable* windowsById =
    nsGlobalWindow::GetWindowsTable();
  if (!windowsById) {
    return;
  }

  // Hold on to every window in memory so that window objects can't be
  // destroyed while we're calling the UnlinkGhostWindows callback.
  WindowArray windows;
  windowsById->Enumerate(GetWindows, &windows);

  // Get the IDs of all the "ghost" windows, and unlink them all.
  nsTHashtable<nsUint64HashKey> ghostWindows;
  sWindowReporter->CheckForGhostWindows(&ghostWindows);
  ghostWindows.EnumerateEntries(UnlinkGhostWindowsEnumerator, nullptr);
}