4
4
5
5
//! Selecting the default global allocator for Servo
6
6
7
- #![ cfg_attr( all( feature = "unstable" , windows) , feature( alloc_system, allocator_api) ) ]
8
- #![ cfg_attr( feature = "unstable" , feature( global_allocator) ) ]
7
+ #![ cfg_attr( feature = "unstable" , feature( global_allocator, allocator_api, alloc_system) ) ]
9
8
10
9
#[ cfg( feature = "unstable" ) ]
11
10
#[ global_allocator]
@@ -16,19 +15,90 @@ pub use platform::*;
16
15
17
16
#[ cfg( all( feature = "unstable" , not( windows) ) ) ]
18
17
mod platform {
19
- extern crate jemallocator ;
18
+ extern crate jemalloc_sys as ffi ;
20
19
21
- pub use self :: jemallocator :: Jemalloc as Allocator ;
22
- use std:: os:: raw:: c_void;
20
+ use std :: alloc :: { GlobalAlloc , Layout , Opaque , System } ;
21
+ use std:: os:: raw:: { c_int , c_void} ;
23
22
24
23
/// Get the size of a heap block.
25
24
pub unsafe extern "C" fn usable_size ( ptr : * const c_void ) -> usize {
26
- jemallocator :: usable_size ( ptr)
25
+ ffi :: malloc_usable_size ( ptr as * const _ )
27
26
}
28
27
29
28
/// Memory allocation APIs compatible with libc
30
29
pub mod libc_compat {
31
- pub use super :: jemallocator:: ffi:: { malloc, realloc, free} ;
30
+ pub use super :: ffi:: { malloc, realloc, free} ;
31
+ }
32
+
33
+ pub struct Allocator ;
34
+
35
+ // The minimum alignment guaranteed by the architecture. This value is used to
36
+ // add fast paths for low alignment values.
37
+ #[ cfg( all( any( target_arch = "arm" ,
38
+ target_arch = "mips" ,
39
+ target_arch = "mipsel" ,
40
+ target_arch = "powerpc" ) ) ) ]
41
+ const MIN_ALIGN : usize = 8 ;
42
+ #[ cfg( all( any( target_arch = "x86" ,
43
+ target_arch = "x86_64" ,
44
+ target_arch = "aarch64" ,
45
+ target_arch = "powerpc64" ,
46
+ target_arch = "powerpc64le" ,
47
+ target_arch = "mips64" ,
48
+ target_arch = "s390x" ,
49
+ target_arch = "sparc64" ) ) ) ]
50
+ const MIN_ALIGN : usize = 16 ;
51
+
52
+ fn layout_to_flags ( align : usize , size : usize ) -> c_int {
53
+ // If our alignment is less than the minimum alignment they we may not
54
+ // have to pass special flags asking for a higher alignment. If the
55
+ // alignment is greater than the size, however, then this hits a sort of odd
56
+ // case where we still need to ask for a custom alignment. See #25 for more
57
+ // info.
58
+ if align <= MIN_ALIGN && align <= size {
59
+ 0
60
+ } else {
61
+ // Equivalent to the MALLOCX_ALIGN(a) macro.
62
+ align. trailing_zeros ( ) as _
63
+ }
64
+ }
65
+
66
+ unsafe impl GlobalAlloc for Allocator {
67
+ #[ inline]
68
+ unsafe fn alloc ( & self , layout : Layout ) -> * mut Opaque {
69
+ let flags = layout_to_flags ( layout. align ( ) , layout. size ( ) ) ;
70
+ ffi:: mallocx ( layout. size ( ) , flags) as * mut Opaque
71
+ }
72
+
73
+ #[ inline]
74
+ unsafe fn alloc_zeroed ( & self , layout : Layout ) -> * mut Opaque {
75
+ if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
76
+ ffi:: calloc ( 1 , layout. size ( ) ) as * mut Opaque
77
+ } else {
78
+ let flags = layout_to_flags ( layout. align ( ) , layout. size ( ) ) | ffi:: MALLOCX_ZERO ;
79
+ ffi:: mallocx ( layout. size ( ) , flags) as * mut Opaque
80
+ }
81
+ }
82
+
83
+ #[ inline]
84
+ unsafe fn dealloc ( & self , ptr : * mut Opaque , layout : Layout ) {
85
+ let flags = layout_to_flags ( layout. align ( ) , layout. size ( ) ) ;
86
+ ffi:: sdallocx ( ptr as * mut _ , layout. size ( ) , flags)
87
+ }
88
+
89
+ #[ inline]
90
+ unsafe fn realloc ( & self ,
91
+ ptr : * mut Opaque ,
92
+ layout : Layout ,
93
+ new_size : usize ) -> * mut Opaque {
94
+ let flags = layout_to_flags ( layout. align ( ) , new_size) ;
95
+ ffi:: rallocx ( ptr as * mut _ , new_size, flags) as * mut Opaque
96
+ }
97
+
98
+ #[ inline]
99
+ fn oom ( & self ) -> ! {
100
+ System . oom ( )
101
+ }
32
102
}
33
103
}
34
104
0 commit comments