From ce56a7303e9a84a28031655acd56299537890a5c Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 31 Jan 2023 00:15:57 -0700 Subject: [PATCH] avoid arena allocation of stream in read_term_from_chars (#1266) --- src/arena.rs | 18 +++++++++--------- src/machine/streams.rs | 11 +++++++++-- src/machine/system_calls.rs | 16 +++++++++++++--- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/arena.rs b/src/arena.rs index 3e75e120..b055c8db 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -698,9 +698,9 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) { ArenaHeaderTag::HttpReadStream => { ptr::drop_in_place(value.payload_offset::>>()); } - ArenaHeaderTag::HttpWriteStream => { - ptr::drop_in_place(value.payload_offset::>>()); - } + ArenaHeaderTag::HttpWriteStream => { + ptr::drop_in_place(value.payload_offset::>>()); + } ArenaHeaderTag::ReadlineStream => { ptr::drop_in_place(value.payload_offset::>()); } @@ -721,12 +721,12 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) { ArenaHeaderTag::TcpListener => { ptr::drop_in_place(value.payload_offset::()); } - ArenaHeaderTag::HttpListener => { - ptr::drop_in_place(value.payload_offset::()); - } - ArenaHeaderTag::HttpResponse => { - ptr::drop_in_place(value.payload_offset::()); - } + ArenaHeaderTag::HttpListener => { + ptr::drop_in_place(value.payload_offset::()); + } + ArenaHeaderTag::HttpResponse => { + ptr::drop_in_place(value.payload_offset::()); + } ArenaHeaderTag::StandardOutputStream => { ptr::drop_in_place(value.payload_offset::>()); } diff --git a/src/machine/streams.rs b/src/machine/streams.rs index 9e558af5..932e7f78 100644 --- a/src/machine/streams.rs +++ b/src/machine/streams.rs @@ -102,6 +102,13 @@ impl EOFAction { #[derive(Debug)] pub struct ByteStream(Cursor>); +impl ByteStream { + #[inline(always)] + pub fn from_string(string: String) -> Self { + ByteStream(Cursor::new(string.into())) + } +} + impl Read for ByteStream { #[inline] fn read(&mut self, buf: &mut [u8]) -> std::io::Result { @@ -1132,14 +1139,14 @@ impl Stream { Ok(()) } - Stream::HttpWrite(ref mut http_stream) => { + Stream::HttpWrite(ref mut http_stream) => { unsafe { http_stream.set_tag(ArenaHeaderTag::Dropped); std::ptr::drop_in_place(&mut http_stream.inner_mut().body_writer as *mut _); } Ok(()) - } + } Stream::InputFile(mut file_stream) => { // close the stream by dropping the inner File. unsafe { diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 69dc018e..93dcdb09 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -5138,10 +5138,20 @@ impl Machine { #[inline(always)] pub(crate) fn read_term_from_chars(&mut self) -> CallResult { if let Some(atom_or_string) = self.machine_st.value_to_str_like(self.machine_st.registers[1]) { - let chars = atom_or_string.to_string(); - let stream = Stream::from_owned_string(chars, &mut self.machine_st.arena); + let chars = CharReader::new(ByteStream::from_string(atom_or_string.to_string())); + let mut parser = Parser::new(chars, &mut self.machine_st); + + let term_write_result = parser.read_term(&CompositeOpDir::new(&self.indices.op_dir, None)) + .map_err(CompilationError::from) + .and_then(|term| { + write_term_to_heap( + &term, + &mut self.machine_st.heap, + &mut self.machine_st.atom_tbl, + ) + }); - let term_write_result = match self.machine_st.read(stream, &self.indices.op_dir) { + let term_write_result = match term_write_result { Ok(term_write_result) => term_write_result, Err(e) => { let stub = functor_stub(atom!("read_term_from_chars"), 2); -- 2.54.0