diff --git a/src/mem/corealloc.h b/src/mem/corealloc.h index c708127..87c6aa7 100644 --- a/src/mem/corealloc.h +++ b/src/mem/corealloc.h @@ -304,7 +304,7 @@ namespace snmalloc while (curr != nullptr) { auto nxt = curr->get_next(); - auto meta = reinterpret_cast(curr); + auto meta = Metaslab::from_link(curr); if (meta->needed() == 0) { prev->pop(); @@ -348,7 +348,7 @@ namespace snmalloc // Wake slab up. meta->set_not_sleeping(sizeclass); - alloc_classes[sizeclass].insert(meta); + alloc_classes[sizeclass].insert(&meta->link); alloc_classes[sizeclass].length++; #ifdef SNMALLOC_TRACING @@ -593,7 +593,7 @@ namespace snmalloc auto& sl = alloc_classes[sizeclass]; if (likely(!(sl.is_empty()))) { - auto meta = reinterpret_cast(sl.pop()); + auto meta = Metaslab::from_link(sl.pop()); // Drop length of sl, and empty count if it was empty. alloc_classes[sizeclass].length--; if (meta->needed() == 0) @@ -736,17 +736,18 @@ namespace snmalloc auto test = [&result](auto& queue) { if (!queue.is_empty()) { - auto curr = reinterpret_cast(queue.get_next()); + auto curr = queue.get_next(); while (curr != nullptr) { - if (curr->needed() != 0) + auto currmeta = Metaslab::from_link(curr); + if (currmeta->needed() != 0) { if (result != nullptr) *result = false; else error("debug_is_empty: found non-empty allocator"); } - curr = reinterpret_cast(curr->get_next()); + curr = currmeta->link.get_next(); } } }; diff --git a/src/mem/metaslab.h b/src/mem/metaslab.h index 41f73b1..56499ec 100644 --- a/src/mem/metaslab.h +++ b/src/mem/metaslab.h @@ -16,10 +16,19 @@ namespace snmalloc // The Metaslab represent the status of a single slab. // This can be either a short or a standard slab. - class alignas(CACHELINE_SIZE) Metaslab : public SlabLink + class alignas(CACHELINE_SIZE) Metaslab { public: - constexpr Metaslab() : SlabLink(true) {} + // TODO: Annotate with CHERI subobject unbound for pointer arithmetic + SlabLink link; + + constexpr Metaslab() : link(true) {} + + /** + * Metaslab::link points at another link field. To get the actual Metaslab, + * use this encapsulation of the container-of logic. + */ + static Metaslab* from_link(SlabLink* ptr); /** * Data-structure for building the free list for this slab. @@ -160,6 +169,12 @@ namespace snmalloc } }; + Metaslab* Metaslab::from_link(SlabLink* lptr) + { + return pointer_offset_signed( + lptr, -static_cast(offsetof(Metaslab, link))); + } + struct RemoteAllocator; /**