Description
Describe the Bug
There is a race condition and a related performance issue in the following section of the wasm-bindgen codebase:
wasm-bindgen/crates/backend/src/util.rs
Lines 135 to 161 in c35cc93
- Race Condition:
The affected code attempts to lazily compute and cache a hash value, but the current implementation is not thread-safe. Consider the following interleaving of two threads:
Thread 1 | Thread 2 |
---|---|
check Hashed | check Hashed |
recompute Hash | recompute Hash |
If two threads call the fmt function concurrently, they may both observe the Hashed flag as false and proceed to recompute the hash independently. This violates the intent of computing the hash only once and leads to redundant work. While the result is ultimately consistent (assuming a stable environment), this introduces unnecessary overhead.
- Memory Ordering Issue
The code currently uses Ordering::SeqCst, which is overly strict for this scenario. A combination of Ordering::Acquire and Ordering::Release is sufficient to ensure correct synchronization while allowing better performance on most architectures. But for now OnceLock is the most concise implementation.
Steps to Reproduce
Found from static analysis
Expected Behavior
No race condition. Performance increase.
Actual Behavior
In a benchmark on x86 Linux, replacing SeqCst atomics with OnceLock not only eliminated potential race conditions by ensuring the hash is computed only once, but also yielded a slight performance improvement.
Additional Context
I will submit a PR with a fix