Skip to content

Commit 772e46f

Browse files
nwf-msrnwf
authored andcommitted
Additional commentary and more verbose names
1 parent b5a6613 commit 772e46f

3 files changed

Lines changed: 49 additions & 22 deletions

File tree

src/backend/backend.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ namespace snmalloc
217217
*
218218
* The template argument is the type of the metadata being allocated. This
219219
* allows the backend to allocate different types of metadata in different
220-
* places or with different policies.
220+
* places or with different policies. The default implementation, here,
221+
* does not avail itself of this degree of freedom.
221222
*/
222223
template<typename T>
223224
static capptr::Chunk<void>

src/backend/largebuddyrange.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,45 @@ namespace snmalloc
1818
class BuddyChunkRep
1919
{
2020
public:
21+
/*
22+
* The values we store in our rbtree are the addresses of (combined spans
23+
* of) chunks of the address space; as such, bits in (MIN_CHUNK_SIZE - 1)
24+
* are unused and so the RED_BIT is packed therein. However, in practice,
25+
* these are not "just any" uintptr_t-s, but specifically the uintptr_t-s
26+
* inside the Pagemap's MetaEntry structures. As such, there are some
27+
* additional bit-swizzling concerns; see set() and get() below.
28+
*/
2129
using Holder = uintptr_t;
2230
using Contents = uintptr_t;
2331

24-
static constexpr address_t RED_BIT = 2;
32+
static constexpr address_t RED_BIT = 1 << 1;
33+
34+
static_assert(RED_BIT < MIN_CHUNK_SIZE);
35+
static_assert(RED_BIT != MetaEntry::META_BOUNDARY_BIT);
36+
static_assert(RED_BIT != MetaEntry::REMOTE_BACKEND_MARKER);
2537

2638
static constexpr Contents null = 0;
2739

2840
static void set(Holder* ptr, Contents r)
2941
{
3042
SNMALLOC_ASSERT((r & (MIN_CHUNK_SIZE - 1)) == 0);
31-
// Preserve lower bits.
43+
/*
44+
* Preserve lower bits, claim as backend, and update contents of holder.
45+
*
46+
* This is excessive at present but no harder than being more precise
47+
* while also being future-proof. All that is strictly required would be
48+
* to preserve META_BOUNDARY_BIT and RED_BIT in ->meta and to assert
49+
* REMOTE_BACKEND_MARKER in ->remote_and_sizeclass (if it isn't already
50+
* asserted). However, we don't know which Holder* we have been given,
51+
* nor do we know whether this Holder* is completely new (and so we are
52+
* the first reasonable opportunity to assert REMOTE_BACKEND_MARKER) or
53+
* recycled from the frontend, and so we preserve and assert more than
54+
* strictly necessary.
55+
*
56+
* The use of `address_cast` below is a CHERI-ism; otherwise both `r` and
57+
* `*ptr & ...` are plausibly provenance-carrying values and the compiler
58+
* balks at the ambiguity.
59+
*/
3260
*ptr = r | address_cast(*ptr & (MIN_CHUNK_SIZE - 1)) |
3361
MetaEntry::REMOTE_BACKEND_MARKER;
3462
}

src/backend/metatypes.h

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,20 @@ namespace snmalloc
8484
class sizeclass_t;
8585

8686
/**
87-
* Entry stored in the pagemap.
87+
* Entry stored in the pagemap. See docs/AddressSpace.md for the full
88+
* MetaEntry lifecycle.
8889
*/
8990
class MetaEntry
9091
{
9192
template<typename Pagemap>
9293
friend class BuddyChunkRep;
9394

9495
/**
95-
* The pointer to the metaslab, the bottom bit is used to indicate if this
96-
* is the first chunk in a PAL allocation, that cannot be combined with
97-
* the preceeding chunk.
96+
* In common cases, the pointer to the metaslab. See docs/AddressSpace.md
97+
* for additional details.
98+
*
99+
* The bottom bit is used to indicate if this is the first chunk in a PAL
100+
* allocation, that cannot be combined with the preceeding chunk.
98101
*/
99102
uintptr_t meta{0};
100103

@@ -107,18 +110,12 @@ namespace snmalloc
107110
* representable. It is also true on Windows as you cannot Commit across
108111
* multiple continuous VirtualAllocs.
109112
*/
110-
static constexpr address_t BOUNDARY_BIT = 1;
113+
static constexpr address_t META_BOUNDARY_BIT = 1 << 0;
111114

112115
/**
113-
* A bit-packed pointer to the owning allocator (if any), and the sizeclass
114-
* of this chunk. The sizeclass here is itself a union between two cases:
115-
*
116-
* * log_2(size), at least MIN_CHUNK_BITS, for large allocations.
117-
*
118-
* * a value in [0, NUM_SMALL_SIZECLASSES] for small allocations. These
119-
* may be directly passed to the sizeclass (not slab_sizeclass) functions
120-
* of sizeclasstable.h
121-
*
116+
* In common cases, a bit-packed pointer to the owning allocator (if any),
117+
* and the sizeclass of this chunk. See mem/metaslab.h:MetaEntryRemote for
118+
* details of this case and docs/AddressSpace.md for further details.
122119
*/
123120
uintptr_t remote_and_sizeclass{0};
124121

@@ -160,7 +157,7 @@ namespace snmalloc
160157
[[nodiscard]] SNMALLOC_FAST_PATH Metaslab* get_metaslab() const
161158
{
162159
SNMALLOC_ASSERT(get_remote() != nullptr);
163-
return unsafe_from_uintptr<Metaslab>(meta & ~BOUNDARY_BIT);
160+
return unsafe_from_uintptr<Metaslab>(meta & ~META_BOUNDARY_BIT);
164161
}
165162

166163
/**
@@ -183,24 +180,25 @@ namespace snmalloc
183180
MetaEntry& operator=(const MetaEntry& other)
184181
{
185182
// Don't overwrite the boundary bit with the other's
186-
meta = (other.meta & ~BOUNDARY_BIT) | address_cast(meta & BOUNDARY_BIT);
183+
meta = (other.meta & ~META_BOUNDARY_BIT) |
184+
address_cast(meta & META_BOUNDARY_BIT);
187185
remote_and_sizeclass = other.remote_and_sizeclass;
188186
return *this;
189187
}
190188

191189
void set_boundary()
192190
{
193-
meta |= BOUNDARY_BIT;
191+
meta |= META_BOUNDARY_BIT;
194192
}
195193

196194
[[nodiscard]] bool is_boundary() const
197195
{
198-
return meta & BOUNDARY_BIT;
196+
return meta & META_BOUNDARY_BIT;
199197
}
200198

201199
bool clear_boundary_bit()
202200
{
203-
return meta &= ~BOUNDARY_BIT;
201+
return meta &= ~META_BOUNDARY_BIT;
204202
}
205203
};
206204

0 commit comments

Comments
 (0)