Skip to content

Commit 894e97f

Browse files
stepanchegfacebook-github-bot
authored andcommitted
test frame native stack size
Summary: Currently starlark frame allocates about 1K of native stack size (unless native frame has for loops, in which case it allocates more). Test it explicitly to prevent regressions. Reviewed By: bobyangyf Differential Revision: D38712859 fbshipit-source-id: 7ef691e8dae6bc393a0387ba8198382fb7ca2c6e
1 parent 7e66902 commit 894e97f

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

starlark/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@
349349
#![allow(stable_features)]
350350
#![feature(alloc_layout_extra)]
351351
#![feature(backtrace)]
352+
#![feature(bench_black_box)]
352353
#![feature(box_patterns)]
353354
#![feature(box_syntax)]
354355
#![feature(cell_filter_map)]

starlark/src/tests/call.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@
1717

1818
//! Test call expression and parameter binding.
1919
20+
use std::hint;
21+
22+
use crate as starlark;
2023
use crate::assert;
2124
use crate::assert::Assert;
25+
use crate::environment::GlobalsBuilder;
26+
use crate::values::UnpackValue;
27+
use crate::values::Value;
2228

2329
#[test]
2430
fn funcall_test() {
@@ -243,3 +249,50 @@ f(1)
243249
"Missing parameter `y`",
244250
);
245251
}
252+
253+
#[test]
254+
fn test_frame_size() {
255+
#[starlark_module]
256+
fn natives(builder: &mut GlobalsBuilder) {
257+
fn stack_ptr(args: Vec<Value>) -> anyhow::Result<usize> {
258+
drop(args);
259+
260+
// Taking a pointer of a stack variable is UB or something, I don't know.
261+
// So pass it through `black_box` to skip compiler optimizations.
262+
let x = 1;
263+
let ptr = hint::black_box(&x);
264+
Ok(ptr as *const i32 as usize)
265+
}
266+
}
267+
268+
let program = r#"
269+
def f(x):
270+
return stack_ptr(x)
271+
272+
def g(x):
273+
noop(x)
274+
return f(x)
275+
276+
F_PTR = f([])
277+
G_F_PTR = g([])
278+
"#;
279+
280+
let mut a = Assert::new();
281+
a.globals_add(natives);
282+
let module = a.pass_module(program);
283+
let one = usize::unpack_value(module.get("F_PTR").unwrap().value()).unwrap();
284+
let two = usize::unpack_value(module.get("G_F_PTR").unwrap().value()).unwrap();
285+
assert!(
286+
two < one,
287+
"stack grows down everywhere we support starlark-rust"
288+
);
289+
// At the moment of writing it is about 1K.
290+
// Note, actual frame size may be larger a frame contains for loops.
291+
let frame_native_size = one - two;
292+
assert!(frame_native_size > 20, "sanity check");
293+
assert!(
294+
frame_native_size < 2024,
295+
"native frame size is too large: {}, evaluation may result in native stack overflow",
296+
frame_native_size,
297+
);
298+
}

0 commit comments

Comments
 (0)