Skip to content

Commit 31fe5d0

Browse files
committed
rt: Run most upcalls on the C stack
1 parent 0fc4403 commit 31fe5d0

File tree

1 file changed

+66
-60
lines changed

1 file changed

+66
-60
lines changed

src/rt/rust_upcall.cpp

Lines changed: 66 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "rust_upcall.h"
77
#include <stdint.h>
88

9+
#define SWITCH_STACK(A, F) upcall_call_shim_on_c_stack((void*)A, (void*)F)
10+
911
extern "C" void record_sp(void *limit);
1012

1113
/**
@@ -32,26 +34,6 @@ upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
3234
task->record_stack_limit();
3335
}
3436

35-
#if defined(__i386__) || defined(__x86_64__) || defined(_M_X64)
36-
void
37-
check_stack(rust_task *task) {
38-
void *esp;
39-
# ifdef __i386__
40-
asm volatile("movl %%esp,%0" : "=r" (esp));
41-
# else
42-
asm volatile("mov %%rsp,%0" : "=r" (esp));
43-
# endif
44-
if (esp < task->stk->data)
45-
task->kernel->fatal("Out of stack space, sorry");
46-
}
47-
#else
48-
#warning "Stack checks are not supported on this architecture"
49-
void
50-
check_stack(rust_task *task) {
51-
// TODO
52-
}
53-
#endif
54-
5537
// Copy elements from one vector to another,
5638
// dealing with reference counts
5739
static inline void
@@ -87,11 +69,12 @@ upcall_s_fail(s_fail_args *args) {
8769
}
8870

8971
struct s_malloc_args {
72+
uintptr_t retval;
9073
size_t nbytes;
9174
type_desc *td;
9275
};
9376

94-
extern "C" CDECL uintptr_t
77+
extern "C" CDECL void
9578
upcall_s_malloc(s_malloc_args *args) {
9679
rust_task *task = rust_scheduler::get_task();
9780
LOG_UPCALL_ENTRY(task);
@@ -115,7 +98,7 @@ upcall_s_malloc(s_malloc_args *args) {
11598
LOG(task, mem,
11699
"upcall malloc(%" PRIdPTR ", 0x%" PRIxPTR ") = 0x%" PRIxPTR,
117100
args->nbytes, args->td, (uintptr_t)p);
118-
return (uintptr_t) p;
101+
args->retval = (uintptr_t) p;
119102
}
120103

121104
struct s_free_args {
@@ -143,11 +126,12 @@ upcall_s_free(s_free_args *args) {
143126
}
144127

145128
struct s_shared_malloc_args {
129+
uintptr_t retval;
146130
size_t nbytes;
147131
type_desc *td;
148132
};
149133

150-
extern "C" CDECL uintptr_t
134+
extern "C" CDECL void
151135
upcall_s_shared_malloc(s_shared_malloc_args *args) {
152136
rust_task *task = rust_scheduler::get_task();
153137
LOG_UPCALL_ENTRY(task);
@@ -161,7 +145,7 @@ upcall_s_shared_malloc(s_shared_malloc_args *args) {
161145
"upcall shared_malloc(%" PRIdPTR ", 0x%" PRIxPTR
162146
") = 0x%" PRIxPTR,
163147
args->nbytes, args->td, (uintptr_t)p);
164-
return (uintptr_t) p;
148+
args->retval = (uintptr_t) p;
165149
}
166150

167151
struct s_shared_free_args {
@@ -184,17 +168,17 @@ upcall_s_shared_free(s_shared_free_args *args) {
184168
}
185169

186170
struct s_get_type_desc_args {
171+
type_desc *retval;
187172
size_t size;
188173
size_t align;
189174
size_t n_descs;
190175
type_desc const **descs;
191176
uintptr_t n_obj_params;
192177
};
193178

194-
extern "C" CDECL type_desc *
179+
extern "C" CDECL void
195180
upcall_s_get_type_desc(s_get_type_desc_args *args) {
196181
rust_task *task = rust_scheduler::get_task();
197-
check_stack(task);
198182
LOG_UPCALL_ENTRY(task);
199183

200184
LOG(task, cache, "upcall get_type_desc with size=%" PRIdPTR
@@ -204,7 +188,7 @@ upcall_s_get_type_desc(s_get_type_desc_args *args) {
204188
type_desc *td = cache->get_type_desc(args->size, args->align, args->n_descs,
205189
args->descs, args->n_obj_params);
206190
LOG(task, cache, "returning tydesc 0x%" PRIxPTR, td);
207-
return td;
191+
args->retval = td;
208192
}
209193

210194
struct s_vec_grow_args {
@@ -238,16 +222,21 @@ upcall_s_vec_push(s_vec_push_args *args) {
238222
v->fill += args->elt_ty->size;
239223
}
240224

225+
struct s_dynastack_mark_args {
226+
void *retval;
227+
};
228+
241229
/**
242230
* Returns a token that can be used to deallocate all of the allocated space
243231
* space in the dynamic stack.
244232
*/
245-
extern "C" CDECL void *
246-
upcall_s_dynastack_mark() {
247-
return rust_scheduler::get_task()->dynastack.mark();
233+
extern "C" CDECL void
234+
upcall_s_dynastack_mark(s_dynastack_mark_args *args) {
235+
args->retval = rust_scheduler::get_task()->dynastack.mark();
248236
}
249237

250238
struct s_dynastack_alloc_args {
239+
void *retval;
251240
size_t sz;
252241
};
253242

@@ -256,13 +245,15 @@ struct s_dynastack_alloc_args {
256245
*
257246
* FIXME: Deprecated since dynamic stacks need to be self-describing for GC.
258247
*/
259-
extern "C" CDECL void *
248+
extern "C" CDECL void
260249
upcall_s_dynastack_alloc(s_dynastack_alloc_args *args) {
261250
size_t sz = args->sz;
262-
return sz ? rust_scheduler::get_task()->dynastack.alloc(sz, NULL) : NULL;
251+
args->retval = sz ?
252+
rust_scheduler::get_task()->dynastack.alloc(sz, NULL) : NULL;
263253
}
264254

265255
struct s_dynastack_alloc_2_args {
256+
void *retval;
266257
size_t sz;
267258
type_desc *ty;
268259
};
@@ -271,11 +262,12 @@ struct s_dynastack_alloc_2_args {
271262
* Allocates space associated with a type descriptor in the dynamic stack and
272263
* returns it.
273264
*/
274-
extern "C" CDECL void *
265+
extern "C" CDECL void
275266
upcall_s_dynastack_alloc_2(s_dynastack_alloc_2_args *args) {
276267
size_t sz = args->sz;
277268
type_desc *ty = args->ty;
278-
return sz ? rust_scheduler::get_task()->dynastack.alloc(sz, ty) : NULL;
269+
args->retval = sz ?
270+
rust_scheduler::get_task()->dynastack.alloc(sz, ty) : NULL;
279271
}
280272

281273
struct s_dynastack_free_args {
@@ -296,20 +288,21 @@ __gxx_personality_v0(int version,
296288
_Unwind_Context *context);
297289

298290
struct s_rust_personality_args {
291+
_Unwind_Reason_Code retval;
299292
int version;
300293
_Unwind_Action actions;
301294
uint64_t exception_class;
302295
_Unwind_Exception *ue_header;
303296
_Unwind_Context *context;
304297
};
305298

306-
extern "C" _Unwind_Reason_Code
299+
extern "C" void
307300
upcall_s_rust_personality(s_rust_personality_args *args) {
308-
return __gxx_personality_v0(args->version,
309-
args->actions,
310-
args->exception_class,
311-
args->ue_header,
312-
args->context);
301+
args->retval = __gxx_personality_v0(args->version,
302+
args->actions,
303+
args->exception_class,
304+
args->ue_header,
305+
args->context);
313306
}
314307

315308
extern "C" void
@@ -355,14 +348,17 @@ extern "C" CDECL void
355348
upcall_fail(char const *expr,
356349
char const *file,
357350
size_t line) {
351+
// FIXME: Need to fix the stack switching function to unwind properly
352+
// in order to switch stacks here
358353
s_fail_args args = {expr,file,line};
359354
upcall_s_fail(&args);
360355
}
361356

362357
extern "C" CDECL uintptr_t
363358
upcall_malloc(size_t nbytes, type_desc *td) {
364-
s_malloc_args args = {nbytes, td};
365-
return upcall_s_malloc(&args);
359+
s_malloc_args args = {0, nbytes, td};
360+
SWITCH_STACK(&args, upcall_s_malloc);
361+
return args.retval;
366362
}
367363

368364
/**
@@ -371,13 +367,14 @@ upcall_malloc(size_t nbytes, type_desc *td) {
371367
extern "C" CDECL void
372368
upcall_free(void* ptr, uintptr_t is_gc) {
373369
s_free_args args = {ptr, is_gc};
374-
upcall_s_free(&args);
370+
SWITCH_STACK(&args, upcall_s_free);
375371
}
376372

377373
extern "C" CDECL uintptr_t
378374
upcall_shared_malloc(size_t nbytes, type_desc *td) {
379-
s_shared_malloc_args args = {nbytes, td};
380-
return upcall_s_shared_malloc(&args);
375+
s_shared_malloc_args args = {0, nbytes, td};
376+
SWITCH_STACK(&args, upcall_s_shared_malloc);
377+
return args.retval;
381378
}
382379

383380
/**
@@ -386,7 +383,7 @@ upcall_shared_malloc(size_t nbytes, type_desc *td) {
386383
extern "C" CDECL void
387384
upcall_shared_free(void* ptr) {
388385
s_shared_free_args args = {ptr};
389-
upcall_s_shared_free(&args);
386+
SWITCH_STACK(&args, upcall_s_shared_free);
390387
}
391388

392389
extern "C" CDECL type_desc *
@@ -396,18 +393,21 @@ upcall_get_type_desc(void *curr_crate, // ignored, legacy compat.
396393
size_t n_descs,
397394
type_desc const **descs,
398395
uintptr_t n_obj_params) {
399-
s_get_type_desc_args args = {size,align,n_descs,descs,n_obj_params};
400-
return upcall_s_get_type_desc(&args);
396+
s_get_type_desc_args args = {0,size,align,n_descs,descs,n_obj_params};
397+
SWITCH_STACK(&args, upcall_s_get_type_desc);
398+
return args.retval;
401399
}
402400

403401
extern "C" CDECL void
404402
upcall_vec_grow(rust_vec** vp, size_t new_sz) {
405403
s_vec_grow_args args = {vp, new_sz};
406-
upcall_s_vec_grow(&args);
404+
SWITCH_STACK(&args, upcall_s_vec_grow);
407405
}
408406

409407
extern "C" CDECL void
410408
upcall_vec_push(rust_vec** vp, type_desc* elt_ty, void* elt) {
409+
// FIXME: Switching stacks here causes crashes, probably
410+
// because this upcall calls take glue
411411
s_vec_push_args args = {vp, elt_ty, elt};
412412
upcall_s_vec_push(&args);
413413
}
@@ -418,7 +418,9 @@ upcall_vec_push(rust_vec** vp, type_desc* elt_ty, void* elt) {
418418
*/
419419
extern "C" CDECL void *
420420
upcall_dynastack_mark() {
421-
return upcall_s_dynastack_mark();
421+
s_dynastack_mark_args args = {0};
422+
SWITCH_STACK(&args, upcall_s_dynastack_mark);
423+
return args.retval;
422424
}
423425

424426
/**
@@ -428,8 +430,9 @@ upcall_dynastack_mark() {
428430
*/
429431
extern "C" CDECL void *
430432
upcall_dynastack_alloc(size_t sz) {
431-
s_dynastack_alloc_args args = {sz};
432-
return upcall_s_dynastack_alloc(&args);
433+
s_dynastack_alloc_args args = {0, sz};
434+
SWITCH_STACK(&args, upcall_s_dynastack_alloc);
435+
return args.retval;
433436
}
434437

435438
/**
@@ -438,15 +441,16 @@ upcall_dynastack_alloc(size_t sz) {
438441
*/
439442
extern "C" CDECL void *
440443
upcall_dynastack_alloc_2(size_t sz, type_desc *ty) {
441-
s_dynastack_alloc_2_args args = {sz, ty};
442-
return upcall_s_dynastack_alloc_2(&args);
444+
s_dynastack_alloc_2_args args = {0, sz, ty};
445+
SWITCH_STACK(&args, upcall_s_dynastack_alloc_2);
446+
return args.retval;
443447
}
444448

445449
/** Frees space in the dynamic stack. */
446450
extern "C" CDECL void
447451
upcall_dynastack_free(void *ptr) {
448452
s_dynastack_free_args args = {ptr};
449-
return upcall_s_dynastack_free(&args);
453+
SWITCH_STACK(&args, upcall_s_dynastack_free);
450454
}
451455

452456
extern "C" _Unwind_Reason_Code
@@ -455,23 +459,25 @@ upcall_rust_personality(int version,
455459
uint64_t exception_class,
456460
_Unwind_Exception *ue_header,
457461
_Unwind_Context *context) {
458-
s_rust_personality_args args = {version, actions, exception_class, ue_header,
459-
context};
460-
return upcall_s_rust_personality(&args);
462+
s_rust_personality_args args = {(_Unwind_Reason_Code)0,
463+
version, actions, exception_class,
464+
ue_header, context};
465+
SWITCH_STACK(&args, upcall_s_rust_personality);
466+
return args.retval;
461467
}
462468

463469
extern "C" void
464470
upcall_cmp_type(int8_t *result, const type_desc *tydesc,
465471
const type_desc **subtydescs, uint8_t *data_0,
466472
uint8_t *data_1, uint8_t cmp_type) {
467473
s_cmp_type_args args = {result, tydesc, subtydescs, data_0, data_1, cmp_type};
468-
upcall_s_cmp_type(&args);
474+
SWITCH_STACK(&args, upcall_s_cmp_type);
469475
}
470476

471477
extern "C" void
472478
upcall_log_type(const type_desc *tydesc, uint8_t *data, uint32_t level) {
473479
s_log_type_args args = {tydesc, data, level};
474-
upcall_s_log_type(&args);
480+
SWITCH_STACK(&args, upcall_s_log_type);
475481
}
476482

477483
struct rust_new_stack2_args {

0 commit comments

Comments
 (0)