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