Skip to content

Commit

Permalink
Bottom commits from BatchIt (#675)
Browse files Browse the repository at this point in the history
* msvc: set __cplusplus to the actual value in use

* ds_core/bits: add mask_bits; convert one_at_bit-s

* remotecache: enable reserve_space multiple objects

* nits

* Small changes to tracing

- Trace "Handling remote" once per batch, rather than per element

- Remote queue events also log the associated metaslab; we'll use this
  to assess the efficacy of #634

* freelist builder: allow forcibly tracking length

* Try forward declaring freelist::Builder to appease macos-14

* freelist: tweak intra-slab obfuscation keys by meta address

* NFC: freelist: allow `next` to be arbitrary value

* Switch to a central, tweaked key for all free lists

* allocconfig: introduce some properties of slabs

We'll use these to pack values in message queues.

- Maximum distance between two objects in a single slab
- Maximum number of objects in a slab

* NFC: Templatize LocalCache on Config

* NFC: split dealloc_local_object_slow

We'll use the _slower form when we're just stepping a slab through
multiple rounds of state transition (to come), which can't involve
the actual memory object in question.

* NFC: make freelist::Object::T-s by placement new

* NFC: CoreAlloc: split dealloc_local_object

The pattern of `if (!fast()) { slow() }` occurs in a few places, including in
contexts where we already know the entry and so don't need to look it up.
  • Loading branch information
nwf-msr authored Sep 12, 2024
1 parent 12f2b10 commit 8b95b9a
Show file tree
Hide file tree
Showing 16 changed files with 289 additions and 177 deletions.
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

0 comments on commit 8b95b9a

Please sign in to comment.