Kalvin Lee | 5f8555b | 2022-05-16 21:30:20 | [diff] [blame] | 1 | # Glossary |
| 2 | |
| 3 | This page describes some core terminology used in PartitionAlloc. |
| 4 | A weak attempt is made to present terms "in conceptual order" s.t. |
| 5 | each term depends mainly upon previously defined ones. |
| 6 | |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 7 | ### Partition |
| 8 | |
| 9 | A heap that is separated and protected both from other |
| 10 | partitions and from non-PartitionAlloc memory. Each partition holds |
| 11 | multiple buckets. |
Kalvin Lee | 8338a46 | 2022-07-29 02:19:25 | [diff] [blame] | 12 | |
| 13 | *** promo |
| 14 | **NOTE**: In code (and comments), "partition," "root," and even |
| 15 | "allocator" are all conceptually the same thing. |
| 16 | *** |
| 17 | |
Kalvin Lee | 5f8555b | 2022-05-16 21:30:20 | [diff] [blame] | 18 | ## Pages |
| 19 | |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 20 | ### System Page |
| 21 | |
| 22 | A memory page defined by the CPU/OS. Commonly |
| 23 | referred to as a "virtual page" in other contexts. This is typically |
| 24 | 4KiB, but it can be larger. PartitionAlloc supports up to 64KiB, |
| 25 | though this constant isn't always known at compile time (depending |
| 26 | on the OS). |
| 27 | |
| 28 | ### Partition Page |
| 29 | |
| 30 | The most common granularity used by |
| 31 | PartitionAlloc. Consists of exactly 4 system pages. |
| 32 | |
| 33 | ### Super Page |
| 34 | |
| 35 | A 2MiB region, aligned on a 2MiB boundary. Not to |
| 36 | be confused with OS-level terms like "large page" or "huge page", |
| 37 | which are also commonly 2MiB. These have to be fully committed / |
| 38 | uncommitted in memory, whereas super pages can be partially committed |
| 39 | with system page granularity. |
| 40 | |
| 41 | ### Extent |
| 42 | |
| 43 | An extent is a run of consecutive super pages (belonging |
| 44 | to a single partition). Extents are to super pages what slot spans are |
| 45 | to slots (see below). |
Kalvin Lee | 5f8555b | 2022-05-16 21:30:20 | [diff] [blame] | 46 | |
| 47 | ## Slots and Spans |
| 48 | |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 49 | ### Slot |
| 50 | |
| 51 | An indivisible allocation unit. Slot sizes are tied to |
| 52 | buckets. For example, each allocation that falls into the bucket |
| 53 | (224, 256] would be satisfied with a slot of size 256. This |
| 54 | applies only to normal buckets, not to direct map. |
| 55 | |
| 56 | ### Slot Span |
| 57 | |
| 58 | A run of same-sized slots that are contiguous in |
| 59 | memory. Slot span size is a multiple of partition page size, but it |
| 60 | isn't always a multiple of slot size, although we try hard for this |
| 61 | to be the case. |
| 62 | |
| 63 | ### Small Bucket |
| 64 | |
| 65 | Allocations up to 4 partition pages. In these |
| 66 | cases, slot spans are always between 1 and 4 partition pages in |
| 67 | size. For each slot span size, the slot span is chosen to minimize |
| 68 | number of pages used while keeping the rounding waste under a |
| 69 | reasonable limit. |
| 70 | |
| 71 | * For example, for a slot size 96, 64B waste is deemed acceptable |
| 72 | when using a single partition page, but for slot size |
| 73 | 384, the potential waste of 256B wouldn't be, so 3 partition pages |
| 74 | are used to achieve 0B waste. |
| 75 | * PartitionAlloc may avoid waste by lowering the number of committed |
| 76 | system pages compared to the number of reserved pages. For |
| 77 | example, for the slot size of 896B we'd use a slot span of 2 |
| 78 | partition pages of 16KiB, i.e. 8 system pages of 4KiB, but commit |
| 79 | only up to 7, thus resulting in perfect packing. |
| 80 | |
| 81 | ### Single-Slot Span |
| 82 | |
| 83 | Allocations above 4 partition pages (but |
mikt | 1397a7c | 2025-05-02 04:35:46 | [diff] [blame] | 84 | ≤`BucketIndexLookup::kMaxBucketSize`). This is because each slot span is guaranteed to |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 85 | hold exactly one slot. |
| 86 | |
| 87 | *** promo |
| 88 | Fun fact: there are sizes ≤4 partition pages that result in a |
| 89 | slot span having exactly 1 slot, but nonetheless they're still |
| 90 | classified as small buckets. The reason is that single-slot spans |
| 91 | are often handled by a different code path, and that distinction |
| 92 | is made purely based on slot size, for simplicity and efficiency. |
| 93 | *** |
Kalvin Lee | 5f8555b | 2022-05-16 21:30:20 | [diff] [blame] | 94 | |
Kalvin Lee | 1389225 | 2023-04-13 07:29:23 | [diff] [blame] | 95 | ## Buckets |
| 96 | |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 97 | ### Bucket |
| 98 | |
| 99 | A collection of regions in a partition that contains |
| 100 | similar-sized objects. For example, one bucket may hold objects of |
| 101 | size (224, 256], another (256, 320], etc. Bucket size |
| 102 | brackets are geometrically spaced, |
mikt | 1397a7c | 2025-05-02 04:35:46 | [diff] [blame] | 103 | [going up to `BucketIndexLookup::kMaxBucketSize`][max-bucket-comment]. |
| 104 | See [Bucket Distribution in PartitionAlloc](./buckets.md) for details. |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 105 | |
| 106 | *** promo |
| 107 | Plainly put, all slots (ergo the resulting spans) of a given size |
| 108 | class are logically chained into one bucket. |
| 109 | *** |
Kalvin Lee | e42e143 | 2023-04-13 07:52:41 | [diff] [blame] | 110 | |
| 111 | ![A bucket, spanning multiple super pages, collects spans whose |
Kalvin Lee | a928781 | 2023-11-21 00:12:05 | [diff] [blame] | 112 | slots are of a particular size class.](./src/partition_alloc/dot/bucket.png) |
Kalvin Lee | e42e143 | 2023-04-13 07:52:41 | [diff] [blame] | 113 | |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 114 | ### Normal Bucket |
| 115 | |
| 116 | Any bucket whose size ceiling does not exceed |
mikt | 1397a7c | 2025-05-02 04:35:46 | [diff] [blame] | 117 | `BucketIndexLookup::kMaxBucketSize`. This is the common case in PartitionAlloc, and |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 118 | the "normal" modifier is often dropped in casual reference. |
| 119 | |
| 120 | ### Direct Map (Bucket) |
| 121 | |
mikt | 1397a7c | 2025-05-02 04:35:46 | [diff] [blame] | 122 | Any allocation whose size exceeds `BucketIndexLookup::kMaxBucketSize`. |
Kalvin Lee | 1389225 | 2023-04-13 07:29:23 | [diff] [blame] | 123 | |
Kalvin Lee | 5f8555b | 2022-05-16 21:30:20 | [diff] [blame] | 124 | ## Other Terms |
| 125 | |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 126 | ### Object |
| 127 | |
| 128 | A chunk of memory returned to the allocating invoker |
| 129 | of the size requested. It doesn't have to span the entire slot, |
| 130 | nor does it have to begin at the slot start. This term is commonly |
| 131 | used as a parameter name in PartitionAlloc code, as opposed to |
| 132 | `slot_start`. |
| 133 | |
| 134 | ### Thread Cache |
| 135 | |
| 136 | A [thread-local structure][pa-thread-cache] that |
| 137 | holds some not-too-large memory chunks, ready to be allocated. This |
| 138 | speeds up in-thread allocation by reducing a lock hold to a |
| 139 | thread-local storage lookup, improving cache locality. |
| 140 | |
| 141 | ### Pool |
| 142 | |
| 143 | A large (and contiguous on 64-bit) virtual address region, housing |
| 144 | super pages, etc. from which PartitionAlloc services allocations. The |
| 145 | primary purpose of the pools is to provide a fast answer to the |
| 146 | question, "Did PartitionAlloc allocate the memory for this pointer |
| 147 | from this pool?" with a single bit-masking operation. |
| 148 | |
| 149 | * The regular pool is a general purpose pool that contains allocations that |
Bartek Nowierski | f2d03ca | 2022-10-04 10:08:57 | [diff] [blame] | 150 | aren't protected by BackupRefPtr. |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 151 | * The BRP pool contains all allocations protected by BackupRefPtr. |
| 152 | * [64-bit only] The configurable pool is named generically, because its |
Bartek Nowierski | f2d03ca | 2022-10-04 10:08:57 | [diff] [blame] | 153 | primary user (the [V8 Sandbox][v8-sandbox]) can configure it at runtime, |
| 154 | providing a pre-existing mapping. Its allocations aren't protected by |
| 155 | BackupRefPtr. |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 156 | * [64-bit only] The thread isolated pool is returning memory protected with |
Stephen Roettger | 3554d01 | 2023-05-10 09:06:54 | [diff] [blame] | 157 | per-thread permissions. At the moment, this is implemented for pkeys on x64. |
| 158 | It's primary user is [V8 CFI][v8-cfi]. |
Kalvin Lee | 67bcfa5 | 2022-10-03 02:58:50 | [diff] [blame] | 159 | |
Kalvin Lee | 9dae9c0 | 2023-07-11 08:19:30 | [diff] [blame] | 160 | ![The singular AddressPoolManager mediates access to the separate pools |
Kalvin Lee | a928781 | 2023-11-21 00:12:05 | [diff] [blame] | 161 | for each PartitionRoot.](./src/partition_alloc/dot/address-space.png) |
Kalvin Lee | 9dae9c0 | 2023-07-11 08:19:30 | [diff] [blame] | 162 | |
Kalvin Lee | 67bcfa5 | 2022-10-03 02:58:50 | [diff] [blame] | 163 | *** promo |
Bartek Nowierski | f2d03ca | 2022-10-04 10:08:57 | [diff] [blame] | 164 | Pools are downgraded into a logical concept in 32-bit environments, |
| 165 | tracking a non-contiguous set of allocations using a bitmap. |
Kalvin Lee | 67bcfa5 | 2022-10-03 02:58:50 | [diff] [blame] | 166 | *** |
| 167 | |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 168 | ### Payload |
| 169 | |
| 170 | The usable area of a super page in which slot spans |
| 171 | reside. While generally this means "everything between the first |
| 172 | and last guard partition pages in a super page," the presence of |
mikt | b0cb752 | 2024-07-12 07:33:52 | [diff] [blame] | 173 | other metadata can bump the starting offset |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 174 | forward. While this term is entrenched in the code, the team |
| 175 | considers it suboptimal and is actively looking for a replacement. |
| 176 | |
| 177 | ### Allocation Fast Path |
| 178 | |
| 179 | A path taken during an allocation that is |
| 180 | considered fast. Usually means that an allocation request can be |
| 181 | immediately satisfied by grabbing a slot from the freelist of the |
| 182 | first active slot span in the bucket. |
| 183 | |
| 184 | ### Allocation Slow Path |
| 185 | |
| 186 | Anything which is not fast (see above). |
| 187 | |
| 188 | Can involve |
| 189 | |
| 190 | * finding another active slot span in the list, |
| 191 | * provisioning more slots in a slot span, |
| 192 | * bringing back a free (or decommitted) slot span, |
| 193 | * allocating a new slot span, or even |
| 194 | * allocating a new super page. |
Kalvin Lee | dbbd6e4 | 2022-08-09 02:35:37 | [diff] [blame] | 195 | |
| 196 | *** aside |
| 197 | By "slow" we may mean something as simple as extra logic (`if` |
| 198 | statements etc.), or something as costly as system calls. |
| 199 | *** |
Kalvin Lee | 5f8555b | 2022-05-16 21:30:20 | [diff] [blame] | 200 | |
Kalvin Lee | 67bcfa5 | 2022-10-03 02:58:50 | [diff] [blame] | 201 | ## Legacy Terms |
| 202 | |
| 203 | These terms are (mostly) deprecated and should not be used. They are |
| 204 | surfaced here to provide a ready reference for readers coming from |
| 205 | older design documents or documentation. |
| 206 | |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 207 | ### GigaCage |
| 208 | |
| 209 | A memory region several gigabytes wide, reserved by |
| 210 | PartitionAlloc upon initialization, from which nearly all allocations |
| 211 | are taken. _Pools_ have overtaken GigaCage in conceptual importance, |
| 212 | and so and so there is less need today to refer to "GigaCage" or the |
| 213 | "cage." This is especially true given the V8 Sandbox and the |
| 214 | configurable pool (see above). |
Kalvin Lee | 67bcfa5 | 2022-10-03 02:58:50 | [diff] [blame] | 215 | |
Kalvin Lee | 5f8555b | 2022-05-16 21:30:20 | [diff] [blame] | 216 | ## PartitionAlloc-Everywhere |
| 217 | |
| 218 | Originally, PartitionAlloc was used only in Blink (Chromium's rendering engine). |
| 219 | It was invoked explicitly, by calling PartitionAlloc APIs directly. |
| 220 | |
| 221 | PartitionAlloc-Everywhere is the name of the project that brought PartitionAlloc |
| 222 | to the entire-ish codebase (exclusions apply). This was done by intercepting |
| 223 | `malloc()`, `free()`, `realloc()`, aforementioned `posix_memalign()`, etc. and |
| 224 | routing them into PartitionAlloc. The shim located in |
Yuki Shiino | 550a6e7 | 2023-10-24 23:07:29 | [diff] [blame] | 225 | `base/allocator/partition_allocator/src/partition_alloc/shim/allocator_shim_default_dispatch_to_partition_alloc.h` is |
Kalvin Lee | 5f8555b | 2022-05-16 21:30:20 | [diff] [blame] | 226 | responsible for intercepting. For more details, see |
| 227 | [base/allocator/README.md](../../../base/allocator/README.md). |
| 228 | |
| 229 | A special, catch-it-all *Malloc* partition has been created for the intercepted |
| 230 | `malloc()` et al. This is to isolate from already existing Blink partitions. |
| 231 | The only exception from that is Blink's *FastMalloc* partition, which was also |
| 232 | catch-it-all in nature, so it's perfectly fine to merge these together, to |
| 233 | minimize fragmentation. |
| 234 | |
| 235 | As of 2022, PartitionAlloc-Everywhere is supported on |
| 236 | |
Kalvin Lee | 2c23897 | 2024-03-11 02:55:01 | [diff] [blame] | 237 | * Windows 32- and 64-bit |
| 238 | * Linux |
| 239 | * Android 32- and 64-bit |
| 240 | * macOS |
| 241 | * Fuchsia |
Kalvin Lee | 5f8555b | 2022-05-16 21:30:20 | [diff] [blame] | 242 | |
mikt | 1397a7c | 2025-05-02 04:35:46 | [diff] [blame] | 243 | [max-bucket-comment]: https://source.chromium.org/search?q=-file:third_party%2F(angle%7Cdawn)%20file:partition_alloc_constants.h%20symbol:BucketIndexLookup::kMaxBucketSize$&ss=chromium |
Kalvin Lee | 022d0cc | 2024-03-27 07:17:22 | [diff] [blame] | 244 | [pa-thread-cache]: https://source.chromium.org/search?q=-file:third_party%2F(angle%7Cdawn)%20file:partition_alloc/thread_cache.h&ss=chromium |
Kalvin Lee | 67bcfa5 | 2022-10-03 02:58:50 | [diff] [blame] | 245 | [v8-sandbox]: https://docs.google.com/document/d/1FM4fQmIhEqPG8uGp5o9A-mnPB5BOeScZYpkHjo0KKA8/preview# |
Stephen Roettger | 6b495de | 2022-11-07 15:55:18 | [diff] [blame] | 246 | [v8-cfi]: https://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/preview# |