address.h: add pointer alignment functions

More explicit than address_cast and bitwise and
This commit is contained in:
Nathaniel Filardo
2019-05-07 13:21:02 +01:00
parent 20e804728b
commit ef7985510c
6 changed files with 40 additions and 11 deletions

View File

@@ -56,4 +56,35 @@ namespace snmalloc
0;
}
/**
* Align a pointer down to a statically specified granularity, which must be a
* power of two.
*/
template<size_t alignment, typename T = void>
inline T* pointer_align_down(void* p)
{
static_assert(alignment > 0);
static_assert(bits::next_pow2_const(alignment) == alignment);
#if __has_builtin(__builtin_align_down)
return static_cast<T*>(__builtin_align_down(p, alignment));
#else
return pointer_cast<T>(bits::align_down(address_cast(p), alignment));
#endif
}
/**
* Align a pointer up to a statically specified granularity, which must be a
* power of two.
*/
template<size_t alignment, typename T = void>
inline T* pointer_align_up(void* p)
{
static_assert(alignment > 0);
static_assert(bits::next_pow2_const(alignment) == alignment);
#if __has_builtin(__builtin_align_up)
return static_cast<T*>(__builtin_align_up(p, alignment));
#else
return pointer_cast<T>(bits::align_up(address_cast(p), alignment));
#endif
}
} // namespace snmalloc

View File

@@ -166,11 +166,12 @@ namespace snmalloc
remaining -= size;
}
auto page_start = bits::align_down(address_cast(p), OS_PAGE_SIZE);
auto page_end = bits::align_up(address_cast(p) + size, OS_PAGE_SIZE);
auto page_start = pointer_align_down<OS_PAGE_SIZE, char>(p);
auto page_end =
pointer_align_up<OS_PAGE_SIZE, char>(pointer_offset(p, size));
PAL::template notify_using<NoZero>(
pointer_cast<void>(page_start), page_end - page_start);
page_start, static_cast<size_t>(page_end - page_start));
return new (p) T(std::forward<Args...>(args)...);
}
@@ -295,8 +296,7 @@ namespace snmalloc
reserved_start =
memory_provider.template reserve<false>(&add, SUPERSLAB_SIZE);
reserved_end = pointer_offset(reserved_start, add);
reserved_start = pointer_cast<void>(
bits::align_up(address_cast(reserved_start), SUPERSLAB_SIZE));
reserved_start = pointer_align_up<SUPERSLAB_SIZE>(reserved_start);
if (add < need)
return false;

View File

@@ -41,7 +41,7 @@ namespace snmalloc
static Mediumslab* get(void* p)
{
return pointer_cast<Mediumslab>(address_cast(p) & SUPERSLAB_MASK);
return pointer_align_down<SUPERSLAB_SIZE, Mediumslab>(p);
}
void init(RemoteAllocator* alloc, sizeclass_t sc, size_t rsize)

View File

@@ -15,7 +15,7 @@ namespace snmalloc
Slab* get_slab()
{
return pointer_cast<Slab>(address_cast(this) & SLAB_MASK);
return pointer_align_down<SLAB_SIZE, Slab>(this);
}
};

View File

@@ -273,9 +273,7 @@ namespace snmalloc
void* page_for_address(uintptr_t p)
{
bool success;
return reinterpret_cast<void*>(
~(OS_PAGE_SIZE - 1) &
reinterpret_cast<uintptr_t>(get_addr<true>(p, success)));
return pointer_align_down<OS_PAGE_SIZE>(get_addr<true>(p, success));
}
T get(uintptr_t p)

View File

@@ -67,7 +67,7 @@ namespace snmalloc
static Superslab* get(void* p)
{
return pointer_cast<Superslab>(address_cast(p) & SUPERSLAB_MASK);
return pointer_align_down<SUPERSLAB_SIZE, Superslab>(p);
}
static bool is_short_sizeclass(sizeclass_t sizeclass)