0-length arrays in Buddy ranges (#672)

* backend_helpers: introduce NopRange

* Fix to Buddy MIN == MAX case

This fixes the 0-length arrays discussed (and made into assertion failures) in
the next commit.  This works because the Buddy's `MIN_SIZE_BITS` is instantiated
at `MIN_CHUNK_BITS`, and so we ensure that we instantiate the LargeBuddyRange
only with `max_page_chunk_size_bits` above `MIN_CHUNK_BITS`.

* Buddy range: assert that MAX > MIN

Now that the case leading to several 0-sized arrays in Buddy ranges, that then
cause gcc's -Warray-bounds to trip, has been removed, add a static assert so
that we can catch this with better error messages next time.
This commit is contained in:
Nathaniel Filardo 2024-09-09 12:25:51 -04:00 коммит произвёл GitHub
Родитель fcad15456b
Коммит 7fbca11527
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 47 добавлений и 5 удалений

Просмотреть файл

@ -75,11 +75,14 @@ namespace snmalloc
CommitRange<PAL>,
// In case of huge pages, we don't want to give each thread its own huge
// page, so commit in the global range.
LargeBuddyRange<
max_page_chunk_size_bits,
max_page_chunk_size_bits,
Pagemap,
page_size_bits>,
std::conditional_t<
(max_page_chunk_size_bits > MIN_CHUNK_BITS),
LargeBuddyRange<
max_page_chunk_size_bits,
max_page_chunk_size_bits,
Pagemap,
page_size_bits>,
NopRange>,
LogRange<4>,
GlobalRange,
StatsRange>;

Просмотреть файл

@ -9,6 +9,7 @@
#include "indirectrange.h"
#include "largebuddyrange.h"
#include "logrange.h"
#include "noprange.h"
#include "pagemap.h"
#include "pagemapregisterrange.h"
#include "palrange.h"

Просмотреть файл

@ -15,6 +15,8 @@ namespace snmalloc
template<typename Rep, size_t MIN_SIZE_BITS, size_t MAX_SIZE_BITS>
class Buddy
{
static_assert(MAX_SIZE_BITS > MIN_SIZE_BITS);
struct Entry
{
typename Rep::Contents cache[3];

Просмотреть файл

@ -0,0 +1,36 @@
#pragma once
#include "range_helpers.h"
namespace snmalloc
{
struct NopRange
{
template<typename ParentRange>
class Type : public ContainsParent<ParentRange>
{
using ContainsParent<ParentRange>::parent;
public:
static constexpr bool Aligned = ParentRange::Aligned;
static constexpr bool ConcurrencySafe = ParentRange::ConcurrencySafe;
using ChunkBounds = typename ParentRange::ChunkBounds;
static_assert(
ChunkBounds::address_space_control ==
capptr::dimension::AddressSpaceControl::Full);
constexpr Type() = default;
CapPtr<void, ChunkBounds> alloc_range(size_t size)
{
return parent.alloc_range(size);
}
void dealloc_range(CapPtr<void, ChunkBounds> base, size_t size)
{
parent.dealloc_range(base, size);
}
};
};
} // namespace snmalloc