Skip to content

Commit a3660c4

Browse files
authored
Update to use a more efficient power of 2 check. (#274)
1 parent db3580a commit a3660c4

10 files changed

+21
-18
lines changed

src/ds/address.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ namespace snmalloc
4949
template<size_t alignment>
5050
static inline bool is_aligned_block(void* p, size_t size)
5151
{
52-
static_assert(bits::next_pow2_const(alignment) == alignment);
52+
static_assert(bits::is_pow2(alignment));
5353

5454
return ((address_cast(p) | size) & (alignment - 1)) == 0;
5555
}
@@ -62,7 +62,7 @@ namespace snmalloc
6262
SNMALLOC_FAST_PATH T* pointer_align_down(void* p)
6363
{
6464
static_assert(alignment > 0);
65-
static_assert(bits::next_pow2_const(alignment) == alignment);
65+
static_assert(bits::is_pow2(alignment));
6666
if constexpr (alignment == 1)
6767
return static_cast<T*>(p);
6868
else
@@ -84,7 +84,7 @@ namespace snmalloc
8484
inline T* pointer_align_up(void* p)
8585
{
8686
static_assert(alignment > 0);
87-
static_assert(bits::next_pow2_const(alignment) == alignment);
87+
static_assert(bits::is_pow2(alignment));
8888
if constexpr (alignment == 1)
8989
return static_cast<T*>(p);
9090
else
@@ -106,7 +106,7 @@ namespace snmalloc
106106
SNMALLOC_FAST_PATH T* pointer_align_down(void* p, size_t alignment)
107107
{
108108
SNMALLOC_ASSERT(alignment > 0);
109-
SNMALLOC_ASSERT(bits::next_pow2(alignment) == alignment);
109+
SNMALLOC_ASSERT(bits::is_pow2(alignment));
110110
#if __has_builtin(__builtin_align_down)
111111
return static_cast<T*>(__builtin_align_down(p, alignment));
112112
#else
@@ -123,7 +123,7 @@ namespace snmalloc
123123
inline T* pointer_align_up(void* p, size_t alignment)
124124
{
125125
SNMALLOC_ASSERT(alignment > 0);
126-
SNMALLOC_ASSERT(bits::next_pow2(alignment) == alignment);
126+
SNMALLOC_ASSERT(bits::is_pow2(alignment));
127127
#if __has_builtin(__builtin_align_up)
128128
return static_cast<T*>(__builtin_align_up(p, alignment));
129129
#else

src/ds/bits.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ namespace snmalloc
211211
#endif
212212
}
213213

214+
constexpr SNMALLOC_FAST_PATH bool is_pow2(size_t x)
215+
{
216+
return (x & (x - 1)) == 0;
217+
}
218+
214219
SNMALLOC_FAST_PATH size_t next_pow2(size_t x)
215220
{
216221
// Correct for numbers [0..MAX_SIZE >> 1).
@@ -244,7 +249,7 @@ namespace snmalloc
244249
constexpr SNMALLOC_FAST_PATH size_t
245250
align_down(size_t value, size_t alignment)
246251
{
247-
SNMALLOC_ASSERT(next_pow2_const(alignment) == alignment);
252+
SNMALLOC_ASSERT(is_pow2(alignment));
248253

249254
size_t align_1 = alignment - 1;
250255
value &= ~align_1;
@@ -253,7 +258,7 @@ namespace snmalloc
253258

254259
constexpr SNMALLOC_FAST_PATH size_t align_up(size_t value, size_t alignment)
255260
{
256-
SNMALLOC_ASSERT(next_pow2_const(alignment) == alignment);
261+
SNMALLOC_ASSERT(is_pow2(alignment));
257262

258263
size_t align_1 = alignment - 1;
259264
value += align_1;

src/ds/helpers.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ namespace snmalloc
5252
template<size_t length, typename T>
5353
class Mod
5454
{
55-
static_assert(
56-
length == bits::next_pow2_const(length), "Must be a power of two.");
55+
static_assert(bits::is_pow2(length), "Must be a power of two.");
5756

5857
private:
5958
T value = 0;

src/mem/address_space.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ namespace snmalloc
175175
template<bool committed>
176176
void* reserve(size_t size)
177177
{
178-
SNMALLOC_ASSERT(bits::next_pow2(size) == size);
178+
SNMALLOC_ASSERT(bits::is_pow2(size));
179179
SNMALLOC_ASSERT(size >= sizeof(void*));
180180

181181
if constexpr (pal_supports<AlignedAllocation, PAL>)

src/mem/sizeclass.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ namespace snmalloc
183183
// Client responsible for checking alignment is not zero
184184
SNMALLOC_ASSERT(alignment != 0);
185185
// Client responsible for checking alignment is a power of two
186-
SNMALLOC_ASSERT(bits::next_pow2(alignment) == alignment);
186+
SNMALLOC_ASSERT(bits::is_pow2(alignment));
187187

188188
return ((alignment - 1) | (size - 1)) + 1;
189189
}

src/pal/pal.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ namespace snmalloc
7676
static constexpr size_t OS_PAGE_SIZE = Pal::page_size;
7777

7878
static_assert(
79-
bits::next_pow2_const(OS_PAGE_SIZE) == OS_PAGE_SIZE,
80-
"OS_PAGE_SIZE must be a power of two");
79+
bits::is_pow2(OS_PAGE_SIZE), "OS_PAGE_SIZE must be a power of two");
8180
static_assert(
8281
OS_PAGE_SIZE % Aal::smallest_page_size == 0,
8382
"The smallest architectural page size must divide OS_PAGE_SIZE");

src/pal/pal_bsd_aligned.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace snmalloc
3232
static void* reserve_aligned(size_t size) noexcept
3333
{
3434
// Alignment must be a power of 2.
35-
SNMALLOC_ASSERT(size == bits::next_pow2(size));
35+
SNMALLOC_ASSERT(bits::is_pow2(size));
3636
SNMALLOC_ASSERT(size >= minimum_alloc_size);
3737

3838
size_t log2align = bits::next_pow2_bits(size);

src/pal/pal_freebsd_kernel.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ namespace snmalloc
6262
template<bool committed>
6363
static void* reserve_aligned(size_t size) noexcept
6464
{
65-
SNMALLOC_ASSERT(size == bits::next_pow2(size));
65+
SNMALLOC_ASSERT(bits::is_pow2(size));
6666
SNMALLOC_ASSERT(size >= minimum_alloc_size);
6767
size_t align = size;
6868

src/pal/pal_posix.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ namespace snmalloc
212212
*/
213213
static std::pair<void*, size_t> reserve_at_least(size_t size) noexcept
214214
{
215-
SNMALLOC_ASSERT(size == bits::next_pow2(size));
215+
SNMALLOC_ASSERT(bits::is_pow2(size));
216216

217217
// Magic number for over-allocating chosen by the Pal
218218
// These should be further refined based on experiments.

src/pal/pal_windows.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ namespace snmalloc
185185
template<bool committed>
186186
static void* reserve_aligned(size_t size) noexcept
187187
{
188-
SNMALLOC_ASSERT(size == bits::next_pow2(size));
188+
SNMALLOC_ASSERT(bits::is_pow2(size));
189189
SNMALLOC_ASSERT(size >= minimum_alloc_size);
190190

191191
DWORD flags = MEM_RESERVE;
@@ -215,7 +215,7 @@ namespace snmalloc
215215
# else
216216
static std::pair<void*, size_t> reserve_at_least(size_t size) noexcept
217217
{
218-
SNMALLOC_ASSERT(size == bits::next_pow2(size));
218+
SNMALLOC_ASSERT(bits::is_pow2(size));
219219

220220
// Magic number for over-allocating chosen by the Pal
221221
// These should be further refined based on experiments.

0 commit comments

Comments
 (0)