[Gc] GC API: addition of calling conventions. Part 1/4

Ivan Maidanski ivmai at mail.ru
Fri Oct 17 12:40:37 PDT 2008


Hi!

Sometimes (on Win32) it's necessary to specify alternative calling conventions for the exported functions. E.g., with VC++ we may use "-Gr -DGC_CALL=__cdecl" either when building GC or when using it.

The suggested patch for GC gives such flexibility. GC_CALL macro is used (if defined) to specify calling conventions for the exported functions, and, moreover, GC_CALLBACK macro is used to specify calling conventions of the user call-backs (same as GC_CALL if undefined).

In addition, this patch does some minor code non-functional polishing in test.c (removal of unused variable, assuming ANSI C compiler, conditional defining of local variable, addition of missing function prototype).

Bye.

PS. Since the whole post exceeds the limit of 40KB, I cut it down (mechanically) to 4 pieces.

-------------- next part --------------
diff -ru bdwgc/alloc.c updated/bdwgc/alloc.c
--- bdwgc/alloc.c	2008-10-11 13:21:55.000000000 +0400
+++ updated/bdwgc/alloc.c	2008-10-16 18:08:54.000000000 +0400
@@ -111,7 +111,7 @@
 extern GC_bool GC_collection_in_progress(void);
 		/* Collection is in progress, or was abandoned.	*/
 
-int GC_never_stop_func (void) { return(0); }
+int GC_CALLBACK GC_never_stop_func (void) { return(0); }
 
 unsigned long GC_time_limit = TIME_LIMIT;
 
@@ -126,7 +126,7 @@
 #if defined(SMALL_CONFIG) || defined(NO_CLOCK)
 #   define GC_timeout_stop_func GC_never_stop_func
 #else
-  STATIC int GC_timeout_stop_func (void)
+  STATIC int GC_CALLBACK GC_timeout_stop_func (void)
   {
     CLOCK_TYPE current_time;
     static unsigned count = 0;
@@ -444,7 +444,7 @@
     }
 }
 
-GC_API int GC_collect_a_little(void)
+GC_API int GC_CALL GC_collect_a_little(void)
 {
     int result;
     DCL_LOCK_STATE;
@@ -776,7 +776,7 @@
 }
 
 /* Externally callable routine to invoke full, stop-world collection */
-GC_API int GC_try_to_collect(GC_stop_func stop_func)
+GC_API int GC_CALL GC_try_to_collect(GC_stop_func stop_func)
 {
     int result;
     DCL_LOCK_STATE;
@@ -799,7 +799,7 @@
     return(result);
 }
 
-GC_API void GC_gcollect(void)
+GC_API void GC_CALL GC_gcollect(void)
 {
     (void)GC_try_to_collect(GC_never_stop_func);
     if (GC_have_errors) GC_print_all_errors();
@@ -912,7 +912,7 @@
     return(x < y? x : y);
 }
 
-GC_API void GC_set_max_heap_size(GC_word n)
+GC_API void GC_CALL GC_set_max_heap_size(GC_word n)
 {
     GC_max_heapsize = n;
 }
@@ -997,7 +997,7 @@
 
 /* Really returns a bool, but it's externally visible, so that's clumsy. */
 /* Arguments is in bytes.						*/
-GC_API int GC_expand_hp(size_t bytes)
+GC_API int GC_CALL GC_expand_hp(size_t bytes)
 {
     int result;
     DCL_LOCK_STATE;
diff -ru bdwgc/dbg_mlc.c updated/bdwgc/dbg_mlc.c
--- bdwgc/dbg_mlc.c	2008-09-26 14:23:06.000000000 +0400
+++ updated/bdwgc/dbg_mlc.c	2008-10-16 23:09:23.000000000 +0400
@@ -19,8 +19,8 @@
 #include <string.h>
 #include "private/dbg_mlc.h"
 
-void GC_default_print_heap_obj_proc();
-GC_API void GC_register_finalizer_no_order
+void GC_default_print_heap_obj_proc(ptr_t p);
+GC_API void GC_CALL GC_register_finalizer_no_order
     	(void * obj, GC_finalization_proc fn, void * cd,
 	 GC_finalization_proc *ofn, void * *ocd);
 
@@ -329,7 +329,7 @@
 
 static GC_describe_type_fn GC_describe_type_fns[MAXOBJKINDS] = {0};
 
-void GC_register_describe_type_fn(int kind, GC_describe_type_fn fn)
+void GC_CALL GC_register_describe_type_fn(int kind, GC_describe_type_fn fn)
 {
   GC_describe_type_fns[kind] = fn;
 }
@@ -457,13 +457,13 @@
 
 size_t GC_debug_header_size = sizeof(oh);
 
-GC_API void GC_debug_register_displacement(size_t offset)
+GC_API void GC_CALL GC_debug_register_displacement(size_t offset)
 {
     GC_register_displacement(offset);
     GC_register_displacement((word)sizeof(oh) + offset);
 }
 
-GC_API void * GC_debug_malloc(size_t lb, GC_EXTRA_PARAMS)
+GC_API void * GC_CALL GC_debug_malloc(size_t lb, GC_EXTRA_PARAMS)
 {
     void * result = GC_malloc(lb + DEBUG_BYTES);
     
@@ -481,7 +481,8 @@
     return (GC_store_debug_info(result, (word)lb, s, (word)i));
 }
 
-GC_API void * GC_debug_malloc_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
+GC_API void * GC_CALL GC_debug_malloc_ignore_off_page(size_t lb,
+						GC_EXTRA_PARAMS)
 {
     void * result = GC_malloc_ignore_off_page(lb + DEBUG_BYTES);
     
@@ -499,7 +500,8 @@
     return (GC_store_debug_info(result, (word)lb, s, (word)i));
 }
 
-GC_API void * GC_debug_malloc_atomic_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
+GC_API void * GC_CALL GC_debug_malloc_atomic_ignore_off_page(size_t lb,
+							GC_EXTRA_PARAMS)
 {
     void * result = GC_malloc_atomic_ignore_off_page(lb + DEBUG_BYTES);
     
@@ -555,7 +557,7 @@
 # endif
 
 #ifdef STUBBORN_ALLOC
-GC_API void * GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
+GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
 {
     void * result = GC_malloc_stubborn(lb + DEBUG_BYTES);
     
@@ -573,7 +575,7 @@
     return (GC_store_debug_info(result, (word)lb, s, (word)i));
 }
 
-GC_API void GC_debug_change_stubborn(void *p)
+GC_API void GC_CALL GC_debug_change_stubborn(void *p)
 {
     void * q = GC_base(p);
     hdr * hhdr;
@@ -590,7 +592,7 @@
     GC_change_stubborn(q);
 }
 
-GC_API void GC_debug_end_stubborn_change(void *p)
+GC_API void GC_CALL GC_debug_end_stubborn_change(void *p)
 {
     register void * q = GC_base(p);
     register hdr * hhdr;
@@ -609,22 +611,22 @@
 
 #else /* !STUBBORN_ALLOC */
 
-GC_API void * GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
+GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS)
 {
     return GC_debug_malloc(lb, OPT_RA s, i);
 }
 
-GC_API void GC_debug_change_stubborn(void *p)
+GC_API void GC_CALL GC_debug_change_stubborn(void *p)
 {
 }
 
-GC_API void GC_debug_end_stubborn_change(void *p)
+GC_API void GC_CALL GC_debug_end_stubborn_change(void *p)
 {
 }
 
 #endif /* !STUBBORN_ALLOC */
 
-GC_API void * GC_debug_malloc_atomic(size_t lb, GC_EXTRA_PARAMS)
+GC_API void * GC_CALL GC_debug_malloc_atomic(size_t lb, GC_EXTRA_PARAMS)
 {
     void * result = GC_malloc_atomic(lb + DEBUG_BYTES);
     
@@ -642,7 +644,7 @@
     return (GC_store_debug_info(result, (word)lb, s, (word)i));
 }
 
-GC_API char *GC_debug_strdup(const char *str, GC_EXTRA_PARAMS)
+GC_API char * GC_CALL GC_debug_strdup(const char *str, GC_EXTRA_PARAMS)
 {
     char *copy;
     if (str == NULL) return NULL;
@@ -655,7 +657,7 @@
     return copy;
 }
 
-GC_API void * GC_debug_malloc_uncollectable(size_t lb, GC_EXTRA_PARAMS)
+GC_API void * GC_CALL GC_debug_malloc_uncollectable(size_t lb, GC_EXTRA_PARAMS)
 {
     void * result = GC_malloc_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
     
@@ -695,7 +697,7 @@
 }
 #endif /* ATOMIC_UNCOLLECTABLE */
 
-GC_API void GC_debug_free(void * p)
+GC_API void GC_CALL GC_debug_free(void * p)
 {
     ptr_t base;
 #   ifndef SHORT_DBG_HDRS
@@ -770,7 +772,7 @@
 }
 #endif
 
-GC_API void * GC_debug_realloc(void * p, size_t lb, GC_EXTRA_PARAMS)
+GC_API void * GC_CALL GC_debug_realloc(void * p, size_t lb, GC_EXTRA_PARAMS)
 {
     void * base;
 #   ifndef SHORT_DBG_HDRS
@@ -934,7 +936,7 @@
     return((void *)result);
 }
 
-void GC_debug_invoke_finalizer(void * obj, void * data)
+void GC_CALLBACK GC_debug_invoke_finalizer(void * obj, void * data)
 {
     register struct closure * cl = (struct closure *) data;
     
@@ -961,7 +963,8 @@
     }
 }
 
-GC_API void GC_debug_register_finalizer(void * obj, GC_finalization_proc fn,
+GC_API void GC_CALL GC_debug_register_finalizer(void * obj,
+					GC_finalization_proc fn,
     					void * cd, GC_finalization_proc *ofn,
 					void * *ocd)
 {
@@ -983,7 +986,7 @@
     store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);
 }
 
-GC_API void GC_debug_register_finalizer_no_order
+GC_API void GC_CALL GC_debug_register_finalizer_no_order
     				    (void * obj, GC_finalization_proc fn,
     				     void * cd, GC_finalization_proc *ofn,
 				     void * *ocd)
@@ -1008,7 +1011,7 @@
     store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);
 }
 
-GC_API void GC_debug_register_finalizer_unreachable
+GC_API void GC_CALL GC_debug_register_finalizer_unreachable
     				    (void * obj, GC_finalization_proc fn,
     				     void * cd, GC_finalization_proc *ofn,
 				     void * *ocd)
@@ -1033,7 +1036,7 @@
     store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);
 }
 
-GC_API void GC_debug_register_finalizer_ignore_self
+GC_API void GC_CALL GC_debug_register_finalizer_ignore_self
     				    (void * obj, GC_finalization_proc fn,
     				     void * cd, GC_finalization_proc *ofn,
 				     void * *ocd)
@@ -1063,12 +1066,12 @@
 # define RA
 #endif
 
-GC_API void * GC_debug_malloc_replacement(size_t lb)
+GC_API void * GC_CALL GC_debug_malloc_replacement(size_t lb)
 {
     return GC_debug_malloc(lb, RA "unknown", 0);
 }
 
-GC_API void * GC_debug_realloc_replacement(void *p, size_t lb)
+GC_API void * GC_CALL GC_debug_realloc_replacement(void *p, size_t lb)
 {
     return GC_debug_realloc(p, lb, RA "unknown", 0);
 }
diff -ru bdwgc/dyn_load.c updated/bdwgc/dyn_load.c
--- bdwgc/dyn_load.c	2008-10-11 13:24:43.000000000 +0400
+++ updated/bdwgc/dyn_load.c	2008-10-16 19:07:16.000000000 +0400
@@ -382,7 +382,7 @@
 
 /* A user-supplied routine that is called to determine if a DSO must
    be scanned by the gc.  */
-static int (*GC_has_static_roots)(const char *, void *, size_t);
+static int (GC_CALLBACK * GC_has_static_roots)(const char *, void *, size_t);
 
 static int GC_register_dynlib_callback(info, size, ptr)
      struct dl_phdr_info * info;
@@ -1219,9 +1219,8 @@
 }
 
 /* Register a routine to filter dynamic library registration.  */
-GC_API void
-GC_register_has_static_roots_callback
-  (int (*callback)(const char *, void *, size_t)) {
+GC_API void GC_CALL GC_register_has_static_roots_callback
+  (int (GC_CALLBACK * callback)(const char *, void *, size_t)) {
 # ifdef HAVE_DL_ITERATE_PHDR
     GC_has_static_roots = callback;
 # endif
diff -ru bdwgc/finalize.c updated/bdwgc/finalize.c
--- bdwgc/finalize.c	2008-10-14 17:45:15.000000000 +0400
+++ updated/bdwgc/finalize.c	2008-10-16 18:43:18.000000000 +0400
@@ -137,7 +137,7 @@
     *table = new_table;
 }
 
-GC_API int GC_register_disappearing_link(void * * link)
+GC_API int GC_CALL GC_register_disappearing_link(void * * link)
 {
     ptr_t base;
     
@@ -147,7 +147,8 @@
     return(GC_general_register_disappearing_link(link, base));
 }
 
-GC_API int GC_general_register_disappearing_link(void * * link, void * obj)
+GC_API int GC_CALL GC_general_register_disappearing_link(void * * link,
+							void * obj)
 {
     struct disappearing_link *curr_dl;
     size_t index;
@@ -206,7 +207,7 @@
     return(0);
 }
 
-GC_API int GC_unregister_disappearing_link(void * * link)
+GC_API int GC_CALL GC_unregister_disappearing_link(void * * link)
 {
     struct disappearing_link *curr_dl, *prev_dl;
     size_t index;
@@ -421,7 +422,7 @@
 #   endif
 }
 
-GC_API void GC_register_finalizer(void * obj,
+GC_API void GC_CALL GC_register_finalizer(void * obj,
 				  GC_finalization_proc fn, void * cd,
 				  GC_finalization_proc *ofn, void ** ocd)
 {
@@ -429,7 +430,7 @@
     				ocd, GC_normal_finalize_mark_proc);
 }
 
-GC_API void GC_register_finalizer_ignore_self(void * obj,
+GC_API void GC_CALL GC_register_finalizer_ignore_self(void * obj,
 			       GC_finalization_proc fn, void * cd,
 			       GC_finalization_proc *ofn, void ** ocd)
 {
@@ -437,7 +438,7 @@
     				ocd, GC_ignore_self_finalize_mark_proc);
 }
 
-GC_API void GC_register_finalizer_no_order(void * obj,
+GC_API void GC_CALL GC_register_finalizer_no_order(void * obj,
 			       GC_finalization_proc fn, void * cd,
 			       GC_finalization_proc *ofn, void ** ocd)
 {
@@ -448,7 +449,7 @@
 static GC_bool need_unreachable_finalization = FALSE;
 	/* Avoid the work if this isn't used.	*/
 
-GC_API void GC_register_finalizer_unreachable(void * obj,
+GC_API void GC_CALL GC_register_finalizer_unreachable(void * obj,
 			       GC_finalization_proc fn, void * cd,
 			       GC_finalization_proc *ofn, void ** ocd)
 {
@@ -713,7 +714,7 @@
  * This routine is externally callable, so is called without 
  * the allocation lock. 
  */
-GC_API void GC_finalize_all(void)
+GC_API void GC_CALL GC_finalize_all(void)
 {
     DCL_LOCK_STATE;
 
@@ -731,14 +732,14 @@
 /* Returns true if it is worth calling GC_invoke_finalizers. (Useful if	*/
 /* finalizers can only be called from some kind of `safe state' and	*/
 /* getting into that safe state is expensive.)				*/
-GC_API int GC_should_invoke_finalizers(void)
+GC_API int GC_CALL GC_should_invoke_finalizers(void)
 {
     return GC_finalize_now != 0;
 }
 
 /* Invoke finalizers for all objects that are ready to be finalized.	*/
 /* Should be called without allocation lock.				*/
-GC_API int GC_invoke_finalizers(void)
+GC_API int GC_CALL GC_invoke_finalizers(void)
 {
     struct finalizable_object * curr_fo;
     int count = 0;
@@ -833,7 +834,8 @@
     }
 }
 
-GC_API void * GC_call_with_alloc_lock(GC_fn_type fn, void * client_data)
+GC_API void * GC_CALL GC_call_with_alloc_lock(GC_fn_type fn,
+					void * client_data)
 {
     void * result;
     DCL_LOCK_STATE;
diff -ru bdwgc/gcj_mlc.c updated/bdwgc/gcj_mlc.c
--- bdwgc/gcj_mlc.c	2008-09-26 14:03:44.000000000 +0400
+++ updated/bdwgc/gcj_mlc.c	2008-10-16 16:23:09.000000000 +0400
@@ -50,7 +50,8 @@
 ptr_t * GC_gcjdebugobjfreelist;
 
 /* Caller does not hold allocation lock. */
-GC_API void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp)
+GC_API void GC_CALL GC_init_gcj_malloc(int mp_index,
+				void * /* really GC_mark_proc */mp)
 {
     GC_bool ignore_gcj_info;
     DCL_LOCK_STATE;
@@ -134,7 +135,8 @@
 #ifdef THREAD_LOCAL_ALLOC
   void * GC_core_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr)
 #else
-  GC_API void * GC_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr)
+  GC_API void * GC_CALL GC_gcj_malloc(size_t lb,
+				void * ptr_to_struct_containing_descr)
 #endif
 {
     ptr_t op;
@@ -179,7 +181,7 @@
 
 /* Similar to GC_gcj_malloc, but add debug info.  This is allocated	*/
 /* with GC_gcj_debug_kind.						*/
-GC_API void * GC_debug_gcj_malloc(size_t lb,
+GC_API void * GC_CALL GC_debug_gcj_malloc(size_t lb,
 		void * ptr_to_struct_containing_descr, GC_EXTRA_PARAMS)
 {
     void * result;
@@ -206,7 +208,7 @@
     return (GC_store_debug_info(result, (word)lb, s, (word)i));
 }
 
-GC_API void * GC_gcj_malloc_ignore_off_page(size_t lb,
+GC_API void * GC_CALL GC_gcj_malloc_ignore_off_page(size_t lb,
 				     void * ptr_to_struct_containing_descr) 
 {
     ptr_t op;


More information about the Gc mailing list