rope: Prevent stack overflows by bumping rayon stack sizes (#41397)

Lukas Wirth created

Thread stacks in rust by default have 2 megabytes of stack which for
sumtrees (or ropes in this case) can easily be exceeded depending on the
workload.

Release Notes:

- Fixed stack overflows when constructing large ropes

Change summary

crates/cli/src/main.rs           | 1 +
crates/remote_server/src/unix.rs | 1 +
crates/rope/src/rope.rs          | 8 ++++----
3 files changed, 6 insertions(+), 4 deletions(-)

Detailed changes

crates/cli/src/main.rs 🔗

@@ -358,6 +358,7 @@ fn main() -> Result<()> {
 
     rayon::ThreadPoolBuilder::new()
         .num_threads(4)
+        .stack_size(10 * 1024 * 1024)
         .thread_name(|ix| format!("RayonWorker{}", ix))
         .build_global()
         .unwrap();

crates/remote_server/src/unix.rs 🔗

@@ -372,6 +372,7 @@ pub fn execute_run(
 
     rayon::ThreadPoolBuilder::new()
         .num_threads(4)
+        .stack_size(10 * 1024 * 1024)
         .thread_name(|ix| format!("RayonWorker{}", ix))
         .build_global()
         .unwrap();

crates/rope/src/rope.rs 🔗

@@ -191,9 +191,9 @@ impl Rope {
             (),
         );
 
-        #[cfg(not(test))]
+        #[cfg(all(test, not(rust_analyzer)))]
         const NUM_CHUNKS: usize = 16;
-        #[cfg(test)]
+        #[cfg(not(all(test, not(rust_analyzer))))]
         const NUM_CHUNKS: usize = 4;
 
         // We accommodate for NUM_CHUNKS chunks of size MAX_BASE
@@ -248,9 +248,9 @@ impl Rope {
             text = remainder;
         }
 
-        #[cfg(test)]
+        #[cfg(all(test, not(rust_analyzer)))]
         const PARALLEL_THRESHOLD: usize = 4;
-        #[cfg(not(test))]
+        #[cfg(not(all(test, not(rust_analyzer))))]
         const PARALLEL_THRESHOLD: usize = 4 * (2 * sum_tree::TREE_BASE);
 
         if new_chunks.len() >= PARALLEL_THRESHOLD {