1*1208bc7eSAndroid Build Coastguard Worker #ifndef JEMALLOC_INTERNAL_SIZE_H
2*1208bc7eSAndroid Build Coastguard Worker #define JEMALLOC_INTERNAL_SIZE_H
3*1208bc7eSAndroid Build Coastguard Worker
4*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/bit_util.h"
5*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/pages.h"
6*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/size_classes.h"
7*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/util.h"
8*1208bc7eSAndroid Build Coastguard Worker
9*1208bc7eSAndroid Build Coastguard Worker /*
10*1208bc7eSAndroid Build Coastguard Worker * sz module: Size computations.
11*1208bc7eSAndroid Build Coastguard Worker *
12*1208bc7eSAndroid Build Coastguard Worker * Some abbreviations used here:
13*1208bc7eSAndroid Build Coastguard Worker * p: Page
14*1208bc7eSAndroid Build Coastguard Worker * ind: Index
15*1208bc7eSAndroid Build Coastguard Worker * s, sz: Size
16*1208bc7eSAndroid Build Coastguard Worker * u: Usable size
17*1208bc7eSAndroid Build Coastguard Worker * a: Aligned
18*1208bc7eSAndroid Build Coastguard Worker *
19*1208bc7eSAndroid Build Coastguard Worker * These are not always used completely consistently, but should be enough to
20*1208bc7eSAndroid Build Coastguard Worker * interpret function names. E.g. sz_psz2ind converts page size to page size
21*1208bc7eSAndroid Build Coastguard Worker * index; sz_sa2u converts a (size, alignment) allocation request to the usable
22*1208bc7eSAndroid Build Coastguard Worker * size that would result from such an allocation.
23*1208bc7eSAndroid Build Coastguard Worker */
24*1208bc7eSAndroid Build Coastguard Worker
25*1208bc7eSAndroid Build Coastguard Worker /*
26*1208bc7eSAndroid Build Coastguard Worker * sz_pind2sz_tab encodes the same information as could be computed by
27*1208bc7eSAndroid Build Coastguard Worker * sz_pind2sz_compute().
28*1208bc7eSAndroid Build Coastguard Worker */
29*1208bc7eSAndroid Build Coastguard Worker extern size_t const sz_pind2sz_tab[NPSIZES+1];
30*1208bc7eSAndroid Build Coastguard Worker /*
31*1208bc7eSAndroid Build Coastguard Worker * sz_index2size_tab encodes the same information as could be computed (at
32*1208bc7eSAndroid Build Coastguard Worker * unacceptable cost in some code paths) by sz_index2size_compute().
33*1208bc7eSAndroid Build Coastguard Worker */
34*1208bc7eSAndroid Build Coastguard Worker extern size_t const sz_index2size_tab[NSIZES];
35*1208bc7eSAndroid Build Coastguard Worker /*
36*1208bc7eSAndroid Build Coastguard Worker * sz_size2index_tab is a compact lookup table that rounds request sizes up to
37*1208bc7eSAndroid Build Coastguard Worker * size classes. In order to reduce cache footprint, the table is compressed,
38*1208bc7eSAndroid Build Coastguard Worker * and all accesses are via sz_size2index().
39*1208bc7eSAndroid Build Coastguard Worker */
40*1208bc7eSAndroid Build Coastguard Worker extern uint8_t const sz_size2index_tab[];
41*1208bc7eSAndroid Build Coastguard Worker
42*1208bc7eSAndroid Build Coastguard Worker static const size_t sz_large_pad =
43*1208bc7eSAndroid Build Coastguard Worker #ifdef JEMALLOC_CACHE_OBLIVIOUS
44*1208bc7eSAndroid Build Coastguard Worker PAGE
45*1208bc7eSAndroid Build Coastguard Worker #else
46*1208bc7eSAndroid Build Coastguard Worker 0
47*1208bc7eSAndroid Build Coastguard Worker #endif
48*1208bc7eSAndroid Build Coastguard Worker ;
49*1208bc7eSAndroid Build Coastguard Worker
50*1208bc7eSAndroid Build Coastguard Worker JEMALLOC_ALWAYS_INLINE pszind_t
sz_psz2ind(size_t psz)51*1208bc7eSAndroid Build Coastguard Worker sz_psz2ind(size_t psz) {
52*1208bc7eSAndroid Build Coastguard Worker if (unlikely(psz > LARGE_MAXCLASS)) {
53*1208bc7eSAndroid Build Coastguard Worker return NPSIZES;
54*1208bc7eSAndroid Build Coastguard Worker }
55*1208bc7eSAndroid Build Coastguard Worker {
56*1208bc7eSAndroid Build Coastguard Worker pszind_t x = lg_floor((psz<<1)-1);
57*1208bc7eSAndroid Build Coastguard Worker pszind_t shift = (x < LG_SIZE_CLASS_GROUP + LG_PAGE) ? 0 : x -
58*1208bc7eSAndroid Build Coastguard Worker (LG_SIZE_CLASS_GROUP + LG_PAGE);
59*1208bc7eSAndroid Build Coastguard Worker pszind_t grp = shift << LG_SIZE_CLASS_GROUP;
60*1208bc7eSAndroid Build Coastguard Worker
61*1208bc7eSAndroid Build Coastguard Worker pszind_t lg_delta = (x < LG_SIZE_CLASS_GROUP + LG_PAGE + 1) ?
62*1208bc7eSAndroid Build Coastguard Worker LG_PAGE : x - LG_SIZE_CLASS_GROUP - 1;
63*1208bc7eSAndroid Build Coastguard Worker
64*1208bc7eSAndroid Build Coastguard Worker size_t delta_inverse_mask = ZU(-1) << lg_delta;
65*1208bc7eSAndroid Build Coastguard Worker pszind_t mod = ((((psz-1) & delta_inverse_mask) >> lg_delta)) &
66*1208bc7eSAndroid Build Coastguard Worker ((ZU(1) << LG_SIZE_CLASS_GROUP) - 1);
67*1208bc7eSAndroid Build Coastguard Worker
68*1208bc7eSAndroid Build Coastguard Worker pszind_t ind = grp + mod;
69*1208bc7eSAndroid Build Coastguard Worker return ind;
70*1208bc7eSAndroid Build Coastguard Worker }
71*1208bc7eSAndroid Build Coastguard Worker }
72*1208bc7eSAndroid Build Coastguard Worker
73*1208bc7eSAndroid Build Coastguard Worker static inline size_t
sz_pind2sz_compute(pszind_t pind)74*1208bc7eSAndroid Build Coastguard Worker sz_pind2sz_compute(pszind_t pind) {
75*1208bc7eSAndroid Build Coastguard Worker if (unlikely(pind == NPSIZES)) {
76*1208bc7eSAndroid Build Coastguard Worker return LARGE_MAXCLASS + PAGE;
77*1208bc7eSAndroid Build Coastguard Worker }
78*1208bc7eSAndroid Build Coastguard Worker {
79*1208bc7eSAndroid Build Coastguard Worker size_t grp = pind >> LG_SIZE_CLASS_GROUP;
80*1208bc7eSAndroid Build Coastguard Worker size_t mod = pind & ((ZU(1) << LG_SIZE_CLASS_GROUP) - 1);
81*1208bc7eSAndroid Build Coastguard Worker
82*1208bc7eSAndroid Build Coastguard Worker size_t grp_size_mask = ~((!!grp)-1);
83*1208bc7eSAndroid Build Coastguard Worker size_t grp_size = ((ZU(1) << (LG_PAGE +
84*1208bc7eSAndroid Build Coastguard Worker (LG_SIZE_CLASS_GROUP-1))) << grp) & grp_size_mask;
85*1208bc7eSAndroid Build Coastguard Worker
86*1208bc7eSAndroid Build Coastguard Worker size_t shift = (grp == 0) ? 1 : grp;
87*1208bc7eSAndroid Build Coastguard Worker size_t lg_delta = shift + (LG_PAGE-1);
88*1208bc7eSAndroid Build Coastguard Worker size_t mod_size = (mod+1) << lg_delta;
89*1208bc7eSAndroid Build Coastguard Worker
90*1208bc7eSAndroid Build Coastguard Worker size_t sz = grp_size + mod_size;
91*1208bc7eSAndroid Build Coastguard Worker return sz;
92*1208bc7eSAndroid Build Coastguard Worker }
93*1208bc7eSAndroid Build Coastguard Worker }
94*1208bc7eSAndroid Build Coastguard Worker
95*1208bc7eSAndroid Build Coastguard Worker static inline size_t
sz_pind2sz_lookup(pszind_t pind)96*1208bc7eSAndroid Build Coastguard Worker sz_pind2sz_lookup(pszind_t pind) {
97*1208bc7eSAndroid Build Coastguard Worker size_t ret = (size_t)sz_pind2sz_tab[pind];
98*1208bc7eSAndroid Build Coastguard Worker assert(ret == sz_pind2sz_compute(pind));
99*1208bc7eSAndroid Build Coastguard Worker return ret;
100*1208bc7eSAndroid Build Coastguard Worker }
101*1208bc7eSAndroid Build Coastguard Worker
102*1208bc7eSAndroid Build Coastguard Worker static inline size_t
sz_pind2sz(pszind_t pind)103*1208bc7eSAndroid Build Coastguard Worker sz_pind2sz(pszind_t pind) {
104*1208bc7eSAndroid Build Coastguard Worker assert(pind < NPSIZES+1);
105*1208bc7eSAndroid Build Coastguard Worker return sz_pind2sz_lookup(pind);
106*1208bc7eSAndroid Build Coastguard Worker }
107*1208bc7eSAndroid Build Coastguard Worker
108*1208bc7eSAndroid Build Coastguard Worker static inline size_t
sz_psz2u(size_t psz)109*1208bc7eSAndroid Build Coastguard Worker sz_psz2u(size_t psz) {
110*1208bc7eSAndroid Build Coastguard Worker if (unlikely(psz > LARGE_MAXCLASS)) {
111*1208bc7eSAndroid Build Coastguard Worker return LARGE_MAXCLASS + PAGE;
112*1208bc7eSAndroid Build Coastguard Worker }
113*1208bc7eSAndroid Build Coastguard Worker {
114*1208bc7eSAndroid Build Coastguard Worker size_t x = lg_floor((psz<<1)-1);
115*1208bc7eSAndroid Build Coastguard Worker size_t lg_delta = (x < LG_SIZE_CLASS_GROUP + LG_PAGE + 1) ?
116*1208bc7eSAndroid Build Coastguard Worker LG_PAGE : x - LG_SIZE_CLASS_GROUP - 1;
117*1208bc7eSAndroid Build Coastguard Worker size_t delta = ZU(1) << lg_delta;
118*1208bc7eSAndroid Build Coastguard Worker size_t delta_mask = delta - 1;
119*1208bc7eSAndroid Build Coastguard Worker size_t usize = (psz + delta_mask) & ~delta_mask;
120*1208bc7eSAndroid Build Coastguard Worker return usize;
121*1208bc7eSAndroid Build Coastguard Worker }
122*1208bc7eSAndroid Build Coastguard Worker }
123*1208bc7eSAndroid Build Coastguard Worker
124*1208bc7eSAndroid Build Coastguard Worker static inline szind_t
sz_size2index_compute(size_t size)125*1208bc7eSAndroid Build Coastguard Worker sz_size2index_compute(size_t size) {
126*1208bc7eSAndroid Build Coastguard Worker if (unlikely(size > LARGE_MAXCLASS)) {
127*1208bc7eSAndroid Build Coastguard Worker return NSIZES;
128*1208bc7eSAndroid Build Coastguard Worker }
129*1208bc7eSAndroid Build Coastguard Worker #if (NTBINS != 0)
130*1208bc7eSAndroid Build Coastguard Worker if (size <= (ZU(1) << LG_TINY_MAXCLASS)) {
131*1208bc7eSAndroid Build Coastguard Worker szind_t lg_tmin = LG_TINY_MAXCLASS - NTBINS + 1;
132*1208bc7eSAndroid Build Coastguard Worker szind_t lg_ceil = lg_floor(pow2_ceil_zu(size));
133*1208bc7eSAndroid Build Coastguard Worker return (lg_ceil < lg_tmin ? 0 : lg_ceil - lg_tmin);
134*1208bc7eSAndroid Build Coastguard Worker }
135*1208bc7eSAndroid Build Coastguard Worker #endif
136*1208bc7eSAndroid Build Coastguard Worker {
137*1208bc7eSAndroid Build Coastguard Worker szind_t x = lg_floor((size<<1)-1);
138*1208bc7eSAndroid Build Coastguard Worker szind_t shift = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM) ? 0 :
139*1208bc7eSAndroid Build Coastguard Worker x - (LG_SIZE_CLASS_GROUP + LG_QUANTUM);
140*1208bc7eSAndroid Build Coastguard Worker szind_t grp = shift << LG_SIZE_CLASS_GROUP;
141*1208bc7eSAndroid Build Coastguard Worker
142*1208bc7eSAndroid Build Coastguard Worker szind_t lg_delta = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM + 1)
143*1208bc7eSAndroid Build Coastguard Worker ? LG_QUANTUM : x - LG_SIZE_CLASS_GROUP - 1;
144*1208bc7eSAndroid Build Coastguard Worker
145*1208bc7eSAndroid Build Coastguard Worker size_t delta_inverse_mask = ZU(-1) << lg_delta;
146*1208bc7eSAndroid Build Coastguard Worker szind_t mod = ((((size-1) & delta_inverse_mask) >> lg_delta)) &
147*1208bc7eSAndroid Build Coastguard Worker ((ZU(1) << LG_SIZE_CLASS_GROUP) - 1);
148*1208bc7eSAndroid Build Coastguard Worker
149*1208bc7eSAndroid Build Coastguard Worker szind_t index = NTBINS + grp + mod;
150*1208bc7eSAndroid Build Coastguard Worker return index;
151*1208bc7eSAndroid Build Coastguard Worker }
152*1208bc7eSAndroid Build Coastguard Worker }
153*1208bc7eSAndroid Build Coastguard Worker
154*1208bc7eSAndroid Build Coastguard Worker JEMALLOC_ALWAYS_INLINE szind_t
sz_size2index_lookup(size_t size)155*1208bc7eSAndroid Build Coastguard Worker sz_size2index_lookup(size_t size) {
156*1208bc7eSAndroid Build Coastguard Worker assert(size <= LOOKUP_MAXCLASS);
157*1208bc7eSAndroid Build Coastguard Worker {
158*1208bc7eSAndroid Build Coastguard Worker szind_t ret = (sz_size2index_tab[(size-1) >> LG_TINY_MIN]);
159*1208bc7eSAndroid Build Coastguard Worker assert(ret == sz_size2index_compute(size));
160*1208bc7eSAndroid Build Coastguard Worker return ret;
161*1208bc7eSAndroid Build Coastguard Worker }
162*1208bc7eSAndroid Build Coastguard Worker }
163*1208bc7eSAndroid Build Coastguard Worker
164*1208bc7eSAndroid Build Coastguard Worker JEMALLOC_ALWAYS_INLINE szind_t
sz_size2index(size_t size)165*1208bc7eSAndroid Build Coastguard Worker sz_size2index(size_t size) {
166*1208bc7eSAndroid Build Coastguard Worker assert(size > 0);
167*1208bc7eSAndroid Build Coastguard Worker if (likely(size <= LOOKUP_MAXCLASS)) {
168*1208bc7eSAndroid Build Coastguard Worker return sz_size2index_lookup(size);
169*1208bc7eSAndroid Build Coastguard Worker }
170*1208bc7eSAndroid Build Coastguard Worker return sz_size2index_compute(size);
171*1208bc7eSAndroid Build Coastguard Worker }
172*1208bc7eSAndroid Build Coastguard Worker
173*1208bc7eSAndroid Build Coastguard Worker static inline size_t
sz_index2size_compute(szind_t index)174*1208bc7eSAndroid Build Coastguard Worker sz_index2size_compute(szind_t index) {
175*1208bc7eSAndroid Build Coastguard Worker #if (NTBINS > 0)
176*1208bc7eSAndroid Build Coastguard Worker if (index < NTBINS) {
177*1208bc7eSAndroid Build Coastguard Worker return (ZU(1) << (LG_TINY_MAXCLASS - NTBINS + 1 + index));
178*1208bc7eSAndroid Build Coastguard Worker }
179*1208bc7eSAndroid Build Coastguard Worker #endif
180*1208bc7eSAndroid Build Coastguard Worker {
181*1208bc7eSAndroid Build Coastguard Worker size_t reduced_index = index - NTBINS;
182*1208bc7eSAndroid Build Coastguard Worker size_t grp = reduced_index >> LG_SIZE_CLASS_GROUP;
183*1208bc7eSAndroid Build Coastguard Worker size_t mod = reduced_index & ((ZU(1) << LG_SIZE_CLASS_GROUP) -
184*1208bc7eSAndroid Build Coastguard Worker 1);
185*1208bc7eSAndroid Build Coastguard Worker
186*1208bc7eSAndroid Build Coastguard Worker size_t grp_size_mask = ~((!!grp)-1);
187*1208bc7eSAndroid Build Coastguard Worker size_t grp_size = ((ZU(1) << (LG_QUANTUM +
188*1208bc7eSAndroid Build Coastguard Worker (LG_SIZE_CLASS_GROUP-1))) << grp) & grp_size_mask;
189*1208bc7eSAndroid Build Coastguard Worker
190*1208bc7eSAndroid Build Coastguard Worker size_t shift = (grp == 0) ? 1 : grp;
191*1208bc7eSAndroid Build Coastguard Worker size_t lg_delta = shift + (LG_QUANTUM-1);
192*1208bc7eSAndroid Build Coastguard Worker size_t mod_size = (mod+1) << lg_delta;
193*1208bc7eSAndroid Build Coastguard Worker
194*1208bc7eSAndroid Build Coastguard Worker size_t usize = grp_size + mod_size;
195*1208bc7eSAndroid Build Coastguard Worker return usize;
196*1208bc7eSAndroid Build Coastguard Worker }
197*1208bc7eSAndroid Build Coastguard Worker }
198*1208bc7eSAndroid Build Coastguard Worker
199*1208bc7eSAndroid Build Coastguard Worker JEMALLOC_ALWAYS_INLINE size_t
sz_index2size_lookup(szind_t index)200*1208bc7eSAndroid Build Coastguard Worker sz_index2size_lookup(szind_t index) {
201*1208bc7eSAndroid Build Coastguard Worker size_t ret = (size_t)sz_index2size_tab[index];
202*1208bc7eSAndroid Build Coastguard Worker assert(ret == sz_index2size_compute(index));
203*1208bc7eSAndroid Build Coastguard Worker return ret;
204*1208bc7eSAndroid Build Coastguard Worker }
205*1208bc7eSAndroid Build Coastguard Worker
206*1208bc7eSAndroid Build Coastguard Worker JEMALLOC_ALWAYS_INLINE size_t
sz_index2size(szind_t index)207*1208bc7eSAndroid Build Coastguard Worker sz_index2size(szind_t index) {
208*1208bc7eSAndroid Build Coastguard Worker assert(index < NSIZES);
209*1208bc7eSAndroid Build Coastguard Worker return sz_index2size_lookup(index);
210*1208bc7eSAndroid Build Coastguard Worker }
211*1208bc7eSAndroid Build Coastguard Worker
212*1208bc7eSAndroid Build Coastguard Worker JEMALLOC_ALWAYS_INLINE size_t
sz_s2u_compute(size_t size)213*1208bc7eSAndroid Build Coastguard Worker sz_s2u_compute(size_t size) {
214*1208bc7eSAndroid Build Coastguard Worker if (unlikely(size > LARGE_MAXCLASS)) {
215*1208bc7eSAndroid Build Coastguard Worker return 0;
216*1208bc7eSAndroid Build Coastguard Worker }
217*1208bc7eSAndroid Build Coastguard Worker #if (NTBINS > 0)
218*1208bc7eSAndroid Build Coastguard Worker if (size <= (ZU(1) << LG_TINY_MAXCLASS)) {
219*1208bc7eSAndroid Build Coastguard Worker size_t lg_tmin = LG_TINY_MAXCLASS - NTBINS + 1;
220*1208bc7eSAndroid Build Coastguard Worker size_t lg_ceil = lg_floor(pow2_ceil_zu(size));
221*1208bc7eSAndroid Build Coastguard Worker return (lg_ceil < lg_tmin ? (ZU(1) << lg_tmin) :
222*1208bc7eSAndroid Build Coastguard Worker (ZU(1) << lg_ceil));
223*1208bc7eSAndroid Build Coastguard Worker }
224*1208bc7eSAndroid Build Coastguard Worker #endif
225*1208bc7eSAndroid Build Coastguard Worker {
226*1208bc7eSAndroid Build Coastguard Worker size_t x = lg_floor((size<<1)-1);
227*1208bc7eSAndroid Build Coastguard Worker size_t lg_delta = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM + 1)
228*1208bc7eSAndroid Build Coastguard Worker ? LG_QUANTUM : x - LG_SIZE_CLASS_GROUP - 1;
229*1208bc7eSAndroid Build Coastguard Worker size_t delta = ZU(1) << lg_delta;
230*1208bc7eSAndroid Build Coastguard Worker size_t delta_mask = delta - 1;
231*1208bc7eSAndroid Build Coastguard Worker size_t usize = (size + delta_mask) & ~delta_mask;
232*1208bc7eSAndroid Build Coastguard Worker return usize;
233*1208bc7eSAndroid Build Coastguard Worker }
234*1208bc7eSAndroid Build Coastguard Worker }
235*1208bc7eSAndroid Build Coastguard Worker
236*1208bc7eSAndroid Build Coastguard Worker JEMALLOC_ALWAYS_INLINE size_t
sz_s2u_lookup(size_t size)237*1208bc7eSAndroid Build Coastguard Worker sz_s2u_lookup(size_t size) {
238*1208bc7eSAndroid Build Coastguard Worker size_t ret = sz_index2size_lookup(sz_size2index_lookup(size));
239*1208bc7eSAndroid Build Coastguard Worker
240*1208bc7eSAndroid Build Coastguard Worker assert(ret == sz_s2u_compute(size));
241*1208bc7eSAndroid Build Coastguard Worker return ret;
242*1208bc7eSAndroid Build Coastguard Worker }
243*1208bc7eSAndroid Build Coastguard Worker
244*1208bc7eSAndroid Build Coastguard Worker /*
245*1208bc7eSAndroid Build Coastguard Worker * Compute usable size that would result from allocating an object with the
246*1208bc7eSAndroid Build Coastguard Worker * specified size.
247*1208bc7eSAndroid Build Coastguard Worker */
248*1208bc7eSAndroid Build Coastguard Worker JEMALLOC_ALWAYS_INLINE size_t
sz_s2u(size_t size)249*1208bc7eSAndroid Build Coastguard Worker sz_s2u(size_t size) {
250*1208bc7eSAndroid Build Coastguard Worker assert(size > 0);
251*1208bc7eSAndroid Build Coastguard Worker if (likely(size <= LOOKUP_MAXCLASS)) {
252*1208bc7eSAndroid Build Coastguard Worker return sz_s2u_lookup(size);
253*1208bc7eSAndroid Build Coastguard Worker }
254*1208bc7eSAndroid Build Coastguard Worker return sz_s2u_compute(size);
255*1208bc7eSAndroid Build Coastguard Worker }
256*1208bc7eSAndroid Build Coastguard Worker
257*1208bc7eSAndroid Build Coastguard Worker /*
258*1208bc7eSAndroid Build Coastguard Worker * Compute usable size that would result from allocating an object with the
259*1208bc7eSAndroid Build Coastguard Worker * specified size and alignment.
260*1208bc7eSAndroid Build Coastguard Worker */
261*1208bc7eSAndroid Build Coastguard Worker JEMALLOC_ALWAYS_INLINE size_t
sz_sa2u(size_t size,size_t alignment)262*1208bc7eSAndroid Build Coastguard Worker sz_sa2u(size_t size, size_t alignment) {
263*1208bc7eSAndroid Build Coastguard Worker size_t usize;
264*1208bc7eSAndroid Build Coastguard Worker
265*1208bc7eSAndroid Build Coastguard Worker assert(alignment != 0 && ((alignment - 1) & alignment) == 0);
266*1208bc7eSAndroid Build Coastguard Worker
267*1208bc7eSAndroid Build Coastguard Worker /* Try for a small size class. */
268*1208bc7eSAndroid Build Coastguard Worker if (size <= SMALL_MAXCLASS && alignment < PAGE) {
269*1208bc7eSAndroid Build Coastguard Worker /*
270*1208bc7eSAndroid Build Coastguard Worker * Round size up to the nearest multiple of alignment.
271*1208bc7eSAndroid Build Coastguard Worker *
272*1208bc7eSAndroid Build Coastguard Worker * This done, we can take advantage of the fact that for each
273*1208bc7eSAndroid Build Coastguard Worker * small size class, every object is aligned at the smallest
274*1208bc7eSAndroid Build Coastguard Worker * power of two that is non-zero in the base two representation
275*1208bc7eSAndroid Build Coastguard Worker * of the size. For example:
276*1208bc7eSAndroid Build Coastguard Worker *
277*1208bc7eSAndroid Build Coastguard Worker * Size | Base 2 | Minimum alignment
278*1208bc7eSAndroid Build Coastguard Worker * -----+----------+------------------
279*1208bc7eSAndroid Build Coastguard Worker * 96 | 1100000 | 32
280*1208bc7eSAndroid Build Coastguard Worker * 144 | 10100000 | 32
281*1208bc7eSAndroid Build Coastguard Worker * 192 | 11000000 | 64
282*1208bc7eSAndroid Build Coastguard Worker */
283*1208bc7eSAndroid Build Coastguard Worker usize = sz_s2u(ALIGNMENT_CEILING(size, alignment));
284*1208bc7eSAndroid Build Coastguard Worker if (usize < LARGE_MINCLASS) {
285*1208bc7eSAndroid Build Coastguard Worker return usize;
286*1208bc7eSAndroid Build Coastguard Worker }
287*1208bc7eSAndroid Build Coastguard Worker }
288*1208bc7eSAndroid Build Coastguard Worker
289*1208bc7eSAndroid Build Coastguard Worker /* Large size class. Beware of overflow. */
290*1208bc7eSAndroid Build Coastguard Worker
291*1208bc7eSAndroid Build Coastguard Worker if (unlikely(alignment > LARGE_MAXCLASS)) {
292*1208bc7eSAndroid Build Coastguard Worker return 0;
293*1208bc7eSAndroid Build Coastguard Worker }
294*1208bc7eSAndroid Build Coastguard Worker
295*1208bc7eSAndroid Build Coastguard Worker /* Make sure result is a large size class. */
296*1208bc7eSAndroid Build Coastguard Worker if (size <= LARGE_MINCLASS) {
297*1208bc7eSAndroid Build Coastguard Worker usize = LARGE_MINCLASS;
298*1208bc7eSAndroid Build Coastguard Worker } else {
299*1208bc7eSAndroid Build Coastguard Worker usize = sz_s2u(size);
300*1208bc7eSAndroid Build Coastguard Worker if (usize < size) {
301*1208bc7eSAndroid Build Coastguard Worker /* size_t overflow. */
302*1208bc7eSAndroid Build Coastguard Worker return 0;
303*1208bc7eSAndroid Build Coastguard Worker }
304*1208bc7eSAndroid Build Coastguard Worker }
305*1208bc7eSAndroid Build Coastguard Worker
306*1208bc7eSAndroid Build Coastguard Worker /*
307*1208bc7eSAndroid Build Coastguard Worker * Calculate the multi-page mapping that large_palloc() would need in
308*1208bc7eSAndroid Build Coastguard Worker * order to guarantee the alignment.
309*1208bc7eSAndroid Build Coastguard Worker */
310*1208bc7eSAndroid Build Coastguard Worker if (usize + sz_large_pad + PAGE_CEILING(alignment) - PAGE < usize) {
311*1208bc7eSAndroid Build Coastguard Worker /* size_t overflow. */
312*1208bc7eSAndroid Build Coastguard Worker return 0;
313*1208bc7eSAndroid Build Coastguard Worker }
314*1208bc7eSAndroid Build Coastguard Worker return usize;
315*1208bc7eSAndroid Build Coastguard Worker }
316*1208bc7eSAndroid Build Coastguard Worker
317*1208bc7eSAndroid Build Coastguard Worker #endif /* JEMALLOC_INTERNAL_SIZE_H */
318