Fix the remaining clang-tidy warnings.

This introduces a new `address_t` type and two new casts: `pointer_cast`
and `address_cast` for casting between an `address_t` and a pointer.
These should make it easier to audit the codebase for casts between
pointers and integers.  In particular, the remaining `reinterpret_cast`s
and `pointer_cast`s should be the only places where we could perform
invalid pointer arithmetic.

Also adds a `pointer_offset` helper that adds an offset (in bytes) to a
pointer, preserving its original type.  This is a sufficiently common
pattern that it seemed worthwhile to centralise it.
This commit is contained in:
David Chisnall
2019-04-29 13:37:05 +01:00
parent 4bafca9be7
commit 28fac4d700
12 changed files with 128 additions and 77 deletions

View File

@@ -56,7 +56,7 @@ namespace snmalloc
class MemoryProviderStateMixin : public PAL
{
std::atomic_flag lock = ATOMIC_FLAG_INIT;
size_t bump;
address_t bump;
size_t remaining;
void new_block()
@@ -69,7 +69,7 @@ namespace snmalloc
PAL::template notify_using<NoZero>(r, OS_PAGE_SIZE);
bump = (size_t)r;
bump = address_cast(r);
remaining = size;
}
@@ -109,7 +109,8 @@ namespace snmalloc
// the stack.
if (slab->get_kind() != Decommitted)
{
PAL::notify_not_using(((char*)slab) + OS_PAGE_SIZE, decommit_size);
PAL::notify_not_using(
static_cast<char*>(slab) + OS_PAGE_SIZE, decommit_size);
}
// Once we've removed these from the stack, there will be no
// concurrent accesses and removal should have established a
@@ -159,16 +160,16 @@ namespace snmalloc
new_block();
}
p = (void*)bump;
p = pointer_cast<void>(bump);
bump += size;
remaining -= size;
}
auto page_start = bits::align_down((size_t)p, OS_PAGE_SIZE);
auto page_end = bits::align_up((size_t)p + size, OS_PAGE_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);
PAL::template notify_using<NoZero>(
(void*)page_start, page_end - page_start);
pointer_cast<void>(page_start), page_end - page_start);
return new (p) T(std::forward<Args...>(args)...);
}
@@ -218,17 +219,16 @@ namespace snmalloc
void* p = PAL::template reserve<committed>(&request);
*size = request;
uintptr_t p0 = (uintptr_t)p;
uintptr_t start = bits::align_up(p0, align);
auto p0 = address_cast(p);
auto start = bits::align_up(p0, align);
if (start > p0)
{
uintptr_t end = bits::align_down(p0 + request, align);
*size = end - start;
PAL::notify_not_using(p, start - p0);
PAL::notify_not_using(
reinterpret_cast<void*>(end), (p0 + request) - end);
p = reinterpret_cast<void*>(start);
PAL::notify_not_using(pointer_cast<void>(end), (p0 + request) - end);
p = pointer_cast<void>(start);
}
return p;
}
@@ -295,16 +295,16 @@ namespace snmalloc
template<AllowReserve allow_reserve>
bool reserve_memory(size_t need, size_t add)
{
if (((size_t)reserved_start + need) > (size_t)reserved_end)
if ((address_cast(reserved_start) + need) > address_cast(reserved_end))
{
if constexpr (allow_reserve == YesReserve)
{
stats.segment_create();
reserved_start =
memory_provider.template reserve<false>(&add, SUPERSLAB_SIZE);
reserved_end = (void*)((size_t)reserved_start + add);
reserved_start =
(void*)bits::align_up((size_t)reserved_start, SUPERSLAB_SIZE);
reserved_end = pointer_offset(reserved_start, add);
reserved_start = pointer_cast<void>(
bits::align_up(address_cast(reserved_start), SUPERSLAB_SIZE));
if (add < need)
return false;
@@ -341,8 +341,8 @@ namespace snmalloc
if (!reserve_memory<allow_reserve>(rsize, add))
return nullptr;
p = (void*)reserved_start;
reserved_start = (void*)((size_t)p + rsize);
p = reserved_start;
reserved_start = pointer_offset(p, rsize);
// All memory is zeroed since it comes from reserved space.
memory_provider.template notify_using<NoZero>(p, size);
@@ -362,7 +362,7 @@ namespace snmalloc
// Passing zero_mem ensures the PAL provides zeroed pages if
// required.
memory_provider.template notify_using<zero_mem>(
(void*)((size_t)p + OS_PAGE_SIZE),
pointer_offset(p, OS_PAGE_SIZE),
bits::align_up(size, OS_PAGE_SIZE) - OS_PAGE_SIZE);
}
else
@@ -382,7 +382,7 @@ namespace snmalloc
// Notify we are using the rest of the allocation.
// Passing zero_mem ensures the PAL provides zeroed pages if required.
memory_provider.template notify_using<zero_mem>(
(void*)((size_t)p + OS_PAGE_SIZE),
pointer_offset(p, OS_PAGE_SIZE),
bits::align_up(size, OS_PAGE_SIZE) - OS_PAGE_SIZE);
}
else