Skip to content

Commit b14af5e

Browse files
authored
Avoid stack overflow in PyStringCache (#239)
1 parent 1764e65 commit b14af5e

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

crates/jiter/src/py_string_cache.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,8 @@ unsafe fn cached_py_string_maybe_ascii<'py>(py: Python<'py>, s: &str, ascii_only
139139
}
140140
}
141141

142-
// capacity should be a power of 2 so the compiler can convert `%` to a right shift below
142+
// Capacity should be a power of 2 so the compiler can convert `%` to a right shift below
143143
// Using a smaller number here (e.g. 1024) seems to be faster in many cases than a larger number (like 65536)
144-
// and also avoids stack overflow risks
145144
const CAPACITY: usize = 16_384;
146145
type Entry = Option<(u64, Py<PyString>)>;
147146

@@ -158,8 +157,16 @@ const ARRAY_REPEAT_VALUE: Entry = None;
158157
impl Default for PyStringCache {
159158
fn default() -> Self {
160159
Self {
161-
#[allow(clippy::large_stack_arrays)]
162-
entries: Box::new([ARRAY_REPEAT_VALUE; CAPACITY]),
160+
// Make sure we don't allocate a large array on the stack (e.g. using `Box::new([ARRAY_REPEAT_VALUE; CAPACITY])`)
161+
// to avoid potential stack overflows.
162+
// Note: we might want to use `Box::<[Entry; CAPACITY]>::new_zeroed()` if we ever bump the MSRV above 1.92,
163+
// given that `Entry` can be used as a niche optimization.
164+
entries: std::iter::repeat_with(|| ARRAY_REPEAT_VALUE)
165+
.take(CAPACITY)
166+
.collect::<Vec<_>>()
167+
.into_boxed_slice()
168+
.try_into()
169+
.unwrap(),
163170
hash_builder: RandomState::default(),
164171
}
165172
}

0 commit comments

Comments
 (0)