From: Bennet Bleßmann Date: Sun, 7 Jul 2024 13:21:08 +0000 (+0200) Subject: wrap Payloads that are dropped eraly in ManuallyDrop X-Git-Tag: v0.10.0~127^2~2 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=1b19ae81d5c3dff3806f9fa7404a0ce0a195fe04;p=scryer-prolog.git wrap Payloads that are dropped eraly in ManuallyDrop --- diff --git a/src/arena.rs b/src/arena.rs index bb346810..c532d24a 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -310,6 +310,13 @@ impl TypedArenaPtr { } } +impl>> TypedArenaPtr { + pub fn drop_payload(&mut self) { + self.set_tag(ArenaHeaderTag::Dropped); + unsafe { ManuallyDrop::drop(&mut *self.as_ptr()) } + } +} + impl TypedArenaPtr where T::Payload: Sized, @@ -582,16 +589,34 @@ impl ArenaAllocated for Rational { } } +impl AllocateInArena for LiveLoadState { + fn arena_allocate(self, arena: &mut Arena) -> TypedArenaPtr { + LiveLoadState::alloc(arena, ManuallyDrop::new(self)) + } +} + impl ArenaAllocated for LiveLoadState { - type Payload = Self; + type Payload = ManuallyDrop; #[inline] fn tag() -> ArenaHeaderTag { ArenaHeaderTag::LiveLoadState } + + unsafe fn dealloc(ptr: NonNull>) { + let mut slab = unsafe { Box::from_raw(ptr.as_ptr()) }; + unsafe { ManuallyDrop::drop(&mut slab.payload) }; + drop(slab); + } +} + +impl AllocateInArena for TcpListener { + fn arena_allocate(self, arena: &mut Arena) -> TypedArenaPtr { + TcpListener::alloc(arena, ManuallyDrop::new(self)) + } } impl ArenaAllocated for TcpListener { - type Payload = Self; + type Payload = ManuallyDrop; #[inline] fn tag() -> ArenaHeaderTag { ArenaHeaderTag::TcpListener @@ -701,6 +726,10 @@ pub struct TypedAllocSlab { } impl TypedAllocSlab { + pub fn payload(&mut self) -> &mut T::Payload { + &mut self.payload + } + /// # Safety /// - ptr points to a valid allocation of Self #[inline] diff --git a/src/machine/loader.rs b/src/machine/loader.rs index 0dfdfad2..07efb58a 100644 --- a/src/machine/loader.rs +++ b/src/machine/loader.rs @@ -305,11 +305,11 @@ impl<'a> LoadState<'a> for LiveLoadAndMachineState<'a> { #[inline(always)] fn evacuate(mut loader: Loader<'a, Self>) -> Result { if loader.payload.load_state.get_tag() != ArenaHeaderTag::Dropped { - loader - .payload - .load_state - .set_tag(ArenaHeaderTag::InactiveLoadState); - Ok(loader.payload.load_state) + loader + .payload + .load_state + .set_tag(ArenaHeaderTag::InactiveLoadState); + Ok(loader.payload.load_state) } else { unreachable!("we never evacuate after dropping") } @@ -323,7 +323,7 @@ impl<'a> LoadState<'a> for LiveLoadAndMachineState<'a> { #[inline(always)] fn reset_machine(loader: &mut Loader<'a, Self>) { if loader.payload.load_state.get_tag() != ArenaHeaderTag::Dropped { - loader.payload.load_state.set_tag(ArenaHeaderTag::Dropped); + loader.payload.load_state.drop_payload(); loader.reset_machine(); } } @@ -1788,11 +1788,8 @@ impl Machine { (HeapCellValueTag::Cons, cons_ptr) => { match_untyped_arena_ptr!(cons_ptr, (ArenaHeaderTag::LiveLoadState, payload) => { - unsafe { - std::ptr::drop_in_place( - payload.as_ptr() as *mut LiveLoadState, - ); - } + let mut payload = payload; + payload.drop_payload() } _ => {} ); diff --git a/src/machine/streams.rs b/src/machine/streams.rs index 61191205..b6281933 100644 --- a/src/machine/streams.rs +++ b/src/machine/streams.rs @@ -454,13 +454,25 @@ impl DerefMut for StreamLayout { macro_rules! arena_allocated_impl_for_stream { ($stream_type:ty, $stream_tag:ident) => { + impl $crate::arena::AllocateInArena<$stream_tag> for StreamLayout<$stream_type> { + fn arena_allocate(self, arena: &mut Arena) -> TypedArenaPtr<$stream_tag> { + $stream_tag::alloc(arena, core::mem::ManuallyDrop::new(self)) + } + } + impl ArenaAllocated for $stream_tag { - type Payload = StreamLayout<$stream_type>; + type Payload = core::mem::ManuallyDrop>; #[inline] fn tag() -> ArenaHeaderTag { ArenaHeaderTag::$stream_tag } + + unsafe fn dealloc(ptr: std::ptr::NonNull>) { + let mut slab = unsafe { Box::from_raw(ptr.as_ptr()) }; + unsafe { std::mem::ManuallyDrop::drop(slab.payload()) }; + drop(slab); + } } }; } @@ -994,7 +1006,7 @@ impl Stream { past_end_of_stream, stream, .. - } = &mut **stream_layout; + } = &mut ***stream_layout; stream .get_mut() @@ -1068,7 +1080,7 @@ impl Stream { past_end_of_stream, stream, .. - } = &mut **stream_layout; + } = &mut ***stream_layout; let cursor_len = stream.get_ref().0.get_ref().len() as u64; cursor_position(past_end_of_stream, &stream.get_ref().0, cursor_len) @@ -1078,7 +1090,7 @@ impl Stream { past_end_of_stream, stream, .. - } = &mut **stream_layout; + } = &mut ***stream_layout; let cursor_len = stream.stream.get_ref().len() as u64; cursor_position(past_end_of_stream, &stream.stream, cursor_len) @@ -1090,7 +1102,7 @@ impl Stream { past_end_of_stream, stream, .. - } = &mut **stream_layout; + } = &mut ***stream_layout; match stream.get_ref().file.metadata() { Ok(metadata) => { @@ -1270,38 +1282,25 @@ impl Stream { Stream::NamedTls(ref mut tls_stream) => tls_stream.inner_mut().tls_stream.shutdown(), #[cfg(feature = "http")] Stream::HttpRead(ref mut http_stream) => { - unsafe { - http_stream.set_tag(ArenaHeaderTag::Dropped); - std::ptr::drop_in_place(&mut http_stream.inner_mut().body_reader as *mut _); - } + http_stream.drop_payload(); Ok(()) } #[cfg(feature = "http")] - Stream::HttpWrite(ref mut http_stream) => { - http_stream.inner_mut().drop(); - unsafe { - http_stream.set_tag(ArenaHeaderTag::Dropped); - std::ptr::drop_in_place(&mut http_stream.inner_mut().buffer as *mut _); - } + Stream::HttpWrite(mut http_stream) => { + http_stream.drop_payload(); Ok(()) } Stream::InputFile(mut file_stream) => { // close the stream by dropping the inner File. - unsafe { - file_stream.set_tag(ArenaHeaderTag::Dropped); - std::ptr::drop_in_place(&mut file_stream.inner_mut().file as *mut _); - } + file_stream.drop_payload(); Ok(()) } Stream::OutputFile(mut file_stream) => { // close the stream by dropping the inner File. - unsafe { - file_stream.set_tag(ArenaHeaderTag::Dropped); - std::ptr::drop_in_place(&mut file_stream.file as *mut _); - } + file_stream.drop_payload(); Ok(()) } diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 17095a36..1145a450 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -6737,12 +6737,8 @@ impl Machine { (HeapCellValueTag::Cons, cons_ptr) => { match_untyped_arena_ptr!(cons_ptr, (ArenaHeaderTag::TcpListener, tcp_listener) => { - unsafe { - // dropping closes the instance. - std::ptr::drop_in_place(&mut tcp_listener as *mut _); - } + tcp_listener.drop_payload(); - tcp_listener.set_tag(ArenaHeaderTag::Dropped); return Ok(()); } _ => {