Skip to content
Merged
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
18 changes: 15 additions & 3 deletions apps/oxlint/src-js/plugins/comments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ export const cachedComments: Comment[] = [];
let previousComments: Comment[] = [];

// Comments whose `loc` property has been accessed, and therefore needs clearing on reset.
// Never shrunk - `activeCommentsWithLocCount` tracks the active count to avoid freeing the backing store.
const commentsWithLoc: Comment[] = [];
let activeCommentsWithLocCount = 0;

// Tracks indices of deserialized comments so their `value` can be cleared on reset,
// preventing source text strings from being held alive by stale `value` slices.
Expand Down Expand Up @@ -111,7 +113,17 @@ class Comment implements Span {
const loc = this.#loc;
if (loc !== null) return loc;

commentsWithLoc.push(this);
// Store comment in `commentsWithLoc` array. `resetComments` will clear the `#loc` property.
// Note: The comparison `activeCommentsWithLocCount < commentsWithLoc.length` must be this way around
// so that V8 can remove the bounds check on `commentsWithLoc[activeCommentsWithLocCount]`.
// `commentsWithLoc.length > activeCommentsWithLocCount` would *not* remove the bounds check in Maglev compiler.
if (activeCommentsWithLocCount < commentsWithLoc.length) {
commentsWithLoc[activeCommentsWithLocCount] = this;
} else {
commentsWithLoc.push(this);
}
activeCommentsWithLocCount++;

return (this.#loc = computeLoc(this.start, this.end));
}

Expand Down Expand Up @@ -411,11 +423,11 @@ export function resetComments(): void {
}

// Reset `#loc` on comments where `loc` has been accessed
for (let i = 0, len = commentsWithLoc.length; i < len; i++) {
for (let i = 0; i < activeCommentsWithLocCount; i++) {
resetCommentLoc(commentsWithLoc[i]);
}

commentsWithLoc.length = 0;
activeCommentsWithLocCount = 0;

// Reset other state
comments = null;
Expand Down
20 changes: 16 additions & 4 deletions apps/oxlint/src-js/plugins/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,10 @@ export const cachedTokens: Token[] = [];
// Reused for next file if next file has less tokens than the previous file (by truncating it to correct length).
let previousTokens: Token[] = [];

// Tokens whose `loc` property has been accessed, and therefore needs clearing on reset
// Tokens whose `loc` property has been accessed, and therefore needs clearing on reset.
// Never shrunk - `activeTokensWithLocCount` tracks the active count to avoid freeing the backing store.
const tokensWithLoc: Token[] = [];
let activeTokensWithLocCount = 0;

// Cached regex descriptor objects, reused across files
const regexObjects: Regex[] = [];
Expand Down Expand Up @@ -182,7 +184,17 @@ class Token {
const loc = this.#loc;
if (loc !== null) return loc;

tokensWithLoc.push(this);
// Store token in `tokensWithLoc` array. `resetTokens` will clear the `#loc` property.
// Note: The comparison `activeTokensWithLocCount < tokensWithLoc.length` must be this way around
// so that V8 can remove the bounds check on `tokensWithLoc[activeTokensWithLocCount]`.
// `tokensWithLoc.length > activeTokensWithLocCount` would *not* remove the bounds check in Maglev compiler.
if (activeTokensWithLocCount < tokensWithLoc.length) {
tokensWithLoc[activeTokensWithLocCount] = this;
} else {
tokensWithLoc.push(this);
}
activeTokensWithLocCount++;

return (this.#loc = computeLoc(this.start, this.end));
}

Expand Down Expand Up @@ -541,11 +553,11 @@ export function resetTokens() {
}

// Reset `#loc` on tokens where `loc` has been accessed
for (let i = 0, len = tokensWithLoc.length; i < len; i++) {
for (let i = 0; i < activeTokensWithLocCount; i++) {
resetLoc(tokensWithLoc[i]);
}

tokensWithLoc.length = 0;
activeTokensWithLocCount = 0;

// Reset `regex` property on regex tokens.
// This avoids having to set it for every non-regex token in `deserializeTokenIfNeeded`.
Expand Down
Loading