Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] - Try to optimize preorder iteration with pool allocation #121

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion src/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ impl<T: ?Sized + Hash> Hash for Arc<T> {
pub(crate) struct HeaderSlice<H, T: ?Sized> {
pub(crate) header: H,
length: usize,
slice: T,
pub(crate) slice: T,
}

impl<H, T> HeaderSlice<H, [T]> {
Expand Down
40 changes: 33 additions & 7 deletions src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,23 @@

use std::{
borrow::Cow,
cell::Cell,
cell::{Cell, RefCell},
fmt,
hash::{Hash, Hasher},
iter,
marker::PhantomData,
mem::{self, ManuallyDrop},
ops::Range,
ptr, slice,
ptr,
rc::Rc,
slice,
};

use countme::Count;

use crate::{
green::{GreenChild, GreenElementRef, GreenNodeData, GreenTokenData, SyntaxKind},
pool::Pool,
sll,
utility_types::Delta,
Direction, GreenNode, GreenToken, NodeOrToken, SyntaxText, TextRange, TextSize, TokenAtOffset,
Expand Down Expand Up @@ -186,12 +190,27 @@ impl Drop for SyntaxToken {
}
}

struct NodeDataDeallocator {
data: ptr::NonNull<NodeData>,
}

impl Drop for NodeDataDeallocator {
fn drop(&mut self) {
unsafe {
NodeData::POOL.with(|pool| {
pool.borrow_mut().deallocate(self.data);
});
}
}
}

#[inline(never)]
unsafe fn free(mut data: ptr::NonNull<NodeData>) {
loop {
debug_assert_eq!(data.as_ref().rc.get(), 0);
debug_assert!(data.as_ref().first.get().is_null());
let node = Box::from_raw(data.as_ptr());
let _to_drop = NodeDataDeallocator { data };
let node = data.as_ref();
match node.parent.take() {
Some(parent) => {
debug_assert!(parent.as_ref().rc.get() > 0);
Expand Down Expand Up @@ -220,6 +239,10 @@ unsafe fn free(mut data: ptr::NonNull<NodeData>) {
}

impl NodeData {
thread_local! {
static POOL: RefCell<Pool<NodeData>> = RefCell::new(Pool::default());
}

#[inline]
fn new(
parent: Option<SyntaxNode>,
Expand Down Expand Up @@ -269,13 +292,13 @@ impl NodeData {
return ptr::NonNull::new_unchecked(res);
}
it => {
let res = Box::into_raw(Box::new(res));
it.add_to_sll(res);
return ptr::NonNull::new_unchecked(res);
let res = Self::POOL.with(move |pool| pool.borrow_mut().allocate(res));
it.add_to_sll(res.as_ptr());
return res;
}
}
}
ptr::NonNull::new_unchecked(Box::into_raw(Box::new(res)))
Self::POOL.with(move |pool| pool.borrow_mut().allocate(res))
}
}

Expand Down Expand Up @@ -388,6 +411,7 @@ impl NodeData {
})
})
}

fn prev_sibling(&self) -> Option<SyntaxNode> {
let mut rev_siblings = self.green_siblings().enumerate().rev();
let index = rev_siblings.len() - (self.index() as usize);
Expand Down Expand Up @@ -647,6 +671,7 @@ impl SyntaxNode {
})
})
}

pub fn last_child(&self) -> Option<SyntaxNode> {
self.green_ref().children().raw.enumerate().rev().find_map(|(index, child)| {
child.as_ref().into_node().map(|green| {
Expand Down Expand Up @@ -679,6 +704,7 @@ impl SyntaxNode {
pub fn next_sibling(&self) -> Option<SyntaxNode> {
self.data().next_sibling()
}

pub fn prev_sibling(&self) -> Option<SyntaxNode> {
self.data().prev_sibling()
}
Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

#[allow(unsafe_code)]
mod green;

#[allow(unsafe_code)]
pub mod pool;

#[allow(unsafe_code)]
pub mod cursor;

Expand Down
Loading