зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1552063 - Use PowerOfTwo and PowerOfTwoMask in profilers - r=gregtatum
PowerOfTwo makes for a cleaner and more expressive interface, showing that the profiler will use a power-of-2 storage size. Using PowerOfTwoMask in ProfilerBuffer also makes it more obvious that we want cheap modulo operations. And we don't need to keep the original capacity, as it's only used once and can easily be recomputed from the mask. Differential Revision: https://phabricator.services.mozilla.com/D36027 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
bd540dabc4
Коммит
b13eeec2e9
|
@ -18,7 +18,7 @@ add_task(async function() {
|
|||
"The profiler is not active yet.");
|
||||
|
||||
front.once("profiler-started", (entries, interval, features, duration) => {
|
||||
is(entries, 1000, "Should apply entries by startProfiler");
|
||||
is(entries, 1024, "Should apply entries by startProfiler");
|
||||
is(interval, 0.1, "Should apply interval by startProfiler");
|
||||
is(features, 0x202, "Should apply features by startProfiler");
|
||||
is(duration, 2, "Should apply duration by startProfiler");
|
||||
|
|
|
@ -17,17 +17,11 @@
|
|||
namespace mozilla {
|
||||
namespace baseprofiler {
|
||||
|
||||
ProfileBuffer::ProfileBuffer(uint32_t aCapacity)
|
||||
: mEntryIndexMask(0), mRangeStart(0), mRangeEnd(0), mCapacity(0) {
|
||||
// Round aCapacity up to the nearest power of two, so that we can index
|
||||
// mEntries with a simple mask and don't need to do a slow modulo operation.
|
||||
const uint32_t UINT32_MAX_POWER_OF_TWO = 1 << 31;
|
||||
MOZ_RELEASE_ASSERT(aCapacity <= UINT32_MAX_POWER_OF_TWO,
|
||||
"aCapacity is larger than what we support");
|
||||
mCapacity = RoundUpPow2(aCapacity);
|
||||
mEntryIndexMask = mCapacity - 1;
|
||||
mEntries = MakeUnique<ProfileBufferEntry[]>(mCapacity);
|
||||
}
|
||||
ProfileBuffer::ProfileBuffer(PowerOfTwo32 aCapacity)
|
||||
: mEntries(MakeUnique<ProfileBufferEntry[]>(aCapacity.Value())),
|
||||
mEntryIndexMask(aCapacity.Mask()),
|
||||
mRangeStart(0),
|
||||
mRangeEnd(0) {}
|
||||
|
||||
ProfileBuffer::~ProfileBuffer() {
|
||||
while (mStoredMarkers.peek()) {
|
||||
|
@ -40,8 +34,8 @@ void ProfileBuffer::AddEntry(const ProfileBufferEntry& aEntry) {
|
|||
GetEntry(mRangeEnd++) = aEntry;
|
||||
|
||||
// The distance between mRangeStart and mRangeEnd must never exceed
|
||||
// mCapacity, so advance mRangeStart if necessary.
|
||||
if (mRangeEnd - mRangeStart > mCapacity) {
|
||||
// capacity, so advance mRangeStart if necessary.
|
||||
if (mRangeEnd - mRangeStart > mEntryIndexMask.MaskValue() + 1) {
|
||||
mRangeStart++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "ProfilerMarker.h"
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/PowerOfTwo.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace baseprofiler {
|
||||
|
@ -30,9 +31,8 @@ namespace baseprofiler {
|
|||
class ProfileBuffer final {
|
||||
public:
|
||||
// ProfileBuffer constructor
|
||||
// @param aCapacity The minimum capacity of the buffer. The actual buffer
|
||||
// capacity will be rounded up to the next power of two.
|
||||
explicit ProfileBuffer(uint32_t aCapacity);
|
||||
// @param aCapacity The capacity of the buffer.
|
||||
explicit ProfileBuffer(PowerOfTwo32 aCapacity);
|
||||
|
||||
~ProfileBuffer();
|
||||
|
||||
|
@ -98,25 +98,25 @@ class ProfileBuffer final {
|
|||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
private:
|
||||
// The storage that backs our buffer. Holds mCapacity entries.
|
||||
// The storage that backs our buffer. Holds capacity entries.
|
||||
// All accesses to entries in mEntries need to go through GetEntry(), which
|
||||
// translates the given buffer position from the near-infinite uint64_t space
|
||||
// into the entry storage space.
|
||||
UniquePtr<ProfileBufferEntry[]> mEntries;
|
||||
|
||||
// A mask such that pos & mEntryIndexMask == pos % mCapacity.
|
||||
uint32_t mEntryIndexMask;
|
||||
// A mask such that pos & mEntryIndexMask == pos % capacity.
|
||||
PowerOfTwoMask32 mEntryIndexMask;
|
||||
|
||||
public:
|
||||
// mRangeStart and mRangeEnd are uint64_t values that strictly advance and
|
||||
// never wrap around. mRangeEnd is always greater than or equal to
|
||||
// mRangeStart, but never gets more than mCapacity steps ahead of
|
||||
// mRangeStart, but never gets more than capacity steps ahead of
|
||||
// mRangeStart, because we can only store a fixed number of entries in the
|
||||
// buffer. Once the entire buffer is in use, adding a new entry will evict an
|
||||
// entry from the front of the buffer (and increase mRangeStart).
|
||||
// In other words, the following conditions hold true at all times:
|
||||
// (1) mRangeStart <= mRangeEnd
|
||||
// (2) mRangeEnd - mRangeStart <= mCapacity
|
||||
// (2) mRangeEnd - mRangeStart <= capacity
|
||||
//
|
||||
// If there are no live entries, then mRangeStart == mRangeEnd.
|
||||
// Otherwise, mRangeStart is the first live entry and mRangeEnd is one past
|
||||
|
@ -126,9 +126,6 @@ class ProfileBuffer final {
|
|||
uint64_t mRangeStart;
|
||||
uint64_t mRangeEnd;
|
||||
|
||||
// The number of entries in our buffer. Always a power of two.
|
||||
uint32_t mCapacity;
|
||||
|
||||
// Markers that marker entries in the buffer might refer to.
|
||||
ProfilerMarkerLinkedList mStoredMarkers;
|
||||
};
|
||||
|
|
|
@ -459,7 +459,7 @@ class ActivePS {
|
|||
return aFeatures;
|
||||
}
|
||||
|
||||
ActivePS(PSLockRef aLock, uint32_t aCapacity, double aInterval,
|
||||
ActivePS(PSLockRef aLock, PowerOfTwo32 aCapacity, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters, uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration)
|
||||
: mGeneration(sNextGeneration++),
|
||||
|
@ -522,7 +522,7 @@ class ActivePS {
|
|||
}
|
||||
|
||||
public:
|
||||
static void Create(PSLockRef aLock, uint32_t aCapacity, double aInterval,
|
||||
static void Create(PSLockRef aLock, PowerOfTwo32 aCapacity, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters,
|
||||
uint32_t aFilterCount, const Maybe<double>& aDuration) {
|
||||
sInstance = new ActivePS(aLock, aCapacity, aInterval, aFeatures, aFilters,
|
||||
|
@ -539,7 +539,7 @@ class ActivePS {
|
|||
|
||||
static bool Exists(PSLockRef) { return !!sInstance; }
|
||||
|
||||
static bool Equals(PSLockRef, uint32_t aCapacity,
|
||||
static bool Equals(PSLockRef, PowerOfTwo32 aCapacity,
|
||||
const Maybe<double>& aDuration, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters,
|
||||
uint32_t aFilterCount) {
|
||||
|
@ -582,7 +582,7 @@ class ActivePS {
|
|||
|
||||
PS_GET(uint32_t, Generation)
|
||||
|
||||
PS_GET(uint32_t, Capacity)
|
||||
PS_GET(PowerOfTwo32, Capacity)
|
||||
|
||||
PS_GET(Maybe<double>, Duration)
|
||||
|
||||
|
@ -805,7 +805,7 @@ class ActivePS {
|
|||
static uint32_t sNextGeneration;
|
||||
|
||||
// The maximum number of entries in mBuffer.
|
||||
const uint32_t mCapacity;
|
||||
const PowerOfTwo32 mCapacity;
|
||||
|
||||
// The maximum duration of entries in mBuffer, in seconds.
|
||||
const Maybe<double> mDuration;
|
||||
|
@ -1743,11 +1743,12 @@ static void PrintUsageThenExit(int aExitCode) {
|
|||
" Features: (x=unavailable, D/d=default/unavailable,\n"
|
||||
" S/s=MOZ_BASE_PROFILER_STARTUP extra "
|
||||
"default/unavailable)\n",
|
||||
unsigned(BASE_PROFILER_DEFAULT_ENTRIES),
|
||||
unsigned(BASE_PROFILER_DEFAULT_STARTUP_ENTRIES),
|
||||
unsigned(BASE_PROFILER_DEFAULT_ENTRIES.Value()),
|
||||
unsigned(BASE_PROFILER_DEFAULT_STARTUP_ENTRIES.Value()),
|
||||
sizeof(ProfileBufferEntry),
|
||||
sizeof(ProfileBufferEntry) * BASE_PROFILER_DEFAULT_ENTRIES,
|
||||
sizeof(ProfileBufferEntry) * BASE_PROFILER_DEFAULT_STARTUP_ENTRIES);
|
||||
sizeof(ProfileBufferEntry) * BASE_PROFILER_DEFAULT_ENTRIES.Value(),
|
||||
sizeof(ProfileBufferEntry) *
|
||||
BASE_PROFILER_DEFAULT_STARTUP_ENTRIES.Value());
|
||||
|
||||
# define PRINT_FEATURE(n_, str_, Name_, desc_) \
|
||||
printf(" %c %5u: \"%s\" (%s)\n", \
|
||||
|
@ -2155,7 +2156,7 @@ static ProfilingStack* locked_register_thread(PSLockRef aLock,
|
|||
return profilingStack;
|
||||
}
|
||||
|
||||
static void locked_profiler_start(PSLockRef aLock, uint32_t aCapacity,
|
||||
static void locked_profiler_start(PSLockRef aLock, PowerOfTwo32 aCapacity,
|
||||
double aInterval, uint32_t aFeatures,
|
||||
const char** aFilters, uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration);
|
||||
|
@ -2202,7 +2203,7 @@ void profiler_init(void* aStackTop) {
|
|||
Vector<const char*> filters;
|
||||
MOZ_RELEASE_ASSERT(filters.append(kMainThreadName));
|
||||
|
||||
uint32_t capacity = BASE_PROFILER_DEFAULT_ENTRIES;
|
||||
PowerOfTwo32 capacity = BASE_PROFILER_DEFAULT_ENTRIES;
|
||||
Maybe<double> duration = Nothing();
|
||||
double interval = BASE_PROFILER_DEFAULT_INTERVAL;
|
||||
|
||||
|
@ -2239,12 +2240,14 @@ void profiler_init(void* aStackTop) {
|
|||
errno = 0;
|
||||
long capacityLong = strtol(startupCapacity, nullptr, 10);
|
||||
// `long` could be 32 or 64 bits, so we force a 64-bit comparison with
|
||||
// the maximum 32-bit unsigned number.
|
||||
// the maximum 32-bit signed number (as more than that is clamped down to
|
||||
// 2^31 anyway).
|
||||
if (errno == 0 && capacityLong > 0 &&
|
||||
static_cast<uint64_t>(capacityLong) <=
|
||||
static_cast<uint64_t>(UINT32_MAX)) {
|
||||
capacity = static_cast<uint32_t>(capacityLong);
|
||||
LOG("- MOZ_BASE_PROFILER_STARTUP_ENTRIES = %u", unsigned(capacity));
|
||||
static_cast<uint64_t>(INT32_MAX)) {
|
||||
capacity = PowerOfTwo32(static_cast<uint32_t>(capacityLong));
|
||||
LOG("- MOZ_BASE_PROFILER_STARTUP_ENTRIES = %u",
|
||||
unsigned(capacity.Value()));
|
||||
} else {
|
||||
LOG("- MOZ_BASE_PROFILER_STARTUP_ENTRIES not a valid integer: %s",
|
||||
startupCapacity);
|
||||
|
@ -2465,7 +2468,7 @@ void profiler_get_start_params(int* aCapacity, Maybe<double>* aDuration,
|
|||
return;
|
||||
}
|
||||
|
||||
*aCapacity = ActivePS::Capacity(lock);
|
||||
*aCapacity = ActivePS::Capacity(lock).Value();
|
||||
*aDuration = ActivePS::Duration(lock);
|
||||
*aInterval = ActivePS::Interval(lock);
|
||||
*aFeatures = ActivePS::Features(lock);
|
||||
|
@ -2489,7 +2492,8 @@ void GetProfilerEnvVarsForChildProcess(
|
|||
}
|
||||
|
||||
aSetEnv("MOZ_BASE_PROFILER_STARTUP", "1");
|
||||
auto capacityString = Smprintf("%d", ActivePS::Capacity(lock));
|
||||
auto capacityString =
|
||||
Smprintf("%u", unsigned(ActivePS::Capacity(lock).Value()));
|
||||
aSetEnv("MOZ_BASE_PROFILER_STARTUP_ENTRIES", capacityString.get());
|
||||
|
||||
// Use AppendFloat instead of Smprintf with %f because the decimal
|
||||
|
@ -2593,16 +2597,16 @@ Maybe<ProfilerBufferInfo> profiler_get_buffer_info() {
|
|||
|
||||
return Some(ProfilerBufferInfo{ActivePS::Buffer(lock).mRangeStart,
|
||||
ActivePS::Buffer(lock).mRangeEnd,
|
||||
ActivePS::Capacity(lock)});
|
||||
ActivePS::Capacity(lock).Value()});
|
||||
}
|
||||
|
||||
static void locked_profiler_start(PSLockRef aLock, uint32_t aCapacity,
|
||||
static void locked_profiler_start(PSLockRef aLock, PowerOfTwo32 aCapacity,
|
||||
double aInterval, uint32_t aFeatures,
|
||||
const char** aFilters, uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration) {
|
||||
if (LOG_TEST) {
|
||||
LOG("locked_profiler_start");
|
||||
LOG("- capacity = %d", aCapacity);
|
||||
LOG("- capacity = %d", int(aCapacity.Value()));
|
||||
LOG("- duration = %.2f", aDuration ? *aDuration : -1);
|
||||
LOG("- interval = %.2f", aInterval);
|
||||
|
||||
|
@ -2627,7 +2631,10 @@ static void locked_profiler_start(PSLockRef aLock, uint32_t aCapacity,
|
|||
# endif
|
||||
|
||||
// Fall back to the default values if the passed-in values are unreasonable.
|
||||
uint32_t capacity = aCapacity > 0 ? aCapacity : BASE_PROFILER_DEFAULT_ENTRIES;
|
||||
// Less than 1024 would not be enough for the most complex stack, so we should
|
||||
// be able to store at least one full stack. TODO: Review magic numbers.
|
||||
PowerOfTwo32 capacity =
|
||||
(aCapacity.Value() >= 1024u) ? aCapacity : BASE_PROFILER_DEFAULT_ENTRIES;
|
||||
Maybe<double> duration = aDuration;
|
||||
|
||||
if (aDuration && *aDuration <= 0) {
|
||||
|
@ -2656,9 +2663,9 @@ static void locked_profiler_start(PSLockRef aLock, uint32_t aCapacity,
|
|||
RacyFeatures::SetActive(ActivePS::Features(aLock));
|
||||
}
|
||||
|
||||
void profiler_start(uint32_t aCapacity, double aInterval, uint32_t aFeatures,
|
||||
const char** aFilters, uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration) {
|
||||
void profiler_start(PowerOfTwo32 aCapacity, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters,
|
||||
uint32_t aFilterCount, const Maybe<double>& aDuration) {
|
||||
LOG("profiler_start");
|
||||
|
||||
SamplerThread* samplerThread = nullptr;
|
||||
|
@ -2696,7 +2703,7 @@ void profiler_start(uint32_t aCapacity, double aInterval, uint32_t aFeatures,
|
|||
}
|
||||
}
|
||||
|
||||
void profiler_ensure_started(uint32_t aCapacity, double aInterval,
|
||||
void profiler_ensure_started(PowerOfTwo32 aCapacity, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters,
|
||||
uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration) {
|
||||
|
@ -3076,8 +3083,8 @@ UniqueProfilerBacktrace profiler_get_backtrace() {
|
|||
regs.Clear();
|
||||
# endif
|
||||
|
||||
// 1000 should be plenty for a single backtrace.
|
||||
auto buffer = MakeUnique<ProfileBuffer>(1000);
|
||||
// 1024 should be plenty for a single backtrace.
|
||||
auto buffer = MakeUnique<ProfileBuffer>(MakePowerOfTwo32<1024>());
|
||||
|
||||
DoSyncSample(lock, *registeredThread, now, regs, *buffer.get());
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
# include "mozilla/Attributes.h"
|
||||
# include "mozilla/GuardObjects.h"
|
||||
# include "mozilla/Maybe.h"
|
||||
# include "mozilla/PowerOfTwo.h"
|
||||
# include "mozilla/Sprintf.h"
|
||||
# include "mozilla/ThreadLocal.h"
|
||||
# include "mozilla/TimeStamp.h"
|
||||
|
@ -229,20 +230,20 @@ MFBT_API bool IsThreadBeingProfiled();
|
|||
// Start and stop the profiler
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static constexpr uint32_t BASE_PROFILER_DEFAULT_ENTRIES =
|
||||
static constexpr PowerOfTwo32 BASE_PROFILER_DEFAULT_ENTRIES =
|
||||
# if !defined(ARCH_ARMV6)
|
||||
1u << 20; // 1'048'576
|
||||
MakePowerOfTwo32<1u << 20>(); // 1'048'576
|
||||
# else
|
||||
1u << 17; // 131'072
|
||||
MakePowerOfTwo32<1u << 17>(); // 131'072
|
||||
# endif
|
||||
|
||||
// Startup profiling usually need to capture more data, especially on slow
|
||||
// systems.
|
||||
static constexpr uint32_t BASE_PROFILER_DEFAULT_STARTUP_ENTRIES =
|
||||
static constexpr PowerOfTwo32 BASE_PROFILER_DEFAULT_STARTUP_ENTRIES =
|
||||
# if !defined(ARCH_ARMV6)
|
||||
1u << 22; // 4'194'304
|
||||
MakePowerOfTwo32<1u << 22>(); // 4'194'304
|
||||
# else
|
||||
1u << 17; // 131'072
|
||||
MakePowerOfTwo32<1u << 17>(); // 131'072
|
||||
# endif
|
||||
|
||||
# define BASE_PROFILER_DEFAULT_DURATION 20
|
||||
|
@ -278,7 +279,7 @@ MFBT_API void profiler_shutdown();
|
|||
// (b) the filter is of the form "pid:<n>" where n is the process
|
||||
// id of the process that the thread is running in.
|
||||
// "aDuration" is the duration of entries in the profiler's circular buffer.
|
||||
MFBT_API void profiler_start(uint32_t aCapacity, double aInterval,
|
||||
MFBT_API void profiler_start(PowerOfTwo32 aCapacity, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters,
|
||||
uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration = Nothing());
|
||||
|
@ -293,7 +294,7 @@ MFBT_API void profiler_stop();
|
|||
// The only difference to profiler_start is that the current buffer contents are
|
||||
// not discarded if the profiler is already running with the requested settings.
|
||||
MFBT_API void profiler_ensure_started(
|
||||
uint32_t aCapacity, double aInterval, uint32_t aFeatures,
|
||||
PowerOfTwo32 aCapacity, double aInterval, uint32_t aFeatures,
|
||||
const char** aFilters, uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration = Nothing());
|
||||
|
||||
|
@ -714,8 +715,8 @@ class MOZ_RAII AutoProfilerTextMarker {
|
|||
|
||||
~AutoProfilerTextMarker() {
|
||||
profiler_add_text_marker(mMarkerName, mText, mCategoryPair, mStartTime,
|
||||
TimeStamp::NowUnfuzzed(), mDocShellId, mDocShellHistoryId,
|
||||
std::move(mCause));
|
||||
TimeStamp::NowUnfuzzed(), mDocShellId,
|
||||
mDocShellHistoryId, std::move(mCause));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -15,17 +15,11 @@
|
|||
|
||||
using namespace mozilla;
|
||||
|
||||
ProfileBuffer::ProfileBuffer(uint32_t aCapacity)
|
||||
: mEntryIndexMask(0), mRangeStart(0), mRangeEnd(0), mCapacity(0) {
|
||||
// Round aCapacity up to the nearest power of two, so that we can index
|
||||
// mEntries with a simple mask and don't need to do a slow modulo operation.
|
||||
const uint32_t UINT32_MAX_POWER_OF_TWO = 1 << 31;
|
||||
MOZ_RELEASE_ASSERT(aCapacity <= UINT32_MAX_POWER_OF_TWO,
|
||||
"aCapacity is larger than what we support");
|
||||
mCapacity = RoundUpPow2(aCapacity);
|
||||
mEntryIndexMask = mCapacity - 1;
|
||||
mEntries = MakeUnique<ProfileBufferEntry[]>(mCapacity);
|
||||
}
|
||||
ProfileBuffer::ProfileBuffer(PowerOfTwo32 aCapacity)
|
||||
: mEntries(MakeUnique<ProfileBufferEntry[]>(aCapacity.Value())),
|
||||
mEntryIndexMask(aCapacity.Mask()),
|
||||
mRangeStart(0),
|
||||
mRangeEnd(0) {}
|
||||
|
||||
ProfileBuffer::~ProfileBuffer() {
|
||||
while (mStoredMarkers.peek()) {
|
||||
|
@ -38,8 +32,8 @@ void ProfileBuffer::AddEntry(const ProfileBufferEntry& aEntry) {
|
|||
GetEntry(mRangeEnd++) = aEntry;
|
||||
|
||||
// The distance between mRangeStart and mRangeEnd must never exceed
|
||||
// mCapacity, so advance mRangeStart if necessary.
|
||||
if (mRangeEnd - mRangeStart > mCapacity) {
|
||||
// capacity, so advance mRangeStart if necessary.
|
||||
if (mRangeEnd - mRangeStart > mEntryIndexMask.MaskValue() + 1) {
|
||||
mRangeStart++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "ProfilerMarker.h"
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/PowerOfTwo.h"
|
||||
|
||||
// A fixed-capacity circular buffer.
|
||||
// This class is used as a queue of entries which, after construction, never
|
||||
|
@ -27,9 +28,8 @@
|
|||
class ProfileBuffer final {
|
||||
public:
|
||||
// ProfileBuffer constructor
|
||||
// @param aCapacity The minimum capacity of the buffer. The actual buffer
|
||||
// capacity will be rounded up to the next power of two.
|
||||
explicit ProfileBuffer(uint32_t aCapacity);
|
||||
// @param aCapacity The capacity of the buffer.
|
||||
explicit ProfileBuffer(mozilla::PowerOfTwo32 aCapacity);
|
||||
|
||||
~ProfileBuffer();
|
||||
|
||||
|
@ -107,25 +107,25 @@ class ProfileBuffer final {
|
|||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
private:
|
||||
// The storage that backs our buffer. Holds mCapacity entries.
|
||||
// The storage that backs our buffer. Holds capacity entries.
|
||||
// All accesses to entries in mEntries need to go through GetEntry(), which
|
||||
// translates the given buffer position from the near-infinite uint64_t space
|
||||
// into the entry storage space.
|
||||
mozilla::UniquePtr<ProfileBufferEntry[]> mEntries;
|
||||
|
||||
// A mask such that pos & mEntryIndexMask == pos % mCapacity.
|
||||
uint32_t mEntryIndexMask;
|
||||
// A mask such that pos & mEntryIndexMask == pos % capacity.
|
||||
mozilla::PowerOfTwoMask32 mEntryIndexMask;
|
||||
|
||||
public:
|
||||
// mRangeStart and mRangeEnd are uint64_t values that strictly advance and
|
||||
// never wrap around. mRangeEnd is always greater than or equal to
|
||||
// mRangeStart, but never gets more than mCapacity steps ahead of
|
||||
// mRangeStart, but never gets more than capacity steps ahead of
|
||||
// mRangeStart, because we can only store a fixed number of entries in the
|
||||
// buffer. Once the entire buffer is in use, adding a new entry will evict an
|
||||
// entry from the front of the buffer (and increase mRangeStart).
|
||||
// In other words, the following conditions hold true at all times:
|
||||
// (1) mRangeStart <= mRangeEnd
|
||||
// (2) mRangeEnd - mRangeStart <= mCapacity
|
||||
// (2) mRangeEnd - mRangeStart <= capacity
|
||||
//
|
||||
// If there are no live entries, then mRangeStart == mRangeEnd.
|
||||
// Otherwise, mRangeStart is the first live entry and mRangeEnd is one past
|
||||
|
@ -135,9 +135,6 @@ class ProfileBuffer final {
|
|||
uint64_t mRangeStart;
|
||||
uint64_t mRangeEnd;
|
||||
|
||||
// The number of entries in our buffer. Always a power of two.
|
||||
uint32_t mCapacity;
|
||||
|
||||
// Markers that marker entries in the buffer might refer to.
|
||||
ProfilerMarkerLinkedList mStoredMarkers;
|
||||
};
|
||||
|
|
|
@ -472,7 +472,7 @@ class ActivePS {
|
|||
return aFeatures;
|
||||
}
|
||||
|
||||
ActivePS(PSLockRef aLock, uint32_t aCapacity, double aInterval,
|
||||
ActivePS(PSLockRef aLock, PowerOfTwo32 aCapacity, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters, uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration)
|
||||
: mGeneration(sNextGeneration++),
|
||||
|
@ -575,7 +575,7 @@ class ActivePS {
|
|||
}
|
||||
|
||||
public:
|
||||
static void Create(PSLockRef aLock, uint32_t aCapacity, double aInterval,
|
||||
static void Create(PSLockRef aLock, PowerOfTwo32 aCapacity, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters,
|
||||
uint32_t aFilterCount, const Maybe<double>& aDuration) {
|
||||
sInstance = new ActivePS(aLock, aCapacity, aInterval, aFeatures, aFilters,
|
||||
|
@ -592,7 +592,7 @@ class ActivePS {
|
|||
|
||||
static bool Exists(PSLockRef) { return !!sInstance; }
|
||||
|
||||
static bool Equals(PSLockRef, uint32_t aCapacity,
|
||||
static bool Equals(PSLockRef, PowerOfTwo32 aCapacity,
|
||||
const Maybe<double>& aDuration, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters,
|
||||
uint32_t aFilterCount) {
|
||||
|
@ -635,7 +635,7 @@ class ActivePS {
|
|||
|
||||
PS_GET(uint32_t, Generation)
|
||||
|
||||
PS_GET(uint32_t, Capacity)
|
||||
PS_GET(PowerOfTwo32, Capacity)
|
||||
|
||||
PS_GET(Maybe<double>, Duration)
|
||||
|
||||
|
@ -918,7 +918,7 @@ class ActivePS {
|
|||
static uint32_t sNextGeneration;
|
||||
|
||||
// The maximum number of entries in mBuffer.
|
||||
const uint32_t mCapacity;
|
||||
const PowerOfTwo32 mCapacity;
|
||||
|
||||
// The maximum duration of entries in mBuffer, in seconds.
|
||||
const Maybe<double> mDuration;
|
||||
|
@ -2025,7 +2025,7 @@ static UniquePtr<ProfileBuffer> CollectJavaThreadProfileData() {
|
|||
// locked_profiler_start uses sample count is 1000 for Java thread.
|
||||
// This entry size is enough now, but we might have to estimate it
|
||||
// if we can customize it
|
||||
auto buffer = MakeUnique<ProfileBuffer>(1000 * 1000);
|
||||
auto buffer = MakeUnique<ProfileBuffer>(MakePowerOfTwo32<1024 * 1024>());
|
||||
|
||||
int sampleId = 0;
|
||||
while (true) {
|
||||
|
@ -2288,10 +2288,11 @@ static void PrintUsageThenExit(int aExitCode) {
|
|||
"\n"
|
||||
" Features: (x=unavailable, D/d=default/unavailable,\n"
|
||||
" S/s=MOZ_PROFILER_STARTUP extra default/unavailable)\n",
|
||||
unsigned(PROFILER_DEFAULT_ENTRIES),
|
||||
unsigned(PROFILER_DEFAULT_STARTUP_ENTRIES), sizeof(ProfileBufferEntry),
|
||||
sizeof(ProfileBufferEntry) * PROFILER_DEFAULT_ENTRIES,
|
||||
sizeof(ProfileBufferEntry) * PROFILER_DEFAULT_STARTUP_ENTRIES);
|
||||
unsigned(PROFILER_DEFAULT_ENTRIES.Value()),
|
||||
unsigned(PROFILER_DEFAULT_STARTUP_ENTRIES.Value()),
|
||||
sizeof(ProfileBufferEntry),
|
||||
sizeof(ProfileBufferEntry) * PROFILER_DEFAULT_ENTRIES.Value(),
|
||||
sizeof(ProfileBufferEntry) * PROFILER_DEFAULT_STARTUP_ENTRIES.Value());
|
||||
|
||||
#define PRINT_FEATURE(n_, str_, Name_, desc_) \
|
||||
printf(" %c %5u: \"%s\" (%s)\n", FeatureCategory(ProfilerFeature::Name_), \
|
||||
|
@ -2790,7 +2791,7 @@ static void NotifyObservers(const char* aTopic,
|
|||
}
|
||||
}
|
||||
|
||||
static void NotifyProfilerStarted(const int aCapacity,
|
||||
static void NotifyProfilerStarted(const PowerOfTwo32& aCapacity,
|
||||
const Maybe<double>& aDuration,
|
||||
double aInterval, uint32_t aFeatures,
|
||||
const char** aFilters,
|
||||
|
@ -2800,14 +2801,15 @@ static void NotifyProfilerStarted(const int aCapacity,
|
|||
filtersArray.AppendElement(aFilters[i]);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIProfilerStartParams> params = new nsProfilerStartParams(
|
||||
aCapacity, aDuration, aInterval, aFeatures, std::move(filtersArray));
|
||||
nsCOMPtr<nsIProfilerStartParams> params =
|
||||
new nsProfilerStartParams(aCapacity.Value(), aDuration, aInterval,
|
||||
aFeatures, std::move(filtersArray));
|
||||
|
||||
ProfilerParent::ProfilerStarted(params);
|
||||
NotifyObservers("profiler-started", params);
|
||||
}
|
||||
|
||||
static void locked_profiler_start(PSLockRef aLock, uint32_t aCapacity,
|
||||
static void locked_profiler_start(PSLockRef aLock, PowerOfTwo32 aCapacity,
|
||||
double aInterval, uint32_t aFeatures,
|
||||
const char** aFilters, uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration);
|
||||
|
@ -2874,7 +2876,7 @@ void profiler_init(void* aStackTop) {
|
|||
MOZ_RELEASE_ASSERT(filters.append("Compositor"));
|
||||
MOZ_RELEASE_ASSERT(filters.append("DOM Worker"));
|
||||
|
||||
uint32_t capacity = PROFILER_DEFAULT_ENTRIES;
|
||||
PowerOfTwo32 capacity = PROFILER_DEFAULT_ENTRIES;
|
||||
Maybe<double> duration = Nothing();
|
||||
double interval = PROFILER_DEFAULT_INTERVAL;
|
||||
|
||||
|
@ -2924,12 +2926,13 @@ void profiler_init(void* aStackTop) {
|
|||
errno = 0;
|
||||
long capacityLong = strtol(startupCapacity, nullptr, 10);
|
||||
// `long` could be 32 or 64 bits, so we force a 64-bit comparison with
|
||||
// the maximum 32-bit unsigned number.
|
||||
// the maximum 32-bit signed number (as more than that is clamped down to
|
||||
// 2^31 anyway).
|
||||
if (errno == 0 && capacityLong > 0 &&
|
||||
static_cast<uint64_t>(capacityLong) <=
|
||||
static_cast<uint64_t>(UINT32_MAX)) {
|
||||
capacity = static_cast<uint32_t>(capacityLong);
|
||||
LOG("- MOZ_PROFILER_STARTUP_ENTRIES = %u", unsigned(capacity));
|
||||
static_cast<uint64_t>(INT32_MAX)) {
|
||||
capacity = PowerOfTwo32(static_cast<uint32_t>(capacityLong));
|
||||
LOG("- MOZ_PROFILER_STARTUP_ENTRIES = %u", unsigned(capacity.Value()));
|
||||
} else {
|
||||
LOG("- MOZ_PROFILER_STARTUP_ENTRIES not a valid integer: %s",
|
||||
startupCapacity);
|
||||
|
@ -3149,7 +3152,7 @@ void profiler_get_start_params(int* aCapacity, Maybe<double>* aDuration,
|
|||
return;
|
||||
}
|
||||
|
||||
*aCapacity = ActivePS::Capacity(lock);
|
||||
*aCapacity = ActivePS::Capacity(lock).Value();
|
||||
*aDuration = ActivePS::Duration(lock);
|
||||
*aInterval = ActivePS::Interval(lock);
|
||||
*aFeatures = ActivePS::Features(lock);
|
||||
|
@ -3175,7 +3178,8 @@ void GetProfilerEnvVarsForChildProcess(
|
|||
}
|
||||
|
||||
aSetEnv("MOZ_PROFILER_STARTUP", "1");
|
||||
auto capacityString = Smprintf("%d", ActivePS::Capacity(lock));
|
||||
auto capacityString =
|
||||
Smprintf("%u", unsigned(ActivePS::Capacity(lock).Value()));
|
||||
aSetEnv("MOZ_PROFILER_STARTUP_ENTRIES", capacityString.get());
|
||||
|
||||
// Use AppendFloat instead of Smprintf with %f because the decimal
|
||||
|
@ -3300,7 +3304,7 @@ Maybe<ProfilerBufferInfo> profiler_get_buffer_info() {
|
|||
|
||||
return Some(ProfilerBufferInfo{ActivePS::Buffer(lock).mRangeStart,
|
||||
ActivePS::Buffer(lock).mRangeEnd,
|
||||
ActivePS::Capacity(lock)});
|
||||
ActivePS::Capacity(lock).Value()});
|
||||
}
|
||||
|
||||
static void PollJSSamplingForCurrentThread() {
|
||||
|
@ -3339,13 +3343,13 @@ static void TriggerPollJSSamplingOnMainThread() {
|
|||
}
|
||||
}
|
||||
|
||||
static void locked_profiler_start(PSLockRef aLock, uint32_t aCapacity,
|
||||
static void locked_profiler_start(PSLockRef aLock, PowerOfTwo32 aCapacity,
|
||||
double aInterval, uint32_t aFeatures,
|
||||
const char** aFilters, uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration) {
|
||||
if (LOG_TEST) {
|
||||
LOG("locked_profiler_start");
|
||||
LOG("- capacity = %d", aCapacity);
|
||||
LOG("- capacity = %u", unsigned(aCapacity.Value()));
|
||||
LOG("- duration = %.2f", aDuration ? *aDuration : -1);
|
||||
LOG("- interval = %.2f", aInterval);
|
||||
|
||||
|
@ -3370,7 +3374,10 @@ static void locked_profiler_start(PSLockRef aLock, uint32_t aCapacity,
|
|||
#endif
|
||||
|
||||
// Fall back to the default values if the passed-in values are unreasonable.
|
||||
uint32_t capacity = aCapacity > 0 ? aCapacity : PROFILER_DEFAULT_ENTRIES;
|
||||
// Less than 1024 would not be enough for the most complex stack, so we should
|
||||
// be able to store at least one full stack. TODO: Review magic numbers.
|
||||
PowerOfTwo32 capacity =
|
||||
(aCapacity.Value() >= 1024) ? aCapacity : PROFILER_DEFAULT_ENTRIES;
|
||||
Maybe<double> duration = aDuration;
|
||||
|
||||
if (aDuration && *aDuration <= 0) {
|
||||
|
@ -3466,9 +3473,9 @@ static void locked_profiler_start(PSLockRef aLock, uint32_t aCapacity,
|
|||
RacyFeatures::SetActive(ActivePS::Features(aLock));
|
||||
}
|
||||
|
||||
void profiler_start(uint32_t aCapacity, double aInterval, uint32_t aFeatures,
|
||||
const char** aFilters, uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration) {
|
||||
void profiler_start(PowerOfTwo32 aCapacity, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters,
|
||||
uint32_t aFilterCount, const Maybe<double>& aDuration) {
|
||||
LOG("profiler_start");
|
||||
|
||||
SamplerThread* samplerThread = nullptr;
|
||||
|
@ -3508,7 +3515,7 @@ void profiler_start(uint32_t aCapacity, double aInterval, uint32_t aFeatures,
|
|||
aFilterCount);
|
||||
}
|
||||
|
||||
void profiler_ensure_started(uint32_t aCapacity, double aInterval,
|
||||
void profiler_ensure_started(PowerOfTwo32 aCapacity, double aInterval,
|
||||
uint32_t aFeatures, const char** aFilters,
|
||||
uint32_t aFilterCount,
|
||||
const Maybe<double>& aDuration) {
|
||||
|
@ -3952,8 +3959,8 @@ UniqueProfilerBacktrace profiler_get_backtrace() {
|
|||
regs.Clear();
|
||||
#endif
|
||||
|
||||
// 1000 should be plenty for a single backtrace.
|
||||
auto buffer = MakeUnique<ProfileBuffer>(1000);
|
||||
// 1024 should be plenty for a single backtrace.
|
||||
auto buffer = MakeUnique<ProfileBuffer>(MakePowerOfTwo32<1024>());
|
||||
|
||||
DoSyncSample(lock, *registeredThread, now, regs, *buffer.get());
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@ mozilla::ipc::IPCResult ProfilerChild::RecvStart(
|
|||
filterArray.AppendElement(params.filters()[i].get());
|
||||
}
|
||||
|
||||
profiler_start(params.entries(), params.interval(), params.features(),
|
||||
filterArray.Elements(), filterArray.Length(),
|
||||
params.duration());
|
||||
profiler_start(PowerOfTwo32(params.entries()), params.interval(),
|
||||
params.features(), filterArray.Elements(),
|
||||
filterArray.Length(), params.duration());
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ mozilla::ipc::IPCResult ProfilerChild::RecvEnsureStarted(
|
|||
filterArray.AppendElement(params.filters()[i].get());
|
||||
}
|
||||
|
||||
profiler_ensure_started(params.entries(), params.interval(),
|
||||
profiler_ensure_started(PowerOfTwo32(params.entries()), params.interval(),
|
||||
params.features(), filterArray.Elements(),
|
||||
filterArray.Length(), params.duration());
|
||||
|
||||
|
|
|
@ -141,8 +141,9 @@ nsProfiler::StartProfiler(uint32_t aEntries, double aInterval,
|
|||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
profiler_start(aEntries, aInterval, features, filterStringVector.begin(),
|
||||
filterStringVector.length(), duration);
|
||||
profiler_start(PowerOfTwo32(aEntries), aInterval, features,
|
||||
filterStringVector.begin(), filterStringVector.length(),
|
||||
duration);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
# include "mozilla/Attributes.h"
|
||||
# include "mozilla/GuardObjects.h"
|
||||
# include "mozilla/Maybe.h"
|
||||
# include "mozilla/PowerOfTwo.h"
|
||||
# include "mozilla/Sprintf.h"
|
||||
# include "mozilla/ThreadLocal.h"
|
||||
# include "mozilla/TimeStamp.h"
|
||||
|
@ -237,20 +238,20 @@ bool IsThreadBeingProfiled();
|
|||
// Start and stop the profiler
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static constexpr uint32_t PROFILER_DEFAULT_ENTRIES =
|
||||
static constexpr mozilla::PowerOfTwo32 PROFILER_DEFAULT_ENTRIES =
|
||||
# if !defined(ARCH_ARMV6)
|
||||
1u << 20; // 1'048'576
|
||||
mozilla::MakePowerOfTwo32<1u << 20>(); // 1'048'576
|
||||
# else
|
||||
1u << 17; // 131'072
|
||||
mozilla::MakePowerOfTwo32<1u << 17>(); // 131'072
|
||||
# endif
|
||||
|
||||
// Startup profiling usually need to capture more data, especially on slow
|
||||
// systems.
|
||||
static constexpr uint32_t PROFILER_DEFAULT_STARTUP_ENTRIES =
|
||||
static constexpr mozilla::PowerOfTwo32 PROFILER_DEFAULT_STARTUP_ENTRIES =
|
||||
# if !defined(ARCH_ARMV6)
|
||||
1u << 22; // 4'194'304
|
||||
mozilla::MakePowerOfTwo32<1u << 22>(); // 4'194'304
|
||||
# else
|
||||
1u << 17; // 131'072
|
||||
mozilla::MakePowerOfTwo32<1u << 17>(); // 131'072
|
||||
# endif
|
||||
|
||||
# define PROFILER_DEFAULT_DURATION 20
|
||||
|
@ -286,7 +287,7 @@ void profiler_shutdown();
|
|||
// id of the process that the thread is running in.
|
||||
// "aDuration" is the duration of entries in the profiler's circular buffer.
|
||||
void profiler_start(
|
||||
uint32_t aCapacity, double aInterval, uint32_t aFeatures,
|
||||
mozilla::PowerOfTwo32 aCapacity, double aInterval, uint32_t aFeatures,
|
||||
const char** aFilters, uint32_t aFilterCount,
|
||||
const mozilla::Maybe<double>& aDuration = mozilla::Nothing());
|
||||
|
||||
|
@ -300,7 +301,7 @@ void profiler_stop();
|
|||
// The only difference to profiler_start is that the current buffer contents are
|
||||
// not discarded if the profiler is already running with the requested settings.
|
||||
void profiler_ensure_started(
|
||||
uint32_t aCapacity, double aInterval, uint32_t aFeatures,
|
||||
mozilla::PowerOfTwo32 aCapacity, double aInterval, uint32_t aFeatures,
|
||||
const char** aFilters, uint32_t aFilterCount,
|
||||
const mozilla::Maybe<double>& aDuration = mozilla::Nothing());
|
||||
|
||||
|
|
|
@ -94,9 +94,9 @@ TEST(GeckoProfiler, FeaturesAndParams)
|
|||
ASSERT_TRUE(!profiler_feature_active(ProfilerFeature::MainThreadIO));
|
||||
ASSERT_TRUE(!profiler_feature_active(ProfilerFeature::Privacy));
|
||||
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
|
||||
features, filters, MOZ_ARRAY_LENGTH(filters),
|
||||
Some(PROFILER_DEFAULT_DURATION));
|
||||
ActiveParamsCheck(
|
||||
PROFILER_DEFAULT_ENTRIES.Value(), PROFILER_DEFAULT_INTERVAL, features,
|
||||
filters, MOZ_ARRAY_LENGTH(filters), Some(PROFILER_DEFAULT_DURATION));
|
||||
|
||||
profiler_stop();
|
||||
|
||||
|
@ -109,15 +109,18 @@ TEST(GeckoProfiler, FeaturesAndParams)
|
|||
ProfilerFeature::MainThreadIO | ProfilerFeature::Privacy;
|
||||
const char* filters[] = {"GeckoMain", "Foo", "Bar"};
|
||||
|
||||
profiler_start(999999, 3, features, filters, MOZ_ARRAY_LENGTH(filters),
|
||||
Some(25.0));
|
||||
// Testing with some arbitrary buffer size (as could be provided by
|
||||
// external code), which we convert to the appropriate power of 2.
|
||||
profiler_start(PowerOfTwo32(999999), 3, features, filters,
|
||||
MOZ_ARRAY_LENGTH(filters), Some(25.0));
|
||||
|
||||
ASSERT_TRUE(profiler_is_active());
|
||||
ASSERT_TRUE(profiler_feature_active(ProfilerFeature::MainThreadIO));
|
||||
ASSERT_TRUE(profiler_feature_active(ProfilerFeature::Privacy));
|
||||
|
||||
// Profiler::Threads is added because filters has multiple entries.
|
||||
ActiveParamsCheck(999999, 3, features | ProfilerFeature::Threads, filters,
|
||||
ActiveParamsCheck(PowerOfTwo32(999999).Value(), 3,
|
||||
features | ProfilerFeature::Threads, filters,
|
||||
MOZ_ARRAY_LENGTH(filters), Some(25.0));
|
||||
|
||||
profiler_stop();
|
||||
|
@ -131,15 +134,16 @@ TEST(GeckoProfiler, FeaturesAndParams)
|
|||
ProfilerFeature::MainThreadIO | ProfilerFeature::Privacy;
|
||||
const char* filters[] = {"GeckoMain", "Foo", "Bar"};
|
||||
|
||||
profiler_start(999999, 3, features, filters, MOZ_ARRAY_LENGTH(filters),
|
||||
Nothing());
|
||||
profiler_start(PowerOfTwo32(999999), 3, features, filters,
|
||||
MOZ_ARRAY_LENGTH(filters), Nothing());
|
||||
|
||||
ASSERT_TRUE(profiler_is_active());
|
||||
ASSERT_TRUE(profiler_feature_active(ProfilerFeature::MainThreadIO));
|
||||
ASSERT_TRUE(profiler_feature_active(ProfilerFeature::Privacy));
|
||||
|
||||
// Profiler::Threads is added because filters has multiple entries.
|
||||
ActiveParamsCheck(999999, 3, features | ProfilerFeature::Threads, filters,
|
||||
ActiveParamsCheck(PowerOfTwo32(999999).Value(), 3,
|
||||
features | ProfilerFeature::Threads, filters,
|
||||
MOZ_ARRAY_LENGTH(filters), Nothing());
|
||||
|
||||
profiler_stop();
|
||||
|
@ -152,15 +156,15 @@ TEST(GeckoProfiler, FeaturesAndParams)
|
|||
uint32_t availableFeatures = profiler_get_available_features();
|
||||
const char* filters[] = {""};
|
||||
|
||||
profiler_start(88888, 10, availableFeatures, filters,
|
||||
profiler_start(PowerOfTwo32(88888), 10, availableFeatures, filters,
|
||||
MOZ_ARRAY_LENGTH(filters), Some(15.0));
|
||||
|
||||
ASSERT_TRUE(profiler_is_active());
|
||||
ASSERT_TRUE(profiler_feature_active(ProfilerFeature::MainThreadIO));
|
||||
ASSERT_TRUE(profiler_feature_active(ProfilerFeature::Privacy));
|
||||
|
||||
ActiveParamsCheck(88888, 10, availableFeatures, filters,
|
||||
MOZ_ARRAY_LENGTH(filters), Some(15.0));
|
||||
ActiveParamsCheck(PowerOfTwo32(88888).Value(), 10, availableFeatures,
|
||||
filters, MOZ_ARRAY_LENGTH(filters), Some(15.0));
|
||||
|
||||
// Don't call profiler_stop() here.
|
||||
}
|
||||
|
@ -172,15 +176,16 @@ TEST(GeckoProfiler, FeaturesAndParams)
|
|||
|
||||
// Second profiler_start() call in a row without an intervening
|
||||
// profiler_stop(); this will do an implicit profiler_stop() and restart.
|
||||
profiler_start(0, 0, features, filters, MOZ_ARRAY_LENGTH(filters),
|
||||
Some(0.0));
|
||||
profiler_start(PowerOfTwo32(0), 0, features, filters,
|
||||
MOZ_ARRAY_LENGTH(filters), Some(0.0));
|
||||
|
||||
ASSERT_TRUE(profiler_is_active());
|
||||
ASSERT_TRUE(!profiler_feature_active(ProfilerFeature::MainThreadIO));
|
||||
ASSERT_TRUE(!profiler_feature_active(ProfilerFeature::Privacy));
|
||||
|
||||
// Entries and intervals go to defaults if 0 is specified.
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES.Value(),
|
||||
PROFILER_DEFAULT_INTERVAL,
|
||||
features | ProfilerFeature::Threads, filters,
|
||||
MOZ_ARRAY_LENGTH(filters), Nothing());
|
||||
|
||||
|
@ -208,9 +213,9 @@ TEST(GeckoProfiler, EnsureStarted)
|
|||
features, filters, MOZ_ARRAY_LENGTH(filters),
|
||||
Some(PROFILER_DEFAULT_DURATION));
|
||||
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
|
||||
features, filters, MOZ_ARRAY_LENGTH(filters),
|
||||
Some(PROFILER_DEFAULT_DURATION));
|
||||
ActiveParamsCheck(
|
||||
PROFILER_DEFAULT_ENTRIES.Value(), PROFILER_DEFAULT_INTERVAL, features,
|
||||
filters, MOZ_ARRAY_LENGTH(filters), Some(PROFILER_DEFAULT_DURATION));
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -228,9 +233,9 @@ TEST(GeckoProfiler, EnsureStarted)
|
|||
features, filters, MOZ_ARRAY_LENGTH(filters),
|
||||
Some(PROFILER_DEFAULT_DURATION));
|
||||
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
|
||||
features, filters, MOZ_ARRAY_LENGTH(filters),
|
||||
Some(PROFILER_DEFAULT_DURATION));
|
||||
ActiveParamsCheck(
|
||||
PROFILER_DEFAULT_ENTRIES.Value(), PROFILER_DEFAULT_INTERVAL, features,
|
||||
filters, MOZ_ARRAY_LENGTH(filters), Some(PROFILER_DEFAULT_DURATION));
|
||||
|
||||
// Check that our position in the buffer stayed the same or advanced.
|
||||
// In particular, it shouldn't have reverted to the start.
|
||||
|
@ -251,8 +256,9 @@ TEST(GeckoProfiler, EnsureStarted)
|
|||
differentFeatures, filters,
|
||||
MOZ_ARRAY_LENGTH(filters));
|
||||
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
|
||||
differentFeatures, filters, MOZ_ARRAY_LENGTH(filters));
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES.Value(),
|
||||
PROFILER_DEFAULT_INTERVAL, differentFeatures, filters,
|
||||
MOZ_ARRAY_LENGTH(filters));
|
||||
|
||||
Maybe<ProfilerBufferInfo> info2 = profiler_get_buffer_info();
|
||||
ASSERT_TRUE(info2->mRangeEnd < info1->mRangeEnd);
|
||||
|
@ -294,8 +300,9 @@ TEST(GeckoProfiler, DifferentThreads)
|
|||
ASSERT_TRUE(!profiler_feature_active(ProfilerFeature::MainThreadIO));
|
||||
ASSERT_TRUE(!profiler_feature_active(ProfilerFeature::Privacy));
|
||||
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
|
||||
features, filters, MOZ_ARRAY_LENGTH(filters));
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES.Value(),
|
||||
PROFILER_DEFAULT_INTERVAL, features, filters,
|
||||
MOZ_ARRAY_LENGTH(filters));
|
||||
|
||||
thread->Dispatch(
|
||||
NS_NewRunnableFunction("GeckoProfiler_DifferentThreads_Test::TestBody",
|
||||
|
@ -323,7 +330,7 @@ TEST(GeckoProfiler, DifferentThreads)
|
|||
!profiler_feature_active(ProfilerFeature::MainThreadIO));
|
||||
ASSERT_TRUE(!profiler_feature_active(ProfilerFeature::Privacy));
|
||||
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES,
|
||||
ActiveParamsCheck(PROFILER_DEFAULT_ENTRIES.Value(),
|
||||
PROFILER_DEFAULT_INTERVAL, features, filters,
|
||||
MOZ_ARRAY_LENGTH(filters));
|
||||
}),
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
#include "ProfileBufferEntry.h"
|
||||
#include "ThreadInfo.h"
|
||||
|
||||
#include "mozilla/PowerOfTwo.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
// Make sure we can record one entry and read it
|
||||
TEST(ThreadProfile, InsertOneEntry)
|
||||
{
|
||||
auto pb = MakeUnique<ProfileBuffer>(10);
|
||||
auto pb = MakeUnique<ProfileBuffer>(mozilla::PowerOfTwo32(10));
|
||||
pb->AddEntry(ProfileBufferEntry::Time(123.1));
|
||||
ASSERT_TRUE(pb->GetEntry(pb->mRangeStart).IsTime());
|
||||
ASSERT_TRUE(pb->GetEntry(pb->mRangeStart).GetDouble() == 123.1);
|
||||
|
@ -21,7 +23,7 @@ TEST(ThreadProfile, InsertOneEntry)
|
|||
// See if we can insert some entries
|
||||
TEST(ThreadProfile, InsertEntriesNoWrap)
|
||||
{
|
||||
auto pb = MakeUnique<ProfileBuffer>(100);
|
||||
auto pb = MakeUnique<ProfileBuffer>(mozilla::PowerOfTwo32(100));
|
||||
int test_size = 50;
|
||||
for (int i = 0; i < test_size; i++) {
|
||||
pb->AddEntry(ProfileBufferEntry::Time(i));
|
||||
|
@ -38,7 +40,7 @@ TEST(ThreadProfile, InsertEntriesNoWrap)
|
|||
TEST(ThreadProfile, InsertEntriesWrap)
|
||||
{
|
||||
int entries = 32;
|
||||
auto pb = MakeUnique<ProfileBuffer>(entries);
|
||||
auto pb = MakeUnique<ProfileBuffer>(mozilla::PowerOfTwo32(entries));
|
||||
ASSERT_TRUE(pb->mRangeStart == 0);
|
||||
ASSERT_TRUE(pb->mRangeEnd == 0);
|
||||
int test_size = 43;
|
||||
|
|
|
@ -28,8 +28,8 @@ bool ANRReporter::RequestNativeStack(bool aUnwind) {
|
|||
const char* NATIVE_STACK_THREADS[] = {"GeckoMain", "Compositor"};
|
||||
|
||||
// Buffer one sample and let the profiler wait a long time
|
||||
profiler_start(/* entries */ 100, /* interval */ 10000, features,
|
||||
NATIVE_STACK_THREADS,
|
||||
profiler_start(/* entries */ PowerOfTwo<uint32_t>(100), /* interval */ 10000,
|
||||
features, NATIVE_STACK_THREADS,
|
||||
sizeof(NATIVE_STACK_THREADS) / sizeof(char*));
|
||||
#endif
|
||||
return true;
|
||||
|
|
Загрузка…
Ссылка в новой задаче