avoid arena allocation of stream in read_term_from_chars (#1266)

This commit is contained in:
Mark Thom
2023-01-31 00:15:57 -07:00
parent 5667ec8699
commit ce56a7303e
3 changed files with 31 additions and 14 deletions

View File

@@ -698,9 +698,9 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) {
ArenaHeaderTag::HttpReadStream => { ArenaHeaderTag::HttpReadStream => {
ptr::drop_in_place(value.payload_offset::<StreamLayout<CharReader<HttpReadStream>>>()); ptr::drop_in_place(value.payload_offset::<StreamLayout<CharReader<HttpReadStream>>>());
} }
ArenaHeaderTag::HttpWriteStream => { ArenaHeaderTag::HttpWriteStream => {
ptr::drop_in_place(value.payload_offset::<StreamLayout<CharReader<HttpWriteStream>>>()); ptr::drop_in_place(value.payload_offset::<StreamLayout<CharReader<HttpWriteStream>>>());
} }
ArenaHeaderTag::ReadlineStream => { ArenaHeaderTag::ReadlineStream => {
ptr::drop_in_place(value.payload_offset::<StreamLayout<ReadlineStream>>()); ptr::drop_in_place(value.payload_offset::<StreamLayout<ReadlineStream>>());
} }
@@ -721,12 +721,12 @@ unsafe fn drop_slab_in_place(value: &mut AllocSlab) {
ArenaHeaderTag::TcpListener => { ArenaHeaderTag::TcpListener => {
ptr::drop_in_place(value.payload_offset::<TcpListener>()); ptr::drop_in_place(value.payload_offset::<TcpListener>());
} }
ArenaHeaderTag::HttpListener => { ArenaHeaderTag::HttpListener => {
ptr::drop_in_place(value.payload_offset::<HttpListener>()); ptr::drop_in_place(value.payload_offset::<HttpListener>());
} }
ArenaHeaderTag::HttpResponse => { ArenaHeaderTag::HttpResponse => {
ptr::drop_in_place(value.payload_offset::<HttpResponse>()); ptr::drop_in_place(value.payload_offset::<HttpResponse>());
} }
ArenaHeaderTag::StandardOutputStream => { ArenaHeaderTag::StandardOutputStream => {
ptr::drop_in_place(value.payload_offset::<StreamLayout<StandardOutputStream>>()); ptr::drop_in_place(value.payload_offset::<StreamLayout<StandardOutputStream>>());
} }

View File

@@ -102,6 +102,13 @@ impl EOFAction {
#[derive(Debug)] #[derive(Debug)]
pub struct ByteStream(Cursor<Vec<u8>>); pub struct ByteStream(Cursor<Vec<u8>>);
impl ByteStream {
#[inline(always)]
pub fn from_string(string: String) -> Self {
ByteStream(Cursor::new(string.into()))
}
}
impl Read for ByteStream { impl Read for ByteStream {
#[inline] #[inline]
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
@@ -1132,14 +1139,14 @@ impl Stream {
Ok(()) Ok(())
} }
Stream::HttpWrite(ref mut http_stream) => { Stream::HttpWrite(ref mut http_stream) => {
unsafe { unsafe {
http_stream.set_tag(ArenaHeaderTag::Dropped); http_stream.set_tag(ArenaHeaderTag::Dropped);
std::ptr::drop_in_place(&mut http_stream.inner_mut().body_writer as *mut _); std::ptr::drop_in_place(&mut http_stream.inner_mut().body_writer as *mut _);
} }
Ok(()) Ok(())
} }
Stream::InputFile(mut file_stream) => { Stream::InputFile(mut file_stream) => {
// close the stream by dropping the inner File. // close the stream by dropping the inner File.
unsafe { unsafe {

View File

@@ -5138,10 +5138,20 @@ impl Machine {
#[inline(always)] #[inline(always)]
pub(crate) fn read_term_from_chars(&mut self) -> CallResult { 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]) { 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 chars = CharReader::new(ByteStream::from_string(atom_or_string.to_string()));
let stream = Stream::from_owned_string(chars, &mut self.machine_st.arena); let mut parser = Parser::new(chars, &mut self.machine_st);
let term_write_result = match self.machine_st.read(stream, &self.indices.op_dir) { 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 term_write_result {
Ok(term_write_result) => term_write_result, Ok(term_write_result) => term_write_result,
Err(e) => { Err(e) => {
let stub = functor_stub(atom!("read_term_from_chars"), 2); let stub = functor_stub(atom!("read_term_from_chars"), 2);