1 #ifndef JEMALLOC_INTERNAL_EXTENT_INLINES_H
2 #define JEMALLOC_INTERNAL_EXTENT_INLINES_H
3
4 #ifndef JEMALLOC_ENABLE_INLINE
5 extent_t *extent_lookup(tsdn_t *tsdn, const void *ptr, bool dependent);
6 arena_t *extent_arena_get(const extent_t *extent);
7 void *extent_base_get(const extent_t *extent);
8 void *extent_addr_get(const extent_t *extent);
9 size_t extent_size_get(const extent_t *extent);
10 size_t extent_usize_get(const extent_t *extent);
11 void *extent_before_get(const extent_t *extent);
12 void *extent_last_get(const extent_t *extent);
13 void *extent_past_get(const extent_t *extent);
14 size_t extent_sn_get(const extent_t *extent);
15 bool extent_active_get(const extent_t *extent);
16 bool extent_retained_get(const extent_t *extent);
17 bool extent_zeroed_get(const extent_t *extent);
18 bool extent_committed_get(const extent_t *extent);
19 bool extent_slab_get(const extent_t *extent);
20 arena_slab_data_t *extent_slab_data_get(extent_t *extent);
21 const arena_slab_data_t *extent_slab_data_get_const(const extent_t *extent);
22 prof_tctx_t *extent_prof_tctx_get(const extent_t *extent);
23 void extent_arena_set(extent_t *extent, arena_t *arena);
24 void extent_addr_set(extent_t *extent, void *addr);
25 void extent_addr_randomize(tsdn_t *tsdn, extent_t *extent, size_t alignment);
26 void extent_size_set(extent_t *extent, size_t size);
27 void extent_usize_set(extent_t *extent, size_t usize);
28 void extent_sn_set(extent_t *extent, size_t sn);
29 void extent_active_set(extent_t *extent, bool active);
30 void extent_zeroed_set(extent_t *extent, bool zeroed);
31 void extent_committed_set(extent_t *extent, bool committed);
32 void extent_slab_set(extent_t *extent, bool slab);
33 void extent_prof_tctx_set(extent_t *extent, prof_tctx_t *tctx);
34 void extent_init(extent_t *extent, arena_t *arena, void *addr,
35 size_t size, size_t usize, size_t sn, bool active, bool zeroed,
36 bool committed, bool slab);
37 void extent_ring_insert(extent_t *sentinel, extent_t *extent);
38 void extent_ring_remove(extent_t *extent);
39 int extent_sn_comp(const extent_t *a, const extent_t *b);
40 int extent_ad_comp(const extent_t *a, const extent_t *b);
41 int extent_snad_comp(const extent_t *a, const extent_t *b);
42 #endif
43
44 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_EXTENT_C_))
45 JEMALLOC_INLINE extent_t *
extent_lookup(tsdn_t * tsdn,const void * ptr,bool dependent)46 extent_lookup(tsdn_t *tsdn, const void *ptr, bool dependent)
47 {
48 rtree_ctx_t rtree_ctx_fallback;
49 rtree_ctx_t *rtree_ctx = tsdn_rtree_ctx(tsdn, &rtree_ctx_fallback);
50
51 return (rtree_read(tsdn, &extents_rtree, rtree_ctx, (uintptr_t)ptr,
52 dependent));
53 }
54
55 JEMALLOC_INLINE arena_t *
extent_arena_get(const extent_t * extent)56 extent_arena_get(const extent_t *extent)
57 {
58 return (extent->e_arena);
59 }
60
61 JEMALLOC_INLINE void *
extent_base_get(const extent_t * extent)62 extent_base_get(const extent_t *extent)
63 {
64 assert(extent->e_addr == PAGE_ADDR2BASE(extent->e_addr) ||
65 !extent->e_slab);
66 return (PAGE_ADDR2BASE(extent->e_addr));
67 }
68
69 JEMALLOC_INLINE void *
extent_addr_get(const extent_t * extent)70 extent_addr_get(const extent_t *extent)
71 {
72 assert(extent->e_addr == PAGE_ADDR2BASE(extent->e_addr) ||
73 !extent->e_slab);
74 return (extent->e_addr);
75 }
76
77 JEMALLOC_INLINE size_t
extent_size_get(const extent_t * extent)78 extent_size_get(const extent_t *extent)
79 {
80 return (extent->e_size);
81 }
82
83 JEMALLOC_INLINE size_t
extent_usize_get(const extent_t * extent)84 extent_usize_get(const extent_t *extent)
85 {
86 assert(!extent->e_slab);
87 return (extent->e_usize);
88 }
89
90 JEMALLOC_INLINE void *
extent_before_get(const extent_t * extent)91 extent_before_get(const extent_t *extent)
92 {
93 return ((void *)((uintptr_t)extent_base_get(extent) - PAGE));
94 }
95
96 JEMALLOC_INLINE void *
extent_last_get(const extent_t * extent)97 extent_last_get(const extent_t *extent)
98 {
99 return ((void *)((uintptr_t)extent_base_get(extent) +
100 extent_size_get(extent) - PAGE));
101 }
102
103 JEMALLOC_INLINE void *
extent_past_get(const extent_t * extent)104 extent_past_get(const extent_t *extent)
105 {
106 return ((void *)((uintptr_t)extent_base_get(extent) +
107 extent_size_get(extent)));
108 }
109
110 JEMALLOC_INLINE size_t
extent_sn_get(const extent_t * extent)111 extent_sn_get(const extent_t *extent)
112 {
113 return (extent->e_sn);
114 }
115
116 JEMALLOC_INLINE bool
extent_active_get(const extent_t * extent)117 extent_active_get(const extent_t *extent)
118 {
119 return (extent->e_active);
120 }
121
122 JEMALLOC_INLINE bool
extent_retained_get(const extent_t * extent)123 extent_retained_get(const extent_t *extent)
124 {
125 return (qr_next(extent, qr_link) == extent);
126 }
127
128 JEMALLOC_INLINE bool
extent_zeroed_get(const extent_t * extent)129 extent_zeroed_get(const extent_t *extent)
130 {
131 return (extent->e_zeroed);
132 }
133
134 JEMALLOC_INLINE bool
extent_committed_get(const extent_t * extent)135 extent_committed_get(const extent_t *extent)
136 {
137 return (extent->e_committed);
138 }
139
140 JEMALLOC_INLINE bool
extent_slab_get(const extent_t * extent)141 extent_slab_get(const extent_t *extent)
142 {
143 return (extent->e_slab);
144 }
145
146 JEMALLOC_INLINE arena_slab_data_t *
extent_slab_data_get(extent_t * extent)147 extent_slab_data_get(extent_t *extent)
148 {
149 assert(extent->e_slab);
150 return (&extent->e_slab_data);
151 }
152
153 JEMALLOC_INLINE const arena_slab_data_t *
extent_slab_data_get_const(const extent_t * extent)154 extent_slab_data_get_const(const extent_t *extent)
155 {
156 assert(extent->e_slab);
157 return (&extent->e_slab_data);
158 }
159
160 JEMALLOC_INLINE prof_tctx_t *
extent_prof_tctx_get(const extent_t * extent)161 extent_prof_tctx_get(const extent_t *extent)
162 {
163 return ((prof_tctx_t *)atomic_read_p(
164 &((extent_t *)extent)->e_prof_tctx_pun));
165 }
166
167 JEMALLOC_INLINE void
extent_arena_set(extent_t * extent,arena_t * arena)168 extent_arena_set(extent_t *extent, arena_t *arena)
169 {
170 extent->e_arena = arena;
171 }
172
173 JEMALLOC_INLINE void
extent_addr_set(extent_t * extent,void * addr)174 extent_addr_set(extent_t *extent, void *addr)
175 {
176 extent->e_addr = addr;
177 }
178
179 JEMALLOC_INLINE void
extent_addr_randomize(tsdn_t * tsdn,extent_t * extent,size_t alignment)180 extent_addr_randomize(tsdn_t *tsdn, extent_t *extent, size_t alignment)
181 {
182 assert(extent_base_get(extent) == extent_addr_get(extent));
183
184 if (alignment < PAGE) {
185 unsigned lg_range = LG_PAGE -
186 lg_floor(CACHELINE_CEILING(alignment));
187 size_t r =
188 prng_lg_range_zu(&extent_arena_get(extent)->offset_state,
189 lg_range, true);
190 uintptr_t random_offset = ((uintptr_t)r) << (LG_PAGE -
191 lg_range);
192 extent->e_addr = (void *)((uintptr_t)extent->e_addr +
193 random_offset);
194 assert(ALIGNMENT_ADDR2BASE(extent->e_addr, alignment) ==
195 extent->e_addr);
196 }
197 }
198
199 JEMALLOC_INLINE void
extent_size_set(extent_t * extent,size_t size)200 extent_size_set(extent_t *extent, size_t size)
201 {
202 extent->e_size = size;
203 }
204
205 JEMALLOC_INLINE void
extent_usize_set(extent_t * extent,size_t usize)206 extent_usize_set(extent_t *extent, size_t usize)
207 {
208 extent->e_usize = usize;
209 }
210
211 JEMALLOC_INLINE void
extent_sn_set(extent_t * extent,size_t sn)212 extent_sn_set(extent_t *extent, size_t sn)
213 {
214 extent->e_sn = sn;
215 }
216
217 JEMALLOC_INLINE void
extent_active_set(extent_t * extent,bool active)218 extent_active_set(extent_t *extent, bool active)
219 {
220 extent->e_active = active;
221 }
222
223 JEMALLOC_INLINE void
extent_zeroed_set(extent_t * extent,bool zeroed)224 extent_zeroed_set(extent_t *extent, bool zeroed)
225 {
226 extent->e_zeroed = zeroed;
227 }
228
229 JEMALLOC_INLINE void
extent_committed_set(extent_t * extent,bool committed)230 extent_committed_set(extent_t *extent, bool committed)
231 {
232 extent->e_committed = committed;
233 }
234
235 JEMALLOC_INLINE void
extent_slab_set(extent_t * extent,bool slab)236 extent_slab_set(extent_t *extent, bool slab)
237 {
238 extent->e_slab = slab;
239 }
240
241 JEMALLOC_INLINE void
extent_prof_tctx_set(extent_t * extent,prof_tctx_t * tctx)242 extent_prof_tctx_set(extent_t *extent, prof_tctx_t *tctx)
243 {
244 atomic_write_p(&extent->e_prof_tctx_pun, tctx);
245 }
246
247 JEMALLOC_INLINE void
extent_init(extent_t * extent,arena_t * arena,void * addr,size_t size,size_t usize,size_t sn,bool active,bool zeroed,bool committed,bool slab)248 extent_init(extent_t *extent, arena_t *arena, void *addr, size_t size,
249 size_t usize, size_t sn, bool active, bool zeroed, bool committed,
250 bool slab)
251 {
252 assert(addr == PAGE_ADDR2BASE(addr) || !slab);
253
254 extent_arena_set(extent, arena);
255 extent_addr_set(extent, addr);
256 extent_size_set(extent, size);
257 extent_usize_set(extent, usize);
258 extent_sn_set(extent, sn);
259 extent_active_set(extent, active);
260 extent_zeroed_set(extent, zeroed);
261 extent_committed_set(extent, committed);
262 extent_slab_set(extent, slab);
263 if (config_prof)
264 extent_prof_tctx_set(extent, NULL);
265 qr_new(extent, qr_link);
266 }
267
268 JEMALLOC_INLINE void
extent_ring_insert(extent_t * sentinel,extent_t * extent)269 extent_ring_insert(extent_t *sentinel, extent_t *extent)
270 {
271 qr_meld(sentinel, extent, extent_t, qr_link);
272 }
273
274 JEMALLOC_INLINE void
extent_ring_remove(extent_t * extent)275 extent_ring_remove(extent_t *extent)
276 {
277 qr_remove(extent, qr_link);
278 }
279
280 JEMALLOC_INLINE int
extent_sn_comp(const extent_t * a,const extent_t * b)281 extent_sn_comp(const extent_t *a, const extent_t *b)
282 {
283 size_t a_sn = extent_sn_get(a);
284 size_t b_sn = extent_sn_get(b);
285
286 return ((a_sn > b_sn) - (a_sn < b_sn));
287 }
288
289 JEMALLOC_INLINE int
extent_ad_comp(const extent_t * a,const extent_t * b)290 extent_ad_comp(const extent_t *a, const extent_t *b)
291 {
292 uintptr_t a_addr = (uintptr_t)extent_addr_get(a);
293 uintptr_t b_addr = (uintptr_t)extent_addr_get(b);
294
295 return ((a_addr > b_addr) - (a_addr < b_addr));
296 }
297
298 JEMALLOC_INLINE int
extent_snad_comp(const extent_t * a,const extent_t * b)299 extent_snad_comp(const extent_t *a, const extent_t *b)
300 {
301 int ret;
302
303 ret = extent_sn_comp(a, b);
304 if (ret != 0)
305 return (ret);
306
307 ret = extent_ad_comp(a, b);
308 return (ret);
309 }
310 #endif
311
312 #endif /* JEMALLOC_INTERNAL_EXTENT_INLINES_H */
313