From 43f5f33913d03de4d9602b7e07b0b0666f564e98 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Mon, 11 Apr 2022 11:38:43 +0100 Subject: [PATCH] Fix missing consolidation marker During creation of large allocation the code was not setting the consolidation bit. This meant that Windows would crash for certain patterns for large allocations. --- src/snmalloc/backend/backend.h | 14 +++++------ .../backend_helpers/largebuddyrange.h | 23 ++----------------- .../backend_helpers/pagemapregisterrange.h | 10 +++++++- src/snmalloc/mem/metadata.h | 3 ++- 4 files changed, 19 insertions(+), 31 deletions(-) diff --git a/src/snmalloc/backend/backend.h b/src/snmalloc/backend/backend.h index cbff62b..d9a2d23 100644 --- a/src/snmalloc/backend/backend.h +++ b/src/snmalloc/backend/backend.h @@ -108,15 +108,13 @@ namespace snmalloc #else // Set up source of memory using P = PalRange; - using Base = std:: - conditional_t>; + using Base = std::conditional_t< + fixed_range, + EmptyRange, + PagemapRegisterRange>; // Global range of memory - using StatsR = StatsRange>; + using StatsR = + StatsRange>; using GlobalR = GlobalRange; # ifdef SNMALLOC_META_PROTECTED diff --git a/src/snmalloc/backend_helpers/largebuddyrange.h b/src/snmalloc/backend_helpers/largebuddyrange.h index 3248df1..6a7bd24 100644 --- a/src/snmalloc/backend_helpers/largebuddyrange.h +++ b/src/snmalloc/backend_helpers/largebuddyrange.h @@ -169,8 +169,7 @@ namespace snmalloc typename ParentRange, size_t REFILL_SIZE_BITS, size_t MAX_SIZE_BITS, - SNMALLOC_CONCEPT(ConceptBuddyRangeMeta) Pagemap, - bool Consolidate = true> + SNMALLOC_CONCEPT(ConceptBuddyRangeMeta) Pagemap> class LargeBuddyRange { ParentRange parent{}; @@ -218,24 +217,7 @@ namespace snmalloc void add_range(capptr::Chunk base, size_t length) { range_to_pow_2_blocks( - base, - length, - [this](capptr::Chunk base, size_t align, bool first) { - if constexpr (!Consolidate) - { - // Tag first entry so we don't consolidate it. - if (first) - { - auto& entry = Pagemap::get_metaentry_mut(address_cast(base)); - entry.claim_for_backend(); - entry.set_boundary(); - } - } - else - { - UNUSED(first); - } - + base, length, [this](capptr::Chunk base, size_t align, bool) { auto overflow = capptr::Chunk(reinterpret_cast( buddy_large.add_block(base.unsafe_uintptr(), align))); @@ -247,7 +229,6 @@ namespace snmalloc { if (ParentRange::Aligned) { - // TODO have to add consolidation blocker for these cases. if (size >= REFILL_SIZE) { return parent.alloc_range(size); diff --git a/src/snmalloc/backend_helpers/pagemapregisterrange.h b/src/snmalloc/backend_helpers/pagemapregisterrange.h index 17ba6e1..de60dd8 100644 --- a/src/snmalloc/backend_helpers/pagemapregisterrange.h +++ b/src/snmalloc/backend_helpers/pagemapregisterrange.h @@ -6,7 +6,8 @@ namespace snmalloc { template< SNMALLOC_CONCEPT(ConceptBackendMetaRange) Pagemap, - typename ParentRange> + typename ParentRange, + bool CanConsolidate = true> class PagemapRegisterRange { ParentRange state{}; @@ -25,6 +26,13 @@ namespace snmalloc if (base != nullptr) Pagemap::register_range(address_cast(base), size); + if (!CanConsolidate) + { + // Mark start of allocation in pagemap. + auto& entry = Pagemap::get_metaentry_mut(address_cast(base)); + entry.set_boundary(); + } + return base; } }; diff --git a/src/snmalloc/mem/metadata.h b/src/snmalloc/mem/metadata.h index ac56f0a..ca90ec1 100644 --- a/src/snmalloc/mem/metadata.h +++ b/src/snmalloc/mem/metadata.h @@ -129,7 +129,8 @@ namespace snmalloc */ [[nodiscard]] bool is_unowned() const { - return (meta == 0) && (remote_and_sizeclass == 0); + return ((meta == 0) || (meta == META_BOUNDARY_BIT)) && + (remote_and_sizeclass == 0); } /**