зеркало из 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>,
|
||||
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
|
||||
// that would allow flows from Objects to Meta-data, and thus UAF
|
||||
// would be able to corrupt meta-data.
|
||||
|
@ -61,16 +67,31 @@ namespace snmalloc
|
|||
GlobalR,
|
||||
SubRange<PAL, SubRangeRatioBits>, // Use SubRange to introduce guard
|
||||
// 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>,
|
||||
GlobalRange<>,
|
||||
CommitRange<PAL>,
|
||||
StatsRange<>>;
|
||||
|
||||
// Local caching of object range
|
||||
using ObjectRange = Pipe<
|
||||
CentralObjectRange,
|
||||
LargeBuddyRange<LocalCacheSizeBits, LocalCacheSizeBits, Pagemap>,
|
||||
LargeBuddyRange<
|
||||
LocalCacheSizeBits,
|
||||
LocalCacheSizeBits,
|
||||
Pagemap,
|
||||
page_size_bits>,
|
||||
LogRange<5>>;
|
||||
|
||||
// Local caching of meta-data range
|
||||
|
|
|
@ -41,11 +41,18 @@ namespace snmalloc
|
|||
using Stats = Pipe<GlobalR, CommitRange<PAL>, StatsRange<>>;
|
||||
|
||||
private:
|
||||
static constexpr size_t page_size_bits =
|
||||
bits::next_pow2_bits_const(PAL::page_size);
|
||||
|
||||
// Source for object allocations and metadata
|
||||
// Use buddy allocators to cache locally.
|
||||
using ObjectRange = Pipe<
|
||||
Stats,
|
||||
LargeBuddyRange<LocalCacheSizeBits, LocalCacheSizeBits, Pagemap>,
|
||||
LargeBuddyRange<
|
||||
LocalCacheSizeBits,
|
||||
LocalCacheSizeBits,
|
||||
Pagemap,
|
||||
page_size_bits>,
|
||||
SmallBuddyRange<>>;
|
||||
|
||||
public:
|
||||
|
|
|
@ -25,6 +25,11 @@ namespace snmalloc
|
|||
|
||||
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);
|
||||
if (range != nullptr)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
parent.dealloc_range(base, size);
|
||||
}
|
||||
|
|
|
@ -193,6 +193,12 @@ namespace snmalloc
|
|||
{
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -26,8 +26,7 @@ namespace snmalloc
|
|||
static constexpr size_t MIN_ALLOC_BITS = bits::ctz_const(MIN_ALLOC_SIZE);
|
||||
|
||||
// Minimum slab size.
|
||||
static constexpr size_t MIN_CHUNK_BITS = bits::max(
|
||||
static_cast<size_t>(14), bits::next_pow2_bits_const(OS_PAGE_SIZE));
|
||||
static constexpr size_t MIN_CHUNK_BITS = static_cast<size_t>(14);
|
||||
static constexpr size_t MIN_CHUNK_SIZE = bits::one_at_bit(MIN_CHUNK_BITS);
|
||||
|
||||
// Minimum number of objects on a slab
|
||||
|
@ -42,6 +41,10 @@ namespace snmalloc
|
|||
static constexpr size_t MAX_SMALL_SIZECLASS_SIZE =
|
||||
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.
|
||||
static constexpr size_t REMOTE_SLOT_BITS = 8;
|
||||
static constexpr size_t REMOTE_SLOTS = 1 << REMOTE_SLOT_BITS;
|
||||
|
|
Загрузка…
Ссылка в новой задаче