Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ if(SNMALLOC_USE_CXX17)
else()
target_compile_features(snmalloc INTERFACE cxx_std_20)
endif()
# https://learn.microsoft.com/en-us/cpp/build/reference/zc-cplusplus
if(MSVC)
target_compile_options(snmalloc INTERFACE "/Zc:__cplusplus")
endif()

# Add header paths.
target_include_directories(snmalloc
Expand Down
2 changes: 1 addition & 1 deletion src/snmalloc/aal/aal.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace snmalloc
{
/*
* Provide a default specification of address_t as uintptr_t for Arch-es
* that support IntegerPointers. Those Arch-es without IntegerPoihnters
* that support IntegerPointers. Those Arch-es without IntegerPointers
* must explicitly give their address_t.
*
* This somewhat obtuse way of spelling the defaulting is necessary so
Expand Down
3 changes: 2 additions & 1 deletion src/snmalloc/backend/globalconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ namespace snmalloc
LocalEntropy entropy;
entropy.init<Pal>();
// Initialise key for remote deallocation lists
RemoteAllocator::key_global = FreeListKey(entropy.get_free_list_key());
entropy.make_free_list_key(RemoteAllocator::key_global);
entropy.make_free_list_key(freelist::Object::key_root);

// Need to randomise pagemap location. If requested and not a
// StrictProvenance architecture, randomize its table's location within
Expand Down
4 changes: 2 additions & 2 deletions src/snmalloc/backend_helpers/largebuddyrange.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ namespace snmalloc
SNMALLOC_ASSERT(size >= MIN_CHUNK_SIZE);
SNMALLOC_ASSERT(bits::is_pow2(size));

if (size >= (bits::one_at_bit(MAX_SIZE_BITS) - 1))
if (size >= bits::mask_bits(MAX_SIZE_BITS))
{
if (ParentRange::Aligned)
return parent.alloc_range(size);
Expand All @@ -378,7 +378,7 @@ namespace snmalloc

if constexpr (MAX_SIZE_BITS != (bits::BITS - 1))
{
if (size >= (bits::one_at_bit(MAX_SIZE_BITS) - 1))
if (size >= bits::mask_bits(MAX_SIZE_BITS))
{
parent_dealloc_range(base, size);
return;
Expand Down
24 changes: 23 additions & 1 deletion src/snmalloc/ds/allocconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,28 @@ namespace snmalloc
MAX_SMALL_SIZECLASS_SIZE >= MIN_CHUNK_SIZE,
"Large sizes need to be representable by as a multiple of MIN_CHUNK_SIZE");

/**
* The number of bits needed to count the number of objects within a slab.
*
* Most likely, this is achieved by the smallest sizeclass, which will have
* many more than MIN_OBJECT_COUNT objects in its slab. But, just in case,
* it's defined here and checked when we compute the sizeclass table, since
* computing this number is potentially nontrivial.
*/
#if defined(SNMALLOC_QEMU_WORKAROUND) && defined(SNMALLOC_VA_BITS_64)
static constexpr size_t MAX_CAPACITY_BITS = 13;
#else
static constexpr size_t MAX_CAPACITY_BITS = 11;
#endif

/**
* The maximum distance between the start of two objects in the same slab.
*/
static constexpr size_t MAX_SLAB_SPAN_SIZE =
(MIN_OBJECT_COUNT - 1) * MAX_SMALL_SIZECLASS_SIZE;
static constexpr size_t MAX_SLAB_SPAN_BITS =
bits::next_pow2_bits_const(MAX_SLAB_SPAN_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;
Expand All @@ -117,7 +139,7 @@ namespace snmalloc
#ifdef USE_REMOTE_CACHE
USE_REMOTE_CACHE
#else
1 << MIN_CHUNK_BITS
MIN_CHUNK_SIZE
#endif
;

Expand Down
26 changes: 20 additions & 6 deletions src/snmalloc/ds_core/bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ namespace snmalloc
static constexpr size_t BITS = sizeof(size_t) * CHAR_BIT;

/**
* Returns a value of type T that has a single bit set,
* Returns a value of type T that has a single bit set at the given index,
* with 0 being the least significant bit.
*
* S is a template parameter because callers use either `int` or `size_t`
* and either is valid to represent a number in the range 0-63 (or 0-127 if
* we want to use `__uint128_t` as `T`).
* S, the type of the bit index, is a template parameter because callers
* use either `int` or `size_t` and either is valid to represent a number in
* the range 0-63 (or 0-127 if we want to use `__uint128_t` as `T`).
*/
template<typename T = size_t, typename S>
constexpr T one_at_bit(S shift)
Expand All @@ -59,6 +60,19 @@ namespace snmalloc
return (static_cast<T>(1)) << shift;
}

/**
* Returns a value of type T that has its n LSBs all set.
*
* S is a template parameter because callers use either `int` or `size_t`
* and either is valid to represent a number in the range 0-63 (or 0-127 if
* we want to use `__uint128_t` as `T`).
*/
template<typename T = size_t, typename S>
constexpr T mask_bits(S n)
{
return one_at_bit<T>(n) - 1;
}

inline SNMALLOC_FAST_PATH size_t clz(size_t x)
{
SNMALLOC_ASSERT(x != 0); // Calling with 0 is UB on some implementations
Expand Down Expand Up @@ -326,7 +340,7 @@ namespace snmalloc
constexpr size_t to_exp_mant_const(size_t value)
{
constexpr size_t LEADING_BIT = one_at_bit(MANTISSA_BITS + LOW_BITS) >> 1;
constexpr size_t MANTISSA_MASK = one_at_bit(MANTISSA_BITS) - 1;
constexpr size_t MANTISSA_MASK = mask_bits(MANTISSA_BITS);

value = value - 1;

Expand All @@ -344,7 +358,7 @@ namespace snmalloc
if (MANTISSA_BITS > 0)
{
m_e = m_e + 1;
constexpr size_t MANTISSA_MASK = one_at_bit(MANTISSA_BITS) - 1;
constexpr size_t MANTISSA_MASK = mask_bits(MANTISSA_BITS);
size_t m = m_e & MANTISSA_MASK;
size_t e = m_e >> MANTISSA_BITS;
size_t b = e == 0 ? 0 : 1;
Expand Down
Loading