diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index a8f39cf91da..e6e89c62cc0 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -209,14 +209,22 @@ upcall_dynastack_free(void *ptr) { return rust_scheduler::get_task()->dynastack.free(ptr); } +extern "C" void record_sp(void *limit); + /** - * Allocates |nbytes| bytes in the C stack and returns a pointer to the start - * of the allocated space. + * Switch to the C stack and call the given function, passing a single pointer + * argument. */ extern "C" CDECL void upcall_call_shim_on_c_stack(void *args, void *fn_ptr) { - rust_scheduler *sched = rust_scheduler::get_task()->sched; + // FIXME (1226) - The shim functions generated by rustc contain the + // morestack prologue, so we need to let them know they have enough + // stack. + record_sp(0); + rust_task *task = rust_scheduler::get_task(); + rust_scheduler *sched = task->sched; sched->c_context.call_shim_on_c_stack(args, fn_ptr); + task->record_stack_limit(); } struct rust_new_stack2_args { diff --git a/src/test/run-pass/morestack4.rs b/src/test/run-pass/morestack4.rs new file mode 100644 index 00000000000..cdba6dd766e --- /dev/null +++ b/src/test/run-pass/morestack4.rs @@ -0,0 +1,100 @@ +// xfail-test +// compile-flags:--stack-growth + +// This is testing for stack frames greater than 256 bytes, +// for which function prologues are generated differently + +type biggy = { + a00: u64, + a01: u64, + a02: u64, + a03: u64, + a04: u64, + a05: u64, + a06: u64, + a07: u64, + a08: u64, + a09: u64, + a10: u64, + a11: u64, + a12: u64, + a13: u64, + a14: u64, + a15: u64, + a16: u64, + a17: u64, + a18: u64, + a19: u64, + a20: u64, + a21: u64, + a22: u64, + a23: u64, + a24: u64, + a25: u64, + a26: u64, + a27: u64, + a28: u64, + a29: u64, + a30: u64, + a31: u64, + a32: u64, + a33: u64, + a34: u64, + a35: u64, + a36: u64, + a37: u64, + a38: u64, + a39: u64, +}; + + +fn getbig(i: biggy) { + if i.a00 != 0u64 { + getbig({a00: i.a00 - 1u64 with i}); + } +} + +fn main() { + getbig({ + a00: 100000u64, + a01: 100000u64, + a02: 100000u64, + a03: 100000u64, + a04: 100000u64, + a05: 100000u64, + a06: 100000u64, + a07: 100000u64, + a08: 100000u64, + a09: 100000u64, + a10: 100000u64, + a11: 100000u64, + a12: 100000u64, + a13: 100000u64, + a14: 100000u64, + a15: 100000u64, + a16: 100000u64, + a17: 100000u64, + a18: 100000u64, + a19: 100000u64, + a20: 100000u64, + a21: 100000u64, + a22: 100000u64, + a23: 100000u64, + a24: 100000u64, + a25: 100000u64, + a26: 100000u64, + a27: 100000u64, + a28: 100000u64, + a29: 100000u64, + a30: 100000u64, + a31: 100000u64, + a32: 100000u64, + a33: 100000u64, + a34: 100000u64, + a35: 100000u64, + a36: 100000u64, + a37: 100000u64, + a38: 100000u64, + a39: 100000u64, + }); +} \ No newline at end of file diff --git a/src/test/run-pass/morestack5.rs b/src/test/run-pass/morestack5.rs new file mode 100644 index 00000000000..bedf3f47ee9 --- /dev/null +++ b/src/test/run-pass/morestack5.rs @@ -0,0 +1,26 @@ +// xfail-test +// compile-flags:--stack-growth + +// This test will call __morestack with various minimum stack sizes + +use std; +import std::task; + +native mod rustrt { + fn set_min_stack(size: uint); +} + +fn getbig(&&i: int) { + if i != 0 { + getbig(i - 1); + } +} + +fn main() { + let sz = 400u; + while sz < 500u { + rustrt::set_min_stack(sz); + task::join(task::spawn_joinable(200, getbig)); + sz += 1u; + } +} \ No newline at end of file