@@ -149,12 +149,24 @@ unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint,
149149 alloc as * mut u8
150150}
151151
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+
152163#[ cfg( jemalloc) ]
153164mod imp {
154165 use core:: option:: { None , Option } ;
155166 use core:: ptr:: { RawPtr , mut_null, null} ;
156167 use core:: num:: Int ;
157168 use libc:: { c_char, c_int, c_void, size_t} ;
169+ use super :: MIN_ALIGN ;
158170
159171 #[ link( name = "jemalloc" , kind = "static" ) ]
160172 #[ cfg( not( test) ) ]
@@ -183,9 +195,15 @@ mod imp {
183195 #[ inline( always) ]
184196 fn mallocx_align ( a : uint ) -> c_int { a. trailing_zeros ( ) as c_int }
185197
198+ #[ inline( always) ]
199+ fn align_to_flags ( align : uint ) -> c_int {
200+ if align <= MIN_ALIGN { 0 } else { mallocx_align ( align) }
201+ }
202+
186203 #[ inline]
187204 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 ;
189207 if ptr. is_null ( ) {
190208 :: oom ( )
191209 }
@@ -195,8 +213,8 @@ mod imp {
195213 #[ inline]
196214 pub unsafe fn reallocate ( ptr : * mut u8 , size : uint , align : uint ,
197215 _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 ;
200218 if ptr. is_null ( ) {
201219 :: oom ( )
202220 }
@@ -206,18 +224,20 @@ mod imp {
206224 #[ inline]
207225 pub unsafe fn reallocate_inplace ( ptr : * mut u8 , size : uint , align : uint ,
208226 _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
211229 }
212230
213231 #[ inline]
214232 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)
216235 }
217236
218237 #[ inline]
219238 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 }
221241 }
222242
223243 pub fn stats_print ( ) {
@@ -234,6 +254,7 @@ mod imp {
234254 use core:: ptr;
235255 use libc;
236256 use libc_heap;
257+ use super :: MIN_ALIGN ;
237258
238259 extern {
239260 fn posix_memalign ( memptr : * mut * mut libc:: c_void ,
@@ -243,16 +264,7 @@ mod imp {
243264
244265 #[ inline]
245266 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 {
256268 libc_heap:: malloc_raw ( size)
257269 } else {
258270 let mut out = 0 as * mut libc:: c_void ;
@@ -269,10 +281,14 @@ mod imp {
269281 #[ inline]
270282 pub unsafe fn reallocate ( ptr : * mut u8 , size : uint , align : uint ,
271283 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+ }
276292 }
277293
278294 #[ inline]
@@ -291,14 +307,16 @@ mod imp {
291307 size
292308 }
293309
294- pub fn stats_print ( ) {
295- }
310+ pub fn stats_print ( ) { }
296311}
297312
298313#[ cfg( not( jemalloc) , windows) ]
299314mod imp {
300315 use libc:: { c_void, size_t} ;
316+ use libc;
317+ use libc_heap;
301318 use core:: ptr:: RawPtr ;
319+ use super :: MIN_ALIGN ;
302320
303321 extern {
304322 fn _aligned_malloc ( size : size_t , align : size_t ) -> * mut c_void ;
@@ -309,22 +327,30 @@ mod imp {
309327
310328 #[ inline]
311329 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
315338 }
316- ptr as * mut u8
317339 }
318340
319341 #[ inline]
320342 pub unsafe fn reallocate ( ptr : * mut u8 , size : uint , align : uint ,
321343 _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
326353 }
327- ptr as * mut u8
328354 }
329355
330356 #[ inline]
@@ -334,8 +360,12 @@ mod imp {
334360 }
335361
336362 #[ 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+ }
339369 }
340370
341371 #[ inline]
0 commit comments