Skip to content

Commit 7469e01

Browse files
committed
perf(semantic): remove branch from Nodes::add_node (#4361)
`AstNodes::add_node` had a branch specifically to handle `Program`. Remove that by inlining the special logic for `Program` into `visit_program`. Probably won't have much effect on benchmarks as the branch is easy to predict, but still removes a few instructions and makes `add_node` easier for compiler to inline.
1 parent 729b288 commit 7469e01

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

crates/oxc_semantic/src/builder.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,19 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
529529
});
530530
/* cfg - must be above directives as directives are in cfg */
531531

532-
self.enter_node(kind);
532+
// Don't call `enter_node` here as `Program` is a special case - node has no `parent_id`.
533+
// Inline the specific logic for `Program` here instead.
534+
// This avoids `Nodes::add_node` having to handle the special case.
535+
// We can also skip calling `self.enter_kind`, and `self.jsdoc.retrieve_attached_jsdoc`
536+
// as they are no-ops for `Program`.
537+
self.current_node_id = self.nodes.add_program_node(
538+
kind,
539+
self.current_scope_id,
540+
control_flow!(self, |cfg| cfg.current_node_ix),
541+
self.current_node_flags,
542+
);
543+
self.record_ast_node();
544+
533545
self.enter_scope(
534546
{
535547
let mut flags = ScopeFlags::Top;

crates/oxc_semantic/src/node.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ impl<'a> AstNodes<'a> {
142142
}
143143

144144
/// Create and add an `AstNode` to the `AstNodes` tree and returns its `AstNodeId`.
145+
/// Node must not be `Program`. Use `add_program_node` instead.
145146
pub fn add_node(
146147
&mut self,
147148
kind: AstKind<'a>,
@@ -150,14 +151,22 @@ impl<'a> AstNodes<'a> {
150151
cfg_id: BasicBlockId,
151152
flags: NodeFlags,
152153
) -> AstNodeId {
153-
let ast_node_id = match kind {
154-
AstKind::Program(_) => {
155-
let id = self.parent_ids.push(None);
156-
self.root = Some(id);
157-
id
158-
}
159-
_ => self.parent_ids.push(Some(parent_node_id)),
160-
};
154+
let ast_node_id = self.parent_ids.push(Some(parent_node_id));
155+
let node = AstNode::new(kind, scope_id, cfg_id, flags, ast_node_id);
156+
self.nodes.push(node);
157+
ast_node_id
158+
}
159+
160+
/// Create and add an `AstNode` to the `AstNodes` tree and returns its `AstNodeId`.
161+
pub fn add_program_node(
162+
&mut self,
163+
kind: AstKind<'a>,
164+
scope_id: ScopeId,
165+
cfg_id: BasicBlockId,
166+
flags: NodeFlags,
167+
) -> AstNodeId {
168+
let ast_node_id = self.parent_ids.push(None);
169+
self.root = Some(ast_node_id);
161170
let node = AstNode::new(kind, scope_id, cfg_id, flags, ast_node_id);
162171
self.nodes.push(node);
163172
ast_node_id

0 commit comments

Comments
 (0)