88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010#![ 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 ;
2811
2912pub struct System ;
13+
3014#[ cfg( any( windows, unix, target_os = "redox" ) ) ]
3115mod realloc_fallback {
3216 use core:: alloc:: { GlobalAlloc , Layout } ;
3317 use core:: cmp;
3418 use core:: ptr;
3519 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 {
3826 // Docs for GlobalAlloc::realloc require this to be valid:
3927 let new_layout = Layout :: from_size_align_unchecked ( new_size, old_layout. align ( ) ) ;
4028 let new_ptr = GlobalAlloc :: alloc ( self , new_layout) ;
@@ -49,97 +37,47 @@ mod realloc_fallback {
4937}
5038#[ cfg( any( unix, target_os = "redox" ) ) ]
5139mod platform {
52- extern crate libc;
40+ use core:: alloc:: { GlobalAlloc , Layout } ;
41+ use core:: ffi:: c_void;
5342 use core:: ptr;
54- use MIN_ALIGN ;
5543 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+ }
5748 unsafe impl GlobalAlloc for System {
5849 #[ inline]
5950 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)
7152 }
7253 #[ inline]
7354 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 ( ) ) ;
8258 }
59+ ptr
8360 }
8461 #[ inline]
8562 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 )
8764 }
8865 #[ inline]
8966 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)
9568 }
9669 }
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]
12770 unsafe fn aligned_malloc ( layout : & Layout ) -> * mut u8 {
12871 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 }
13574 }
13675}
13776#[ cfg( windows) ]
13877#[ allow( nonstandard_style) ]
13978mod platform {
140- use MIN_ALIGN ;
141- use System ;
14279 use core:: alloc:: { GlobalAlloc , Layout } ;
80+ use System ;
14381 type LPVOID = * mut u8 ;
14482 type HANDLE = LPVOID ;
14583 type SIZE_T = usize ;
@@ -165,18 +103,9 @@ mod platform {
165103 }
166104 #[ inline]
167105 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
180109 }
181110 unsafe impl GlobalAlloc for System {
182111 #[ inline]
@@ -189,24 +118,13 @@ mod platform {
189118 }
190119 #[ inline]
191120 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 ( ) ) ;
202124 }
203125 #[ inline]
204126 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)
210128 }
211129 }
212130}
0 commit comments