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.
This commit is contained in:
Matthew Parkinson
2022-04-11 11:38:43 +01:00
committed by Matthew Parkinson
parent f0361f8c01
commit 43f5f33913
4 changed files with 19 additions and 31 deletions

View File

@@ -108,15 +108,13 @@ namespace snmalloc
#else
// Set up source of memory
using P = PalRange<DefaultPal>;
using Base = std::
conditional_t<fixed_range, EmptyRange, PagemapRegisterRange<Pagemap, P>>;
using Base = std::conditional_t<
fixed_range,
EmptyRange,
PagemapRegisterRange<Pagemap, P, CONSOLIDATE_PAL_ALLOCS>>;
// Global range of memory
using StatsR = StatsRange<LargeBuddyRange<
Base,
24,
bits::BITS - 1,
Pagemap,
CONSOLIDATE_PAL_ALLOCS>>;
using StatsR =
StatsRange<LargeBuddyRange<Base, 24, bits::BITS - 1, Pagemap>>;
using GlobalR = GlobalRange<StatsR>;
# ifdef SNMALLOC_META_PROTECTED

View File

@@ -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<void> base, size_t length)
{
range_to_pow_2_blocks<MIN_CHUNK_BITS>(
base,
length,
[this](capptr::Chunk<void> 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<void> base, size_t align, bool) {
auto overflow = capptr::Chunk<void>(reinterpret_cast<void*>(
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);

View File

@@ -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;
}
};

View File

@@ -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);
}
/**