diff --git a/src/ds/address.h b/src/ds/address.h index 0dde502..d46da59 100644 --- a/src/ds/address.h +++ b/src/ds/address.h @@ -16,12 +16,21 @@ namespace snmalloc */ using address_t = Aal::address_t; + /** + * Perform arithmetic on a uintptr_t. + */ + inline uintptr_t pointer_offset(uintptr_t base, size_t diff) + { + return base + diff; + } + /** * Perform pointer arithmetic and return the adjusted pointer. */ template inline U* pointer_offset(T* base, size_t diff) { + SNMALLOC_ASSERT(base != nullptr); /* Avoid UB */ return reinterpret_cast(reinterpret_cast(base) + diff); } @@ -38,6 +47,7 @@ namespace snmalloc template inline U* pointer_offset_signed(T* base, ptrdiff_t diff) { + SNMALLOC_ASSERT(base != nullptr); /* Avoid UB */ return reinterpret_cast(reinterpret_cast(base) + diff); } @@ -89,6 +99,27 @@ namespace snmalloc return is_aligned_block(address_cast(p), size); } + /** + * Align a uintptr_t down to a statically specified granularity, which must be + * a power of two. + */ + template + inline uintptr_t pointer_align_down(uintptr_t p) + { + static_assert(alignment > 0); + static_assert(bits::is_pow2(alignment)); + if constexpr (alignment == 1) + return p; + else + { +#if __has_builtin(__builtin_align_down) + return __builtin_align_down(p, alignment); +#else + return bits::align_down(p, alignment); +#endif + } + } + /** * Align a pointer down to a statically specified granularity, which must be a * power of two. @@ -96,19 +127,8 @@ namespace snmalloc template inline T* pointer_align_down(void* p) { - static_assert(alignment > 0); - static_assert(bits::is_pow2(alignment)); - if constexpr (alignment == 1) - return static_cast(p); - else - { -#if __has_builtin(__builtin_align_down) - return static_cast(__builtin_align_down(p, alignment)); -#else - return reinterpret_cast( - bits::align_down(reinterpret_cast(p), alignment)); -#endif - } + return reinterpret_cast( + pointer_align_down(reinterpret_cast(p))); } template