@@ -64,6 +64,7 @@ impl MachineAlloc {
64
64
fn add_page ( & mut self ) {
65
65
let page_layout =
66
66
unsafe { Layout :: from_size_align_unchecked ( self . page_size , self . page_size ) } ;
67
+ // We don't overwrite the bytes we hand out so make sure they're zeroed by default!
67
68
let page_ptr = unsafe { alloc:: alloc ( page_layout) } ;
68
69
self . allocated . push ( vec ! [ 0u8 ; self . page_size / 8 ] . into_boxed_slice ( ) ) ;
69
70
self . pages . push ( page_ptr) ;
@@ -90,7 +91,7 @@ impl MachineAlloc {
90
91
let mut alloc = ALLOCATOR . lock ( ) . unwrap ( ) ;
91
92
unsafe {
92
93
if alloc. enabled {
93
- ( alloc. alloc_inner ( layout, alloc :: alloc ) , false )
94
+ ( alloc. alloc_inner ( layout, false ) , false )
94
95
} else {
95
96
( alloc:: alloc ( layout) , true )
96
97
}
@@ -105,7 +106,7 @@ impl MachineAlloc {
105
106
pub unsafe fn alloc_zeroed ( layout : Layout ) -> ( * mut u8 , bool ) {
106
107
let mut alloc = ALLOCATOR . lock ( ) . unwrap ( ) ;
107
108
if alloc. enabled {
108
- let ptr = unsafe { alloc. alloc_inner ( layout, alloc :: alloc_zeroed ) } ;
109
+ let ptr = unsafe { alloc. alloc_inner ( layout, true ) } ;
109
110
( ptr, false )
110
111
} else {
111
112
unsafe { ( alloc:: alloc_zeroed ( layout) , true ) }
@@ -114,15 +115,11 @@ impl MachineAlloc {
114
115
115
116
/// SAFETY: The allocator must have been `enable()`d already and
116
117
/// the `layout` must be valid.
117
- unsafe fn alloc_inner (
118
- & mut self ,
119
- layout : Layout ,
120
- sys_allocator : unsafe fn ( Layout ) -> * mut u8 ,
121
- ) -> * mut u8 {
118
+ unsafe fn alloc_inner ( & mut self , layout : Layout , zeroed : bool ) -> * mut u8 {
122
119
let ( size, align) = MachineAlloc :: normalized_layout ( layout) ;
123
120
124
121
if align > self . page_size || size > self . page_size {
125
- unsafe { self . alloc_multi_page ( layout, sys_allocator ) }
122
+ unsafe { self . alloc_multi_page ( layout, zeroed ) }
126
123
} else {
127
124
for ( page, pinfo) in std:: iter:: zip ( & mut self . pages , & mut self . allocated ) {
128
125
for idx in ( 0 ..self . page_size ) . step_by ( align) {
@@ -138,26 +135,27 @@ impl MachineAlloc {
138
135
if ret. addr ( ) >= page. addr ( ) + self . page_size {
139
136
panic ! ( "Returing {} from page {}" , ret. addr( ) , page. addr( ) ) ;
140
137
}
141
- return page. offset ( idx. try_into ( ) . unwrap ( ) ) ;
138
+ if zeroed {
139
+ // No need to zero out more than was specifically requested
140
+ ret. write_bytes ( 0 , layout. size ( ) ) ;
141
+ }
142
+ return ret;
142
143
}
143
144
}
144
145
}
145
146
}
146
147
147
148
// We get here only if there's no space in our existing pages
148
149
self . add_page ( ) ;
149
- unsafe { self . alloc_inner ( layout, sys_allocator ) }
150
+ unsafe { self . alloc_inner ( layout, zeroed ) }
150
151
}
151
152
}
152
153
153
154
/// SAFETY: Same as `alloc_inner()` with the added requirement that `layout`
154
155
/// must ask for a size larger than the host pagesize.
155
- unsafe fn alloc_multi_page (
156
- & mut self ,
157
- layout : Layout ,
158
- sys_allocator : unsafe fn ( Layout ) -> * mut u8 ,
159
- ) -> * mut u8 {
160
- let ret = unsafe { sys_allocator ( layout) } ;
156
+ unsafe fn alloc_multi_page ( & mut self , layout : Layout , zeroed : bool ) -> * mut u8 {
157
+ let ret =
158
+ unsafe { if zeroed { alloc:: alloc_zeroed ( layout) } else { alloc:: alloc ( layout) } } ;
161
159
self . huge_allocs . push ( ( ret, layout. size ( ) ) ) ;
162
160
ret
163
161
}
@@ -197,6 +195,7 @@ impl MachineAlloc {
197
195
let size_pinfo = size / 8 ;
198
196
// Everything is always aligned to at least 8 bytes so this is ok
199
197
pinfo[ ptr_idx_pinfo..ptr_idx_pinfo + size_pinfo] . fill ( 0 ) ;
198
+ // And also zero out the page contents!
200
199
}
201
200
202
201
let mut free = vec ! [ ] ;
@@ -219,11 +218,10 @@ impl MachineAlloc {
219
218
/// SAFETY: Same as `dealloc()` with the added requirement that `layout`
220
219
/// must ask for a size larger than the host pagesize.
221
220
unsafe fn dealloc_multi_page ( & mut self , ptr : * mut u8 , layout : Layout ) {
222
- let ( idx, _ ) = self
221
+ let idx = self
223
222
. huge_allocs
224
223
. iter ( )
225
- . enumerate ( )
226
- . find ( |pg| ptr. addr ( ) == pg. 1 . 0 . addr ( ) )
224
+ . position ( |pg| ptr. addr ( ) == pg. 0 . addr ( ) )
227
225
. expect ( "Freeing unallocated pages" ) ;
228
226
let ptr = self . huge_allocs . remove ( idx) . 0 ;
229
227
unsafe {
0 commit comments