8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
#![ no_std]
11
- #![ feature( allocator_api, rustc_private) ]
12
- #![ cfg_attr( any( unix, target_os = "redox" ) , feature( libc) ) ]
13
-
14
- // The minimum alignment guaranteed by the architecture. This value is used to
15
- // add fast paths for low alignment values.
16
- #[ cfg( all( any( target_arch = "x86" ,
17
- target_arch = "arm" ,
18
- target_arch = "mips" ,
19
- target_arch = "powerpc" ,
20
- target_arch = "powerpc64" ) ) ) ]
21
- const MIN_ALIGN : usize = 8 ;
22
- #[ cfg( all( any( target_arch = "x86_64" ,
23
- target_arch = "aarch64" ,
24
- target_arch = "mips64" ,
25
- target_arch = "s390x" ,
26
- target_arch = "sparc64" ) ) ) ]
27
- const MIN_ALIGN : usize = 16 ;
28
11
29
12
pub struct System ;
13
+
30
14
#[ cfg( any( windows, unix, target_os = "redox" ) ) ]
31
15
mod realloc_fallback {
32
16
use core:: alloc:: { GlobalAlloc , Layout } ;
33
17
use core:: cmp;
34
18
use core:: ptr;
35
19
impl super :: System {
36
- pub ( crate ) unsafe fn realloc_fallback ( & self , ptr : * mut u8 , old_layout : Layout ,
37
- new_size : usize ) -> * mut u8 {
20
+ pub ( crate ) unsafe fn realloc_fallback (
21
+ & self ,
22
+ ptr : * mut u8 ,
23
+ old_layout : Layout ,
24
+ new_size : usize ,
25
+ ) -> * mut u8 {
38
26
// Docs for GlobalAlloc::realloc require this to be valid:
39
27
let new_layout = Layout :: from_size_align_unchecked ( new_size, old_layout. align ( ) ) ;
40
28
let new_ptr = GlobalAlloc :: alloc ( self , new_layout) ;
@@ -49,97 +37,47 @@ mod realloc_fallback {
49
37
}
50
38
#[ cfg( any( unix, target_os = "redox" ) ) ]
51
39
mod platform {
52
- extern crate libc;
40
+ use core:: alloc:: { GlobalAlloc , Layout } ;
41
+ use core:: ffi:: c_void;
53
42
use core:: ptr;
54
- use MIN_ALIGN ;
55
43
use System ;
56
- use core:: alloc:: { GlobalAlloc , Layout } ;
44
+ extern "C" {
45
+ fn posix_memalign ( memptr : * mut * mut c_void , align : usize , size : usize ) -> i32 ;
46
+ fn free ( p : * mut c_void ) ;
47
+ }
57
48
unsafe impl GlobalAlloc for System {
58
49
#[ inline]
59
50
unsafe fn alloc ( & self , layout : Layout ) -> * mut u8 {
60
- if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
61
- libc:: malloc ( layout. size ( ) ) as * mut u8
62
- } else {
63
- #[ cfg( target_os = "macos" ) ]
64
- {
65
- if layout. align ( ) > ( 1 << 31 ) {
66
- return ptr:: null_mut ( )
67
- }
68
- }
69
- aligned_malloc ( & layout)
70
- }
51
+ aligned_malloc ( & layout)
71
52
}
72
53
#[ inline]
73
54
unsafe fn alloc_zeroed ( & self , layout : Layout ) -> * mut u8 {
74
- if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= layout. size ( ) {
75
- libc:: calloc ( layout. size ( ) , 1 ) as * mut u8
76
- } else {
77
- let ptr = self . alloc ( layout. clone ( ) ) ;
78
- if !ptr. is_null ( ) {
79
- ptr:: write_bytes ( ptr, 0 , layout. size ( ) ) ;
80
- }
81
- ptr
55
+ let ptr = self . alloc ( layout. clone ( ) ) ;
56
+ if !ptr. is_null ( ) {
57
+ ptr:: write_bytes ( ptr, 0 , layout. size ( ) ) ;
82
58
}
59
+ ptr
83
60
}
84
61
#[ inline]
85
62
unsafe fn dealloc ( & self , ptr : * mut u8 , _layout : Layout ) {
86
- libc :: free ( ptr as * mut libc :: c_void )
63
+ free ( ptr as * mut c_void )
87
64
}
88
65
#[ inline]
89
66
unsafe fn realloc ( & self , ptr : * mut u8 , layout : Layout , new_size : usize ) -> * mut u8 {
90
- if layout. align ( ) <= MIN_ALIGN && layout. align ( ) <= new_size {
91
- libc:: realloc ( ptr as * mut libc:: c_void , new_size) as * mut u8
92
- } else {
93
- self . realloc_fallback ( ptr, layout, new_size)
94
- }
67
+ self . realloc_fallback ( ptr, layout, new_size)
95
68
}
96
69
}
97
- #[ cfg( any( target_os = "android" ,
98
- target_os = "hermit" ,
99
- target_os = "redox" ,
100
- target_os = "solaris" ) ) ]
101
- #[ inline]
102
- unsafe fn aligned_malloc ( layout : & Layout ) -> * mut u8 {
103
- // On android we currently target API level 9 which unfortunately
104
- // doesn't have the `posix_memalign` API used below. Instead we use
105
- // `memalign`, but this unfortunately has the property on some systems
106
- // where the memory returned cannot be deallocated by `free`!
107
- //
108
- // Upon closer inspection, however, this appears to work just fine with
109
- // Android, so for this platform we should be fine to call `memalign`
110
- // (which is present in API level 9). Some helpful references could
111
- // possibly be chromium using memalign [1], attempts at documenting that
112
- // memalign + free is ok [2] [3], or the current source of chromium
113
- // which still uses memalign on android [4].
114
- //
115
- // [1]: https://codereview.chromium.org/10796020/
116
- // [2]: https://code.google.com/p/android/issues/detail?id=35391
117
- // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
118
- // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
119
- // /memory/aligned_memory.cc
120
- libc:: memalign ( layout. align ( ) , layout. size ( ) ) as * mut u8
121
- }
122
- #[ cfg( not( any( target_os = "android" ,
123
- target_os = "hermit" ,
124
- target_os = "redox" ,
125
- target_os = "solaris" ) ) ) ]
126
- #[ inline]
127
70
unsafe fn aligned_malloc ( layout : & Layout ) -> * mut u8 {
128
71
let mut out = ptr:: null_mut ( ) ;
129
- let ret = libc:: posix_memalign ( & mut out, layout. align ( ) , layout. size ( ) ) ;
130
- if ret != 0 {
131
- ptr:: null_mut ( )
132
- } else {
133
- out as * mut u8
134
- }
72
+ let ret = posix_memalign ( & mut out, layout. align ( ) , layout. size ( ) ) ;
73
+ if ret != 0 { ptr:: null_mut ( ) } else { out as * mut u8 }
135
74
}
136
75
}
137
76
#[ cfg( windows) ]
138
77
#[ allow( nonstandard_style) ]
139
78
mod platform {
140
- use MIN_ALIGN ;
141
- use System ;
142
79
use core:: alloc:: { GlobalAlloc , Layout } ;
80
+ use System ;
143
81
type LPVOID = * mut u8 ;
144
82
type HANDLE = LPVOID ;
145
83
type SIZE_T = usize ;
@@ -165,18 +103,9 @@ mod platform {
165
103
}
166
104
#[ inline]
167
105
unsafe fn allocate_with_flags ( layout : Layout , flags : DWORD ) -> * mut u8 {
168
- let ptr = if layout. align ( ) <= MIN_ALIGN {
169
- HeapAlloc ( GetProcessHeap ( ) , flags, layout. size ( ) )
170
- } else {
171
- let size = layout. size ( ) + layout. align ( ) ;
172
- let ptr = HeapAlloc ( GetProcessHeap ( ) , flags, size) ;
173
- if ptr. is_null ( ) {
174
- ptr
175
- } else {
176
- align_ptr ( ptr, layout. align ( ) )
177
- }
178
- } ;
179
- ptr as * mut u8
106
+ let size = layout. size ( ) + layout. align ( ) ;
107
+ let ptr = HeapAlloc ( GetProcessHeap ( ) , flags, size) ;
108
+ ( if ptr. is_null ( ) { ptr } else { align_ptr ( ptr, layout. align ( ) ) } ) as * mut u8
180
109
}
181
110
unsafe impl GlobalAlloc for System {
182
111
#[ inline]
@@ -189,24 +118,13 @@ mod platform {
189
118
}
190
119
#[ inline]
191
120
unsafe fn dealloc ( & self , ptr : * mut u8 , layout : Layout ) {
192
- if layout. align ( ) <= MIN_ALIGN {
193
- let err = HeapFree ( GetProcessHeap ( ) , 0 , ptr as LPVOID ) ;
194
- debug_assert ! ( err != 0 , "Failed to free heap memory: {}" ,
195
- GetLastError ( ) ) ;
196
- } else {
197
- let header = get_header ( ptr) ;
198
- let err = HeapFree ( GetProcessHeap ( ) , 0 , header. 0 as LPVOID ) ;
199
- debug_assert ! ( err != 0 , "Failed to free heap memory: {}" ,
200
- GetLastError ( ) ) ;
201
- }
121
+ let header = get_header ( ptr) ;
122
+ let err = HeapFree ( GetProcessHeap ( ) , 0 , header. 0 as LPVOID ) ;
123
+ debug_assert ! ( err != 0 , "Failed to free heap memory: {}" , GetLastError ( ) ) ;
202
124
}
203
125
#[ inline]
204
126
unsafe fn realloc ( & self , ptr : * mut u8 , layout : Layout , new_size : usize ) -> * mut u8 {
205
- if layout. align ( ) <= MIN_ALIGN {
206
- HeapReAlloc ( GetProcessHeap ( ) , 0 , ptr as LPVOID , new_size) as * mut u8
207
- } else {
208
- self . realloc_fallback ( ptr, layout, new_size)
209
- }
127
+ self . realloc_fallback ( ptr, layout, new_size)
210
128
}
211
129
}
212
130
}
0 commit comments