2019-06-06 09:18:09 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "BaseProfiler.h"
|
|
|
|
|
2019-06-28 02:09:41 +03:00
|
|
|
#ifdef MOZ_BASE_PROFILER
|
Bug 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum
PowerOfTwo stores a power of 2 value, i.e., 2^N.
PowerOfTwoMask stores a mask corresponding to a power of 2, i.e., 2^N-1.
These should be used in places where a power of 2 (or its mask) is stored or
expected.
`% PowerOfTwo{,Mask}` and `& PowerOfTwoMask` operations are optimal.
MakePowerOfTwo{,Mask}<T, Value>() may be used to create statically-checked
constants.
{,Make}PowerOfTwo{,Mask}{32,64} shortcuts for common 32- and 64-bit types.
Differential Revision: https://phabricator.services.mozilla.com/D36026
--HG--
extra : moz-landing-system : lando
2019-06-28 01:33:29 +03:00
|
|
|
|
2019-07-03 17:49:10 +03:00
|
|
|
# include "mozilla/leb128iterator.h"
|
Bug 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum
PowerOfTwo stores a power of 2 value, i.e., 2^N.
PowerOfTwoMask stores a mask corresponding to a power of 2, i.e., 2^N-1.
These should be used in places where a power of 2 (or its mask) is stored or
expected.
`% PowerOfTwo{,Mask}` and `& PowerOfTwoMask` operations are optimal.
MakePowerOfTwo{,Mask}<T, Value>() may be used to create statically-checked
constants.
{,Make}PowerOfTwo{,Mask}{32,64} shortcuts for common 32- and 64-bit types.
Differential Revision: https://phabricator.services.mozilla.com/D36026
--HG--
extra : moz-landing-system : lando
2019-06-28 10:12:54 +03:00
|
|
|
# include "mozilla/PowerOfTwo.h"
|
|
|
|
|
2019-06-28 02:09:41 +03:00
|
|
|
# include "mozilla/Attributes.h"
|
|
|
|
# include "mozilla/Vector.h"
|
Bug 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum
PowerOfTwo stores a power of 2 value, i.e., 2^N.
PowerOfTwoMask stores a mask corresponding to a power of 2, i.e., 2^N-1.
These should be used in places where a power of 2 (or its mask) is stored or
expected.
`% PowerOfTwo{,Mask}` and `& PowerOfTwoMask` operations are optimal.
MakePowerOfTwo{,Mask}<T, Value>() may be used to create statically-checked
constants.
{,Make}PowerOfTwo{,Mask}{32,64} shortcuts for common 32- and 64-bit types.
Differential Revision: https://phabricator.services.mozilla.com/D36026
--HG--
extra : moz-landing-system : lando
2019-06-28 01:33:29 +03:00
|
|
|
|
2019-06-28 02:09:41 +03:00
|
|
|
# if defined(_MSC_VER)
|
|
|
|
# include <windows.h>
|
|
|
|
# include <mmsystem.h>
|
|
|
|
# include <process.h>
|
Bug 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum
PowerOfTwo stores a power of 2 value, i.e., 2^N.
PowerOfTwoMask stores a mask corresponding to a power of 2, i.e., 2^N-1.
These should be used in places where a power of 2 (or its mask) is stored or
expected.
`% PowerOfTwo{,Mask}` and `& PowerOfTwoMask` operations are optimal.
MakePowerOfTwo{,Mask}<T, Value>() may be used to create statically-checked
constants.
{,Make}PowerOfTwo{,Mask}{32,64} shortcuts for common 32- and 64-bit types.
Differential Revision: https://phabricator.services.mozilla.com/D36026
--HG--
extra : moz-landing-system : lando
2019-06-28 10:12:54 +03:00
|
|
|
# else
|
2019-06-28 02:09:41 +03:00
|
|
|
# include <time.h>
|
|
|
|
# include <unistd.h>
|
|
|
|
# endif
|
Bug 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum
PowerOfTwo stores a power of 2 value, i.e., 2^N.
PowerOfTwoMask stores a mask corresponding to a power of 2, i.e., 2^N-1.
These should be used in places where a power of 2 (or its mask) is stored or
expected.
`% PowerOfTwo{,Mask}` and `& PowerOfTwoMask` operations are optimal.
MakePowerOfTwo{,Mask}<T, Value>() may be used to create statically-checked
constants.
{,Make}PowerOfTwo{,Mask}{32,64} shortcuts for common 32- and 64-bit types.
Differential Revision: https://phabricator.services.mozilla.com/D36026
--HG--
extra : moz-landing-system : lando
2019-06-28 01:33:29 +03:00
|
|
|
|
2019-06-28 02:09:41 +03:00
|
|
|
using namespace mozilla;
|
Bug 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum
PowerOfTwo stores a power of 2 value, i.e., 2^N.
PowerOfTwoMask stores a mask corresponding to a power of 2, i.e., 2^N-1.
These should be used in places where a power of 2 (or its mask) is stored or
expected.
`% PowerOfTwo{,Mask}` and `& PowerOfTwoMask` operations are optimal.
MakePowerOfTwo{,Mask}<T, Value>() may be used to create statically-checked
constants.
{,Make}PowerOfTwo{,Mask}{32,64} shortcuts for common 32- and 64-bit types.
Differential Revision: https://phabricator.services.mozilla.com/D36026
--HG--
extra : moz-landing-system : lando
2019-06-28 01:33:29 +03:00
|
|
|
|
Bug 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum
PowerOfTwo stores a power of 2 value, i.e., 2^N.
PowerOfTwoMask stores a mask corresponding to a power of 2, i.e., 2^N-1.
These should be used in places where a power of 2 (or its mask) is stored or
expected.
`% PowerOfTwo{,Mask}` and `& PowerOfTwoMask` operations are optimal.
MakePowerOfTwo{,Mask}<T, Value>() may be used to create statically-checked
constants.
{,Make}PowerOfTwo{,Mask}{32,64} shortcuts for common 32- and 64-bit types.
Differential Revision: https://phabricator.services.mozilla.com/D36026
--HG--
extra : moz-landing-system : lando
2019-06-28 10:12:54 +03:00
|
|
|
MOZ_MAYBE_UNUSED static void SleepMilli(unsigned aMilliseconds) {
|
|
|
|
# if defined(_MSC_VER)
|
|
|
|
Sleep(aMilliseconds);
|
|
|
|
# else
|
|
|
|
struct timespec ts;
|
|
|
|
ts.tv_sec = aMilliseconds / 1000;
|
|
|
|
ts.tv_nsec = long(aMilliseconds % 1000) * 1000000;
|
|
|
|
struct timespec tr;
|
|
|
|
while (nanosleep(&ts, &tr)) {
|
|
|
|
if (errno == EINTR) {
|
|
|
|
ts = tr;
|
|
|
|
} else {
|
|
|
|
printf("nanosleep() -> %s\n", strerror(errno));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestPowerOfTwoMask() {
|
|
|
|
printf("TestPowerOfTwoMask...\n");
|
|
|
|
|
|
|
|
static_assert(MakePowerOfTwoMask<uint32_t, 0>().MaskValue() == 0, "");
|
|
|
|
constexpr PowerOfTwoMask<uint32_t> c0 = MakePowerOfTwoMask<uint32_t, 0>();
|
|
|
|
MOZ_RELEASE_ASSERT(c0.MaskValue() == 0);
|
|
|
|
|
|
|
|
static_assert(MakePowerOfTwoMask<uint32_t, 0xFFu>().MaskValue() == 0xFFu, "");
|
|
|
|
constexpr PowerOfTwoMask<uint32_t> cFF =
|
|
|
|
MakePowerOfTwoMask<uint32_t, 0xFFu>();
|
|
|
|
MOZ_RELEASE_ASSERT(cFF.MaskValue() == 0xFFu);
|
|
|
|
|
|
|
|
static_assert(
|
|
|
|
MakePowerOfTwoMask<uint32_t, 0xFFFFFFFFu>().MaskValue() == 0xFFFFFFFFu,
|
|
|
|
"");
|
|
|
|
constexpr PowerOfTwoMask<uint32_t> cFFFFFFFF =
|
|
|
|
MakePowerOfTwoMask<uint32_t, 0xFFFFFFFFu>();
|
|
|
|
MOZ_RELEASE_ASSERT(cFFFFFFFF.MaskValue() == 0xFFFFFFFFu);
|
|
|
|
|
|
|
|
struct TestDataU32 {
|
|
|
|
uint32_t mInput;
|
|
|
|
uint32_t mMask;
|
|
|
|
};
|
|
|
|
// clang-format off
|
|
|
|
TestDataU32 tests[] = {
|
|
|
|
{ 0, 0 },
|
|
|
|
{ 1, 1 },
|
|
|
|
{ 2, 3 },
|
|
|
|
{ 3, 3 },
|
|
|
|
{ 4, 7 },
|
|
|
|
{ 5, 7 },
|
|
|
|
{ (1u << 31) - 1, (1u << 31) - 1 },
|
|
|
|
{ (1u << 31), uint32_t(-1) },
|
|
|
|
{ (1u << 31) + 1, uint32_t(-1) },
|
|
|
|
{ uint32_t(-1), uint32_t(-1) }
|
|
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
for (const TestDataU32& test : tests) {
|
|
|
|
PowerOfTwoMask<uint32_t> p2m(test.mInput);
|
|
|
|
MOZ_RELEASE_ASSERT(p2m.MaskValue() == test.mMask);
|
|
|
|
for (const TestDataU32& inner : tests) {
|
|
|
|
if (p2m.MaskValue() != uint32_t(-1)) {
|
|
|
|
MOZ_RELEASE_ASSERT((inner.mInput % p2m) ==
|
|
|
|
(inner.mInput % (p2m.MaskValue() + 1)));
|
|
|
|
}
|
|
|
|
MOZ_RELEASE_ASSERT((inner.mInput & p2m) == (inner.mInput % p2m));
|
|
|
|
MOZ_RELEASE_ASSERT((p2m & inner.mInput) == (inner.mInput & p2m));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("TestPowerOfTwoMask done\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestPowerOfTwo() {
|
|
|
|
printf("TestPowerOfTwo...\n");
|
|
|
|
|
|
|
|
static_assert(MakePowerOfTwo<uint32_t, 1>().Value() == 1, "");
|
|
|
|
constexpr PowerOfTwo<uint32_t> c1 = MakePowerOfTwo<uint32_t, 1>();
|
|
|
|
MOZ_RELEASE_ASSERT(c1.Value() == 1);
|
|
|
|
static_assert(MakePowerOfTwo<uint32_t, 1>().Mask().MaskValue() == 0, "");
|
|
|
|
|
|
|
|
static_assert(MakePowerOfTwo<uint32_t, 128>().Value() == 128, "");
|
|
|
|
constexpr PowerOfTwo<uint32_t> c128 = MakePowerOfTwo<uint32_t, 128>();
|
|
|
|
MOZ_RELEASE_ASSERT(c128.Value() == 128);
|
|
|
|
static_assert(MakePowerOfTwo<uint32_t, 128>().Mask().MaskValue() == 127, "");
|
|
|
|
|
|
|
|
static_assert(MakePowerOfTwo<uint32_t, 0x80000000u>().Value() == 0x80000000u,
|
|
|
|
"");
|
|
|
|
constexpr PowerOfTwo<uint32_t> cMax = MakePowerOfTwo<uint32_t, 0x80000000u>();
|
|
|
|
MOZ_RELEASE_ASSERT(cMax.Value() == 0x80000000u);
|
|
|
|
static_assert(
|
|
|
|
MakePowerOfTwo<uint32_t, 0x80000000u>().Mask().MaskValue() == 0x7FFFFFFFu,
|
|
|
|
"");
|
|
|
|
|
|
|
|
struct TestDataU32 {
|
|
|
|
uint32_t mInput;
|
|
|
|
uint32_t mValue;
|
|
|
|
uint32_t mMask;
|
|
|
|
};
|
|
|
|
// clang-format off
|
|
|
|
TestDataU32 tests[] = {
|
|
|
|
{ 0, 1, 0 },
|
|
|
|
{ 1, 1, 0 },
|
|
|
|
{ 2, 2, 1 },
|
|
|
|
{ 3, 4, 3 },
|
|
|
|
{ 4, 4, 3 },
|
|
|
|
{ 5, 8, 7 },
|
|
|
|
{ (1u << 31) - 1, (1u << 31), (1u << 31) - 1 },
|
|
|
|
{ (1u << 31), (1u << 31), (1u << 31) - 1 },
|
|
|
|
{ (1u << 31) + 1, (1u << 31), (1u << 31) - 1 },
|
|
|
|
{ uint32_t(-1), (1u << 31), (1u << 31) - 1 }
|
|
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
for (const TestDataU32& test : tests) {
|
|
|
|
PowerOfTwo<uint32_t> p2(test.mInput);
|
|
|
|
MOZ_RELEASE_ASSERT(p2.Value() == test.mValue);
|
|
|
|
MOZ_RELEASE_ASSERT(p2.MaskValue() == test.mMask);
|
|
|
|
PowerOfTwoMask<uint32_t> p2m = p2.Mask();
|
|
|
|
MOZ_RELEASE_ASSERT(p2m.MaskValue() == test.mMask);
|
|
|
|
for (const TestDataU32& inner : tests) {
|
|
|
|
MOZ_RELEASE_ASSERT((inner.mInput % p2) == (inner.mInput % p2.Value()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("TestPowerOfTwo done\n");
|
|
|
|
}
|
|
|
|
|
2019-07-03 17:49:10 +03:00
|
|
|
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);
|
|
|
|
MOZ_RELEASE_ASSERT(ULEB128MaxSize<uint64_t>() == 10);
|
|
|
|
|
|
|
|
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" },
|
|
|
|
{ 1u, 1, "\x01" },
|
|
|
|
|
|
|
|
// 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
|
|
|
|
// is off.
|
|
|
|
{ 0x7Fu, 1, "\x7F" },
|
|
|
|
|
|
|
|
// Next number: 128, or 0x80.
|
|
|
|
// Original data representation: 1000 0000
|
|
|
|
// Broken up into groups of 7: 1 0000000
|
|
|
|
// Padded with 0 (msB) or 1 (lsB): 00000001 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.)
|
|
|
|
// Original data representation: 1000 0001
|
|
|
|
// Broken up into groups of 7: 1 0000001
|
|
|
|
// Padded with 0 (msB) or 1 (lsB): 00000001 10000001
|
|
|
|
// Byte representation: 0x01 0x81
|
|
|
|
// 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
|
|
|
|
// Byte representation: 0x01 0xFF
|
|
|
|
// Little endian order: -> 0xFF 0x01
|
|
|
|
{ 0xFFu, 2, "\xFF\x01" },
|
|
|
|
|
|
|
|
// Next: 256, or 0x100.
|
|
|
|
// Original data representation: 1 0000 0000
|
|
|
|
// Broken up into groups of 7: 10 0000000
|
|
|
|
// Padded with 0 (msB) or 1 (lsB): 00000010 10000000
|
|
|
|
// Byte representation: 0x10 0x80
|
|
|
|
// Little endian order: -> 0x80 0x02
|
|
|
|
{ 0x100u, 2, "\x80\x02" },
|
|
|
|
|
|
|
|
// Highest 32-bit number: 0xFFFFFFFF (8 bytes, all bits set).
|
|
|
|
// Original: 1111 1111 1111 1111 1111 1111 1111 1111
|
|
|
|
// Groups: 1111 1111111 1111111 1111111 1111111
|
|
|
|
// Padded: 00001111 11111111 11111111 11111111 11111111
|
|
|
|
// Bytes: 0x0F 0xFF 0xFF 0xFF 0xFF
|
|
|
|
// Little Endian: -> 0xFF 0xFF 0xFF 0xFF 0x0F
|
|
|
|
{ 0xFFFFFFFFu, 5, "\xFF\xFF\xFF\xFF\x0F" },
|
|
|
|
|
|
|
|
// Highest 64-bit number: 0xFFFFFFFFFFFFFFFF (16 bytes, all bits set).
|
|
|
|
// 64 bits, that's 9 groups of 7 bits, plus 1 (most significant) bit.
|
|
|
|
{ 0xFFFFFFFFFFFFFFFFu, 10, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01" }
|
|
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
for (const TestDataU64& test : tests) {
|
|
|
|
MOZ_RELEASE_ASSERT(ULEB128Size(test.mValue) == test.mSize);
|
|
|
|
// Prepare a buffer that can accomodate the largest-possible LEB128.
|
|
|
|
uint8_t buffer[ULEB128MaxSize<uint64_t>()];
|
|
|
|
// Use a pointer into the buffer as iterator.
|
|
|
|
uint8_t* p = buffer;
|
|
|
|
// And write the LEB128.
|
|
|
|
WriteULEB128(test.mValue, p);
|
|
|
|
// Pointer (iterator) should have advanced just past the expected LEB128
|
|
|
|
// size.
|
|
|
|
MOZ_RELEASE_ASSERT(p == buffer + test.mSize);
|
|
|
|
// Check expected bytes.
|
|
|
|
for (unsigned i = 0; i < test.mSize; ++i) {
|
|
|
|
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_ASSERT(p == buffer + test.mSize);
|
|
|
|
// And check the read value.
|
|
|
|
MOZ_RELEASE_ASSERT(read == test.mValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("TestLEB128 done\n");
|
|
|
|
}
|
|
|
|
|
2019-06-06 09:18:09 +03:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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) {
|
|
|
|
if (n == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (n == 1) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
unsigned long long f2 = Fibonacci<NextDepth(DEPTH)>(n - 2);
|
|
|
|
if (DEPTH == 0) {
|
2019-06-06 09:19:01 +03:00
|
|
|
BASE_PROFILER_ADD_MARKER("Half-way through Fibonacci", OTHER);
|
2019-06-06 09:18:09 +03:00
|
|
|
}
|
|
|
|
unsigned long long f1 = Fibonacci<NextDepth(DEPTH)>(n - 1);
|
|
|
|
return f2 + f1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestProfiler() {
|
|
|
|
printf("TestProfiler starting -- pid: %d, tid: %d\n",
|
2019-06-06 09:20:03 +03:00
|
|
|
baseprofiler::profiler_current_process_id(),
|
|
|
|
baseprofiler::profiler_current_thread_id());
|
Bug 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum
PowerOfTwo stores a power of 2 value, i.e., 2^N.
PowerOfTwoMask stores a mask corresponding to a power of 2, i.e., 2^N-1.
These should be used in places where a power of 2 (or its mask) is stored or
expected.
`% PowerOfTwo{,Mask}` and `& PowerOfTwoMask` operations are optimal.
MakePowerOfTwo{,Mask}<T, Value>() may be used to create statically-checked
constants.
{,Make}PowerOfTwo{,Mask}{32,64} shortcuts for common 32- and 64-bit types.
Differential Revision: https://phabricator.services.mozilla.com/D36026
--HG--
extra : moz-landing-system : lando
2019-06-28 10:12:54 +03:00
|
|
|
// ::SleepMilli(10000);
|
|
|
|
|
|
|
|
// Test dependencies.
|
|
|
|
TestPowerOfTwoMask();
|
|
|
|
TestPowerOfTwo();
|
2019-07-03 17:49:10 +03:00
|
|
|
TestLEB128();
|
2019-06-06 09:18:09 +03:00
|
|
|
|
|
|
|
{
|
|
|
|
printf("profiler_init()...\n");
|
2019-06-06 09:19:01 +03:00
|
|
|
AUTO_BASE_PROFILER_INIT;
|
2019-06-06 09:18:09 +03:00
|
|
|
|
2019-06-06 09:20:03 +03:00
|
|
|
MOZ_RELEASE_ASSERT(!baseprofiler::profiler_is_active());
|
|
|
|
MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_being_profiled());
|
|
|
|
MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_sleeping());
|
2019-06-06 09:18:09 +03:00
|
|
|
|
|
|
|
printf("profiler_start()...\n");
|
Bug 1552063 - PowerOfTwo, PowerOfTwoMask - r=gregtatum
PowerOfTwo stores a power of 2 value, i.e., 2^N.
PowerOfTwoMask stores a mask corresponding to a power of 2, i.e., 2^N-1.
These should be used in places where a power of 2 (or its mask) is stored or
expected.
`% PowerOfTwo{,Mask}` and `& PowerOfTwoMask` operations are optimal.
MakePowerOfTwo{,Mask}<T, Value>() may be used to create statically-checked
constants.
{,Make}PowerOfTwo{,Mask}{32,64} shortcuts for common 32- and 64-bit types.
Differential Revision: https://phabricator.services.mozilla.com/D36026
--HG--
extra : moz-landing-system : lando
2019-06-28 10:12:54 +03:00
|
|
|
Vector<const char*> filters;
|
2019-06-06 09:18:09 +03:00
|
|
|
// Profile all registered threads.
|
|
|
|
MOZ_RELEASE_ASSERT(filters.append(""));
|
2019-06-06 09:20:03 +03:00
|
|
|
const uint32_t features = baseprofiler::ProfilerFeature::Leaf |
|
|
|
|
baseprofiler::ProfilerFeature::StackWalk |
|
|
|
|
baseprofiler::ProfilerFeature::Threads;
|
|
|
|
baseprofiler::profiler_start(baseprofiler::BASE_PROFILER_DEFAULT_ENTRIES,
|
|
|
|
BASE_PROFILER_DEFAULT_INTERVAL, features,
|
|
|
|
filters.begin(), filters.length());
|
2019-06-06 09:18:09 +03:00
|
|
|
|
2019-06-06 09:20:03 +03:00
|
|
|
MOZ_RELEASE_ASSERT(baseprofiler::profiler_is_active());
|
|
|
|
MOZ_RELEASE_ASSERT(baseprofiler::profiler_thread_is_being_profiled());
|
|
|
|
MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_sleeping());
|
2019-06-06 09:18:09 +03:00
|
|
|
|
|
|
|
{
|
2019-06-06 09:19:01 +03:00
|
|
|
AUTO_BASE_PROFILER_TEXT_MARKER_CAUSE("fibonacci", "First leaf call",
|
|
|
|
OTHER, nullptr);
|
2019-06-06 09:18:09 +03:00
|
|
|
static const unsigned long long fibStart = 40;
|
|
|
|
printf("Fibonacci(%llu)...\n", fibStart);
|
2019-06-06 09:19:01 +03:00
|
|
|
AUTO_BASE_PROFILER_LABEL("Label around Fibonacci", OTHER);
|
2019-06-06 09:18:09 +03:00
|
|
|
unsigned long long f = Fibonacci(fibStart);
|
|
|
|
printf("Fibonacci(%llu) = %llu\n", fibStart, f);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("Sleep 1s...\n");
|
|
|
|
{
|
2019-06-06 09:19:01 +03:00
|
|
|
AUTO_BASE_PROFILER_THREAD_SLEEP;
|
2019-06-06 09:18:09 +03:00
|
|
|
SleepMilli(1000);
|
|
|
|
}
|
|
|
|
|
2019-06-06 09:20:03 +03:00
|
|
|
printf("baseprofiler_save_profile_to_file()...\n");
|
|
|
|
baseprofiler::profiler_save_profile_to_file("TestProfiler_profile.json");
|
2019-06-06 09:18:09 +03:00
|
|
|
|
|
|
|
printf("profiler_stop()...\n");
|
2019-06-06 09:20:03 +03:00
|
|
|
baseprofiler::profiler_stop();
|
2019-06-06 09:18:09 +03:00
|
|
|
|
2019-06-06 09:20:03 +03:00
|
|
|
MOZ_RELEASE_ASSERT(!baseprofiler::profiler_is_active());
|
|
|
|
MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_being_profiled());
|
|
|
|
MOZ_RELEASE_ASSERT(!baseprofiler::profiler_thread_is_sleeping());
|
2019-06-06 09:18:09 +03:00
|
|
|
|
|
|
|
printf("profiler_shutdown()...\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("TestProfiler done\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
#else // MOZ_BASE_PROFILER
|
|
|
|
|
|
|
|
// Testing that macros are still #defined (but do nothing) when
|
|
|
|
// MOZ_BASE_PROFILER is disabled.
|
|
|
|
void TestProfiler() {
|
|
|
|
// These don't need to make sense, we just want to know that they're defined
|
|
|
|
// and don't do anything.
|
2019-06-06 09:19:01 +03:00
|
|
|
AUTO_BASE_PROFILER_INIT;
|
2019-06-06 09:18:09 +03:00
|
|
|
|
|
|
|
// This wouldn't build if the macro did output its arguments.
|
2019-06-06 09:19:01 +03:00
|
|
|
AUTO_BASE_PROFILER_TEXT_MARKER_CAUSE(catch, catch, catch, catch);
|
2019-06-06 09:18:09 +03:00
|
|
|
|
2019-06-06 09:19:01 +03:00
|
|
|
AUTO_BASE_PROFILER_LABEL(catch, catch);
|
2019-06-06 09:18:09 +03:00
|
|
|
|
2019-06-06 09:19:01 +03:00
|
|
|
AUTO_BASE_PROFILER_THREAD_SLEEP;
|
2019-06-06 09:18:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // MOZ_BASE_PROFILER else
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
// Note that there are two `TestProfiler` functions above, depending on
|
|
|
|
// whether MOZ_BASE_PROFILER is #defined.
|
|
|
|
TestProfiler();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|