Skip to content

Commit 9cd612f

Browse files
committed
perf(linter/plugins): recycle comment objects (#20362)
Apply the same optimization as #19978 to comments - hold a pool of `Comment` objects, and re-use those objects rather than creating new objects each time. Same as with `Token`s, `loc` property is a getter which calculates `loc` lazily, and caches it in a private property.
1 parent b9f09fc commit 9cd612f

File tree

14 files changed

+365
-177
lines changed

14 files changed

+365
-177
lines changed

apps/oxlint/src-js/generated/constants.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,28 @@ export const SOURCE_START_OFFSET = 8;
6060
* Byte offset of length of source text, relative to start of `Program`.
6161
*/
6262
export const SOURCE_LEN_OFFSET = 16;
63+
64+
/**
65+
* Byte offset of comments `Vec` pointer, relative to start of `Program`.
66+
*/
67+
export const COMMENTS_OFFSET = 24;
68+
69+
/**
70+
* Byte offset of comments `Vec` length, relative to start of `Program`.
71+
*/
72+
export const COMMENTS_LEN_OFFSET = 32;
73+
74+
/**
75+
* Size of `Comment` struct in bytes.
76+
*/
77+
export const COMMENT_SIZE = 16;
78+
79+
/**
80+
* Byte offset of `kind` field, relative to start of `Comment` struct.
81+
*/
82+
export const COMMENT_KIND_OFFSET = 12;
83+
84+
/**
85+
* Discriminant value for `CommentKind::Line`.
86+
*/
87+
export const COMMENT_LINE_KIND = 0;

apps/oxlint/src-js/generated/deserialize.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
// To edit this generated file you have to edit `tasks/ast_tools/src/generators/raw_transfer.rs`.
33

44
import type { Program } from "./types.d.ts";
5-
import type { Node, Comment } from "../plugins/types.ts";
5+
import type { Node } from "../plugins/types.ts";
66
import type { Location as SourceLocation } from "../plugins/location.ts";
77

88
type BufferWithArrays = Uint8Array & { uint32: Uint32Array; float64: Float64Array };
9-
type GetLoc = (node: Node | Comment) => SourceLocation;
9+
type GetLoc = (node: Node) => SourceLocation;
1010

1111
export declare function deserializeProgramOnly(
1212
buffer: BufferWithArrays,

apps/oxlint/src-js/generated/deserialize.js

Lines changed: 3 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
// To edit this generated file you have to edit `tasks/ast_tools/src/generators/raw_transfer.rs`.
33

44
import { tokens, initTokens } from "../plugins/tokens.js";
5+
import { comments, initComments } from "../plugins/comments.js";
56

67
let uint8,
78
uint32,
89
float64,
910
sourceText,
1011
sourceIsAscii,
1112
sourceStartPos,
12-
astId = 0,
1313
parent = null,
1414
getLoc;
1515

@@ -49,38 +49,18 @@ function deserializeWith(buffer, sourceTextInput, sourceByteLen, getLocInput, de
4949
export function resetBuffer() {
5050
// Clear buffer and source text string to allow them to be garbage collected
5151
uint8 = uint32 = float64 = sourceText = void 0;
52-
astId++;
5352
}
5453

5554
function deserializeProgram(pos) {
56-
let localAstId = astId,
57-
end = deserializeU32(pos + 4),
55+
let end = deserializeU32(pos + 4),
5856
program = (parent = {
5957
__proto__: NodeProto,
6058
type: "Program",
6159
body: null,
6260
sourceType: deserializeModuleKind(pos + 137),
6361
hashbang: null,
6462
get comments() {
65-
// Check AST in buffer is still the same AST (buffers are reused)
66-
if (localAstId !== astId)
67-
throw Error("Comments are only accessible while linting the file");
68-
// Deserialize the comments.
69-
// Replace this getter with the comments array, so we don't deserialize twice.
70-
let comments = deserializeVecComment(pos + 24),
71-
{ hashbang } = this;
72-
if (hashbang !== null) {
73-
let start, end;
74-
comments.unshift({
75-
__proto__: NodeProto,
76-
type: "Shebang",
77-
value: hashbang.value,
78-
start: (start = hashbang.start),
79-
end: (end = hashbang.end),
80-
range: [start, end],
81-
});
82-
}
83-
Object.defineProperty(this, "comments", { value: comments });
63+
comments === null && initComments();
8464
return comments;
8565
},
8666
get tokens() {
@@ -5744,33 +5724,6 @@ function deserializeJSDocUnknownType(pos) {
57445724
};
57455725
}
57465726

5747-
function deserializeCommentKind(pos) {
5748-
switch (uint8[pos]) {
5749-
case 0:
5750-
return "Line";
5751-
case 1:
5752-
return "Block";
5753-
case 2:
5754-
return "Block";
5755-
default:
5756-
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
5757-
}
5758-
}
5759-
5760-
function deserializeComment(pos) {
5761-
let type = deserializeCommentKind(pos + 12),
5762-
start = deserializeU32(pos),
5763-
end = deserializeU32(pos + 4);
5764-
return {
5765-
__proto__: NodeProto,
5766-
type,
5767-
value: sourceText.slice(start + 2, end - (type === "Line" ? 0 : 2)),
5768-
start,
5769-
end,
5770-
range: [start, end],
5771-
};
5772-
}
5773-
57745727
function deserializeAssignmentOperator(pos) {
57755728
switch (uint8[pos]) {
57765729
case 0:
@@ -5951,18 +5904,6 @@ function deserializeStr(pos) {
59515904
return out;
59525905
}
59535906

5954-
function deserializeVecComment(pos) {
5955-
let arr = [],
5956-
pos32 = pos >> 2;
5957-
pos = uint32[pos32];
5958-
let endPos = pos + uint32[pos32 + 2] * 16;
5959-
for (; pos !== endPos; ) {
5960-
arr.push(deserializeComment(pos));
5961-
pos += 16;
5962-
}
5963-
return arr;
5964-
}
5965-
59665907
function deserializeOptionHashbang(pos) {
59675908
if (uint32[(pos + 8) >> 2] === 0 && uint32[(pos + 12) >> 2] === 0) return null;
59685909
return deserializeHashbang(pos);

apps/oxlint/src-js/generated/types.d.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// Auto-generated code, DO NOT EDIT DIRECTLY!
22
// To edit this generated file you have to edit `tasks/ast_tools/src/generators/typescript.rs`.
33

4-
import { Span } from "../plugins/location.ts";
5-
import { Token } from "../plugins/tokens.ts";
6-
import { Comment } from "../plugins/types.ts";
7-
export { Span, Comment, Token };
4+
import type { Comment } from "../plugins/comments.ts";
5+
import type { Span } from "../plugins/location.ts";
6+
import type { Token } from "../plugins/tokens.ts";
7+
8+
export type { Comment, Span, Token };
89

910
export interface Program extends Span {
1011
type: "Program";

apps/oxlint/src-js/plugins.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export { eslintCompatPlugin } from "./package/compat.ts";
66
export type * as ESTree from "./generated/types";
77

88
// Plugin types
9+
export type { Comment } from "./plugins/comments.ts";
910
export type { Context, LanguageOptions } from "./plugins/context.ts";
1011
export type { Fix, Fixer, FixFn } from "./plugins/fix.ts";
1112
export type { Globals, Envs } from "./plugins/globals.ts";
@@ -52,11 +53,4 @@ export type {
5253
RuleReplacedByExternalSpecifier,
5354
} from "./plugins/rule_meta.ts";
5455
export type { LineColumn, Location, Range, Ranged, Span } from "./plugins/location.ts";
55-
export type {
56-
AfterHook,
57-
BeforeHook,
58-
Comment,
59-
Node,
60-
Visitor,
61-
VisitorWithHooks,
62-
} from "./plugins/types.ts";
56+
export type { AfterHook, BeforeHook, Node, Visitor, VisitorWithHooks } from "./plugins/types.ts";

0 commit comments

Comments
 (0)