@@ -125,16 +125,25 @@ pub struct RawTransferMetadata2 {
125125 /// * Also be set to `true` if `FixedSizeAllocator` is dropped on Rust side.
126126 /// Memory will be freed in finalizer when JS garbage collector collects the buffer.
127127 pub ( crate ) can_be_freed : AtomicBool ,
128- /// Padding to pad struct to size 16.
129- pub ( crate ) _padding : u32 ,
128+ /// Pointer to start of original allocation backing the `Allocator`.
129+ pub ( crate ) alloc_ptr : NonNull < u8 > ,
130+ /// Padding to pad struct to size 32.
131+ pub ( crate ) _padding : u64 ,
130132}
131133use RawTransferMetadata2 as RawTransferMetadata ;
132134
133135const METADATA_SIZE : usize = size_of :: < RawTransferMetadata > ( ) ;
134136
135137impl RawTransferMetadata {
136- fn new ( id : u32 ) -> Self {
137- Self { data_offset : 0 , is_ts : false , id, can_be_freed : AtomicBool :: new ( true ) , _padding : 0 }
138+ fn new ( id : u32 , alloc_ptr : NonNull < u8 > ) -> Self {
139+ Self {
140+ data_offset : 0 ,
141+ is_ts : false ,
142+ id,
143+ can_be_freed : AtomicBool :: new ( true ) ,
144+ alloc_ptr,
145+ _padding : 0 ,
146+ }
138147 }
139148}
140149
@@ -175,8 +184,6 @@ const ALLOC_LAYOUT: Layout = match Layout::from_size_align(ALLOC_SIZE, ALLOC_ALI
175184pub struct FixedSizeAllocator {
176185 /// `Allocator` which utilizes part of the original allocation
177186 allocator : ManuallyDrop < Allocator > ,
178- /// Pointer to start of original allocation
179- alloc_ptr : NonNull < u8 > ,
180187}
181188
182189impl FixedSizeAllocator {
@@ -215,14 +222,14 @@ impl FixedSizeAllocator {
215222 let allocator = unsafe { Allocator :: from_raw_parts ( chunk_ptr, CHUNK_SIZE ) } ;
216223
217224 // Store metadata after allocator chunk
218- let metadata = RawTransferMetadata :: new ( id) ;
225+ let metadata = RawTransferMetadata :: new ( id, alloc_ptr ) ;
219226 // SAFETY: `chunk_ptr` is at least `BUFFER_SIZE` bytes from the end of the allocation.
220227 // `CHUNK_SIZE` had the size of `RawTransferMetadata` subtracted from it.
221228 // So there is space within the allocation for `RawTransferMetadata` after the `Allocator`'s chunk.
222229 unsafe { chunk_ptr. add ( CHUNK_SIZE ) . cast :: < RawTransferMetadata > ( ) . write ( metadata) } ;
223230
224231 // Store pointer to original allocation, so it can be used to deallocate in `drop`
225- Self { allocator : ManuallyDrop :: new ( allocator) , alloc_ptr }
232+ Self { allocator : ManuallyDrop :: new ( allocator) }
226233 }
227234
228235 /// Reset this [`FixedSizeAllocator`].
@@ -245,8 +252,17 @@ impl FixedSizeAllocator {
245252
246253impl Drop for FixedSizeAllocator {
247254 fn drop ( & mut self ) {
255+ // Get pointer to start of allocation backing this `FixedSizeAllocator`
256+ let alloc_ptr = {
257+ let metadata_ptr = self . allocator . end_ptr ( ) . cast :: < RawTransferMetadata > ( ) ;
258+ // SAFETY: `FixedSizeAllocator` is being dropped, so no other references to data in it may exist.
259+ // `FixedSizeAllocator::new` wrote `RawTransferMetadata` to the location pointed to by `end_ptr`.
260+ let metadata = unsafe { metadata_ptr. as_ref ( ) } ;
261+ metadata. alloc_ptr
262+ } ;
263+
248264 // SAFETY: Originally allocated from `System` allocator at `alloc_ptr`, with layout `ALLOC_LAYOUT`
249- unsafe { System . dealloc ( self . alloc_ptr . as_ptr ( ) , ALLOC_LAYOUT ) }
265+ unsafe { System . dealloc ( alloc_ptr. as_ptr ( ) , ALLOC_LAYOUT ) }
250266 }
251267}
252268
0 commit comments