oxc-project / oxc-project/backlog

Reduce bounds checks on `Semantic`'s `Vec`s

Open
#67 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
7
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Copied from https://github.com/oxc-project/oxc/issues/3318#issuecomment-2116453002:

As far as I'm aware, the Vecs which ReferenceId, SymbolId and ScopeId index into can only grow, never contract.

We could capitalize on this invariant to remove bounds checks. Something like:

pub struct ReferenceVec(Vec<Whatever>);
pub struct ReferenceId(u32);

impl ReferenceId {
  const EMPTY: Self = ReferenceId(0);
}

impl ReferenceVec {
  pub fn new() -> Self {
    // Initialize vec with a dummy at index 0
    let mut inner = Vec::new();
    inner.push(Whatever::default());
    Self(inner)
  }

  pub fn push(&mut self, value: Whatever) -> ReferenceId {
    let index = ReferenceId(self.0.len());
    self.0.push(value);
    index
  }

  // Returns `&Whatever` not `Option<&Whatever>`
  // because `ReferenceId` is always a valid index
  pub fn get(&self, index: ReferenceId) -> &Whatever {
    // `index` must be in bounds, so skip bounds check
    unsafe { self.0.get(index.0).unwrap_unchecked() }
  }

  // NB: No `pop` method
}

i.e. The only way to get a ReferenceId is via push(), and because ReferenceVec never shrinks, once you have a ReferenceId, it always remains valid. So no need for bounds check on get().

Actual implementation would need to be more complex than the above. Would need some mechanism to prevent you using a ReferenceId from one ReferenceVec on another ReferenceVec. But hopefully the above gives the general idea.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating Semantic's ReferenceId, SymbolId, and ScopeId types and the Vecs they index into. Read how those collections are created, accessed, and mutated, then verify whether they only grow and cannot be mixed across collections. Done means bounds checks are safely removed while preserving valid indexing and preventing cross-collection ID use.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
performance
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.