diff --git a/src/mzscheme/src/future.c b/src/mzscheme/src/future.c index c73134a218..32d1f1b70d 100644 --- a/src/mzscheme/src/future.c +++ b/src/mzscheme/src/future.c @@ -54,88 +54,71 @@ void scheme_init_futures(Scheme_Env *env) # include "./tests/unit_test.h" #endif -extern void *on_demand_jit_code; +static Scheme_Object *future(int argc, Scheme_Object *argv[]); +static Scheme_Object *touch(int argc, Scheme_Object *argv[]); +static Scheme_Object *processor_count(int argc, Scheme_Object *argv[]); +static void futures_init(void); +static void init_future_thread(struct Scheme_Future_State *fs, int i); #define THREAD_POOL_SIZE 12 #define INITIAL_C_STACK_SIZE 500000 -static pthread_t g_pool_threads[THREAD_POOL_SIZE]; -static int *g_fuel_pointers[THREAD_POOL_SIZE]; -static unsigned long *g_stack_boundary_pointers[THREAD_POOL_SIZE]; -static int *g_need_gc_pointers[THREAD_POOL_SIZE]; -static int g_num_avail_threads = 0; -static unsigned long g_cur_cpu_mask = 1; -static void *g_signal_handle = NULL; -static struct NewGC *g_shared_GC; -static future_t *g_future_queue = NULL; -static future_t *g_future_waiting_atomic = NULL; -static Scheme_Object *g_thread_skeleton; -int g_next_futureid = 0; -pthread_t g_rt_threadid = 0; +typedef struct Scheme_Future_State { + struct Scheme_Future_Thread_State *pool_threads[THREAD_POOL_SIZE]; -static pthread_mutex_t g_future_queue_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t g_future_pending_cv = PTHREAD_COND_INITIALIZER; + void *signal_handle; -THREAD_LOCAL_DECL(static pthread_cond_t worker_can_continue_cv); + int future_queue_count; + future_t *future_queue; + future_t *future_queue_end; + future_t *future_waiting_atomic; + int next_futureid; + + pthread_mutex_t future_mutex; + pthread_cond_t future_pending_cv; + pthread_cond_t gc_ok_c; + pthread_cond_t gc_done_c; + + int gc_not_ok, wait_for_gc; + + int *gc_counter_ptr; + + int future_threads_created; +} Scheme_Future_State; + +typedef struct Scheme_Future_Thread_State { + int id; + pthread_t threadid; + int worker_gc_counter; + pthread_cond_t worker_can_continue_cv; + future_t *current_ft; + long runstack_size; + + volatile int *fuel_pointer; + volatile unsigned long *stack_boundary_pointer; + volatile int *need_gc_pointer; +} Scheme_Future_Thread_State; + +THREAD_LOCAL_DECL(static Scheme_Future_State *scheme_future_state); +THREAD_LOCAL_DECL(void *jit_future_storage[2]); -static pthread_cond_t gc_ok_c = PTHREAD_COND_INITIALIZER; -static pthread_cond_t gc_done_c = PTHREAD_COND_INITIALIZER; -static int gc_not_ok, wait_for_gc; #ifdef MZ_PRECISE_GC THREAD_LOCAL_DECL(extern unsigned long GC_gen0_alloc_page_ptr); #endif -static future_t **g_current_ft; -static Scheme_Object ***g_scheme_current_runstack; -static Scheme_Object ***g_scheme_current_runstack_start; -static void **g_jit_future_storage; -static Scheme_Object **g_current_thread; -static int *gc_counter_ptr; -THREAD_LOCAL_DECL(static int worker_gc_counter); - #ifdef MZ_PRECISE_GC static void register_traversers(void); #endif -extern void scheme_on_demand_generate_lambda(Scheme_Native_Closure *nc, int argc, Scheme_Object **argv); -static void start_gc_not_ok(); -static void end_gc_not_ok(future_t *ft); +static void start_gc_not_ok(Scheme_Future_State *fs); +static void end_gc_not_ok(Scheme_Future_Thread_State *fts, + Scheme_Future_State *fs, + Scheme_Object **current_rs); -static void future_do_runtimecall(void *func, int is_atomic); - -THREAD_LOCAL_DECL(static future_t *current_ft); - -//Stuff for scheme runstack -//Some of these may mimic defines in thread.c, but are redefined here -//to avoid making any changes to that file for now (moving anything out into common -//headers, etc.) -#ifndef DEFAULT_INIT_STACK_SIZE -#define DEFAULT_INIT_STACK_SIZE 1000 -#endif - -//Functions -#ifndef UNIT_TEST static void *worker_thread_future_loop(void *arg); -static void invoke_rtcall(future_t *future); -static future_t *enqueue_future(future_t *ft);; -static future_t *get_pending_future(void); -static future_t *get_last_future(void); -#else -//Garbage stubs for unit testing -#define START_XFORM_SKIP -#define END_XFORM_SKIP -void scheme_add_global(char *name, int arity, Scheme_Env *env) { } -int scheme_make_prim_w_arity(prim_t func, char *name, int arg1, int arg2) { return 1; } -Scheme_Object *future_touch(int futureid) -{ - Scheme_Object *args[1] = { &futureid }; - return touch(1, args); -} -#endif - -void *g_funcargs[5]; -void *func_retval = NULL; - +static void invoke_rtcall(Scheme_Future_State * volatile fs, future_t * volatile future); +static future_t *enqueue_future(Scheme_Future_State *fs, future_t *ft);; +static future_t *get_pending_future(Scheme_Future_State *fs); #ifdef MZ_PRECISE_GC # define scheme_future_setjmp(newbuf) scheme_jit_setjmp((newbuf).jb) @@ -145,68 +128,6 @@ void *func_retval = NULL; # define scheme_future_longjmp(newbuf, v) scheme_longjmp(newbuf, v) #endif - -/**********************************************************************/ -/* Helpers for debugging */ -/**********************************************************************/ -#ifdef DEBUG_FUTURES -int g_rtcall_count = 0; - -static Scheme_Object **get_thread_runstack(void) -{ - return MZ_RUNSTACK; -} - - -static Scheme_Object **get_thread_runstack_start(void) -{ - return MZ_RUNSTACK_START; -} - -void dump_state(void) -{ - future_t *f; - pthread_mutex_lock(&g_future_queue_mutex); - printf("\n"); - printf("FUTURES STATE:\n"); - printf("-------------------------------------------------------------\n"); - if (NULL == g_future_queue) - { - printf("No futures currently running. %d thread(s) available in the thread pool.\n\n", g_num_avail_threads); - pthread_mutex_unlock(&g_future_queue_mutex); - return; - } - - for (f = g_future_queue; f != NULL; f = f->next) - { - printf("Future %d [Thread: %p, Runstack start = %p, Runstack = %p]: ", f->id, f->threadid, f->runstack_start, f->runstack); - fflush(stdout); - switch (f->status) - { - case PENDING: - printf("Waiting to be assigned to thread\n"); - break; - case RUNNING: - printf("Executing JIT code\n"); - break; - case WAITING_FOR_PRIM: - printf("Waiting for runtime primitive invocation (prim=%p)\n", (void*)f->rt_prim); - break; - case FINISHED: - printf("Finished work, waiting for cleanup\n"); - break; - } - - fflush(stdout); - printf("%d thread(s) available in the thread pool.\n", g_num_avail_threads); - printf("\n"); - fflush(stdout); - } - - pthread_mutex_unlock(&g_future_queue_mutex); -} -#endif - /**********************************************************************/ /* Semaphore helpers */ /**********************************************************************/ @@ -217,9 +138,6 @@ typedef struct sema_t { pthread_cond_t c; } sema_t; -#define SEMA_INITIALIZER { 0, PTHREAD_MUTEX_INITIALIZER, \ - PTHREAD_COND_INITIALIZER } - static void sema_wait(sema_t *s) { pthread_mutex_lock(&s->m); @@ -238,7 +156,36 @@ static void sema_signal(sema_t *s) pthread_mutex_unlock(&s->m); } -static sema_t ready_sema = SEMA_INITIALIZER; +static void sema_init(sema_t *s) +{ + pthread_mutex_init(&s->m, NULL); + pthread_cond_init(&s->c, NULL); + s->ready = 0; +} + +static void sema_destroy(sema_t *s) +{ + pthread_mutex_destroy(&s->m); + pthread_cond_destroy(&s->c); +} + +/**********************************************************************/ +/* Arguments for a newly created future thread */ +/**********************************************************************/ + +typedef struct future_thread_params_t { + struct sema_t ready_sema; + struct NewGC *shared_GC; + Scheme_Future_State *fs; + Scheme_Future_Thread_State *fts; + Scheme_Thread *thread_skeleton; + Scheme_Object **runstack_start; + + Scheme_Object ***scheme_current_runstack_ptr; + Scheme_Object ***scheme_current_runstack_start_ptr; + Scheme_Thread **current_thread_ptr; + void *jit_future_storage_ptr; +} future_thread_params_t; /**********************************************************************/ /* Plumbing for MzScheme initialization */ @@ -285,143 +232,179 @@ void scheme_init_futures(Scheme_Env *env) scheme_finish_primitive_module(newenv); scheme_protect_primitive_provide(newenv, NULL); - - REGISTER_SO(g_future_queue); - REGISTER_SO(g_future_waiting_atomic); } - -//Setup code here that should be invoked on -//the runtime thread. void futures_init(void) { - int i; - pthread_t threadid; - GC_CAN_IGNORE pthread_attr_t attr; - g_rt_threadid = pthread_self(); - g_signal_handle = scheme_get_signal_handle(); + Scheme_Future_State *fs; + void *hand; + + fs = (Scheme_Future_State *)malloc(sizeof(Scheme_Future_State)); + memset(fs, 0, sizeof(Scheme_Future_State)); + scheme_future_state = fs; + + REGISTER_SO(fs->future_queue); + REGISTER_SO(fs->future_queue_end); + REGISTER_SO(fs->future_waiting_atomic); + + pthread_mutex_init(&fs->future_mutex, NULL); + pthread_cond_init(&fs->future_pending_cv, NULL); + pthread_cond_init(&fs->gc_ok_c, NULL); + pthread_cond_init(&fs->gc_done_c, NULL); + + fs->gc_counter_ptr = &scheme_did_gc_count; + + hand = scheme_get_signal_handle(); + fs->signal_handle = hand; #ifdef MZ_PRECISE_GC register_traversers(); #endif +} + +static void init_future_thread(Scheme_Future_State *fs, int i) +{ + Scheme_Future_Thread_State *fts; + future_thread_params_t params; + pthread_t threadid; + GC_CAN_IGNORE pthread_attr_t attr; //Create the worker thread pool. These threads will //'queue up' and wait for futures to become available pthread_attr_init(&attr); - pthread_attr_setstacksize(&attr, INITIAL_C_STACK_SIZE); - for (i = 0; i < THREAD_POOL_SIZE; i++) - { - /* FIXME: insteda of using global variables, we need to - commuincate though some record. Global variables - won't work with places, since the relevant values - are all place-specific. */ - gc_counter_ptr = &scheme_did_gc_count; - g_shared_GC = GC; + pthread_attr_setstacksize(&attr, INITIAL_C_STACK_SIZE); - /* Make enough of a thread record to deal with multiple values. */ - g_thread_skeleton = (Scheme_Object *)MALLOC_ONE_TAGGED(Scheme_Thread); - g_thread_skeleton->type = scheme_thread_type; + fts = (Scheme_Future_Thread_State *)malloc(sizeof(Scheme_Future_Thread_State)); + memset(fts, 0, sizeof(Scheme_Future_Thread_State)); + fts->id = i; - pthread_create(&threadid, &attr, worker_thread_future_loop, &i); - sema_wait(&ready_sema); - - scheme_register_static(g_current_ft, sizeof(void*)); - scheme_register_static(g_scheme_current_runstack, sizeof(void*)); - scheme_register_static(g_scheme_current_runstack_start, sizeof(void*)); - scheme_register_static(g_jit_future_storage, 2 * sizeof(void*)); - scheme_register_static(g_current_thread, sizeof(void*)); + params.shared_GC = GC; + params.fts = fts; + params.fs = fs; - g_pool_threads[i] = threadid; - } + /* Make enough of a thread record to deal with multiple values. */ + params.thread_skeleton = MALLOC_ONE_TAGGED(Scheme_Thread); + params.thread_skeleton->so.type = scheme_thread_type; - g_num_avail_threads = THREAD_POOL_SIZE; -} - -static void start_gc_not_ok() -{ - while (wait_for_gc) { - pthread_cond_wait(&gc_done_c, &g_future_queue_mutex); + { + Scheme_Object **rs_start, **rs; + long init_runstack_size = 1000; + rs_start = scheme_alloc_runstack(init_runstack_size); + rs = rs_start XFORM_OK_PLUS init_runstack_size; + params.runstack_start = rs_start; + fts->runstack_size = init_runstack_size; } - gc_not_ok++; + sema_init(¶ms.ready_sema); + pthread_create(&threadid, &attr, worker_thread_future_loop, ¶ms); + sema_wait(¶ms.ready_sema); + sema_destroy(¶ms.ready_sema); + + fts->threadid = threadid; + + scheme_register_static(&fts->current_ft, sizeof(void*)); + 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.current_thread_ptr, sizeof(void*)); + + fs->pool_threads[i] = fts; +} + +static void start_gc_not_ok(Scheme_Future_State *fs) +{ + while (fs->wait_for_gc) { + pthread_cond_wait(&fs->gc_done_c, &fs->future_mutex); + } + + fs->gc_not_ok++; #ifdef MZ_PRECISE_GC - if (worker_gc_counter != *gc_counter_ptr) { - GC_gen0_alloc_page_ptr = 0; /* forces future to ask for memory */ - worker_gc_counter = *gc_counter_ptr; + { + Scheme_Future_Thread_State *fts = scheme_future_thread_state; + if (fts->worker_gc_counter != *fs->gc_counter_ptr) { + GC_gen0_alloc_page_ptr = 0; /* forces future to ask for memory */ + fts->worker_gc_counter = *fs->gc_counter_ptr; + } } #endif } -static void end_gc_not_ok(future_t *ft) +static void end_gc_not_ok(Scheme_Future_Thread_State *fts, + Scheme_Future_State *fs, + Scheme_Object **current_rs) { - if (ft) { - scheme_set_runstack_limits(ft->runstack_start, - ft->runstack_size, - ft->runstack - ft->runstack_start, - ft->runstack_size); - } + scheme_set_runstack_limits(MZ_RUNSTACK_START, + fts->runstack_size, + (current_rs + ? current_rs XFORM_OK_MINUS MZ_RUNSTACK_START + : fts->runstack_size), + fts->runstack_size); /* FIXME: clear scheme_current_thread->ku.multiple.array ? */ - --gc_not_ok; - pthread_cond_signal(&gc_ok_c); + --fs->gc_not_ok; + pthread_cond_signal(&fs->gc_ok_c); } void scheme_future_block_until_gc() { + Scheme_Future_State *fs = scheme_future_state; int i; - pthread_mutex_lock(&g_future_queue_mutex); - wait_for_gc = 1; - pthread_mutex_unlock(&g_future_queue_mutex); + if (!fs) return; + + pthread_mutex_lock(&fs->future_mutex); + fs->wait_for_gc = 1; + pthread_mutex_unlock(&fs->future_mutex); for (i = 0; i < THREAD_POOL_SIZE; i++) { - if (g_fuel_pointers[i] != NULL) - { - *(g_need_gc_pointers[i]) = 1; - *(g_fuel_pointers[i]) = 0; - *(g_stack_boundary_pointers[i]) += INITIAL_C_STACK_SIZE; - } + if (fs->pool_threads[i]) { + *(fs->pool_threads[i]->need_gc_pointer) = 1; + *(fs->pool_threads[i]->fuel_pointer) = 0; + *(fs->pool_threads[i]->stack_boundary_pointer) += INITIAL_C_STACK_SIZE; + } } asm("mfence"); - pthread_mutex_lock(&g_future_queue_mutex); - while (gc_not_ok) { - pthread_cond_wait(&gc_ok_c, &g_future_queue_mutex); + pthread_mutex_lock(&fs->future_mutex); + while (fs->gc_not_ok) { + pthread_cond_wait(&fs->gc_ok_c, &fs->future_mutex); } - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); } void scheme_future_continue_after_gc() { + Scheme_Future_State *fs = scheme_future_state; int i; + if (!fs) return; + for (i = 0; i < THREAD_POOL_SIZE; i++) { - if (g_fuel_pointers[i] != NULL) - { - *(g_need_gc_pointers[i]) = 0; - *(g_fuel_pointers[i]) = 1; - *(g_stack_boundary_pointers[i]) -= INITIAL_C_STACK_SIZE; - } - + if (fs->pool_threads[i]) { + *(fs->pool_threads[i]->need_gc_pointer) = 0; + *(fs->pool_threads[i]->fuel_pointer) = 1; + *(fs->pool_threads[i]->stack_boundary_pointer) -= INITIAL_C_STACK_SIZE; + } } - pthread_mutex_lock(&g_future_queue_mutex); - wait_for_gc = 0; - pthread_cond_broadcast(&gc_done_c); - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_lock(&fs->future_mutex); + fs->wait_for_gc = 0; + pthread_cond_broadcast(&fs->gc_done_c); + pthread_mutex_unlock(&fs->future_mutex); } void scheme_future_gc_pause() /* Called in future thread */ { - future_t *future = current_ft; - future->runstack = MZ_RUNSTACK; - pthread_mutex_lock(&g_future_queue_mutex); - end_gc_not_ok(future); - start_gc_not_ok(); /* waits until wait_for_gc is 0 */ - pthread_mutex_unlock(&g_future_queue_mutex); + Scheme_Future_Thread_State *fts = scheme_future_thread_state; + Scheme_Future_State *fs = scheme_future_state; + + pthread_mutex_lock(&fs->future_mutex); + end_gc_not_ok(fts, fs, MZ_RUNSTACK); + start_gc_not_ok(fs); /* waits until wait_for_gc is 0 */ + pthread_mutex_unlock(&fs->future_mutex); } /**********************************************************************/ @@ -431,12 +414,8 @@ void scheme_future_gc_pause() Scheme_Object *future(int argc, Scheme_Object *argv[]) /* Called in runtime thread */ { -#ifdef DEBUG_FUTURES - LOG_THISCALL; -#endif - - int init_runstack_size; - int futureid; + Scheme_Future_State *fs = scheme_future_state; + int futureid, count; future_t *ft; Scheme_Native_Closure *nc; Scheme_Native_Closure_Data *ncd; @@ -445,6 +424,16 @@ Scheme_Object *future(int argc, Scheme_Object *argv[]) //Input validation scheme_check_proc_arity("future", 0, 0, argc, argv); + if (fs->future_threads_created < THREAD_POOL_SIZE) { + pthread_mutex_lock(&fs->future_mutex); + count = fs->future_queue_count; + pthread_mutex_unlock(&fs->future_mutex); + if (count >= fs->future_threads_created) { + init_future_thread(fs, fs->future_threads_created); + fs->future_threads_created++; + } + } + nc = (Scheme_Native_Closure*)lambda; ncd = nc->code; @@ -452,45 +441,28 @@ Scheme_Object *future(int argc, Scheme_Object *argv[]) ft = MALLOC_ONE_TAGGED(future_t); ft->so.type = scheme_future_type; - futureid = ++g_next_futureid; + futureid = ++fs->next_futureid; ft->id = futureid; ft->orig_lambda = lambda; ft->status = PENDING; - //Allocate a new scheme stack for the future - //init_runstack_size = MZ_RUNSTACK - MZ_RUNSTACK_START; - init_runstack_size = 1000; - -#ifdef DEBUG_FUTURES - printf("Allocating Scheme stack of %d bytes for future %d.\n", init_runstack_size, futureid); -#endif - - { - Scheme_Object **rs_start, **rs; - rs_start = scheme_alloc_runstack(init_runstack_size); - rs = rs_start XFORM_OK_PLUS init_runstack_size; - ft->runstack_start = rs_start; - ft->runstack = rs; - ft->runstack_size = init_runstack_size; - } - //JIT compile the code if not already jitted //Temporarily repoint MZ_RUNSTACK //to the worker thread's runstack - //in case the JIT compiler uses the stack address //when generating code - if (ncd->code == on_demand_jit_code) + if (ncd->code == scheme_on_demand_jit_code) { scheme_on_demand_generate_lambda(nc, 0, NULL); } ft->code = (void*)ncd->code; - pthread_mutex_lock(&g_future_queue_mutex); - enqueue_future(ft); + pthread_mutex_lock(&fs->future_mutex); + enqueue_future(fs, ft); //Signal that a future is pending - pthread_cond_signal(&g_future_pending_cv); - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_cond_signal(&fs->future_pending_cv); + pthread_mutex_unlock(&fs->future_mutex); return (Scheme_Object*)ft; } @@ -499,49 +471,51 @@ Scheme_Object *future(int argc, Scheme_Object *argv[]) int future_ready(Scheme_Object *obj) /* Called in runtime thread by Scheme scheduler */ { + Scheme_Future_State *fs = scheme_future_state; int ret = 0; future_t *ft = (future_t*)obj; - pthread_mutex_lock(&g_future_queue_mutex); - if (ft->work_completed || ft->rt_prim) - { - ret = 1; - } - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_lock(&fs->future_mutex); + if (ft->work_completed || ft->rt_prim) { + ret = 1; + } + pthread_mutex_unlock(&fs->future_mutex); + return ret; } -static void dequeue_future(future_t *ft) +static void dequeue_future(Scheme_Future_State *fs, future_t *ft) /* called from both future and runtime threads */ { START_XFORM_SKIP; + if (ft->prev == NULL) - { - //Set next to be the head of the queue - g_future_queue = ft->next; - if (g_future_queue != NULL) - g_future_queue->prev = NULL; - } + fs->future_queue = ft->next; else - { - ft->prev->next = ft->next; - if (NULL != ft->next) - ft->next->prev = ft->prev; - } + ft->prev->next = ft->next; + + if (ft->next == NULL) + fs->future_queue_end = ft->prev; + else + ft->next->prev = ft->prev; + + ft->next = NULL; + ft->prev = NULL; + + --fs->future_queue_count; + END_XFORM_SKIP; } - Scheme_Object *touch(int argc, Scheme_Object *argv[]) /* Called in runtime thread */ { + Scheme_Future_State *fs = scheme_future_state; Scheme_Object *retval = NULL; future_t *ft; if (!SAME_TYPE(SCHEME_TYPE(argv[0]), scheme_future_type)) - { - scheme_wrong_type("touch", "future", 0, argc, argv); - } + scheme_wrong_type("touch", "future", 0, argc, argv); ft = (future_t*)argv[0]; @@ -550,29 +524,29 @@ Scheme_Object *touch(int argc, Scheme_Object *argv[]) dump_state(); #endif - pthread_mutex_lock(&g_future_queue_mutex); + pthread_mutex_lock(&fs->future_mutex); if (ft->status == PENDING) { ft->status = RUNNING; - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); retval = _scheme_apply(ft->orig_lambda, 0, NULL); - pthread_mutex_lock(&g_future_queue_mutex); + pthread_mutex_lock(&fs->future_mutex); ft->work_completed = 1; ft->retval = retval; ft->status = FINISHED; - dequeue_future(ft); - pthread_mutex_unlock(&g_future_queue_mutex); + dequeue_future(fs, ft); + pthread_mutex_unlock(&fs->future_mutex); return retval; } - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); //Spin waiting for primitive calls or a return value from //the worker thread wait_for_rtcall_or_completion: scheme_block_until(future_ready, NULL, (Scheme_Object*)ft, 0); - pthread_mutex_lock(&g_future_queue_mutex); + pthread_mutex_lock(&fs->future_mutex); if (ft->work_completed) { retval = ft->retval; @@ -580,25 +554,23 @@ Scheme_Object *touch(int argc, Scheme_Object *argv[]) LOG("Successfully touched future %d\n", ft->id); // fflush(stdout); - //Increment the number of available pool threads - g_num_avail_threads++; - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); } else if (ft->rt_prim) { //Invoke the primitive and stash the result //Release the lock so other threads can manipulate the queue //while the runtime call executes - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); LOG("Invoking primitive %p on behalf of future %d...", ft->rt_prim, ft->id); - invoke_rtcall(ft); + invoke_rtcall(fs, ft); LOG("done.\n"); goto wait_for_rtcall_or_completion; } else { - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); goto wait_for_rtcall_or_completion; } @@ -651,19 +623,26 @@ void *worker_thread_future_loop(void *arg) is signaled. */ { START_XFORM_SKIP; + /* valid only until signaling */ + future_thread_params_t *params = (future_thread_params_t *)arg; + Scheme_Future_Thread_State *fts = params->fts; + Scheme_Future_State *fs = params->fs; Scheme_Object *v; Scheme_Object* (*jitcode)(Scheme_Object*, int, Scheme_Object**); future_t *ft; - int id = *(int *)arg; mz_jmp_buf newbuf; scheme_init_os_thread(); - GC = g_shared_GC; - scheme_current_thread = g_thread_skeleton; + scheme_future_state = fs; + scheme_future_thread_state = fts; + + GC = params->shared_GC; + scheme_current_thread = params->thread_skeleton; //Set processor affinity - /*pthread_mutex_lock(&g_future_queue_mutex); + /*pthread_mutex_lock(&fs->future_mutex); + static unsigned long cur_cpu_mask = 1; if (pthread_setaffinity_np(pthread_self(), sizeof(g_cur_cpu_mask), &g_cur_cpu_mask)) { printf( @@ -672,60 +651,54 @@ void *worker_thread_future_loop(void *arg) pthread_self()); } - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); */ - pthread_cond_init(&worker_can_continue_cv, NULL); + pthread_cond_init(&fts->worker_can_continue_cv, NULL); scheme_use_rtcall = 1; scheme_fuel_counter = 1; scheme_jit_stack_boundary = ((unsigned long)&v) - INITIAL_C_STACK_SIZE; - g_need_gc_pointers[id] = &scheme_future_need_gc_pause; - g_fuel_pointers[id] = &scheme_fuel_counter; - g_stack_boundary_pointers[id] = &scheme_jit_stack_boundary; + fts->need_gc_pointer = &scheme_future_need_gc_pause; + fts->fuel_pointer = &scheme_fuel_counter; + fts->stack_boundary_pointer = &scheme_jit_stack_boundary; - g_current_ft = ¤t_ft; - g_scheme_current_runstack = &scheme_current_runstack; - g_scheme_current_runstack_start = &scheme_current_runstack_start; - g_jit_future_storage = &jit_future_storage[0]; - g_current_thread = &scheme_current_thread; - sema_signal(&ready_sema); + MZ_RUNSTACK_START = params->runstack_start; + MZ_RUNSTACK = MZ_RUNSTACK_START + fts->runstack_size; + + params->scheme_current_runstack_ptr = &scheme_current_runstack; + params->scheme_current_runstack_start_ptr = &scheme_current_runstack_start; + params->current_thread_ptr = &scheme_current_thread; + params->jit_future_storage_ptr = &jit_future_storage[0]; + + sema_signal(¶ms->ready_sema); wait_for_work: - pthread_mutex_lock(&g_future_queue_mutex); - start_gc_not_ok(); - while (!(ft = get_pending_future())) - { - end_gc_not_ok(NULL); - pthread_cond_wait(&g_future_pending_cv, &g_future_queue_mutex); - start_gc_not_ok(); - } + pthread_mutex_lock(&fs->future_mutex); + start_gc_not_ok(fs); + while (!(ft = get_pending_future(fs))) { + end_gc_not_ok(fts, fs, NULL); + pthread_cond_wait(&fs->future_pending_cv, &fs->future_mutex); + start_gc_not_ok(fs); + } LOG("Got a signal that a future is pending..."); //Work is available for this thread ft->status = RUNNING; - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); - ft->threadid = pthread_self(); - ft->thread_short_id = id; - - //Decrement the number of available pool threads - g_num_avail_threads--; - - //Initialize the runstack for this thread - //MZ_RUNSTACK AND MZ_RUNSTACK_START should be thread-local - MZ_RUNSTACK = ft->runstack; - MZ_RUNSTACK_START = ft->runstack_start; + ft->threadid = fts->threadid; + ft->thread_short_id = fts->id; //Set up the JIT compiler for this thread scheme_jit_fill_threadlocal_table(); jitcode = (Scheme_Object* (*)(Scheme_Object*, int, Scheme_Object**))(ft->code); - current_ft = ft; + fts->current_ft = ft; //Run the code //Passing no arguments for now. @@ -749,24 +722,22 @@ void *worker_thread_future_loop(void *arg) LOG("Finished running JIT code at %p.\n", ft->code); // Get future again, since a GC may have occurred - ft = current_ft; + ft = fts->current_ft; //Set the return val in the descriptor - pthread_mutex_lock(&g_future_queue_mutex); + pthread_mutex_lock(&fs->future_mutex); ft->work_completed = 1; ft->retval = v; - ft->runstack = NULL; - ft->runstack_start = NULL; - //Update the status ft->status = FINISHED; - dequeue_future(ft); + dequeue_future(fs, ft); - scheme_signal_received_at(g_signal_handle); + scheme_signal_received_at(fs->signal_handle); - end_gc_not_ok(NULL); - pthread_mutex_unlock(&g_future_queue_mutex); + end_gc_not_ok(fts, fs, NULL); + + pthread_mutex_unlock(&fs->future_mutex); goto wait_for_work; @@ -781,21 +752,24 @@ void scheme_check_future_work() and that can be done in any Scheme thread (e.g., get a new page for allocation). */ future_t *ft; + Scheme_Future_State *fs = scheme_future_state; + + if (!fs) return; while (1) { /* Try to get a future waiting on a atomic operation */ - pthread_mutex_lock(&g_future_queue_mutex); - ft = g_future_waiting_atomic; + pthread_mutex_lock(&fs->future_mutex); + ft = fs->future_waiting_atomic; if (ft) { - g_future_waiting_atomic = ft->next_waiting_atomic; + fs->future_waiting_atomic = ft->next_waiting_atomic; ft->next_waiting_atomic = NULL; ft->waiting_atomic = 0; } - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); if (ft) { if (ft->rt_prim && ft->rt_prim_is_atomic) { - invoke_rtcall(ft); + invoke_rtcall(fs, ft); } } else break; @@ -806,44 +780,30 @@ void scheme_check_future_work() //i.e. if we are already running on the runtime thread. Otherwise returns //1, and 'retval' is set to point to the return value of the runtime //call invocation. -void future_do_runtimecall(void *func, - int is_atomic) +static void future_do_runtimecall(Scheme_Future_Thread_State *fts, + void *func, + int is_atomic) /* Called in future thread */ { START_XFORM_SKIP; future_t *future; - - //If already running on the main thread - //or no future is involved, do nothing - //and return FALSE - if (pthread_self() == g_rt_threadid) - { - //Should never get here! This check should be done - //by the caller using the macros defined in scheme-futures.h! - return; - } + Scheme_Future_State *fs = scheme_future_state; //Fetch the future descriptor for this thread - future = current_ft; + future = fts->current_ft; //set up the arguments for the runtime call //to be picked up by the main rt thread - //pthread_mutex_lock(&future->mutex); - pthread_mutex_lock(&g_future_queue_mutex); + pthread_mutex_lock(&fs->future_mutex); - //Update the stack pointer for this future - //to be in sync with MZ_RUNSTACK - the runtime thread - //will use this value to temporarily swap its stack - //for the worker thread's - future->runstack = MZ_RUNSTACK; future->prim_func = func; future->rt_prim = 1; future->rt_prim_is_atomic = is_atomic; if (is_atomic) { if (!future->waiting_atomic) { - future->next_waiting_atomic = g_future_waiting_atomic; - g_future_waiting_atomic = future; + future->next_waiting_atomic = fs->future_waiting_atomic; + fs->future_waiting_atomic = future; future->waiting_atomic = 1; } } @@ -851,19 +811,19 @@ void future_do_runtimecall(void *func, //Update the future's status to waiting future->status = WAITING_FOR_PRIM; - scheme_signal_received_at(g_signal_handle); + scheme_signal_received_at(fs->signal_handle); //Wait for the signal that the RT call is finished - future->can_continue_cv = &worker_can_continue_cv; + future->can_continue_cv = &fts->worker_can_continue_cv; while (future->can_continue_cv) { - end_gc_not_ok(future); - pthread_cond_wait(&worker_can_continue_cv, &g_future_queue_mutex); - start_gc_not_ok(); + end_gc_not_ok(fts, fs, MZ_RUNSTACK); + pthread_cond_wait(&fts->worker_can_continue_cv, &fs->future_mutex); + start_gc_not_ok(fs); //Fetch the future instance again, in case the GC has moved the pointer - future = current_ft; + future = fts->current_ft; } - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); if (future->no_retval) { future->no_retval = 0; @@ -877,45 +837,52 @@ void future_do_runtimecall(void *func, /**********************************************************************/ /* Functions for primitive invocation */ /**********************************************************************/ -void scheme_rtcall_void_void_3args(const char *who, int src_type, void (*f)()) +void scheme_rtcall_void_void_3args(const char *who, int src_type, prim_void_void_3args_t f) /* Called in future thread */ { START_XFORM_SKIP; - future_t *future = current_ft; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; + future_t *future = fts->current_ft; future->prim_protocol = SIG_VOID_VOID_3ARGS; + future->arg_S0 = MZ_RUNSTACK; + future->time_of_request = scheme_get_inexact_milliseconds(); future->source_of_request = who; future->source_type = src_type; - future_do_runtimecall((void*)f, 1); + future_do_runtimecall(fts, (void*)f, 1); + + future->arg_S0 = NULL; END_XFORM_SKIP; } -void *scheme_rtcall_alloc_void_pvoid(const char *who, int src_type, void (*f)()) +unsigned long scheme_rtcall_alloc_void_pvoid(const char *who, int src_type, prim_alloc_void_pvoid_t f) /* Called in future thread */ { START_XFORM_SKIP; future_t *future; - void *retval; + unsigned long retval; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; + Scheme_Future_State *fs = scheme_future_state; while (1) { - future = current_ft; + future = fts->current_ft; future->time_of_request = 0; /* takes too long?: scheme_get_inexact_milliseconds(); */ future->source_of_request = who; future->source_type = src_type; future->prim_protocol = SIG_ALLOC_VOID_PVOID; - future_do_runtimecall((void*)f, 1); + future_do_runtimecall(fts, (void*)f, 1); - future = current_ft; + future = fts->current_ft; retval = future->alloc_retval; - future->alloc_retval = NULL; + future->alloc_retval = 0; - if (*gc_counter_ptr == future->alloc_retval_counter) + if (*fs->gc_counter_ptr == future->alloc_retval_counter) break; } @@ -924,6 +891,7 @@ void *scheme_rtcall_alloc_void_pvoid(const char *who, int src_type, void (*f)()) } static void receive_special_result(future_t *f, Scheme_Object *retval) +/* Called in future thread */ { if (SAME_OBJ(retval, SCHEME_MULTIPLE_VALUES)) { Scheme_Thread *p = scheme_current_thread; @@ -965,7 +933,7 @@ static void send_special_result(future_t *f, Scheme_Object *retval) //Does the work of actually invoking a primitive on behalf of a //future. This function is always invoked on the main (runtime) //thread. -static void do_invoke_rtcall(future_t *future) +static void do_invoke_rtcall(Scheme_Future_State *fs, future_t *future) /* Called in runtime thread */ { #ifdef DEBUG_FUTURES @@ -1001,17 +969,16 @@ static void do_invoke_rtcall(future_t *future) { prim_void_void_3args_t func = (prim_void_void_3args_t)future->prim_func; - func(future->runstack); + func(future->arg_S0); break; } case SIG_ALLOC_VOID_PVOID: { - void *ret; + unsigned long ret; prim_alloc_void_pvoid_t func = (prim_alloc_void_pvoid_t)future->prim_func; ret = func(); future->alloc_retval = ret; - ret = NULL; future->alloc_retval_counter = scheme_did_gc_count; break; } @@ -1021,15 +988,17 @@ static void do_invoke_rtcall(future_t *future) break; } - pthread_mutex_lock(&g_future_queue_mutex); + pthread_mutex_lock(&fs->future_mutex); //Signal the waiting worker thread that it //can continue running machine code - pthread_cond_signal(future->can_continue_cv); - future->can_continue_cv= NULL; - pthread_mutex_unlock(&g_future_queue_mutex); + if (future->can_continue_cv) { + pthread_cond_signal(future->can_continue_cv); + future->can_continue_cv= NULL; + } + pthread_mutex_unlock(&fs->future_mutex); } -static void invoke_rtcall(future_t * volatile future) +static void invoke_rtcall(Scheme_Future_State * volatile fs, future_t * volatile future) { Scheme_Thread *p = scheme_current_thread; mz_jmp_buf newbuf, * volatile savebuf; @@ -1037,16 +1006,16 @@ static void invoke_rtcall(future_t * volatile future) savebuf = p->error_buf; p->error_buf = &newbuf; if (scheme_setjmp(newbuf)) { - pthread_mutex_lock(&g_future_queue_mutex); + pthread_mutex_lock(&fs->future_mutex); future->no_retval = 1; //Signal the waiting worker thread that it //can continue running machine code pthread_cond_signal(future->can_continue_cv); future->can_continue_cv = NULL; - pthread_mutex_unlock(&g_future_queue_mutex); + pthread_mutex_unlock(&fs->future_mutex); scheme_longjmp(*savebuf, 1); } else { - do_invoke_rtcall(future); + do_invoke_rtcall(fs, future); } p->error_buf = savebuf; } @@ -1056,89 +1025,36 @@ static void invoke_rtcall(future_t * volatile future) /* Helpers for manipulating the futures queue */ /**********************************************************************/ -future_t *enqueue_future(future_t *ft) +future_t *enqueue_future(Scheme_Future_State *fs, future_t *ft) /* Called in runtime thread */ { - future_t *last; - last = get_last_future(); - if (NULL == last) - { - g_future_queue = ft; - return ft; - } - - ft->prev = last; - last->next = ft; - ft->next = NULL; + if (fs->future_queue_end) { + fs->future_queue_end->next = ft; + ft->prev = fs->future_queue_end; + } + fs->future_queue_end = ft; + if (!fs->future_queue) + fs->future_queue = ft; + fs->future_queue_count++; return ft; } - -future_t *get_pending_future(void) +future_t *get_pending_future(Scheme_Future_State *fs) /* Called in future thread */ { START_XFORM_SKIP; future_t *f; - for (f = g_future_queue; f != NULL; f = f->next) - { - if (f->status == PENDING) - return f; - } + + for (f = fs->future_queue; f != NULL; f = f->next) { + if (f->status == PENDING) + return f; + } return NULL; END_XFORM_SKIP; } -future_t *get_last_future(void) -/* Called in runtime thread */ -{ - future_t *ft = g_future_queue; - if (NULL == ft) - { - return ft; - } - - while (ft->next != NULL) - { - ft = ft->next; - } - - return ft; -} - - -void clear_futures(void) -{ - int i; - future_t *f, *tmp; - pthread_mutex_lock(&g_future_queue_mutex); - for (i = 0; i < THREAD_POOL_SIZE; i++) - { - pthread_cancel(g_pool_threads[i]); - } - - pthread_mutex_unlock(&g_future_queue_mutex); - f = get_last_future(); - if (NULL == f) - return; - - while (1) - { - tmp = f->prev; - free(f); - if (tmp == NULL) - { - break; - } - - tmp->next = NULL; - f = tmp; - } - - g_future_queue = NULL; -} - /**********************************************************************/ /* Precise GC */ /**********************************************************************/ diff --git a/src/mzscheme/src/future.h b/src/mzscheme/src/future.h index 6fb9893ffa..d6f5fc9490 100644 --- a/src/mzscheme/src/future.h +++ b/src/mzscheme/src/future.h @@ -23,16 +23,8 @@ int scheme_make_prim_w_arity(prim_t func, char *name, int arg1, int arg2); #include "pthread.h" #include -extern pthread_t g_rt_threadid; -extern Scheme_Object *start_primitive_tracking(int argc, Scheme_Object *argv[]); -extern Scheme_Object *end_primitive_tracking(int argc, Scheme_Object *argv[]); -extern Scheme_Object *future(int argc, Scheme_Object *argv[]); -extern Scheme_Object *touch(int argc, Scheme_Object *argv[]); -extern Scheme_Object *processor_count(int argc, Scheme_Object *argv[]); -extern void futures_init(void); - typedef void (*prim_void_void_3args_t)(Scheme_Object **); -typedef void *(*prim_alloc_void_pvoid_t)(); +typedef unsigned long (*prim_alloc_void_pvoid_t)(); typedef Scheme_Object* (*prim_obj_int_pobj_obj_t)(Scheme_Object*, int, Scheme_Object**); 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*); @@ -57,9 +49,6 @@ typedef struct future_t { int work_completed; pthread_cond_t *can_continue_cv; - long runstack_size; - Scheme_Object **runstack; - Scheme_Object **runstack_start; Scheme_Object *orig_lambda; void *code; @@ -70,7 +59,7 @@ typedef struct future_t { const char *source_of_request; int source_type; - void *alloc_retval; + unsigned long alloc_retval; int alloc_retval_counter; void *prim_func; @@ -110,24 +99,6 @@ typedef struct future_t { struct future_t *next_waiting_atomic; } future_t; -#ifdef UNIT_TEST -//If unit testing, expose internal functions and vars to -//the test suite -extern future_t *g_future_queue; -extern int g_next_futureid; -extern pthread_t g_rt_threadid; - -extern void *worker_thread_future_loop(void *arg); -extern void *invoke_rtcall(future_t *future); -extern future_t *enqueue_future(void); -extern future_t *get_pending_future(void); -extern future_t *get_my_future(void); -extern future_t *get_future_by_threadid(pthread_t threadid); -extern future_t *get_future(int futureid); -extern future_t *get_last_future(void); -extern void clear_futures(void); -#endif - //Primitive instrumentation stuff //Signature flags for primitive invocations @@ -147,8 +118,8 @@ extern void clear_futures(void); /*GDB_BREAK;*/ \ } -extern void scheme_rtcall_void_void_3args(const char *who, int src_type, void (*f)()); -extern void *scheme_rtcall_alloc_void_pvoid(const char *who, int src_type, void (*f)()); +extern void scheme_rtcall_void_void_3args(const char *who, int src_type, prim_void_void_3args_t f); +extern unsigned long scheme_rtcall_alloc_void_pvoid(const char *who, int src_type, prim_alloc_void_pvoid_t f); #else @@ -205,6 +176,9 @@ extern void *scheme_rtcall_alloc_void_pvoid(const char *who, int src_type, void #define LOG_RTCALL_ENV_ENV_VOID(a,b) #endif +extern void *scheme_on_demand_jit_code; +extern void scheme_on_demand_generate_lambda(Scheme_Native_Closure *nc, int argc, Scheme_Object **argv); + void scheme_future_block_until_gc(); void scheme_future_continue_after_gc(); void scheme_check_future_work(); diff --git a/src/mzscheme/src/gen-jit-ts.ss b/src/mzscheme/src/gen-jit-ts.ss index 7d4928c723..e1d2fd5542 100644 --- a/src/mzscheme/src/gen-jit-ts.ss +++ b/src/mzscheme/src/gen-jit-ts.ss @@ -64,11 +64,12 @@ @|result-type| scheme_rtcall_@|ts|(const char *who, int src_type, prim_@|ts| f@|(if (null? arg-types) "" ",")| @|args|) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; @(if (string=? result-type "void") "" @string-append{@|result-type| retval;}) - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_@|ts|; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -81,8 +82,8 @@ [i (in-naturals)]) @string-append{ future->arg_@|(string t)|@|(number->string i)| = @|a|;}) "\n") - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; @(if (string=? result-type "void") "" @string-append{retval = @|fretval|;}) @(if (string=? result-type "void") "" @string-append{@|fretval| = 0;}) @(if (string=? result-type "Scheme_Object*") @string-append{receive_special_result(future, retval);} "") diff --git a/src/mzscheme/src/jit.c b/src/mzscheme/src/jit.c index 41e1e91187..6af88e813c 100644 --- a/src/mzscheme/src/jit.c +++ b/src/mzscheme/src/jit.c @@ -144,7 +144,7 @@ static void *vector_ref_code, *vector_ref_check_index_code, *vector_set_code, *v static void *string_ref_code, *string_ref_check_index_code, *string_set_code, *string_set_check_index_code; static void *bytes_ref_code, *bytes_ref_check_index_code, *bytes_set_code, *bytes_set_check_index_code; static void *syntax_e_code; -void *on_demand_jit_code; +void *scheme_on_demand_jit_code; static void *on_demand_jit_arity_code; static void *get_stack_pointer_code; static void *stack_cache_pop_code; @@ -296,6 +296,7 @@ void scheme_jit_fill_threadlocal_table(); # define tl_scheme_jit_stack_boundary tl_delta(scheme_jit_stack_boundary) # define tl_jit_future_storage tl_delta(jit_future_storage) # define tl_scheme_future_need_gc_pause tl_delta(scheme_future_need_gc_pause) +# define tl_scheme_use_rtcall tl_delta(scheme_use_rtcall) #ifdef MZ_XFORM START_XFORM_SKIP; @@ -2194,6 +2195,27 @@ extern int g_print_prims; # define mz_prepare_direct_prim(n) mz_prepare(n) # define mz_finishr_direct_prim(reg, proc) (jit_pusharg_p(reg), (void)mz_finish(proc)) # define mz_direct_only(p) /* skip this arg, so that total count <= 3 args */ +/* Inlines check of scheme_use_rtcall: */ +# define mz_generate_direct_prim(direct_only, first_arg, reg, prim_indirect) \ + { \ + GC_CAN_IGNORE jit_insn *refdirect, *refcont; \ + int argstate; \ + jit_save_argstate(argstate); \ + mz_tl_ldi_i(JIT_R0, tl_scheme_use_rtcall); \ + __START_TINY_JUMPS__(1); \ + refdirect = jit_beqi_i(jit_forward(), JIT_R0, 0); \ + first_arg; \ + mz_finishr_direct_prim(reg, prim_indirect); \ + refcont = jit_jmpi(jit_forward()); \ + CHECK_LIMIT(); \ + mz_patch_branch(refdirect); \ + jit_restore_argstate(argstate); \ + direct_only; \ + first_arg; \ + mz_finishr(reg); \ + mz_patch_ucbranch(refcont); \ + __END_TINY_JUMPS__(1); \ + } static Scheme_Object *noncm_prim_indirect(Scheme_Prim proc, int argc) { START_XFORM_SKIP; @@ -2239,7 +2261,7 @@ static void ts_on_demand(void) static void *ts_prepare_retry_alloc(void *p, void *p2) { START_XFORM_SKIP; - void *ret; + unsigned long ret; if (scheme_use_rtcall) { jit_future_storage[0] = p; @@ -2265,6 +2287,8 @@ static void *ts_prepare_retry_alloc(void *p, void *p2) # define mz_direct_only(p) p # define ts_on_demand on_demand # define ts_prepare_retry_alloc prepare_retry_alloc +# define mz_generate_direct_prim(direct_only, first_arg, reg, prim_indirect) \ + (mz_direct_only(direct_only), first_arg, mz_finishr_direct_prim(reg, prim_indirect)) #endif static int generate_pause_for_gc_and_retry(mz_jit_state *jitter, @@ -2339,9 +2363,12 @@ static int generate_direct_prim_tail_call(mz_jit_state *jitter, int num_rands) jit_movi_i(JIT_R1, num_rands); mz_prepare_direct_prim(2); /* a prim takes 3 args, but a NONCM prim ignores the 3rd */ CHECK_LIMIT(); - mz_direct_only(jit_pusharg_p(JIT_RUNSTACK)); - jit_pusharg_i(JIT_R1); - mz_finishr_direct_prim(JIT_V1, noncm_prim_indirect); + { + /* May use JIT_R0 and create local branch: */ + mz_generate_direct_prim(jit_pusharg_p(JIT_RUNSTACK), + jit_pusharg_i(JIT_R1), + JIT_V1, noncm_prim_indirect); + } CHECK_LIMIT(); /* Return: */ mz_pop_threadlocal(); @@ -2544,9 +2571,12 @@ static int generate_direct_prim_non_tail_call(mz_jit_state *jitter, int num_rand jit_movi_i(JIT_R1, num_rands); mz_prepare_direct_prim(2); /* a prim takes 3 args, but a NONCM prim ignores the 3rd */ CHECK_LIMIT(); - mz_direct_only(jit_pusharg_p(JIT_RUNSTACK)); - jit_pusharg_i(JIT_R1); - mz_finishr_direct_prim(JIT_V1, noncm_prim_indirect); + { + /* May use JIT_R0 and create local branch: */ + mz_generate_direct_prim(jit_pusharg_p(JIT_RUNSTACK), + jit_pusharg_i(JIT_R1), + JIT_V1, noncm_prim_indirect); + } CHECK_LIMIT(); jit_retval(JIT_R0); VALIDATE_RESULT(JIT_R0); @@ -2839,9 +2869,14 @@ static int generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc mz_prepare_direct_prim(3); jit_pusharg_p(JIT_V1); if (num_rands < 0) { jit_movr_p(JIT_V1, JIT_R0); } /* save argc to manually pop runstack */ - mz_direct_only(jit_pusharg_p(JIT_RUNSTACK)); - jit_pusharg_i(JIT_R2); - mz_finishr_direct_prim(JIT_R1, prim_indirect); + { + __END_SHORT_JUMPS__(1); + /* May use JIT_R0 and create local branch: */ + mz_generate_direct_prim(jit_pusharg_p(JIT_RUNSTACK), + jit_pusharg_i(JIT_R2), + JIT_R1, prim_indirect); + __START_SHORT_JUMPS__(1); + } CHECK_LIMIT(); jit_retval(JIT_R0); VALIDATE_RESULT(JIT_R0); @@ -8232,9 +8267,12 @@ static int do_generate_common(mz_jit_state *jitter, void *_data) } JIT_UPDATE_THREAD_RSPTR(); mz_prepare_direct_prim(2); - mz_direct_only(jit_pusharg_p(JIT_RUNSTACK)); - jit_pusharg_p(JIT_R1); - mz_finishr_direct_prim(JIT_R2, noncm_prim_indirect); + { + /* May use JIT_R0 and create local branch: */ + mz_generate_direct_prim(jit_pusharg_p(JIT_RUNSTACK), + jit_pusharg_p(JIT_R1), + JIT_R2, noncm_prim_indirect); + } CHECK_LIMIT(); jit_retval(JIT_R0); VALIDATE_RESULT(JIT_R0); @@ -8262,7 +8300,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data) /* Used as the code stub for a closure whose code is not yet compiled. See generate_function_prolog for the state of registers on entry */ - on_demand_jit_code = jit_get_ip().ptr; + scheme_on_demand_jit_code = jit_get_ip().ptr; jit_prolog(NATIVE_ARG_COUNT); in = jit_arg_p(); jit_getarg_p(JIT_R0, in); /* closure */ @@ -8332,7 +8370,7 @@ static int do_generate_common(mz_jit_state *jitter, void *_data) mz_pop_locals(); jit_ret(); CHECK_LIMIT(); - register_helper_func(jitter, on_demand_jit_code); + register_helper_func(jitter, scheme_on_demand_jit_code); /* *** app_values_tail_slow_code *** */ /* RELIES ON jit_prolog(NATIVE_ARG_COUNT) FROM ABOVE */ @@ -9556,7 +9594,7 @@ static void on_demand_with_args(Scheme_Object **in_argv) argc = in_argv[1]; argv = (Scheme_Object **)in_argv[2]; - if (((Scheme_Native_Closure *)c)->code->code == on_demand_jit_code) + if (((Scheme_Native_Closure *)c)->code->code == scheme_on_demand_jit_code) scheme_on_demand_generate_lambda((Scheme_Native_Closure *)c, SCHEME_INT_VAL(argc), argv); } @@ -9591,7 +9629,7 @@ Scheme_Native_Closure_Data *scheme_generate_lambda(Scheme_Closure_Data *data, in ndata->iso.so.type = scheme_rt_native_code_plus_case; #endif } - ndata->code = on_demand_jit_code; + ndata->code = scheme_on_demand_jit_code; ndata->u.tail_code = on_demand_jit_arity_code; ndata->arity_code = on_demand_jit_arity_code; ndata->u2.orig_code = data; @@ -9861,7 +9899,7 @@ static void generate_case_lambda(Scheme_Case_Lambda *c, Scheme_Native_Closure_Da static int lambda_has_been_jitted(Scheme_Native_Closure_Data *ndata) { - return (ndata->code != on_demand_jit_code); + return (ndata->code != scheme_on_demand_jit_code); } int scheme_native_arity_check(Scheme_Object *closure, int argc) diff --git a/src/mzscheme/src/jit_ts_future_glue.c b/src/mzscheme/src/jit_ts_future_glue.c index cd02973459..3c7177bca9 100644 --- a/src/mzscheme/src/jit_ts_future_glue.c +++ b/src/mzscheme/src/jit_ts_future_glue.c @@ -1,11 +1,12 @@ Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g44, int g45, Scheme_Object** g46) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_siS_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -15,8 +16,8 @@ future->arg_s0 = g44; future->arg_i1 = g45; future->arg_S2 = g46; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -26,11 +27,12 @@ Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g47, Scheme_Object** g48, Scheme_Object* g49) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_iSs_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -40,8 +42,8 @@ future->arg_i0 = g47; future->arg_S1 = g48; future->arg_s2 = g49; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -51,11 +53,12 @@ Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g50) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_s_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -63,8 +66,8 @@ future->source_of_request = who; future->source_type = src_type; future->arg_s0 = g50; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -74,11 +77,12 @@ Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Closure_Data* g51) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_n_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -86,8 +90,8 @@ future->source_of_request = who; future->source_type = src_type; future->arg_n0 = g51; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -97,11 +101,12 @@ Scheme_Object* scheme_rtcall__s(const char *who, int src_type, prim__s f ) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG__s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -109,8 +114,8 @@ future->source_of_request = who; future->source_type = src_type; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -120,11 +125,12 @@ Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g52, Scheme_Object* g53) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_ss_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -133,8 +139,8 @@ future->source_type = src_type; future->arg_s0 = g52; future->arg_s1 = g53; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -144,11 +150,12 @@ MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g54, Scheme_Object* g55) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; MZ_MARK_STACK_TYPE retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_ss_m; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -157,8 +164,8 @@ future->source_type = src_type; future->arg_s0 = g54; future->arg_s1 = g55; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_m; future->retval_m = 0; @@ -168,11 +175,12 @@ Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g56, long g57) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_Sl_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -181,8 +189,8 @@ future->source_type = src_type; future->arg_S0 = g56; future->arg_l1 = g57; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -192,11 +200,12 @@ Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, long g58) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_l_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -204,8 +213,8 @@ future->source_of_request = who; future->source_type = src_type; future->arg_l0 = g58; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -215,11 +224,12 @@ void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g59, Scheme_Object* g60, int g61) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_bsi_v; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -229,8 +239,8 @@ future->arg_b0 = g59; future->arg_s1 = g60; future->arg_i2 = g61; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; @@ -240,11 +250,12 @@ void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g62, int g63, Scheme_Object** g64) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_iiS_v; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -254,8 +265,8 @@ future->arg_i0 = g62; future->arg_i1 = g63; future->arg_S2 = g64; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; @@ -265,11 +276,12 @@ void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g65, Scheme_Object* g66) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_ss_v; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -278,8 +290,8 @@ future->source_type = src_type; future->arg_s0 = g65; future->arg_s1 = g66; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; @@ -289,11 +301,12 @@ void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g67) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_b_v; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -301,8 +314,8 @@ future->source_of_request = who; future->source_type = src_type; future->arg_b0 = g67; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; @@ -312,11 +325,12 @@ Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g68, long g69) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_sl_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -325,8 +339,8 @@ future->source_type = src_type; future->arg_s0 = g68; future->arg_l1 = g69; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -336,11 +350,12 @@ Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g70, Scheme_Object** g71) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_iS_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -349,8 +364,8 @@ future->source_type = src_type; future->arg_i0 = g70; future->arg_S1 = g71; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -360,11 +375,12 @@ Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g72) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_S_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -372,8 +388,8 @@ future->source_of_request = who; future->source_type = src_type; future->arg_S0 = g72; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -383,11 +399,12 @@ void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g73) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_s_v; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -395,8 +412,8 @@ future->source_of_request = who; future->source_type = src_type; future->arg_s0 = g73; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; @@ -406,11 +423,12 @@ Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g74, Scheme_Object** g75, int g76) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; Scheme_Object* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_iSi_s; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -420,8 +438,8 @@ future->arg_i0 = g74; future->arg_S1 = g75; future->arg_i2 = g76; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_s; future->retval_s = 0; receive_special_result(future, retval); @@ -431,11 +449,12 @@ void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g77, int g78, Scheme_Object** g79) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_siS_v; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -445,8 +464,8 @@ future->arg_s0 = g77; future->arg_i1 = g78; future->arg_S2 = g79; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; @@ -456,11 +475,12 @@ void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g80) { START_XFORM_SKIP; + Scheme_Future_Thread_State *fts = scheme_future_thread_state; future_t *future; double tm; void* retval; - future = current_ft; + future = fts->current_ft; future->prim_protocol = SIG_z_p; future->prim_func = f; tm = scheme_get_inexact_milliseconds(); @@ -468,8 +488,8 @@ future->source_of_request = who; future->source_type = src_type; future->arg_z0 = g80; - future_do_runtimecall((void*)f, 0); - future = current_ft; + future_do_runtimecall(fts, (void*)f, 0); + future = fts->current_ft; retval = future->retval_p; future->retval_p = 0; diff --git a/src/mzscheme/src/lightning/i386/core.h b/src/mzscheme/src/lightning/i386/core.h index f41bb3cd43..e6f72085a4 100644 --- a/src/mzscheme/src/lightning/i386/core.h +++ b/src/mzscheme/src/lightning/i386/core.h @@ -373,6 +373,8 @@ struct jit_local_state { #define jit_prepare_d(nd) (_jitl.argssize += 2 * (nd)) #ifdef JIT_X86_64 # define jit_pusharg_i(rs) (_jitl.argssize++, MOVQrr(rs, JIT_CALLTMPSTART + _jitl.argssize - 1)) +# define jit_save_argstate(curstate) curstate = _jitl.argssize; +# define jit_restore_argstate(curstate) _jitl.argssize = curstate; # define jit_finish(sub) (jit_shift_args(), (void)jit_calli((sub)), jit_restore_locals()) # define jit_normal_finish(sub) jit_calli((sub)) # define jit_reg_is_arg(reg) ((reg == _EDI) || (reg ==_ESI) || (reg == _EDX)) @@ -396,6 +398,8 @@ struct jit_local_state { (MOVQrr(_R12, _ESI), MOVQrr(_R13, _EDI)) #else # define jit_pusharg_i(rs) PUSHLr(rs) +# define jit_save_argstate(curstate) curstate = _jitl.argssize; +# define jit_restore_argstate(curstate) _jitl.argssize = curstate; # define jit_finish(sub) ((void)jit_calli((sub)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0) # define jit_finishr(reg) (jit_callr((reg)), ADDLir(sizeof(long) * _jitl.argssize, JIT_SP), _jitl.argssize = 0) # define jit_normal_finish(sub) jit_finish(sub) diff --git a/src/mzscheme/src/lightning/ppc/core.h b/src/mzscheme/src/lightning/ppc/core.h index de6f406b3d..534a213651 100644 --- a/src/mzscheme/src/lightning/ppc/core.h +++ b/src/mzscheme/src/lightning/ppc/core.h @@ -246,6 +246,8 @@ struct jit_local_state { #define jit_prolog(n) _jit_prolog(&_jit, (n)) #define jit_pushr_i(rs) STWUrm((rs), -4, 1) #define jit_pusharg_i(rs) (--_jitl.nextarg_puti, MRrr((3 + _jitl.nextarg_putd * 2 + _jitl.nextarg_putf + _jitl.nextarg_puti), (rs))) +#define jit_save_argstate(curstate) (curstate = _jitl.nextarg_puti) +#define jit_restore_argstate(curstate) (_jitl.nextarg_puti = curstate) #define jit_ret() _jit_epilog(&_jit) #define jit_retval_i(rd) MRrr((rd), 3) #define jit_rsbi_i(d, rs, is) jit_chk_ims((is), SUBFICrri((d), (rs), (is)), SUBFCrrr((d), (rs), JIT_AUX)) diff --git a/src/mzscheme/src/mzmark.c b/src/mzscheme/src/mzmark.c index db5cbca0e4..d93dee46de 100644 --- a/src/mzscheme/src/mzmark.c +++ b/src/mzscheme/src/mzmark.c @@ -5420,8 +5420,6 @@ static int future_SIZE(void *p) { static int future_MARK(void *p) { future_t *f = (future_t *)p; - gcMARK(f->runstack); - gcMARK(f->runstack_start); gcMARK(f->orig_lambda); gcMARK(f->arg_s0); gcMARK(f->arg_S0); @@ -5445,8 +5443,6 @@ static int future_MARK(void *p) { static int future_FIXUP(void *p) { future_t *f = (future_t *)p; - gcFIXUP(f->runstack); - gcFIXUP(f->runstack_start); gcFIXUP(f->orig_lambda); gcFIXUP(f->arg_s0); gcFIXUP(f->arg_S0); diff --git a/src/mzscheme/src/mzmarksrc.c b/src/mzscheme/src/mzmarksrc.c index 47c96e960c..7a29d0fc72 100644 --- a/src/mzscheme/src/mzmarksrc.c +++ b/src/mzscheme/src/mzmarksrc.c @@ -2223,8 +2223,6 @@ START future; future { mark: future_t *f = (future_t *)p; - gcMARK(f->runstack); - gcMARK(f->runstack_start); gcMARK(f->orig_lambda); gcMARK(f->arg_s0); gcMARK(f->arg_S0);