Skip to content

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

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
wants to merge 11 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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