@@ -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) ) ]
@@ -166,7 +178,10 @@ mod imp {
166
178
flags : c_int ) -> * mut c_void ;
167
179
fn je_xallocx ( ptr : * mut c_void , size : size_t , extra : size_t ,
168
180
flags : c_int ) -> size_t ;
181
+ #[ cfg( stage0) ]
169
182
fn je_dallocx ( ptr : * mut c_void , flags : c_int ) ;
183
+ #[ cfg( not( stage0) ) ]
184
+ fn je_sdallocx ( ptr : * mut c_void , size : size_t , flags : c_int ) ;
170
185
fn je_nallocx ( size : size_t , flags : c_int ) -> size_t ;
171
186
fn je_malloc_stats_print ( write_cb : Option < extern "C" fn ( cbopaque : * mut c_void ,
172
187
* const c_char ) > ,
@@ -183,9 +198,15 @@ mod imp {
183
198
#[ inline( always) ]
184
199
fn mallocx_align ( a : uint ) -> c_int { a. trailing_zeros ( ) as c_int }
185
200
201
+ #[ inline( always) ]
202
+ fn align_to_flags ( align : uint ) -> c_int {
203
+ if align <= MIN_ALIGN { 0 } else { mallocx_align ( align) }
204
+ }
205
+
186
206
#[ inline]
187
207
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 ;
208
+ let flags = align_to_flags ( align) ;
209
+ let ptr = je_mallocx ( size as size_t , flags) as * mut u8 ;
189
210
if ptr. is_null ( ) {
190
211
:: oom ( )
191
212
}
@@ -195,8 +216,8 @@ mod imp {
195
216
#[ inline]
196
217
pub unsafe fn reallocate ( ptr : * mut u8 , size : uint , align : uint ,
197
218
_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 ;
219
+ let flags = align_to_flags ( align ) ;
220
+ let ptr = je_rallocx ( ptr as * mut c_void , size as size_t , flags ) as * mut u8 ;
200
221
if ptr. is_null ( ) {
201
222
:: oom ( )
202
223
}
@@ -206,18 +227,28 @@ mod imp {
206
227
#[ inline]
207
228
pub unsafe fn reallocate_inplace ( ptr : * mut u8 , size : uint , align : uint ,
208
229
_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
230
+ let flags = align_to_flags ( align ) ;
231
+ je_xallocx ( ptr as * mut c_void , size as size_t , 0 , flags ) == size as size_t
211
232
}
212
233
213
234
#[ inline]
235
+ #[ cfg( stage0) ]
214
236
pub unsafe fn deallocate ( ptr : * mut u8 , _size : uint , align : uint ) {
215
- je_dallocx ( ptr as * mut c_void , mallocx_align ( align) )
237
+ let flags = align_to_flags ( align) ;
238
+ je_dallocx ( ptr as * mut c_void , flags)
239
+ }
240
+
241
+ #[ inline]
242
+ #[ cfg( not( stage0) ) ]
243
+ pub unsafe fn deallocate ( ptr : * mut u8 , size : uint , align : uint ) {
244
+ let flags = align_to_flags ( align) ;
245
+ je_sdallocx ( ptr as * mut c_void , size as size_t , flags)
216
246
}
217
247
218
248
#[ inline]
219
249
pub fn usable_size ( size : uint , align : uint ) -> uint {
220
- unsafe { je_nallocx ( size as size_t , mallocx_align ( align) ) as uint }
250
+ let flags = align_to_flags ( align) ;
251
+ unsafe { je_nallocx ( size as size_t , flags) as uint }
221
252
}
222
253
223
254
pub fn stats_print ( ) {
@@ -234,6 +265,7 @@ mod imp {
234
265
use core:: ptr;
235
266
use libc;
236
267
use libc_heap;
268
+ use super :: MIN_ALIGN ;
237
269
238
270
extern {
239
271
fn posix_memalign ( memptr : * mut * mut libc:: c_void ,
@@ -243,16 +275,7 @@ mod imp {
243
275
244
276
#[ inline]
245
277
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 > ( ) {
278
+ if align <= MIN_ALIGN {
256
279
libc_heap:: malloc_raw ( size)
257
280
} else {
258
281
let mut out = 0 as * mut libc:: c_void ;
@@ -269,10 +292,14 @@ mod imp {
269
292
#[ inline]
270
293
pub unsafe fn reallocate ( ptr : * mut u8 , size : uint , align : uint ,
271
294
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;
295
+ if align <= MIN_ALIGN {
296
+ libc_heap:: realloc_raw ( ptr, size)
297
+ } else {
298
+ let new_ptr = allocate ( size, align) ;
299
+ ptr:: copy_memory ( new_ptr, ptr as * const u8 , cmp:: min ( size, old_size) ) ;
300
+ deallocate ( ptr, old_size, align) ;
301
+ new_ptr
302
+ }
276
303
}
277
304
278
305
#[ inline]
@@ -291,14 +318,16 @@ mod imp {
291
318
size
292
319
}
293
320
294
- pub fn stats_print ( ) {
295
- }
321
+ pub fn stats_print ( ) { }
296
322
}
297
323
298
324
#[ cfg( not( jemalloc) , windows) ]
299
325
mod imp {
300
326
use libc:: { c_void, size_t} ;
327
+ use libc;
328
+ use libc_heap;
301
329
use core:: ptr:: RawPtr ;
330
+ use super :: MIN_ALIGN ;
302
331
303
332
extern {
304
333
fn _aligned_malloc ( size : size_t , align : size_t ) -> * mut c_void ;
@@ -309,22 +338,30 @@ mod imp {
309
338
310
339
#[ inline]
311
340
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 ( ) ;
341
+ if align <= MIN_ALIGN {
342
+ libc_heap:: malloc_raw ( size)
343
+ } else {
344
+ let ptr = _aligned_malloc ( size as size_t , align as size_t ) ;
345
+ if ptr. is_null ( ) {
346
+ :: oom ( ) ;
347
+ }
348
+ ptr as * mut u8
315
349
}
316
- ptr as * mut u8
317
350
}
318
351
319
352
#[ inline]
320
353
pub unsafe fn reallocate ( ptr : * mut u8 , size : uint , align : uint ,
321
354
_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 ( ) ;
355
+ if align <= MIN_ALIGN {
356
+ libc_heap:: realloc_raw ( ptr, size)
357
+ } else {
358
+ let ptr = _aligned_realloc ( ptr as * mut c_void , size as size_t ,
359
+ align as size_t ) ;
360
+ if ptr. is_null ( ) {
361
+ :: oom ( ) ;
362
+ }
363
+ ptr as * mut u8
326
364
}
327
- ptr as * mut u8
328
365
}
329
366
330
367
#[ inline]
@@ -334,8 +371,12 @@ mod imp {
334
371
}
335
372
336
373
#[ inline]
337
- pub unsafe fn deallocate ( ptr : * mut u8 , _size : uint , _align : uint ) {
338
- _aligned_free ( ptr as * mut c_void )
374
+ pub unsafe fn deallocate ( ptr : * mut u8 , _size : uint , align : uint ) {
375
+ if align <= MIN_ALIGN {
376
+ libc:: free ( ptr as * mut libc:: c_void )
377
+ } else {
378
+ _aligned_free ( ptr as * mut c_void )
379
+ }
339
380
}
340
381
341
382
#[ inline]
0 commit comments