This page describes some core terminology used in PartitionAlloc. A weak attempt is made to present terms “in conceptual order” s.t. each term depends mainly upon previously defined ones.
A heap that is separated and protected both from other partitions and from non-PartitionAlloc memory. Each partition holds multiple buckets.
A memory page defined by the CPU/OS. Commonly referred to as a “virtual page” in other contexts. This is typically 4KiB, but it can be larger. PartitionAlloc supports up to 64KiB, though this constant isn't always known at compile time (depending on the OS).
The most common granularity used by PartitionAlloc. Consists of exactly 4 system pages.
A 2MiB region, aligned on a 2MiB boundary. Not to be confused with OS-level terms like “large page” or “huge page”, which are also commonly 2MiB. These have to be fully committed / uncommitted in memory, whereas super pages can be partially committed with system page granularity.
An extent is a run of consecutive super pages (belonging to a single partition). Extents are to super pages what slot spans are to slots (see below).
An indivisible allocation unit. Slot sizes are tied to buckets. For example, each allocation that falls into the bucket (224, 256] would be satisfied with a slot of size 256. This applies only to normal buckets, not to direct map.
A run of same-sized slots that are contiguous in memory. Slot span size is a multiple of partition page size, but it isn't always a multiple of slot size, although we try hard for this to be the case.
Allocations up to 4 partition pages. In these cases, slot spans are always between 1 and 4 partition pages in size. For each slot span size, the slot span is chosen to minimize number of pages used while keeping the rounding waste under a reasonable limit.
Allocations above 4 partition pages (but ≤kMaxBucketed
). This is because each slot span is guaranteed to hold exactly one slot.
A collection of regions in a partition that contains similar-sized objects. For example, one bucket may hold objects of size (224, 256], another (256, 320], etc. Bucket size brackets are geometrically spaced, going up to kMaxBucketed
.
Any bucket whose size ceiling does not exceed kMaxBucketed
. This is the common case in PartitionAlloc, and the “normal” modifier is often dropped in casual reference.
Any allocation whose size exceeds kMaxBucketed
.
A chunk of memory returned to the allocating invoker of the size requested. It doesn't have to span the entire slot, nor does it have to begin at the slot start. This term is commonly used as a parameter name in PartitionAlloc code, as opposed to slot_start
.
A thread-local structure that holds some not-too-large memory chunks, ready to be allocated. This speeds up in-thread allocation by reducing a lock hold to a thread-local storage lookup, improving cache locality.
A large (and contiguous on 64-bit) virtual address region, housing super pages, etc. from which PartitionAlloc services allocations. The primary purpose of the pools is to provide a fast answer to the question, “Did PartitionAlloc allocate the memory for this pointer from this pool?” with a single bit-masking operation.
The usable area of a super page in which slot spans reside. While generally this means “everything between the first and last guard partition pages in a super page,” the presence of other metadata can bump the starting offset forward. While this term is entrenched in the code, the team considers it suboptimal and is actively looking for a replacement.
A path taken during an allocation that is considered fast. Usually means that an allocation request can be immediately satisfied by grabbing a slot from the freelist of the first active slot span in the bucket.
Anything which is not fast (see above).
Can involve
if
statements etc.), or something as costly as system calls.These terms are (mostly) deprecated and should not be used. They are surfaced here to provide a ready reference for readers coming from older design documents or documentation.
A memory region several gigabytes wide, reserved by PartitionAlloc upon initialization, from which nearly all allocations are taken. Pools have overtaken GigaCage in conceptual importance, and so and so there is less need today to refer to “GigaCage” or the “cage.” This is especially true given the V8 Sandbox and the configurable pool (see above).
Originally, PartitionAlloc was used only in Blink (Chromium's rendering engine). It was invoked explicitly, by calling PartitionAlloc APIs directly.
PartitionAlloc-Everywhere is the name of the project that brought PartitionAlloc to the entire-ish codebase (exclusions apply). This was done by intercepting malloc()
, free()
, realloc()
, aforementioned posix_memalign()
, etc. and routing them into PartitionAlloc. The shim located in base/allocator/partition_allocator/src/partition_alloc/shim/allocator_shim_default_dispatch_to_partition_alloc.h
is responsible for intercepting. For more details, see base/allocator/README.md.
A special, catch-it-all Malloc partition has been created for the intercepted malloc()
et al. This is to isolate from already existing Blink partitions. The only exception from that is Blink‘s FastMalloc partition, which was also catch-it-all in nature, so it’s perfectly fine to merge these together, to minimize fragmentation.
As of 2022, PartitionAlloc-Everywhere is supported on