ast: Use boxed slice instead of vec for list nodes

This saves a decent amount of memory, both because we no longer have excess
capacity sitting around that we'll never use, but also because we no longer need
to store the "capacity" value.
This commit is contained in:
Peter Ammon
2025-03-16 13:45:48 -07:00
parent 271a85571d
commit be88d103ba

View File

@@ -439,7 +439,7 @@ fn allows_keyword(&self, kw: ParseKeyword) -> bool {
pub trait List: Node {
type ContentsNode: Node + Default;
fn contents(&self) -> &[Box<Self::ContentsNode>];
fn contents_mut(&mut self) -> &mut Vec<Box<Self::ContentsNode>>;
fn contents_mut(&mut self) -> &mut Box<[Box<Self::ContentsNode>]>;
/// Return our count.
fn count(&self) -> usize {
self.contents().len()
@@ -636,7 +636,8 @@ macro_rules! define_list_node {
#[derive(Default, Debug)]
pub struct $name {
parent: Option<*const dyn Node>,
list_contents: Vec<Box<$contents>>,
// Note we box the nodes themselves, for pointer stability.
list_contents: Box<[Box<$contents>]>,
}
implement_node!($name, list, $type);
impl List for $name {
@@ -644,7 +645,7 @@ impl List for $name {
fn contents(&self) -> &[Box<Self::ContentsNode>] {
&self.list_contents
}
fn contents_mut(&mut self) -> &mut Vec<Box<Self::ContentsNode>> {
fn contents_mut(&mut self) -> &mut Box<[Box<Self::ContentsNode>]> {
&mut self.list_contents
}
}
@@ -3547,7 +3548,6 @@ fn populate_list<ListType: List>(&mut self, list: &mut ListType, exhaust_stream:
}
// We're going to populate a vector with our nodes.
// Later on we will copy this to the heap with a single allocation.
let mut contents = vec![];
loop {
@@ -3614,7 +3614,7 @@ fn populate_list<ListType: List>(&mut self, list: &mut ListType, exhaust_stream:
"Contents size out of bounds"
);
assert!(list.contents().is_empty(), "List should still be empty");
*list.contents_mut() = contents;
*list.contents_mut() = contents.into_boxed_slice();
}
FLOGF!(