@@ -199,7 +199,7 @@ struct BlockFree {
199
199
#[ derive( Debug ) ]
200
200
struct BlockUsed {
201
201
size : usize ,
202
- payload : usize ,
202
+ payload : usize , // Act as placeholder
203
203
}
204
204
205
205
impl BlockFree {
@@ -217,6 +217,10 @@ impl BlockFree {
217
217
fn block_size ( & self ) -> usize {
218
218
self . size & SIZE_MASK
219
219
}
220
+
221
+ fn clear_alloced ( & mut self ) {
222
+ self . size &= SIZE_MASK ;
223
+ }
220
224
}
221
225
222
226
impl BlockUsed {
@@ -243,6 +247,43 @@ impl BlockUsed {
243
247
fn clear_alloced ( & mut self ) {
244
248
self . size &= SIZE_MASK ;
245
249
}
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
+ }
246
287
}
247
288
248
289
intrusive_adapter ! ( BlockFreeAda = UnsafeRef <BlockFree >: BlockFree { link: Link } ) ;
@@ -367,36 +408,21 @@ impl Reserve {
367
408
idx
368
409
}
369
410
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 ( )
383
417
}
384
418
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 ) }
400
426
}
401
427
402
428
/// Malloc memory
0 commit comments