@@ -203,7 +203,8 @@ fn allocate_first_fit(previous: &mut Hole, size: usize, align: usize) -> Option<
203203
204204/// Frees the allocation given by `(addr, size)`. It starts at the given hole and walks the list to
205205/// find the correct place (the list is sorted by address).
206- fn deallocate ( hole : & mut Hole , addr : usize , size : usize ) {
206+ fn deallocate ( mut hole : & mut Hole , addr : usize , mut size : usize ) {
207+ loop {
207208 assert ! ( size >= HoleList :: min_size( ) ) ;
208209
209210 let hole_addr = if hole. size == 0 {
@@ -216,8 +217,8 @@ fn deallocate(hole: &mut Hole, addr: usize, size: usize) {
216217 hole as * mut _ as usize
217218 } ;
218219
219- // Each freed block must be handled by the previous hole in memory. Thus the freed address must
220- // be always behind the current hole.
220+ // Each freed block must be handled by the previous hole in memory. Thus the freed
221+ // address must be always behind the current hole.
221222 assert ! ( hole_addr + hole. size <= addr) ;
222223
223224 // get information about the next block
@@ -245,14 +246,16 @@ fn deallocate(hole: &mut Hole, addr: usize, size: usize) {
245246 // after: ___XXX__FFFFYYYYY____ where F is the freed block
246247
247248 hole. next = hole. next_unwrap ( ) . next . take ( ) ; // remove the Y block
248- deallocate ( hole, addr, size + next. size ) ; // free the merged F/Y block
249+ size += next. size ; // free the merged F/Y block in next iteration
250+ continue ;
249251 }
250252 Some ( next) if next. addr <= addr => {
251253 // block is behind the next hole, so we delegate it to the next hole
252254 // before: ___XXX__YYYYY________ where X is this hole and Y the next hole
253255 // after: ___XXX__YYYYY__FFFF__ where F is the freed block
254256
255- deallocate ( hole. next_unwrap ( ) , addr, size) ;
257+ hole = move_helper ( hole) . next_unwrap ( ) ; // start next iteration at next hole
258+ continue ;
256259 }
257260 _ => {
258261 // block is between this and the next hole
@@ -274,4 +277,17 @@ fn deallocate(hole: &mut Hole, addr: usize, size: usize) {
274277 hole. next = Some ( unsafe { Unique :: new ( ptr) } ) ;
275278 }
276279 }
280+ break ;
281+ }
282+ }
283+
284+ /// Identity function to ease moving of references.
285+ ///
286+ /// By default, references are reborrowed instead of moved (equivalent to `&mut *reference`). This
287+ /// function forces a move.
288+ ///
289+ /// for more information, see:
290+ /// https://bluss.github.io/rust/fun/2015/10/11/stuff-the-identity-function-does/#id-forces-references-to-move
291+ fn move_helper < T > ( x : T ) -> T {
292+ x
277293}
0 commit comments