@@ -149,12 +149,24 @@ unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint,
149
149
alloc as * mut u8
150
150
}
151
151
152
+ // The minimum alignment guaranteed by the architecture. This value is used to
153
+ // add fast paths for low alignment values. In practice, the alignment is a
154
+ // constant at the call site and the branch will be optimized out.
155
+ #[ cfg( target_arch = "arm" ) ]
156
+ #[ cfg( target_arch = "mips" ) ]
157
+ #[ cfg( target_arch = "mipsel" ) ]
158
+ static MIN_ALIGN : uint = 8 ;
159
+ #[ cfg( target_arch = "x86" ) ]
160
+ #[ cfg( target_arch = "x86_64" ) ]
161
+ static MIN_ALIGN : uint = 16 ;
162
+
152
163
#[ cfg( jemalloc) ]
153
164
mod imp {
154
165
use core:: option:: { None , Option } ;
155
166
use core:: ptr:: { RawPtr , mut_null, null} ;
156
167
use core:: num:: Int ;
157
168
use libc:: { c_char, c_int, c_void, size_t} ;
169
+ use super :: MIN_ALIGN ;
158
170
159
171
#[ link( name = "jemalloc" , kind = "static" ) ]
160
172
#[ cfg( not( test) ) ]
@@ -183,9 +195,15 @@ mod imp {
183
195
#[ inline( always) ]
184
196
fn mallocx_align ( a : uint ) -> c_int { a. trailing_zeros ( ) as c_int }
185
197
198
+ #[ inline( always) ]
199
+ fn align_to_flags ( align : uint ) -> c_int {
200
+ if align <= MIN_ALIGN { 0 } else { mallocx_align ( align) }
201
+ }
202
+
186
203
#[ inline]
187
204
pub unsafe fn allocate ( size : uint , align : uint ) -> * mut u8 {
188
- let ptr = je_mallocx ( size as size_t , mallocx_align ( align) ) as * mut u8 ;
205
+ let flags = align_to_flags ( align) ;
206
+ let ptr = je_mallocx ( size as size_t , flags) as * mut u8 ;
189
207
if ptr. is_null ( ) {
190
208
:: oom ( )
191
209
}
@@ -195,8 +213,8 @@ mod imp {
195
213
#[ inline]
196
214
pub unsafe fn reallocate ( ptr : * mut u8 , size : uint , align : uint ,
197
215
_old_size : uint ) -> * mut u8 {
198
- let ptr = je_rallocx ( ptr as * mut c_void , size as size_t ,
199
- mallocx_align ( align ) ) as * mut u8 ;
216
+ let flags = align_to_flags ( align ) ;
217
+ let ptr = je_rallocx ( ptr as * mut c_void , size as size_t , flags ) as * mut u8 ;
200
218
if ptr. is_null ( ) {
201
219
:: oom ( )
202
220
}
@@ -206,18 +224,20 @@ mod imp {
206
224
#[ inline]
207
225
pub unsafe fn reallocate_inplace ( ptr : * mut u8 , size : uint , align : uint ,
208
226
_old_size : uint ) -> bool {
209
- je_xallocx ( ptr as * mut c_void , size as size_t , 0 ,
210
- mallocx_align ( align ) ) == size as size_t
227
+ let flags = align_to_flags ( align ) ;
228
+ je_xallocx ( ptr as * mut c_void , size as size_t , 0 , flags ) == size as size_t
211
229
}
212
230
213
231
#[ inline]
214
232
pub unsafe fn deallocate ( ptr : * mut u8 , _size : uint , align : uint ) {
215
- je_dallocx ( ptr as * mut c_void , mallocx_align ( align) )
233
+ let flags = align_to_flags ( align) ;
234
+ je_dallocx ( ptr as * mut c_void , flags)
216
235
}
217
236
218
237
#[ inline]
219
238
pub fn usable_size ( size : uint , align : uint ) -> uint {
220
- unsafe { je_nallocx ( size as size_t , mallocx_align ( align) ) as uint }
239
+ let flags = align_to_flags ( align) ;
240
+ unsafe { je_nallocx ( size as size_t , flags) as uint }
221
241
}
222
242
223
243
pub fn stats_print ( ) {
@@ -234,6 +254,7 @@ mod imp {
234
254
use core:: ptr;
235
255
use libc;
236
256
use libc_heap;
257
+ use super :: MIN_ALIGN ;
237
258
238
259
extern {
239
260
fn posix_memalign ( memptr : * mut * mut libc:: c_void ,
@@ -243,16 +264,7 @@ mod imp {
243
264
244
265
#[ inline]
245
266
pub unsafe fn allocate ( size : uint , align : uint ) -> * mut u8 {
246
- // The posix_memalign manpage states
247
- //
248
- // alignment [...] must be a power of and a multiple of
249
- // sizeof(void *)
250
- //
251
- // The `align` parameter to this function is the *minimum* alignment for
252
- // a block of memory, so we special case everything under `*uint` to
253
- // just pass it to malloc, which is guaranteed to align to at least the
254
- // size of `*uint`.
255
- if align < mem:: size_of :: < uint > ( ) {
267
+ if align <= MIN_ALIGN {
256
268
libc_heap:: malloc_raw ( size)
257
269
} else {
258
270
let mut out = 0 as * mut libc:: c_void ;
@@ -269,10 +281,14 @@ mod imp {
269
281
#[ inline]
270
282
pub unsafe fn reallocate ( ptr : * mut u8 , size : uint , align : uint ,
271
283
old_size : uint ) -> * mut u8 {
272
- let new_ptr = allocate ( size, align) ;
273
- ptr:: copy_memory ( new_ptr, ptr as * const u8 , cmp:: min ( size, old_size) ) ;
274
- deallocate ( ptr, old_size, align) ;
275
- return new_ptr;
284
+ if align <= MIN_ALIGN {
285
+ libc_heap:: realloc_raw ( ptr, size)
286
+ } else {
287
+ let new_ptr = allocate ( size, align) ;
288
+ ptr:: copy_memory ( new_ptr, ptr as * const u8 , cmp:: min ( size, old_size) ) ;
289
+ deallocate ( ptr, old_size, align) ;
290
+ new_ptr
291
+ }
276
292
}
277
293
278
294
#[ inline]
@@ -291,14 +307,16 @@ mod imp {
291
307
size
292
308
}
293
309
294
- pub fn stats_print ( ) {
295
- }
310
+ pub fn stats_print ( ) { }
296
311
}
297
312
298
313
#[ cfg( not( jemalloc) , windows) ]
299
314
mod imp {
300
315
use libc:: { c_void, size_t} ;
316
+ use libc;
317
+ use libc_heap;
301
318
use core:: ptr:: RawPtr ;
319
+ use super :: MIN_ALIGN ;
302
320
303
321
extern {
304
322
fn _aligned_malloc ( size : size_t , align : size_t ) -> * mut c_void ;
@@ -309,22 +327,30 @@ mod imp {
309
327
310
328
#[ inline]
311
329
pub unsafe fn allocate ( size : uint , align : uint ) -> * mut u8 {
312
- let ptr = _aligned_malloc ( size as size_t , align as size_t ) ;
313
- if ptr. is_null ( ) {
314
- :: oom ( ) ;
330
+ if align <= MIN_ALIGN {
331
+ libc_heap:: malloc_raw ( size)
332
+ } else {
333
+ let ptr = _aligned_malloc ( size as size_t , align as size_t ) ;
334
+ if ptr. is_null ( ) {
335
+ :: oom ( ) ;
336
+ }
337
+ ptr as * mut u8
315
338
}
316
- ptr as * mut u8
317
339
}
318
340
319
341
#[ inline]
320
342
pub unsafe fn reallocate ( ptr : * mut u8 , size : uint , align : uint ,
321
343
_old_size : uint ) -> * mut u8 {
322
- let ptr = _aligned_realloc ( ptr as * mut c_void , size as size_t ,
323
- align as size_t ) ;
324
- if ptr. is_null ( ) {
325
- :: oom ( ) ;
344
+ if align <= MIN_ALIGN {
345
+ libc_heap:: realloc_raw ( ptr, size)
346
+ } else {
347
+ let ptr = _aligned_realloc ( ptr as * mut c_void , size as size_t ,
348
+ align as size_t ) ;
349
+ if ptr. is_null ( ) {
350
+ :: oom ( ) ;
351
+ }
352
+ ptr as * mut u8
326
353
}
327
- ptr as * mut u8
328
354
}
329
355
330
356
#[ inline]
@@ -334,8 +360,12 @@ mod imp {
334
360
}
335
361
336
362
#[ inline]
337
- pub unsafe fn deallocate ( ptr : * mut u8 , _size : uint , _align : uint ) {
338
- _aligned_free ( ptr as * mut c_void )
363
+ pub unsafe fn deallocate ( ptr : * mut u8 , _size : uint , align : uint ) {
364
+ if align <= MIN_ALIGN {
365
+ libc:: free ( ptr as * mut libc:: c_void )
366
+ } else {
367
+ _aligned_free ( ptr as * mut c_void )
368
+ }
339
369
}
340
370
341
371
#[ inline]
0 commit comments