1*8e33eff8Schristos #ifndef JEMALLOC_INTERNAL_EXTENT_STRUCTS_H 2*8e33eff8Schristos #define JEMALLOC_INTERNAL_EXTENT_STRUCTS_H 3*8e33eff8Schristos 4*8e33eff8Schristos #include "jemalloc/internal/atomic.h" 5*8e33eff8Schristos #include "jemalloc/internal/bitmap.h" 6*8e33eff8Schristos #include "jemalloc/internal/mutex.h" 7*8e33eff8Schristos #include "jemalloc/internal/ql.h" 8*8e33eff8Schristos #include "jemalloc/internal/ph.h" 9*8e33eff8Schristos #include "jemalloc/internal/size_classes.h" 10*8e33eff8Schristos 11*8e33eff8Schristos typedef enum { 12*8e33eff8Schristos extent_state_active = 0, 13*8e33eff8Schristos extent_state_dirty = 1, 14*8e33eff8Schristos extent_state_muzzy = 2, 15*8e33eff8Schristos extent_state_retained = 3 16*8e33eff8Schristos } extent_state_t; 17*8e33eff8Schristos 18*8e33eff8Schristos /* Extent (span of pages). Use accessor functions for e_* fields. */ 19*8e33eff8Schristos struct extent_s { 20*8e33eff8Schristos /* 21*8e33eff8Schristos * Bitfield containing several fields: 22*8e33eff8Schristos * 23*8e33eff8Schristos * a: arena_ind 24*8e33eff8Schristos * b: slab 25*8e33eff8Schristos * c: committed 26*8e33eff8Schristos * d: dumpable 27*8e33eff8Schristos * z: zeroed 28*8e33eff8Schristos * t: state 29*8e33eff8Schristos * i: szind 30*8e33eff8Schristos * f: nfree 31*8e33eff8Schristos * n: sn 32*8e33eff8Schristos * 33*8e33eff8Schristos * nnnnnnnn ... nnnnffff ffffffii iiiiiitt zdcbaaaa aaaaaaaa 34*8e33eff8Schristos * 35*8e33eff8Schristos * arena_ind: Arena from which this extent came, or all 1 bits if 36*8e33eff8Schristos * unassociated. 37*8e33eff8Schristos * 38*8e33eff8Schristos * slab: The slab flag indicates whether the extent is used for a slab 39*8e33eff8Schristos * of small regions. This helps differentiate small size classes, 40*8e33eff8Schristos * and it indicates whether interior pointers can be looked up via 41*8e33eff8Schristos * iealloc(). 42*8e33eff8Schristos * 43*8e33eff8Schristos * committed: The committed flag indicates whether physical memory is 44*8e33eff8Schristos * committed to the extent, whether explicitly or implicitly 45*8e33eff8Schristos * as on a system that overcommits and satisfies physical 46*8e33eff8Schristos * memory needs on demand via soft page faults. 47*8e33eff8Schristos * 48*8e33eff8Schristos * dumpable: The dumpable flag indicates whether or not we've set the 49*8e33eff8Schristos * memory in question to be dumpable. Note that this 50*8e33eff8Schristos * interacts somewhat subtly with user-specified extent hooks, 51*8e33eff8Schristos * since we don't know if *they* are fiddling with 52*8e33eff8Schristos * dumpability (in which case, we don't want to undo whatever 53*8e33eff8Schristos * they're doing). To deal with this scenario, we: 54*8e33eff8Schristos * - Make dumpable false only for memory allocated with the 55*8e33eff8Schristos * default hooks. 56*8e33eff8Schristos * - Only allow memory to go from non-dumpable to dumpable, 57*8e33eff8Schristos * and only once. 58*8e33eff8Schristos * - Never make the OS call to allow dumping when the 59*8e33eff8Schristos * dumpable bit is already set. 60*8e33eff8Schristos * These three constraints mean that we will never 61*8e33eff8Schristos * accidentally dump user memory that the user meant to set 62*8e33eff8Schristos * nondumpable with their extent hooks. 63*8e33eff8Schristos * 64*8e33eff8Schristos * 65*8e33eff8Schristos * zeroed: The zeroed flag is used by extent recycling code to track 66*8e33eff8Schristos * whether memory is zero-filled. 67*8e33eff8Schristos * 68*8e33eff8Schristos * state: The state flag is an extent_state_t. 69*8e33eff8Schristos * 70*8e33eff8Schristos * szind: The szind flag indicates usable size class index for 71*8e33eff8Schristos * allocations residing in this extent, regardless of whether the 72*8e33eff8Schristos * extent is a slab. Extent size and usable size often differ 73*8e33eff8Schristos * even for non-slabs, either due to sz_large_pad or promotion of 74*8e33eff8Schristos * sampled small regions. 75*8e33eff8Schristos * 76*8e33eff8Schristos * nfree: Number of free regions in slab. 77*8e33eff8Schristos * 78*8e33eff8Schristos * sn: Serial number (potentially non-unique). 79*8e33eff8Schristos * 80*8e33eff8Schristos * Serial numbers may wrap around if !opt_retain, but as long as 81*8e33eff8Schristos * comparison functions fall back on address comparison for equal 82*8e33eff8Schristos * serial numbers, stable (if imperfect) ordering is maintained. 83*8e33eff8Schristos * 84*8e33eff8Schristos * Serial numbers may not be unique even in the absence of 85*8e33eff8Schristos * wrap-around, e.g. when splitting an extent and assigning the same 86*8e33eff8Schristos * serial number to both resulting adjacent extents. 87*8e33eff8Schristos */ 88*8e33eff8Schristos uint64_t e_bits; 89*8e33eff8Schristos #define MASK(CURRENT_FIELD_WIDTH, CURRENT_FIELD_SHIFT) ((((((uint64_t)0x1U) << (CURRENT_FIELD_WIDTH)) - 1)) << (CURRENT_FIELD_SHIFT)) 90*8e33eff8Schristos 91*8e33eff8Schristos #define EXTENT_BITS_ARENA_WIDTH MALLOCX_ARENA_BITS 92*8e33eff8Schristos #define EXTENT_BITS_ARENA_SHIFT 0 93*8e33eff8Schristos #define EXTENT_BITS_ARENA_MASK MASK(EXTENT_BITS_ARENA_WIDTH, EXTENT_BITS_ARENA_SHIFT) 94*8e33eff8Schristos 95*8e33eff8Schristos #define EXTENT_BITS_SLAB_WIDTH 1 96*8e33eff8Schristos #define EXTENT_BITS_SLAB_SHIFT (EXTENT_BITS_ARENA_WIDTH + EXTENT_BITS_ARENA_SHIFT) 97*8e33eff8Schristos #define EXTENT_BITS_SLAB_MASK MASK(EXTENT_BITS_SLAB_WIDTH, EXTENT_BITS_SLAB_SHIFT) 98*8e33eff8Schristos 99*8e33eff8Schristos #define EXTENT_BITS_COMMITTED_WIDTH 1 100*8e33eff8Schristos #define EXTENT_BITS_COMMITTED_SHIFT (EXTENT_BITS_SLAB_WIDTH + EXTENT_BITS_SLAB_SHIFT) 101*8e33eff8Schristos #define EXTENT_BITS_COMMITTED_MASK MASK(EXTENT_BITS_COMMITTED_WIDTH, EXTENT_BITS_COMMITTED_SHIFT) 102*8e33eff8Schristos 103*8e33eff8Schristos #define EXTENT_BITS_DUMPABLE_WIDTH 1 104*8e33eff8Schristos #define EXTENT_BITS_DUMPABLE_SHIFT (EXTENT_BITS_COMMITTED_WIDTH + EXTENT_BITS_COMMITTED_SHIFT) 105*8e33eff8Schristos #define EXTENT_BITS_DUMPABLE_MASK MASK(EXTENT_BITS_DUMPABLE_WIDTH, EXTENT_BITS_DUMPABLE_SHIFT) 106*8e33eff8Schristos 107*8e33eff8Schristos #define EXTENT_BITS_ZEROED_WIDTH 1 108*8e33eff8Schristos #define EXTENT_BITS_ZEROED_SHIFT (EXTENT_BITS_DUMPABLE_WIDTH + EXTENT_BITS_DUMPABLE_SHIFT) 109*8e33eff8Schristos #define EXTENT_BITS_ZEROED_MASK MASK(EXTENT_BITS_ZEROED_WIDTH, EXTENT_BITS_ZEROED_SHIFT) 110*8e33eff8Schristos 111*8e33eff8Schristos #define EXTENT_BITS_STATE_WIDTH 2 112*8e33eff8Schristos #define EXTENT_BITS_STATE_SHIFT (EXTENT_BITS_ZEROED_WIDTH + EXTENT_BITS_ZEROED_SHIFT) 113*8e33eff8Schristos #define EXTENT_BITS_STATE_MASK MASK(EXTENT_BITS_STATE_WIDTH, EXTENT_BITS_STATE_SHIFT) 114*8e33eff8Schristos 115*8e33eff8Schristos #define EXTENT_BITS_SZIND_WIDTH LG_CEIL_NSIZES 116*8e33eff8Schristos #define EXTENT_BITS_SZIND_SHIFT (EXTENT_BITS_STATE_WIDTH + EXTENT_BITS_STATE_SHIFT) 117*8e33eff8Schristos #define EXTENT_BITS_SZIND_MASK MASK(EXTENT_BITS_SZIND_WIDTH, EXTENT_BITS_SZIND_SHIFT) 118*8e33eff8Schristos 119*8e33eff8Schristos #define EXTENT_BITS_NFREE_WIDTH (LG_SLAB_MAXREGS + 1) 120*8e33eff8Schristos #define EXTENT_BITS_NFREE_SHIFT (EXTENT_BITS_SZIND_WIDTH + EXTENT_BITS_SZIND_SHIFT) 121*8e33eff8Schristos #define EXTENT_BITS_NFREE_MASK MASK(EXTENT_BITS_NFREE_WIDTH, EXTENT_BITS_NFREE_SHIFT) 122*8e33eff8Schristos 123*8e33eff8Schristos #define EXTENT_BITS_SN_SHIFT (EXTENT_BITS_NFREE_WIDTH + EXTENT_BITS_NFREE_SHIFT) 124*8e33eff8Schristos #define EXTENT_BITS_SN_MASK (UINT64_MAX << EXTENT_BITS_SN_SHIFT) 125*8e33eff8Schristos 126*8e33eff8Schristos /* Pointer to the extent that this structure is responsible for. */ 127*8e33eff8Schristos void *e_addr; 128*8e33eff8Schristos 129*8e33eff8Schristos union { 130*8e33eff8Schristos /* 131*8e33eff8Schristos * Extent size and serial number associated with the extent 132*8e33eff8Schristos * structure (different than the serial number for the extent at 133*8e33eff8Schristos * e_addr). 134*8e33eff8Schristos * 135*8e33eff8Schristos * ssssssss [...] ssssssss ssssnnnn nnnnnnnn 136*8e33eff8Schristos */ 137*8e33eff8Schristos size_t e_size_esn; 138*8e33eff8Schristos #define EXTENT_SIZE_MASK ((size_t)~(PAGE-1)) 139*8e33eff8Schristos #define EXTENT_ESN_MASK ((size_t)PAGE-1) 140*8e33eff8Schristos /* Base extent size, which may not be a multiple of PAGE. */ 141*8e33eff8Schristos size_t e_bsize; 142*8e33eff8Schristos }; 143*8e33eff8Schristos 144*8e33eff8Schristos /* 145*8e33eff8Schristos * List linkage, used by a variety of lists: 146*8e33eff8Schristos * - bin_t's slabs_full 147*8e33eff8Schristos * - extents_t's LRU 148*8e33eff8Schristos * - stashed dirty extents 149*8e33eff8Schristos * - arena's large allocations 150*8e33eff8Schristos */ 151*8e33eff8Schristos ql_elm(extent_t) ql_link; 152*8e33eff8Schristos 153*8e33eff8Schristos /* 154*8e33eff8Schristos * Linkage for per size class sn/address-ordered heaps, and 155*8e33eff8Schristos * for extent_avail 156*8e33eff8Schristos */ 157*8e33eff8Schristos phn(extent_t) ph_link; 158*8e33eff8Schristos 159*8e33eff8Schristos union { 160*8e33eff8Schristos /* Small region slab metadata. */ 161*8e33eff8Schristos arena_slab_data_t e_slab_data; 162*8e33eff8Schristos 163*8e33eff8Schristos /* 164*8e33eff8Schristos * Profile counters, used for large objects. Points to a 165*8e33eff8Schristos * prof_tctx_t. 166*8e33eff8Schristos */ 167*8e33eff8Schristos atomic_p_t e_prof_tctx; 168*8e33eff8Schristos }; 169*8e33eff8Schristos }; 170*8e33eff8Schristos typedef ql_head(extent_t) extent_list_t; 171*8e33eff8Schristos typedef ph(extent_t) extent_tree_t; 172*8e33eff8Schristos typedef ph(extent_t) extent_heap_t; 173*8e33eff8Schristos 174*8e33eff8Schristos /* Quantized collection of extents, with built-in LRU queue. */ 175*8e33eff8Schristos struct extents_s { 176*8e33eff8Schristos malloc_mutex_t mtx; 177*8e33eff8Schristos 178*8e33eff8Schristos /* 179*8e33eff8Schristos * Quantized per size class heaps of extents. 180*8e33eff8Schristos * 181*8e33eff8Schristos * Synchronization: mtx. 182*8e33eff8Schristos */ 183*8e33eff8Schristos extent_heap_t heaps[NPSIZES+1]; 184*8e33eff8Schristos 185*8e33eff8Schristos /* 186*8e33eff8Schristos * Bitmap for which set bits correspond to non-empty heaps. 187*8e33eff8Schristos * 188*8e33eff8Schristos * Synchronization: mtx. 189*8e33eff8Schristos */ 190*8e33eff8Schristos bitmap_t bitmap[BITMAP_GROUPS(NPSIZES+1)]; 191*8e33eff8Schristos 192*8e33eff8Schristos /* 193*8e33eff8Schristos * LRU of all extents in heaps. 194*8e33eff8Schristos * 195*8e33eff8Schristos * Synchronization: mtx. 196*8e33eff8Schristos */ 197*8e33eff8Schristos extent_list_t lru; 198*8e33eff8Schristos 199*8e33eff8Schristos /* 200*8e33eff8Schristos * Page sum for all extents in heaps. 201*8e33eff8Schristos * 202*8e33eff8Schristos * The synchronization here is a little tricky. Modifications to npages 203*8e33eff8Schristos * must hold mtx, but reads need not (though, a reader who sees npages 204*8e33eff8Schristos * without holding the mutex can't assume anything about the rest of the 205*8e33eff8Schristos * state of the extents_t). 206*8e33eff8Schristos */ 207*8e33eff8Schristos atomic_zu_t npages; 208*8e33eff8Schristos 209*8e33eff8Schristos /* All stored extents must be in the same state. */ 210*8e33eff8Schristos extent_state_t state; 211*8e33eff8Schristos 212*8e33eff8Schristos /* 213*8e33eff8Schristos * If true, delay coalescing until eviction; otherwise coalesce during 214*8e33eff8Schristos * deallocation. 215*8e33eff8Schristos */ 216*8e33eff8Schristos bool delay_coalesce; 217*8e33eff8Schristos }; 218*8e33eff8Schristos 219*8e33eff8Schristos #endif /* JEMALLOC_INTERNAL_EXTENT_STRUCTS_H */ 220