oxc-project / oxc-project/backlog
`ThinVec` type
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 7
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
The problem
There are various parts of AST where we have a Vec which is usually empty. e.g.:
Function::directivesClass::decoratorsFormalParameter::decorators
To save space, we currently use Box<Vec<T>> for these fields. This is better than plain Vec, as it's 8 bytes instead of 32.
But downsides are:
- Checking if
Vecis empty or not involves a "far off" memory read (followBox's pointer). - When the
Vecdoes have content, reading/writing an element involves double-indirection (followBox's pointer, thenVec's pointer).
ThinVec
We could do a bit better with a ThinVec-like type.
ThinVec stores its length and capacity in same allocation as the vec's data. So ThinVec itself is pointer-sized (8 bytes).
I could not find an existing ThinVec-like crate which accepts a custom allocator, so we'd have to build our own.
Designing for our use case
Because we'll be using it with arena allocator, we don't have to worry about Drop, so we could make a tweak to the design to allow very cheap ThinVec::is_empty:
- When the
ThinVecis empty (len == 0), store a sentinel value in place of the pointer. - Sentinel value could be
0. - If we want
Option<ThinVec>to also be pointer-sized, we could use aNonNullpointer with sentinel value of1. As long as alignment ofTinThinVec<T>is greater than 1 (all our AST types have alignment of at least 4), then1can never be a valid pointer. - When a
ThinVechas elements and has its last element removed, its pointer is replaced with the sentinel. This means its allocation is discarded, and if you push to theThinVecagain, it'll have to make a fresh allocation. But I think this is a rare case, so not much of a problem in practice. - The other trade-off is that
ThinVec::leninvolves a branch to first check for the sentinel (rather than originalThinVecwhere this is straight-line code). But as we expect almost allThinVecs to be empty, this branch should be very predictable.
Optimization for single-entry ThinVecs
We could also have an optimization for ThinVecs with a single entry, where ThinVec would set lowest bit of pointer to 1 and the pointer points to the single entry (essentially it's a Box). This does impose cost of checking that bit and an AND instruction to get rid of it, on every read/write, so may not be worthwhile. But might be useful for Vecs which commonly contain only a single entry.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the AST fields named in the issue—Function::directives, Class::decorators, and FormalParameter::decorators—and compare their current Box<Vec> representation with the linked thin-vec design. Define the custom-allocator requirements and evaluate the empty sentinel, removal behavior, Option, and single-entry optimization; the issue names no implementation files or tests, so completion criteria need to be established first.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100