rt: Create different stack-switching paths for upcalls and shims
Shims need to play with the stack limit, upcalls don't. Only one upcall, upcall_fail is allowed to catch, and we need a find a way to get rid of that catch as well because it results in _Unwind_Resume running off the end of the Rust stack.
This commit is contained in:
parent
f57fd8de1f
commit
c73eb8ff51
1 changed files with 34 additions and 22 deletions
|
|
@ -27,7 +27,15 @@ check_stack_alignment() __attribute__ ((aligned (16)));
|
|||
static void check_stack_alignment() { }
|
||||
#endif
|
||||
|
||||
#define SWITCH_STACK(A, F) upcall_call_shim_on_c_stack((void*)A, (void*)F)
|
||||
#define UPCALL_SWITCH_STACK(A, F) call_upcall_on_c_stack((void*)A, (void*)F)
|
||||
|
||||
inline void
|
||||
call_upcall_on_c_stack(void *args, void *fn_ptr) {
|
||||
check_stack_alignment();
|
||||
rust_task *task = rust_scheduler::get_task();
|
||||
rust_scheduler *sched = task->sched;
|
||||
sched->c_context.call_shim_on_c_stack(args, fn_ptr);
|
||||
}
|
||||
|
||||
extern "C" void record_sp(void *limit);
|
||||
|
||||
|
|
@ -35,7 +43,8 @@ extern "C" void record_sp(void *limit);
|
|||
* Switches to the C-stack and invokes |fn_ptr|, passing |args| as argument.
|
||||
* This is used by the C compiler to call native functions and by other
|
||||
* upcalls to switch to the C stack. The return value is passed through a
|
||||
* field in the args parameter.
|
||||
* field in the args parameter. This upcall is specifically for switching
|
||||
* to the shim functions generated by rustc.
|
||||
*/
|
||||
extern "C" CDECL void
|
||||
upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
|
||||
|
|
@ -51,10 +60,9 @@ upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
|
|||
try {
|
||||
sched->c_context.call_shim_on_c_stack(args, fn_ptr);
|
||||
} catch (...) {
|
||||
task = rust_scheduler::get_task();
|
||||
task->record_stack_limit();
|
||||
throw;
|
||||
A(sched, false, "Native code threw an exception");
|
||||
}
|
||||
|
||||
task = rust_scheduler::get_task();
|
||||
task->record_stack_limit();
|
||||
}
|
||||
|
|
@ -80,8 +88,12 @@ extern "C" CDECL void
|
|||
upcall_fail(char const *expr,
|
||||
char const *file,
|
||||
size_t line) {
|
||||
s_fail_args args = {expr,file,line};
|
||||
SWITCH_STACK(&args, upcall_s_fail);
|
||||
try {
|
||||
s_fail_args args = {expr,file,line};
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_fail);
|
||||
} catch (rust_task*) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
|
@ -124,7 +136,7 @@ upcall_s_malloc(s_malloc_args *args) {
|
|||
extern "C" CDECL uintptr_t
|
||||
upcall_malloc(size_t nbytes, type_desc *td) {
|
||||
s_malloc_args args = {0, nbytes, td};
|
||||
SWITCH_STACK(&args, upcall_s_malloc);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_malloc);
|
||||
return args.retval;
|
||||
}
|
||||
|
||||
|
|
@ -156,7 +168,7 @@ upcall_s_free(s_free_args *args) {
|
|||
extern "C" CDECL void
|
||||
upcall_free(void* ptr, uintptr_t is_gc) {
|
||||
s_free_args args = {ptr, is_gc};
|
||||
SWITCH_STACK(&args, upcall_s_free);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_free);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
|
@ -189,7 +201,7 @@ upcall_s_shared_malloc(s_shared_malloc_args *args) {
|
|||
extern "C" CDECL uintptr_t
|
||||
upcall_shared_malloc(size_t nbytes, type_desc *td) {
|
||||
s_shared_malloc_args args = {0, nbytes, td};
|
||||
SWITCH_STACK(&args, upcall_s_shared_malloc);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_shared_malloc);
|
||||
return args.retval;
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +228,7 @@ upcall_s_shared_free(s_shared_free_args *args) {
|
|||
extern "C" CDECL void
|
||||
upcall_shared_free(void* ptr) {
|
||||
s_shared_free_args args = {ptr};
|
||||
SWITCH_STACK(&args, upcall_s_shared_free);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_shared_free);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
|
@ -262,7 +274,7 @@ void upcall_s_create_shared_type_desc(s_create_shared_type_desc_args *args)
|
|||
extern "C" CDECL type_desc *
|
||||
upcall_create_shared_type_desc(type_desc *td) {
|
||||
s_create_shared_type_desc_args args = { td, 0 };
|
||||
SWITCH_STACK(&args, upcall_s_create_shared_type_desc);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_create_shared_type_desc);
|
||||
return args.res;
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +297,7 @@ void upcall_s_free_shared_type_desc(type_desc *td)
|
|||
|
||||
extern "C" CDECL void
|
||||
upcall_free_shared_type_desc(type_desc *td) {
|
||||
SWITCH_STACK(td, upcall_s_free_shared_type_desc);
|
||||
UPCALL_SWITCH_STACK(td, upcall_s_free_shared_type_desc);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
|
@ -325,7 +337,7 @@ upcall_get_type_desc(void *curr_crate, // ignored, legacy compat.
|
|||
type_desc const **descs,
|
||||
uintptr_t n_obj_params) {
|
||||
s_get_type_desc_args args = {0,size,align,n_descs,descs,n_obj_params};
|
||||
SWITCH_STACK(&args, upcall_s_get_type_desc);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_get_type_desc);
|
||||
return args.retval;
|
||||
}
|
||||
|
||||
|
|
@ -347,7 +359,7 @@ upcall_s_vec_grow(s_vec_grow_args *args) {
|
|||
extern "C" CDECL void
|
||||
upcall_vec_grow(rust_vec** vp, size_t new_sz) {
|
||||
s_vec_grow_args args = {vp, new_sz};
|
||||
SWITCH_STACK(&args, upcall_s_vec_grow);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_vec_grow);
|
||||
}
|
||||
|
||||
// Copy elements from one vector to another,
|
||||
|
|
@ -414,7 +426,7 @@ upcall_s_dynastack_mark(s_dynastack_mark_args *args) {
|
|||
extern "C" CDECL void *
|
||||
upcall_dynastack_mark() {
|
||||
s_dynastack_mark_args args = {0};
|
||||
SWITCH_STACK(&args, upcall_s_dynastack_mark);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_mark);
|
||||
return args.retval;
|
||||
}
|
||||
|
||||
|
|
@ -439,7 +451,7 @@ upcall_s_dynastack_alloc(s_dynastack_alloc_args *args) {
|
|||
extern "C" CDECL void *
|
||||
upcall_dynastack_alloc(size_t sz) {
|
||||
s_dynastack_alloc_args args = {0, sz};
|
||||
SWITCH_STACK(&args, upcall_s_dynastack_alloc);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_alloc);
|
||||
return args.retval;
|
||||
}
|
||||
|
||||
|
|
@ -465,7 +477,7 @@ upcall_s_dynastack_alloc_2(s_dynastack_alloc_2_args *args) {
|
|||
extern "C" CDECL void *
|
||||
upcall_dynastack_alloc_2(size_t sz, type_desc *ty) {
|
||||
s_dynastack_alloc_2_args args = {0, sz, ty};
|
||||
SWITCH_STACK(&args, upcall_s_dynastack_alloc_2);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_alloc_2);
|
||||
return args.retval;
|
||||
}
|
||||
|
||||
|
|
@ -482,7 +494,7 @@ upcall_s_dynastack_free(s_dynastack_free_args *args) {
|
|||
extern "C" CDECL void
|
||||
upcall_dynastack_free(void *ptr) {
|
||||
s_dynastack_free_args args = {ptr};
|
||||
SWITCH_STACK(&args, upcall_s_dynastack_free);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_free);
|
||||
}
|
||||
|
||||
extern "C" _Unwind_Reason_Code
|
||||
|
|
@ -524,7 +536,7 @@ upcall_rust_personality(int version,
|
|||
s_rust_personality_args args = {(_Unwind_Reason_Code)0,
|
||||
version, actions, exception_class,
|
||||
ue_header, context};
|
||||
SWITCH_STACK(&args, upcall_s_rust_personality);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_rust_personality);
|
||||
return args.retval;
|
||||
}
|
||||
|
||||
|
|
@ -553,7 +565,7 @@ upcall_cmp_type(int8_t *result, const type_desc *tydesc,
|
|||
const type_desc **subtydescs, uint8_t *data_0,
|
||||
uint8_t *data_1, uint8_t cmp_type) {
|
||||
s_cmp_type_args args = {result, tydesc, subtydescs, data_0, data_1, cmp_type};
|
||||
SWITCH_STACK(&args, upcall_s_cmp_type);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_cmp_type);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
|
|
@ -573,7 +585,7 @@ upcall_s_log_type(s_log_type_args *args) {
|
|||
extern "C" void
|
||||
upcall_log_type(const type_desc *tydesc, uint8_t *data, uint32_t level) {
|
||||
s_log_type_args args = {tydesc, data, level};
|
||||
SWITCH_STACK(&args, upcall_s_log_type);
|
||||
UPCALL_SWITCH_STACK(&args, upcall_s_log_type);
|
||||
}
|
||||
|
||||
struct rust_new_stack2_args {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue