Tweaks to end bounds checking.

Introduce a `OnePastEnd` option for the pointer immediately after the
end of the allocation.  This simplifies some of the logic in callers,
where they wants to say 'is base + length safe to use?'.

Also restructure some of the other logic somewhat.
This commit is contained in:
David Chisnall
2019-02-15 11:09:05 +00:00
committed by David Chisnall
parent 9a6b0aef1f
commit c47eed1922
2 changed files with 24 additions and 10 deletions

View File

@@ -27,8 +27,19 @@ namespace snmalloc
{
enum Boundary
{
/**
* The location of the first byte of this allocation.
*/
Start,
End
/**
* The location of the last byte of the allocation.
*/
End,
/**
* The location one past the end of the allocation. This is mostly useful
* for bounds checking, where anything less than this value is safe.
*/
OnePastEnd
};
enum PageMapSuperslabKind
@@ -414,7 +425,7 @@ namespace snmalloc
Metaslab& meta = super->get_meta(slab);
uint8_t sc = meta.sizeclass;
size_t slab_end = (size_t)slab + SLAB_SIZE - 1;
size_t slab_end = (size_t)slab + SLAB_SIZE;
return external_pointer<location>(p, sc, slab_end);
}
@@ -423,7 +434,7 @@ namespace snmalloc
Mediumslab* slab = (Mediumslab*)super;
uint8_t sc = slab->get_sizeclass();
size_t slab_end = (size_t)slab + SUPERSLAB_SIZE - 1;
size_t slab_end = (size_t)slab + SUPERSLAB_SIZE;
return external_pointer<location>(p, sc, slab_end);
}
@@ -439,7 +450,7 @@ namespace snmalloc
if (size == 0)
{
if (location == End)
if constexpr ((location == End) || (location == OnePastEnd))
// We don't know the End, so return MAX_PTR
return (void*)-1;
else
@@ -448,10 +459,12 @@ namespace snmalloc
}
// This is a large alloc, mask off to the slab size.
if (location == Start)
if constexpr (location == Start)
return (void*)ss;
else
else if constexpr (location == End)
return (void*)((size_t)ss + (1ULL << size) - 1ULL);
else
return (void*)((size_t)ss + (1ULL << size));
#endif
}
@@ -688,9 +701,10 @@ namespace snmalloc
static void* external_pointer(void* p, uint8_t sizeclass, size_t end_point)
{
size_t rsize = sizeclass_to_size(sizeclass);
size_t end_point_correction =
location == End ? end_point : end_point - rsize + 1;
size_t offset_from_end = end_point - (size_t)p;
size_t end_point_correction = location == End ?
(end_point - 1) :
(location == OnePastEnd ? end_point : (end_point - rsize));
size_t offset_from_end = (end_point - 1) - (size_t)p;
size_t end_to_end = round_by_sizeclass(rsize, offset_from_end);
return (void*)(end_point_correction - end_to_end);
}

View File

@@ -17,7 +17,7 @@ extern "C"
{
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(__malloc_end_pointer)(void* ptr)
{
return Alloc::external_pointer<End>(ptr);
return Alloc::external_pointer<OnePastEnd>(ptr);
}
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(malloc)(size_t size)