diff --git a/src/backend/backend.h b/src/backend/backend.h index 36328f4..1cc9c0b 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -87,6 +87,8 @@ namespace snmalloc return {p, nullptr}; } + meta->meta_common.chunk = p; + MetaEntry t(meta, remote, sizeclass); Pagemap::set_metaentry(local_state, address_cast(p), size, t); return {p, meta}; diff --git a/src/mem/corealloc.h b/src/mem/corealloc.h index 98c80a8..b0fc28e 100644 --- a/src/mem/corealloc.h +++ b/src/mem/corealloc.h @@ -321,13 +321,16 @@ namespace snmalloc // have the whole chunk. auto start_of_slab = pointer_align_down( p, snmalloc::sizeclass_to_slab_size(sizeclass)); - // TODO Add bounds correctly here - chunk_record->meta_common.chunk = - capptr::Chunk(start_of_slab.unsafe_ptr()); + + SNMALLOC_ASSERT( + address_cast(start_of_slab) == + address_cast(chunk_record->meta_common.chunk)); #ifdef SNMALLOC_TRACING std::cout << "Slab " << start_of_slab.unsafe_ptr() << " is unused, Object sizeclass " << sizeclass << std::endl; +#else + UNUSED(start_of_slab); #endif return chunk_record; } diff --git a/src/mem/localalloc.h b/src/mem/localalloc.h index 1e62123..db4bbfa 100644 --- a/src/mem/localalloc.h +++ b/src/mem/localalloc.h @@ -536,15 +536,10 @@ namespace snmalloc ChunkRecord* slab_record = reinterpret_cast(entry.get_metaslab()); - /* - * StrictProvenance TODO: this is a subversive amplification. p_tame is - * tame but Alloc-bounded, but we're coercing it to Chunk-bounded. We - * should, instead, not be storing ->chunk here, but should be keeping - * a CapPtr to this region internally even while it's - * allocated. - */ - slab_record->meta_common.chunk = - capptr::Chunk(p_tame.unsafe_ptr()); + + SNMALLOC_ASSERT( + address_cast(slab_record->meta_common.chunk) == address_cast(p_tame)); + check_init( []( CoreAlloc* core_alloc, diff --git a/src/mem/metaslab.h b/src/mem/metaslab.h index 997439b..1057c14 100644 --- a/src/mem/metaslab.h +++ b/src/mem/metaslab.h @@ -9,6 +9,13 @@ namespace snmalloc { + /** + * A guaranteed type-stable sub-structure of all metadata referenced by the + * Pagemap. Use-specific structures (Metaslab, ChunkRecord) are expected to + * have this at offset zero so that, even in the face of concurrent mutation + * and reuse of the memory backing that metadata, the types of these fields + * remain fixed. + */ struct MetaCommon { capptr::Chunk chunk; @@ -18,6 +25,8 @@ namespace snmalloc class alignas(CACHELINE_SIZE) Metaslab { public: + MetaCommon meta_common; + // Used to link metaslabs together in various other data-structures. Metaslab* next{nullptr}; @@ -186,6 +195,11 @@ namespace snmalloc } }; + static_assert(std::is_standard_layout_v); + static_assert( + offsetof(Metaslab, meta_common) == 0, + "ChunkRecord and Metaslab must share a common prefix"); + /** * Entry stored in the pagemap. */