Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/packages/packages/apps/Protips/res/values-be/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 2 kB image not shown  

Quellcode-Bibliothek TestBaseProfiler.cpp

  Sprache: C
 

/* 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 "mozilla/Attributes.h"
#include "mozilla/BaseAndGeckoProfilerDetail.h"
#include "mozilla/BaseProfileJSONWriter.h"
#include "mozilla/BaseProfiler.h"
#include "mozilla/BaseProfilerDetail.h"
#include "mozilla/FailureLatch.h"
#include "mozilla/NotNull.h"
#include "mozilla/ProgressLogger.h"
#include "mozilla/ProportionValue.h"

#include "mozilla/BaseProfilerMarkerTypes.h"
#include "mozilla/leb128iterator.h"
#include "mozilla/ModuloBuffer.h"
#include "mozilla/mozalloc.h"
#include "mozilla/PowerOfTwo.h"
#include "mozilla/ProfileBufferChunk.h"
#include "mozilla/ProfileBufferChunkManagerSingle.h"
#include "mozilla/ProfileBufferChunkManagerWithLocalLimit.h"
#include "mozilla/ProfileBufferControlledChunkManager.h"
#include "mozilla/ProfileChunkedBuffer.h"
#include "mozilla/Vector.h"

#if defined(_MSC_VER) || defined(__MINGW32__)
#  include <windows.h>
#  include <mmsystem.h>
#  include <process.h>
#else
#  include <errno.h>
#  include <time.h>
#endif

#include <algorithm>
#include <atomic>
#include <iostream>
#include <random>
#include <thread>
#include <type_traits>
#include <utility>

void TestFailureLatch() {
  printf("TestFailureLatch...\n");

  // Test infallible latch.
  {
    mozilla::FailureLatchInfallibleSource& infallibleLatch =
        mozilla::FailureLatchInfallibleSource::Singleton();

    MOZ_RELEASE_ASSERT(!infallibleLatch.Fallible());
    MOZ_RELEASE_ASSERT(!infallibleLatch.Failed());
    MOZ_RELEASE_ASSERT(!infallibleLatch.GetFailure());
    MOZ_RELEASE_ASSERT(&infallibleLatch.SourceFailureLatch() ==
                       &mozilla::FailureLatchInfallibleSource::Singleton());
    MOZ_RELEASE_ASSERT(&std::as_const(infallibleLatch).SourceFailureLatch() ==
                       &mozilla::FailureLatchInfallibleSource::Singleton());
  }

  // Test failure latch basic functions.
  {
    mozilla::FailureLatchSource failureLatch;

    MOZ_RELEASE_ASSERT(failureLatch.Fallible());
    MOZ_RELEASE_ASSERT(!failureLatch.Failed());
    MOZ_RELEASE_ASSERT(!failureLatch.GetFailure());
    MOZ_RELEASE_ASSERT(&failureLatch.SourceFailureLatch() == &failureLatch);
    MOZ_RELEASE_ASSERT(&std::as_const(failureLatch).SourceFailureLatch() ==
                       &failureLatch);

    failureLatch.SetFailure("error");

    MOZ_RELEASE_ASSERT(failureLatch.Fallible());
    MOZ_RELEASE_ASSERT(failureLatch.Failed());
    MOZ_RELEASE_ASSERT(failureLatch.GetFailure());
    MOZ_RELEASE_ASSERT(strcmp(failureLatch.GetFailure(), "error") == 0);

    failureLatch.SetFailure("later error");

    MOZ_RELEASE_ASSERT(failureLatch.Fallible());
    MOZ_RELEASE_ASSERT(failureLatch.Failed());
    MOZ_RELEASE_ASSERT(failureLatch.GetFailure());
    MOZ_RELEASE_ASSERT(strcmp(failureLatch.GetFailure(), "error") == 0);
  }

  // Test SetFailureFrom.
  {
    mozilla::FailureLatchSource failureLatch;

    MOZ_RELEASE_ASSERT(!failureLatch.Failed());
    failureLatch.SetFailureFrom(failureLatch);
    MOZ_RELEASE_ASSERT(!failureLatch.Failed());
    MOZ_RELEASE_ASSERT(!failureLatch.GetFailure());

    // SetFailureFrom with no error.
    {
      mozilla::FailureLatchSource failureLatchInnerOk;
      MOZ_RELEASE_ASSERT(!failureLatchInnerOk.Failed());
      MOZ_RELEASE_ASSERT(!failureLatchInnerOk.GetFailure());

      MOZ_RELEASE_ASSERT(!failureLatch.Failed());
      failureLatch.SetFailureFrom(failureLatchInnerOk);
      MOZ_RELEASE_ASSERT(!failureLatch.Failed());

      MOZ_RELEASE_ASSERT(!failureLatchInnerOk.Failed());
      MOZ_RELEASE_ASSERT(!failureLatchInnerOk.GetFailure());
    }
    MOZ_RELEASE_ASSERT(!failureLatch.Failed());
    MOZ_RELEASE_ASSERT(!failureLatch.GetFailure());

    // SetFailureFrom with error.
    {
      mozilla::FailureLatchSource failureLatchInnerError;
      MOZ_RELEASE_ASSERT(!failureLatchInnerError.Failed());
      MOZ_RELEASE_ASSERT(!failureLatchInnerError.GetFailure());

      failureLatchInnerError.SetFailure("inner error");
      MOZ_RELEASE_ASSERT(failureLatchInnerError.Failed());
      MOZ_RELEASE_ASSERT(
          strcmp(failureLatchInnerError.GetFailure(), "inner error") == 0);

      MOZ_RELEASE_ASSERT(!failureLatch.Failed());
      failureLatch.SetFailureFrom(failureLatchInnerError);
      MOZ_RELEASE_ASSERT(failureLatch.Failed());

      MOZ_RELEASE_ASSERT(failureLatchInnerError.Failed());
      MOZ_RELEASE_ASSERT(
          strcmp(failureLatchInnerError.GetFailure(), "inner error") == 0);
    }
    MOZ_RELEASE_ASSERT(failureLatch.Failed());
    MOZ_RELEASE_ASSERT(strcmp(failureLatch.GetFailure(), "inner error") == 0);

    failureLatch.SetFailureFrom(failureLatch);
    MOZ_RELEASE_ASSERT(failureLatch.Failed());
    MOZ_RELEASE_ASSERT(strcmp(failureLatch.GetFailure(), "inner error") == 0);

    // SetFailureFrom with error again, ignored.
    {
      mozilla::FailureLatchSource failureLatchInnerError;
      failureLatchInnerError.SetFailure("later inner error");
      MOZ_RELEASE_ASSERT(failureLatchInnerError.Failed());
      MOZ_RELEASE_ASSERT(strcmp(failureLatchInnerError.GetFailure(),
                                "later inner error") == 0);

      MOZ_RELEASE_ASSERT(failureLatch.Failed());
      failureLatch.SetFailureFrom(failureLatchInnerError);
      MOZ_RELEASE_ASSERT(failureLatch.Failed());

      MOZ_RELEASE_ASSERT(failureLatchInnerError.Failed());
      MOZ_RELEASE_ASSERT(strcmp(failureLatchInnerError.GetFailure(),
                                "later inner error") == 0);
    }
    MOZ_RELEASE_ASSERT(failureLatch.Failed());
    MOZ_RELEASE_ASSERT(strcmp(failureLatch.GetFailure(), "inner error") == 0);
  }

  // Test FAILURELATCH_IMPL_PROXY
  {
    class Proxy final : public mozilla::FailureLatch {
     public:
      explicit Proxy(mozilla::FailureLatch& aFailureLatch)
          : mFailureLatch(WrapNotNull(&aFailureLatch)) {}

      void Set(mozilla::FailureLatch& aFailureLatch) {
        mFailureLatch = WrapNotNull(&aFailureLatch);
      }

      FAILURELATCH_IMPL_PROXY(*mFailureLatch)

     private:
      mozilla::NotNull<mozilla::FailureLatch*> mFailureLatch;
    };

    Proxy proxy{mozilla::FailureLatchInfallibleSource::Singleton()};

    MOZ_RELEASE_ASSERT(!proxy.Fallible());
    MOZ_RELEASE_ASSERT(!proxy.Failed());
    MOZ_RELEASE_ASSERT(!proxy.GetFailure());
    MOZ_RELEASE_ASSERT(&proxy.SourceFailureLatch() ==
                       &mozilla::FailureLatchInfallibleSource::Singleton());
    MOZ_RELEASE_ASSERT(&std::as_const(proxy).SourceFailureLatch() ==
                       &mozilla::FailureLatchInfallibleSource::Singleton());

    // Error from proxy.
    {
      mozilla::FailureLatchSource failureLatch;
      proxy.Set(failureLatch);
      MOZ_RELEASE_ASSERT(proxy.Fallible());
      MOZ_RELEASE_ASSERT(!proxy.Failed());
      MOZ_RELEASE_ASSERT(!proxy.GetFailure());
      MOZ_RELEASE_ASSERT(&proxy.SourceFailureLatch() == &failureLatch);
      MOZ_RELEASE_ASSERT(&std::as_const(proxy).SourceFailureLatch() ==
                         &failureLatch);

      proxy.SetFailure("error");
      MOZ_RELEASE_ASSERT(proxy.Failed());
      MOZ_RELEASE_ASSERT(strcmp(proxy.GetFailure(), "error") == 0);
      MOZ_RELEASE_ASSERT(failureLatch.Failed());
      MOZ_RELEASE_ASSERT(strcmp(failureLatch.GetFailure(), "error") == 0);

      // Don't forget to stop pointing at soon-to-be-destroyed object.
      proxy.Set(mozilla::FailureLatchInfallibleSource::Singleton());
    }

    // Error from proxy's origin.
    {
      mozilla::FailureLatchSource failureLatch;
      proxy.Set(failureLatch);
      MOZ_RELEASE_ASSERT(proxy.Fallible());
      MOZ_RELEASE_ASSERT(!proxy.Failed());
      MOZ_RELEASE_ASSERT(!proxy.GetFailure());
      MOZ_RELEASE_ASSERT(&proxy.SourceFailureLatch() == &failureLatch);
      MOZ_RELEASE_ASSERT(&std::as_const(proxy).SourceFailureLatch() ==
                         &failureLatch);

      failureLatch.SetFailure("error");
      MOZ_RELEASE_ASSERT(proxy.Failed());
      MOZ_RELEASE_ASSERT(strcmp(proxy.GetFailure(), "error") == 0);
      MOZ_RELEASE_ASSERT(failureLatch.Failed());
      MOZ_RELEASE_ASSERT(strcmp(failureLatch.GetFailure(), "error") == 0);

      // Don't forget to stop pointing at soon-to-be-destroyed object.
      proxy.Set(mozilla::FailureLatchInfallibleSource::Singleton());
    }

    MOZ_RELEASE_ASSERT(!proxy.Fallible());
    MOZ_RELEASE_ASSERT(!proxy.Failed());
    MOZ_RELEASE_ASSERT(!proxy.GetFailure());
    MOZ_RELEASE_ASSERT(&proxy.SourceFailureLatch() ==
                       &mozilla::FailureLatchInfallibleSource::Singleton());
    MOZ_RELEASE_ASSERT(&std::as_const(proxy).SourceFailureLatch() ==
                       &mozilla::FailureLatchInfallibleSource::Singleton());
  }

  // Test FAILURELATCH_IMPL_PROXY_OR_INFALLIBLE
  {
    class ProxyOrNull final : public mozilla::FailureLatch {
     public:
      ProxyOrNull() = default;

      void Set(mozilla::FailureLatch* aFailureLatchOrNull) {
        mFailureLatchOrNull = aFailureLatchOrNull;
      }

      FAILURELATCH_IMPL_PROXY_OR_INFALLIBLE(mFailureLatchOrNull, ProxyOrNull)

     private:
      mozilla::FailureLatch* mFailureLatchOrNull = nullptr;
    };

    ProxyOrNull proxy;

    MOZ_RELEASE_ASSERT(!proxy.Fallible());
    MOZ_RELEASE_ASSERT(!proxy.Failed());
    MOZ_RELEASE_ASSERT(!proxy.GetFailure());
    MOZ_RELEASE_ASSERT(&proxy.SourceFailureLatch() ==
                       &mozilla::FailureLatchInfallibleSource::Singleton());
    MOZ_RELEASE_ASSERT(&std::as_const(proxy).SourceFailureLatch() ==
                       &mozilla::FailureLatchInfallibleSource::Singleton());

    // Error from proxy.
    {
      mozilla::FailureLatchSource failureLatch;
      proxy.Set(&failureLatch);
      MOZ_RELEASE_ASSERT(proxy.Fallible());
      MOZ_RELEASE_ASSERT(!proxy.Failed());
      MOZ_RELEASE_ASSERT(!proxy.GetFailure());
      MOZ_RELEASE_ASSERT(&proxy.SourceFailureLatch() == &failureLatch);
      MOZ_RELEASE_ASSERT(&std::as_const(proxy).SourceFailureLatch() ==
                         &failureLatch);

      proxy.SetFailure("error");
      MOZ_RELEASE_ASSERT(proxy.Failed());
      MOZ_RELEASE_ASSERT(strcmp(proxy.GetFailure(), "error") == 0);
      MOZ_RELEASE_ASSERT(failureLatch.Failed());
      MOZ_RELEASE_ASSERT(strcmp(failureLatch.GetFailure(), "error") == 0);

      // Don't forget to stop pointing at soon-to-be-destroyed object.
      proxy.Set(nullptr);
    }

    // Error from proxy's origin.
    {
      mozilla::FailureLatchSource failureLatch;
      proxy.Set(&failureLatch);
      MOZ_RELEASE_ASSERT(proxy.Fallible());
      MOZ_RELEASE_ASSERT(!proxy.Failed());
      MOZ_RELEASE_ASSERT(!proxy.GetFailure());
      MOZ_RELEASE_ASSERT(&proxy.SourceFailureLatch() == &failureLatch);
      MOZ_RELEASE_ASSERT(&std::as_const(proxy).SourceFailureLatch() ==
                         &failureLatch);

      failureLatch.SetFailure("error");
      MOZ_RELEASE_ASSERT(proxy.Failed());
      MOZ_RELEASE_ASSERT(strcmp(proxy.GetFailure(), "error") == 0);
      MOZ_RELEASE_ASSERT(failureLatch.Failed());
      MOZ_RELEASE_ASSERT(strcmp(failureLatch.GetFailure(), "error") == 0);

      // Don't forget to stop pointing at soon-to-be-destroyed object.
      proxy.Set(nullptr);
    }

    MOZ_RELEASE_ASSERT(!proxy.Fallible());
    MOZ_RELEASE_ASSERT(!proxy.Failed());
    MOZ_RELEASE_ASSERT(!proxy.GetFailure());
    MOZ_RELEASE_ASSERT(&proxy.SourceFailureLatch() ==
                       &mozilla::FailureLatchInfallibleSource::Singleton());
    MOZ_RELEASE_ASSERT(&std::as_const(proxy).SourceFailureLatch() ==
                       &mozilla::FailureLatchInfallibleSource::Singleton());
  }

  printf("TestFailureLatch done\n");
}

void TestProfilerUtils() {
  printf("TestProfilerUtils...\n");

  {
    using mozilla::baseprofiler::BaseProfilerProcessId;
    using Number = BaseProfilerProcessId::NumberType;
    static constexpr Number scMaxNumber = std::numeric_limits<Number>::max();

    static_assert(
        BaseProfilerProcessId{}.ToNumber() == 0,
        "These tests assume that the unspecified process id number is 0; "
        "if this fails, please update these tests accordingly");

    static_assert(!BaseProfilerProcessId{}.IsSpecified());
    static_assert(!BaseProfilerProcessId::FromNumber(0).IsSpecified());
    static_assert(BaseProfilerProcessId::FromNumber(1).IsSpecified());
    static_assert(BaseProfilerProcessId::FromNumber(123).IsSpecified());
    static_assert(BaseProfilerProcessId::FromNumber(scMaxNumber).IsSpecified());

    static_assert(BaseProfilerProcessId::FromNumber(Number(1)).ToNumber() ==
                  Number(1));
    static_assert(BaseProfilerProcessId::FromNumber(Number(123)).ToNumber() ==
                  Number(123));
    static_assert(BaseProfilerProcessId::FromNumber(scMaxNumber).ToNumber() ==
                  scMaxNumber);

    static_assert(BaseProfilerProcessId{} == BaseProfilerProcessId{});
    static_assert(BaseProfilerProcessId::FromNumber(Number(123)) ==
                  BaseProfilerProcessId::FromNumber(Number(123)));
    static_assert(BaseProfilerProcessId{} !=
                  BaseProfilerProcessId::FromNumber(Number(123)));
    static_assert(BaseProfilerProcessId::FromNumber(Number(123)) !=
                  BaseProfilerProcessId{});
    static_assert(BaseProfilerProcessId::FromNumber(Number(123)) !=
                  BaseProfilerProcessId::FromNumber(scMaxNumber));
    static_assert(BaseProfilerProcessId::FromNumber(scMaxNumber) !=
                  BaseProfilerProcessId::FromNumber(Number(123)));

    // Verify trivial-copyability by memcpy'ing to&from same-size storage.
    static_assert(std::is_trivially_copyable_v<BaseProfilerProcessId>);
    BaseProfilerProcessId pid;
    MOZ_RELEASE_ASSERT(!pid.IsSpecified());
    Number pidStorage;
    static_assert(sizeof(pidStorage) == sizeof(pid));
    // Copy from BaseProfilerProcessId to storage. Note: We cannot assume that
    // this is equal to what ToNumber() gives us. All we can do is verify that
    // copying from storage back to BaseProfilerProcessId works as expected.
    std::memcpy(&pidStorage, &pid, sizeof(pidStorage));
    BaseProfilerProcessId pid2 = BaseProfilerProcessId::FromNumber(2);
    MOZ_RELEASE_ASSERT(pid2.IsSpecified());
    std::memcpy(&pid2, &pidStorage, sizeof(pid));
    MOZ_RELEASE_ASSERT(!pid2.IsSpecified());

    pid = BaseProfilerProcessId::FromNumber(123);
    std::memcpy(&pidStorage, &pid, sizeof(pidStorage));
    pid2 = BaseProfilerProcessId{};
    MOZ_RELEASE_ASSERT(!pid2.IsSpecified());
    std::memcpy(&pid2, &pidStorage, sizeof(pid));
    MOZ_RELEASE_ASSERT(pid2.IsSpecified());
    MOZ_RELEASE_ASSERT(pid2.ToNumber() == 123);

    // No conversions to/from numbers.
    static_assert(!std::is_constructible_v<BaseProfilerProcessId, Number>);
    static_assert(!std::is_assignable_v<BaseProfilerProcessId, Number>);
    static_assert(!std::is_constructible_v<Number, BaseProfilerProcessId>);
    static_assert(!std::is_assignable_v<Number, BaseProfilerProcessId>);

    static_assert(
        std::is_same_v<
            decltype(mozilla::baseprofiler::profiler_current_process_id()),
            BaseProfilerProcessId>);
    MOZ_RELEASE_ASSERT(
        mozilla::baseprofiler::profiler_current_process_id().IsSpecified());
  }

  {
    mozilla::baseprofiler::profiler_init_main_thread_id();

    using mozilla::baseprofiler::BaseProfilerThreadId;
    using Number = BaseProfilerThreadId::NumberType;
    static constexpr Number scMaxNumber = std::numeric_limits<Number>::max();

    static_assert(
        BaseProfilerThreadId{}.ToNumber() == 0,
        "These tests assume that the unspecified thread id number is 0; "
        "if this fails, please update these tests accordingly");

    static_assert(!BaseProfilerThreadId{}.IsSpecified());
    static_assert(!BaseProfilerThreadId::FromNumber(0).IsSpecified());
    static_assert(BaseProfilerThreadId::FromNumber(1).IsSpecified());
    static_assert(BaseProfilerThreadId::FromNumber(123).IsSpecified());
    static_assert(BaseProfilerThreadId::FromNumber(scMaxNumber).IsSpecified());

    static_assert(BaseProfilerThreadId::FromNumber(Number(1)).ToNumber() ==
                  Number(1));
    static_assert(BaseProfilerThreadId::FromNumber(Number(123)).ToNumber() ==
                  Number(123));
    static_assert(BaseProfilerThreadId::FromNumber(scMaxNumber).ToNumber() ==
                  scMaxNumber);

    static_assert(BaseProfilerThreadId{} == BaseProfilerThreadId{});
    static_assert(BaseProfilerThreadId::FromNumber(Number(123)) ==
                  BaseProfilerThreadId::FromNumber(Number(123)));
    static_assert(BaseProfilerThreadId{} !=
                  BaseProfilerThreadId::FromNumber(Number(123)));
    static_assert(BaseProfilerThreadId::FromNumber(Number(123)) !=
                  BaseProfilerThreadId{});
    static_assert(BaseProfilerThreadId::FromNumber(Number(123)) !=
                  BaseProfilerThreadId::FromNumber(scMaxNumber));
    static_assert(BaseProfilerThreadId::FromNumber(scMaxNumber) !=
                  BaseProfilerThreadId::FromNumber(Number(123)));

    // Verify trivial-copyability by memcpy'ing to&from same-size storage.
    static_assert(std::is_trivially_copyable_v<BaseProfilerThreadId>);
    BaseProfilerThreadId tid;
    MOZ_RELEASE_ASSERT(!tid.IsSpecified());
    Number tidStorage;
    static_assert(sizeof(tidStorage) == sizeof(tid));
    // Copy from BaseProfilerThreadId to storage. Note: We cannot assume that
    // this is equal to what ToNumber() gives us. All we can do is verify that
    // copying from storage back to BaseProfilerThreadId works as expected.
    std::memcpy(&tidStorage, &tid, sizeof(tidStorage));
    BaseProfilerThreadId tid2 = BaseProfilerThreadId::FromNumber(2);
    MOZ_RELEASE_ASSERT(tid2.IsSpecified());
    std::memcpy(&tid2, &tidStorage, sizeof(tid));
    MOZ_RELEASE_ASSERT(!tid2.IsSpecified());

    tid = BaseProfilerThreadId::FromNumber(Number(123));
    std::memcpy(&tidStorage, &tid, sizeof(tidStorage));
    tid2 = BaseProfilerThreadId{};
    MOZ_RELEASE_ASSERT(!tid2.IsSpecified());
    std::memcpy(&tid2, &tidStorage, sizeof(tid));
    MOZ_RELEASE_ASSERT(tid2.IsSpecified());
    MOZ_RELEASE_ASSERT(tid2.ToNumber() == Number(123));

    // No conversions to/from numbers.
    static_assert(!std::is_constructible_v<BaseProfilerThreadId, Number>);
    static_assert(!std::is_assignable_v<BaseProfilerThreadId, Number>);
    static_assert(!std::is_constructible_v<Number, BaseProfilerThreadId>);
    static_assert(!std::is_assignable_v<Number, BaseProfilerThreadId>);

    static_assert(std::is_same_v<
                  decltype(mozilla::baseprofiler::profiler_current_thread_id()),
                  BaseProfilerThreadId>);
    BaseProfilerThreadId mainTestThreadId =
        mozilla::baseprofiler::profiler_current_thread_id();
    MOZ_RELEASE_ASSERT(mainTestThreadId.IsSpecified());

    BaseProfilerThreadId mainThreadId =
        mozilla::baseprofiler::profiler_main_thread_id();
    MOZ_RELEASE_ASSERT(mainThreadId.IsSpecified());

    MOZ_RELEASE_ASSERT(mainThreadId == mainTestThreadId,
                       "Test should run on the main thread");
    MOZ_RELEASE_ASSERT(mozilla::baseprofiler::profiler_is_main_thread());

    std::thread testThread([&]() {
      const BaseProfilerThreadId testThreadId =
          mozilla::baseprofiler::profiler_current_thread_id();
      MOZ_RELEASE_ASSERT(testThreadId.IsSpecified());
      MOZ_RELEASE_ASSERT(testThreadId != mainThreadId);
      MOZ_RELEASE_ASSERT(!mozilla::baseprofiler::profiler_is_main_thread());
    });
    testThread.join();
  }

  // No conversions between processes and threads.
  static_assert(
      !std::is_constructible_v<mozilla::baseprofiler::BaseProfilerThreadId,
                               mozilla::baseprofiler::BaseProfilerProcessId>);
  static_assert(
      !std::is_assignable_v<mozilla::baseprofiler::BaseProfilerThreadId,
                            mozilla::baseprofiler::BaseProfilerProcessId>);
  static_assert(
      !std::is_constructible_v<mozilla::baseprofiler::BaseProfilerProcessId,
                               mozilla::baseprofiler::BaseProfilerThreadId>);
  static_assert(
      !std::is_assignable_v<mozilla::baseprofiler::BaseProfilerProcessId,
                            mozilla::baseprofiler::BaseProfilerThreadId>);

  printf("TestProfilerUtils done\n");
}

void TestBaseAndProfilerDetail() {
  printf("TestBaseAndProfilerDetail...\n");

  {
    using mozilla::profiler::detail::FilterHasPid;

    const auto pid123 =
        mozilla::baseprofiler::BaseProfilerProcessId::FromNumber(123);
    MOZ_RELEASE_ASSERT(FilterHasPid("pid:123", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid(" ", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("123", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("pid", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("pid:", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("pid=123", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("pid:123 ", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("pid: 123", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("pid:0123", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("pid:0000000000000000000000123", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("pid:12", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("pid:1234", pid123));
    MOZ_RELEASE_ASSERT(!FilterHasPid("pid:0", pid123));

    using PidNumber = mozilla::baseprofiler::BaseProfilerProcessId::NumberType;
    const PidNumber maxNumber = std::numeric_limits<PidNumber>::max();
    const auto maxPid =
        mozilla::baseprofiler::BaseProfilerProcessId::FromNumber(maxNumber);
    const std::string maxPidString = "pid:" + std::to_string(maxNumber);
    MOZ_RELEASE_ASSERT(FilterHasPid(maxPidString.c_str(), maxPid));

    const std::string tooBigPidString = maxPidString + "0";
    MOZ_RELEASE_ASSERT(!FilterHasPid(tooBigPidString.c_str(), maxPid));
  }

  {
    using mozilla::profiler::detail::FiltersExcludePid;
    const auto pid123 =
        mozilla::baseprofiler::BaseProfilerProcessId::FromNumber(123);

    MOZ_RELEASE_ASSERT(
        !FiltersExcludePid(mozilla::Span<const char*>{}, pid123));

    {
      const charconst filters[] = {"main"};
      MOZ_RELEASE_ASSERT(!FiltersExcludePid(filters, pid123));
    }

    {
      const charconst filters[] = {"main""pid:123"};
      MOZ_RELEASE_ASSERT(!FiltersExcludePid(filters, pid123));
    }

    {
      const charconst filters[] = {"main""pid:456"};
      MOZ_RELEASE_ASSERT(!FiltersExcludePid(filters, pid123));
    }

    {
      const charconst filters[] = {"pid:123"};
      MOZ_RELEASE_ASSERT(!FiltersExcludePid(filters, pid123));
    }

    {
      const charconst filters[] = {"pid:123""pid:456"};
      MOZ_RELEASE_ASSERT(!FiltersExcludePid(filters, pid123));
    }

    {
      const charconst filters[] = {"pid:456""pid:123"};
      MOZ_RELEASE_ASSERT(!FiltersExcludePid(filters, pid123));
    }

    {
      const charconst filters[] = {"pid:456"};
      MOZ_RELEASE_ASSERT(FiltersExcludePid(filters, pid123));
    }

    {
      const charconst filters[] = {"pid:456""pid:789"};
      MOZ_RELEASE_ASSERT(FiltersExcludePid(filters, pid123));
    }
  }

  printf("TestBaseAndProfilerDetail done\n");
}

void TestSharedMutex() {
  printf("TestSharedMutex...\n");

  mozilla::baseprofiler::detail::BaseProfilerSharedMutex sm;

  // First round of minimal tests in this thread.

  MOZ_RELEASE_ASSERT(!sm.IsLockedExclusiveOnCurrentThread());

  sm.LockExclusive();
  MOZ_RELEASE_ASSERT(sm.IsLockedExclusiveOnCurrentThread());
  sm.UnlockExclusive();
  MOZ_RELEASE_ASSERT(!sm.IsLockedExclusiveOnCurrentThread());

  sm.LockShared();
  MOZ_RELEASE_ASSERT(!sm.IsLockedExclusiveOnCurrentThread());
  sm.UnlockShared();
  MOZ_RELEASE_ASSERT(!sm.IsLockedExclusiveOnCurrentThread());

  {
    mozilla::baseprofiler::detail::BaseProfilerAutoLockExclusive exclusiveLock{
        sm};
    MOZ_RELEASE_ASSERT(sm.IsLockedExclusiveOnCurrentThread());
  }
  MOZ_RELEASE_ASSERT(!sm.IsLockedExclusiveOnCurrentThread());

  {
    mozilla::baseprofiler::detail::BaseProfilerAutoLockShared sharedLock{sm};
    MOZ_RELEASE_ASSERT(!sm.IsLockedExclusiveOnCurrentThread());
  }
  MOZ_RELEASE_ASSERT(!sm.IsLockedExclusiveOnCurrentThread());

  // The following will run actions between two threads, to verify that
  // exclusive and shared locks work as expected.

  // These actions will happen from top to bottom.
  // This will test all possible lock interactions.
  enum NextAction {                  // State of the lock:
    t1Starting,                      // (x=exclusive, s=shared, ?=blocked)
    t2Starting,                      // t1 t2
    t1LockExclusive,                 // x
    t2LockExclusiveAndBlock,         // x  x? - Can't have two exclusives.
    t1UnlockExclusive,               //    x
    t2UnblockedAfterT1Unlock,        //    x
    t1LockSharedAndBlock,            // s? x - Can't have shared during excl
    t2UnlockExclusive,               // s
    t1UnblockedAfterT2Unlock,        // s
    t2LockShared,                    // s  s - Can have multiple shared locks
    t1UnlockShared,                  //    s
    t2StillLockedShared,             //    s
    t1LockExclusiveAndBlock,         // x? s - Can't have excl during shared
    t2UnlockShared,                  // x
    t1UnblockedAfterT2UnlockShared,  // x
    t2CheckAfterT1Lock/* This Source Code Form is subject to the terms of the Mozilla Public License, v.20  a copy  the MPL  otdistributedwith this file,
    t1LastUnlockExclusive,           // (unlocked)
    done
  };

  // Each thread will repeatedly read this `nextAction`, and run actions that
  // target it...
  std::atomic<NextAction> nextAction{static_cast<NextAction>(0)};
  // ... and advance to the next available action (which should usually be for
  // the other thread).
  i mozillajava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
   (nextAction < done)
    nextAction  static_castN(static_cast<() 1;
  ;

  std:include mozilla/ectorhjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
    for (;){
      switch (nextAction) {
         t1Starting
         AdvanceAction()java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
java.lang.StringIndexOutOfBoundsException: Range [15, 10) out of bounds for length 16
         t1LockExclusive:
Mjava.lang.StringIndexOutOfBoundsException: Range [30, 28) out of bounds for length 69
          sm.LockExclusive();
          MOZ_RELEASE_ASSERT(sm.IsLockedExclusiveOnCurrentThread());
          dvanceAction();
          break;
caset1UnlockExclusive:
          MOZ_RELEASE_ASSERT(sm.IsLockedExclusiveOnCurrentThread());
          // Advance first, before unlocking, so that t2 sees the new state.
          AdvanceAction();
          sm.UnlockExclusive();
MOZ_RELEASE_ASSERT(!sm.IsLockedExclusiveOnCurrentThread());
          java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 3
         t1LockSharedAndBlock:
          // Advance action before attempting to lock after t2's exclusive lock.!.ailed()java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
MOZ_RELEASE_ASSERT(std::as_const()SourceFailureLatch()=
java.lang.StringIndexOutOfBoundsException: Range [37, 26) out of bounds for length 26
//Wejava.lang.StringIndexOutOfBoundsException: Range [20, 16) out of bounds for length 60
              java.lang.StringIndexOutOfBoundsException: Range [30, 22) out of bounds for length 72
java.lang.StringIndexOutOfBoundsException: Range [33, 28) out of bounds for length 69
          AdvanceAction(;
          break;
        case t1UnlockShared:
MOZ_RELEASE_ASSERT(!sm.IsLockedExclusiveOnCurrentThread());
          // Advance first, before unlocking, so that t2 sees the new state.
         java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 26
          java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
          MOZ_RELEASE_ASSERTfailureLatchInnerOk.()java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
          MOZ_RELEASE_ASSERT(failureLatchInnerOk.Failed());
        case t1LockExclusiveAndBlock:
          (smIsLockedExclusiveOnCurrentThread()java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
         / Advance action before attempting to lock after t2's shared lock.!failureLatchInnerErrorFailed()
          AdvanceAction();
          sm.LockExclusive();
          // We will only acquire the lock after t2 unlocks.
MOZ_RELEASE_ASSERT(nextAction = t1UnblockedAfterT2UnlockShared;
          java.lang.StringIndexOutOfBoundsException: Range [58, 28) out of bounds for length 68
          AdvanceAction()
          reak;
        case t1LastUnlockExclusive:
          MOZ_RELEASE_ASSERTsmIsLockedExclusiveOnCurrentThread()
 so that t2sees the new state.
          ()
sm.UnlockExclusive()java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
          MOZ_RELEASE_ASSERT
break;
        case done:
          ;
        default:
          /Ignore other actions intendedfor t2.
          break;
      }
    }
  };

  std::java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
    for (;java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 6
        case     (proxy.Fallible());
          AdvanceAction(;
                m:FailureLatchInfallibleSource:Singleton();
        case t2LockExclusiveAndBlock:
java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 69
          actionbefore     'exclusive
          java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 26
          sm.LockExclusive();
// We will only acquire the lock after t1 unlocks.
MOZ_RELEASE_ASSERT =t2UnblockedAfterT1Unlock
                strcmp(.etFailure() error")= ;
          java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 0
          ;
      !GetFailure())java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
          (.IsLockedExclusiveOnCurrentThread;
          // Advance first, before unlocking, so that t1 sees the new state.
          AdvanceAction(
      p.Failed()java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
          MOZ_RELEASE_ASSERT(!sm.      MOZ_RELEASE_ASSERT(failureLatch.Failed);
          break;
              MOZ_RE(( )=java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
          sm.LockShared();
          MOZ_RELEASE_ASSERT(!sm.java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
AdvanceAction;
          break;
        case t2StillLockedShared:
          AdvanceAction);
          break;
        case (ozilla:FailureLatch ) java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
          java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
              MOZ_RELEASE_ASSERT(!proxy.GetFailure());
          java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 53
          .)
          java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 24
          break;
        :
          !()
          AdvanceAction(;
          break;
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
                java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 74
        default
          // Ignore other actions intended for t1.
          break;
      }
    }
   /java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33

  MOZ_RELEASE_ASSERTpFailed()
  t2.();

  java.lang.StringIndexOutOfBoundsException: Range [25, 8) out of bounds for length 35
 .SetFailure("rror";

 ()java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
  printf(..n)

  using mozillaMOZ_RELEASE_ASSERT!Failed();

#define STATIC_ASSERT_EQ(a, b) \
  (a) =();  java.lang.StringIndexOutOfBoundsException: Range [32, 33) out of bounds for length 32
  MOZ_RELEASE_ASSERT((a) ==}

(e) STATIC_ASSERT_EQ,t)

  // Conversion from&to double.
STATIC_ASSERT_EQ((.() .)
), 0.0;
  ProportionValue(.)(,05;
 java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 57

  // Clamping.
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
s:numeric_limitsdouble>:in()( .;
  java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
      (std:numeric_limits<long double>::min()).ToDouble(), 0.0);
  java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 0
  static_assert:())=
  STATIC_ASSERT_EQ(ProportionValue                  :())
 (.)ToDouble) .)
  STATIC_ASSERT_EQ(
      >::max().)

   literal.
  {
    using namespace mozilla::literals::ProportionValue_literals;
    STATIC_ASSERT_EQ(_pc,ProportionValue(.);
    (.pc,ProportionValue(.0)
    STATIC_ASSERT_EQpidStorage =sizeof(pid)
    STATIC_ASSERT_EQ(50._pc, // copying from storage back to BaseProfilerPro
    STATIC_ASSERT_EQ(100_pc, ProportionValue( BaseProfilerProcessId  :()
    100_, (.);
    (pc ProportionValue(.))
    , ProportionValue(1.0));
    STATIC_ASSERT_EQ(1000_c,ProportionValue(1.0);
    (1000_c (.)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
  }
  {
// ProportionValue_literals is an inline namespace of mozilla::literals, so
    // it's optional.
     mozilla:literals;
    STATIC_ASSERT_EQMOZ_RELEASE_ASSERT(
   (._, (.);
    STATIC_ASSERT_EQ(50_pc, java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 3
    STATIC_ASSERT_EQ(50._, ProportionValue(0.5));
    .0));
    STATIC_ASSERT_EQ(100.   static    :<:max(;
    101_c,ProportionValue1.);
        static_assert(BaseProfilerThreadId::FromNumber(0).IsSpecified());
    STATIC_ASSERT_EQ(1000    :FromNumber()IsSpecified)java.lang.StringIndexOutOfBoundsException: Range [71, 72) out of bounds for length 71
    STATIC_ASSERT_EQ(1000._c ProportionValue(10);
  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  // Invalid construction, conversion to double NaN.
  ().ToDouble()))

roportionValue_literalsjava.lang.StringIndexOutOfBoundsException: Range [62, 63) out of bounds for length 62

  // Conversion to&from underlying integral number.
                  :Number();
      :FromUnderlyingType(pc)(.)java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
      0.0):FromNumber(Number(123)));
  STATIC_ASSERT_EQ(
      ProportionValue::FromUnderlyingType((50_pc).ToUnderlyingType())
          .ToDouble(),
      0.5);
  STATIC_ASSERT_EQ(
      :FromUnderlyingType(100_)ToUnderlyingType()
          .ToDouble(),
      1.0);
  (:F(
                        MOZ_RELEASE_ASSERT(tid2java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 43
.IsInvalid();

  // IsExactlyZero.
  STATIC_ASSERT(static_assert(!std::is_constructible_v<Number, BaseProfilerThreadId>);
  STATIC_ASSERT((0_java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 0
  STATIC_ASSERT(!(     
;
  ::));

  // IsExactlyOne.
                       should )java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
  mozilla::)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
  ).))java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
  STATIC_ASSERT((100_pc  // No conversions between processes and threads.
 (!ProportionValue::akeInvalid()IsExactlyOne());

  // IsValid.
  STATIC_ASSERT(java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 16
 STATIC_ASSERT((0_pc).IsValid());
  (50_c.()java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
  STATIC_ASSERT((100_pc).IsValid());
  STATIC_ASSERT(!ProportionValue::MakeInvalid().IsValid());

  // IsInvalid.
  java.lang.StringIndexOutOfBoundsException: Range [0, 15) out of bounds for length 3
  STATIC_ASSERT(!    const auto pid123 =
  STATIC_ASSERT(!(50_pc).IsInvalid(    F("pid:" );
  STATIC_ASSERT(!( !"123,pid123)
  MOZ_RELEASE_ASSERT!p1234");

  // Addition.
  ((0_pc + 0_pc)ToDouble(,0.0;
(pc  pc.(,1.0;
  (100pc  _.() .)java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
00_  _c)(,10;
java.lang.StringIndexOutOfBoundsException: Range [23, 2) out of bounds for length 70
  ()).IsInvalid()java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70

  // Subtraction.
  (), 0.0);
  STATIC_ASSERT_EQ((0_pc - 100_pc    }
  STATIC_ASSERT_EQ((100_pc - 0_pc).ToDouble(), 1.MOZ_RELEASE_ASSERT!f,)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
  (_  pc.() .;
  STATIC_ASSERT       * ]  123}
::MakeInvalid()IsInvalid);

  // Multiplication.
  
STATIC_ASSERT_EQ(_*100_.) 0.;
  STATIC_ASSERT_EQ((50_pc  printf("estBaseAndProfilerDetail done\n");
 STATIC_ASSERT_EQ((50_pc * 100_pc).ToDouble(), 0.5);
  STATIC_ASSERT_EQ((100_pc * 50_pc).java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 0
  STATIC_ASSERT_EQ((100_pc * 0_pc).ToDouble(), 0.0);
  ((_ * _pc)ToDouble(),10;
  MOZ_RELEASE_ASSERT(sm.());
  STATIC_ASSERT  {

  // Division by a positive integer value.}java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
  STATIC_ASSERT_EQ((  }
  STATIC_ASSERT_EQ((100_pc / 2u).  MOZ_RELEASE_ASSERT(!sm.IsLockedExclusiveOnCurren(!sm.IsLockedExclusiveOnCurrentThread);
  STATIC_ASSERT_EQ(
      (ProportionValue::FromUnderlyingType(6u) / 2u).ToUnderlyingTypejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  STATIC_ASSERT_EQ(
      (ProportionValue::FromUnderlyingType(5u) / 2u enumNextAction{//State of the lock:
  STATIC_ASSERT_EQ(
      (ProportionValue::FromUnderlyingType(    ,//    x
  STATIC_ASSERT_EQ(
      (    t2UnlockExclusive               // s
  STATIC_ASSERT((100_pc /    t2LockShared,                    // s  s - Can have multiple shared locks
  STATIC_ASSERT((ProportionValue::MakeInvalid() / 2u).IsInvalid    t2StillLockedShared,             //    s

/java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
  STATIC_ASSERT_EQ((100_pc * 1u).ToDouble(),   java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
  ((_  1)( 5;
;
  (pc*.) .)  // Clamped.
   STATIC_ASSERT_EQ(
      (ProportionValue::FromUnderlyingType(1u) * 2u).java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 24
  STATIC_ASSERT((::akeInvalid(  2)IsInvalid);

/java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
  STATIC_ASSERT_EQ(
      ProportionValue:FromUnderlyingType(6u /3).ToUnderlyingType(,2u;
  STATIC_ASSERT_EQ(
      (        case t1LockSharedAndBlock:
  STATIC_ASSERT_EQ(
      (ProportionValue::FromUnderlyingType(8u)          (= t1UnblockedAfterT2Unlock)java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
  ;
      (MOZ_RELEASE_ASSERTsmIsLockedExclusiveOnCurrentThread;

  // Direct comparisons.
  STATIC_ASSERT_EQ(0_pc, 0_pc);
  STATIC_ASSERT(0_pc == 0_java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 26
  STATIC_ASSERT(!(0_pc == 100          MOZ_RELEASE_ASSERT(sm.IsLockedExclusiveOnCurrentThread());
  STATIC_ASSERT(0_pc != 100_pc);
  STATIC_ASSERT(!(0_        java.lang.StringIndexOutOfBoundsException: Range [18, 19) out of bounds for length 18
  STATIC_ASSERT(0_pc < 100_pc    }
  STATIC_ASSERT(!(0_c <0_c));
  STATIC_ASSERT(0_pc <= 0_pc);
  STATIC_ASSERT(0_pc <= 100_pc);
  STATIC_ASSERT(!(100_pc <= 0_pc));
  STATIC_ASSERT(100_pc           /Advance action before attempting   'sexclusive lock.
  ((100_pc >100pc)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
  STATIC_ASSERT(100_pc >= 0 before ,so   sees new .
  STATIC_ASSERT(100_pc >= 100_pc);
  = 100_pc))java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
  // 0.5 is binary-friendly, so we can double it and compare it exactly.(java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
  (0pc+ 50_pc, 100pc;

#undef STATIC_ASSERT_EQcase t2CheckAfterT1Lock:

  printf("TestProportionValue done\          (;
}

template <typename java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 7
qual(& ,Args&. aArgs){
  return ((aArg0 == aArgs}
}

void java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 0
Logger..\")java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36

  using mozilla::ProgressLogger
  using mozilla:ProportionValue;
  using namespace STATIC_ASSERT_EQ(ProportionValue(0.0).ToDouble(), 0.0);

  auto       ProportionValuestd::numeric_limits<double>::min()).ToDouble(), 0.0);
  (progressRefPtr);
  MOZ_RELEASE_ASSERT(progressRefPtr->java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19

  {
    ProgressLogger pl(progressRefPtr, "Started", "All done");
    MOZ_RELEASE_ASSERT(progressRefPtr->Progress().IsExactlyZero());
    MOZ_RELEASE_ASSERT(pl.GetGlobalProgress().IsExactlyZero());
    java.lang.StringIndexOutOfBoundsException: Range [49, 22) out of bounds for length 66
                                  (), Started");
STATIC_ASSERT_EQ(101pc (10);
    // At this top level, the scale is 1:1.

    MOZ_RELEASE_ASSERT(
        java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 3
    MOZ_RELEASE_ASSERT    // it's optional.
    (_c,P(00)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49

    pl.SetLocalProgress(0_pc, "Restarted");
    MOZ_RELEASE_ASSERT(
        AreAllEqual(progressRefPtr->Progress(), pl    STATIC_ASSERT_EQ(_,ProportionValue(0))
    MOZ_RELEASE_ASSERT(AreAllEqual(progressRefPtrjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                                   (), "estarted"))java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77

    {
      // Create a sub-logger for the whole global range. Notice that this is(
      // moving the current progress back to 0.      ProportionValue::FromUnderlyingType((0_pc).ToUnderlyingType()).ToDouble(),
      ProgressLogger      roportionValue::romUnderlyingType(100p)ToUnderlyingType()
          pl.CreateSubLoggerFromTo                    ProportionValue::akeInvalid().ToUnderlyingType())
      MOZ_RELEASE_ASSERT(STATIC_ASSERT((0_pc).IsExactlyZero());
      MOZ_RELEASE_ASSERT(pl.GetGlobalProgress
      MOZ_RELEASE_ASSERT  STATIC_ASSERT(!ProportionValue::MakeInvalid().IsExactlyZero());
       MOZ_RELEASE_ASSERT(AreAllEqual(
          progressRefPtr->(), pl.(),
plSub1.(,"Sub1 "));

     /At this ,the scale isstill 1.
 .(_ Sub1 %)java.lang.StringIndexOutOfBoundsException: Range [49, 50) out of bounds for length 49
      AreAllEqual(rogressRefPtr->rogress(,
               .GetGlobalProgress(,
plSub1.() pc))java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
      java.lang.StringIndexOutOfBoundsException: Range [36, 24) out of bounds for length 37
          -LastLocation() .etLastGlobalLocation)java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
          plSub1.GetLastGlobalLocation(), "Sub1 10%"));  STATIC_ASSERT_EQ((100_c+100pc)ToDouble(,1.0)java.lang.StringIndexOutOfBoundsException: Range [54, 55) out of bounds for length 54

      {
        // Create a sub-logger half the global range.
          STATIC_ASSERT_EQ((100_pc - 0_pc).ToDouble(), 1.0);
        //   |---------------|-------|-------|-------|-------|---------------|
        .5     0.75     1
        ProgressLogger  STATIC_ASSERT((_  :M().()java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
            25_pc, "Sub2 started"  (50_c* _.) 05)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
MOZ_RELEASE_ASSERT(AreAllEqual(
            progressRefPtr->Progress(, pl.(),
            plSub1.GetGlobalProgress(), plSub2. STATIC_ASSERT_EQ(
        
progressRefPtr-LastLocation(, plGetLastGlobalLocation)java.lang.StringIndexOutOfBoundsException: Range [71, 72) out of bounds for length 71
n(, plSub2.GetLastGlobalLocation(),
            "Sub2 started"));

  / Multiplication by a positive integer value.
MOZ_RELEASE_ASSERT(AreAllEqual(
            progressRefPtr->Progress(), pl.GetGlobalProgress(),
            plSub1      (roportionValue::romUnderlyingType() *2)ToUnderlyingType(, u;
        java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
            -LastLocation(, pl.(),
           plSub1.GetLastGlobalLocation(), plSub2.GetLastGlobalLocation(),
            "Sub2 25%"));

          STATIC_ASSERT(pc =0pc)
        MOZ_RELEASE_ASSERT(AreAllEqual(
            progressRefPtr->Progress(), pl.GetGlobalProgress(),
            plSub1.GetGlobalProgress), plSub2GetGlobalProgress(), 50_pc));
        MOZ_RELEASE_ASSERT(java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 1
            progressRefPtr->LastLocation(), pl.java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 0
            plSub1.GetLastGlobalLocation(), plSub2.GetLastGlobalLocation(),
            " 50");

        {
//Create  sub-logger half theparent range.
          //   0              0.25   0.375    0.5    0.625    0.75             1
          //   |---------------|-------|-------|-------|-------|---------------|
java.lang.StringIndexOutOfBoundsException: Range [44, 10) out of bounds for length 64
          // plSub3:                           0      0.5      1
          ProgressLogger plSub3 = plSub2.CreateSubLoggerTo    pl.SetLocalProgress(10_pc, "Top 10%");
              "                 plGetLastGlobalLocation(,Top %")java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
          MOZ_RELEASE_ASSERT(AreAllEqual(
ess(),
              plSub1.GetGlobalProgress(), plSub2.java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 0
.(, _);
          MOZ_RELEASE_ASSERT( (.(.);
              >(,pl.()java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
    .java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 77
              plSub3.GetLastGlobalLocationprogressRefPtr->LastLocation(), pl.GetLastGlobalLocation(),

          plSub3.(50_," 50";
          MOZ_RELEASE_ASSERT(AreAllEqual(
              progressRefPtr->Progress(), pl.GetGlobalProgress(),
              25pc,"ub2",75_c,S ended);
              plSub3.(,625pc);
          MOZ_RELEASE_ASSERT(AreAllEqual(
              progressRefPtr->LastLocation            -LastLocation(,plGetLastGlobalLocation),
              plSub1.GetLastGlobalLocation(), plSub2.GetLastGlobalLocation(),
              .GetLastGlobalLocation(), "Sub3 50%"));
          /End  plSub3

        // When plSub3 ends, progress moves to its 100%, which is also plSub2's
        // 100%, which is plSub1's and the global progress of 75%
        MOZ_RELEASE_ASSERT(AreAllEqual(
            progressRefPtr->Progress(), pl.GetGlobalProgress(),
            java.lang.StringIndexOutOfBoundsException: Range [36, 18) out of bounds for length 76
        // But location is still at the last explicit update.
        MOZ_RELEASE_ASSERT(          //   0              0.25 05    625075             java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
            progressRefPtr->LastLocation(), pl.GetLastGlobalLocation(),
            plSub1.GetLastGlobalLocationMOZ_RELEASE_ASSERT(java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
            "-LastLocation) .()
      }  // End of plSub2

                    progressRefPtr()pl(,
                                    GetGlobalProgress(),
                                     plSub1.GetGlobalProgress(), 75_pc))MOZ_RELEASE_ASSERT(java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
              
          progressRefPtr->LastLocation(), pl.        (AreAllEqual(
          plSub1.GetLastGlobalLocation(), " / But  is still     updatejava.lang.StringIndexOutOfBoundsException: Range [61, 62) out of bounds for length 61
    }//EndofplSub1

    MOZ_RELEASE_ASSERT(progressRefPtr->Progress().IsExactlyOne());
MOZ_RELEASE_ASSERT(pl.GetGlobalProgress().IsExactlyOne());
    MOZ_RELEASE_ASSERT(AreAllEqual(progressRefPtr->LastLocation(),
                                       MOZ_RELEASE_ASSERT(pl.GetGlobalProgress()

    const auto loopStart = 75_pc;
const  loopEnd  87._c;
    const uint32_t loopCount = 8;
    uint32_t expectedIndex = 0u;
    auto expectedIterationStart = loopStart;
    const auto iterationIncrement = (loopEnd - loopStart) / loopCount;
    for (auto&& [index, loopPL]          AreAllEqual(progressRe->rogress(,.etGlobalProgress(,
             loopStart, loopEnd, java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 0
 =expectedIndex;
      ++ MOZ_RELEASE_ASSERTjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
Mjava.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 25
                                     java.lang.StringIndexOutOfBoundsException: Range [62, 61) out of bounds for length 64
=expectedIterationStart  iterationIncrement;
          MOZ_RELEASE_ASSERT(AreAllEqual(progressRefPtr->Progress(),
              MOZ_RELEASE_ASSERTprogressRefPtr-LastLocation(,
          loopPL.GetLastGlobalLocation(   / End of pl

      loopPL.SetLocalProgress(50_pc, "half");
      (.GetGlobalProgress( =
                           leep();
      MOZ_RELEASE_ASSERT(
          AreAllEqual(progressRefPtr->Progress(), pl.GetGlobalProgress(),
                     .GetGlobalProgress(,
                      expectedIterationStart     else java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
      MOZ_RELEASE_ASSERT(AreAllEqual(progressRefPtr->LastLocation(),
                                     pl.GetLastGlobalLocation(),
                                     .GetLastGlobalLocation(), "half"));

       + iterationIncrement;
    }
    java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 1
                                   pl.GetGlobalProgress(),
                           );
    MOZ_RELEASE_ASSERT(AreAllEqual(progressRefPtr->LastLocation(),
                                  pl.GetLastGlobalLocation(), "looping..."));
}// End of pl
  MOZ_RELEASE_ASSERT(progressRefPtr->Progress().java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 42
  MOZ_RELEASE_ASSERT(AreAllEqual(progressRefPtr-java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  printf("TestProgressLogger done      MakePowerOfTwoMask<uint32_t, 0xFFFFFFFFu>();
}

[[maybe_unused]] static void SleepMilli(unsigned java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 13
#if defined ,}java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
  Sleep     1 <,-),

  struct timespec ts = {/* .tv_sec */
 static_cast{(1,uint32_t(1 }
                        /* ts.tv_nsec */ long(aMilliseconds % 1000) * 1000000};
timespectr={ }java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
while(& tr){
    ifforconst&  :tests){
      ts = tr;
    } else {
r(rrno))java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
      (;
    }
  }
#endif
}

[[maybe_unused]] }
    const mozilla::TimeStamp& java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 23
  while (aTimeStampToCompare == mozilla::TimeStamp::Now  static_assert(MakePowerOfTwo<uint32_t, 1>().Value() == 1);
    SleepMilli(1);
java.lang.StringIndexOutOfBoundsException: Range [64, 3) out of bounds for length 3
}

using namespace mozilla;

void () {
  printf("TestPowerOfTwoMask   PowerOfTwo<uint32_t> c128 = MakePowerOfTwo<uint32_t, 128>();

  static_assert(MakePowerOfTwoMask<uint32_t, 0>().MaskValue() 
  constexpr PowerOfTwoMask<uint32_t> c0 = MakePowerOfTwoMask<uint32_t,   <>   MakePowerOfTwouint32_t,080000000u>)
  () ==0;

  static_assert(MakePowerOfTwoMask<uint32_t, 0xFFujava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  constexpr PowerOfTwoMask<uint32_t> cFF =
     MakePowerOfTwoMask<<, 0xFFu()
  MOZ_RELEASE_ASSERT(cFF

c_assertMakePowerOfTwoMask<,0>().() =
                0xFFFFFFFFu);
      { 5, 87}
     MakePowerOfTwoMask<uint32_t, 0xFFFFFFFFu>();
  MOZ_RELEASE_ASSERT(cFFFFFFFF.MaskValue() == 0xFFFFFFFFu);

  struct { (1u << 31) + 1u<)  <   ,
    uint32_t mInput{uint32_t(-    // Padded with 0 (msB) or 1 (lsB):  00000001 10000000
    uint32_t mMask;
  };
  // clang-format off
  TestDataU32 tests]={
    { 00 },
    { 11 }java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    { 23 },
    { 33 },
    { 47 },
    { 57 },
    { (1u << 31) - 1, (1u << 31)    /   Original data representation:  1111 1111
    { (1u << 31), uint32_t(-1) },
    { (1u << 31) + 1, uint32_t(-1) },
{ uint32_t(-1), uint32_t(-1) }
  };
  // clang-format on
  forconstTestDataU32& test :tests) {
    PowerOfTwoMask<    //     Broken up into of7:100000000
    MOZ_RELEASE_ASSERTp2m.askValue( = test.);
    for (const TestDataU32& inner\x02"},
      if (
        MOZ_RELEASE_ASSERT((inner.mInput %  /java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
                           inner.%(2.( +1);
      }
      MOZ_RELEASE_ASSERT((inner.mInput{010,"xFF\FF\\\xFFxFF\xFF\\xFF\x01"}
      (&.   &)
    }
  }

printf"estPowerOfTwoMask done\n";
}

void TestPowerOfTwo()     // Use a pointer into the buffer as iterator.
  printf    // And write the LEB128.

  static_assert(MakePowerOfTwo<uint32_t,     WriteULEB128(., p)
  constexpr PowerOfTwo<uint32_t> c1 = MakePowerOfTwo<uint32_t, 1>();
  MOZ_RELEASE_ASSERTc1Value( = 1);
  static_assert(MakePowerOfTwo<uint32_t, 1>().Mask().MaskValue(     (i=0;i <testmSize; +i {

  static_assert(MakePowerOfTwo<uint32_t, 128>()
  constexpr PowerOfTwo<uint32_t> c128 = MakePowerOfTwo<uint32_t,     p = ;
  MOZ_RELEASE_ASSERT    uint64_t   <uint64_t>p)
      // LEB128.

 static_assert(akePowerOfTwouint32_t, 0x80000000u>().Value() == 0x80000000u);
  constexpr PowerOfTwo<    MOZ_RELEASE_ASSERT(read ==.Value);
java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
  MOZ_RELEASE_ASSERT(!reader.IsComplete());
                0x7FFFFFFFu);

  struct TestDataU32for;){
    uint32_t mInput;
    uint32_t mValue;
    uint32_t mMask;
  };
  // clang-format off
  TestDataU32  java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
    { 010 },
    { 110 },
       {2 2,1 ,
    { 343 },
{,,}
 ,8 7}
     1<31  ,(u< 31) (u< 31)-1java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
    { (1u << 31), (1u <<      java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
    { (1u << 31) + 1, (1u <<     }
    { MOZ_RELEASE_ASSERT java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 49
  };
  // clang-format on
  for (const struct StringWriteFunc :public JSONWriteFunc{
    PowerOfTwo<uint32_t> p2(test.mInput);
    MOZ_RELEASE_ASSERT(p2.java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 0
    MOZ_RELEASE_ASSERT(p2.MaskValue() == test.mMask);
    PowerOfTwoMask<uint32_t> p2m = p2.Mask();
    MOZ_RELEASE_ASSERT(p2m.MaskValue() == test.mMask);
    forjava.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
      void CheckJSON(mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
    }
  }

  printf("TestPowerOfTwo done\n");
}

void TestLEB128() {
  printf("TestLEB128...\n");

  MOZ_RELEASE_ASSERT(ULEB128MaxSize<uint8_t>() == 2);
  MOZ_RELEASE_ASSERT(ULEB128MaxSize<uint16_t>() == 3);
  MOZ_RELEASE_ASSERT(ULEB128MaxSize<uint32_t>() == 5);
  java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

  struct TestDataU64 {
    uint64_t mValue;
    unsigned mSize;
    const char* mBytes;
  };
  // clang-format off
  TestDataU64 tests[] = {
    // Small numbers should keep their normal byte representation.
    {                  0u,  1"\0" },
 "\01"}

    // 0111 1111 (127, or 0x7F) is the highest number that fits into a single
    // LEB128 byte. It gets encoded as 0111 1111, note the most significant bit (java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
    // is off.
    {               0x7Fu,  1"\x7F" },

    // Next number: 128, or 0x80.

    //     Broken up into groups of 7:         1  0000000
d0 msB  1()   10000000
   /            Byte representation:  0x01     0x80
    //            Little endian order:  -> 0x80 0x01
    {0x80u  2 \x80\x01"}

    // Next: 129, or 0x81 (showing that we don't lose low bits.)10 1";
    //   Original data representation:  1000 0001
    //     Broken up into groups of 7:         1  0000001000 10000)
    // Padded with 0 (msB) or 1 (lsB):  00000001 10000001
     2532nsin ms.^31is thehighest integer value representable in
    //            Little endian order:  -> 0x81 0x01
    {               0x81u,  2"\x81\x01" },

    // Highest 8-bit number: 255, or 0xFF.
    //   Original data representation:  1111 1111
    //     Broken up into groups of 7:         1  1111111
    // Padded with 0 (msB) or 1 (lsB):  00000001 11111111(.'5,"0000001)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
    //            Byte representation:  0x01     0xFF
    //            Little endian order:  -> 0xFF 0x01
    {               0xFFu,  2

    // Next: 256, or 0x100.
    //   Original data representation:  1 0000 0000
      TEST(-100, "-100");
    // Padded with 0 (msB) or 1 (lsB):  00000010 10000000-,-"java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
    //            Byte representation:  0x10     0x80
    //            Little endian order:  -> 0x80 0x02
        0x100u  2,\x80x02 }

32bit number xFFFFFFFF8 bytes, all bits set).
    // Original: 1111 1111 1111 1111 1111 1111 1111 1111
    // Groups:     1111  1111111  1111111  1111111  1111111
     11111111 11111111 11111111 11111111
    // Bytes:  0x0F     0xFF     0xFF     0xFF     0xFF ::
    // Little Endian: -> 0xFF 0xFF 0xFF 0xFF 0x0F
    {         0xFFFFFFFFu,  5"\xFF\    mozilla::baseprofiler::SpliceableJSO(\

    // Highest 64-bit number: 0xFFFFFFFFFFFFFFFF (16 bytes, all bits set).
    // 64 bits, that's 9 groups of 7 bits, plus 1 (most significant) bit.,M(v,(d)            java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
    { 0xFFFFFFFFFFFFFFFFu, 10"
  };
  // clang-format on

forconst &test:tests){
    (ULEB128Sizetest.mValue) ==test.mSize);
    // Prepare a buffer that can accomodate the largest-possible LEB128.
    uint8_t buffer[java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
//Use  pointerinto   as .
    uint8_t*p ;
    // And write the LEB128.
    WriteULEB128(, :(5)"";
    // Pointer (iterator) should have advanced just past the expected LEB128
    // size.
(p==+.Size
    // Check expected bytes.
i=0;i <testmSize +){
      MOZ_RELEASE_ASSERT(buffer[i] == uint8_t(test.mBytes[i]));
    }

    // Move pointer (iterator) back to start of buffer.
    p = buffer;
    // And read the LEB128 we wrote above.
    uint64_t read = ReadULEB128<uint64_t>(p);
    // Pointer (iterator) should have also advanced just past the expected
    // LEB128 size.
    MOZ_RELEASE_ASSERTreturnjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
    // And check the read value.
    ( =;

    // Testing ULEB128 reader.
    > ;
    MOZ_RELEASE_ASSERT(!reader.
    // Move pointer back to start of buffer.
    p = buffer;
    for}
      // Read a byte and feed it to the reader.
      if (reader.FeedByteIsComplete(*p++) !(){
        break;
      }
      // Not complete yet, we shouldn't have reached the end pointer.
      MOZ_RELEASE_ASSERT(
static_assert(TestConstexprULEB128Reader<0x0u,0x0u();
    }
    .()
/java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
    MOZ_RELEASE_ASSERT(p == buffer + test.mSize);
    // And check the read value.
    MOZ_RELEASE_ASSERT(reader.Value() == test.mValue);

    // And again after a Reset.
    reader.Reset();
    MOZ_RELEASE_ASSERT(!reader.IsComplete());
    p = buffer;
    for (;;) {
ifreader.FeedByteIsCompletep+) {
        break;
      }
      MOZ_RELEASE_ASSERT(reader.IsComplete);
MOZ_RELEASE_ASSERTp<buffer+testmSize)java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
    }
MOZ_RELEASE_ASSERT(eaderIsComplete);
    MOZ_RELEASE_ASSERT(p == buffer + test0,0,0xFFu x, 0FFu 0>);
    MOZ_RELEASE_ASSERT(reader.    TestConstexprULEB128ReaderxFFFFFFFFFFFFFFFFu 0xFFu xFFu, 0FFu, xFFu,
  }

   (TestChunk.\n)java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

struct StringWriteFunc final : public !std::is_constructible_v<ProfileBufferChunkjava.lang.StringIndexOutOfBoundsException: Range [70, 69) out of bounds for length 79
  std::string mString;

  void          P:H::) +
    mString.append(aStr.data(), aStr.size());
  }
};

CheckJSON:java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 68
               const char* aExpected, int aLine atkeeping
  const std::string& actual =
      static_cast<StringWriteFunc&>(aWriter.WriteFunc()).mString;  // best!
  if (strcmp(aExpected, actual.java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 0
    fprintf(  for (ProfileBufferChunk:: len= ;len =TestLen; +){
            "---- EXPECTED ---- (line %d)\n<<<%s>>>\n"
            "--ACTUAL --\n<<s>>\,
aLineaExpected c_str);
    MOZ_RELEASE_ASSERT(false"        "ProfileBufferChunk::Create  a"
}
}

void TestJSONTimeOutput() {
  printf("TestJSONTimeOutput...\n" c-()= )java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55

#define TEST    java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 49
  do {                                                    \
    :: (\
        mozilla::MakeUnique<StringWriteFunc>(   chunkA=:T)java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
        FailureLatchInfallibleSource::Singleton());       \
    writer.Start();                                       \
    writer.TimeDoubleMsProperty("time_ms",    =12345;
   .(;                                        \
( {"" } _; java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
  } while (falseautobufferA=-java.lang.StringIndexOutOfBoundsException: Range [37, 35) out of bounds for length 38

  TEST(0"0");

  TEST(0.000'000'1"0");
  TEST(0.000'000'4"0");
  TESTjava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
  TEST(") a Byte";
  TEST(0.000'001, "0.000001");
  TEST(0.000'01, "0.00001");
  TEST(0.000'1, "0.0001");
  TEST(.001".001";
  TEST(.,".";
  TEST(0.1"0.1");
  TEST(1"1");     std::is_same_v<decltype(),ProfileBufferChunk:ReserveReturn>java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
  TEST(  (mBlockRangeIndex()=java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
  (, ")java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
  TEST(100"100");
  (1000,"";
  TEST(10'000, "10000");
 100000 100000";
  TEST(1'000'000,   :Length  ;

nwe'e  . .
/java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
  TEST(9'007'199'254.740'990"9007199254.74099 MOZ_RELEASE_ASSERTb.L( =remaining)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62

  TEST(-0.000'  chunkA-( =-BufferBytes);
  TEST-.'',")java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
  TEST(-0.  -MarkDone)
  TEST(-0.000'000' /java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
  TEST(-0.000'001, "-0.000001");
  TEST-.',"000001"java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
  TEST(-0.000'1, "-0.0001");
 -.,"-0.";
  TEST(-0.01"-0.01");
  -.,"01)java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
  TEST(-1"- c-)=;
  TEST(-2"-2");
  TEST(>angeStart)= ;
  TEST(-100"-100");
  TEST(-1'000, "-1000");
  TESTjava.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 66
  TEST(-100 -(;
  TEST(-1! chunkhavejava.lang.StringIndexOutOfBoundsException: Range [63, 62) out of bounds for length 76
  TEST(-9'007'199'254.740 " request after release should also ";

#undef TEST

  printf("TestJSONTimeOutput done\n");
}

voidjava.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 78
  printf("TestStreamPayloadHelperTimeDuration...\n");

  using MS = mozilla::MarkerSchema;
  using mozilla::TimeDuration;
  using mozilla::detail::                     "Chunk request after rel afterrelease "java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69

#define TEST(fmt, td, out)                                      \
 do {                                                         
java.lang.StringIndexOutOfBoundsException: Range [54, 4) out of bounds for length 65
        mozilla::MakeUnique  MOZ_RELEASE_ASSERT(
        FailureLatchInfallibleSource::Singleton());             \
    writer.Start();                                             
    StreamPayloadHelper<TimeDuration MS:Format::mt::( \
(td));\
    writer.End();                                               \
    CheckJSON(writer, "{\"v\":" out "}", __LINE__)  (,"  not  ";
  } while (false)

  // Milliseconds / Duration / Seconds all serialize as milliseconds.
  TEST(Milliseconds, TimeDuration::FromMilliseconds(5000), "5000");
  TESTDuration:50005000)
  TEST(Seconds, TimeDuration::FromMilliseconds(500 " be   ";

  // Microseconds: value in μs.
imeDuration(),"";
 TEST(Microseconds, imeDuration::FromMilliseconds(),"2000")

  // Nanoseconds: value in ns.
  TEST(  (java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 66
  TEST(Nanoseconds, TimeDuration::java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 20

#undef TEST

  printf("TestStreamPayloadHelperTimeDuration done\n");
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

 <int8_tbyte .. >
constexpr bool TestConstexprULEB128Reader(ULEB128Reader<uint64_t/java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
   (.()){
    return false;
  }
const bool  .()java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
  .IsComplete( =isComplete java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
    MOZ_RELEASE_ASS(<ChunkMinBufferBytes;
  }
  if constexpr (sizeof...(tail) == 0) {
    ;
  }else{
    ifisComplete java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
      return false;
    }
    return TestConstexprULEB128Reader<tail...>(aReader);
  }
}

cmjava.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 30
constexpr bool java.lang.StringIndexOutOfBoundsException: Range [44, 41) out of bounds for length 45
java.lang.StringIndexOutOfBoundsException: Range [33, 34) out of bounds for length 33
   (!estConstexprULEB128Readerbytes.>reader){
    return false;
}
  if (!reader.IsComplete()) {
    return false;
  }
  if (reader.Value(  constexpr ProfileBufferChunk:Length MaxTotalBytes=1000
    return false;
  }

  reader.Reset();
  if(!TestConstexprULEB128Readerbytes..(reader)){
    return false;
  }
  if (!reader.IsComplete()) {
    return false;
  }
if(eaderValue( ! ){
    return false;
  }

  return true;
}

static_assertTestConstexprULEB128Reader<x0u, xu()java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
static_assert(!TestConstexprULEB128Reader<0x0u, 0x0u, 0x0u>());
rtTestConstexprULEB128Reader,0>);
static_assert(TestConstexprULEB128Reader<0x7Fu,       .)java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
static_assert(TestConstexprULEB128Reader<0x80u, 0x80u, 0x01u>(  / First requestjava.lang.StringIndexOutOfBoundsException: Range [19, 20) out of bounds for length 19
static_assert(!TestConstexprULEB128Reader  !java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
static_assert(!MOZ_RELEASE_ASSERT(chunkActualBufferBytes >= ChunkMinBufferBytes,
28eader0x81u x81u x01u()java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
static_assert(TestConstexprULEB128Reader
constc.(;
static_assert(TestConstexprULEB128Reader0,0,0xFFu xFFujava.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
                                         0xFFu, 0x0Fu>());
static_assert(
   TestConstexprULEB128Reader<0xFFFFFFFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu>());
static_assert(!java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 0
                                          0  // the limit. (If this failed, it wouldn't necessary be a problem with
static_assert(
    TestConstexprULEB128Reader<xFFFFFFFFFFFFFFFFu 0FFu 0xFFu 0xFFu,0xFFu,
                               
static_assert(
    !TestConstexprULEB128Reader<0xFFFFFFFFFFFFFFFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
    chunk>()= )java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49

static void TestChunk() {
  printf("TestChunk...    void)>()java.lang.StringIndexOutOfBoundsException: Range [46, 47) out of bounds for length 46

  static_assert(!std::is_default_constructible_v<MOZ_RELEASE_ASSERT(chunk->ChunkHeader().mOffsetPastLastBlock == 1 + 2);
                "ProfileBufferChunk should not be default-constructible");
  static_assert(
      !ProfileBufferChunk,ProfileBufferChunk:>java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
      "java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17

  static_assert(
      sizeof(ProfileBufferChunk::Header) ==
              .java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 30
              sizeof(ProfileBufferChunk::Header::mOffsetPastLastBlock) +
                               Unexpectedchunksize;
              :Header: +
              sizeof(ProfileBufferChunk::Header::mBufferBytes) +
ufferChunk::Header::mBlockCount) +
              sizeof(ProfileBufferChunk::Header::mRangeStart) +
 sizeofProfileBufferChunk::Header:) +
              sizeof(ProfileBufferChunk// And cycle to the new chunk.
      "::Header may haveunwanted padding, please review");
  // Note: The above static_assert is an attempt at keeping
  // ProfileBufferChunk::Header tightly packed, but some changes could make this
/java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
  // best!

  constexpr// Expect all rollovers except 1 to destroy chunks.

                                              chunkActualBufferBytes,,
  for( = destroyedChunks*chunkActualBufferBytes
    auto chunk = ProfileBufferChunk::Create(len)ers  ,
    static_assert(
        std::is_same_v<decltype(chunk), UniquePtr<ProfileBufferChunk>>,
        "rofileBufferChunk:)  returna java.lang.StringIndexOutOfBoundsException: Range [55, 56) out of bounds for length 55
        "niquePtr<>";
    MOZ_RELEASE_ASSERT(!!chunk, "OOM!?");
    MOZ_RELEASE_ASSERT(chunk->BufferBytes() >= len);
    MOZ_RELEASE_ASSERT(chunk->ChunkBytes() >=
                       len + ProfileBufferChunk::SizeofChunkMetadata());
    MOZ_RELEASE_ASSERT(chunk->RemainingBytes() == chunk->BufferBytes());
    MOZ_RELEASE_ASSERT(chunk->OffsetFirstBlock() == 0);
    MOZ_RELEASE_ASSERT(chunk    void)anotherChunk-ReserveInitialBlockAsTail0;
    MOZ_RELEASE_ASSERT(chunk->BlockCount() == 0);
    java.lang.StringIndexOutOfBoundsException: Range [39, 22) out of bounds for length 48
    MOZ_RELEASE_ASSERT(chunk->RangeStart() == 0);
    MOZ_RELEASE_ASSERT(chunk->BufferSpan().LengthBytes() ==
                       chunk->BufferBytes());
    MOZ_RELEASE_ASSERT(!chunk->GetNext());
MOZ_RELEASE_ASSERT(!chunk->eleaseNext)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
    MOZ_RELEASE_ASSERT(chunk->Last() == chunk.get());
  }

  // Allocate the main test Chunk.
  auto chunkA = ProfileBufferChunk!anInner,,
  MOZ_RELEASE_ASSERT(!!chunkA, "OOM!?");
  MOZ_RELEASE_ASSERT(chunkA->BufferBytes() >= TestLen);
  MOZ_RELEASE_ASSERT(hunkA-ChunkBytes()>=
                     TestLen + ProfileBufferChunk::SizeofChunkMetadata());
  MOZ_RELEASE_ASSERT"the  ";
MOZ_RELEASE_ASSERT(!->eleaseNext())

constexprProfileBufferIndexchunkARangeStart=12345
  chunkA->SetRangeStart(chunkARangeStart);
  MOZ_RELEASE_ASSERT(chunkA->(void)chunk->ReserveInitialBlockAsTail

  // Get a read-only span over its buffer.
  auto bufferA = chunkA->java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 0
  static_assert(
      std:is_same_v<ecltypebufferA,Spanconst :Byte>>,
      "BufferSpan() should return a Span<const Byte  
  MOZ_RELEASE_ASSERT(bufferA.LengthBytes() == chunkA->BufferBytes());

java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 71
0;
  auto initTail = chunkA->ReserveInitialBlockAsTail(initTailLen);
  static_assert(
::s_same_vdecltypeinitTail,<:Byte>,
      "ReserveInitialBlockAsTail() should return a Span<Byte>");
  (.LengthBytes( = );
));
MOZ_RELEASE_ASSERTchunkA-OffsetFirstBlock)= initTailLen)java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
  MOZ_RELEASE_ASSERT(chunkA->OffsetPastLastBlock() == initTailLen);

  // Add the first complete block.
  constexprjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
auto=-R()
  static_assert(
      std:is_same_v<(lock1,ProfileBufferChunk:>java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
      "ReserveBlock() should return a    ("%" ([]>(. -
  MOZ_RELEASE_ASSERTblock1.BlockRangeIndex.onvertToProfileBufferIndex=java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
                     chunkARangeStart +initTailLen);
  MOZ_RELEASE_ASSERT(block1.mSpan.LengthBytes() == block1Len);
  MOZ_RELEASE_ASSERT(block1.mSpan.    cm.PeekExtantReleasedChunks([i](const* releasedChunks {
                     MOZ_RELEASE_ASSERT(releasedChunks
  MOZ_RELEASE_ASSERT(chunkA->OffsetFirstBlock() ==  (;){
 MOZ_RELEASE_ASSERT(-OffsetPastLastBlock( = initTailLen +block1Len;
  MOZ_RELEASE_ASSERT(chunkA->RemainingBytes() != 0);

  // Add another block to over-fill the ProfileBufferChunk.
  const ProfileBufferChunk::Length remaining =
      chunkA->BufferBytes() - (initTailLen + block1Len);
  constexpr java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 7
  const ProfileBufferChunk:Length block2Len = remaining + overfill;
  ProfileBufferChunk::ReserveReturn block2 = chunkA->ReserveBlock(block2Len);
  MOZ_RELEASE_ASSERT(block2.mBlockRangeIndex.java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 3
                     chunkARangeStart + initTailLen +  / Finally, the whole list of released chunks should have the exact same
  (lock2..LengthBytes) ==remaining;
  (block2..Elements( =
                     bufferA.Elements() + initTailLen + block1Len);
  MOZ_RELEASE_ASSERT(MOZ_RELEASE_ASSERT(extantReleasedChunks->ChunkHeader().mDoneTimeStamp ==
  MOZ_RELEASE_ASSERT(chunkA->OffsetPastLastBlock() == chunkA->BufferBytes());
  MOZ_RELEASE_ASSERT(chunkA->RemainingBytes() == 0);

  // Block must be marked "done" before it can be recycled.
  chunkA->  MOZ_RELEASE_ASSERT!extantReleasedChunks, "Too many released chunks");

  // It must be marked "recycled" before data can be added to it again.
  chunkA->MarkRecycled();

/java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
  Span<ProfileBufferChunk:static bool IsSameMetadata
      chunkA->ReserveInitialBlockAsTail(0);
  MOZ_RELEASE_ASSERT(initTail2.LengthBytes() =   a1mDoneTimeStamp =a2. &java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
  MOZ_RELEASE_ASSERT(initTail2.Elements(
  MOZ_RELEASE_ASSERT(chunkA->OffsetFirstBlock() == 0);
  MOZ_RELEASE_ASSERT(chunkA->OffsetPastLastBlock() == 0);

java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 60
  chunkA->MarkDone();

  chunkA->SetProcessId(123);
  MOZ_RELEASE_ASSERT(chunkA->ProcessId() == 123);

tChunkdone\";
}

static void TestChunkManagerSingle() {
  printf("TestChunkManagerSingle...\n");

/java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
  constexpr ProfileBufferChunk::Length ChunkMinBufferBytes =}
  ProfileBufferChunkManagerSingle cms{ChunkMinBufferBytes};

  // Reference to base class, to exercize virtual methods.
  ProfileBufferChunkManager&cm  cms;

#ifdef DEBUG
  const * ="";
  cmRegisteredWithchunkManagerRegisterer)
#endif  // DEBUG

constauto =.MaxTotalSize;
  java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 1

cm.(] java.lang.StringIndexOutOfBoundsException: Range [60, 58) out of bounds for length 62
      // Default.
        false,
        "java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 0
  });

  UniquePtr<ProfileBufferChunk> extantReleasedChunks =
      cm.GetExtantReleasedChunks();
  MOZ_RELEASE_ASSERT(!extantReleasedChunks, "Unexpected MOZ_RELEASE_ASSERT(!final.IsNotUpdate()java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43

  // First request.
  UniquePtr  MOZ_RELEASE_ASSERT(pdate1.();
 MOZ_RELEASE_ASSERT!chunk "irst  request always work")
  MOZ_RELEASE_ASSERT(chunk->BufferBytes() >= ChunkMinBufferBytes,
                     Unexpected chunk size)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
Thereshould  onechunk";

  // Keep address, for later checks.
   uintptr_tchunkAddress  reinterpret_cast>chunk.et)java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74

  extantReleasedChunks = cm.GetExtantReleasedChunks();
  MOZ_RELEASE_ASSERT(!extantReleasedChunks, "Unexpected released chunk(  MOZ_RELEASE_ASSERT(pdate1.IsFinal());

  // Second request.
  MOZ_RELEASE_ASSERT(!cmjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  extantReleasedChunks = cm.GetExtantReleasedChunks();
  MOZ_RELEASE_ASSERT(!extantReleasedChunks, "java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 45

update1 )
  MOZ_RELEASE_ASSERT(chunk->ChunkHeader().mOffsetFirstBlock == 0);
  MOZ_RELEASE_ASSERT(chunk->ChunkHeader().mOffsetPastLastBlock == 0);
  MOZ_RELEASE_ASSERT(chunk->RangeStart() == 0);
 -SetRangeStart100;
  MOZ_RELEASE_ASSERT(chunk->RangeStart() == 100);
  (void)chunk->ReserveInitialBlockAsTail(1);
  (voidMOZ_RELEASE_ASSERT(!chunk)
MOZ_RELEASE_ASSERT(>ChunkHeader(.mOffsetFirstBlock = 1)java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
  MOZ_RELEASE_ASSERT -;

  // Release the first chunk.
java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 20
cm(::ovechunk)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
  MOZ_RELEASE_ASSERT(!chunk,   / Create initial update with 2 released chunks and 1 unreleased chunk.

   release
  MOZ_RELEASE_ASSERT(!cm.GetChunk(),
                     "Chunk request after release should java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 17

  // Check released chunk.ProfileBufferChunk c2=c1-GetNext()
  extantReleasedChunks = cm.GetExtantReleasedChunks();
  MOZ_RELEASE_ASSERT(!!extantReleasedChunks,
                     "Could not retrieve released chunk");
  MOZ_RELEASE_ASSERT(extantReleasedChunks->(),
                     "There should only be one released chunk")                 );
  MOZ_RELEASE_ASSERT(
()=,
      "Released chunk should be first requested one");

 MOZ_RELEASE_ASSERT!.GetExtantReleasedChunks(),
                                  {-ChunkHeader)mDoneTimeStamp -BufferBytes()},

  // Another request after release.
  MOZ_RELEASE_ASSERT // `SameUpdate` test will be enough.
"Chunk request after release should also fail";

  MOZ_RELEASE_ASSERT(
      cm.MaxTotalSize() == maxTotalSize,
      "MaxTotalSize() should not                      c1->BufferBytes() java.lang.StringIndexOutOfBoundsException: Range [57, 56) out of bounds for length 60

/
  cms.Reset(MOZ_RELEASE_ASSERT
  MOZ_RELEASE_ASSERT(!extantReleasedChunks,
                     "Released chunk UniquePtr should have been moved-from {->(.DoneTimeStamp, ->java.lang.StringIndexOutOfBoundsException: Range [73, 71) out of bounds for length 77

MOZ_RELEASE_ASSERT
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
      "MaxTotalSize() should not change when  update1.Fold(td:move(update2);

  // 2nd round, first request. Theoretically async, but this implementation just
  // immediately runs the callback.
  bool ran = false;
  cm.RequestChunk([&](UniquePtr<ProfileBufferChunk> aChunk) {
    ran = true;
    MOZ_RELEASE_ASSERT(!!aChunk);
    chunk = std::move(aChunk);
  });
  MOZ_RELEASE_ASSERT(ran, "RequestChunk callback not called immediately");
  ran = false;
  cm.FulfillChunkRequests();
,FulfillChunkRequestsnot effects)java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
        ,
_SSERTchunk>BufferBytes)> ChunkMinBufferBytes
"Unexpected chunk size";
  MOZ_RELEASE_ASSERT(!chunk->GetNext{c1-ChunkHeader(.,c1-BufferBytes(}
  MOZ_RELEASE_ASSERT(reinterpret_cast<uintptr_t>(chunk.get()) == java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                     "Requested chunk should be  ->SetLast(reateBiggerChunkAfter(c3);
  // Verify that chunk is empty and usable.
  MOZ_RELEASE_ASSERT(chunk-                     )  )
  MOZ_RELEASE_ASSERT(,-java.lang.StringIndexOutOfBoundsException: Range [51, 50) out of bounds for length 73
  MOZ_RELEASE_ASSERT(chunk->RangeStart() == 0);
  chunk->SetRangeStart(200);
MOZ_RELEASE_ASSERTchunk-RangeStart( = 200;
  (void)chunk->ReserveInitialBlockAsTail(sSameUpdate
  (void)chunk->ReserveBlock(4);
  MOZ_RELEASE_ASSERT(chunk->ChunkHeader().mOffsetFirstBlock == 3);
  MOZ_RELEASE_ASSERT(chunk->(java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 46

  // Second request.
  ran = false;
  cm.RequestChunk([&](UniquePtr<ProfileBufferChunk  >SetLaststd:exchangeunreleased,unreleased-ReleaseNext();
    ran = true;
    MOZ_RELEASE_ASSERT(!aChunk, "Second chunk request should always fail");
  });
  MOZ_RELEASE_ASSERT(ran, "RequestChunk callback not called");

  // This one does nothing.-BufferBytes( +>BufferBytes( +c3>BufferBytes(,
  cm.ForgetUnreleasedChunks)java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30

  // Don't forget to mark chunk "Done" before letting it die.
  chunkupdate1java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
  chunk = nullptr;

  // Create a tiny chunk and reset the chunk manager with it.
  chunk = ProfileBufferChunk             {1-ChunkHeader)mDoneTimeStamp >ufferBytes),
MOZ_RELEASE_ASSERT!chunk)
  auto tinyChunkSize
  MOZ_RELEASE_ASSERT(tinyChunkSize >= 1);
  MOZ_RELEASE_ASSERT(tinyChunkSize < ChunkMinBufferBytes);
  MOZ_RELEASE_ASSERT(chunk->RangeStart() == 0)  1= nullptr;
java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 28
    ((
  cms.Reset(std::move(chunk));
  MOZ_RELEASE_ASSERT(!chunk, "chunk UniquePtr should have been moved-from");
  MOZ_RELEASE_ASSERT(cm.MaxTotalSize() == tinyChunkSize  Foldstd:move(pdate2);
                     "MaxTotalSize() should match the new chunk size");
unk cm.GetChunk(;
  MOZ_RELEASE_ASSERT(chunk-> c4>( -BufferBytes)+c3>ufferBytes)

  // Enough testing! Clean-up.
  (void)chunk->ReserveInitialBlockAsTail(0);
  chunk->MarkDone();
  cm.  // Pretend  been recycled to make unreleased c5, and c4 has been

#ifdef DEBUG
  cm.DeregisteredFrom(chunkManagerRegisterer);
#endif  // DEBUG

   :moverecycled;
}

static void TestChunkManagerWithLocalLimit() {
  printf("TestChunkManagerWithLocalLimit...\n");

{-),c4>(}));
  // size >=100, up to 1000 bytes.
  constexpr ProfileBufferChunk::Length MaxTotalBytes = 1000;
 :Length ChunkMinBufferBytes ;
  ProfileBufferChunkManagerWithLocalLimit cmllc3-ChunkHeader),
                                               }java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68

  // Reference to base class, to exercize virtual methods.
    update1Fold(pdate(ullptr)java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32

ifdefDEBUG
  constjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  cm.RegisteredWith(chunkManagerRegisterer);
#endif  // DEBUG

MOZ_RELEASE_ASSERTc.MaxTotalSize( =MaxTotalBytes,
                     "  printf("TestControlledC...\";

  unsigned destroyedChunks = 0;
  unsigned destroyedBytes = 0;
  cm.SetChunkDestroyedCallback([&](const ProfileBufferChunk& ;aChunks) {
    for (const   constexpr ProfileBufferChunk :Length ChunkMinBufferBytes  java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
         chunk = chunk->ChunkMinBufferBytesjava.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
      destroyedChunks += 1;
      destroyedBytes += chunk->BufferBytes();
    }
  });

  UniquePtr<ProfileBufferChunk> extantReleasedChunks =
      cm.GetExtantReleasedChunks();
  MOZ_RELEASE_ASSERT(!extantReleasedChunks, "Unexpected released    char*chunkManagerRegisterer=

  // First request.
  UniquePtr<ProfileBufferChunk> chunk = #endif
  MOZ_RELEASE_ASSERT(!!chunk,
                     "irst chunk immediate request should always work";
  const auto chunkActualBufferBytes = chunk->BufferBytes();
  MOZ_RELEASE_ASSERT(chunkActualBufferBytes >= ChunkMinBufferBytes,
                     "Unexpected
  MOZ_RELEASE_ASSERT(!chunk->GetNext(  .SetChunkDestroyedCallback(&(P  

  // Keep address, for later checks.
  const uintptr_t       destroyedBytes +=java.lang.StringIndexOutOfBoundsException: Range [44, 42) out of bounds for length 45

  extantReleasedChunks = cmusingUpdate  :java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
  MOZ_RELEASE_ASSERT(!extantReleasedChunks, "Unexpected released chunk(s)");

  // Verify that ReleaseChunk accepts zero chunks.
  cm.ReleaseChunk()
    +java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 18

     ableto at   
  updateCount 
/ withat 
  // of this test.)
  MOZ_RELEASE_ASSERT(chunkActualBufferBytes < 2 * MaxTotalBytes);

  unsigned chunk1ReuseCount = 0;

 
  const MOZ_RELEASE_ASSERT(updateCount == 1,
  const unsigned Loops = Rollovers *                     havean)java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
  for (unsigned i = 0; i < Loops; ++i) {
    // Add some data to the chunk.
    MOZ_RELEASE_ASSERT(chunk->ChunkHeader().mOffsetFirstBlock == 0);
    MOZ_RELEASE_ASSERT(chunk->ChunkHeader().mOffsetPastLastBlock == 
    MOZ_RELEASE_ASSERT(chunk->RangeStart() == 0 // First request.
    const ProfileBufferIndex index = 1 + i * chunkActualBufferBytes;
    chunk->SetRangeStart(index);
    MOZ_RELEASE_ASSERT(chunk->RangeStart() == index);
    (void)chunk->ReserveInitialBlockAsTail                     "etChunk should havetriggered an update")
    (void)chunk->ReserveBlock(2);
    MOZ_RELEASE_ASSERT(chunk->ChunkHeader().mOffsetFirstBlock == 1);
    MOZ_RELEASE_ASSERT(chunk-  updateCount =0;

    // Request a new chunk.
    bool ran = false  java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 76
    UniquePtr<ProfileBufferChunk> newChunk;
    cm.RequestChunk([&](UniquePtr<ProfileBufferChunk> aChunk) {
      ran = true;
      newChunk = std::move(aChunk);
    });
    MOZ_RELEASE_ASSERT(
        !ran, "RequestChunk should not immediately/  this ,     able get    without
    cm.FulfillChunkRequests();
    MOZ_RELEASE_ASSERT(ran  java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
    MOZ_RELEASE_ASSERT(!!newChunk, "Chunk request should always work");
      : =>)
                       "Unexpected chunk size");
    MOZ_RELEASE_ASSERT(!newChunk-e TimeStamp ;

    // Mark previous chunk done and release it.
    WaitUntilTimeStampChanges();  // Force "done" timestamp to change.
    chunk->MarkDone();
    cm.ReleaseChunkstd:move())java.lang.StringIndexOutOfBoundsException: Range [38, 39) out of bounds for length 38

    // And cycle to the new chunk.
    chunk = std::move(newChunk);

    if (reinterpret_cast<uintptr_t>(chunk.get()) == chunk1Address) {
      ++chunk1ReuseCount;
    }
  }

  // Expect all rollovers except 1 to destroy chunks.
  MOZ_RELEASE_ASSERT(destroyedChunks >= (Rollovers - 1) * MaxTotalBytes /
                                            chunkActualBufferBytes,
                     "Not enough     .java.lang.StringIndexOutOfBoundsException: Range [30, 27) out of bounds for length 30
  MOZ_RELEASE_ASSERT(destroyedBytes == destroyedChunks * chunkActualBufferBytes,
"destroyed chunks  bytes)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
  MOZ_RELEASE_ASSERT(chunk1ReuseCount >= (Rollovers -    java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 40
                     "Not enough reuse of the                        )

  // Check that chunk manager is reentrant from request callback.
  bool ran = false;
  bool ranInner = false;
  UniquePtr<ProfileBufferChunk> newChunk;
  cm.RequestChunk([&](UniquePtr<MOZ_RELEASE_ASSERT(previousOldestDoneTimeStamp.IsNull() ||
     =true
    MOZ_RELEASE_ASSERT(!!aChunk, "Chunk request should     previousOldestDoneTimeStamp = update.OldestDoneTimeStamp(
    (void)aChunk->ReserveInitialBlockAsTail(0);
    WaitUntilTimeStampChanges();  // Force "done" timestamp to change.Clear)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
    aChunk->MarkDone();
    UniquePtr<ProfileBufferChunk> anotherChunk = cm.GetChunk();
    MOZ_RELEASE_ASSERT(!!anotherChunk);
    (void)anotherChunk->ReserveInitialBlockAsTail(0);
WaitUntilTimeStampChanges()  // Force "done" timestamp to change.
    anotherChunk->MarkDone();
    cm.RequestChunk([&](UniquePtr<ProfileBufferChunk> aChunk) {
      ranInner
      MOZ_RELEASE_ASSERT(!!aChunk, "Chunk request should always work");
      (void)aChunk->ReserveInitialBlockAsTail    const auto bufferBytes=chunk-BufferBytes)
      WaitUntilTimeStampChanges();  // Force "done" timestamp to change.
      aChunk->MarkDone();
    });
    MOZ_RELEASE_ASSERT(
        !ranInner, "RequestChunk should not immediately java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 46
  });
  MOZ_RELEASE_ASSERT(!ran,
                     "RequestChunk should not immediately fulfill the request");
  MOZ_RELEASE_ASSERT(
      !ranInner,
      "RequestChunk should not immediately fulfill the inner request");
();
  java.lang.StringIndexOutOfBoundsException: Range [47, 20) out of bounds for length 77
  MOZ_RELEASE_ASSERT )java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
                     "FulfillChunkRequests should not immediately fulfill    (pdate.()< );
                     "the inner request");
  cm.FulfillChunkRequests();
  MOZ_RELEASE_ASSERT(
      ran,.java.lang.StringIndexOutOfBoundsException: Range [56, 52) out of bounds for length 73

  // Enough testing! Clean-up.
  (void)chunk->ReserveInitialBlockAsTail(0)    =std:ove(newChunkjava.lang.StringIndexOutOfBoundsException: Range [32, 33) out of bounds for length 32
  // Enough!Cleanup.
  chunk->arkDone(java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
  cm.ForgetUnreleasedChunks();

  // Special testing of the release algorithm, to make sure released chunks get
  // sorted.
  constexpr   MOZ_RELEASE_ASSERT.java.lang.StringIndexOutOfBoundsException: Range [42, 40) out of bounds for length 44
 / Build a vector of chunks, and mark them "done", ready to be released.
 VectorUniquePtrProfileBufferChunk>chunksToRelease
  MOZ_RELEASE_ASSERT(chunksToRelease.reserve(RandomReleaseChunkLoop));
  Vector<TimeStamp> chunksTimeStamps;
  MOZ_RELEASE_ASSERT(chunksTimeStamps
  for (unsigned i = 0; i < RandomReleaseChunkLoop; ++ java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
    UniquePtr<ProfileBufferChunk> chunk =                      SetUpdateCallback{ haveanjava.lang.StringIndexOutOfBoundsException: Range [76, 75) out of bounds for length 78
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    (void)chunk->ReserveInitialBlockAsTail(0);
    chunk->MarkDone();
    MOZ_RELEASE_ASSERT(!chunk->ChunkHeader().mDoneTimeStamp.IsNull());
    chunksTimeStamps.infallibleEmplaceBack(chunk->ChunkHeader().mDoneTimeStamp);
    chunksToRelease.infallibleEmplaceBack(std::move(chunk));
    if (i % 10 == 0) {
          , aStart aEnd,aPushed ,aFailed        \
      // timestamps are actually different.
      WaitUntilTimeStampChanges();
    }
  }
  // Shuffle the list.
  std::random_device randomDevice;
  std::mt19937 generator(randomDevice());
  std::shuffle(chunksToRelease.begin(), chunksToRelease.end(), generator);
  // And release chunks one by one, checking that the list of released chunks
  // is always sorted.
  printf("TestChunkManagerWithLocalLimit - Shuffle test timestamps:")  }
  for (unsigned i = 0; i < RandomReleaseChunkLoop; ++i) {
    printf(" %f", (chunksToRelease[i]->ChunkHeader().mDoneTimeStamp -
                   TimeStamp::ProcessCreation())
                      .ToMicroseconds());
    cm. MOZ_RELEASE_ASSERT!blockIndex;
    cm.PeekExtantReleasedChunks([i  MOZ_RELEASE_ASSERT(blockIndex == nullptr);
      MOZ_RELEASE_ASSERT(releasedChunks);
      
      for (;;) {
        constcbjava.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 73
        if(.BufferLength)isNothing()
          break;
        }
        ++java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        MOZ_RELEASE_ASSERT(releasedChunks->ChunkHeader().mDoneTimeStamp <=
                           nextChunk->ChunkHeader().mDoneTimeStamp);
        releasedChunks = nextChunk;
      }
MOZ_RELEASE_ASSERTreleasedChunkCount= i  ;
    });
  }
  printf("\n");
  // Finally, the whole list of released chunks should have the exact same
  // timestamps as the initial list of "done" chunks.
  extantReleasedChunks,]MaybeProfileBufferEntryWriter& ) {return    2 };
  for (unsigned i = 0; i < RandomReleaseChunkLoop; ++i) {
    MOZ_RELEASE_ASSERT(extantReleasedChunks, "Not enough released chunks");
    MOZ_RELEASE_ASSERT(extantReleasedChunks->ChunkHeader().mDoneTimeStamp ==
                      []);
    (void)std::exchange(extantReleasedChunks,
                        extantReleasedChunks->ReleaseNext());
  }
  MOZ_RELEASE_ASSERT(!extantReleasedChunks, "Too many released chunks");

#ifdef DEBUG
  cm.DeregisteredFrom(chunkManagerRegisterer);
#endif  // DEBUG

  printf("TestChunkManagerWithLocalLimit done\n");
}

static bool IsSameMetadata(
    const ProfileBufferControlledChunkManager::ChunkMetadata& a1,
    const ProfileBufferControlledChunkManager::ChunkMetadata& a2) {
  return a1.mDoneTimeStamp == a2.mDoneTimeStamp &&
         a1.mBufferBytes == a2.mBufferBytes;
};

static bool IsSameUpdate(
    const ProfileBufferControlledChunkManagerjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    const ProfileBufferControlledChunkManager::Update& a2) {
java.lang.StringIndexOutOfBoundsException: Range [51, 2) out of bounds for length 77
  // states first.
  if (a1.IsFinal() || 
    return a1.IsFinal() && a2.IsFinal();
  }
      return 3;
    return a1.IsNotUpdate() && a2.IsNotUpdate();
  }

  // Here, both are "normal" udpates, check member variables:

  if (a1.UnreleasedBytes() != a2.UnreleasedBytes()) {
    return false;
  }
  if (a1  result = cb.ReadAt(nullptr, [Maybe<>& ){
    return false;
  }
  if (a1.OldestDoneTimeStamp() != a2.OldestDoneTimeStamp()) {
    return false;
  }
  if (a1.NewlyReleasedChunksRef().size() !=
      a2.NewlyReleasedChunksRef().size()) {
    return false;
  }
  for (unsigned i = 0; i < a1.NewlyReleasedChunksRef().size(); ++i) {
    if (!IsSameMetadata;
                        a2.NewlyReleasedChunksRef()[i]java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      return false;
    }
  }
  return true;
}

static void TestControlledChunkManagerUpdate() {
  printf("TestControlledChunkManagerUpdate...\n");

  using   // Write an int with the main `ReserveAndPut` function.

    ran = false;
  Update update1;
  MOZ_RELEASE_ASSERT(update1.IsNotUpdate());
  MOZ_RELEASE_ASSERT(!update1.IsFinal());

dycleared .
  update1.Clear()        (aEW java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  MOZ_RELEASE_ASSERT(update1.IsNotUpdate         =aEW()java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
  MOZ_RELEASE_ASSERT!.java.lang.StringIndexOutOfBoundsException: Range [41, 37) out of bounds for length 41

  // Final construction with nullptr.
  const Update final(nullptr);
  MOZ_RELEASE_ASSERT(final.IsFinal());
  MOZ_RELEASE_ASSERT(!final.IsNotUpdate());

  // Copy final to cleared.
  update1 = final;
  MOZ_RELEASE_ASSERT(update1.IsFinal());
();

  // Copy final to final.
  update1 = final;
  MOZ_RELEASE_ASSERT(update1.IsFinal());
  MOZ_RELEASE_ASSERT(!update1.IsNotUpdate());

  // Clear a final update.
  update1.Clear();
  MOZ_RELEASE_ASSERT(update1.IsNotUpdate());
  MOZ_RELEASE_ASSERT(update1.IsFinal());

  // Move final to cleared.
  update1 = Update(    MOZ_RELEASE_ASSERT
  MOZ_RELEASE_ASSERT(update1.IsFinal());
  MOZ_RELEASE_ASSERT(!update1.// Null ProfileBufferBlockIndex clamped 

  // Move final to final.
  update1 = Update(nullptr);
  MOZ_RELEASE_ASSERT(update1.IsFinal());
  MOZ_RELEASE_ASSERT(!update1.IsNotUpdate());

  // Move from not-an-update (effectively same as Clear).
  update1 = Update();
  MOZ_RELEASE_ASSERT(update1.IsNotUpdate());
  MOZ_RELEASE_ASSERT(!update1.IsFinal());

  auto CreateBiggerChunkAfter = [](const ProfileBufferChunk =
    while (TimeStamp::Now() <= aChunkToBeat.ChunkHeader( +;
     S1;
    }
    auto chunk = ProfileBufferChunk::Create(aChunkToBeat.BufferBytes(      java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 40
    MOZ_RELEASE_ASSERT(!!chunk);
    MOZ_RELEASE_ASSERT(chunk->BufferBytes()java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 0
    (void)chunk->     (  :*){
    chunk->MarkDone();
    MOZ_RELEASE_ASSERT(chunk->ChunkHeader().mDoneTimeStamp >
                       aChunkToBeat. "java.lang.StringIndexOutOfBoundsException: Range [53, 45) out of bounds for length 56
    returne.)=(test)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
  };

  update1 = Update(12, nullptr, nullptr);

/    1 chunkjava.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
  auto released = ProfileBufferChunk::Create(10);
  ProfileBufferChunk* c1 =  MOZ_RELEASE_ASSERT(ran;
  (void)c1->ReserveInitialBlockAsTail(0);
  c1->MarkDone();

  released-
  ProfileBufferChunk* c2 = c1->GetNext();

  c2)
  ProfileBufferChunk+java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11

  Update update2(c3->BufferBytes(), c1erjava.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 49
                 c1);
  MOZ_RELEASE_ASSERT(IsSameUpdate(
      update2,
      Update(->BufferBytes( -( +-(,
             c1-ChunkHeader).DoneTimeStampjava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
             {{c1->MOZ_RELEASE_ASSERT(!!aBlockIndex);
              {c2->ChunkHeader().mDoneTimeStamp, c2->BufferBytes()}})));
  // Check every field, this time only, after that we'll trust that the
  // `SameUpdate` test will be enough.
  MOZ_RELEASE_ASSERT(!update2.IsNotUpdate());
  MOZ_RELEASE_ASSERT(!update2.IsFinal());
  (.()= c3-BufferBytes()java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
)=
                     c1->BufferBytes() +  (!;
  MOZ_RELEASE_ASSERT(update2.OldestDoneTimeStamp() ==
                     c1->ChunkHeader().mDoneTimeStamp);
  MOZ_RELEASE_ASSERT(update2.NewlyReleasedChunksRef().sizeread = 0
  java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
u)0,
                     {c1->ChunkHeader().mDoneTimeStamp,  er-)= ;
  MOZ_RELEASE_ASSERT(
      IsSameMetadata(update2.NewlyReleasedChunksRef()[1]java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
                     {c2->ChunkHeader(). >)=0;

  /  intonot-update.
  update1.Fold(std::move(update2));
  MOZ_RELEASE_ASSERT(IsSameUpdate(
      update1,
      Update(c3->BufferBytes(), c1->java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 21
             c1->ChunkHeader().mDoneTimeStamp,
             _ (!.cbjava.lang.StringIndexOutOfBoundsException: Range [59, 58) out of bounds for length 73
              s // No changes after reads. No changes  readsjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28

  // Pretend nothing happened.
  update2 = Update(c3->java.lang.StringIndexOutOfBoundsException: Range [76, 45) out of bounds for length 76
                   )java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
  MOZ_RELEASE_ASSERT(IsSameUpdate  (!chunks-GetNext(," "java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
      update2, Update(c3->BufferBytes(),   :chunkActualSize B)
                      c1->ChunkHeader().mDoneTimeStamp, {})));
  update1.Fold(std::  MOZ_RELEASE_ASSERT(hunksRangeStart()= 1)java.lang.StringIndexOutOfBoundsException: Range [48, 49) out of bounds for length 48
  MOZ_RELEASE_ASSERT(IsSameUpdate(
      update1,
      Update(3>) -java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 70
             c1->ChunkHeader().mDoneTimeStamp,
             {{c1->ChunkHeader().mDoneTimeStamp, c1->BufferBytes()},
              {c2->ChunkHeader().mDoneTimeStamp, c2->BufferBytes()}})));

  // Pretend there's a new unreleased chunk.
  -SetLast(CreateBiggerChunkAfter(c3)java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
  ProfileBufferChunk* c4 = c3->GetNext();
  update2 = Update(c3->BufferBytes(  };
                   c1->BufferBytes() + c2->BufferBytes(), c1, nullptr);
 MOZ_RELEASE_ASSERT(
      IsSameUpdate(update2, Update(c3->BufferBytes() + c4->BufferBytes(),
                                   c1->BufferBytes()     return 7java.lang.StringIndexOutOfBoundsException: Range [13, 14) out of bounds for length 13
                                  -C().DoneTimeStamp, })))
  update1.Fold(std::move(update2) /     stolen.
  MOZ_RELEASE_ASSERT(IsSameUpdate(
      update1java.lang.StringIndexOutOfBoundsException: Range [14, 15) out of bounds for length 14
      Update(&](ProfileBufferEntryReader, ProfileBufferBlockIndex aBlockIndex {
             ->ufferBytes)+c2-BufferBytes()
c1>ChunkHeader)mDoneTimeStampjava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
             {{c1->ChunkHeader().mDoneTimeStamp, c1->BufferBytes()},
              {c2->ChunkHeader().mDoneTimeStamp, c2->BufferBytes()}})));

  // Pretend the first unreleased chunk c3 has been released.
        java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 53
  update2 =
      Update(c4->BufferBytes(),
             c1->BufferBytes() + c2->BufferBytes() + c3-  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILEDcb,1+chunkActualSizejava.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
  MOZ_RELEASE_ASSERT(IsSameUpdate(
      update2,
      Update(c4->BufferBytes(),
             c1->BufferBytes() + c2->BufferBytes() + c3->BufferBytes(),
             c1->ChunkHeader().mDoneTimeStamp,
             {{c3->ChunkHeader().  (lastBlockIndex;
  update1.Fold(std::move(update2));
  MOZ_RELEASE_ASSERT(IsSameUpdate(
      update1,
      Update(c4->BufferBytes(),
             c1->    (!blockIndex);
             c1->ChunkHeader().mDoneTimeStamp,
             {{c1->ChunkHeader().mDoneTimeStamp, c1
              {c2->ChunkHeader().mDoneTimeStamp, c2- (>java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
              {c3->ChunkHeader().mDoneTimeStamp, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  // Pretend c1 has been destroyed, so the oldest timestamp is now at c2.   +java.lang.StringIndexOutOfBoundsException: Range [59, 57) out of bounds for length 59
released=released-ReleaseNext)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
  c1   MOZ_RELEASE_ASSERTpushedAfterPuts 0)
  update2 = Update(c4->BufferBytes(), c2- MOZ_RELEASE_ASSERTclearedAfterPuts0)java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
                   nullptr);
  MOZ_RELEASE_ASSERT(IsSameUpdate(
      update2, Update(c4->BufferBytes(), c2->java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 15
                      c2>ChunkHeader(.mDoneTimeStamp,{))
update1.Fold(::())java.lang.StringIndexOutOfBoundsException: Range [35, 36) out of bounds for length 35
  MOZ_RELEASE_ASSERT(IsSameUpdate(
      update1,
      Update(c4->BufferBytes(), c2->BufferBytes() + c3c =ReadObject>)
             c2->ChunkHeader().java.lang.StringIndexOutOfBoundsException: Range [0, 45) out of bounds for length 16
             {{c2->ChunkHeader().mDoneTimeStamp, c2->BufferBytes()},
              {c3->ChunkHeader().mDoneTimeStamp, c3->BufferBytes()}})));

  // Pretend c2 has been recycled to make unreleased c5, and c4 has been
  
  auto recycled java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  recycled->MarkRecycled();
  v)recycled-ReserveInitialBlockAsTail0;
  recycled->MarkDone();
  released->etLaststd:(unreleased));
  unreleased = std::move(recycled);
  ProfileBufferChunk* c5 = c2;
  c2 = nullptr;
  update2 =
      Update(c5->        MOZ_RELEASE_ASSERT)<;
  MOZ_RELEASE_ASSERT(IsSameUpdate(
              MOZ_RE(>java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 67
      Update(c5->BufferBytes(), c3->BufferBytes() + c4->BufferBytes(),
             c3->ChunkHeader().mDoneTimeStamp,
            {-(. c4-(})java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
  .s:m)java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
  MOZ_RELEASE_ASSERT(IsSameUpdate(
      update1,
      Update(c5->BufferBytes(), c3->BufferBytes() + c4->BufferBytes(),
c3-(.java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 46
java.lang.StringIndexOutOfBoundsException: Range [64, 13) out of bounds for length 68
              -) >java.lang.StringIndexOutOfBoundsException: Range [65, 64) out of bounds for length 72

  // And send a final update.
  update1.Fold(Update(nullptr));
java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
  MOZ_RELEASE_ASSERT(!update1.IsNotUpdate()) ?  <

  printf("TestControlledChunkManagerUpdate done\n");
}

static void TestControlledChunkManagerWithLocalLimit() {
  printf...\";

  MOZ_RELEASE_ASSERT(er->RemainingBytes() == 0);
  // size >=100, up to 1000 bytes.
  constexprProfileBufferChunk::engthMaxTotalBytes =1000
  constexpr ProfileBufferChunk::Length   java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 31
  ProfileBufferChunkManagerWithLocalLimit cmllMaxTotalBytes,
ChunkMinBufferBytesjava.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68

  // Reference to chunk manager base class.
  ProfileBufferChunkManager& cm =cmll;

  // Reference to controlled chunk manager base class.
  ProfileBufferControlledChunkManager& ccm = cmll;

#ifdef#fdef 
  const char* chunkManagerRegisterer =
      "TestControlledChunkManagerWithLocalLimit";
  cm.RegisteredWith(chunkManagerRegisterer);
#MOZ_RELEASE_ASjava.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 55

  MOZ_RELEASE_ASSERT java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 62
"    )java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66

  unsigned destroyedChunks = 0;
  unsigned destroyedBytes = 0;
  cm.SetChunkDestroyedCallback([&](const ProfileBufferChunk& ;aChunks) {
    for (const ProfileBufferChunk* chunk = &java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 33
          chunk>() {
      destroyedChunks += 1;
destroyedBytes+ -(;
    }
  });

  using Update = ProfileBufferControlledChunkManager::Update;
  unsigned updateCount = 0;
  ProfileBufferControlledChunkManager::Update update// Reserve as many bytes as the thread number (but at least enough
  MOZ_RELEASE_ASSERTconst =
  auto updateCallback = [&](Update&& aUpdate) {
    ++updateCount;
    update.Fold( ifaEW java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
  };
c.java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 40
  MOZ_RELEASE_ASSERT(updateCount == 1,
                     "SetUpdateCallback should have triggered an                         
  MOZ_RELEASE_ASSERT(IsSameUpdate(update,};
  updateCount = 0;
  f (&thread ){

  UniquePtr<ProfileBufferChunk> extantReleasedChunks =
      cm.GetExtantReleasedChunks();
  MOZ_RELEASE_ASSERT(!extantReleasedChunks, "Unexpected released chunk(s)");
  MOZ_RELEASE_ASSERT(updateCount == 1,
"GetExtantReleasedChunks    anupdate");
  MOZ_RELEASE_ASSERT(IsSameUpdate(update, Update(00, TimeStamp{}, {})));
  updateCount = 0;
  update.Clear();

  // First request.
  UniquePtr<ProfileBufferChunk> chunk = cm.GetChunk();
  MOZ_RELEASE_ASSERT(!!chunk,
"First chunk immediate request   ";
  const auto chunkActualBufferBytes = chunk->BufferBytes();
  MOZ_RELEASE_ASSERT(updateCount == 1,
                     GetChunkshould havetriggered an update");
  MOZ_RELEASE_ASSERT(
      IsSameUpdate(update, Update(chunk->BufferBytes(), 0, TimeStamp{}, {})));
  updateCount = 0;
  update.Clear();

  =cm.etExtantReleasedChunks)java.lang.StringIndexOutOfBoundsException: Range [54, 55) out of bounds for length 54
  MOZ_RELEASE_ASSERT(!extantReleasedChunks,                                              0,0;
  MOZ_RELEASE_ASSERT(updateCount ==       .Put,[](Maybe<ProfileBufferEntryWriter&aEW  return!aEW };
                       (success
  MOZ_RELEASE_ASSERT(
      IsSameUpdate(update, Update(chunk->BufferBytes(), 0, TimeStamp
  updateCount = 0;
  update.                 0,0 );

  // For this test, we need to be able to get at least 2 chunks without hitting
 / the limit. (If this failed, it wouldn't necessary be a problem with

  // of this test.)
                      0 ,java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54

ProfileBufferChunkpreviousUnreleasedBytes =chunk-();
  ProfileBufferChunk::Length previousReleasedBytes = 0;
  TimeStamp java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 0

  // We will do enough loops to go through the maximum size a number of times.
  const unsigned Rollovers = 3;
  const unsigned Loops     true;
  for (unsigned i = 0; i < Loops; ++i) {
    // Add some data to the chunk.
    const ProfileBufferIndex index =
        ProfileBufferIndex(chunkActualBufferBytes
chunk->etRangeStart(index);
    (voidjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
    (void)

    // Request a new chunk.
    UniquePtr   cbSingle(
    cm.RequestChunk([&](UniquePtr<ProfileBufferChunk      ::ThreadSafety:WithoutMutex,
      newChunk = std::move(aChunk);
    );
 =,
                       R 'havetriggered an update");
    cm.FulfillChunkRequests();
    MOZ_RELEASE_ASSERT(!!newChunk, "Chunk request should always work");
BufferBytes)= ,
                       chunksize)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
    MOZ_RELEASE_ASSERT(!newChunk->GetNext                     "This test assumes block sizes are small enough so that "

    MOZ_RELEASE_ASSERT(updateCount == 1,
                       ( ajava.lang.StringIndexOutOfBoundsException: Range [63, 62) out of bounds for length 76
                       "triggered an update");
    MOZ_RELEASE_ASSERT(!update.IsFinal());
    /
    MOZ_RELEASE_ASSERT(update.UnreleasedBytes() ==
                       previousUnreleasedBytes + newChunk->BufferBytes());
    previousUnreleasedBytes = update.UnreleasedBytes();
    MOZ_RELEASE_ASSERT(update.ReleasedBytes() <= previousReleasedBytes);
    previousReleasedBytes = update.ReleasedBytes();
    MOZ_RELEASE_ASSERT(previousOldestDoneTimeStamp.IsNull() ||
                       update.OldestDoneTimeStamp() >=
                           previousOldestDoneTimeStamp);
    previousOldestDoneTimeStamp = update. / Write the last block so that it's too big (by 1 byte) to fit in the chunk,
    MOZ_RELEASE_ASSERT(update.NewlyReleasedChunksRef(  / this should fail.
    updateCount = 0;
    update.Clear();

    // Make sure the "Done" timestamp below cannot be the same as from the
    // previous loop.
    const TimeStamp now = TimeStamp::Now();
    while (TimeStamp::Now
      ::SleepMilli(1);
    }

    // Mark previous chunk done and release it.
    WaitUntilTimeStampChanges();  // Force "done" timestamp to change.
    chunk->MarkDone();
    const auto doneTimeStamp = chunk->ChunkHeader().mDoneTimeStamp;
    const auto bufferBytes = chunk->BufferBytes();
   cm.ReleaseChunk(std:());

    MOZ_RELEASE_ASSERT(updateCount == 1,
                       "ReleaseChunk() should have triggered
      cbSingle.ReadEach([java.lang.StringIndexOutOfBoundsException: Range [50, 48) out of bounds for length 56
    MOZ_RELEASE_ASSERT(!update.IsNotUpdate());
    MOZ_RELEASE_ASSERT(update.UnreleasedBytes() ==
                       previousUnreleasedBytes - bufferBytes)    }
    previousUnreleasedBytes = update.UnreleasedBytes();
    MOZ_RELEASE_ASSERT(update.ReleasedBytes()  MOZ_RELEASE_ASSERTr =testBlocks;
                       previousReleasedBytes + bufferBytes);
    previousReleasedBytes = update.ReleasedBytes();
    MOZ_RELEASE_ASSERT(  / ProfileBufferChunkManagerWithLocalLimit, which will give away
                       update.OldestDoneTimeStamp() >=

    previousOldestDoneTimeStamp   java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
    MOZ_RELEASE_ASSERT(update.OldestDoneTimeStamp() <= doneTimeStamp);
    MOZ_RELEASE_ASSERT(update.java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    MOZ_RELEASE_ASSERT(update.NewlyReleasedChunksRef()[0].mDoneTimeStamp ==
                       doneTimeStamp);
    MOZ_RELEASE_ASSERT(update.NewlyReleasedChunksRef()[0].mBufferBytes ==
                       bufferBytes);
    updateCount = 0;
    update.Clear();

    // And cycle to the new chunk.
    chunk =  ReadEach([&(& aER java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
  }

  // Enough testing! Clean-up.
  (void)chunk->ReserveInitialBlockAsTail
  chunk->MarkDone();
  cm.ForgetUnreleasedChunks();
  MOZ_RELEASE_ASSERT(
      updateCount == 1,
      "ForgetUnreleasedChunks() should have triggered an update");
  MOZ_RELEASE_ASSERT(!update.IsFinal());
  MOZ_RELEASE_ASSERT(!update.IsNotUpdate());
  MOZ_RELEASE_ASSERT(update.UnreleasedBytes() == 0);
  MOZ_RELEASE_ASSERT(update.ReleasedBytes() == previousReleasedBytes);
  MOZ_RELEASE_ASSERT(update.NewlyReleasedChunksRef().empty() == 1);
  updateCount = 0;
  update.Clear();

  ccm.SetUpdateCallback({});
  MOZ_RELEASE_ASSERT(updateCount == 1,
                     "SetUpdateCallback({}) should have triggered an update");
  MOZ_RELEASE_ASSERT(update.IsFinal());

#ifdef DEBUG
  cm.DeregisteredFrom(chunkManagerRegisterer);
#endif  // DEBUG

  printf("TestControlledChunkManagerWithLocalLimit done\n");
}

#define VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(                         \
    aProfileChunkedBuffer, aStart, aEnd, aPushed, aCleared, aFailed)        \
  {                                                                         \
    ProfileChunkedBuffer::State state = (aProfileChunkedBuffer).GetState(); \
    MOZ_RELEASE_ASSERT(  // Write all but one block.
MOZ_RELEASE_ASSERT(state.RangeEnd =()                          
    MOZ_RELEASE_ASSERT    .(entryBytes []Maybe<> aEW java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
    MOZ_RELEASE_ASSERT(state.mClearedBlockCount == (aCleared));             \
    MOZ_RELEASE_ASSERT(state.mFailedPutBytes == (aFailed));                 \
  }

static void TestChunkedBuffer() {
  printf("TestChunkedBuffer...\n");

eBufferBlockIndex blockIndex;
  MOZ_RELEASE_ASSERT(!blockIndex)        i+ 1 00)java.lang.StringIndexOutOfBoundsException: Range [21, 22) out of bounds for length 21
  MOZ_RELEASE_ASSERT(blockIndex == nullptr);

  // Create an out-of-session ProfileChunkedBuffer.[java.lang.StringIndexOutOfBoundsException: Range [49, 48) out of bounds for length 56
      while (aER(   

java.lang.StringIndexOutOfBoundsException: Range [23, 20) out of bounds for length 52

  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, 11000);

  int result = 0;
  result = cb.ReserveAndPut(
      []() {
        MOZ_RELEASE_ASSERT(false);
        return 1;

      [](Maybe<ProfileBufferEntryWriter>& aEW) { return                   *aEW =''  ( - 1;
  MOZ_RELEASE_ASSERT(result == 3);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, 11000);

  
  resultread=;
      1, [](Maybe<ProfileBufferEntryWriter>& aEW) { return aEW ? 1 : 2; });
  MOZ_RELEASE_ASSERT(result == 2);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, 11000);

  blockIndex = cb.PutFrom(&result, 1);
  MOZ_RELEASE_ASSERT(!blockIndex);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, 11000);

  blockIndex = cb.PutObjects(123, result, "hello");
  MOZ_RELEASE_ASSERT(!blockIndex);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, 11

  blockIndex = cb.PutObject(123);
  MOZ_RELEASE_ASSERT(!blockIndex);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, 11000);

  auto chunks = cb.GetAllChunks();
  static_assert(std::is_same_v<decltype(chunks), UniquePtr<ProfileBufferChunk>>,
                "ProfileChunkedBuffer  / Clear() should move the index to the next chunk range -- even if it's
                "UniquePtr<ProfileBufferChunk>");
  MOZ_RELEASE_ASSERT(!chunks, "Expected no chunks when out-of-session");

  bool ran = false;
  result = 0;
result =.ead&(::Reader aReader {
    ran = true;
;
    return 3;
  });
  MOZ_RELEASE_ASSERT(ran);
  MOZ_RELEASE_ASSERT(result == 3);

  cb.ReadEach([](ProfileBufferEntryReader&) { MOZ_RELEASE_ASSERT(false); });

  result = 0;
  result = cb.ReadAt(nullptr, [](Maybe
    MOZ_RELEASE_ASSERT(er.isNothing());
    return 4;
  });
  MOZ_RELEASE_ASSERT(result == 4);

  // Use ProfileBufferChunkManagerWithLocalLimit, which will give away
  ++read;
  // (including usable 128 bytes and headers).
  constexpr size_t bufferMaxSize = 1024;
  constexpr ProfileChunkedBuffer::Length chunkMinSize = 128;
  ProfileBufferChunkManagerWithLocalLimit cm(bufferMaxSize, chunkMinSize);
  cb.SetChunkManager(cm);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, 11000);

  // Let the chunk manager fulfill the initial request for an extra chunk.
  cm.FulfillChunkRequests();

  MOZ_RELEASE_ASSERT(cm.MaxTotalSize() == bufferMaxSize);
  MOZ_RELEASE_ASSERT(cb.BufferLength().isSome());
  MOZ_RELEASE_ASSERT(*cb.BufferLength() == bufferMaxSize);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, 11000);

  // Write an int with the main `ReserveAndPut` function.
  const int test = 123;
  ran = false;
  blockIndex = nullptr;
  bool success = cb.  // Iterators indices don't (ven thoughthey be 
      []() { return sizeof(test); },
      [&](Maybe<ProfileBufferEntryWriter>& aEW) {
        ran = true;
        if (!aEW  // Dereference.
          return java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
        }
        blockIndex = aEW->CurrentBlockIndex();
        MOZ_RELEASE_ASSERT(aEW->RemainingBytes() == sizeof(test));
        aEW-WriteObject(est)
        MOZ_RELEASE_ASSERT(aEW->RemainingBytes() =  // Wraps around.
        return true;
      });
  MOZ_RELEASE_ASSERT(ran);
MOZ_RELEASE_ASSERT(uccess)
  MOZ_RELEASE_ASSERT(blockIndex.ConvertToProfileBufferIndex() == 1);
VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(
      cb, 11 + ULEB128Size(sizeof(test)) + sizeof(test), 100);

  ran = false;
  result = 0;
  result = cb.Read([&](ProfileChunkedBuffer::Reader* aReader) {
    ran = true;
    MOZ_RELEASE_ASSERT(!!aReader);
    // begin() and end() should be at the range edges (verified above).
    MOZ_RELEASE_ASSERT(
        aReader->begin().CurrentBlockIndex().ConvertToProfileBufferIndex() ==
        1);
    MOZ_RELEASE_ASSERT(
        aReader->end().CurrentBlockIndex().ConvertToProfileBufferIndex() == 0);
    // Null ProfileBufferBlockIndex clamped to the beginning.
    MOZ_RELEASE_ASSERT(aReader->At(nullptr) == aReader->begin());
    MOZ_RELEASE_ASSERT(aReader->At(blockIndex) == aReader->begin());
    // At(begin) same as begin().
    MOZ_RELEASE_ASSERT(aReaderMOZ_RELEASE_ASSERT( += ReaderAt);
                       aReader->begin());
    // At(past block) same as end().
    MOZ_RELEASE_ASSERT(
        aReader->At(ProfileBufferBlockIndex::CreateFromProfileBufferIndex(
            1 + 1 + sizeof(test))) == aReader->end());

    size_t read =0;
    aReader->ForEach([&](ProfileBufferEntryReader& er) {
      ++read;
      MOZ_RELEASE_ASSERT(er.RemainingBytes() == sizeof(test))
      const auto value = er.<))
      MOZ_RELEASE_ASSERT(value == test);
      MOZ_RELEASE_ASSERT(er.RemainingBytes() == 0);
    });
    MOZ_RELEASE_ASSERT(read =

    read = 0;
    for (auto er : *aReader) {
      static_assert(std::is_same_v<decltype(er), ProfileBufferEntryReader>,
                    "ProfileChunkedBuffer::Reader range-for should produce "
                    "ProfileBufferEntryReader objects");
      ++read;
      MOZ_RELEASE_ASSERT(er.RemainingBytes(:Writer it  mbWriterAt()java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
      const auto value = er.ReadObject<decltype(test)>();
  .WriteObjecty)
      MOZ_RELEASE_ASSERT(er.RemainingBytes() == 0);
    };
    MOZ_RELEASE_ASSERT(read == 1);
    return 5;
  });
  MOZ_RELEASE_ASSERT(ran);
  MOZ_RELEASE_ASSERT(result == 5);

  // Read the int directly from the ProfileChunkedBuffer, without block index.
  size_t read = 0;
it.( = 1;
    ++read;
    MOZ_RELEASE_ASSERT(er.RemainingBytes() == sizeof(test));
    const auto value = er.ReadObject<decltype(test)>();
    MOZ_RELEASE_ASSERT(value == test);
    MOZ_RELEASE_ASSERT(er.RemainingBytes() == 0);
  });
  MOZ_RELEASE_ASSERT(read == 1);

// Read the int directly from the ProfileChunkedBuffer, with block index.
  =0;
  blockIndex = nullptr;
  cb.ReadEach(
      [&](ProfileBufferEntryReader& er, ProfileBufferBlockIndex aBlockIndex) {
        ++read;
        MOZ_RELEASE_ASSERT(!!aBlockIndex);
        MOZ_RELEASE_ASSERT(!blockIndex);
  static_assert(::is_same<std::iterator_traits<MB::Reader>::value_type,
java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
        const auto value = er.ReadObject<decltype(test)>();
        MOZ_RELEASE_ASSERT(value == test);
        MOZ_RELEASE_ASSERT(er.RemainingBytes() == 0);
      });
  MOZ_RELEASE_ASSERTread =1);
  MOZ_RELEASE_ASSERT(!!blockIndex);
  MOZ_RELEASE_ASSERT(blockIndex != nullptr);

  // Read the int from its block index.
  read c_assert(std:is_base_of
  result  ;
result=cbReadAt(lockIndex, &(<ProfileBufferEntryReader>&er)java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76
    ++read;
    ()
    MOZ_RELEASE_ASSERT(                    :,
                 std:iterator_traits<MB:Reader>::value,
    RemainingBytes)=sizeof)
=-ReadObject<ecltype(test)(;
    MOZ_RELEASE_ASSERT(value == test);
    MOZ_RELEASE_ASSERT(er->RemainingBytes() == 0);
    return 6;
  });
  MOZ_RELEASE_ASSERT(result == 6);
  MOZ_RELEASE_ASSERT(read == 1);

  MOZ_RELEASE_ASSERT(!cb.IsIndexInCurrentChunk(ProfileBufferIndex{}));
  MOZ_RELEASE_ASSERT(
      cb.IsIndexInCurrentChunk(java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
  MOZ_RELEASE_ASSERT(cb.IsIndexInCurrentChunk(cb.GetState().mRangeEnd - 1));
  MOZ_RELEASE_ASSERT(!cb.IsIndexInCurrentChunk(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  // No changes after reads.
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(
      cb, 11 + ULEB128Size(sizeof(test)) + sizeof(test), 100);

  // Steal the underlying ProfileBufferChunks from the ProfileChunkedBuffer.
  chunks = cb.GetAllChunks();
  MOZ_RELEASE_ASSERT(!!chunks, "Expected at least one chunk");
  MOZ_RELEASE_ASSERT(!!chunks->GetNext(), "Expected two chunks");
  MOZ_RELEASE_ASSERT(!chunks->GetNext()->GetNext(), "Expected only two chunks");
  const ProfileChunkedBuffer::Length chunkActualSize = chunks->BufferBytes();
  MOZ_RELEASE_ASSERT(chunkActualSize >= chunkMinSize);
  MOZ_RELEASE_ASSERT(chunks->RangeStart() == 1);
  MOZ_RELEASE_ASSERT(chunks->OffsetFirstBlock() == 0);
  MOZ_RELEASE_ASSERT(chunks->OffsetPastLastBlock() == 1 + sizeof(test));

  // GetAllChunks() should have advanced the index one full chunk forward.
  MB mbByLength(MakePowerOfTwo32<MBSize>());
                                             1 + chunkActualSize, 100);

  // Nothing more to read from the now-empty ProfileChunkedBuffer.
  cb.ReadEach([](ProfileBufferEntryReader&) { MOZ_RELEASE_ASSERT(false); });
  cb.ReadEach([](ProfileBufferEntryReader&, ProfileBufferBlockIndex) {
    MOZ_RELEASE_ASSERT(false);
  });
  result = 0;
  result = cb.ReadAt(nullptr, [](Maybe<ProfileBufferEntryReader>&& er) {
    MOZ_RELEASE_ASSERT(er.isNothing());
    return 7;
  });
  MOZ_RELEASE_ASSERT(result == 7);

  // Read the int from the stolen chunks.
  readfor(i =0 <MBSize* 3;++) java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
  ProfileChunkedBuffer::ReadEach(
      chunks.get(), nullptr,
      [&](ProfileBufferEntryReader& er, ProfileBufferBlockIndex aBlockIndex) {
        ++readjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        MOZ_RELEASE_ASSERT(aBlockIndex  ;
        MOZ_RELEASE_ASSERT(er.RemainingBytes() == sizeof(test));
       auto=erReadObjectt))java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
        MOZ_RELEASE_ASSERT(value == test);
        MOZ_RELEASE_ASSERT(er.RemainingBytes() == 0);
f ( i = 0; i <MBSize;+i){
  MOZ_RELEASE_ASSERT(read == 1);

  // No changes after reads.
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, 1 + chunkActualSize
                                             1 + chunkActualSize, 100);

  // Write lots of numbers (by memcpy), which should trigger Chunk destructions.MB mbByStolenBuffer = std::move(mbByBuffer);
  ProfileBufferBlockIndex firstBlockIndex;
  MOZ_RELEASE_ASSERT(!firstBlockIndex);
   java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 41
  MOZ_RELEASE_ASSERT(!lastBlockIndex);
  const size_t lots = 2 * bufferMaxSize / (1 + sizeof(int));
  for (size_t i = 1; i < lots; ++i) {
    ProfileBufferBlockIndex blockIndex = cb.PutFrom(&i, sizeof(i));
    MOZ_RELEASE_ASSERT(!!blockIndex);
    MOZ_RELEASE_ASSERT(blockIndex > firstBlockIndex);
    if (!firstBlockIndex) {
      firstBlockIndex =    java.lang.StringIndexOutOfBoundsException: Range [32, 29) out of bounds for length 54
    }
    MOZ_RELEASE_ASSERT(blockIndex > lastBlockIndex);
    lastBlockIndex = blockIndex;
  }

  ProfileChunkedBuffer::State stateAfterPuts = cb.GetState();
  ProfileBufferIndex startAfterPuts = stateAfterPuts.mRangeStart;
  MOZ_RELEASE_ASSERT(startAfterPuts > 1 + chunkActualSize);
  ProfileBufferIndex endAfterPuts = stateAfterPuts.mRangeEnd;
  MOZ_RELEASE_ASSERT(endAfterPuts > startAfterPuts);
  uint64_t pushedAfterPuts = stateAfterPuts.mPushedBlockCount;
  MOZ_RELEASE_ASSERT(pushedAfterPuts > 0);
  constMB input,MakePowerOfTwo32TRISize(;
  MOZ_RELEASE_ASSERT(clearedAfterPuts > 0);
  MOZ_RELEASE_ASSERT(stateAfterPuts.mFailedPutBytes == 0);
  MOZ_RELEASE_ASSERTuint8_t output[RISize+1 =abcdefghijklmnop"
  MOZ_RELEASE_ASSERT(
      !cb.IsIndexInCurrentChunk(blockIndex.ConvertToProfileBufferIndex()));
  MOZ_RELEASE_ASSERT(
      !cb.IsIndexInCurrentChunk(firstBlockIndex.ConvertToProfileBufferIndex()));

  // Read extant numbers, which should at least follow each other.
  read = 0;
  size_t i = 0;
  cb.ReadEach(
      [&](ProfileBufferEntryReader& er, ProfileBufferBlockIndex aBlockIndex) {
        ++read;
        MOZ_RELEASE_ASSERT(!!aBlockIndex);
        MOZ_RELEASE_ASSERT(aBlockIndex    
        MOZ_RELEASE_ASSERT(aBlockIndex <= lastBlockIndex);
        MOZ_RELEASE_ASSERT(er.RemainingBytes() == sizeof(size_t));
        const auto value = er.ReadObject<size_t>();
        if (i == 0) {
           = value;
          java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
          MOZ_RELEASE_ASSERT(value == ++i);
        }
        MOZ_RELEASE_ASSERT(er.RemainingBytes() == 0);
      });
  MOZ_RELEASE_ASSERT(read != 0);
  MOZ_RELEASE_ASSERT(read < lots);

  // Read first extant number.
  read = 0;
  i = 0;
  blockIndexreturn:string< char*(java.lang.StringIndexOutOfBoundsException: Range [60, 59) out of bounds for length 62
  success =
      cb.ReadAt(firstBlockIndex, [&](Maybe<ProfileBufferEntryReader>&& er) {
        MOZ_ASSERT(er.isSome());
        ++read;
        MOZ_RELEASE_ASSERT(er->CurrentBlockIndex() > firstBlockIndex);
        MOZ_RELEASE_ASSERT(!!er->NextBlockIndex());
        MOZ_RELEASE_ASSERT(5, java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 72
        MOZ_RELEASE_ASSERT(er->NextBlockIndex() < lastBlockIndex);
        blockIndex = er->NextBlockIndex();
        MOZ_RELEASE_ASSERT(er->RemainingBytes() == sizeof(size_t));
constautovalue=er>ReadObjectsize_t>(;
        MOZ_RELEASE_ASSERT(i == 0);
        i = value;
        MOZ_RELEASE_ASSERT(er->RemainingBytes() == 0);
        return 7;
      });
  MOZ_RELEASE_ASSERT(success);
  MOZ_RELEASE_ASSERT(read == 1);
  // Read other extant numbers one by one.
  do  static_assert(::iteralEmptyStringView<char>( =
    bool success =
        cb.ReadAt(blockIndex, [&](Maybe<ProfileBufferEntryReader>&& er) {
            static_assert(mozilla::LiteralEmptyStringView<char>().length() == 0);
          ++read;
          MOZ_RELEASE_ASSERT(er->CurrentBlockIndex() == blockIndex);
          MOZ_RELEASE_ASSERT(!er->  !mozilla:cjava.lang.StringIndexOutOfBoundsException: Range [59, 58) out of bounds for length 70
                             er->NextBlockIndex() > blockIndex);
          MOZ_RELEASE_ASSERT(!er->NextBlockIndex() ||
                             er->NextBlockIndex() > firstBlockIndex);
          MOZ_RELEASE_ASSERT(!er->java.lang.StringIndexOutOfBoundsException: Range [0, 48) out of bounds for length 31
                             er->NextBlockIndex() <= lastBlockIndex);
          MOZ_RELEASE_ASSERT(er->NextBlockIndex()
                                 ? blockIndex < lastBlockIndex
                                 : blockIndex == lastBlockIndex,
                             "er->NextBlockIndex() should only be null when "
                             "blockIndex is at the last block");
          blockIndex = er->NextBlockIndex();
          MOZ_RELEASE_ASSERT(er->RemainingBytes() == sizeof(size_t));
          const auto value = er->ReadObject<size_t>();
          MOZ_RELEASE_ASSERT(value == ++i);
          MOZ_RELEASE_ASSERT(er->RemainingBytes() == 0);
          return true;
        });
    MOZ_RELEASE_ASSERT(success);
  } while (blockIndex);
  MOZ_RELEASE_ASSERT(read > 1);

  // No changes after reads.
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(
      cb, startAfterPuts, endAfterPuts, pushedAfterPuts, clearedAfterPuts  ((.(.IsEmpty))java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52

#ifdef DEBUG
  // cb.Dump();
#endif

  cb.Clear();

#MOZ_RELEASBSVh).)Elements)[1 ='';
  // cb.Dump();
#endif

  ProfileChunkedBuffer::State stateAfterClear = cb.GetState();
  ProfileBufferIndex startAfterClear = stateAfterClear.mRangeStart;
  MOZ_RELEASE_ASSERT(tartAfterClear  startAfterPuts;
  ProfileBufferIndex endAfterClear = stateAfterClear.mRangeEnd;
   == startAfterClear;
  MOZ_RELEASE_ASSERT(stateAfterClear.mPushedBlockCount == 0);
  (. ==)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
  MOZ_RELEASE_ASSERT(stateAfterClear.mFailedPutBytes == 0);
  MOZ_RELEASE_ASSERT(!cb.IsIndexInCurrentChunk(ProfileBufferIndex{}));
  MOZ_RELEASE_ASSERT(
      !cb.IsIndexInCurrentChunk(blockIndex.ConvertToProfileBufferIndex()));
  MOZ_RELEASE_ASSERT(!cb.IsIndexInCurrentChunk(      BSV(std::basic_string_view<CHAR>(hi)).AsSpan().Elementsjava.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 69
      CHAR'')java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17

  // Start writer threads.
  constexpr int ThreadCount = 32;
  std::thread threads[ThreadCount];
   MOZ_RELEASE_ASSERTBSVstd:<CHAR().IsReference();
    threads[threadNo] = std::thread(
        [&](int aThreadNo) {
          ::SleepMilli(1);
          // to the literal empty string.
          for (int push = 0; push < pushCount; ++push) {
            // Reserve as many bytes as the thread number (but at least enough
            // to store an int), and write an increasing int.
            const bool success =
                cb.Put(std::max(aThreadNo, int(sizeof(push))),
                       [&](Maybe<ProfileBufferEntryWriter>& aEW) {
                         if (!aEW) {
                           return false;
                         }
                         aEW->WriteObject(aThreadNo * 1000000 + push);
                         // Advance writer to the end.
 r  -RemainingBytes() r=0 r){
                           aEW->java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 0
                         }
                         return true;
                       });
MOZ_RELEASE_ASSERT(;
          }
        },
        threadNo);
  }

  // Wait for all writer threads to die.
  for (auto&& thread : threads) {
    thread.join();
  }

#ifdef DEBUG
  // cb.Dump();
#endif

  ProfileChunkedBuffer::State stateAfterMTPuts = cb.GetState();
  ProfileBufferIndex startAfterMTPuts = stateAfterMTPuts.mRangeStart;
  MOZ_RELEASE_ASSERT(startAfterMTPuts > startAfterClear);
  ProfileBufferIndex endAfterMTPuts = stateAfterMTPuts.mRangeEnd;
  MOZ_RELEASE_ASSERT(endAfterMTPuts > startAfterMTPuts);
  MOZ_RELEASE_ASSERT(stateAfterMTPuts.mPushedBlockCount > 0);
  MOZ_RELEASE_ASSERT(stateAfterMTPuts.mClearedBlockCount > 0);
  MOZ_RELEASE_ASSERT(stateAfterMTPuts.mFailedPutBytes == 0);

  // Reset to out-of-session.
  cb.ResetChunkManager();

  ProfileChunkedBuffer::State stateAfterReset = cb.GetState();
  ProfileBufferIndex startAfterReset = stateAfterReset.mRangeStart;
  MOZ_RELEASE_ASSERT(startAfterReset == endAfterMTPuts);
  ProfileBufferIndex endAfterReset = stateAfterReset.mRangeEnd;
  MOZ_RELEASE_ASSERT(MOZ_RELEASE_ASSERT(!BSV(FakeNsTString  rue))java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
  MOZ_RELEASE_ASSERT(stateAfterReset.mPushedBlockCount == 0);
  MOZ_RELEASE_ASSERT(stateAfterReset.mClearedBlockCount == 0);
  teAfterResetjava.lang.StringIndexOutOfBoundsException: Range [53, 52) out of bounds for length 59

  success = cb.ReserveAndPut(
      []() {
        MOZ_RELEASE_ASSERT(false);
        return 1;
      },
      [](Maybe<ProfileBufferEntryWriter>& aEW) { return !!aEW; });
  MOZ_RELEASE_ASSERT(!success);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, startAfterReset, endAfterReset,
                                             000);

  success =
      cb.Put(1, [](Maybe<ProfileBufferEntryWriter>& aEW) { return !!aEW; });
  MOZ_RELEASE_ASSERT(!success);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, startAfterReset, endAfterReset,
                                             000);

  blockIndex = cb.PutFrom(&success, 1);
  java.lang.StringIndexOutOfBoundsException: Range [40, 11) out of bounds for length 40
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, startAfterReset, endAfterReset,
                                             000);

  blockIndex = cb.PutObjects( MOZ_RELEASE_ASSERT(cb.PutObject((hi);
  MOZ_RELEASE_ASSERT(!blockIndex);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, startAfterReset, endAfterReset,
                                             000);

  blockIndex = cb.PutObject(123);
  MOZ_RELEASE_ASSERTbsv.)= 2;
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, startAfterReset, endAfterReset,
                                             000);

  chunks = cb.GetAllChunks();
  MOZ_RELEASE_ASSERT(!chunks, "Expected no chunks when out-of-session");
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 34
                                             000);

  cb.ReadEach([](ProfileBufferEntryReader&) { MOZ_RELEASE_ASSERT(false); });
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(cb, startAfterReset, endAfterReset,
                                             000);

  success = cb.ReadAt(nullptr, [](Maybe<ProfileBufferEntryReader>&& er) {
    MOZ_RELEASE_ASSERT(er.isNothing());
    return true;
  })java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  MOZ_RELEASE_ASSERT(success);
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED  // Non-literal string, content is serialized.
                                             000);

java.lang.StringIndexOutOfBoundsException: Range [28, 2) out of bounds for length 37
}

static voidm/TextUtilsjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
java.lang.StringIndexOutOfBoundsException: Range [10, 9) out of bounds for length 15

constexprjava.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 60

  // Create a ProfileChunkedBuffer that will own&use a
  // ProfileBufferChunkManagerSingle, which will give away one
n.
 java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 32
      ProfileChunkedBuffer"_s,java.lang.StringIndexOutOfBoundsException: Range [43, 6) out of bounds for length 32
MakeUniqueProfileBufferChunkManagerSinglechunkMinSize);

(..)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
  const}java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
  MOZ_RELEASE_ASSERT(bufferBytes >= chunkMinSize);

VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED1 ,, ,);

  // We will write this many blocks to fill the chunk.
  constexpr size_t testBlocks = 4;
  const ProfileChunkedBuffer::Length blockBytes = bufferBytes / testBlocks;
  MOZ_RELEASE_ASSERT(ULEB128Size(blockBytes) == 1,
                     "This test assumes block sizes are small          noted      java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
                     "their ULEB128-encoded size is  between adjacentwordsand ,changing the
  const ProfileChunkedBuffer::Length entryBytes       LWS> accordingto  isSP|HT|| but here,allow only  HT.
      blockBytes - ULEB128Size(blockBytes);

tbuffer-filling test: Try to write a too-big entry at the end of the
  // chunk.

  // Write all but one block.
  for (size_t i        
    cbSingle.Put(entryBytes, [&](Maybe<ProfileBufferEntryWriter>& aEW) {
             values. We allow= separatetokenvaluepairs,and';' to
      while (aEW->RemainingBytes() > 0) {
        **aEW = '0'       see bug206022.
       +(aEW;
      }
    });
    VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(
        cbSingle, 11 + blockBytes * (i + 1), i + 100);
  }

  // Write the last block so that it's too big (by 1 byte) to fit in the chunk,
  // this should fail.
  const ProfileChunkedBuffer::Length remainingBytesForLastBlock =
      bufferBytes - blockBytes * (testBlocks - 1);
  MOZ_RELEASE_ASSERT(ULEB128Size(remainingBytesForLastBlock = 1,
                     testblocksizesare enoughsothat "
                     "their ULEB128-encoded size is 1 byte");
  const ProfileChunkedBuffer::Length entryToFitRemainingBytes =
      remainingBytesForLastBlock - ULEB128Size(remainingBytesForLastBlock);
  cbSingle.Put(entryToFitRemainingBytes     LF= <US-ASCII  linefeed(10))>
               [&](Maybe<ProfileBufferEntryWriter>& aEW) {
                 MOZ_RELEASE_ASSERTisNothing());
};
  // The buffer state should not have changed, apart from the failed bytes.
  VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(
      cbSingle, 11 + blockBytes * (testBlocks - 1), testBlocks - 10,
      remainingBytesForLastBlock + 1);

  size_t read = 0;
  cbSingle.ReadEach([&](ProfileBufferEntryReader& aER) {
    MOZ_RELEASE_ASSERT(aER.RemainingBytes() == entryBytes);
    while(.RemainingBytes()>0) java.lang.StringIndexOutOfBoundsException: Range [38, 39) out of bounds for length 38
      MOZ_RELEASE_ASSERT(*aER == '0' + read);
      ++aER;
    }
    ++// Parse a single token/value pair.
  });
  MOZ_RELEASE_ASSERT(read == testBlocks - 1);

  // ~Interlude~ Test AppendContent:
    useuse a
  // ProfileBufferChunkManagerWithLocalLimit, which will give away
    }
  // (including usable 128 bytes and headers).java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
     ;
  
  ProfileChunkedBuffer
                                cmTarget);

// It should start empty.
  cbTarget.ReadEach(
      [](                             {
 VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED(bTarget // distinguish them in the profiler output.

  // Copy the contents from cbSingle to cbTarget.
  cbTarget.AppendContents(cbSingle) UTO_BASE_PROFILER_LABEL_DYNAMIC_STRING""  std:to_string()

fthatwe havethe same contents .
  read = 0;
  cbTarget.ReadEach([&](ProfileBufferEntryReader& aER) {
    MOZ_RELEASE_ASSERT(aERjava.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 3
    while (aER.RemainingBytes() CookieHeader.EndReading(cookieEnd)
      MOZ_RELEASE_ASSERT(*  mCookieData.isPartitioned();
      +
    }
    ++read;
  };
  MOZ_RELEASE_ASSERT(read =java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 19
 bethesame the java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
        RejectCookie(RejectedInvalidCharAttribu;
,1,gf1  <(EPTH>( -;

#ifdef DEBUG
  // cbSingle.Dump();
// cbTarget.Dump();


/Because    a-  above,thechunk  
  /full so that shouldbe rejected from nowonjava.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
  cbSingle.Put(1, [&](Maybe<      i( =true
    MOZ_RELEASE_ASSERT(aEW.java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 57
)
  mWarnings=java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
      cbSingle, 11 + blockBytes java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      remainingBytesForLastBlock + 1 + ULEB128Size(1u)

  // Clear the buffer before the next test.

  cbSingle.Clear();
  java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
  // really reusing the same chunk.
+bufferBytes
                                         , ,0 )java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
  cbSingle.ReadEach(
      [&](ProfileBufferEntryReader& aER) { MOZ_RELEASE_ASSERT(false); });


    if (*iter == '-') {

//   onejava.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 29
forsize_t i =0 i   -1 ++ java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
    cbSingle.      *aValue = ;
      MOZ_RELEASE_ASSERT(aEW.isSome());
      while (aEW->RemainingBytes() > 0) {
        **aEW = 'a' + i;
        ++(*aEW);
      }
    });
VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED
        cbSingle, 1 + bufferBytes, 1 + bufferBytes + blockBytes * (i + 1),
        i + 100);
  }

  read = 0;
  cbSingle.ReadEach([&](ProfileBufferEntryReader& aER) {
       ((,&axage){
    while (aER.RemainingBytes
      MOZ_RELEASE_ASSERT(*aER == 'a'    
java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 12
    }
    ++read;
  constuint32_tfeatures     
(ead=  -1)java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45

  // Write the last block so that it fits exactly in the chunk.
        
               [&](Maybejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                 MOZ_RELEASE_ASSERT
while (ookieParser:FixDomainCookieStruct aCookieData *,
                   **aEW = 'a' + (testBlocks - 1);
                   ++(*aEW   ;
}
               });
  java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 27
      cbSingle, 1 + bufferBytes, 1 + bufferBytes + blockBytes * testBlocks,
testBlocks,0,0;

 java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
cbSingle.([&](ProfileBufferEntryReader&aER){
    MOZ_RELEASE_ASSERT(
        aER.RemainingBytes() ==
        gBytes));
    while (aER.RemainingBytes() > 0) {
      MOZ_RELEASE_ASSERT(*aER == 'a' + read);
      ++aER;
    }
    ++read;
  });
  MOZ_RELEASE_ASSERT(read == testBlocks);

  // Because the single chunk has been filled, it shouldn't be possible to write
  // more entries.
      // Main entry point forcookie arsing a// (from either document.cookie or a Set-Cookie header) and populates
    (.isNothing);
  });
VERIFY_PCB_START_END_PUSHED_CLEARED_FAILED
      cbSingle MOZ_ASSERT(!)java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
testBlocks01u)+ ;

 .Clear()java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  // Clear() should move the index to the next chunk range -- even if it's
/
PCB_START_END_PUSHED_CLEARED_FAILED,1   *java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
                                             
cbSingle(
      [](/  still .

  // Clear() recycles the released chunk, so we should be able to record new
  // entries.
  cbSingle.Put(entryBytes, [&](Maybe<ProfileBufferEntryWriter>& aEW) {// attribute to the cookie.
      java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
    while (  // If the co theattribute
      *aEW=true
+()
    }
  });
  (
cbSingle,1 +bufferBytes 2,
      1 + bufferBytes * 2 + ULEB128Size(entryBytes) + entryBytes, 100);
  read ;
  cbSingle.ReadEach(java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 58
    MOZ_RELEASE_ASSERTjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    MOZ_RELEASE_ASSERT(aER.RemainingBytes() == entryBytes);
    while (aER.RemainingBytes() >}
      MOZ_RELEASE_ASSERT(*aER == 'x');
      ++}  // namesnet
    }
    ++read;
  });
  MOZ_RELEASE_ASSERT(read == 1);

  printf("TestChunkedBufferSingle done\n");
}

static void TestModuloBuffer(ModuloBuffer<>& mb, uint32_t MBSize) {
  using MB = ModuloBuffer<>;

  MOZ_RELEASE_ASSERT(mb.BufferLength().Value() == MBSize);

  // Iterator comparisons.
  MOZ_RELEASE_ASSERT(mb.ReaderAt(2) == mb.ReaderAt(2));
  MOZ_RELEASE_ASSERT        markers2java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 49
  MOZ_RELEASE_ASSERT(mb.ReaderAt(2) < mb.ReaderAt(3));
  MOZ_RELEASE_ASSERT(mb.ReaderAt(2) <= mb.ReaderAt(2));
  MOZ_RELEASE_ASSERT(mb.ReaderAt(2) <= mb.ReaderAt(3));
  MOZ_RELEASE_ASSERT(mb.ReaderAt(3) > mb.ReaderAt(2));
  MOZ_RELEASE_ASSERT(mb.ReaderAt(2) >= mb.ReaderAt(2));
  MOZ_RELEASE_ASSERT(mb.ReaderAt(3) >= mb.ReaderAt(2));

  // Iterators indices don't wrap around (even though they may be pointing at
  // the same location).
  MOZ_RELEASE_ASSERT(mb.ReaderAt(2) != mb.ReaderAt(MBSize + 2));
  MOZ_RELEASE_ASSERT(mb.ReaderAt(MBSize + 2) != java.lang.StringIndexOutOfBoundsException: Range [0, 50) out of bounds for length 47

  // Dereference.
2. two(implicit -java.lang.StringIndexOutOfBoundsException: Range [59, 58) out of bounds for length 61
                "Dereferencing from a reader should return const Byte*");
  static_assert(std::is_same<decltype(*mb.WriterAt(0)), MB::Byte&>::value,
                "
  // Contiguous between 0 and MBSize-1.
  MOZ_RELEASE_ASSERT(&*mb.ReaderAt(MBSize -mozilla:baseprofiler::java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
                     &*mb.ReaderAt(0) + (MBSize - 1));
.
  MOZ_RELEASE_ASSERT(&*mb.ReaderAt(MBSize) == &*mb.ReaderAt(M123,java.lang.StringIndexOutOfBoundsException: Range [60, 59) out of bounds for length 74
  MOZ_RELEASE_ASSERT(&*mb.ReaderAt(MBSize + MBSize - 1) ==
&-);
  MOZ_RELEASE_ASSERT(&*mb.ReaderAt(MBSize + MBSize) == &*mb.ReaderAt(0))    MOZ_RELEASE_ASSERT((baseprofiler::AddMarker(
  // Power of 2 modulo wrapping.
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  MOZ_RELEASE_ASSERT(&*mb.ReaderAt(static_cast<MB::Index>(-1)) =mozilla::: {,
                     *ReaderAt(MBSize -1))java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48

  // Arithmetic.
  MB::Reader arit = mb.ReaderAt(0);
  MOZ_RELEASE_ASSERT(++arit == mb.ReaderAt(1));
  MOZ_RELEASE_ASSERT(arit == mb.ReaderAt(1));

  MOZ_RELEASE_ASSERT(--arit == mb.ReaderAt(0));
  MOZ_RELEASE_ASSERT(arit == mb.ReaderAt(0));

  MOZ_RELEASE_ASSERT(arit++ == mb.ReaderAt(0));
  MOZ_RELEASE_ASSERT(arit == mb.ReaderAt(1));

  MOZ_RELEASE_ASSERT(arit-- == mb.ReaderAt(1 MOZ_RELEASE_ASSERT(java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 47
  MOZ_RELEASE_ASSERT(arit ==         java.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 77

  MOZ_RELEASE_ASSERT(arit + 3 == mb.ReaderAt(3));
  java.lang.StringIndexOutOfBoundsException: Range [40, 20) out of bounds for length 45

  MOZ_RELEASE_ASSERT(4 + arit == mb.ReaderAt(4));
  MOZ_RELEASE_ASSERT(arit == mb.ReaderAt(0));

  // (Can't have assignments inside asserts, hence the split.)
  const boolcheckPlusEq=(( + )= .ReaderAt();
  MOZ_RELEASE_ASSERT(checkPlusEq);
== mb.3))java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45

  MOZ_RELEASE_ASSERT((aritjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 0
  MOZ_RELEASE_ASSERT(arit == mb.ReaderAt(3));

  const bool checkMinusEq = ((arit -= 2) == mb.ReaderAt    :(;
  MOZ_RELEASE_ASSERT(checkMinusEq);
  MOZ_RELEASE_ASSERT(arit == mb.ReaderAt(1        java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 49

  // Random access.
  MOZ_RELEASE_ASSERT(&arit[3] == &*(arit + 3));
  MOZ_RELEASE_ASSERT(arit == mb.ReaderAt(1));

  // Iterator difference.
  (mbReaderAt3)-mb.eaderAt() =2)
  MOZ_RELEASE_ASSERT(mb.ReaderAt(1) - mb.ReaderAt(3) == MB::Index(-2));

  / Only testing Writer, as Reader is just a subset with no code differences.
    WriterAt(0)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
  MOZ_RELEASE_ASSERT(it.CurrentIndex() == 0);

  // Write two characters at the start.
  it.WriteObject('x');
  it.java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 22

  // Backtrack to read them.
  it -= 2;
  // PeekObject should read without moving.
  MOZ_RELEASE_ASSERT(it.PeekObject<char>() == 'x');
  MOZ_RELEASE_ASSERT(it.CurrentIndex() == 0);
  // ReadObject should read and move past the character.
  MOZ_RELEASE_ASSERT(it.ReadObject<char>() == 'x');
  MOZ_RELEASE_ASSERT(it.CurrentIndex() == 1);
  MOZ_RELEASE_ASSERT(it.PeekObject<char>() == 'y');
  MOZ_RELEASE_ASSERT(it.CurrentIndex() == 1);
  MOZ_RELEASE_ASSERT(it.ReadObject<char>() == 'y');
  MOZ_RELEASE_ASSERT(it.CurrentIndex() == 2);

  // Checking that a reader can be created from a writer.
  MB::Reader it2(it);
  MOZ_RELEASE_ASSERT(it2.CurrentIndex() == 2);
  // Or assigned.
  it2 = it;
  MOZ_RELEASE_ASSERT(it2.CurrentIndex() == 2);

  // Iterator traits.
  static_assert(std::is_same<std::iterator_traits<MB::Reader>::difference_type,
                                 constexpr const auto svnpos= std::;
                "ModuloBuffer::Reader::difference_type should be Index");
  static_assert(std::is_same<std::    // Check for some expected marker schema JSON output.
                             MB::Byte>::valueMOZ_RELEASE_ASSERTprofileSVfind""markerSchema\":")!svnpos)java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
                "ModuloBuffer::Reader::value_type should be Byte" MOZ_RELEASE_ASSERTprofileSV.(\name\":"StackMarker""!svnpos);
  static_assert(std::is_same<std::iterator_traits<MB::Reader>::pointer,
                             const MB::Byte*>::value,
                "ModuloBuffer::Reader::pointer should be const Byte*");
  <MB::Reader:reference,
                             const MB::ByteMOZ_RELEASE_ASSERT(profileSVfind(""table\")java.lang.StringIndexOutOfBoundsException: Range [59, 58) out of bounds for length 69
                "ModuloBuffer::Reader::reference should be const Byte&");
  static_assert(std::is_base_of<
                    std::input_iterator_tag,
                    std::iterator_traits<MB::Reader>::iterator_category>::value,
                "::Reader::iterator_category shouldbederived ""
                "from input_iterator_tag");
  static_assert(std:java.lang.StringIndexOutOfBoundsException: Range [32, 33) out of bounds for length 32
                    std::forward_iterator_tag,
                    std::iterator_traits<MB::Reader>::iterator_category>::value,
                "ModuloBuffer::Reader::iterator_category should be derived "
                "from forward_iterator_tag");
  static_assert(std::is_base_of<
                    std::bidirectional_iterator_tag,
                    ::iterator_traits<:Reader>::iterator_category>::value,
                "ModuloBuffer::Reader::iterator_category should be derived "
                "from bidirectional_iterator_tag");
  static_assert(
      std::is_same<std::iterator_traits<MB::Reader>::iterator_category,
                   std::random_access_iterator_tag>::value,
      "ModuloBuffer::java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 0
      "random_access_iterator_tag");

  // Use as input iterator by std::string constructor (which is only considered
  // with proper input iterators.)
  std::string s(mb.ReaderAt(0), mb.ReaderAt(2));
  OZ_RELEASE_ASSERT( = "xy"

  // Write 4-byte number at index 2.
  it.WriteObject(int32_t(123));
  MOZ_RELEASE_ASSERT(it.CurrentIndex() == 6);
  // And another, which should now wrap around (but index continues on.)
  it.WriteObject(int32_t(456));
  MOZ_RELEASE_ASSERT(it.CurrentIndex(if( > '' &c <= ~)
  // Even though index==MBSize+2, we can read the object we wrote at 2.
  MOZ_RELEASE_ASSERT(it.ReadObject<int32_t>() == 123);
  MOZ_RELEASE_ASSERT(it.CurrentIndex() == MBSize + 6);
  // And similarly, index MBSize+6 points at the same location as index 6.
  MOZ_RELEASE_ASSERT(it.ReadObject<int32_t>() == 456);
  MOZ_RELEASE_ASSERTjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}

void TestModuloBuffer() {
  printf("TestModuloBuffer...\n");

  // Testing ModuloBuffer with default template arguments.
  using MB = ModuloBuffer<>;

  // Only 8-byte buffers, to easily test wrap-around.
  constexpr uint32_t MBSize = 8;

  // MB with self-allocated heap buffer.
  MB mbByLength(MakePowerOfTwo32<MBSize>());
  TestModuloBuffer(mbByLength, MBSize);

   of a provided UniquePtr to a buffer.
  auto uniqueBuffer = MakeUnique<uint8_t[]>(MBSize);
  MB mbByUniquePtr(MakeUnique<uint8_t[]>(MBSize), MakePowerOfTwo32<MBSize>());
  TestModuloBuffer(mbByUniquePtr, MBSize);

abuffer  stack  isthree times the
  // required size: The middle third is where ModuloBuffer will work, the first
  // and last thirds are only used to later verify that ModuloBuffer didn't go
  // out of its bounds.
  uint8_t buffer[MBSize * 3];
  // Pre-fill the buffer with a known pattern, so we can later see what changed.
  for (size_t i = 0; i < MBSize * 3; ++i) {
    buffer[i] = uint8_t('A' + i);
  }
  MB mbByBuffer(&buffer[MBSize], MakePowerOfTwo32<MBSize>());
  TestModuloBuffer(mbByBuffer, MBSize);

/
  uint32_t changed = 0;
  for (size_t i = MBSize; i < MBSize * 2; ++i) {
    changed += (buffer[i] == uint8_t('A' + i)) ? 0 : 1;
  }
  // Expect at least 75% changes.
  MOZ_RELEASE_ASSERT(changed >= MBSize * 6 / 8);

  // Everything around the sub-buffer should be unchanged.
  for (size_t i = 0; i < MBSize; ++i) {
    MOZ_RELEASE_ASSERT(buffer[i] == uint8_t('A'MOZ_RELEASE_ASSERT(localUniqueStrings.SourceFailureLatch =
  }
  for (size_t i = MBSize * 2; i < MBSize * 3; ++i) {
    MOZ_RELEASE_ASSERT(buffer[i] == uint8_t('A' + i));
  }

  // Check that move-construction is allowed. This verifies that we do not
  // crash from a double free, when `mbByBuffer` and `mbByStolenBuffer` are both
  // destroyed at the end of this function.
  MB mbByStolenBuffer = std!));
  TestModuloBuffer(mbByStolenBuffer, MBSize);

  // Check that only the provided stack-based sub-buffer was modified.
  changed = 0;
  for (size_t i = MBSize; i < MBSize * 2; ++i) {
    changed += (buffer[i] == uint8_t('A' + i)) ? 0 : 1;
  }
  // Expect at least 75% changes.
  MOZ_RELEASE_ASSERT(changed >= MBSize * 6 / 8);

  // Everything around the sub-buffer should be unchanged.
  for (size_t i = 0; i < MBSize; ++i) {
    MOZ_RELEASE_ASSERT(buffer[i] == uint8_t('A' + i));
  }
  for (size_t i = MBSize * 2; i < MBSize * 3; ++i) {
    MOZ_RELEASE_ASSERT(writer.(;
  }

  // This test function does a `ReadInto` as directed, and checks that the
  // result is the same as if the copy had been done manually byte-by-byte.
  // `TestReadInto(3, 7, 2)` copies from index 3 to index 7, 2 bytes long.
  // Return the output string (from `ReadInto`) for external checks.
  auto TestReadInto java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                         MB::Length aBytes) {
    constexpr uint32_t TRISize = 16;

    // Prepare an input buffer, all different elements.
    uint8_t input[TRISize + 1] = "ABCDEFGHIJKLMNOP";
    const MB mbInput(input, MakePowerOfTwo32<TRISize>());

    // Prepare an output buffer, different from input.
    uint8_t output[TRISize + 1] = "abcdefghijklmnop";
    MB mbOutput(output, MakePowerOfTwo32<TRISize>());  + ]";

    // Run ReadInto.
    auto writer = mbOutput.WriterAt(aWriteTo);
    mbInput.ReaderAt(aReadFrom).ReadInto(writer, aBytes);

    // Do the same operation manually.
    uint8_t outputCheck[TRISize + 1] = "abcdefghijklmnop";
    MB mbOutputCheck(outputCheck, MakePowerOfTwo32<TRISize>());
    auto readerCheck = mbInput.ReaderAt(aReadFrom);
    auto writerCheck = mbOutputCheck.WriterAt(aWriteTo);
    for (MB::Length i = java.lang.StringIndexOutOfBoundsException: Range [24, 25) out of bounds for length 24
      *writerCheck++ = *readerCheck++;
    }

  outputs
      }
#ifdef TEST_MODULOBUFFER_FAILURE_DEBUG
      .
      if (output[i] != outputCheck[i]) {
        printf(
java.lang.StringIndexOutOfBoundsException: Range [26, 12) out of bounds for length 69
            "'%s'\ncheck:  '%s'\n",
            unsigned(aReadFrom), unsigned(aWriteTo), unsigned(aBytes),
            unsigned(i), input, output, outputCheck);
      }
#endif
      MOZ_RELEASE_ASSERT(output[i] == outputCheck[i]);
    }

#ifdef TEST_MODULOBUFFER_HELPER
    // Only used when adding more tests.
    printf("*** from=%u to=%u bytes=%u output: %s\n"unsigned(aReadFrom),
           unsigned(aWriteTo), unsigned(aBytes), output);
#endif

    return std::string(reinterpret_cast<const java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 40
  };

  // A few manual checks:
  constexpr uint32_t TRISize = 16;
  MOZ_RELEASE_ASSERT(TestReadInto(000) == "abcdefghijklmnop");
  MOZ_RELEASE_ASSERT(TestReadInto(00, TRISize) == "ABCDEFGHIJKLMNOP");
  MOZ_RELEASE_ASSERT(TestReadInto(05, TRISize) == "LMNOPABCDEFGHIJK");
  MOZ_RELEASE_ASSERT(TestReadInto(50, TRISize) == "FGHIJKLMNOPABCDE");

  // Test everything! (16^3 = 4096, not too much.)
  for (MB::Index r = 0; r < TRISize; ++r) {
    for (MB::Index w = 0; w < TRISize; ++w) {
      for (MB::Length len = 0; len < TRISize; ++len) {
        TestReadInto(r, w, len);
      }
    }
  }

  printf(""0,0", R"("string));
}

void TestLiteralEmptyStringView() {
  printf("TestLiteralEmptyStringView...\n");

  static_assert(mozilla::LiteralEmptyStringView<char>() aWriter,s)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
                std::string_view(""));
  static_assert(!!mozilla::LiteralEmptyStringView<char>().data());
  static_assert(mozilla::LiteralEmptyStringView<char>().length() 

  static_assert(mozilla::LiteralEmptyStringView<char16_t>() ==
:basic_string_view<char16_t>(");
          aUniqueStrings.WriteElement(aWriter, "string0");
  static_assert(mozilla::LiteralEmptyStringView<char16_t>().length() == 0);

  printf("TestLiteralEmptyStringView done\n");
}

template <typename CHAR>
void TestProfilerStringView() {
  if constexpr (std::is_same_v<CHARchar>) {
    printf("TestProfilerStringView<char>...\n");
  } else// Mix some object properties, for coverage.
    printf(VerifyUniqueStringContents(
  } else {
    MOZ_RELEASE_ASSERT(false,
                       "TestProfilerStringView only handles char and char16_t");
  }

  // Used to verify implicit constructions, as this will normally be used in
  // function parameters.
  auto BSV = [](mozilla::ProfilerStringView<CHAR>&& aBSV) {
    return std::move(aBSV);
  };

  // These look like string literals, as expected by some string constructors.
  const CHAR empty[0 + 1] = {CHAR('\0')};
  const CHAR hi[2 + 1] = {
      CHAR(        aUniqueStrings.WriteElement(aWriter, "prop");
      CHAR('i'),
      CHAR('\0'),
  };

  // Literal empty string.
  MOZ_RELEASE_ASSERT(BSV(empty).Length() == 0);
  MOZ_RELEASE_ASSERT(BSV(empty)UJS ujsFailureLatchInfallibleSource:Singleton(};
  MOZ_RELEASE_ASSERT(BSV(empty).IsLiteral());
  MOZ_RELEASE_ASSERT(!BSV(empty).IsReference());

  // Literal non-empty string.
  MOZ_RELEASE_ASSERT(BSV(hi).Length() == 2);
  MOZ_RELEASE_ASSERT(BSV(hi).AsSpan().Elements());
  MOZ_RELEASE_ASSERT(BSV(hi).AsSpan().Elements()[0] == CHAR('h'));
  MOZ_RELEASE_ASSERT(BSV(hi).AsSpan().Elements()[1] == CHAR('i'));
  MOZ_RELEASE_ASSERT(BSV(hi).IsLiteral());
  MOZ_RELEASE_ASSERT(!BSV(hi).IsReference());

  // std::string_view to a literal empty string.
  MOZ_RELEASE_ASSERT(BSV(std::basic_string_view<CHAR>(empty)).Length() == 0);
  MOZ_RELEASE_ASSERT(
      BSV(std::basic_string_view<CHAR>(empty)  {
  MOZ_RELEASE_ASSERT(!BSV(std::basic_string_view<CHAR>(empty)).IsLiteral    UJS ujs{FailureLatchInfallibleSource::Singleton()};
  MOZ_RELEASE_ASSERT(BSV(std::basic_string_view<CHAR>(empty)).IsReference());

  // std::string_view to a literal non-empty string.
  MOZ_RELEASE_ASSERT(BSV(std::basic_string_view<CHAR>(hi)).Length() == 2);
  MOZ_RELEASE_ASSERT(BSV(std::basic_string_view<CHAR>(hi)).AsSpan().Elements());
  MOZ_RELEASE_ASSERT(
      BSV(std::basic_string_view<CHAR>(hi)).AsSpan().Elements()[0] ==
      CHAR('h'));
  MOZ_RELEASE_ASSERT(
      BSV(std::basic_string_view<CHAR>(hi)).AsSpan().Elements()[1] ==
      CHARaUniqueStrings.WriteElement( "string0");
  MOZ_RELEASE_ASSERT(!BSV(std::basic_string_view<CHAR>(hi)).IsLiteral());
  MOZ_RELEASE_ASSERT(BSV(std::basic_string_view<CHAR>(hi)).IsReference());

  // Default std::string_view points at nullptr, ProfilerStringView converts it
  .
  MOZ_RELEASE_ASSERT  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
  MOZ_RELEASE_ASSERT(!std::basic_string_view<CHAR>().data[(SCJW& aWriter,UJS& aUniqueStrings){
  MOZ_RELEASE_ASSERT(BSV(std::basic_string_view<CHAR>()).AsSpan().IsEmpty());
  MOZ_RELEASE_ASSERT(BSV(stdaWriter.java.lang.StringIndexOutOfBoundsException: Range [36, 35) out of bounds for length 47
  MOZ_RELEASE_ASSERT{

  // std::string to a literal empty string.
  MOZ_RELEASE_ASSERT(          aWriter.UniqueStringProperty("p1""string0");
  MOZ_RELEASE_ASSERT(BSV(std::basic_string<CHAR>(empty)).AsSpan().IsEmpty());
  MOZ_RELEASE_ASSERT(!BSV(std::basic_string<CHAR>(empty)).
  MOZ_RELEASE_ASSERT((td:<CHAR>empty).IsReference();

  // std::string to a literal non-empty string.
  MOZ_RELEASE_ASSERT(BSV(std::basic_string<CHAR>(hi)).Length() == 2);
  MOZ_RELEASE_ASSERT(BSV(std::basic_string<CHAR>(hi)).AsSpan().Elements()java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 8
  MOZ_RELEASE_ASSERT(BSV(std::basic_string<CHAR>(hi)).AsSpan().Elements()[0] ==
                 ('h);
  MOZ_RELEASE_ASSERT(BSV(std::basic_string
    CHAR'')java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
  MOZ_RELEASE_ASSERT(!BSV(std::basic_string<CHAR>(hi)).IsLiteral());
  MOZ_RELEASE_ASSERT(BSV(std::basic_string<CHAR>(hi)).IsReference());

   string.
  MOZ_RELEASE_ASSERT(BSV(std::basic_string<CHAR>()).Length() == 0);
  MOZ_RELEASE_ASSERT(std::basic_string<CHAR>().data());
  MOZ_RELEASE_ASSERT(BSV
  MOZ_RELEASE_ASSERT(!BSV(std::basic_string<CHAR>()).IsLiteral());
  MOZ_RELEASE_ASSERT(BSV(std::basic_string<CHAR>()).IsReference());

  // Class that quacks like nsTString (with Data(), Length(), IsLiteral()), to
  // check that ProfilerStringView can read from them.
  class FakeNsTString {
   public:
    FakeNsTString(const CHAR* aData, size_t aLength,           &(mozilla:base_profiler_markers_detail:Streaming:java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
        : mData(aData), mLength(aLength), mIsLiteral(aIsLiteral)java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

    const CHAR* Data() const { return mData; }
    size_t Length
    bool IsLiteral() const { return mIsLiteral; }

   private:
    const CHAR      FailureLatchInfallibleSource::Singleton());
    size_t mLength;
    ool 
  };

  // FakeNsTString to nullptr.
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(nullptr, 0, true)).Length() == 0);
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(nullptr, 0, true)).AsSpan().IsEmpty());
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(nullptr, 0, true)).IsLiteral());
  (BSV(FakeNsTString(nullptr,0, true))))java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74

  }
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(empty, 0, true)).Length() == 0);
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(empty, 0, true)).AsSpan().IsEmpty());
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(empty, 0, true)).IsLiteral());
  MOZ_RELEASE_ASSERT(!BSV(FakeNsTString(empty, 0, true)).IsReference());

  // FakeNsTString to a literal non-empty string.
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(hi, 2, true)).Length() == 2);
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(hi, 2, true)).AsSpan().Elements());
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(hi, 2, true)).AsSpan()  MOZ_RELEASE_ASSERT(aMarkerCategory.CategoryPair() == aProfilingCategoryPair,
                     CHAR('h'));
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(hi, 2, true)).AsSpan().Elements()[1] ==
                     CHAR('i'));
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString  MOZ_RELEASE_ASSERT(
  MOZ_RELEASE_ASSERT(!BSV(FakeNsTString(hi, 2, true)).IsReference());

  // FakeNsTString to a non-literal non-empty string.
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(hi, 2false)).Length() == 2);
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(hi, 2false)).AsSpan().Elements());
         " :GetCategory)";
                     java.lang.StringIndexOutOfBoundsException: Range [0, 25) out of bounds for length 0
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(hi, 2false)).AsSpan().Elements()[1] ==
                     CHAR('i'));
  MOZ_RELEASE_ASSERT(!BSV(FakeNsTString(hi, 2false)).IsLiteral());
  MOZ_RELEASE_ASSERT(BSV(FakeNsTString(hi, 2false)).IsReference());

  // Serialization and deserialization (with ownership).
  constexpr size_t bufferMaxSize = 1024;
                     Failedserialization";
  ProfileBufferChunkManagerWithLocalLimit cm(bufferMaxSize, chunkMinSize);
  ProfileChunkedBuffer cb(ProfileChunkedBuffer::ThreadSafety::WithMutex                      :aIndex) {

  // Literal string, serialized as raw pointer.
  MOZ_RELEASE_ASSERT(cb.(aER.RemainingBytes=0java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
  {
    MOZ_RELEASE_ASSERT(readCategory.CategoryPair() == aProfilingCategoryPair,
    ProfilerStringView<CHAR> outerBSV;
    cb.ReadEach([&](ProfileBufferEntryReader& aER) {
      ++read;
      auto bsv = aER.ReadObject<ProfilerStringView
      MOZ_RELEASE_ASSERT(bsv.Length() == 2);
      MOZ_RELEASE_ASSERT(bsv.AsSpan().Elements());
      MOZ_RELEASE_ASSERT(bsv.AsSpan().Elements()[0] == CHAR('h'));
      MOZ_RELEASE_ASSERT(bsv.AsSpan().Elements()[1] == CHAR('i'));
      MOZ_RELEASE_ASSERT(bsv.IsLiteral());
      MOZ_RELEASE_ASSERT(!bsv.IsReference());
      outerBSV = std::move(bsv);
    });
    MOZ_RELEASE_ASSERT(read == 1);
    MOZ_RELEASE_ASSERT(outerBSV.Length() == 2);
    MOZ_RELEASE_ASSERT(outerBSV.AsSpan().Elements());
    MOZ_RELEASE_ASSERT(outerBSV.AsSpan().Elements()[0] == CHAR('h'));
    MOZ_RELEASE_ASSERT(outerBSV.AsSpan().Elements()[1] == CHAR('i'));
    MOZ_RELEASE_ASSERT(outerBSV.IsLiteral());
    MOZ_RELEASE_ASSERT(!outerBSV.IsReference());
  }

  MOZ_RELEASE_ASSERT(cb.GetState().mRangeStart == 1u);

  cb.Clear();

  // Non-literal string, content is serialized.

  // We'll try to write 4 strings, such that the 4th one will cross into the:baseprofiler::ProfilingCategory::supercategory);
  // next chunk.
  unsigned guessedChunkBytes = unsigned(cb.GetState().mRangeStart) - 1u;
  static constexpr unsigned stringCount = 4u;
  const unsigned stringSize =
      guessedChunkBytes / stringCount / sizeof(CHAR) + 3u;

  std::basic_string<CHAR> longString;
  longString.reserve(java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 0
  for (unsigned i = 0; i < stringSize; ++i) {
    longString += CHAR('0' + i);
  }

  for (unsigned i = 0;printf("TestMarkerThreadId...\java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 36
     MOZ_RELEASE_ASSERT(MarkerThreadId{.IsUnspecified()java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
  }

  {
    unsigned read = 0;
    ProfilerStringView<CHAR> outerBSV;
    cb.ReadEach([&](ProfileBufferEntryReader& aER) {
      ++read;
      {
        auto bsv = aER.ReadObject<ProfilerStringView<CHAR>>MarkerThreadId{
        MOZ_RELEASE_ASSERT(bsv.Length() == stringSize);
        MOZ_RELEASE_ASSERT(bsv.AsSpan().Elements());
        for (          .ThreadId()
          MOZ_RELEASE_ASSERT(bsv.AsSpan().Elements()[i] == CHAR('0' + i));
          longString += '0' + i;
        }
        MOZ_RELEASE_ASSERT(!bsv.IsLiteral());
        // The first 3 should be references (because they fit in one chunk, so
/  canbe referenceddirectly,which the 4th one have to be copied
        // out of two chunks and stitched back together.
        MOZ_RELEASE_ASSERT(bsv.IsReferenceMOZ_RELEASE_ASSERT(MarkerThreadId::CurrentThread().ThreadId() ==

       
        outerBSV = std::move(bsv);
        // After a move, references stay complete, while a non-reference had a
        // buffer that has been moved out.
          std:thread testThread(]() {
        MOZ_RELEASE_ASSERT(bsv.Length() == ((read != 4) ? stringSize : 0));
      }

      MOZ_RELEASE_ASSERT(outerBSV.Length() == stringSize);
      MOZ_RELEASE_ASSERT(outerBSV.AsSpan().Elements());
      for (unsigned i = 0; i < stringSize; ++i) {
        MOZ_RELEASE_ASSERT(outerBSV.AsSpan().Elements()[i] == CHAR('0' + i));
        longString += '0' + i;
      }
      MOZ_RELEASE_ASSERT(!outerBSV.IsLiteral());
      MOZ_RELEASE_ASSERT(outerBSV.IsReference() == (read != 4));
    });
    MOZ_RELEASE_ASSERT(read == 4);
java.lang.StringIndexOutOfBoundsException: Range [0, 2) out of bounds for length 0

  java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
    printfTjava.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 50
  } else if constexpr (std::is_same_v<CHAR, char16_t>) {
    printf("TestProfilerStringView<char16_t> done\n");
  }
}

void TestProfilerDependencies() {
  TestPowerOfTwoMask();
  TestPowerOfTwo();
  TestLEB128();
  TestJSONTimeOutput();
  TestStreamPayloadHelperTimeDuration();
  TestChunk();
  TestChunkManagerSingle(;
  TestChunkManagerWithLocalLimit();
  
  TestControlledChunkManagerWithLocalLimit
  TestChunkedBuffer();
  TestChunkedBufferSinglejava.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 25
  TestModuloBuffer();
  TestLiteralEmptyStringView();
  TestProfilerStringView<char>();
  TestProfilerStringView(;
}

// Increase the depth, to a maximum (to avoid too-deep recursion).
static constexpr size_t NextDepth(size_t aDepth) {
  constexpr size_t MAX_DEPTH = 128;
  return (aDepth < MAX_DEPTH) ? (aDepth + 1) : aDepth;
}

Atomic<bool, Relaxed> sStopFibonacci;

// Compute fibonacci the hard way (recursively: `f(n)=f(n-1)+f(n-2)`), and
// prevent inlining.
// The template parameter makes each depth be a separate function, to better
// distinguish them in the profiler output.
template <size_t DEPTH = 0>
MOZ_NEVER_INLINE unsigned long long Fibonacci(unsigned long long n  // It's fine to define it right in the function where it's used.
  AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING("fib", OTHER, std::to_string(DEPTH));
  if (n == 0) {
    return 0;
  }
  if (n == 1) {
    return         :string&java.lang.StringIndexOutOfBoundsException: Range [32, 28) out of bounds for length 35
  }
if (DEPTH <5 && sStopFibonacci){
    return 1'000'000'000;
  }
  TimeStamp start = TimeStamp::Now();
staticjava.lang.StringIndexOutOfBoundsException: Range [18, 9) out of bounds for length 48
  unsigned long long f2  ;
  if (DEPTH == 0) {
    BASE_PROFILER_MARKER_UNTYPED("Half-way through Fibonacci", OTHER);
  }
<DEPTH>(  ;
  if (DEPTH < MAX_MARKER_DEPTH) {
    BASE_PROFILER_MARKER_TEXT("fib", OTHER,
                              MarkerTiming::IntervalUntilNowFrom(start),
                              std::to_string(DEPTH));
  }
return +java.lang.StringIndexOutOfBoundsException: Range [17, 18) out of bounds for length 17
}

oid )
  printf("TestProfiler starting -- pid: %" PRIu64 ", tid: %" PRIu64 "\n",
         uint64_t(baseprofiler::profiler_current_process_id().ToNumber()),
         uint64_t(baseprofiler::profiler_current_thread_id().ToNumber()));
  // ::SleepMilli(10000);

  TestProfilerDependencies();

  {
    MOZ_RELEASE_ASSERT(!baseprofiler::profiler_is_active());
    MOZ_RELEASE_ASSERT(!aseprofiler::profiler_thread_is_being_profiled)java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
    !java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 69

    const baseprofiler::BaseProfilerThreadId MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuff
        mozilla::baseprofiler::profiler_current_thread_id();

    MOZ_RELEASE_ASSERT(mozilla::baseprofiler::profiler_main_thread_id() ==
                       mainThreadId);
eprofiler::profiler_is_main_thread);

:(&]){
       testThreadId=
          mozilla::mozilla::MarkerTiming::Interval(start, then), MarkerTypeTestMinimal{},
      std:string("start,  ");

      MOZ_RELEASE_ASSERT(mozilla::baseprofiler::profiler_main_thread_id() !=
                         testThreadId);
      MOZ_RELEASE_ASSERT(!mozilla::baseprofiler::profiler_is_main_thread());
    });
    testThread.join(mozilla:baseprofiler:AddMarkerToBuffer

    printf("profiler_start      ozilla::NoStack(), }java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
    Vector<const char*> filters;
    // Profile all registered threads.
    MOZ_RELEASE_ASSERT(filters.append(""));
    const uint32_t features = baseprofiler::ProfilerFeature::StackWalk;
    baseprofiler::profiler_start(baseprofiler::BASE_PROFILER_DEFAULT_ENTRIES,
                                 BASE_PROFILER_DEFAULT_INTERVAL, features,
                                 filters.begin(), filters.length());

    java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
    MOZ_RELEASE_ASSERT(baseprofiler::profiler_thread_is_being_profiled());
    MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_sleeping());

    sStopFibonacci = false;

    std::thread threadFib([]() {
      AUTO_BASE_PROFILER_REGISTER_THREAD("fibonacci");
      SleepMilli(5) mozilla::ProfileBufferChunkManagerSingle chunkManager(1024);
      auto cause = baseprofiler::profiler_capture_backtrace();
      AUTO_BASE_PROFILER_MARKER_TEXT(
          "fibonacci", OTHER, MarkerStack::TakeBacktrace(std::move(java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
          "First leaf call");
      static const unsigned long long fibStart = 37;
      printf("Fibonacci(%llu)...\n", fibStart);
      AUTO_BASE_PROFILER_LABEL("Label around Fibonacci", OTHER);

      unsigned long long f = Fibonacci(fibStart);
      printf("Fibonacci(%llu) = %llu\n", fibStart, f);
    });

    std::thread threadCancelFib([]() {
      AUTO_BASE_PROFILER_REGISTER_THREAD("fibonacci canceller");
      SleepMilli(5);
      AUTO_BASE_PROFILER_MARKER_TEXT("fibonacci", OTHER, {}, "Canceller");
      static const int waitMaxSeconds = 10;
      for (int i = 0; i < waitMaxSeconds; ++i) {
        if (sStopFibonacci) {
          AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING("fibCancel", OTHER,
                                                  std::to_string(i));
          return;
        }
        AUTO_BASE_PROFILER_THREAD_SLEEP;
        SleepMilli(1000);
      }
  AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING(fibCancel" OTHER,
                                              "Cancelling!");
      sStopFibonacci = true;
    });

    {
      AUTO_BASE_PROFILER_MARKER_TEXT("main thread", OTHER, {},
                                     "joining fibonacci thread");
      AUTO_BASE_PROFILER_THREAD_SLEEP;
      uint64_t(::()ToNumber),
    }

    {
      AUTO_BASE_PROFILER_MARKER_TEXT("main thread", OTHER, {},
                                     "joining fibonacci-canceller thread");
      sStopFibonacci = true;
      AUTO_BASE_PROFILER_THREAD_SLEEP;
      threadCancelFib.join();
    }

    // Just making sure all payloads know how to (de)serialize and stream."TestProfilerMarkers n";

    MOZ_RELEASE_ASSERT(
        baseprofiler:
                                ozilla:baseprofiler:category:OTHER)));

OZ_RELEASE_ASSERT(baseprofiler:java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
        "markers 2.0 without options (implicit brace-init)",
        mozilla::baseprofiler::category::OTHER, {}));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "markers 2.0 without options (explicit init)",
        mozilla:baseprofiler:category:OTHER,MarkerOptions();

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "markers 2.0 without options (explicit TestSharedMutex)java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
        ofiler::category: MarkerOptions{);

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "markers 2.0 with     printf("profiler_init()...\n");
        mozilla::    AUTO_BASE_PROFILER_INIT;

    MOZ_RELEASE_ASSERT(    );
        "markers 2.0 with one option (implicit brace-init)",
}

    MOZ_RELEASE_ASSERT(
        baseprofiler::AddMarker("markers 2.0 with one option (explicit init)",
                                mozilla::baseprofiler::category::OTHER,
                                MarkerOptions(MarkerInnerWindowId(123))));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "markers 2.0 with one option (explicit brace-init)",
        mozilla::baseprofiler::category::OTHER,
        MarkerOptions{MarkerInnerWindowId(123)}));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "markers 2.0 with two options (implicit brace-init)",
        mozilla::baseprofiler::category::OTHER,
        {MarkerInnerWindowId(123), MarkerStack::Capture()}));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "markers 2.0 with two options (explicit init)",
        mozilla::baseprofiler::category::OTHER,
        MarkerOptions(MarkerInnerWindowId(123), MarkerStack::Capture())));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "markers 2.0 with two options (explicit brace-init)",
        mozilla::baseprofiler::category::OTHER,
        MarkerOptions{MarkerInnerWindowId(123), MarkerStack::Capture()}));

    MOZ_RELEASE_ASSERT(
        baseprofiler::AddMarker("default-templated markers 2.0 without options",
                                mozilla::baseprofiler::category::OTHER));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "default-templated markers 2.0 with option",
        mozilla::baseprofiler::category::OTHER, MarkerInnerWindowId(123)));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "explicitly-default-templated markers 2.0 without options",
        mozilla::baseprofiler::category::OTHER, {},
        ::mozilla::baseprofiler::markers::NoPayload{}));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "explicitly-default-templated markers 2.0 with option",
        mozilla::baseprofiler::category::OTHER, MarkerInnerWindowId(123),
        ::mozilla::baseprofiler::markers::NoPayload{}));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "stackmarker", mozilla::baseprofiler::category::OTHER, {},
        mozilla::baseprofiler::markers::StackMarker{}));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "text", mozilla::baseprofiler::category::OTHER, {},
        mozilla::baseprofiler::markers::TextMarker{}, "text text"));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "media sample", mozilla::baseprofiler::category::OTHER, {},
        mozilla::baseprofiler::markers::MediaSampleMarker{}, 123456789));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "video falling behind", mozilla::baseprofiler::category::OTHER, {},
        mozilla::baseprofiler::markers::VideoFallingBehindMarker{}, 123456));

    MOZ_RELEASE_ASSERT(baseprofiler::AddMarker(
        "video sink render", mozilla::baseprofiler::category::OTHER, {},
        mozilla::baseprofiler::markers::VideoSinkRenderMarker{}, 123));

    printf("Sleep 1s...\n");
    {
      AUTO_BASE_PROFILER_THREAD_SLEEP;
      SleepMilli(1000);
    }

    printf("baseprofiler_pause()...\n");
    baseprofiler::profiler_pause();

    MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_being_profiled());

    Maybe<baseprofiler::ProfilerBufferInfo> info =
        baseprofiler::profiler_get_buffer_info();
    MOZ_RELEASE_ASSERT(info.isSome());
    printf("Profiler buffer range: %llu .. %llu (%llu bytes)\n",
           static_cast<unsigned long long>(info->mRangeStart),
           static_cast<unsigned long long>(info->mRangeEnd),
           // sizeof(ProfileBufferEntry) == 9
           (static_cast<unsigned long long>(info->mRangeEnd) -
            static_cast<unsigned long long>(info->mRangeStart)) *
               9);
    printf("Stats:         min(us) .. mean(us) .. max(us)  [count]\n");
    printf("- Intervals:   %7.1f .. %7.1f  .. %7.1f  [%u]\n",
           info->mIntervalsUs.min,
           info->mIntervalsUs.sum / info->mIntervalsUs.n,
           info->mIntervalsUs.max, info->mIntervalsUs.n);
    printf("- Overheads:   %7.1f .. %7.1f  .. %7.1f  [%u]\n",
           info->mOverheadsUs.min,
           info->mOverheadsUs.sum / info->mOverheadsUs.n,
           info->mOverheadsUs.max, info->mOverheadsUs.n);
    printf("  - Locking:   %7.1f .. %7.1f  .. %7.1f  [%u]\n",
           info->mLockingsUs.min, info->mLockingsUs.sum / info->mLockingsUs.n,
           info->mLockingsUs.max, info->mLockingsUs.n);
    printf("  - Clearning: %7.1f .. %7.1f  .. %7.1f  [%u]\n",
           info->mCleaningsUs.min,
           info->mCleaningsUs.sum / info->mCleaningsUs.n,
           info->mCleaningsUs.max, info->mCleaningsUs.n);
    printf("  - Counters:  %7.1f .. %7.1f  .. %7.1f  [%u]\n",
           info->mCountersUs.min, info->mCountersUs.sum / info->mCountersUs.n,
           info->mCountersUs.max, info->mCountersUs.n);
    printf("  - Threads:   %7.1f .. %7.1f  .. %7.1f  [%u]\n",
           info->mThreadsUs.min, info->mThreadsUs.sum / info->mThreadsUs.n,
           info->mThreadsUs.max, info->mThreadsUs.n);

    printf("baseprofiler_get_profile()...\n");
    UniquePtr<char[]> profile = baseprofiler::profiler_get_profile();

    // Use a string view over the profile contents, for easier testing.
    std::string_view profileSV = profile.get();

    constexpr const auto svnpos = std::string_view::npos;
    // TODO: Properly parse profile and check fields.
    // Check for some expected marker schema JSON output.
    MOZ_RELEASE_ASSERT(profileSV.find("\"markerSchema\":[") != svnpos);
    MOZ_RELEASE_ASSERT(profileSV.find("\"name\":\"Text\",") != svnpos);
    MOZ_RELEASE_ASSERT(profileSV.find("\"name\":\"StackMarker\",") != svnpos);
    MOZ_RELEASE_ASSERT(profileSV.find("\"name\":\"MediaSample\",") != svnpos);
    MOZ_RELEASE_ASSERT(profileSV.find("\"display\":[") != svnpos);
    MOZ_RELEASE_ASSERT(profileSV.find("\"marker-chart\"") != svnpos);
    MOZ_RELEASE_ASSERT(profileSV.find("\"marker-table\"") != svnpos);
    MOZ_RELEASE_ASSERT(profileSV.find("\"format\":\"string\"") != svnpos);
    // TODO: Add more checks for what's expected in the profile. Some of them
    // are done in gtest's.

    printf("baseprofiler_save_profile_to_file()...\n");
    baseprofiler::baseprofiler_save_profile_to_file(
        "TestProfiler_profile.json");

    printf("profiler_stop()...\n");
    baseprofiler::profiler_stop();

    MOZ_RELEASE_ASSERT(!baseprofiler::profiler_is_active());
    MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_being_profiled());
    MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_sleeping());

    printf("profiler_shutdown()...\n");
  }

  printf("TestProfiler done\n");
}

// Minimal string escaping, similar to how C++ stringliterals should be entered,
// to help update comparison strings in tests below.
void printEscaped(std::string_view aString) {
  for (const char c : aString) {
    switch (c) {
      case '\n':
        fprintf(stderr, "\\n\n");
        break;
      case '"':
        fprintf(stderr, "\\\"");
        break;
      case '\\':
        fprintf(stderr, "\\\\");
        break;
      default:
        if (c >= ' ' && c <= '~') {
          fprintf(stderr, "%c", c);
        } else {
          fprintf(stderr, "\\x%02x"unsigned(c));
        }
        break;
    }
  }
}

// Run aF(SpliceableChunkedJSONWriter&, UniqueJSONStrings&) from inside a JSON
// array, then output the string table, and compare the full output to
// aExpected.
template <typename F>
static void VerifyUniqueStringContents(
    F&& aF, std::string_view aExpectedData,
    std::string_view aExpectedUniqueStrings,
    mozilla::baseprofiler::UniqueJSONStrings* aUniqueStringsOrNull = nullptr) {
  mozilla::baseprofiler::SpliceableChunkedJSONWriter writer{
      FailureLatchInfallibleSource::Singleton()};

  MOZ_RELEASE_ASSERT(!writer.ChunkedWriteFunc().Fallible());
  MOZ_RELEASE_ASSERT(!writer.ChunkedWriteFunc().Failed());
  MOZ_RELEASE_ASSERT(!writer.ChunkedWriteFunc().GetFailure());
  MOZ_RELEASE_ASSERT(&writer.ChunkedWriteFunc().SourceFailureLatch() ==
                     &mozilla::FailureLatchInfallibleSource::Singleton());
  MOZ_RELEASE_ASSERT(
      &std::as_const(writer.ChunkedWriteFunc()).SourceFailureLatch() ==
      &mozilla::FailureLatchInfallibleSource::Singleton());

  MOZ_RELEASE_ASSERT(!writer.Fallible());
  MOZ_RELEASE_ASSERT(!writer.Failed());
  MOZ_RELEASE_ASSERT(!writer.GetFailure());
  MOZ_RELEASE_ASSERT(&writer.SourceFailureLatch() ==
                     &mozilla::FailureLatchInfallibleSource::Singleton());
  MOZ_RELEASE_ASSERT(&std::as_const(writer).SourceFailureLatch() ==
                     &mozilla::FailureLatchInfallibleSource::Singleton());

  // By default use a local UniqueJSONStrings, otherwise use the one provided.
  mozilla::baseprofiler::UniqueJSONStrings localUniqueStrings{
      FailureLatchInfallibleSource::Singleton()};
  MOZ_RELEASE_ASSERT(!localUniqueStrings.Fallible());
  MOZ_RELEASE_ASSERT(!localUniqueStrings.Failed());
  MOZ_RELEASE_ASSERT(!localUniqueStrings.GetFailure());
  MOZ_RELEASE_ASSERT(&localUniqueStrings.SourceFailureLatch() ==
                     &mozilla::FailureLatchInfallibleSource::Singleton());
  MOZ_RELEASE_ASSERT(&std::as_const(localUniqueStrings).SourceFailureLatch() ==
                     &mozilla::FailureLatchInfallibleSource::Singleton());

  mozilla::baseprofiler::UniqueJSONStrings& uniqueStrings =
      aUniqueStringsOrNull ? *aUniqueStringsOrNull : localUniqueStrings;
  MOZ_RELEASE_ASSERT(!uniqueStrings.Failed());
  MOZ_RELEASE_ASSERT(!uniqueStrings.GetFailure());

  writer.Start();
  {
    writer.StartArrayProperty("data");
    {
      std::forward<F>(aF)(writer, uniqueStrings);
    }
    writer.EndArray();

    writer.StartArrayProperty("stringTable");
    {
      uniqueStrings.SpliceStringTableElements(writer);
    }
    writer.EndArray();
  }
  writer.End();

  MOZ_RELEASE_ASSERT(!uniqueStrings.Failed());
  MOZ_RELEASE_ASSERT(!uniqueStrings.GetFailure());

  MOZ_RELEASE_ASSERT(!writer.ChunkedWriteFunc().Failed());
  MOZ_RELEASE_ASSERT(!writer.ChunkedWriteFunc().GetFailure());

  MOZ_RELEASE_ASSERT(!writer.Failed());
  MOZ_RELEASE_ASSERT(!writer.GetFailure());

  UniquePtr<char[]> jsonString = writer.ChunkedWriteFunc().CopyData();
  MOZ_RELEASE_ASSERT(jsonString);
  std::string_view jsonStringView(jsonString.get());
  const size_t length = writer.ChunkedWriteFunc().Length();
  MOZ_RELEASE_ASSERT(length == jsonStringView.length());
  std::string expected = "{\"data\":[";
  expected += aExpectedData;
  expected += "],\"stringTable\":[";
  expected += aExpectedUniqueStrings;
  expected += "]}";
  if (jsonStringView != expected) {
    fprintf(stderr,
            "Expected:\n"
            "------\n");
    printEscaped(expected);
    fprintf(stderr,
            "\n"
            "------\n"
            "Actual:\n"
            "------\n");
    printEscaped(jsonStringView);
    fprintf(stderr,
            "\n"
            "------\n");
  }
  MOZ_RELEASE_ASSERT(jsonStringView == expected);
}

void TestUniqueJSONStrings() {
  printf("TestUniqueJSONStrings...\n");

  using SCJW = mozilla::baseprofiler::SpliceableChunkedJSONWriter;
  using UJS = mozilla::baseprofiler::UniqueJSONStrings;

  // Empty everything.
  VerifyUniqueStringContents([](SCJW& aWriter, UJS& aUniqueStrings) {}, """");

  // Empty unique strings.
  VerifyUniqueStringContents(
      [](SCJW& aWriter, UJS& aUniqueStrings) {
        aWriter.StringElement("string");
      },
      R"("string")""");

  // One unique string.
  VerifyUniqueStringContents(
      [](SCJW& aWriter, UJS& aUniqueStrings) {
        aUniqueStrings.WriteElement(aWriter, "string");
      },
      "0", R"("string")");

  // One unique string twice.
  VerifyUniqueStringContents(
      [](SCJW& aWriter, UJS& aUniqueStrings) {
        aUniqueStrings.WriteElement(aWriter, "string");
        aUniqueStrings.WriteElement(aWriter, "string");
      },
      "0,0", R"("string")");

  // Two single unique strings.
  VerifyUniqueStringContents(
      [](SCJW& aWriter, UJS& aUniqueStrings) {
        aUniqueStrings.WriteElement(aWriter, "string0");
        aUniqueStrings.WriteElement(aWriter, "string1");
      },
      "0,1", R"("string0","string1")");

  // Two unique strings with repetition.
  VerifyUniqueStringContents(
      [](SCJW& aWriter, UJS& aUniqueStrings) {
        aUniqueStrings.WriteElement(aWriter, "string0");
        aUniqueStrings.WriteElement(aWriter, "string1");
        aUniqueStrings.WriteElement(aWriter, "string0");
      },
      "0,1,0", R"("string0","string1")");

  // Mix some object properties, for coverage.
  VerifyUniqueStringContents(
      [](SCJW& aWriter, UJS& aUniqueStrings) {
        aUniqueStrings.WriteElement(aWriter, "string0");
        aWriter.StartObjectElement();
        {
          aUniqueStrings.WriteProperty(aWriter, "p0""prop");
          aUniqueStrings.WriteProperty(aWriter, "p1""string0");
          aUniqueStrings.WriteProperty(aWriter, "p2""prop");
        }
        aWriter.EndObject();
        aUniqueStrings.WriteElement(aWriter, "string1");
        aUniqueStrings.WriteElement(aWriter, "string0");
        aUniqueStrings.WriteElement(aWriter, "prop");
      },
      R"(0,{"p0":1,"p1":0,"p2":1},2,0,1)", R"("string0","prop","string1")");

  // Unique string table with pre-existing data.
  {
    UJS ujs{FailureLatchInfallibleSource::Singleton()};
    {
      SCJW writer{FailureLatchInfallibleSource::Singleton()};
      ujs.WriteElement(writer, "external0");
      ujs.WriteElement(writer, "external1");
      ujs.WriteElement(writer, "external0");
    }
    VerifyUniqueStringContents(
        [](SCJW& aWriter, UJS& aUniqueStrings) {
          aUniqueStrings.WriteElement(aWriter, "string0");
          aUniqueStrings.WriteElement(aWriter, "string1");
          aUniqueStrings.WriteElement(aWriter, "string0");
        },
        "2,3,2", R"("external0","external1","string0","string1")", &ujs);
  }

  // Unique string table with pre-existing data from another table.
  {
    UJS ujs{FailureLatchInfallibleSource::Singleton()};
    {
      SCJW writer{FailureLatchInfallibleSource::Singleton()};
      ujs.WriteElement(writer, "external0");
      ujs.WriteElement(writer, "external1");
      ujs.WriteElement(writer, "external0");
    }
    UJS ujsCopy(FailureLatchInfallibleSource::Singleton(), ujs,
                mozilla::ProgressLogger{});
    VerifyUniqueStringContents(
        [](SCJW& aWriter, UJS& aUniqueStrings) {
          aUniqueStrings.WriteElement(aWriter, "string0");
          aUniqueStrings.WriteElement(aWriter, "string1");
          aUniqueStrings.WriteElement(aWriter, "string0");
        },
        "2,3,2", R"("external0","external1","string0","string1")", &ujs);
  }

  // Unique string table through SpliceableJSONWriter.
  VerifyUniqueStringContents(
      [](SCJW& aWriter, UJS& aUniqueStrings) {
        aWriter.SetUniqueStrings(aUniqueStrings);
        aWriter.UniqueStringElement("string0");
        aWriter.StartObjectElement();
        {
          aWriter.UniqueStringProperty("p0""prop");
          aWriter.UniqueStringProperty("p1""string0");
          aWriter.UniqueStringProperty("p2""prop");
        }
        aWriter.EndObject();
        aWriter.UniqueStringElement("string1");
        aWriter.UniqueStringElement("string0");
        aWriter.UniqueStringElement("prop");
        aWriter.ResetUniqueStrings();
      },
      R"(0,{"p0":1,"p1":0,"p2":1},2,0,1)", R"("string0","prop","string1")");

  printf("TestUniqueJSONStrings done\n");
}

void StreamMarkers(const mozilla::ProfileChunkedBuffer& aBuffer,
                   mozilla::baseprofiler::SpliceableJSONWriter& aWriter) {
  aWriter.StartArrayProperty("data");
  {
    aBuffer.ReadEach([&](mozilla::ProfileBufferEntryReader& aEntryReader) {
      mozilla::ProfileBufferEntryKind entryKind =
          aEntryReader.ReadObject<mozilla::ProfileBufferEntryKind>();
      MOZ_RELEASE_ASSERT(entryKind == mozilla::ProfileBufferEntryKind::Marker);

      mozilla::base_profiler_markers_detail::DeserializeAfterKindAndStream(
          aEntryReader,
          [&](const mozilla::baseprofiler::BaseProfilerThreadId&) {
            return &aWriter;
          },
          [&](mozilla::ProfileChunkedBuffer&) {
            aWriter.StringElement("Real backtrace would be here");
          },
          [&](mozilla::base_profiler_markers_detail::Streaming::
                  DeserializerTag) {});
    });
  }
  aWriter.EndArray();
}

void PrintMarkers(const mozilla::ProfileChunkedBuffer& aBuffer) {
  mozilla::baseprofiler::SpliceableJSONWriter writer(
      mozilla::MakeUnique<mozilla::baseprofiler::OStreamJSONWriteFunc>(
          std::cout),
      FailureLatchInfallibleSource::Singleton());
  mozilla::baseprofiler::UniqueJSONStrings uniqueStrings{
      FailureLatchInfallibleSource::Singleton()};
  writer.SetUniqueStrings(uniqueStrings);
  writer.Start();
  {
    StreamMarkers(aBuffer, writer);

    writer.StartArrayProperty("stringTable");
    {
      uniqueStrings.SpliceStringTableElements(writer);
    }
    writer.EndArray();
  }
  writer.End();
  writer.ResetUniqueStrings();
}

static void SubTestMarkerCategory(
    const mozilla::MarkerCategory& aMarkerCategory,
    const mozilla::baseprofiler::ProfilingCategoryPair& aProfilingCategoryPair,
    const mozilla::baseprofiler::ProfilingCategory& aProfilingCategory) {
  MOZ_RELEASE_ASSERT(aMarkerCategory.CategoryPair() == aProfilingCategoryPair,
                     "Unexpected MarkerCategory::CategoryPair()");

  MOZ_RELEASE_ASSERT(
      mozilla::MarkerCategory(aProfilingCategoryPair).CategoryPair() ==
          aProfilingCategoryPair,
      "MarkerCategory(<name>).CategoryPair() should return <name>");

  MOZ_RELEASE_ASSERT(aMarkerCategory.GetCategory() == aProfilingCategory,
                     "Unexpected MarkerCategory::GetCategory()");

  mozilla::ProfileBufferChunkManagerSingle chunkManager(512);
  mozilla::ProfileChunkedBuffer buffer(
      mozilla::ProfileChunkedBuffer::ThreadSafety::WithoutMutex, chunkManager);
  mozilla::ProfileBufferBlockIndex i = buffer.PutObject(aMarkerCategory);
  MOZ_RELEASE_ASSERT(i != mozilla::ProfileBufferBlockIndex{},
                     "Failed serialization");
  buffer.ReadEach([&](mozilla::ProfileBufferEntryReader& aER,
                      mozilla::ProfileBufferBlockIndex aIndex) {
    MOZ_RELEASE_ASSERT(aIndex == i, "Unexpected deserialization index");
    const auto readCategory = aER.ReadObject<mozilla::MarkerCategory>();
    MOZ_RELEASE_ASSERT(aER.RemainingBytes() == 0,
                       "Unexpected extra serialized bytes");
    MOZ_RELEASE_ASSERT(readCategory.CategoryPair() == aProfilingCategoryPair,
                       "Incorrect deserialization value");
  });
}

void TestMarkerCategory() {
  printf("TestMarkerCategory...\n");

  mozilla::ProfileBufferChunkManagerSingle chunkManager(512);
  mozilla::ProfileChunkedBuffer buffer(
      mozilla::ProfileChunkedBuffer::ThreadSafety::WithoutMutex, chunkManager);

#define CATEGORY_ENUM_BEGIN_CATEGORY(name, labelAsString, color)
#define CATEGORY_ENUM_SUBCATEGORY(supercategory, name, labelAsString)     \
  static_assert(                                                          \
      std::is_same_v<decltype(mozilla::baseprofiler::category::name),     \
                     const mozilla::MarkerCategory>,                      \
      "baseprofiler::category::<name> should be a const MarkerCategory"); \
                                                                          \
  SubTestMarkerCategory(                                                  \
      mozilla::baseprofiler::category::name,                              \
      mozilla::baseprofiler::ProfilingCategoryPair::name,                 \
      mozilla::baseprofiler::ProfilingCategory::supercategory);
#define CATEGORY_ENUM_END_CATEGORY
  MOZ_PROFILING_CATEGORY_LIST(CATEGORY_ENUM_BEGIN_CATEGORY,
                              CATEGORY_ENUM_SUBCATEGORY,
                              CATEGORY_ENUM_END_CATEGORY)
#undef CATEGORY_ENUM_BEGIN_CATEGORY
#undef CATEGORY_ENUM_SUBCATEGORY
#undef CATEGORY_ENUM_END_CATEGORY

  printf("TestMarkerCategory done\n");
}

void TestMarkerThreadId() {
  printf("TestMarkerThreadId...\n");

  MOZ_RELEASE_ASSERT(MarkerThreadId{}.IsUnspecified());
  MOZ_RELEASE_ASSERT(!MarkerThreadId::MainThread().IsUnspecified());
  MOZ_RELEASE_ASSERT(!MarkerThreadId::CurrentThread().IsUnspecified());

  MOZ_RELEASE_ASSERT(!MarkerThreadId{
      mozilla::baseprofiler::BaseProfilerThreadId::FromNumber(42)}
                          .IsUnspecified());
  MOZ_RELEASE_ASSERT(
      MarkerThreadId{
          mozilla::baseprofiler::BaseProfilerThreadId::FromNumber(42)}
          .ThreadId()
          .ToNumber() == 42);

  // We'll assume that this test runs in the main thread (which should be true
  // when called from the `main` function).
  MOZ_RELEASE_ASSERT(MarkerThreadId::MainThread().ThreadId() ==
                     mozilla::baseprofiler::profiler_main_thread_id());

  MOZ_RELEASE_ASSERT(MarkerThreadId::CurrentThread().ThreadId() ==
                     mozilla::baseprofiler::profiler_current_thread_id());

  MOZ_RELEASE_ASSERT(MarkerThreadId::CurrentThread().ThreadId() ==
                     mozilla::baseprofiler::profiler_main_thread_id());

  std::thread testThread([]() {
    MOZ_RELEASE_ASSERT(!MarkerThreadId::MainThread().IsUnspecified());
    MOZ_RELEASE_ASSERT(!MarkerThreadId::CurrentThread().IsUnspecified());

    MOZ_RELEASE_ASSERT(MarkerThreadId::MainThread().ThreadId() ==
                       mozilla::baseprofiler::profiler_main_thread_id());

    MOZ_RELEASE_ASSERT(MarkerThreadId::CurrentThread().ThreadId() ==
                       mozilla::baseprofiler::profiler_current_thread_id());

    MOZ_RELEASE_ASSERT(MarkerThreadId::CurrentThread().ThreadId() !=
                       mozilla::baseprofiler::profiler_main_thread_id());
  });
  testThread.join();

  printf("TestMarkerThreadId done\n");
}

void TestMarkerNoPayload() {
  printf("TestMarkerNoPayload...\n");

  mozilla::ProfileBufferChunkManagerSingle chunkManager(512);
  mozilla::ProfileChunkedBuffer buffer(
      mozilla::ProfileChunkedBuffer::ThreadSafety::WithoutMutex, chunkManager);

  mozilla::ProfileBufferBlockIndex i0 =
      mozilla::baseprofiler::AddMarkerToBuffer(
          buffer, "literal", mozilla::baseprofiler::category::OTHER_Profiling);
  MOZ_RELEASE_ASSERT(i0);

  const std::string dynamic = "dynamic";
  mozilla::ProfileBufferBlockIndex i1 =
      mozilla::baseprofiler::AddMarkerToBuffer(
          buffer, dynamic,
          mozilla::baseprofiler::category::GRAPHICS_FlushingAsyncPaints, {});
  MOZ_RELEASE_ASSERT(i1);
  MOZ_RELEASE_ASSERT(i1 > i0);

  mozilla::ProfileBufferBlockIndex i2 =
      mozilla::baseprofiler::AddMarkerToBuffer(
          buffer, std::string_view("string_view"),
          mozilla::baseprofiler::category::GRAPHICS_FlushingAsyncPaints, {});
  MOZ_RELEASE_ASSERT(i2);
  MOZ_RELEASE_ASSERT(i2 > i1);

#ifdef DEBUG
  buffer.Dump();
#endif

  PrintMarkers(buffer);

  printf("TestMarkerNoPayload done\n");
}

void TestUserMarker() {
  printf("TestUserMarker...\n");

  // User-defined marker type with text.
  // It's fine to define it right in the function where it's used.
  struct MarkerTypeTestMinimal {
    static constexpr Span<const char> MarkerTypeName() {
      return MakeStringSpan("test-minimal");
    }
    static void StreamJSONMarkerData(
        mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
        const std::string& aText) {
      aWriter.StringProperty("text", aText);
    }
    static mozilla::MarkerSchema MarkerTypeDisplay() {
      using MS = mozilla::MarkerSchema;
      MS schema{MS::Location::MarkerChart, MS::Location::MarkerTable};
      schema.SetTooltipLabel("tooltip for test-minimal");
      schema.AddKeyLabelFormat("text""Text", MS::Format::String);
      return schema;
    }
  };

  mozilla::ProfileBufferChunkManagerSingle chunkManager(1024);
  mozilla::ProfileChunkedBuffer buffer(
      mozilla::ProfileChunkedBuffer::ThreadSafety::WithoutMutex, chunkManager);

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, "test2", mozilla::baseprofiler::category::OTHER_Profiling, {},
      MarkerTypeTestMinimal{}, std::string("payload text")));

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, "test2", mozilla::baseprofiler::category::OTHER_Profiling,
      mozilla::MarkerThreadId(
          mozilla::baseprofiler::BaseProfilerThreadId::FromNumber(123)),
      MarkerTypeTestMinimal{}, std::string("ThreadId(123)")));

  auto start = mozilla::TimeStamp::Now();

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, "test2", mozilla::baseprofiler::category::OTHER_Profiling,
      mozilla::MarkerTiming::InstantAt(start), MarkerTypeTestMinimal{},
      std::string("InstantAt(start)")));

  auto then = mozilla::TimeStamp::Now();

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, "test2", mozilla::baseprofiler::category::OTHER_Profiling,
      mozilla::MarkerTiming::IntervalStart(start), MarkerTypeTestMinimal{},
      std::string("IntervalStart(start)")));

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, "test2", mozilla::baseprofiler::category::OTHER_Profiling,
      mozilla::MarkerTiming::IntervalEnd(then), MarkerTypeTestMinimal{},
      std::string("IntervalEnd(then)")));

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, "test2", mozilla::baseprofiler::category::OTHER_Profiling,
      mozilla::MarkerTiming::Interval(start, then), MarkerTypeTestMinimal{},
      std::string("Interval(start, then)")));

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, "test2", mozilla::baseprofiler::category::OTHER_Profiling,
      mozilla::MarkerTiming::IntervalUntilNowFrom(start),
      MarkerTypeTestMinimal{}, std::string("IntervalUntilNowFrom(start)")));

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, "test2", mozilla::baseprofiler::category::OTHER_Profiling,
      mozilla::MarkerStack::NoStack(), MarkerTypeTestMinimal{},
      std::string("NoStack")));
  // Note: We cannot test stack-capture here, because the profiler is not
  // initialized.

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, "test2", mozilla::baseprofiler::category::OTHER_Profiling,
      mozilla::MarkerInnerWindowId(123), MarkerTypeTestMinimal{},
      std::string("InnerWindowId(123)")));

#ifdef DEBUG
  buffer.Dump();
#endif

  PrintMarkers(buffer);

  printf("TestUserMarker done\n");
}

void TestPredefinedMarkers() {
  printf("TestPredefinedMarkers...\n");

  mozilla::ProfileBufferChunkManagerSingle chunkManager(1024);
  mozilla::ProfileChunkedBuffer buffer(
      mozilla::ProfileChunkedBuffer::ThreadSafety::WithoutMutex, chunkManager);

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, std::string_view("stackmarker"),
      mozilla::baseprofiler::category::OTHER, {},
      mozilla::baseprofiler::markers::StackMarker{}));

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, std::string_view("text"), mozilla::baseprofiler::category::OTHER,
      {}, mozilla::baseprofiler::markers::TextMarker{}, "text text"));

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, std::string_view("media"), mozilla::baseprofiler::category::OTHER,
      {}, mozilla::baseprofiler::markers::MediaSampleMarker{}, 123456789));

  MOZ_RELEASE_ASSERT(mozilla::baseprofiler::AddMarkerToBuffer(
      buffer, std::string_view("media"), mozilla::baseprofiler::category::OTHER,
      {}, mozilla::baseprofiler::markers::VideoFallingBehindMarker{}, 123,
      456));

#ifdef DEBUG
  buffer.Dump();
#endif

  PrintMarkers(buffer);

  printf("TestPredefinedMarkers done\n");
}

void TestProfilerMarkers() {
  printf(
      "TestProfilerMarkers -- pid: %" PRIu64 ", tid: %" PRIu64 "\n",
      uint64_t(mozilla::baseprofiler::profiler_current_process_id().ToNumber()),
      uint64_t(mozilla::baseprofiler::profiler_current_thread_id().ToNumber()));
  // ::SleepMilli(10000);

  TestUniqueJSONStrings();
  TestMarkerCategory();
  TestMarkerThreadId();
  TestMarkerNoPayload();
  TestUserMarker();
  TestPredefinedMarkers();

  printf("TestProfilerMarkers done\n");
}

#if defined(XP_WIN)
int wmain()
#else
int main()
#endif  // defined(XP_WIN)
{
  printf("BaseTestProfiler -- pid: %" PRIu64 ", tid: %" PRIu64 "\n",
         uint64_t(baseprofiler::profiler_current_process_id().ToNumber()),
         uint64_t(baseprofiler::profiler_current_thread_id().ToNumber()));
  // ::SleepMilli(10000);

  TestFailureLatch();
  TestProfilerUtils();
  TestBaseAndProfilerDetail();
  TestSharedMutex();
  TestProportionValue();
  TestProgressLogger();

  {
    printf("profiler_init()...\n");
    AUTO_BASE_PROFILER_INIT;

    TestProfiler();
    TestProfilerMarkers();
  }

  return 0;
}

Messung V0.5 in Prozent
C=89 H=93 G=90

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.184Bemerkung:  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Anfrage:

Dauer der Verarbeitung:

Sekunden

sprechenden Kalenders