Skip to content

Commit cfc98d3

Browse files
committed
Prepare to store offset_in_parent in green nodes
1 parent 6a61abd commit cfc98d3

File tree

5 files changed

+70
-240
lines changed

5 files changed

+70
-240
lines changed

Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ description = "Library for generic lossless syntax trees"
88
edition = "2018"
99

1010
[dependencies]
11-
erasable = "1.2.1"
1211
rustc-hash = "1.0.1"
13-
slice-dst = "1.4.1"
1412
smol_str = "0.1.10"
1513
text-size = "1.0.0"
1614
triomphe = "0.1.1"

src/green.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ mod token;
33
mod element;
44
mod builder;
55

6+
use self::element::GreenElement;
67
pub(crate) use self::element::GreenElementRef;
7-
use self::element::{GreenElement, PackedGreenElement};
88

99
pub use self::{
1010
builder::{Checkpoint, GreenNodeBuilder, NodeCache},
@@ -26,7 +26,6 @@ mod tests {
2626
f::<GreenNode>();
2727
f::<GreenToken>();
2828
f::<GreenElement>();
29-
f::<PackedGreenElement>();
3029
}
3130

3231
#[test]
@@ -36,6 +35,5 @@ mod tests {
3635
eprintln!("GreenNode {}", size_of::<GreenNode>());
3736
eprintln!("GreenToken {}", size_of::<GreenToken>());
3837
eprintln!("GreenElement {}", size_of::<GreenElement>());
39-
eprintln!("PackedGreenElement {}", size_of::<PackedGreenElement>());
4038
}
4139
}

src/green/element.rs

Lines changed: 0 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
use std::{fmt, hash, mem};
2-
3-
use erasable::ErasedPtr;
4-
51
use crate::{
62
green::{GreenNode, GreenToken, SyntaxKind},
73
NodeOrToken, TextSize,
@@ -10,11 +6,6 @@ use crate::{
106
pub(super) type GreenElement = NodeOrToken<GreenNode, GreenToken>;
117
pub(crate) type GreenElementRef<'a> = NodeOrToken<&'a GreenNode, &'a GreenToken>;
128

13-
#[repr(transparent)]
14-
pub(super) struct PackedGreenElement {
15-
ptr: ErasedPtr,
16-
}
17-
189
impl From<GreenNode> for GreenElement {
1910
#[inline]
2011
fn from(node: GreenNode) -> GreenElement {
@@ -29,13 +20,6 @@ impl<'a> From<&'a GreenNode> for GreenElementRef<'a> {
2920
}
3021
}
3122

32-
impl From<GreenNode> for PackedGreenElement {
33-
#[inline]
34-
fn from(node: GreenNode) -> PackedGreenElement {
35-
unsafe { mem::transmute(node) }
36-
}
37-
}
38-
3923
impl From<GreenToken> for GreenElement {
4024
#[inline]
4125
fn from(token: GreenToken) -> GreenElement {
@@ -50,13 +34,6 @@ impl<'a> From<&'a GreenToken> for GreenElementRef<'a> {
5034
}
5135
}
5236

53-
impl From<GreenToken> for PackedGreenElement {
54-
#[inline]
55-
fn from(token: GreenToken) -> PackedGreenElement {
56-
unsafe { mem::transmute(token) }
57-
}
58-
}
59-
6037
impl GreenElement {
6138
/// Returns kind of this element.
6239
#[inline]
@@ -90,121 +67,3 @@ impl GreenElementRef<'_> {
9067
}
9168
}
9269
}
93-
94-
impl From<GreenElement> for PackedGreenElement {
95-
fn from(element: GreenElement) -> Self {
96-
match element {
97-
NodeOrToken::Node(node) => node.into(),
98-
NodeOrToken::Token(token) => token.into(),
99-
}
100-
}
101-
}
102-
103-
impl From<PackedGreenElement> for GreenElement {
104-
fn from(element: PackedGreenElement) -> Self {
105-
if element.is_node() {
106-
NodeOrToken::Node(element.into_node().unwrap())
107-
} else {
108-
NodeOrToken::Token(element.into_token().unwrap())
109-
}
110-
}
111-
}
112-
113-
impl PackedGreenElement {
114-
fn is_node(&self) -> bool {
115-
self.ptr.as_ptr() as usize & 1 == 0
116-
}
117-
118-
pub(crate) fn as_node(&self) -> Option<&GreenNode> {
119-
if self.is_node() {
120-
unsafe { Some(&*(&self.ptr as *const ErasedPtr as *const GreenNode)) }
121-
} else {
122-
None
123-
}
124-
}
125-
126-
pub(crate) fn into_node(self) -> Option<GreenNode> {
127-
if self.is_node() {
128-
unsafe { Some(mem::transmute(self)) }
129-
} else {
130-
None
131-
}
132-
}
133-
134-
pub(crate) fn as_token(&self) -> Option<&GreenToken> {
135-
if !self.is_node() {
136-
unsafe { Some(&*(&self.ptr as *const ErasedPtr as *const GreenToken)) }
137-
} else {
138-
None
139-
}
140-
}
141-
142-
pub(crate) fn into_token(self) -> Option<GreenToken> {
143-
if !self.is_node() {
144-
unsafe { Some(mem::transmute(self)) }
145-
} else {
146-
None
147-
}
148-
}
149-
150-
pub(crate) fn as_ref(&self) -> GreenElementRef<'_> {
151-
if self.is_node() {
152-
NodeOrToken::Node(self.as_node().unwrap())
153-
} else {
154-
NodeOrToken::Token(self.as_token().unwrap())
155-
}
156-
}
157-
}
158-
159-
impl fmt::Debug for PackedGreenElement {
160-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161-
if self.is_node() {
162-
self.as_node().unwrap().fmt(f)
163-
} else {
164-
self.as_token().unwrap().fmt(f)
165-
}
166-
}
167-
}
168-
169-
impl Eq for PackedGreenElement {}
170-
impl PartialEq for PackedGreenElement {
171-
fn eq(&self, other: &Self) -> bool {
172-
self.as_node() == other.as_node() && self.as_token() == other.as_token()
173-
}
174-
}
175-
176-
impl hash::Hash for PackedGreenElement {
177-
fn hash<H>(&self, state: &mut H)
178-
where
179-
H: hash::Hasher,
180-
{
181-
if self.is_node() {
182-
self.as_node().unwrap().hash(state)
183-
} else {
184-
self.as_token().unwrap().hash(state)
185-
}
186-
}
187-
}
188-
189-
impl Drop for PackedGreenElement {
190-
fn drop(&mut self) {
191-
if self.is_node() {
192-
PackedGreenElement { ptr: self.ptr }.into_node();
193-
} else {
194-
PackedGreenElement { ptr: self.ptr }.into_token();
195-
}
196-
}
197-
}
198-
199-
unsafe impl Send for PackedGreenElement
200-
where
201-
GreenToken: Send,
202-
GreenNode: Send,
203-
{
204-
}
205-
unsafe impl Sync for PackedGreenElement
206-
where
207-
GreenToken: Sync,
208-
GreenNode: Sync,
209-
{
210-
}

src/green/node.rs

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
use std::{iter::FusedIterator, mem, slice, sync::Arc};
1+
use std::{ffi::c_void, fmt, iter::FusedIterator, mem, slice};
22

3-
use erasable::Thin;
4-
use slice_dst::SliceWithHeader;
3+
use triomphe::{Arc, ThinArc};
54

65
use crate::{
7-
green::{GreenElement, GreenElementRef, PackedGreenElement, SyntaxKind},
8-
GreenToken, TextSize,
6+
green::{GreenElement, GreenElementRef, SyntaxKind},
7+
GreenToken, NodeOrToken, TextSize,
98
};
109

11-
#[repr(align(2))] // NB: this is an at-least annotation
1210
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1311
pub(super) struct GreenNodeHead {
1412
kind: SyntaxKind,
@@ -17,23 +15,51 @@ pub(super) struct GreenNodeHead {
1715

1816
/// Internal node in the immutable tree.
1917
/// It has other nodes and tokens as children.
20-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21-
#[repr(transparent)]
18+
#[derive(Clone, PartialEq, Eq, Hash)]
2219
pub struct GreenNode {
23-
pub(super) data: Thin<Arc<SliceWithHeader<GreenNodeHead, PackedGreenElement>>>,
20+
data: ThinArc<GreenNodeHead, GreenChild>,
21+
}
22+
23+
impl fmt::Debug for GreenNode {
24+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25+
f.debug_struct("GreenNode")
26+
.field("kind", &self.kind())
27+
.field("text_len", &self.text_len())
28+
.field("n_children", &self.children().len())
29+
.finish()
30+
}
2431
}
2532

33+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2634
enum GreenChild {
2735
Node {
2836
// offset: TextSize,
29-
node: GreenNode
37+
node: GreenNode,
3038
},
3139
Token {
3240
// offset: TextSize,
33-
token: GreenToken
41+
token: GreenToken,
3442
},
3543
}
3644

45+
impl From<GreenElement> for GreenChild {
46+
fn from(e: GreenElement) -> Self {
47+
match e {
48+
NodeOrToken::Node(node) => GreenChild::Node { node },
49+
NodeOrToken::Token(token) => GreenChild::Token { token },
50+
}
51+
}
52+
}
53+
54+
impl GreenChild {
55+
fn as_ref(&self) -> GreenElementRef {
56+
match self {
57+
GreenChild::Node { node } => NodeOrToken::Node(node),
58+
GreenChild::Token { token } => NodeOrToken::Token(token),
59+
}
60+
}
61+
}
62+
3763
#[cfg(target_pointer_width = "64")]
3864
const _: () = {
3965
let cond = mem::size_of::<GreenChild>() == mem::size_of::<usize>() * 2;
@@ -49,30 +75,33 @@ impl GreenNode {
4975
I::IntoIter: ExactSizeIterator,
5076
{
5177
let mut text_len: TextSize = 0.into();
52-
let children = children
53-
.into_iter()
54-
.inspect(|it| text_len += it.text_len())
55-
.map(PackedGreenElement::from);
56-
let mut data: Arc<_> =
57-
SliceWithHeader::new(GreenNodeHead { kind, text_len: 0.into() }, children);
78+
let children =
79+
children.into_iter().inspect(|it| text_len += it.text_len()).map(GreenChild::from);
80+
81+
let data =
82+
ThinArc::from_header_and_iter(GreenNodeHead { kind, text_len: 0.into() }, children);
5883

5984
// XXX: fixup `text_len` after construction, because we can't iterate
6085
// `children` twice.
61-
Arc::get_mut(&mut data).unwrap().header.text_len = text_len;
86+
let data = {
87+
let mut data = Arc::from_thin(data);
88+
Arc::get_mut(&mut data).unwrap().header.header.text_len = text_len;
89+
Arc::into_thin(data)
90+
};
6291

63-
GreenNode { data: data.into() }
92+
GreenNode { data }
6493
}
6594

6695
/// Kind of this node.
6796
#[inline]
6897
pub fn kind(&self) -> SyntaxKind {
69-
self.data.header.kind
98+
self.data.header.header.kind
7099
}
71100

72101
/// Returns the length of the text covered by this node.
73102
#[inline]
74103
pub fn text_len(&self) -> TextSize {
75-
self.data.header.text_len
104+
self.data.header.header.text_len
76105
}
77106

78107
/// Children of this node.
@@ -81,15 +110,14 @@ impl GreenNode {
81110
Children { inner: self.data.slice.iter() }
82111
}
83112

84-
pub(crate) fn ptr(&self) -> *const u8 {
85-
let r: &SliceWithHeader<_, _> = &*self.data;
86-
r as *const _ as _
113+
pub fn ptr(&self) -> *const c_void {
114+
self.data.heap_ptr()
87115
}
88116
}
89117

90118
#[derive(Debug, Clone)]
91119
pub struct Children<'a> {
92-
inner: slice::Iter<'a, PackedGreenElement>,
120+
inner: slice::Iter<'a, GreenChild>,
93121
}
94122

95123
// NB: forward everything stable that iter::Slice specializes as of Rust 1.39.0
@@ -105,7 +133,7 @@ impl<'a> Iterator for Children<'a> {
105133

106134
#[inline]
107135
fn next(&mut self) -> Option<GreenElementRef<'a>> {
108-
self.inner.next().map(PackedGreenElement::as_ref)
136+
self.inner.next().map(GreenChild::as_ref)
109137
}
110138

111139
#[inline]
@@ -123,7 +151,7 @@ impl<'a> Iterator for Children<'a> {
123151

124152
#[inline]
125153
fn nth(&mut self, n: usize) -> Option<Self::Item> {
126-
self.inner.nth(n).map(PackedGreenElement::as_ref)
154+
self.inner.nth(n).map(GreenChild::as_ref)
127155
}
128156

129157
#[inline]
@@ -150,12 +178,12 @@ impl<'a> Iterator for Children<'a> {
150178
impl<'a> DoubleEndedIterator for Children<'a> {
151179
#[inline]
152180
fn next_back(&mut self) -> Option<Self::Item> {
153-
self.inner.next_back().map(PackedGreenElement::as_ref)
181+
self.inner.next_back().map(GreenChild::as_ref)
154182
}
155183

156184
#[inline]
157185
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
158-
self.inner.nth_back(n).map(PackedGreenElement::as_ref)
186+
self.inner.nth_back(n).map(GreenChild::as_ref)
159187
}
160188

161189
#[inline]

0 commit comments

Comments
 (0)