mirror of
https://github.com/aphrody-labs/oxc.git
synced 2026-10-15 06:39:17 +00:00
perf(mangler): share allocated names across reused slots (#25605)
Avoid duplicate semantic-arena allocations when multiple symbols share one mangler slot. Previously, Phase 5 renamed every symbol in a shared slot individually. Each call to `Scoping::set_symbol_name` cloned the same generated `Ident` into the semantic arena, so a slot shared by `N` symbols made `N` allocations and copied the name `N` times. This adds `Scoping::set_symbol_names`, which clones the generated name once into the semantic arena and copies the immutable `Ident` handle to every symbol in that slot. The name must still be cloned once: generated names are backed by the mangler’s temporary allocator, which may be reset after mangling. Sharing that temporary backing would be unsound. ## Before / after For a slot containing `N` symbols and a mangled name of length `L`: | | Arena allocations | Copied bytes | |---|---:|---:| | Before | `N` | `N × L` | | After | `1` | `L` | | Benchmark | Old: one per symbol | New: one per slot | Saved | |---|---:|---:|---:| | `RadixUIAdoptionSection.jsx` | 12 | 12 | 0 | | `react.development.js` | 470 | 143 | 327 | | `App.tsx` | 1,791 | 426 | 1,365 | | `binder.ts` | 930 | 374 | 556 | | `kitchen-sink.tsx` | 5,422 | 1,058 | 4,364 | | `RadixUIAdoptionSection.jsx_keep_names` | 12 | 12 | 0 |
This commit is contained in:
1 parent
50201a465e
commit
757f3d4113
2 files changed
+18
-3
No files matched your search
@@ -853,9 +853,8 @@ impl<'a, const CAPACITY: usize> NameTable<'a, CAPACITY> {
|
||||
symbols_renamed_in_this_batch.iter().zip(slice_of_same_len_strings.iter())
|
||||
{
|
||||
// A slot can be shared by several symbols (cross-scope reuse); rename them all.
|
||||
for &symbol_id in &symbol_to_rename.symbol_ids {
|
||||
scoping.set_symbol_name(symbol_id, Ident::from(new_name.as_str()));
|
||||
}
|
||||
scoping
|
||||
.set_symbol_names(&symbol_to_rename.symbol_ids, Ident::from(new_name.as_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,6 +374,22 @@ impl Scoping {
|
||||
});
|
||||
}
|
||||
|
||||
/// Rename multiple symbols to the same name.
|
||||
///
|
||||
/// The name is allocated once in the semantic arena and shared between all symbols.
|
||||
#[inline]
|
||||
pub fn set_symbol_names(&mut self, symbol_ids: &[SymbolId], name: Ident<'_>) {
|
||||
if symbol_ids.is_empty() {
|
||||
return;
|
||||
}
|
||||
self.cell.with_dependent_mut(|allocator, cell| {
|
||||
let name = name.clone_in(allocator);
|
||||
for &symbol_id in symbol_ids {
|
||||
cell.symbol_names[symbol_id.index()] = name;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Get the [`SymbolFlags`] for a symbol, which describe how the symbol is declared.
|
||||
///
|
||||
/// To find how a symbol is used, use [`Scoping::get_resolved_references`].
|
||||
|
||||
Reference in new issue
Block a user