Skip to content

Commit 55ee14a

Browse files
committed
fixup! Give up if ensure_sufficient_stack is called more than 1000 times
1 parent c1fa3f2 commit 55ee14a

1 file changed

Lines changed: 12 additions & 7 deletions

File tree

  • compiler/rustc_data_structures/src

compiler/rustc_data_structures/src/stack.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@ const STACK_PER_RECURSION: usize = 1024 * 1024; // 1MB
1818
const STACK_PER_RECURSION: usize = 16 * 1024 * 1024; // 16MB
1919

2020
thread_local! {
21-
static TIMES_GROWN: Cell<u16> = const { Cell::new(0) };
21+
static TIMES_GROWN: Cell<u32> = const { Cell::new(0) };
2222
}
2323

24-
// Give up if we expand the stack this many times and are still trying to recurse deeper.
25-
const MAX_STACK_GROWTH: u16 = 1000;
24+
/// Give up if we expand the stack this many times and are still trying to recurse deeper.
25+
const MAX_STACK_GROWTH: u32 = 1000;
26+
/// Estimate number of frames used per call to `grow`.
27+
///
28+
/// This is only used on platforms where we can't tell how much stack we have left, so we `grow`
29+
/// unconditionally.
30+
const ESTIMATED_FRAME_SIZE: u32 = 10000;
2631

2732
/// Grows the stack on demand to prevent stack overflow. Call this in strategic locations
2833
/// to "break up" recursive calls. E.g. almost any call to `visit_expr` or equivalent can benefit
@@ -32,15 +37,15 @@ const MAX_STACK_GROWTH: u16 = 1000;
3237
pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
3338
// if we can't guess the remaining stack (unsupported on some platforms) we immediately grow
3439
// the stack and then cache the new stack size (which we do know now because we allocated it.
35-
let enough_space = match stacker::remaining_stack() {
36-
Some(remaining) => remaining >= RED_ZONE,
37-
None => false,
40+
let (enough_space, max_stack) = match stacker::remaining_stack() {
41+
Some(remaining) => (remaining >= RED_ZONE, MAX_STACK_GROWTH),
42+
None => (false, MAX_STACK_GROWTH * ESTIMATED_FRAME_SIZE),
3843
};
3944
if likely(enough_space) {
4045
f()
4146
} else {
4247
let times = TIMES_GROWN.get();
43-
if unlikely(times > MAX_STACK_GROWTH) {
48+
if unlikely(times > max_stack) {
4449
too_much_stack();
4550
}
4651
TIMES_GROWN.set(times + 1);

0 commit comments

Comments
 (0)