diff --git a/src/ds/address.h b/src/ds/address.h index 75c2e09..66e0fcd 100644 --- a/src/ds/address.h +++ b/src/ds/address.h @@ -87,4 +87,16 @@ namespace snmalloc return pointer_cast(bits::align_up(address_cast(p), alignment)); #endif } + + /** + * Compute the difference in pointers in units of char. base is + * expected to point to the base of some (sub)allocation into which cursor + * points; would-be negative answers trip an assertion in debug builds. + */ + inline size_t pointer_diff(void* base, void* cursor) + { + assert(cursor >= base); + return static_cast( + static_cast(cursor) - static_cast(base)); + } } // namespace snmalloc diff --git a/src/mem/alloc.h b/src/mem/alloc.h index c5732ce..1260e9c 100644 --- a/src/mem/alloc.h +++ b/src/mem/alloc.h @@ -1193,7 +1193,7 @@ namespace snmalloc #ifdef CHECK_CLIENT if (!is_multiple_of_sizeclass( sizeclass_to_size(sizeclass), - address_cast(slab) + SUPERSLAB_SIZE - address_cast(p))) + pointer_diff(p, pointer_offset(slab, SUPERSLAB_SIZE)))) { error("Not deallocating start of an object"); } diff --git a/src/mem/mediumslab.h b/src/mem/mediumslab.h index 826f0fa..835c05c 100644 --- a/src/mem/mediumslab.h +++ b/src/mem/mediumslab.h @@ -125,8 +125,7 @@ namespace snmalloc uint16_t pointer_to_index(void* p) { // Get the offset from the slab for a memory location. - return static_cast( - ((address_cast(p) - address_cast(this))) >> 8); + return static_cast(pointer_diff(this, p) >> 8); } }; } // namespace snmalloc diff --git a/src/mem/slab.h b/src/mem/slab.h index 4953a38..7d0db15 100644 --- a/src/mem/slab.h +++ b/src/mem/slab.h @@ -16,7 +16,7 @@ namespace snmalloc uint16_t pointer_to_index(void* p) { // Get the offset from the slab for a memory location. - return static_cast(address_cast(p) - address_cast(this)); + return static_cast(pointer_diff(this, p)); } public: @@ -144,7 +144,7 @@ namespace snmalloc Metaslab& meta = super->get_meta(this); return is_multiple_of_sizeclass( sizeclass_to_size(meta.sizeclass), - address_cast(this) + SLAB_SIZE - address_cast(p)); + pointer_diff(p, pointer_offset(this, SLAB_SIZE))); } // Returns true, if it deallocation can proceed without changing any status diff --git a/src/mem/superslab.h b/src/mem/superslab.h index 9a9d13c..70a86d1 100644 --- a/src/mem/superslab.h +++ b/src/mem/superslab.h @@ -44,9 +44,9 @@ namespace snmalloc // Used size_t as results in better code in MSVC size_t slab_to_index(Slab* slab) { - auto res = ((address_cast(slab) - address_cast(this)) >> SLAB_BITS); - assert(res == (uint8_t)res); - return res; + auto res = (pointer_diff(this, slab) >> SLAB_BITS); + assert(res == static_cast(res)); + return static_cast(res); } public: