1 #ifndef JEMALLOC_INTERNAL_ARENA_INLINES_B_H
2 #define JEMALLOC_INTERNAL_ARENA_INLINES_B_H
3 
4 #ifndef JEMALLOC_ENABLE_INLINE
5 szind_t	arena_bin_index(arena_t *arena, arena_bin_t *bin);
6 prof_tctx_t	*arena_prof_tctx_get(tsdn_t *tsdn, const extent_t *extent,
7     const void *ptr);
8 void	arena_prof_tctx_set(tsdn_t *tsdn, extent_t *extent, const void *ptr,
9     size_t usize, prof_tctx_t *tctx);
10 void	arena_prof_tctx_reset(tsdn_t *tsdn, extent_t *extent, const void *ptr,
11     prof_tctx_t *tctx);
12 void	arena_decay_ticks(tsdn_t *tsdn, arena_t *arena, unsigned nticks);
13 void	arena_decay_tick(tsdn_t *tsdn, arena_t *arena);
14 void	*arena_malloc(tsdn_t *tsdn, arena_t *arena, size_t size, szind_t ind,
15     bool zero, tcache_t *tcache, bool slow_path);
16 arena_t	*arena_aalloc(tsdn_t *tsdn, const void *ptr);
17 size_t	arena_salloc(tsdn_t *tsdn, const extent_t *extent, const void *ptr);
18 void	arena_dalloc(tsdn_t *tsdn, extent_t *extent, void *ptr,
19     tcache_t *tcache, bool slow_path);
20 void	arena_sdalloc(tsdn_t *tsdn, extent_t *extent, void *ptr, size_t size,
21     tcache_t *tcache, bool slow_path);
22 #endif
23 
24 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ARENA_C_))
25 JEMALLOC_INLINE szind_t
arena_bin_index(arena_t * arena,arena_bin_t * bin)26 arena_bin_index(arena_t *arena, arena_bin_t *bin)
27 {
28 	szind_t binind = (szind_t)(bin - arena->bins);
29 	assert(binind < NBINS);
30 	return (binind);
31 }
32 
33 JEMALLOC_INLINE prof_tctx_t *
arena_prof_tctx_get(tsdn_t * tsdn,const extent_t * extent,const void * ptr)34 arena_prof_tctx_get(tsdn_t *tsdn, const extent_t *extent, const void *ptr)
35 {
36 	cassert(config_prof);
37 	assert(ptr != NULL);
38 
39 	if (unlikely(!extent_slab_get(extent)))
40 		return (large_prof_tctx_get(tsdn, extent));
41 	return ((prof_tctx_t *)(uintptr_t)1U);
42 }
43 
44 JEMALLOC_INLINE void
arena_prof_tctx_set(tsdn_t * tsdn,extent_t * extent,const void * ptr,size_t usize,prof_tctx_t * tctx)45 arena_prof_tctx_set(tsdn_t *tsdn, extent_t *extent, const void *ptr,
46     size_t usize, prof_tctx_t *tctx)
47 {
48 	cassert(config_prof);
49 	assert(ptr != NULL);
50 
51 	if (unlikely(!extent_slab_get(extent)))
52 		large_prof_tctx_set(tsdn, extent, tctx);
53 }
54 
55 JEMALLOC_INLINE void
arena_prof_tctx_reset(tsdn_t * tsdn,extent_t * extent,const void * ptr,prof_tctx_t * tctx)56 arena_prof_tctx_reset(tsdn_t *tsdn, extent_t *extent, const void *ptr,
57     prof_tctx_t *tctx)
58 {
59 	cassert(config_prof);
60 	assert(ptr != NULL);
61 	assert(!extent_slab_get(extent));
62 
63 	large_prof_tctx_reset(tsdn, extent);
64 }
65 
66 JEMALLOC_ALWAYS_INLINE void
arena_decay_ticks(tsdn_t * tsdn,arena_t * arena,unsigned nticks)67 arena_decay_ticks(tsdn_t *tsdn, arena_t *arena, unsigned nticks)
68 {
69 	tsd_t *tsd;
70 	ticker_t *decay_ticker;
71 
72 	if (unlikely(tsdn_null(tsdn)))
73 		return;
74 	tsd = tsdn_tsd(tsdn);
75 	decay_ticker = decay_ticker_get(tsd, arena_ind_get(arena));
76 	if (unlikely(decay_ticker == NULL))
77 		return;
78 	if (unlikely(ticker_ticks(decay_ticker, nticks)))
79 		arena_purge(tsdn, arena, false);
80 }
81 
82 JEMALLOC_ALWAYS_INLINE void
arena_decay_tick(tsdn_t * tsdn,arena_t * arena)83 arena_decay_tick(tsdn_t *tsdn, arena_t *arena)
84 {
85 	malloc_mutex_assert_not_owner(tsdn, &arena->lock);
86 
87 	arena_decay_ticks(tsdn, arena, 1);
88 }
89 
90 JEMALLOC_ALWAYS_INLINE void *
arena_malloc(tsdn_t * tsdn,arena_t * arena,size_t size,szind_t ind,bool zero,tcache_t * tcache,bool slow_path)91 arena_malloc(tsdn_t *tsdn, arena_t *arena, size_t size, szind_t ind, bool zero,
92     tcache_t *tcache, bool slow_path)
93 {
94 	assert(!tsdn_null(tsdn) || tcache == NULL);
95 	assert(size != 0);
96 
97 	if (likely(tcache != NULL)) {
98 		if (likely(size <= SMALL_MAXCLASS)) {
99 			return (tcache_alloc_small(tsdn_tsd(tsdn), arena,
100 			    tcache, size, ind, zero, slow_path));
101 		}
102 		if (likely(size <= tcache_maxclass)) {
103 			return (tcache_alloc_large(tsdn_tsd(tsdn), arena,
104 			    tcache, size, ind, zero, slow_path));
105 		}
106 		/* (size > tcache_maxclass) case falls through. */
107 		assert(size > tcache_maxclass);
108 	}
109 
110 	return (arena_malloc_hard(tsdn, arena, size, ind, zero));
111 }
112 
113 JEMALLOC_ALWAYS_INLINE arena_t *
arena_aalloc(tsdn_t * tsdn,const void * ptr)114 arena_aalloc(tsdn_t *tsdn, const void *ptr)
115 {
116 	return (extent_arena_get(iealloc(tsdn, ptr)));
117 }
118 
119 /* Return the size of the allocation pointed to by ptr. */
120 JEMALLOC_ALWAYS_INLINE size_t
arena_salloc(tsdn_t * tsdn,const extent_t * extent,const void * ptr)121 arena_salloc(tsdn_t *tsdn, const extent_t *extent, const void *ptr)
122 {
123 	size_t ret;
124 
125 	assert(ptr != NULL);
126 
127 	if (likely(extent_slab_get(extent)))
128 		ret = index2size(extent_slab_data_get_const(extent)->binind);
129 	else
130 		ret = large_salloc(tsdn, extent);
131 
132 	return (ret);
133 }
134 
135 JEMALLOC_ALWAYS_INLINE void
arena_dalloc(tsdn_t * tsdn,extent_t * extent,void * ptr,tcache_t * tcache,bool slow_path)136 arena_dalloc(tsdn_t *tsdn, extent_t *extent, void *ptr, tcache_t *tcache,
137     bool slow_path)
138 {
139 	assert(!tsdn_null(tsdn) || tcache == NULL);
140 	assert(ptr != NULL);
141 
142 	if (likely(extent_slab_get(extent))) {
143 		/* Small allocation. */
144 		if (likely(tcache != NULL)) {
145 			szind_t binind = extent_slab_data_get(extent)->binind;
146 			tcache_dalloc_small(tsdn_tsd(tsdn), tcache, ptr, binind,
147 			    slow_path);
148 		} else {
149 			arena_dalloc_small(tsdn, extent_arena_get(extent),
150 			    extent, ptr);
151 		}
152 	} else {
153 		size_t usize = extent_usize_get(extent);
154 
155 		if (likely(tcache != NULL) && usize <= tcache_maxclass) {
156 			if (config_prof && unlikely(usize <= SMALL_MAXCLASS)) {
157 				arena_dalloc_promoted(tsdn, extent, ptr,
158 				    tcache, slow_path);
159 			} else {
160 				tcache_dalloc_large(tsdn_tsd(tsdn), tcache,
161 				    ptr, usize, slow_path);
162 			}
163 		} else
164 			large_dalloc(tsdn, extent);
165 	}
166 }
167 
168 JEMALLOC_ALWAYS_INLINE void
arena_sdalloc(tsdn_t * tsdn,extent_t * extent,void * ptr,size_t size,tcache_t * tcache,bool slow_path)169 arena_sdalloc(tsdn_t *tsdn, extent_t *extent, void *ptr, size_t size,
170     tcache_t *tcache, bool slow_path)
171 {
172 	assert(!tsdn_null(tsdn) || tcache == NULL);
173 	assert(ptr != NULL);
174 
175 	if (likely(extent_slab_get(extent))) {
176 		/* Small allocation. */
177 		if (likely(tcache != NULL)) {
178 			szind_t binind = size2index(size);
179 			assert(binind == extent_slab_data_get(extent)->binind);
180 			tcache_dalloc_small(tsdn_tsd(tsdn), tcache, ptr, binind,
181 			    slow_path);
182 		} else {
183 			arena_dalloc_small(tsdn, extent_arena_get(extent),
184 			    extent, ptr);
185 		}
186 	} else {
187 		if (likely(tcache != NULL) && size <= tcache_maxclass) {
188 			if (config_prof && unlikely(size <= SMALL_MAXCLASS)) {
189 				arena_dalloc_promoted(tsdn, extent, ptr,
190 				    tcache, slow_path);
191 			} else {
192 				tcache_dalloc_large(tsdn_tsd(tsdn), tcache, ptr,
193 				    size, slow_path);
194 			}
195 		} else
196 			large_dalloc(tsdn, extent);
197 	}
198 }
199 
200 #endif /* (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ARENA_C_)) */
201 #endif /* JEMALLOC_INTERNAL_ARENA_INLINES_B_H */
202