AAL: introduce capptr_size_round, use w/ metadata

This commit is contained in:
Nathaniel Wesley Filardo
2022-09-13 16:24:21 +01:00
committed by Nathaniel Filardo
parent 2ee522cd22
commit 50c7500536
4 changed files with 55 additions and 0 deletions

View File

@@ -215,6 +215,11 @@ namespace snmalloc
return CapPtr<T, BOut>::unsafe_from(
a.template as_static<T>().unsafe_ptr());
}
static SNMALLOC_FAST_PATH size_t capptr_size_round(size_t sz) noexcept
{
return sz;
}
};
} // namespace snmalloc

View File

@@ -88,5 +88,29 @@ namespace snmalloc
void* pb = __builtin_cheri_bounds_set_exact(a.unsafe_ptr(), size);
return CapPtr<T, BOut>::unsafe_from(static_cast<T*>(pb));
}
static SNMALLOC_FAST_PATH size_t capptr_size_round(size_t sz) noexcept
{
/*
* Round up sz to the next representable value for the target
* architecture's choice of CHERI Concentrate T/B mantissa width.
*
* On Morello specifically, this intrinsic will (soon, as of this text
* being written) expand to a multi-instruction sequence to work around a
* bug in which sz values satisfying $\exists_E sz = ((1 << 12) - 1) <<
* (E + 3)$ are incorrectly increased. If for some reason this ends up
* being at all hot, there will also be a
* __builtin_morello_round_representable_length_inexact, which will just
* return too big of a size for those values (by rounding up to $1 << (E
* + 15)$). While technically incorrect, this behavior is probably fine
* for snmalloc: we already slot metadata allocations into NAPOT holes
* and then return any unused space at the top, so the over-reach would,
* at the worst, just prevent said return, and our sizeclasses never run
* into this issue. That is, we're clear to use the __builtin_morello_*
* intrinsic if the multi-instruction sequence proves slow. See
* https://git.morello-project.org/morello/llvm-project/-/merge_requests/199
*/
return __builtin_cheri_round_representable_length(sz);
}
};
} // namespace snmalloc

View File

@@ -59,6 +59,28 @@ namespace snmalloc
AAL::template capptr_bound<void, capptr::bounds::Chunk>(auth, sz)
}
noexcept->ConceptSame<capptr::Chunk<void>>;
/**
* Round up an allocation size to a size this architecture can represent.
* While there may also, in general, be alignment requirements for
* representability, in snmalloc so far we have not had reason to consider
* these explicitly: when we use our...
*
* - sizeclass machinery (for user-facing data), we assume that all
* sizeclasses describe architecturally representable aligned-and-sized
* regions
*
* - Range machinery (for internal meta-data), we always choose NAPOT
* regions big enough for the requested size (returning space above the
* allocation within such regions for use as smaller NAPOT regions).
*
* That is, capptr_size_round is not needed on the user-facing fast paths,
* merely internally for bootstrap and metadata management.
*/
{
AAL::capptr_size_round(sz)
}
noexcept->ConceptSame<size_t>;
};
template<typename AAL>

View File

@@ -43,6 +43,10 @@ namespace snmalloc
alloc_meta_data(LocalState* local_state, size_t size)
{
capptr::Arena<void> p;
// Meta-data does not use our sizeclass machinery, so have Aal round up
size = Aal::capptr_size_round(size);
if (local_state != nullptr)
{
p = local_state->get_meta_range().alloc_range_with_leftover(size);