diff --git a/racket/src/racket/src/jit.h b/racket/src/racket/src/jit.h index f921be2fd5..c72762ed7d 100644 --- a/racket/src/racket/src/jit.h +++ b/racket/src/racket/src/jit.h @@ -348,6 +348,7 @@ struct scheme_jit_common_record { void *list_ref_code, *list_tail_code; void *finish_tail_call_code, *finish_tail_call_fixup_code; void *module_run_start_code, *module_exprun_start_code, *module_start_start_code; + void *thread_start_child_code; void *box_flonum_from_stack_code, *box_flonum_from_reg_code; void *fl1_fail_code[JIT_NUM_FL_KINDS], *fl2rr_fail_code[2][JIT_NUM_FL_KINDS]; void *fl2fr_fail_code[2][JIT_NUM_FL_KINDS], *fl2rf_fail_code[2][JIT_NUM_FL_KINDS]; diff --git a/racket/src/racket/src/jitcommon.c b/racket/src/racket/src/jitcommon.c index 34d8f5eec9..f2f2619a16 100644 --- a/racket/src/racket/src/jitcommon.c +++ b/racket/src/racket/src/jitcommon.c @@ -3639,6 +3639,33 @@ static int more_common0(mz_jit_state *jitter, void *_data) scheme_jit_register_sub_func(jitter, sjc.module_start_start_code, scheme_eof); } + /* *** thread_start_child_code *** */ + /* A simple indirection to generate code that libunwind can't follow, + particularly as used by exceptions in the Objective-C runtime */ + { + int in; + + sjc.thread_start_child_code = jit_get_ip(); + jit_prolog(2); + in = jit_arg_p(); + jit_getarg_p(JIT_R0, in); /* child */ + in = jit_arg_p(); + jit_getarg_p(JIT_R1, in); /* child_thunk */ + CHECK_LIMIT(); + mz_push_locals(); + + jit_prepare(2); + jit_pusharg_p(JIT_R1); + jit_pusharg_p(JIT_R0); + (void)mz_finish(scheme_do_thread_start_child); + CHECK_LIMIT(); + mz_pop_locals(); + jit_ret(); + CHECK_LIMIT(); + + scheme_jit_register_sub_func(jitter, sjc.thread_start_child_code, scheme_eof); + } + return 1; } diff --git a/racket/src/racket/src/jitstack.c b/racket/src/racket/src/jitstack.c index 02a76732fd..5b18d41405 100644 --- a/racket/src/racket/src/jitstack.c +++ b/racket/src/racket/src/jitstack.c @@ -689,6 +689,7 @@ void scheme_jit_now(Scheme_Object *f) typedef void *(*Module_Run_Proc)(Scheme_Env *menv, Scheme_Env *env, Scheme_Object **name); typedef void *(*Module_Exprun_Proc)(Scheme_Env *menv, int set_ns, Scheme_Object **name); typedef void *(*Module_Start_Proc)(struct Start_Module_Args *a, Scheme_Object **name); +typedef void (*Thread_Start_Child_Proc)(Scheme_Thread *child, Scheme_Object *child_thunk); void *scheme_module_run_start(Scheme_Env *menv, Scheme_Env *env, Scheme_Object *name) { @@ -717,8 +718,23 @@ void *scheme_module_start_start(struct Start_Module_Args *a, Scheme_Object *name return scheme_module_start_finish(a); } +void scheme_thread_start_child(Scheme_Thread *child, Scheme_Object *child_thunk) +{ + Thread_Start_Child_Proc proc = (Thread_Start_Child_Proc)sjc.thread_start_child_code; + if (proc) + proc(child, child_thunk); + else + scheme_do_thread_start_child(child, child_thunk); +} + + #else void* scheme_jit_find_code_end(void *p) { return NULL; } +void scheme_thread_start_child(Scheme_Thread *child, Scheme_Object *child_thunk) +{ + return scheme_do_thread_start_child(child, child_thunk); +} + #endif diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index c0f5da41b2..0a25dc45b4 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -667,6 +667,9 @@ void scheme_suspend_remembered_threads(void); void scheme_resume_remembered_threads(void); #endif +void scheme_thread_start_child(Scheme_Thread *child, Scheme_Object *child_thunk); +void scheme_do_thread_start_child(Scheme_Thread *child, Scheme_Object *child_thunk); + int scheme_wait_until_suspend_ok(void); #ifdef MZ_USE_MZRT diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 93a927bd79..62adb3f330 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -1,6 +1,6 @@ /* Racket - Copyright (c) 2004-2015 PLT Design Inc. + Copyright (c) 2004-2014 PLT Design Inc. Copyright (c) 1995-2001 Matthew Flatt This library is free software; you can redistribute it and/or @@ -3167,6 +3167,11 @@ static void start_child(Scheme_Thread * volatile child, } } +void scheme_do_thread_start_child(Scheme_Thread *child, Scheme_Object *child_eval) +{ + return start_child(child, child_eval); +} + static Scheme_Object *make_subprocess(Scheme_Object *child_thunk, void *child_start, Scheme_Config *config, @@ -3223,7 +3228,7 @@ static Scheme_Object *make_subprocess(Scheme_Object *child_thunk, child->stack_start = child_start; /* Sets the child's jmpbuf for swapping in later: */ - start_child(child, child_thunk); + scheme_thread_start_child(child, child_thunk); if (scheme_notify_multithread && turn_on_multi) { scheme_notify_multithread(1);