diff --git a/src/foreign/foreign.c b/src/foreign/foreign.c index ae237a110e..b0fd55bed5 100644 --- a/src/foreign/foreign.c +++ b/src/foreign/foreign.c @@ -84,6 +84,10 @@ static void save_errno_values(int kind); +/* This make hides pointerness from cdefstruct so that it + doesn't generate a mark/fixup action: */ +#define NON_GCBALE_PTR(t) t* + /*****************************************************************************/ /* Defining EnumProcessModules for openning `self' as an ffi-lib */ @@ -161,7 +165,7 @@ END_XFORM_SKIP; static Scheme_Type ffi_lib_tag; typedef struct ffi_lib_struct { Scheme_Object so; - void* handle; + NON_GCBALE_PTR(void) handle; Scheme_Object* name; Scheme_Hash_Table* objects; } ffi_lib_struct; @@ -180,14 +184,12 @@ int ffi_lib_SIZE(void *p) { } int ffi_lib_MARK(void *p) { ffi_lib_struct *s = (ffi_lib_struct *)p; - gcMARK(s->handle); gcMARK(s->name); gcMARK(s->objects); return gcBYTES_TO_WORDS(sizeof(ffi_lib_struct)); } int ffi_lib_FIXUP(void *p) { ffi_lib_struct *s = (ffi_lib_struct *)p; - gcFIXUP(s->handle); gcFIXUP(s->name); gcFIXUP(s->objects); return gcBYTES_TO_WORDS(sizeof(ffi_lib_struct)); @@ -271,9 +273,9 @@ static Scheme_Object *foreign_ffi_lib_name(int argc, Scheme_Object *argv[]) static Scheme_Type ffi_obj_tag; typedef struct ffi_obj_struct { Scheme_Object so; - void* obj; + NON_GCBALE_PTR(void) obj; char* name; - ffi_lib_struct* lib; + NON_GCBALE_PTR(ffi_lib_struct) lib; } ffi_obj_struct; #define SCHEME_FFIOBJP(x) (SCHEME_TYPE(x)==ffi_obj_tag) #define MYNAME "ffi-obj?" @@ -290,16 +292,12 @@ int ffi_obj_SIZE(void *p) { } int ffi_obj_MARK(void *p) { ffi_obj_struct *s = (ffi_obj_struct *)p; - gcMARK(s->obj); gcMARK(s->name); - gcMARK(s->lib); return gcBYTES_TO_WORDS(sizeof(ffi_obj_struct)); } int ffi_obj_FIXUP(void *p) { ffi_obj_struct *s = (ffi_obj_struct *)p; - gcFIXUP(s->obj); gcFIXUP(s->name); - gcFIXUP(s->lib); return gcBYTES_TO_WORDS(sizeof(ffi_obj_struct)); } END_XFORM_SKIP; @@ -1049,13 +1047,13 @@ ffi_abi sym_to_abi(char *who, Scheme_Object *sym) if (SCHEME_FALSEP(sym) || SAME_OBJ(sym, default_sym)) return FFI_DEFAULT_ABI; else if (SAME_OBJ(sym, sysv_sym)) { -#if defined(WINDOWS_DYNAMIC_LOAD) && !defined(_WIN64) +#ifdef WINDOWS_DYNAMIC_LOAD return FFI_SYSV; #else scheme_signal_error("%s: ABI not implemented: %V", who, sym); #endif } else if (SAME_OBJ(sym, stdcall_sym)) { -#if defined(WINDOWS_DYNAMIC_LOAD) && !defined(_WIN64) +#ifdef WINDOWS_DYNAMIC_LOAD return FFI_STDCALL; #else scheme_signal_error("%s: ABI not implemented: %V", who, sym); @@ -1153,7 +1151,7 @@ static Scheme_Object *foreign_make_cstruct_type(int argc, Scheme_Object *argv[]) static Scheme_Type ffi_callback_tag; typedef struct ffi_callback_struct { Scheme_Object so; - void* callback; + NON_GCBALE_PTR(void) callback; Scheme_Object* proc; Scheme_Object* itypes; Scheme_Object* otype; @@ -1174,7 +1172,6 @@ int ffi_callback_SIZE(void *p) { } int ffi_callback_MARK(void *p) { ffi_callback_struct *s = (ffi_callback_struct *)p; - gcMARK(s->callback); gcMARK(s->proc); gcMARK(s->itypes); gcMARK(s->otype); @@ -1183,7 +1180,6 @@ int ffi_callback_MARK(void *p) { } int ffi_callback_FIXUP(void *p) { ffi_callback_struct *s = (ffi_callback_struct *)p; - gcFIXUP(s->callback); gcFIXUP(s->proc); gcFIXUP(s->itypes); gcFIXUP(s->otype); diff --git a/src/foreign/foreign.rktc b/src/foreign/foreign.rktc index f517cfe844..de0a0609b0 100755 --- a/src/foreign/foreign.rktc +++ b/src/foreign/foreign.rktc @@ -87,6 +87,10 @@ exec racket "$0" > `echo "$0" | sed 's/rktc$/c/'` "$0" static void save_errno_values(int kind); +/* This make hides pointerness from cdefstruct so that it + doesn't generate a mark/fixup action: */ +#define NON_GCBALE_PTR(t) t* + /*****************************************************************************/ /* Defining EnumProcessModules for openning `self' as an ffi-lib */ @@ -161,7 +165,7 @@ END_XFORM_SKIP; /* Library objects */ @cdefstruct[ffi-lib - [handle "void*"] + [handle "NON_GCBALE_PTR(void)"] [name "Scheme_Object*"] [objects "Scheme_Hash_Table*"]] @@ -228,9 +232,9 @@ THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs); /* Pull pointers (mostly functions) out of ffi-lib objects */ @cdefstruct[ffi-obj - [obj "void*"] + [obj "NON_GCBALE_PTR(void)"] [name "char*"] - [lib "ffi_lib_struct*"]] + [lib "NON_GCBALE_PTR(ffi_lib_struct)"]] /* (ffi-obj objname ffi-lib-or-libname) -> ffi-obj */ @cdefine[ffi-obj 2]{ @@ -972,7 +976,7 @@ ffi_abi sym_to_abi(char *who, Scheme_Object *sym) /* Callback type */ @cdefstruct[ffi-callback - [callback "void*"] + [callback "NON_GCBALE_PTR(void)"] [proc "Scheme_Object*"] [itypes "Scheme_Object*"] [otype "Scheme_Object*"] diff --git a/src/racket/src/salloc.c b/src/racket/src/salloc.c index b8a3707ddd..497f7dbe14 100644 --- a/src/racket/src/salloc.c +++ b/src/racket/src/salloc.c @@ -1222,10 +1222,11 @@ void scheme_reset_finalizations(void) current_lifetime++; } -static void do_next_finalization(void *o, void *data) +static void do_next_finalization(void *o, void *_data) { - Finalizations *fns = *(Finalizations **)data; + Finalizations *fns = *(Finalizations **)_data; Finalization *fn; + GC_CAN_IGNORE void *data; if (fns->lifetime != current_lifetime) return; @@ -1234,7 +1235,7 @@ static void do_next_finalization(void *o, void *data) if (fns->scheme_first->next || fns->ext_f || fns->prim_first) { /* Re-install low-level finalizer and run a scheme finalizer */ GC_register_eager_finalizer(o, fns->scheme_first->next ? 1 : 2, - do_next_finalization, data, NULL, NULL); + do_next_finalization, _data, NULL, NULL); } fn = fns->scheme_first; @@ -1244,15 +1245,26 @@ static void do_next_finalization(void *o, void *data) else fn->next->prev = NULL; - fn->f(o, fn->data); + /* Clear out the `data' pointer, in case it refers to + memory that is free()ed, in which case the GC might + later take over the same page of memory. */ + data = fn->data; + fn->data = NULL; + + fn->f(o, data); return; } - if (fns->ext_f) - fns->ext_f(o, fns->ext_data); + if (fns->ext_f) { + data = fns->ext_data; + fns->ext_data = NULL; + fns->ext_f(o, data); + } for (fn = fns->prim_first; fn; fn = fn->next) { - fn->f(o, fn->data); + data = fn->data; + fn->data = NULL; + fn->f(o, data); } }