AAL: introduce capptr_size_round, use w/ metadata
This commit is contained in:
committed by
Nathaniel Filardo
parent
2ee522cd22
commit
50c7500536
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user