Skip to content

Commit c73eb8f

Browse files
committed
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.
1 parent f57fd8d commit c73eb8f

File tree

1 file changed

+34
-22
lines changed

1 file changed

+34
-22
lines changed

src/rt/rust_upcall.cpp

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,24 @@ check_stack_alignment() __attribute__ ((aligned (16)));
2727
static void check_stack_alignment() { }
2828
#endif
2929

30-
#define SWITCH_STACK(A, F) upcall_call_shim_on_c_stack((void*)A, (void*)F)
30+
#define UPCALL_SWITCH_STACK(A, F) call_upcall_on_c_stack((void*)A, (void*)F)
31+
32+
inline void
33+
call_upcall_on_c_stack(void *args, void *fn_ptr) {
34+
check_stack_alignment();
35+
rust_task *task = rust_scheduler::get_task();
36+
rust_scheduler *sched = task->sched;
37+
sched->c_context.call_shim_on_c_stack(args, fn_ptr);
38+
}
3139

3240
extern "C" void record_sp(void *limit);
3341

3442
/**********************************************************************
3543
* Switches to the C-stack and invokes |fn_ptr|, passing |args| as argument.
3644
* This is used by the C compiler to call native functions and by other
3745
* upcalls to switch to the C stack. The return value is passed through a
38-
* field in the args parameter.
46+
* field in the args parameter. This upcall is specifically for switching
47+
* to the shim functions generated by rustc.
3948
*/
4049
extern "C" CDECL void
4150
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) {
5160
try {
5261
sched->c_context.call_shim_on_c_stack(args, fn_ptr);
5362
} catch (...) {
54-
task = rust_scheduler::get_task();
55-
task->record_stack_limit();
56-
throw;
63+
A(sched, false, "Native code threw an exception");
5764
}
65+
5866
task = rust_scheduler::get_task();
5967
task->record_stack_limit();
6068
}
@@ -80,8 +88,12 @@ extern "C" CDECL void
8088
upcall_fail(char const *expr,
8189
char const *file,
8290
size_t line) {
83-
s_fail_args args = {expr,file,line};
84-
SWITCH_STACK(&args, upcall_s_fail);
91+
try {
92+
s_fail_args args = {expr,file,line};
93+
UPCALL_SWITCH_STACK(&args, upcall_s_fail);
94+
} catch (rust_task*) {
95+
throw;
96+
}
8597
}
8698

8799
/**********************************************************************
@@ -124,7 +136,7 @@ upcall_s_malloc(s_malloc_args *args) {
124136
extern "C" CDECL uintptr_t
125137
upcall_malloc(size_t nbytes, type_desc *td) {
126138
s_malloc_args args = {0, nbytes, td};
127-
SWITCH_STACK(&args, upcall_s_malloc);
139+
UPCALL_SWITCH_STACK(&args, upcall_s_malloc);
128140
return args.retval;
129141
}
130142

@@ -156,7 +168,7 @@ upcall_s_free(s_free_args *args) {
156168
extern "C" CDECL void
157169
upcall_free(void* ptr, uintptr_t is_gc) {
158170
s_free_args args = {ptr, is_gc};
159-
SWITCH_STACK(&args, upcall_s_free);
171+
UPCALL_SWITCH_STACK(&args, upcall_s_free);
160172
}
161173

162174
/**********************************************************************
@@ -189,7 +201,7 @@ upcall_s_shared_malloc(s_shared_malloc_args *args) {
189201
extern "C" CDECL uintptr_t
190202
upcall_shared_malloc(size_t nbytes, type_desc *td) {
191203
s_shared_malloc_args args = {0, nbytes, td};
192-
SWITCH_STACK(&args, upcall_s_shared_malloc);
204+
UPCALL_SWITCH_STACK(&args, upcall_s_shared_malloc);
193205
return args.retval;
194206
}
195207

@@ -216,7 +228,7 @@ upcall_s_shared_free(s_shared_free_args *args) {
216228
extern "C" CDECL void
217229
upcall_shared_free(void* ptr) {
218230
s_shared_free_args args = {ptr};
219-
SWITCH_STACK(&args, upcall_s_shared_free);
231+
UPCALL_SWITCH_STACK(&args, upcall_s_shared_free);
220232
}
221233

222234
/**********************************************************************
@@ -262,7 +274,7 @@ void upcall_s_create_shared_type_desc(s_create_shared_type_desc_args *args)
262274
extern "C" CDECL type_desc *
263275
upcall_create_shared_type_desc(type_desc *td) {
264276
s_create_shared_type_desc_args args = { td, 0 };
265-
SWITCH_STACK(&args, upcall_s_create_shared_type_desc);
277+
UPCALL_SWITCH_STACK(&args, upcall_s_create_shared_type_desc);
266278
return args.res;
267279
}
268280

@@ -285,7 +297,7 @@ void upcall_s_free_shared_type_desc(type_desc *td)
285297

286298
extern "C" CDECL void
287299
upcall_free_shared_type_desc(type_desc *td) {
288-
SWITCH_STACK(td, upcall_s_free_shared_type_desc);
300+
UPCALL_SWITCH_STACK(td, upcall_s_free_shared_type_desc);
289301
}
290302

291303
/**********************************************************************
@@ -325,7 +337,7 @@ upcall_get_type_desc(void *curr_crate, // ignored, legacy compat.
325337
type_desc const **descs,
326338
uintptr_t n_obj_params) {
327339
s_get_type_desc_args args = {0,size,align,n_descs,descs,n_obj_params};
328-
SWITCH_STACK(&args, upcall_s_get_type_desc);
340+
UPCALL_SWITCH_STACK(&args, upcall_s_get_type_desc);
329341
return args.retval;
330342
}
331343

@@ -347,7 +359,7 @@ upcall_s_vec_grow(s_vec_grow_args *args) {
347359
extern "C" CDECL void
348360
upcall_vec_grow(rust_vec** vp, size_t new_sz) {
349361
s_vec_grow_args args = {vp, new_sz};
350-
SWITCH_STACK(&args, upcall_s_vec_grow);
362+
UPCALL_SWITCH_STACK(&args, upcall_s_vec_grow);
351363
}
352364

353365
// Copy elements from one vector to another,
@@ -414,7 +426,7 @@ upcall_s_dynastack_mark(s_dynastack_mark_args *args) {
414426
extern "C" CDECL void *
415427
upcall_dynastack_mark() {
416428
s_dynastack_mark_args args = {0};
417-
SWITCH_STACK(&args, upcall_s_dynastack_mark);
429+
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_mark);
418430
return args.retval;
419431
}
420432

@@ -439,7 +451,7 @@ upcall_s_dynastack_alloc(s_dynastack_alloc_args *args) {
439451
extern "C" CDECL void *
440452
upcall_dynastack_alloc(size_t sz) {
441453
s_dynastack_alloc_args args = {0, sz};
442-
SWITCH_STACK(&args, upcall_s_dynastack_alloc);
454+
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_alloc);
443455
return args.retval;
444456
}
445457

@@ -465,7 +477,7 @@ upcall_s_dynastack_alloc_2(s_dynastack_alloc_2_args *args) {
465477
extern "C" CDECL void *
466478
upcall_dynastack_alloc_2(size_t sz, type_desc *ty) {
467479
s_dynastack_alloc_2_args args = {0, sz, ty};
468-
SWITCH_STACK(&args, upcall_s_dynastack_alloc_2);
480+
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_alloc_2);
469481
return args.retval;
470482
}
471483

@@ -482,7 +494,7 @@ upcall_s_dynastack_free(s_dynastack_free_args *args) {
482494
extern "C" CDECL void
483495
upcall_dynastack_free(void *ptr) {
484496
s_dynastack_free_args args = {ptr};
485-
SWITCH_STACK(&args, upcall_s_dynastack_free);
497+
UPCALL_SWITCH_STACK(&args, upcall_s_dynastack_free);
486498
}
487499

488500
extern "C" _Unwind_Reason_Code
@@ -524,7 +536,7 @@ upcall_rust_personality(int version,
524536
s_rust_personality_args args = {(_Unwind_Reason_Code)0,
525537
version, actions, exception_class,
526538
ue_header, context};
527-
SWITCH_STACK(&args, upcall_s_rust_personality);
539+
UPCALL_SWITCH_STACK(&args, upcall_s_rust_personality);
528540
return args.retval;
529541
}
530542

@@ -553,7 +565,7 @@ upcall_cmp_type(int8_t *result, const type_desc *tydesc,
553565
const type_desc **subtydescs, uint8_t *data_0,
554566
uint8_t *data_1, uint8_t cmp_type) {
555567
s_cmp_type_args args = {result, tydesc, subtydescs, data_0, data_1, cmp_type};
556-
SWITCH_STACK(&args, upcall_s_cmp_type);
568+
UPCALL_SWITCH_STACK(&args, upcall_s_cmp_type);
557569
}
558570

559571
extern "C" void
@@ -573,7 +585,7 @@ upcall_s_log_type(s_log_type_args *args) {
573585
extern "C" void
574586
upcall_log_type(const type_desc *tydesc, uint8_t *data, uint32_t level) {
575587
s_log_type_args args = {tydesc, data, level};
576-
SWITCH_STACK(&args, upcall_s_log_type);
588+
UPCALL_SWITCH_STACK(&args, upcall_s_log_type);
577589
}
578590

579591
struct rust_new_stack2_args {

0 commit comments

Comments
 (0)