Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use pointers, not addresses, in more places #188

Merged
merged 2 commits into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions src/ds/address.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,6 @@ namespace snmalloc
return reinterpret_cast<address_t>(ptr);
}

/**
* Cast from an address back to a pointer of the specified type. All uses of
* this will eventually need auditing for CHERI compatibility.
*/
template<typename T>
inline T* pointer_cast(address_t address)
{
return reinterpret_cast<T*>(address);
}

/**
* Test if a pointer is aligned to a given size, which must be a power of
* two.
Expand Down Expand Up @@ -81,7 +71,8 @@ namespace snmalloc
#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));
return reinterpret_cast<T*>(
bits::align_down(reinterpret_cast<uintptr_t>(p), alignment));
#endif
}
}
Expand All @@ -102,11 +93,29 @@ namespace snmalloc
#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));
return reinterpret_cast<T*>(
bits::align_up(reinterpret_cast<uintptr_t>(p), alignment));
#endif
}
}

/**
* Align a pointer down to a dynamically specified granularity, which must be
* a power of two.
*/
template<typename T = void>
SNMALLOC_FAST_PATH T* pointer_align_down(void* p, size_t alignment)
{
SNMALLOC_ASSERT(alignment > 0);
SNMALLOC_ASSERT(bits::next_pow2(alignment) == alignment);
#if __has_builtin(__builtin_align_down)
return static_cast<T*>(__builtin_align_down(p, alignment));
#else
return reinterpret_cast<T*>(
bits::align_down(reinterpret_cast<uintptr_t>(p), alignment));
#endif
}

/**
* Align a pointer up to a dynamically specified granularity, which must
* be a power of two.
Expand All @@ -119,7 +128,8 @@ namespace snmalloc
#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));
return reinterpret_cast<T*>(
bits::align_up(reinterpret_cast<uintptr_t>(p), alignment));
#endif
}

Expand Down
41 changes: 18 additions & 23 deletions src/mem/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ namespace snmalloc
}

template<Boundary location = Start>
static address_t external_address(void* p)
static void* external_pointer(void* p)
{
#ifdef USE_MALLOC
error("Unsupported");
Expand Down Expand Up @@ -423,41 +423,36 @@ namespace snmalloc
return external_pointer<location>(p, sc, slab_end);
}

auto ss = address_cast(super);
auto ss = super;

while (size > 64)
{
// This is a large alloc redirect.
ss = ss - (1ULL << (size - 64));
ss = pointer_offset_signed(
ss, -(static_cast<ptrdiff_t>(1) << (size - 64)));
size = ChunkMap::get(ss);
}

if (size == 0)
{
if constexpr ((location == End) || (location == OnePastEnd))
// We don't know the End, so return MAX_PTR
return UINTPTR_MAX;
return pointer_offset<void>(nullptr, UINTPTR_MAX);
else
// We don't know the Start, so return MIN_PTR
return 0;
return nullptr;
}

// This is a large alloc, mask off to the slab size.
if constexpr (location == Start)
return ss;
else if constexpr (location == End)
return (ss + (1ULL << size) - 1ULL);
return pointer_offset(ss, (1ULL << size) - 1ULL);
else
return (ss + (1ULL << size));
return pointer_offset(ss, 1ULL << size);
#endif
}

template<Boundary location = Start>
static void* external_pointer(void* p)
{
return pointer_cast<void>(external_address<location>(p));
}

static size_t alloc_size(const void* p)
{
// This must be called on an external pointer.
Expand Down Expand Up @@ -824,24 +819,24 @@ namespace snmalloc
}

template<Boundary location>
static uintptr_t
static void*
external_pointer(void* p, sizeclass_t sizeclass, void* end_point)
{
size_t rsize = sizeclass_to_size(sizeclass);

void* end_point_correction = location == End ?
(static_cast<uint8_t*>(end_point) - 1) :
(location == OnePastEnd ? end_point :
(static_cast<uint8_t*>(end_point) - rsize));
pointer_offset_signed(end_point, -1) :
(location == OnePastEnd ?
end_point :
pointer_offset_signed(end_point, -static_cast<ptrdiff_t>(rsize)));

ptrdiff_t offset_from_end =
(static_cast<uint8_t*>(end_point) - 1) - static_cast<uint8_t*>(p);
size_t offset_from_end =
pointer_diff(p, pointer_offset_signed(end_point, -1));

size_t end_to_end =
round_by_sizeclass(rsize, static_cast<size_t>(offset_from_end));
size_t end_to_end = round_by_sizeclass(rsize, offset_from_end);

return address_cast<uint8_t>(
static_cast<uint8_t*>(end_point_correction) - end_to_end);
return pointer_offset_signed(
end_point_correction, -static_cast<ptrdiff_t>(end_to_end));
}

void init_message_queue()
Expand Down
26 changes: 12 additions & 14 deletions src/mem/largealloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,9 @@ namespace snmalloc
lazy_decommit_guard.clear();
}

void push_space(address_t start, size_t large_class)
void push_space(void* p, size_t large_class)
{
// All fresh pages so can use "NoZero"
void* p = pointer_cast<void>(start);
if (large_class > 0)
PAL::template notify_using<NoZero>(p, OS_PAGE_SIZE);
else
Expand Down Expand Up @@ -284,24 +283,24 @@ namespace snmalloc
if (p == nullptr)
return nullptr;

address_t p0 = address_cast(p);
address_t start = bits::align_up(p0, align);
address_t p1 = p0 + request;
address_t end = start + size;
void* start = pointer_align_up(p, align);
void* p1 = pointer_offset(p, request);
void* end = pointer_offset(start, size);

for (; end < bits::align_down(p1, align); end += size)
for (; end < pointer_align_down(p1, align);
end = pointer_offset(end, size))
{
push_space(end, large_class);
}

// Put offcuts before alignment into the large stack
address_t offcut_end = start;
address_t offcut_start;
void* offcut_end = start;
void* offcut_start;
for (size_t i = large_class; i > 0;)
{
i--;
size_t offcut_align = bits::one_at_bit(SUPERSLAB_BITS) << i;
offcut_start = bits::align_up(p0, offcut_align);
offcut_start = pointer_align_up(p, offcut_align);
if (offcut_start != offcut_end)
{
push_space(offcut_start, i);
Expand All @@ -315,19 +314,18 @@ namespace snmalloc
{
i--;
auto offcut_align = bits::one_at_bit(SUPERSLAB_BITS) << i;
offcut_end = bits::align_down(p1, offcut_align);
offcut_end = pointer_align_down(p1, offcut_align);
if (offcut_start != offcut_end)
{
push_space(offcut_start, i);
offcut_start = offcut_end;
}
}

void* result = pointer_cast<void>(start);
if (committed)
PAL::template notify_using<NoZero>(result, size);
PAL::template notify_using<NoZero>(start, size);

return result;
return start;
}
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/mem/superslab.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ namespace snmalloc
Slab* alloc_slab(sizeclass_t sizeclass)
{
uint8_t h = head;
Slab* slab = pointer_cast<Slab>(
address_cast(this) + (static_cast<size_t>(h) << SLAB_BITS));
Slab* slab = pointer_offset(
reinterpret_cast<Slab*>(this), (static_cast<size_t>(h) << SLAB_BITS));

uint8_t n = meta[h].next;

Expand Down