Skip to content

Replace hashbrown raw api by HashTable - #197

Open
antonylsg wants to merge 44 commits into
rust-analyzer:masterfrom
antonylsg:hash_table
Open

Replace hashbrown raw api by HashTable#197
antonylsg wants to merge 44 commits into
rust-analyzer:masterfrom
antonylsg:hash_table

Conversation

@antonylsg

Copy link
Copy Markdown

Replace hashbrown raw entry api by HashTable as it may be removed.

mattfbacon and others added 30 commits January 20, 2024 22:25
Both of these use source code locations to identify the node, which can
get invalidated by syntax tree mutations. This commit adds assertions to
prevent their use, and adds documentation to inform users of the issue

Fixes rust-analyzer#150
`std::mem::offset` has been availible on stable since 1.77.0.
`memoffset` uses this when compiled against a recent enough rustc.

Moving to the implementation in `std` lets us drop both `memoffset` and `autocfg` from our dependencies.
Also, rephrase slightly.
Fix typo in docstring: two => to
This allows users of the API to apply a filter on the SyntaxKind
before materializing concrete SyntaxNode/Token objects, which require
a memory allocation for the NodeData.

For slint, this removes ~400k allocations when parsing a largish
project, about 50% of all rowan allocations (850k down to 450k).
When possible, reuse the allocated NodeData instead of allocating a
new one for each iteration. This can be done as long as the refcount
is 1 - we can then just rewire the values in NodeData to point to the
new item.

This removes ~220k allocations when compiling a largish slint file,
about half of all rowan allocations that happen during iteration,
i.e. we go from 450k down to 230k.
This makes this API actually useful from the outside - there is no
lifetime problem with the matcher callback, and we can remap the
raw Kind to the Language::Kind on the fly.
…teration

Optimize children iteration by reusing NodeData if possible
Fixes an assertion in debug builds which I accidentally
introduced when attending the review comments for [1]
in [2] - instead of only removing the increment, I also
removed the decrement which was wrong - `std::mem::forget`
only allows us to remove the increment, but the decrement
is still needed before free since we are in a place of
code that is by definition only run when the rc value is set to 1.
See also `can_take_ptr`.

I did not spot this earlier since I ran the integration test
on a release build, where the assertion was disabled. It's sad
that the rowan repo itself doesn't have any big test coverage
in this repo itself, but rather relies on external repos for
testing purposes...

[1]: rust-analyzer#171 (comment)
[2]: https://github.com/rust-analyzer/rowan/compare/60a632ad984ab451e32058169193511154c675a9..ab5463e2749330be6846886c21e98c83caca8598

Fixes: rust-analyzer#172
Decrement refcount before calling free in to_next_sibling
…sing-an-iterable-to-splice-children

Allow passing an iterable to `splice_children`
The patch f06a2c9 changed the
code to use skip instead of nth, which lead to an off-by-one
bug that was uncovered by unit tests in ludtwig, see [1].

[1]: MalteJanz/ludtwig#122

Fixes: rust-analyzer#175
* doc: change link in README
* doc: update link in tutorial
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.