futures: future-local handling of stack overflow

Includes the addition of 'overflow and 'start-overflow-work
events, whcih are effectively specializations of 'sync and
'start-work to expose overflow handling.

Also, fix a bug related to a potential GC during mark-stack
restore from a lightweight continuation.
This commit is contained in:
Matthew Flatt 2012-06-20 07:33:01 +08:00
parent f91dc81bf5
commit 40c892ff80
15 changed files with 674 additions and 316 deletions

View File

@ -188,7 +188,11 @@ a data value that is an instance of a @racket[future-event]
@tech{prefab} structure:
@racketblock[
(define-struct future-event (future-id proc-id action time unsafe-op-name)
(define-struct future-event (future-id
proc-id
action
time
unsafe-op-name)
#:prefab)
]
@ -222,6 +226,10 @@ The @racket[action] field is a symbol:
started in a process other than 0 (e.g., the thunk requires too
much local storage to start).}
@item{@racket['start-overflow-work]: like @racket['start-work], where
the future thunk's work was previously stopped due to an
internal stack overflow.}
@item{@racket['sync]: blocking (processes other than 0) or initiation
of handing (process 0) for an ``unsafe'' operation in a future
thunk's evaluation; the operation must run in process 0.}
@ -235,6 +243,10 @@ The @racket[action] field is a symbol:
@racket['block], but for a @racket[touch] operation within a
future thunk.}
@item{@racket['overflow] (never in process 0): like @racket['sync] or
@racket['block], but for the case that a process encountered an
internal stack overflow while evaluating a future thunk.}
@item{@racket['result] or @racket['abort]: waiting or handling for
@racket['sync], @racket['block], or @racket['touch] ended with
a value or an error, respectively.}
@ -255,15 +267,15 @@ The @racket[action] field is a symbol:
]
Assuming no @racket['missing] events, then @racket['start-work] or
@racket['start-0-work] is always paired with @racket['end-work],
Assuming no @racket['missing] events, then @racket['start-work],
@racket['start-0-work], @racket['start-overflow-work] is always paired with @racket['end-work];
@racket['sync], @racket['block], and @racket['touch] are always paired
with @racket['result], @racket['abort], or @racket['suspend], and
with @racket['result], @racket['abort], or @racket['suspend]; and
@racket['touch-pause] is always paired with @racket['touch-resume].
In process 0, some event pairs can be nested within other event pairs:
@racket['sync], @racket['block], or @racket['touch] with
@racket['result] or @racket['abort], and @racket['touch-pause] with
@racket['result] or @racket['abort]; and @racket['touch-pause] with
@racket['touch-resume].
An @racket[block] in process 0 is generated when an unsafe operation

View File

@ -819,6 +819,37 @@ We should also test deep continuations.
(check-equal? (unbox b2) #false)
(neg-good)
(check-equal? (unbox b2) #true))
;; check handling of marks in stack-overflow handling:
(let ()
(define (maybe-add1 n)
(if (number? n)
(add1 n)
n))
(define (loop n)
(if (zero? n)
(continuation-mark-set->list (current-continuation-marks) 'x)
(with-continuation-mark
'x
n
(maybe-add1 (loop (sub1 n))))))
(define f (func (lambda () (loop 10000))))
(check-equal? 10000 (length (touch f))))
;; check arity error in overflow handling:
(let ()
(define (loop n)
(if (zero? n)
(values 0 0)
(add1 (loop (sub1 n)))))
(for ([i (in-range 1340 1320 -1)])
(define f (func (lambda () (loop i))))
(sleep 0.1)
(with-handlers ([exn:fail? (lambda (exn)
(unless (regexp-match #rx"context" (exn-message exn))
(raise exn)))])
(touch f))))
)
(run-tests future)

View File

@ -1,7 +1,10 @@
Version 5.3.0.11
racket/base: added impersonate-prompt-tag & chaperone-prompt-tag
racket/control: added call/prompt, call/comp, abort/cc and
allow #:tag argument for % and f-control
allow #:tag argument for % and f-control
racket/future: handling of internal stack overflow without
necessarily blocking on process 0; added 'overflow and
'start-overflow-work log events
Version 5.3.0.10
racket/base: add progress-evt?, thread-cell-values?, prefab-key?,

View File

@ -238,7 +238,7 @@ typedef struct Thread_Local_Variables {
int scheme_did_gc_count_;
struct Scheme_Future_State *scheme_future_state_;
struct Scheme_Future_Thread_State *scheme_future_thread_state_;
void *jit_future_storage_[2];
void *jit_future_storage_[4];
struct Scheme_Object **scheme_current_runstack_start_;
struct Scheme_Object **scheme_current_runstack_;
intptr_t scheme_current_cont_mark_stack_;

View File

@ -7855,8 +7855,7 @@ Scheme_Object *scheme_apply_lightweight_continuation(Scheme_Lightweight_Continua
intptr_t min_stacksize)
XFORM_SKIP_PROC
{
intptr_t len, cm_len, cm_pos_delta, cm_delta, i, cm;
Scheme_Cont_Mark *seg;
intptr_t len, cm_delta, i, cm;
Scheme_Object **rs;
len = lw->saved_lwc->runstack_start - lw->saved_lwc->runstack_end;
@ -7882,18 +7881,13 @@ Scheme_Object *scheme_apply_lightweight_continuation(Scheme_Lightweight_Continua
scheme_current_lwc->cont_mark_stack_start = MZ_CONT_MARK_STACK;
scheme_current_lwc->cont_mark_pos_start = MZ_CONT_MARK_POS + 2;
cm_len = lw->saved_lwc->cont_mark_stack_end - lw->saved_lwc->cont_mark_stack_start;
if (cm_len) {
/* install captured continuation marks, adjusting the pos
to match the new context: */
seg = lw->cont_mark_stack_slice;
cm_pos_delta = MZ_CONT_MARK_POS + 2 - lw->saved_lwc->cont_mark_pos_start;
for (i = 0; i < cm_len; i++) {
MZ_CONT_MARK_POS = seg[i].pos + cm_pos_delta;
scheme_set_cont_mark(seg[i].key, seg[i].val);
}
MZ_CONT_MARK_POS = lw->saved_lwc->cont_mark_pos_end + cm_pos_delta;
}
#ifdef MZ_USE_FUTURES
jit_future_storage[3] = result;
#endif
lw = scheme_restore_lightweight_continuation_marks(lw); /* can trigger GC */
#ifdef MZ_USE_FUTURES
result = (Scheme_Object *)jit_future_storage[3];
#endif
cm_delta = (intptr_t)MZ_CONT_MARK_STACK - (intptr_t)lw->saved_lwc->cont_mark_stack_end;
@ -7918,6 +7912,35 @@ Scheme_Object *scheme_apply_lightweight_continuation(Scheme_Lightweight_Continua
return scheme_apply_lightweight_continuation_stack(lw->saved_lwc, lw->stack_slice, result);
}
Scheme_Lightweight_Continuation *scheme_restore_lightweight_continuation_marks(Scheme_Lightweight_Continuation *lw)
XFORM_SKIP_PROC
/* Called by any thread, but this function can trigger a GC in the runtime thread */
{
intptr_t cm_len, i, cm_pos_delta;
Scheme_Cont_Mark *seg;
cm_len = lw->saved_lwc->cont_mark_stack_end - lw->saved_lwc->cont_mark_stack_start;
if (cm_len) {
/* install captured continuation marks, adjusting the pos
to match the new context: */
seg = lw->cont_mark_stack_slice;
cm_pos_delta = MZ_CONT_MARK_POS + 2 - lw->saved_lwc->cont_mark_pos_start;
for (i = 0; i < cm_len; i++) {
MZ_CONT_MARK_POS = seg[i].pos + cm_pos_delta;
#ifdef MZ_USE_FUTURES
jit_future_storage[2] = lw;
#endif
scheme_set_cont_mark(seg[i].key, seg[i].val); /* can trigger a GC */
#ifdef MZ_USE_FUTURES
lw = (Scheme_Lightweight_Continuation *)jit_future_storage[2];
#endif
}
MZ_CONT_MARK_POS = lw->saved_lwc->cont_mark_pos_end + cm_pos_delta;
}
return lw;
}
int scheme_push_marks_from_lightweight_continuation(Scheme_Lightweight_Continuation *lw,
Scheme_Cont_Frame_Data *d)
{

View File

@ -303,8 +303,10 @@ static void requeue_future(struct future_t *future, struct Scheme_Future_State *
static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
void *func,
int is_atomic,
int can_suspend);
static int capture_future_continuation(struct Scheme_Future_State *fs, future_t *ft, void **storage, int need_lock);
int can_suspend,
int for_overflow);
static int capture_future_continuation(struct Scheme_Future_State *fs, future_t *ft, void **storage,
int need_lock, int for_overflow);
#define FUTURE_C_STACK_SIZE 500000
#define FUTURE_RUNSTACK_SIZE 2000
@ -316,6 +318,7 @@ enum {
FEVENT_COMPLETE,
FEVENT_START_WORK,
FEVENT_START_RTONLY_WORK,
FEVENT_RESUME_WORK,
FEVENT_END_WORK,
FEVENT_RTCALL_ATOMIC,
FEVENT_HANDLE_RTCALL_ATOMIC,
@ -327,6 +330,7 @@ enum {
FEVENT_RTCALL_ABORT,
FEVENT_HANDLE_RTCALL_ABORT,
FEVENT_RTCALL_SUSPEND,
FEVENT_OVERFLOW,
FEVENT_TOUCH_PAUSE,
FEVENT_TOUCH_RESUME,
FEVENT_MISSING,
@ -334,18 +338,20 @@ enum {
};
static const char * const fevent_strs[] = { "create", "complete",
"start-work", "start-0-work", "end-work",
"start-work", "start-0-work", "start-overflow-work",
"end-work",
"sync", "sync", "block", "touch", "block",
"result", "result", "abort", "abort",
"suspend",
"suspend", "overflow",
"touch-pause", "touch-resume", "missing" };
static const char * const fevent_long_strs[] = { "created", "completed",
"started work", "started (process 0, only)", "ended work",
"started work", "started (process 0, only)", "started (overflow)",
"ended work",
"synchronizing with process 0", "synchronizing",
"BLOCKING on process 0", "touching future", "HANDLING",
"result from process 0", "result determined",
"abort from process 0", "abort determined",
"suspended",
"suspended", "overflow",
"paused for touch", "resumed for touch",
"events missing" };
@ -384,7 +390,7 @@ typedef struct Scheme_Future_State {
THREAD_LOCAL_DECL(static Scheme_Future_State *scheme_future_state);
THREAD_LOCAL_DECL(void *jit_future_storage[2]);
THREAD_LOCAL_DECL(void *jit_future_storage[4]);
#ifdef MZ_PRECISE_GC
THREAD_LOCAL_DECL(extern uintptr_t GC_gen0_alloc_page_ptr);
@ -408,8 +414,13 @@ static Scheme_Object *apply_future_lw(future_t *ft);
static int fsemaphore_ready(Scheme_Object *obj);
static void init_fevent(Fevent_Buffer *b);
static void free_fevent(Fevent_Buffer *b);
static void future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, int what);
static int future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, int what);
static Scheme_Object *would_be_future(int argc, Scheme_Object *argv[]);
static void push_suspended_lw(Scheme_Future_State *fs, future_t *ft);
static void pop_suspended_lw(Scheme_Future_State *fs, future_t *ft);
static Scheme_Object *bad_multi_result_proc;
static Scheme_Object *bad_multi_result(int argc, Scheme_Object **argv);
READ_ONLY static int cpucount;
static void init_cpucount(void);
@ -543,6 +554,9 @@ void scheme_init_futures(Scheme_Env *newenv)
void scheme_init_futures_once()
{
init_cpucount();
REGISTER_SO(bad_multi_result_proc);
bad_multi_result_proc = scheme_make_prim(bad_multi_result);
}
void scheme_init_futures_per_place()
@ -664,7 +678,7 @@ static void init_future_thread(Scheme_Future_State *fs, int i)
scheme_register_static(params.scheme_current_runstack_ptr, sizeof(void*));
scheme_register_static(params.scheme_current_runstack_start_ptr, sizeof(void*));
scheme_register_static(params.jit_future_storage_ptr, 2 * sizeof(void*));
scheme_register_static(params.jit_future_storage_ptr, 4 * sizeof(void*));
scheme_register_static(params.current_thread_ptr, sizeof(void*));
fs->pool_threads[i] = fts;
@ -1205,8 +1219,6 @@ static Scheme_Object *make_future(Scheme_Object *lambda, int enqueue)
/* Can't even call it in a future thread */
ft->status = PENDING_OVERSIZE;
}
ft->code = (void*)ncd->start_code;
} else
ft->status = PENDING_OVERSIZE;
@ -1226,6 +1238,12 @@ static Scheme_Object *make_future(Scheme_Object *lambda, int enqueue)
return (Scheme_Object*)ft;
}
int scheme_can_apply_native_in_future(Scheme_Object *proc)
XFORM_SKIP_PROC /* can be called from future thread */
{
return (((Scheme_Native_Closure *)proc)->code->max_let_depth < FUTURE_RUNSTACK_SIZE * sizeof(void*));
}
static Scheme_Object *do_make_future(int argc, Scheme_Object *argv[])
{
scheme_check_proc_arity("future", 0, 0, argc, argv);
@ -1244,7 +1262,7 @@ Scheme_Object *scheme_future(int argc, Scheme_Object *argv[])
if (SAME_TYPE(SCHEME_TYPE(proc), scheme_native_closure_type)
&& scheme_native_arity_check(proc, 0)
&& (((Scheme_Native_Closure *)proc)->code->start_code != scheme_on_demand_jit_code)
&& (((Scheme_Native_Closure *)proc)->code->max_let_depth < FUTURE_RUNSTACK_SIZE * sizeof(void*))) {
&& scheme_can_apply_native_in_future(proc)) {
/* try to alocate a future in the future thread */
future_t *ft;
ft = MALLOC_ONE_TAGGED(future_t);
@ -1255,7 +1273,6 @@ Scheme_Object *scheme_future(int argc, Scheme_Object *argv[])
ft->orig_lambda = proc;
ft->status = PENDING;
ft->cust = scheme_current_thread->current_ft->cust;
ft->code = ((Scheme_Native_Closure *)proc)->code->start_code;
mzrt_mutex_lock(fs->future_mutex);
ft->id = ++fs->next_futureid;
@ -1490,7 +1507,7 @@ Scheme_Object *scheme_fsemaphore_wait(int argc, Scheme_Object **argv)
fsemaphore_t *sema;
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
Scheme_Future_State *fs = scheme_future_state;
void *storage[3];
void *storage[4];
if (!SAME_TYPE(SCHEME_TYPE(argv[0]), scheme_fsemaphore_type)) {
SCHEME_WRONG_CONTRACT_MAYBE_IN_FT("fsemaphore-wait", "fsemaphore?", 0, argc, argv);
@ -1541,7 +1558,7 @@ Scheme_Object *scheme_fsemaphore_wait(int argc, Scheme_Object **argv)
/* Try to capture it locally (on this thread) */
if (GC_gen0_alloc_page_ptr
&& capture_future_continuation(fs, future, storage, 0)) {
&& capture_future_continuation(fs, future, storage, 0, 0)) {
/* capture sets fts->thread->current_ft to NULL */
mzrt_mutex_lock(fs->future_mutex);
} else {
@ -1759,12 +1776,13 @@ static Scheme_Object *shallower_apply_future_lw_k(void)
return apply_future_lw(ft);
}
static void future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, int what)
{
static int future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, int what)
{
mz_jmp_buf newbuf, * volatile savebuf;
Scheme_Thread *p = scheme_current_thread;
Scheme_Object * volatile retval;
future_t * volatile old_ft;
int done;
old_ft = p->current_ft;
p->current_ft = ft;
@ -1785,7 +1803,25 @@ static void future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, i
} else
retval = apply_future_lw(ft);
} else {
retval = scheme_apply_multi(ft->orig_lambda, 0, NULL);
if (ft->suspended_lw_stack) {
Scheme_Object *rator, **argv;
int argc;
Scheme_Lightweight_Continuation *lc;
rator = (Scheme_Object *)ft->suspended_lw_stack[2];
argc = SCHEME_INT_VAL((Scheme_Object *)ft->suspended_lw_stack[3]);
argv = (Scheme_Object **)ft->suspended_lw_stack[4];
ft->suspended_lw_stack[2] = NULL;
ft->suspended_lw_stack[4] = NULL;
lc = (Scheme_Lightweight_Continuation *)ft->suspended_lw_stack[1];
scheme_restore_lightweight_continuation_marks(lc);
if (ft->suspended_lw_stack[5])
retval = _scheme_apply_multi(rator, argc, argv);
else
retval = _scheme_apply(rator, argc, argv);
} else
retval = scheme_apply_multi(ft->orig_lambda, 0, NULL);
}
send_special_result(ft, retval);
}
@ -1796,17 +1832,27 @@ static void future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, i
ft->retval = retval;
mzrt_mutex_lock(fs->future_mutex);
ft->status = FINISHED;
trigger_added_touches(fs, ft);
mzrt_mutex_unlock(fs->future_mutex);
if (ft->suspended_lw_stack && retval) {
pop_suspended_lw(fs, ft);
done = 0;
} else {
if (!retval)
ft->suspended_lw_stack = NULL;
ft->status = FINISHED;
trigger_added_touches(fs, ft);
done = 1;
}
record_fevent(FEVENT_COMPLETE, ft->id);
mzrt_mutex_unlock(fs->future_mutex);
record_fevent(FEVENT_END_WORK, ft->id);
if (!retval) {
scheme_longjmp(*savebuf, 1);
}
return done;
}
static int prefer_to_apply_future_in_runtime()
@ -1851,18 +1897,21 @@ Scheme_Object *general_touch(int argc, Scheme_Object *argv[])
what = FEVENT_START_RTONLY_WORK;
} else if (ft->status != SUSPENDED) {
dequeue_future(fs, ft);
if (ft->suspended_lw_stack)
what = FEVENT_RESUME_WORK;
}
ft->status = RUNNING;
mzrt_mutex_unlock(fs->future_mutex);
if (ft->in_tracing_mode) {
run_would_be_future(ft);
retval = ft->retval;
break;
} else {
future_in_runtime(fs, ft, what);
if (future_in_runtime(fs, ft, what)) {
retval = ft->retval;
break;
}
}
retval = ft->retval;
break;
}
else if ((ft->status == RUNNING)
|| (ft->status == WAITING_FOR_FSEMA)
@ -1900,7 +1949,7 @@ Scheme_Object *general_touch(int argc, Scheme_Object *argv[])
ft->status = RUNNING;
/* may raise an exception or escape: */
mzrt_mutex_unlock(fs->future_mutex);
future_in_runtime(fs, ft, FEVENT_START_WORK);
(void)future_in_runtime(fs, ft, FEVENT_START_WORK);
} else {
/* Someone needs to handle the future. We're banking on some
future thread eventually picking up the future, which is
@ -2079,7 +2128,7 @@ void *worker_thread_future_loop(void *arg)
Scheme_Native_Proc *jitcode;
future_t *ft;
mz_jmp_buf newbuf;
int fid;
int fid, what;
scheme_future_state = fs;
scheme_future_thread_state = fts;
@ -2137,8 +2186,13 @@ void *worker_thread_future_loop(void *arg)
if (ft) {
fs->busy_thread_count++;
if (ft->suspended_lw_stack)
what = FEVENT_RESUME_WORK;
else
what = FEVENT_START_WORK;
fid = ft->id;
record_fevent(FEVENT_START_WORK, fid);
record_fevent(what, fid);
/* Work is available for this thread */
ft->status = RUNNING;
@ -2166,8 +2220,6 @@ void *worker_thread_future_loop(void *arg)
v = _apply_future_lw(ft);
}
} else {
jitcode = ft->code;
/* Run the code:
The lambda passed to a future will always be a parameterless
function.
@ -2182,8 +2234,30 @@ void *worker_thread_future_loop(void *arg)
/* failed or suspended */
v = NULL;
} else {
Scheme_Object *rator, **argv;
int argc;
if (ft->suspended_lw_stack) {
Scheme_Lightweight_Continuation *lc;
lc = (Scheme_Lightweight_Continuation *)ft->suspended_lw_stack[1];
scheme_restore_lightweight_continuation_marks(lc); /* might trigger GC */
ft = fts->thread->current_ft;
rator = (Scheme_Object *)ft->suspended_lw_stack[2];
argc = SCHEME_INT_VAL((Scheme_Object *)ft->suspended_lw_stack[3]);
argv = (Scheme_Object **)ft->suspended_lw_stack[4];
ft->suspended_lw_stack[2] = NULL;
ft->suspended_lw_stack[4] = NULL;
} else {
rator = ft->orig_lambda;
argc = 0;
argv = NULL;
}
scheme_fill_lwc_start();
v = scheme_call_as_lightweight_continuation(jitcode, ft->orig_lambda, 0, NULL);
jitcode = ((Scheme_Native_Closure *)rator)->code->start_code;
v = scheme_call_as_lightweight_continuation(jitcode, rator, argc, argv);
if (SAME_OBJ(v, SCHEME_TAIL_CALL_WAITING)) {
v = scheme_ts_scheme_force_value_same_mark(v);
}
@ -2205,15 +2279,29 @@ void *worker_thread_future_loop(void *arg)
if (ft->no_retval >= 0) {
/* Set the return val in the descriptor */
ft->retval = v;
/* In case of multiple values: */
send_special_result(ft, v);
/* Update the status */
ft->status = FINISHED;
trigger_added_touches(fs, ft);
if (ft->suspended_lw_stack) {
if (!ft->suspended_lw_stack[5] && SAME_OBJ(v, SCHEME_MULTIPLE_VALUES)) {
/* multiple results are not allowed; keep the same lw stack,
but replace the function to call: */
ft->status = PENDING_OVERSIZE;
ft->suspended_lw_stack[2] = bad_multi_result_proc;
ft->suspended_lw_stack[3] = scheme_make_integer(ft->multiple_count);
ft->suspended_lw_stack[4] = ft->multiple_array;
ft->retval_s = NULL;
ft->multiple_array = NULL;
} else
pop_suspended_lw(fs, ft);
} else {
/* Update the status */
ft->status = FINISHED;
trigger_added_touches(fs, ft);
}
record_fevent(FEVENT_COMPLETE, fid);
} else {
ft->suspended_lw_stack = NULL;
}
fts->thread->current_ft = NULL;
@ -2290,7 +2378,8 @@ static Scheme_Object *apply_future_lw(future_t *ft)
return (Scheme_Object *)scheme_top_level_do(apply_future_lw_k, 0);
}
static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, void **storage, int need_lock)
static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, void **storage,
int need_lock, int for_overflow)
XFORM_SKIP_PROC
/* The lock is *not* held when calling this function.
This function explicitly cooperates with the GC by storing the
@ -2300,13 +2389,23 @@ static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, vo
{
Scheme_Lightweight_Continuation *lw;
Scheme_Object **arg_S;
void **stack;
storage[2] = ft;
if (for_overflow) {
stack = MALLOC_N(void*, 6);
if (!stack) return 0;
storage[3] = stack;
ft = (future_t *)storage[2];
} else
stack = NULL;
lw = scheme_capture_lightweight_continuation(ft->fts->thread, ft->lwc, storage);
if (!lw) return 0;
ft = (future_t *)storage[2];
stack = (void **)storage[3];
if (need_lock) {
mzrt_mutex_lock(fs->future_mutex);
@ -2342,9 +2441,48 @@ static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, vo
ft->arg_S2 = arg_S;
}
if (for_overflow) {
stack[0] = ft->suspended_lw_stack;
stack[5] = ((for_overflow > 1) ? scheme_true : NULL);
ft->suspended_lw_stack = stack;
}
return 1;
}
static void push_suspended_lw(Scheme_Future_State *fs, future_t *ft)
XFORM_SKIP_PROC
/* called in any thread; needs lock */
{
ft->suspended_lw_stack[1] = ft->suspended_lw;
ft->suspended_lw = NULL;
ft->suspended_lw_stack[2] = ft->arg_s0;
ft->arg_s0 = NULL;
ft->suspended_lw_stack[3] = scheme_make_integer(ft->arg_i0);
ft->suspended_lw_stack[4] = ft->arg_S0;
ft->arg_S0 = NULL;
ft->status = PENDING;
(void)enqueue_future(fs, ft);
}
static void pop_suspended_lw(Scheme_Future_State *fs, future_t *ft)
XFORM_SKIP_PROC
/* called in any thread; needs lock */
{
ft->retval_s = ft->retval;
ft->retval = NULL;
ft->suspended_lw = (Scheme_Lightweight_Continuation *)ft->suspended_lw_stack[1];
ft->maybe_suspended_lw = 1;
ft->suspended_lw_stack = (void **)ft->suspended_lw_stack[0];
ft->status = PENDING;
(void)enqueue_future(fs, ft);
}
void scheme_check_future_work()
/* Called in the runtime thread by the scheduler */
{
@ -2448,14 +2586,21 @@ void scheme_check_future_work()
mzrt_mutex_unlock(fs->future_mutex);
if (ft) {
void *storage[3];
void *storage[4];
if (capture_future_continuation(fs, ft, storage, 1)) {
if (capture_future_continuation(fs, ft, storage, 1,
((ft->status == WAITING_FOR_OVERFLOW)
? ft->arg_i1
: 0))) {
/* capture performs mzrt_mutex_lock(fs->future_mutex) on success. */
if (ft->suspended_lw)
FUTURE_ASSERT((ft->status == WAITING_FOR_PRIM)
|| (ft->status == WAITING_FOR_FSEMA));
else
if (ft->suspended_lw) {
FUTURE_ASSERT((ft->status == WAITING_FOR_PRIM)
|| (ft->status == WAITING_FOR_FSEMA)
|| (ft->status == WAITING_FOR_OVERFLOW));
if (ft->status == WAITING_FOR_OVERFLOW) {
push_suspended_lw(fs, ft);
}
} else
FUTURE_ASSERT(ft->status != RUNNING);
mzrt_mutex_unlock(fs->future_mutex);
} else {
@ -2503,7 +2648,8 @@ void scheme_check_future_work()
static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
void *func,
int is_atomic,
int can_suspend)
int can_suspend,
int for_overflow)
XFORM_SKIP_PROC
/* Called in either future or runtime thread. Can only be called in the runtime thread
if we are in slow-path trace mode (i.e. we are running a future that is bound to the
@ -2511,7 +2657,7 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
{
future_t *future;
Scheme_Future_State *fs = scheme_future_state;
void *storage[3];
void *storage[4];
int insist_to_suspend, prefer_to_suspend, fid;
/* Fetch the future descriptor for this thread */
@ -2534,7 +2680,8 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
fid = future->id;
/* Policy question: When should the future thread suspend
/* If for_overflow, then a suspend is required. Otherwise...
Policy question: When should the future thread suspend
the current future? It costs something to suspend and
resume a future.
The current policy:
@ -2544,7 +2691,7 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
more work available in the future queue, and only if we
can suspend ourselves (because asking the runtime thread
to suspend wouldn't accomplish anything). */
insist_to_suspend = !is_atomic;
insist_to_suspend = !is_atomic || for_overflow;
prefer_to_suspend = (insist_to_suspend || fs->future_queue_count);
if (!scheme_custodian_is_available(future->cust)) {
@ -2559,7 +2706,7 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
if (prefer_to_suspend
&& GC_gen0_alloc_page_ptr
&& capture_future_continuation(fs, future, storage, 0)) {
&& capture_future_continuation(fs, future, storage, 0, for_overflow)) {
/* this future thread will suspend handling the future
continuation until the result of the blocking call is ready;
fts->thread->current_ft was set to NULL */
@ -2567,17 +2714,29 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
mzrt_mutex_lock(fs->future_mutex);
if (func == touch) {
if (for_overflow) {
record_fevent(FEVENT_OVERFLOW, fid);
} else if (func == touch) {
record_fevent(FEVENT_RTCALL_TOUCH, fid);
} else {
record_fevent(is_atomic ? FEVENT_RTCALL_ATOMIC : FEVENT_RTCALL, fid);
}
/* Set up the arguments for the runtime call
to be picked up by the main rt thread */
future->prim_func = func;
future->rt_prim_is_atomic = is_atomic;
future->status = WAITING_FOR_PRIM;
if (for_overflow) {
if (!fts->thread->current_ft) {
/* capture complete; re-enqueue so that it continues on fresh stack */
push_suspended_lw(fs, future);
} else {
future->status = WAITING_FOR_OVERFLOW;
future->arg_i1 = for_overflow;
}
} else {
/* Set up the arguments for the runtime call
to be picked up by the main rt thread */
future->prim_func = func;
future->rt_prim_is_atomic = is_atomic;
future->status = WAITING_FOR_PRIM;
}
if (is_atomic) {
future->next_waiting_atomic = fs->future_waiting_atomic;
@ -2594,6 +2753,8 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
future->in_queue_waiting_for_lwc = 1;
}
future->want_lw = 1;
/* In case of for_overflow, runtime thread is responsible for
enqueuing the future to continue. */
}
}
@ -2631,6 +2792,7 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
future = fts->thread->current_ft;
FUTURE_ASSERT(!future || !future->can_continue_sema);
FUTURE_ASSERT(!future || !for_overflow);
if (future) {
future->want_lw = 0;
@ -2644,7 +2806,8 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
future->status = RUNNING;
}
} else {
record_fevent(FEVENT_RTCALL_SUSPEND, fid);
if (!for_overflow)
record_fevent(FEVENT_RTCALL_SUSPEND, fid);
}
mzrt_mutex_unlock(fs->future_mutex);
@ -2661,6 +2824,12 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
}
}
static Scheme_Object *bad_multi_result(int argc, Scheme_Object **argv)
{
scheme_wrong_return_arity(NULL, 1, argc, argv, NULL);
return NULL;
}
/**********************************************************************/
/* Functions for primitive invocation */
/**********************************************************************/
@ -2680,7 +2849,7 @@ void scheme_wrong_contract_from_ft(const char *who, const char *expected_type, i
future->time_of_request = get_future_timestamp();
future->source_of_request = who;
future_do_runtimecall(fts, NULL, 0, 1);
future_do_runtimecall(fts, NULL, 0, 1, 0);
/* Fetch the future again, in case moved by a GC */
future = fts->thread->current_ft;
@ -2709,7 +2878,7 @@ Scheme_Object **scheme_rtcall_on_demand(Scheme_Object **argv)
future->source_of_request = "[jit_on_demand]";
future->source_type = FSRC_OTHER;
future_do_runtimecall(fts, NULL, 1, 1);
future_do_runtimecall(fts, NULL, 1, 1, 0);
/* Fetch the future again, in case moved by a GC */
future = fts->thread->current_ft;
@ -2743,7 +2912,7 @@ Scheme_Object *scheme_rtcall_make_fsemaphore(Scheme_Object *ready)
else
is_atomic = 0;
future_do_runtimecall(fts, NULL, is_atomic, 1);
future_do_runtimecall(fts, NULL, is_atomic, 1, 0);
/* Fetch the future again, in case moved by a GC */
future = fts->thread->current_ft;
@ -2774,7 +2943,7 @@ Scheme_Object *scheme_rtcall_make_future(Scheme_Object *proc)
future->source_of_request = "future";
future->source_type = FSRC_OTHER;
future_do_runtimecall(fts, NULL, is_atomic, 1);
future_do_runtimecall(fts, NULL, is_atomic, 1, 0);
/* Fetch the future again, in case moved by a GC */
future = fts->thread->current_ft;
@ -2801,7 +2970,7 @@ void scheme_rtcall_allocate_values(int count, Scheme_Thread *t)
future->source_of_request = "[allocate_values]";
future->source_type = FSRC_OTHER;
future_do_runtimecall(fts, NULL, 1, 0);
future_do_runtimecall(fts, NULL, 1, 0, 0);
/* Fetch the future again, in case moved by a GC */
future = fts->thread->current_ft;
@ -2827,7 +2996,43 @@ Scheme_Object *scheme_rtcall_tail_apply(Scheme_Object *rator, int argc, Scheme_O
future->source_of_request = "[tail-call]";
future->source_type = FSRC_OTHER;
future_do_runtimecall(fts, NULL, 1, 0);
future_do_runtimecall(fts, NULL, 1, 0, 0);
/* Fetch the future again, in case moved by a GC */
future = fts->thread->current_ft;
future->arg_s0 = NULL;
future->arg_S0 = NULL;
retval = future->retval_s;
future->retval_s = NULL;
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object *scheme_rtcall_apply_with_new_stack(Scheme_Object *rator, int argc, Scheme_Object **argv,
int multi)
XFORM_SKIP_PROC
/* Called in future thread; rator is a native closure with a runstack limit that fits */
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
future_t *future = fts->thread->current_ft;
Scheme_Object *retval;
future->prim_protocol = SIG_APPLY_AFRESH;
future->arg_s0 = rator;
future->arg_i0 = argc;
future->arg_S0 = argv;
future->arg_i1 = multi;
future->time_of_request = get_future_timestamp();
future->source_of_request = "[stack-overflow]";
future->source_type = FSRC_OTHER;
future_do_runtimecall(fts, NULL, 1, 1, (multi ? 2 : 1));
/* Fetch the future again, in case moved by a GC */
future = fts->thread->current_ft;
@ -2883,7 +3088,7 @@ uintptr_t scheme_rtcall_alloc()
future->prim_protocol = SIG_ALLOC;
future->arg_i0 = fts->gen0_size;
future_do_runtimecall(fts, NULL, 1, 0);
future_do_runtimecall(fts, NULL, 1, 0, 0);
future = fts->thread->current_ft;
retval = future->alloc_retval;
@ -2919,7 +3124,7 @@ void scheme_rtcall_new_mark_segment(Scheme_Thread *p)
future->prim_protocol = SIG_ALLOC_MARK_SEGMENT;
future->arg_s0 = (Scheme_Object *)p;
future_do_runtimecall(fts, NULL, 1, 0);
future_do_runtimecall(fts, NULL, 1, 0, 0);
}
static int push_marks(future_t *f, Scheme_Cont_Frame_Data *d)
@ -3033,7 +3238,7 @@ static void do_invoke_rtcall(Scheme_Future_State *fs, future_t *future)
flush_future_logs(fs);
/* use lg_future_event so we can include `str' in the message: */
/* use log_future_event so we can include `str' in the message: */
log_future_event(fs,
"future %d, process %d: %s: %s; time: %f",
src,
@ -3153,6 +3358,28 @@ static void do_invoke_rtcall(Scheme_Future_State *fs, future_t *future)
/* doesn't return */
break;
}
case SIG_APPLY_AFRESH:
{
GC_CAN_IGNORE Scheme_Object *arg_s0 = future->arg_s0;
GC_CAN_IGNORE Scheme_Object **arg_S0 = future->arg_S0;
GC_CAN_IGNORE Scheme_Object *retval;
/* This code is used only for would-be futures: */
FUTURE_ASSERT(future->in_tracing_mode);
future->arg_s0 = NULL;
future->arg_S0 = NULL;
if (future->arg_i1)
retval = _scheme_apply_multi(arg_s0, future->arg_i0, arg_S0);
else
retval = _scheme_apply(arg_s0, future->arg_i0, arg_S0);
future->retval_s = retval;
send_special_result(future, retval);
break;
}
# define JIT_TS_LOCALIZE(t, f) GC_CAN_IGNORE t f = future->f

View File

@ -8,14 +8,27 @@ typedef Scheme_Object* (*prim_int_pobj_obj_t)(int, Scheme_Object**);
typedef Scheme_Object* (*prim_int_pobj_obj_obj_t)(int, Scheme_Object**, Scheme_Object*);
typedef void* (*prim_pvoid_pvoid_pvoid_t)(void*, void*);
/* PENDING is ready to run: */
#define PENDING 0
/* RUNNING is running in some thread: */
#define RUNNING 1
/* WAITING_FOR_PRIM is waiting for the runtime thread to start runnin
a primitive -- possibiliy atomic, possibly not, and possibly a LWC
capture happens while waiting: */
#define WAITING_FOR_PRIM 2
/* FINISHED means the result (or failure) is ready: */
#define FINISHED 3
/* PENDING is ready to run, but won't work in a future thread: */
#define PENDING_OVERSIZE 4
/* WAITING_FOR_PRIM is the runtime thread working on a primitive: */
#define HANDLING_PRIM 5
/* WAITING_FOR_FSEMA is in the queue of an fsemaphore: */
#define WAITING_FOR_FSEMA 6
/* SUSPENDED is the owning custodian is gone, so the future will never finish: */
#define SUSPENDED 7
/* WAITING_FOR_OVERFLOW is waiting for an LCW capture to continue
for a stack overflow: */
#define WAITING_FOR_OVERFLOW 8
/* FSRC_OTHER means: descriptive string is provided for logging,
called function *DOES NOT NEED* to lookup continuation marks. */
@ -88,7 +101,6 @@ typedef struct future_t {
that case */
Scheme_Object *orig_lambda;
void *code;
Scheme_Custodian *cust; /* an approximate custodian; don't use a future
thread if this custodian is shut down */
@ -178,6 +190,8 @@ typedef struct future_t {
extra flag avoids spinning if the suspended continuation
cannot be resumed in the main thread for some reason */
void **suspended_lw_stack; /* for overflow handling */
Scheme_Object *retval_s;
void *retval_p; /* use only with conservative GC */
MZ_MARK_STACK_TYPE retval_m;
@ -228,6 +242,7 @@ typedef struct fsemaphore_t {
#define SIG_FUTURE 6
#define SIG_WRONG_TYPE_EXN 7
#define SIG_TAIL_APPLY 8
#define SIG_APPLY_AFRESH 9
# include "jit_ts_protos.h"
@ -240,6 +255,9 @@ extern void scheme_rtcall_allocate_values(int count, Scheme_Thread *t);
extern Scheme_Object *scheme_rtcall_make_fsemaphore(Scheme_Object *ready);
extern Scheme_Object *scheme_rtcall_make_future(Scheme_Object *proc);
extern Scheme_Object *scheme_rtcall_tail_apply(Scheme_Object *rator, int argc, Scheme_Object **argv);
extern Scheme_Object *scheme_rtcall_apply_with_new_stack(Scheme_Object *rator, int argc, Scheme_Object **argv, int multi);
int scheme_can_apply_native_in_future(Scheme_Object *proc);
void scheme_future_block_until_gc();
void scheme_future_continue_after_gc();

View File

@ -98,7 +98,7 @@
@string-append{ future->arg_@|(string t)|@|(number->string i)| = @|a|;})
"\n")
@(if (equal? arg-types '("Scheme_Object*")) @string-append{send_special_result(future, @(car arg-names));} "")
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@(if (string=? result-type "void") "" @string-append{retval = @|fretval|;})

View File

@ -1,38 +1,38 @@
#define define_ts_siS_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object* g5, int g6, Scheme_Object** g7) \
static Scheme_Object* ts_ ## id(Scheme_Object* g7, int g8, Scheme_Object** g9) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_siS_s("[" #id "]", src_type, id, g5, g6, g7); \
return scheme_rtcall_siS_s("[" #id "]", src_type, id, g7, g8, g9); \
else \
return id(g5, g6, g7); \
return id(g7, g8, g9); \
}
#define define_ts_iSs_s(id, src_type) \
static Scheme_Object* ts_ ## id(int g8, Scheme_Object** g9, Scheme_Object* g10) \
static Scheme_Object* ts_ ## id(int g10, Scheme_Object** g11, Scheme_Object* g12) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_iSs_s("[" #id "]", src_type, id, g8, g9, g10); \
return scheme_rtcall_iSs_s("[" #id "]", src_type, id, g10, g11, g12); \
else \
return id(g8, g9, g10); \
return id(g10, g11, g12); \
}
#define define_ts_s_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object* g11) \
static Scheme_Object* ts_ ## id(Scheme_Object* g13) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_s_s("[" #id "]", src_type, id, g11); \
return scheme_rtcall_s_s("[" #id "]", src_type, id, g13); \
else \
return id(g11); \
return id(g13); \
}
#define define_ts_n_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Native_Closure_Data* g12) \
static Scheme_Object* ts_ ## id(Scheme_Native_Closure_Data* g14) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_n_s("[" #id "]", src_type, id, g12); \
return scheme_rtcall_n_s("[" #id "]", src_type, id, g14); \
else \
return id(g12); \
return id(g14); \
}
#define define_ts__s(id, src_type) \
static Scheme_Object* ts_ ## id() \
@ -44,200 +44,200 @@ static Scheme_Object* ts_ ## id() \
return id(); \
}
#define define_ts_ss_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object* g13, Scheme_Object* g14) \
static Scheme_Object* ts_ ## id(Scheme_Object* g15, Scheme_Object* g16) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_ss_s("[" #id "]", src_type, id, g13, g14); \
return scheme_rtcall_ss_s("[" #id "]", src_type, id, g15, g16); \
else \
return id(g13, g14); \
return id(g15, g16); \
}
#define define_ts_ssi_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object* g15, Scheme_Object* g16, int g17) \
static Scheme_Object* ts_ ## id(Scheme_Object* g17, Scheme_Object* g18, int g19) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_ssi_s("[" #id "]", src_type, id, g15, g16, g17); \
return scheme_rtcall_ssi_s("[" #id "]", src_type, id, g17, g18, g19); \
else \
return id(g15, g16, g17); \
return id(g17, g18, g19); \
}
#define define_ts_tt_s(id, src_type) \
static Scheme_Object* ts_ ## id(const Scheme_Object* g18, const Scheme_Object* g19) \
static Scheme_Object* ts_ ## id(const Scheme_Object* g20, const Scheme_Object* g21) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_tt_s("[" #id "]", src_type, id, g18, g19); \
else \
return id(g18, g19); \
}
#define define_ts_ss_m(id, src_type) \
static MZ_MARK_STACK_TYPE ts_ ## id(Scheme_Object* g20, Scheme_Object* g21) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_ss_m("[" #id "]", src_type, id, g20, g21); \
return scheme_rtcall_tt_s("[" #id "]", src_type, id, g20, g21); \
else \
return id(g20, g21); \
}
#define define_ts_Sl_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object** g22, intptr_t g23) \
#define define_ts_ss_m(id, src_type) \
static MZ_MARK_STACK_TYPE ts_ ## id(Scheme_Object* g22, Scheme_Object* g23) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_Sl_s("[" #id "]", src_type, id, g22, g23); \
return scheme_rtcall_ss_m("[" #id "]", src_type, id, g22, g23); \
else \
return id(g22, g23); \
}
#define define_ts_l_s(id, src_type) \
static Scheme_Object* ts_ ## id(intptr_t g24) \
#define define_ts_Sl_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object** g24, intptr_t g25) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_l_s("[" #id "]", src_type, id, g24); \
return scheme_rtcall_Sl_s("[" #id "]", src_type, id, g24, g25); \
else \
return id(g24); \
return id(g24, g25); \
}
#define define_ts_l_s(id, src_type) \
static Scheme_Object* ts_ ## id(intptr_t g26) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_l_s("[" #id "]", src_type, id, g26); \
else \
return id(g26); \
}
#define define_ts_bsi_v(id, src_type) \
static void ts_ ## id(Scheme_Bucket* g25, Scheme_Object* g26, int g27) \
static void ts_ ## id(Scheme_Bucket* g27, Scheme_Object* g28, int g29) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_bsi_v("[" #id "]", src_type, id, g25, g26, g27); \
scheme_rtcall_bsi_v("[" #id "]", src_type, id, g27, g28, g29); \
else \
id(g25, g26, g27); \
id(g27, g28, g29); \
}
#define define_ts_iiS_v(id, src_type) \
static void ts_ ## id(int g28, int g29, Scheme_Object** g30) \
static void ts_ ## id(int g30, int g31, Scheme_Object** g32) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_iiS_v("[" #id "]", src_type, id, g28, g29, g30); \
scheme_rtcall_iiS_v("[" #id "]", src_type, id, g30, g31, g32); \
else \
id(g28, g29, g30); \
id(g30, g31, g32); \
}
#define define_ts_ss_v(id, src_type) \
static void ts_ ## id(Scheme_Object* g31, Scheme_Object* g32) \
static void ts_ ## id(Scheme_Object* g33, Scheme_Object* g34) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_ss_v("[" #id "]", src_type, id, g31, g32); \
scheme_rtcall_ss_v("[" #id "]", src_type, id, g33, g34); \
else \
id(g31, g32); \
id(g33, g34); \
}
#define define_ts_b_v(id, src_type) \
static void ts_ ## id(Scheme_Bucket* g33) \
static void ts_ ## id(Scheme_Bucket* g35) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_b_v("[" #id "]", src_type, id, g33); \
scheme_rtcall_b_v("[" #id "]", src_type, id, g35); \
else \
id(g33); \
id(g35); \
}
#define define_ts_sl_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object* g34, intptr_t g35) \
static Scheme_Object* ts_ ## id(Scheme_Object* g36, intptr_t g37) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_sl_s("[" #id "]", src_type, id, g34, g35); \
else \
return id(g34, g35); \
}
#define define_ts_iS_s(id, src_type) \
static Scheme_Object* ts_ ## id(int g36, Scheme_Object** g37) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_iS_s("[" #id "]", src_type, id, g36, g37); \
return scheme_rtcall_sl_s("[" #id "]", src_type, id, g36, g37); \
else \
return id(g36, g37); \
}
#define define_ts_S_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object** g38) \
#define define_ts_iS_s(id, src_type) \
static Scheme_Object* ts_ ## id(int g38, Scheme_Object** g39) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_S_s("[" #id "]", src_type, id, g38); \
return scheme_rtcall_iS_s("[" #id "]", src_type, id, g38, g39); \
else \
return id(g38); \
return id(g38, g39); \
}
#define define_ts_S_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object** g40) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_S_s("[" #id "]", src_type, id, g40); \
else \
return id(g40); \
}
#define define_ts_s_v(id, src_type) \
static void ts_ ## id(Scheme_Object* g39) \
static void ts_ ## id(Scheme_Object* g41) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_s_v("[" #id "]", src_type, id, g39); \
scheme_rtcall_s_v("[" #id "]", src_type, id, g41); \
else \
id(g39); \
id(g41); \
}
#define define_ts_iSi_s(id, src_type) \
static Scheme_Object* ts_ ## id(int g40, Scheme_Object** g41, int g42) \
static Scheme_Object* ts_ ## id(int g42, Scheme_Object** g43, int g44) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_iSi_s("[" #id "]", src_type, id, g40, g41, g42); \
return scheme_rtcall_iSi_s("[" #id "]", src_type, id, g42, g43, g44); \
else \
return id(g40, g41, g42); \
return id(g42, g43, g44); \
}
#define define_ts_siS_v(id, src_type) \
static void ts_ ## id(Scheme_Object* g43, int g44, Scheme_Object** g45) \
static void ts_ ## id(Scheme_Object* g45, int g46, Scheme_Object** g47) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_siS_v("[" #id "]", src_type, id, g43, g44, g45); \
scheme_rtcall_siS_v("[" #id "]", src_type, id, g45, g46, g47); \
else \
id(g43, g44, g45); \
id(g45, g46, g47); \
}
#define define_ts_z_p(id, src_type) \
static void* ts_ ## id(size_t g46) \
static void* ts_ ## id(size_t g48) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_z_p("[" #id "]", src_type, id, g46); \
return scheme_rtcall_z_p("[" #id "]", src_type, id, g48); \
else \
return id(g46); \
return id(g48); \
}
#define define_ts_si_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object* g47, int g48) \
static Scheme_Object* ts_ ## id(Scheme_Object* g49, int g50) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_si_s("[" #id "]", src_type, id, g47, g48); \
return scheme_rtcall_si_s("[" #id "]", src_type, id, g49, g50); \
else \
return id(g47, g48); \
return id(g49, g50); \
}
#define define_ts_sis_v(id, src_type) \
static void ts_ ## id(Scheme_Object* g49, int g50, Scheme_Object* g51) \
static void ts_ ## id(Scheme_Object* g51, int g52, Scheme_Object* g53) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_sis_v("[" #id "]", src_type, id, g49, g50, g51); \
scheme_rtcall_sis_v("[" #id "]", src_type, id, g51, g52, g53); \
else \
id(g49, g50, g51); \
id(g51, g52, g53); \
}
#define define_ts_ss_i(id, src_type) \
static int ts_ ## id(Scheme_Object* g52, Scheme_Object* g53) \
static int ts_ ## id(Scheme_Object* g54, Scheme_Object* g55) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_ss_i("[" #id "]", src_type, id, g52, g53); \
return scheme_rtcall_ss_i("[" #id "]", src_type, id, g54, g55); \
else \
return id(g52, g53); \
return id(g54, g55); \
}
#define define_ts_iSp_v(id, src_type) \
static void ts_ ## id(int g54, Scheme_Object** g55, void* g56) \
static void ts_ ## id(int g56, Scheme_Object** g57, void* g58) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
scheme_rtcall_iSp_v("[" #id "]", src_type, id, g54, g55, g56); \
scheme_rtcall_iSp_v("[" #id "]", src_type, id, g56, g57, g58); \
else \
id(g54, g55, g56); \
id(g56, g57, g58); \
}
#define define_ts_sss_s(id, src_type) \
static Scheme_Object* ts_ ## id(Scheme_Object* g57, Scheme_Object* g58, Scheme_Object* g59) \
static Scheme_Object* ts_ ## id(Scheme_Object* g59, Scheme_Object* g60, Scheme_Object* g61) \
XFORM_SKIP_PROC \
{ \
if (scheme_use_rtcall) \
return scheme_rtcall_sss_s("[" #id "]", src_type, id, g57, g58, g59); \
return scheme_rtcall_sss_s("[" #id "]", src_type, id, g59, g60, g61); \
else \
return id(g57, g58, g59); \
return id(g59, g60, g61); \
}

View File

@ -1,4 +1,4 @@
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g60, int g61, Scheme_Object** g62)
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g62, int g63, Scheme_Object** g64)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -13,11 +13,11 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g60;
future->arg_i1 = g61;
future->arg_S2 = g62;
future->arg_s0 = g62;
future->arg_i1 = g63;
future->arg_S2 = g64;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -25,7 +25,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g63, Scheme_Object** g64, Scheme_Object* g65)
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g65, Scheme_Object** g66, Scheme_Object* g67)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -40,11 +40,11 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g63;
future->arg_S1 = g64;
future->arg_s2 = g65;
future->arg_i0 = g65;
future->arg_S1 = g66;
future->arg_s2 = g67;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -52,7 +52,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g66)
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g68)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -67,9 +67,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g66;
send_special_result(future, g66);
future_do_runtimecall(fts, (void*)f, 0, 1);
future->arg_s0 = g68;
send_special_result(future, g68);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -77,7 +77,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Closure_Data* g67)
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Closure_Data* g69)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -92,9 +92,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_n0 = g67;
future->arg_n0 = g69;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -119,7 +119,7 @@
future->source_type = src_type;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -127,7 +127,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g68, Scheme_Object* g69)
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g70, Scheme_Object* g71)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -142,10 +142,10 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g68;
future->arg_s1 = g69;
future->arg_s0 = g70;
future->arg_s1 = g71;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -153,7 +153,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g70, Scheme_Object* g71, int g72)
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g72, Scheme_Object* g73, int g74)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -168,11 +168,11 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g70;
future->arg_s1 = g71;
future->arg_i2 = g72;
future->arg_s0 = g72;
future->arg_s1 = g73;
future->arg_i2 = g74;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -180,7 +180,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g73, const Scheme_Object* g74)
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g75, const Scheme_Object* g76)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -195,10 +195,10 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_t0 = g73;
future->arg_t1 = g74;
future->arg_t0 = g75;
future->arg_t1 = g76;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -206,7 +206,7 @@
receive_special_result(future, retval, 1);
return retval;
}
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g75, Scheme_Object* g76)
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g77, Scheme_Object* g78)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -221,10 +221,10 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g75;
future->arg_s1 = g76;
future->arg_s0 = g77;
future->arg_s1 = g78;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_m;
@ -232,7 +232,7 @@
return retval;
}
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g77, intptr_t g78)
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g79, intptr_t g80)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -247,10 +247,10 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_S0 = g77;
future->arg_l1 = g78;
future->arg_S0 = g79;
future->arg_l1 = g80;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -258,7 +258,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g79)
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g81)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -273,9 +273,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_l0 = g79;
future->arg_l0 = g81;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -283,7 +283,7 @@
receive_special_result(future, retval, 1);
return retval;
}
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g80, Scheme_Object* g81, int g82)
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g82, Scheme_Object* g83, int g84)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -298,11 +298,11 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_b0 = g80;
future->arg_s1 = g81;
future->arg_i2 = g82;
future->arg_b0 = g82;
future->arg_s1 = g83;
future->arg_i2 = g84;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@ -310,7 +310,7 @@
}
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g83, int g84, Scheme_Object** g85)
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g85, int g86, Scheme_Object** g87)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -325,11 +325,11 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g83;
future->arg_i1 = g84;
future->arg_S2 = g85;
future->arg_i0 = g85;
future->arg_i1 = g86;
future->arg_S2 = g87;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@ -337,7 +337,7 @@
}
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g86, Scheme_Object* g87)
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g88, Scheme_Object* g89)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -352,10 +352,10 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g86;
future->arg_s1 = g87;
future->arg_s0 = g88;
future->arg_s1 = g89;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@ -363,7 +363,7 @@
}
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g88)
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g90)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -378,9 +378,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_b0 = g88;
future->arg_b0 = g90;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@ -388,7 +388,7 @@
}
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g89, intptr_t g90)
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g91, intptr_t g92)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -403,10 +403,10 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g89;
future->arg_l1 = g90;
future->arg_s0 = g91;
future->arg_l1 = g92;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -414,7 +414,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g91, Scheme_Object** g92)
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g93, Scheme_Object** g94)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -429,10 +429,10 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g91;
future->arg_S1 = g92;
future->arg_i0 = g93;
future->arg_S1 = g94;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -440,7 +440,7 @@
receive_special_result(future, retval, 1);
return retval;
}
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g93)
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g95)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -455,9 +455,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_S0 = g93;
future->arg_S0 = g95;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -465,7 +465,7 @@
receive_special_result(future, retval, 1);
return retval;
}
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g94)
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g96)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -480,9 +480,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g94;
send_special_result(future, g94);
future_do_runtimecall(fts, (void*)f, 0, 1);
future->arg_s0 = g96;
send_special_result(future, g96);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@ -490,7 +490,7 @@
}
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g95, Scheme_Object** g96, int g97)
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g97, Scheme_Object** g98, int g99)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -505,11 +505,11 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g95;
future->arg_S1 = g96;
future->arg_i2 = g97;
future->arg_i0 = g97;
future->arg_S1 = g98;
future->arg_i2 = g99;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -517,7 +517,7 @@
receive_special_result(future, retval, 1);
return retval;
}
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g98, int g99, Scheme_Object** g100)
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g100, int g101, Scheme_Object** g102)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -532,11 +532,11 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g98;
future->arg_i1 = g99;
future->arg_S2 = g100;
future->arg_s0 = g100;
future->arg_i1 = g101;
future->arg_S2 = g102;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@ -544,7 +544,7 @@
}
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g101)
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g103)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -559,9 +559,9 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_z0 = g101;
future->arg_z0 = g103;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_p;
@ -569,7 +569,7 @@
return retval;
}
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g102, int g103)
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g104, int g105)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -584,10 +584,10 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g102;
future->arg_i1 = g103;
future->arg_s0 = g104;
future->arg_i1 = g105;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;
@ -595,7 +595,7 @@
receive_special_result(future, retval, 1);
return retval;
}
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g104, int g105, Scheme_Object* g106)
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g106, int g107, Scheme_Object* g108)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -610,11 +610,11 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g104;
future->arg_i1 = g105;
future->arg_s2 = g106;
future->arg_s0 = g106;
future->arg_i1 = g107;
future->arg_s2 = g108;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@ -622,7 +622,7 @@
}
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g107, Scheme_Object* g108)
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g109, Scheme_Object* g110)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -637,10 +637,10 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g107;
future->arg_s1 = g108;
future->arg_s0 = g109;
future->arg_s1 = g110;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_i;
@ -648,7 +648,7 @@
return retval;
}
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g109, Scheme_Object** g110, void* g111)
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g111, Scheme_Object** g112, void* g113)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -663,11 +663,11 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_i0 = g109;
future->arg_S1 = g110;
future->arg_p2 = g111;
future->arg_i0 = g111;
future->arg_S1 = g112;
future->arg_p2 = g113;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
@ -675,7 +675,7 @@
}
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g112, Scheme_Object* g113, Scheme_Object* g114)
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g114, Scheme_Object* g115, Scheme_Object* g116)
XFORM_SKIP_PROC
{
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
@ -690,11 +690,11 @@
future->time_of_request = tm;
future->source_of_request = who;
future->source_type = src_type;
future->arg_s0 = g112;
future->arg_s1 = g113;
future->arg_s2 = g114;
future->arg_s0 = g114;
future->arg_s1 = g115;
future->arg_s2 = g116;
future_do_runtimecall(fts, (void*)f, 0, 1);
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
fts->thread = scheme_current_thread;
future = fts->thread->current_ft;
retval = future->retval_s;

View File

@ -1,81 +1,81 @@
#define SIG_siS_s 10
typedef Scheme_Object* (*prim_siS_s)(Scheme_Object*, int, Scheme_Object**);
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g170, int g171, Scheme_Object** g172);
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g172, int g173, Scheme_Object** g174);
#define SIG_iSs_s 11
typedef Scheme_Object* (*prim_iSs_s)(int, Scheme_Object**, Scheme_Object*);
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g173, Scheme_Object** g174, Scheme_Object* g175);
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g175, Scheme_Object** g176, Scheme_Object* g177);
#define SIG_s_s 12
typedef Scheme_Object* (*prim_s_s)(Scheme_Object*);
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g176);
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g178);
#define SIG_n_s 13
typedef Scheme_Object* (*prim_n_s)(Scheme_Native_Closure_Data*);
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Closure_Data* g177);
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Closure_Data* g179);
#define SIG__s 14
typedef Scheme_Object* (*prim__s)();
Scheme_Object* scheme_rtcall__s(const char *who, int src_type, prim__s f );
#define SIG_ss_s 15
typedef Scheme_Object* (*prim_ss_s)(Scheme_Object*, Scheme_Object*);
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g178, Scheme_Object* g179);
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g180, Scheme_Object* g181);
#define SIG_ssi_s 16
typedef Scheme_Object* (*prim_ssi_s)(Scheme_Object*, Scheme_Object*, int);
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g180, Scheme_Object* g181, int g182);
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g182, Scheme_Object* g183, int g184);
#define SIG_tt_s 17
typedef Scheme_Object* (*prim_tt_s)(const Scheme_Object*, const Scheme_Object*);
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g183, const Scheme_Object* g184);
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g185, const Scheme_Object* g186);
#define SIG_ss_m 18
typedef MZ_MARK_STACK_TYPE (*prim_ss_m)(Scheme_Object*, Scheme_Object*);
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g185, Scheme_Object* g186);
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g187, Scheme_Object* g188);
#define SIG_Sl_s 19
typedef Scheme_Object* (*prim_Sl_s)(Scheme_Object**, intptr_t);
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g187, intptr_t g188);
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g189, intptr_t g190);
#define SIG_l_s 20
typedef Scheme_Object* (*prim_l_s)(intptr_t);
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g189);
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g191);
#define SIG_bsi_v 21
typedef void (*prim_bsi_v)(Scheme_Bucket*, Scheme_Object*, int);
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g190, Scheme_Object* g191, int g192);
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g192, Scheme_Object* g193, int g194);
#define SIG_iiS_v 22
typedef void (*prim_iiS_v)(int, int, Scheme_Object**);
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g193, int g194, Scheme_Object** g195);
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g195, int g196, Scheme_Object** g197);
#define SIG_ss_v 23
typedef void (*prim_ss_v)(Scheme_Object*, Scheme_Object*);
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g196, Scheme_Object* g197);
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g198, Scheme_Object* g199);
#define SIG_b_v 24
typedef void (*prim_b_v)(Scheme_Bucket*);
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g198);
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g200);
#define SIG_sl_s 25
typedef Scheme_Object* (*prim_sl_s)(Scheme_Object*, intptr_t);
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g199, intptr_t g200);
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g201, intptr_t g202);
#define SIG_iS_s 26
typedef Scheme_Object* (*prim_iS_s)(int, Scheme_Object**);
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g201, Scheme_Object** g202);
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g203, Scheme_Object** g204);
#define SIG_S_s 27
typedef Scheme_Object* (*prim_S_s)(Scheme_Object**);
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g203);
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g205);
#define SIG_s_v 28
typedef void (*prim_s_v)(Scheme_Object*);
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g204);
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g206);
#define SIG_iSi_s 29
typedef Scheme_Object* (*prim_iSi_s)(int, Scheme_Object**, int);
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g205, Scheme_Object** g206, int g207);
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g207, Scheme_Object** g208, int g209);
#define SIG_siS_v 30
typedef void (*prim_siS_v)(Scheme_Object*, int, Scheme_Object**);
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g208, int g209, Scheme_Object** g210);
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g210, int g211, Scheme_Object** g212);
#define SIG_z_p 31
typedef void* (*prim_z_p)(size_t);
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g211);
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g213);
#define SIG_si_s 32
typedef Scheme_Object* (*prim_si_s)(Scheme_Object*, int);
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g212, int g213);
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g214, int g215);
#define SIG_sis_v 33
typedef void (*prim_sis_v)(Scheme_Object*, int, Scheme_Object*);
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g214, int g215, Scheme_Object* g216);
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g216, int g217, Scheme_Object* g218);
#define SIG_ss_i 34
typedef int (*prim_ss_i)(Scheme_Object*, Scheme_Object*);
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g217, Scheme_Object* g218);
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g219, Scheme_Object* g220);
#define SIG_iSp_v 35
typedef void (*prim_iSp_v)(int, Scheme_Object**, void*);
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g219, Scheme_Object** g220, void* g221);
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g221, Scheme_Object** g222, void* g223);
#define SIG_sss_s 36
typedef Scheme_Object* (*prim_sss_s)(Scheme_Object*, Scheme_Object*, Scheme_Object*);
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g222, Scheme_Object* g223, Scheme_Object* g224);
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g224, Scheme_Object* g225, Scheme_Object* g226);

View File

@ -199,6 +199,45 @@ static Scheme_Object *_scheme_tail_apply_from_native_fixup_args(Scheme_Object *r
return ts__scheme_tail_apply_from_native(rator, argc + already, base);
}
#if defined(MZ_USE_FUTURES) && defined(MZ_PRECISE_GC)
static Scheme_Object *try_future_local_stack_overflow(Scheme_Object *rator, int argc, Scheme_Object **argv, int multi)
XFORM_SKIP_PROC
{
if (SAME_TYPE(SCHEME_TYPE(rator), scheme_native_closure_type)
&& scheme_can_apply_native_in_future(rator)) {
/* the only reason to get here is stack overflow,
either for the runstack or C stack */
return scheme_rtcall_apply_with_new_stack(rator, argc, argv, multi);
} else if (multi)
return ts__scheme_apply_multi_from_native(rator, argc, argv);
else
return ts__scheme_apply_from_native(rator, argc, argv);
}
static Scheme_Object *x_ts__scheme_apply_multi_from_native(Scheme_Object *rator, int argc, Scheme_Object **argv)
XFORM_SKIP_PROC
{
if (scheme_use_rtcall)
return try_future_local_stack_overflow(rator, argc, argv, 1);
else
return _scheme_apply_multi_from_native(rator, argc, argv);
}
static Scheme_Object *x_ts__scheme_apply_from_native(Scheme_Object *rator, int argc, Scheme_Object **argv)
XFORM_SKIP_PROC
{
if (scheme_use_rtcall)
return try_future_local_stack_overflow(rator, argc, argv, 0);
else
return _scheme_apply_from_native(rator, argc, argv);
}
#else
# define x_ts__scheme_apply_multi_from_native ts__scheme_apply_multi_from_native
# define x_ts__scheme_apply_from_native ts__scheme_apply_from_native
#endif
static int generate_pause_for_gc_and_retry(mz_jit_state *jitter,
int in_short_jumps,
int gc_reg, /* must not be JIT_R1 */
@ -913,9 +952,9 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc
jit_pusharg_p(JIT_V1);
if (num_rands < 0) { jit_movr_p(JIT_V1, JIT_R0); } /* save argc to manually pop runstack */
if (multi_ok) {
(void)mz_finish_lwe(ts__scheme_apply_multi_from_native, refrts);
(void)mz_finish_lwe(x_ts__scheme_apply_multi_from_native, refrts);
} else {
(void)mz_finish_lwe(ts__scheme_apply_from_native, refrts);
(void)mz_finish_lwe(x_ts__scheme_apply_from_native, refrts);
}
CHECK_LIMIT();
mz_patch_ucbranch(ref5);

View File

@ -33,6 +33,7 @@ static int future_MARK(void *p, struct NewGC *gc) {
gcMARK2(f->next_waiting_lwc, gc);
gcMARK2(f->next_waiting_touch, gc);
gcMARK2(f->suspended_lw, gc);
gcMARK2(f->suspended_lw_stack, gc);
gcMARK2(f->prev_in_fsema_queue, gc);
gcMARK2(f->next_in_fsema_queue, gc);
gcMARK2(f->touching, gc);
@ -66,6 +67,7 @@ static int future_FIXUP(void *p, struct NewGC *gc) {
gcFIXUP2(f->next_waiting_lwc, gc);
gcFIXUP2(f->next_waiting_touch, gc);
gcFIXUP2(f->suspended_lw, gc);
gcFIXUP2(f->suspended_lw_stack, gc);
gcFIXUP2(f->prev_in_fsema_queue, gc);
gcFIXUP2(f->next_in_fsema_queue, gc);
gcFIXUP2(f->touching, gc);

View File

@ -2474,6 +2474,7 @@ future {
gcMARK2(f->next_waiting_lwc, gc);
gcMARK2(f->next_waiting_touch, gc);
gcMARK2(f->suspended_lw, gc);
gcMARK2(f->suspended_lw_stack, gc);
gcMARK2(f->prev_in_fsema_queue, gc);
gcMARK2(f->next_in_fsema_queue, gc);
gcMARK2(f->touching, gc);

View File

@ -2457,6 +2457,8 @@ Scheme_Object *scheme_apply_lightweight_continuation(Scheme_Lightweight_Continua
Scheme_Object **scheme_adjust_runstack_argument(Scheme_Lightweight_Continuation *captured,
Scheme_Object **arg);
Scheme_Lightweight_Continuation *scheme_restore_lightweight_continuation_marks(Scheme_Lightweight_Continuation *lw);
int scheme_can_apply_lightweight_continuation(Scheme_Lightweight_Continuation *captured,
int check_overflow);