@@ -199,7 +199,7 @@ struct BlockFree {
199199#[ derive( Debug ) ]
200200struct BlockUsed {
201201 size : usize ,
202- payload : usize ,
202+ payload : usize , // Act as placeholder
203203}
204204
205205impl BlockFree {
@@ -217,6 +217,10 @@ impl BlockFree {
217217 fn block_size ( & self ) -> usize {
218218 self . size & SIZE_MASK
219219 }
220+
221+ fn clear_alloced ( & mut self ) {
222+ self . size &= SIZE_MASK ;
223+ }
220224}
221225
222226impl BlockUsed {
@@ -243,6 +247,43 @@ impl BlockUsed {
243247 fn clear_alloced ( & mut self ) {
244248 self . size &= SIZE_MASK ;
245249 }
250+
251+ // Return the ptr of payload
252+ fn payload_ptr ( & self ) -> usize {
253+ self . payload as * const u8 as usize
254+ }
255+
256+ unsafe fn with_payload < ' a > ( payload_ptr : usize ) -> & ' a mut BlockUsed {
257+ let payload_ptr = payload_ptr as * const u8 ;
258+ let block = & mut * ( payload_ptr. byte_offset ( -( HEADER_SIZE as isize ) ) as * mut BlockUsed ) ;
259+ block
260+ }
261+ }
262+
263+ impl < ' a > From < & ' a mut BlockFree > for & ' a mut BlockUsed {
264+ fn from ( block_free : & ' a mut BlockFree ) -> Self {
265+ let block_used = unsafe { & mut * ( block_free as * mut _ as * mut BlockUsed ) } ;
266+
267+ block_used. size = block_free. block_size ( ) ;
268+ // Clear residual link information
269+ block_used. payload = 0 ;
270+ block_used. set_alloced ( ) ;
271+
272+ block_used
273+ }
274+ }
275+
276+ impl < ' a > From < & ' a mut BlockUsed > for & ' a mut BlockFree {
277+ fn from ( block_used : & ' a mut BlockUsed ) -> Self {
278+ let block_free = unsafe { & mut * ( block_used as * mut _ as * mut BlockFree ) } ;
279+
280+ block_free. size = block_used. block_size ( ) ;
281+ block_free. link = Link :: new ( ) ;
282+ // Useless method to mark free tag
283+ block_free. clear_alloced ( ) ;
284+
285+ block_free
286+ }
246287}
247288
248289intrusive_adapter ! ( BlockFreeAda = UnsafeRef <BlockFree >: BlockFree { link: Link } ) ;
@@ -367,36 +408,21 @@ impl Reserve {
367408 idx
368409 }
369410
370- // Reconstruct BlockUsed with BlockFree block_size() and set alloc, return payload addr.
371- // BlockFree -> BlockUsed -> Payload addr (Used)
372- fn block_to_payload ( & self , block : UnsafeRef < BlockFree > ) -> usize {
373- let block_size = block. block_size ( ) ;
374- let mut block_used = BlockUsed :: new ( block_size) ;
375- block_used. set_alloced ( ) ;
376-
377- let block_used_ptr = UnsafeRef :: into_raw ( block) as * mut BlockUsed ;
378- unsafe {
379- block_used_ptr. write ( block_used) ;
380- // Regular offset shifts count*T bytes
381- block_used_ptr. byte_offset ( HEADER_SIZE as isize ) as usize
382- }
411+ // Reconstruct BlockUsed with BlockFree block_size() and set alloc, return payload ptr.
412+ // BlockFree -> BlockUsed -> Payload ptr (Used)
413+ fn block_to_payload ( & self , mut block_free : UnsafeRef < BlockFree > ) -> usize {
414+ // Inexplicily change inner data of pointer
415+ let block_used: & mut BlockUsed = block_free. as_mut ( ) . into ( ) ;
416+ block_used. payload_ptr ( )
383417 }
384418
385- // Reconstruct a new BlockFree with BlockUsed block_size(), return payload addr.
386- // Payload addr (Used) -> BlockUsed -> BlockFree
387- fn payload_to_block ( & self , payload_addr : usize ) -> UnsafeRef < BlockFree > {
388- let payload_ptr = payload_addr as * const u8 ;
389- let block_used_ptr =
390- unsafe { payload_ptr. byte_offset ( -( HEADER_SIZE as isize ) ) as * mut BlockUsed } ;
391-
392- // Implicitly clear alloc mask, reconstruct new BlockFree
393- let block_size = unsafe { block_used_ptr. read ( ) . block_size ( ) } ;
394- let block_free = BlockFree :: new ( block_size) ;
395- let block_free_ptr = block_used_ptr as * mut BlockFree ;
396- unsafe {
397- block_free_ptr. write ( block_free) ;
398- UnsafeRef :: from_raw ( block_free_ptr)
399- }
419+ // Reconstruct a new BlockFree with BlockUsed block_size(), return payload ptr.
420+ // Payload ptr (Used) -> BlockUsed -> BlockFree
421+ fn payload_to_block ( & self , payload_ptr : usize ) -> UnsafeRef < BlockFree > {
422+ let block_used = unsafe { BlockUsed :: with_payload ( payload_ptr) } ;
423+ // Inexplicily change inner data of pointer
424+ let block_free: & mut BlockFree = block_used. into ( ) ;
425+ unsafe { UnsafeRef :: from_raw ( block_free as * const BlockFree ) }
400426 }
401427
402428 /// Malloc memory
0 commit comments