зеркало из https://github.com/microsoft/snmalloc.git
Alter PAGE_SIZE usage (#534)
* Sanity check on parameters to large buddy. * Check commit occurs at page granularity * Alter PAGE_SIZE usage Using PAGE_SIZE as the minimum size of the CHUNK means that if this is configured to 2MiB, then there is a gap between MAX_SMALL_SIZECLASS_SIZE, and MIN_CHUNK_SIZE, and thus we can't represent certain sizes,
This commit is contained in:
Родитель
03c9da6aa4
Коммит
53d9fd2abe
|
@ -40,6 +40,12 @@ namespace snmalloc
|
||||||
LogRange<2>,
|
LogRange<2>,
|
||||||
GlobalRange<>>;
|
GlobalRange<>>;
|
||||||
|
|
||||||
|
static constexpr size_t page_size_bits =
|
||||||
|
bits::next_pow2_bits_const(PAL::page_size);
|
||||||
|
|
||||||
|
static constexpr size_t max_page_chunk_size_bits =
|
||||||
|
bits::max(page_size_bits, MIN_CHUNK_BITS);
|
||||||
|
|
||||||
// Central source of object-range, does not pass back to GlobalR as
|
// Central source of object-range, does not pass back to GlobalR as
|
||||||
// that would allow flows from Objects to Meta-data, and thus UAF
|
// that would allow flows from Objects to Meta-data, and thus UAF
|
||||||
// would be able to corrupt meta-data.
|
// would be able to corrupt meta-data.
|
||||||
|
@ -61,16 +67,31 @@ namespace snmalloc
|
||||||
GlobalR,
|
GlobalR,
|
||||||
SubRange<PAL, SubRangeRatioBits>, // Use SubRange to introduce guard
|
SubRange<PAL, SubRangeRatioBits>, // Use SubRange to introduce guard
|
||||||
// pages.
|
// pages.
|
||||||
LargeBuddyRange<GlobalCacheSizeBits, bits::BITS - 1, Pagemap>,
|
LargeBuddyRange<
|
||||||
|
GlobalCacheSizeBits,
|
||||||
|
bits::BITS - 1,
|
||||||
|
Pagemap,
|
||||||
|
page_size_bits>,
|
||||||
|
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>,
|
||||||
LogRange<4>,
|
LogRange<4>,
|
||||||
GlobalRange<>,
|
GlobalRange<>,
|
||||||
CommitRange<PAL>,
|
|
||||||
StatsRange<>>;
|
StatsRange<>>;
|
||||||
|
|
||||||
// Local caching of object range
|
// Local caching of object range
|
||||||
using ObjectRange = Pipe<
|
using ObjectRange = Pipe<
|
||||||
CentralObjectRange,
|
CentralObjectRange,
|
||||||
LargeBuddyRange<LocalCacheSizeBits, LocalCacheSizeBits, Pagemap>,
|
LargeBuddyRange<
|
||||||
|
LocalCacheSizeBits,
|
||||||
|
LocalCacheSizeBits,
|
||||||
|
Pagemap,
|
||||||
|
page_size_bits>,
|
||||||
LogRange<5>>;
|
LogRange<5>>;
|
||||||
|
|
||||||
// Local caching of meta-data range
|
// Local caching of meta-data range
|
||||||
|
|
|
@ -41,11 +41,18 @@ namespace snmalloc
|
||||||
using Stats = Pipe<GlobalR, CommitRange<PAL>, StatsRange<>>;
|
using Stats = Pipe<GlobalR, CommitRange<PAL>, StatsRange<>>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr size_t page_size_bits =
|
||||||
|
bits::next_pow2_bits_const(PAL::page_size);
|
||||||
|
|
||||||
// Source for object allocations and metadata
|
// Source for object allocations and metadata
|
||||||
// Use buddy allocators to cache locally.
|
// Use buddy allocators to cache locally.
|
||||||
using ObjectRange = Pipe<
|
using ObjectRange = Pipe<
|
||||||
Stats,
|
Stats,
|
||||||
LargeBuddyRange<LocalCacheSizeBits, LocalCacheSizeBits, Pagemap>,
|
LargeBuddyRange<
|
||||||
|
LocalCacheSizeBits,
|
||||||
|
LocalCacheSizeBits,
|
||||||
|
Pagemap,
|
||||||
|
page_size_bits>,
|
||||||
SmallBuddyRange<>>;
|
SmallBuddyRange<>>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -25,6 +25,11 @@ namespace snmalloc
|
||||||
|
|
||||||
capptr::Chunk<void> alloc_range(size_t size)
|
capptr::Chunk<void> alloc_range(size_t size)
|
||||||
{
|
{
|
||||||
|
SNMALLOC_ASSERT_MSG(
|
||||||
|
(size % PAL::page_size) == 0,
|
||||||
|
"size ({}) must be a multiple of page size ({})",
|
||||||
|
size,
|
||||||
|
PAL::page_size);
|
||||||
auto range = parent.alloc_range(size);
|
auto range = parent.alloc_range(size);
|
||||||
if (range != nullptr)
|
if (range != nullptr)
|
||||||
PAL::template notify_using<NoZero>(range.unsafe_ptr(), size);
|
PAL::template notify_using<NoZero>(range.unsafe_ptr(), size);
|
||||||
|
@ -33,6 +38,11 @@ namespace snmalloc
|
||||||
|
|
||||||
void dealloc_range(capptr::Chunk<void> base, size_t size)
|
void dealloc_range(capptr::Chunk<void> base, size_t size)
|
||||||
{
|
{
|
||||||
|
SNMALLOC_ASSERT_MSG(
|
||||||
|
(size % PAL::page_size) == 0,
|
||||||
|
"size ({}) must be a multiple of page size ({})",
|
||||||
|
size,
|
||||||
|
PAL::page_size);
|
||||||
PAL::notify_not_using(base.unsafe_ptr(), size);
|
PAL::notify_not_using(base.unsafe_ptr(), size);
|
||||||
parent.dealloc_range(base, size);
|
parent.dealloc_range(base, size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,6 +193,12 @@ namespace snmalloc
|
||||||
{
|
{
|
||||||
using ContainsParent<ParentRange>::parent;
|
using ContainsParent<ParentRange>::parent;
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
REFILL_SIZE_BITS <= MAX_SIZE_BITS, "REFILL_SIZE_BITS > MAX_SIZE_BITS");
|
||||||
|
static_assert(
|
||||||
|
MIN_REFILL_SIZE_BITS <= REFILL_SIZE_BITS,
|
||||||
|
"MIN_REFILL_SIZE_BITS > REFILL_SIZE_BITS");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum size of a refill
|
* Maximum size of a refill
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,8 +26,7 @@ namespace snmalloc
|
||||||
static constexpr size_t MIN_ALLOC_BITS = bits::ctz_const(MIN_ALLOC_SIZE);
|
static constexpr size_t MIN_ALLOC_BITS = bits::ctz_const(MIN_ALLOC_SIZE);
|
||||||
|
|
||||||
// Minimum slab size.
|
// Minimum slab size.
|
||||||
static constexpr size_t MIN_CHUNK_BITS = bits::max(
|
static constexpr size_t MIN_CHUNK_BITS = static_cast<size_t>(14);
|
||||||
static_cast<size_t>(14), bits::next_pow2_bits_const(OS_PAGE_SIZE));
|
|
||||||
static constexpr size_t MIN_CHUNK_SIZE = bits::one_at_bit(MIN_CHUNK_BITS);
|
static constexpr size_t MIN_CHUNK_SIZE = bits::one_at_bit(MIN_CHUNK_BITS);
|
||||||
|
|
||||||
// Minimum number of objects on a slab
|
// Minimum number of objects on a slab
|
||||||
|
@ -42,6 +41,10 @@ namespace snmalloc
|
||||||
static constexpr size_t MAX_SMALL_SIZECLASS_SIZE =
|
static constexpr size_t MAX_SMALL_SIZECLASS_SIZE =
|
||||||
bits::one_at_bit(MAX_SMALL_SIZECLASS_BITS);
|
bits::one_at_bit(MAX_SMALL_SIZECLASS_BITS);
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
MAX_SMALL_SIZECLASS_SIZE >= MIN_CHUNK_SIZE,
|
||||||
|
"Large sizes need to be representable by as a multiple of MIN_CHUNK_SIZE");
|
||||||
|
|
||||||
// Number of slots for remote deallocation.
|
// Number of slots for remote deallocation.
|
||||||
static constexpr size_t REMOTE_SLOT_BITS = 8;
|
static constexpr size_t REMOTE_SLOT_BITS = 8;
|
||||||
static constexpr size_t REMOTE_SLOTS = 1 << REMOTE_SLOT_BITS;
|
static constexpr size_t REMOTE_SLOTS = 1 << REMOTE_SLOT_BITS;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче