The hygiene transform has a memory leak where some hstr::Entrys are never freed. A reproducer can be found here: https://github.com/nathanwhit/swc-memory-leak-repro. It just parses a simple program and then runs the hygiene transform over it. Running with miri (as suggested in the readme of the repro) points out a memory leak.
Input code
No response
Config
No response
Playground link (or link to the minimal reproduction)
I took a bit of a look at this, and I think the issue may stem from this set of FastIds. From what I can tell, the JsWords in that set are not guaranteed to be dropped (they're wrapped in ManuallyDrop), and so the reference counts of the underlying Atoms never hit 0.
I would expect that all FastJsWords that are added to the set would eventually be converted back to JsWords at the end of the transform so that their reference counts are decreased properly. (In other words, I think each FastJsWord::new should be paired with a FastJsWord::into_inner call so the JsWord gets dropped).
I've tested a local patch that calls into_inner on each FastJsWord in that set when the ScopeData is dropped, and confirmed that resolves the memory leak.
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.
Describe the bug
The hygiene transform has a memory leak where some
hstr::Entry
s are never freed. A reproducer can be found here: https://github.com/nathanwhit/swc-memory-leak-repro. It just parses a simple program and then runs the hygiene transform over it. Running with miri (as suggested in the readme of the repro) points out a memory leak.Input code
No response
Config
No response
Playground link (or link to the minimal reproduction)
https://github.com/nathanwhit/swc-memory-leak-repro
SWC Info output
No response
Expected behavior
The transform runs and frees all memory allocated once it is complete.
Actual behavior
No response
Version
swc_ecma_transforms_base = "0.140.1"
Additional context
Running the linked reproducer with miri points out the memory leak:
``` error: memory leaked: alloc6124 (Rust heap, size: 48, align: 8), allocated here: --> /home/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/alloc.rs:100:9 | 100 | __rust_alloc(layout.size(), layout.align()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: BACKTRACE: = note: inside `std::alloc::alloc` at /home/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/alloc.rs:243:9: 243:39 = note: inside `alloc::alloc::exchange_malloc` at /home/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/alloc.rs:332:11: 332:34 = note: inside `std::boxed::Box::(for some extra context, this was minimized from https://github.com/denoland/deno/issues/24380)
I took a bit of a look at this, and I think the issue may stem from this set of
FastId
s. From what I can tell, theJsWord
s in that set are not guaranteed to be dropped (they're wrapped inManuallyDrop
), and so the reference counts of the underlyingAtom
s never hit 0.I would expect that all
FastJsWord
s that are added to the set would eventually be converted back toJsWord
s at the end of the transform so that their reference counts are decreased properly. (In other words, I think eachFastJsWord::new
should be paired with aFastJsWord::into_inner
call so theJsWord
gets dropped).I've tested a local patch that calls
into_inner
on eachFastJsWord
in that set when theScopeData
is dropped, and confirmed that resolves the memory leak.