From de1c5b1e9f7e9e8bbf46de7ffd68a392d122da32 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Wed, 1 Feb 2012 23:45:20 +0400 Subject: [PATCH] Add support of GC_ATTR_MALLOC for MS VS * include/gc.h (GC_malloc, GC_malloc_atomic, GC_strdup, GC_strndup, GC_malloc_uncollectable, GC_malloc_stubborn, GC_memalign, GC_malloc_ignore_off_page, GC_malloc_atomic_ignore_off_page, GC_malloc_atomic_uncollectable, GC_debug_malloc_atomic_uncollectable, GC_debug_malloc, GC_debug_malloc_atomic, GC_debug_strdup, GC_debug_strndup, GC_debug_malloc_uncollectable, GC_debug_malloc_stubborn, GC_debug_malloc_ignore_off_page, GC_debug_malloc_atomic_ignore_off_page, GC_debug_malloc_replacement, GC_debug_realloc_replacement, GC_wcsdup, GC_debug_wcsdup): Move GC_ATTR_MALLOC and GC_ATTR_ALLOC_SIZE from the function declaration tail to the beginning (just after GC_API) for compatibility with MS VC. * include/gc_gcj.h (GC_gcj_malloc, GC_debug_gcj_malloc, GC_gcj_malloc_ignore_off_page): Likewise. * include/gc_config_macros.h (GC_ATTR_MALLOC): Implement for MS VC (Visual Studio) v14+. --- include/gc.h | 101 ++++++++++++++++++------------------- include/gc_config_macros.h | 8 ++- include/gc_gcj.h | 21 ++++---- 3 files changed, 66 insertions(+), 64 deletions(-) diff --git a/include/gc.h b/include/gc.h index 18491571..8befce8d 100644 --- a/include/gc.h +++ b/include/gc.h @@ -374,20 +374,21 @@ GC_API void GC_CALL GC_init(void); /* GC_non_gc_bytes appropriately. */ /* Note that the GC_malloc_stubborn support doesn't really exist */ /* anymore. MANUAL_VDB provides comparable functionality. */ -GC_API void * GC_CALL GC_malloc(size_t /* size_in_bytes */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API void * GC_CALL GC_malloc_atomic(size_t /* size_in_bytes */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API char * GC_CALL GC_strdup(const char *) GC_ATTR_MALLOC; -GC_API char * GC_CALL GC_strndup(const char *, size_t) GC_ATTR_MALLOC; -GC_API void * GC_CALL GC_malloc_uncollectable(size_t /* size_in_bytes */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API void * GC_CALL GC_malloc_stubborn(size_t /* size_in_bytes */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_malloc(size_t /* size_in_bytes */); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_malloc_atomic(size_t /* size_in_bytes */); +GC_API GC_ATTR_MALLOC char * GC_CALL GC_strdup(const char *); +GC_API GC_ATTR_MALLOC char * GC_CALL + GC_strndup(const char *, size_t); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_malloc_uncollectable(size_t /* size_in_bytes */); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_malloc_stubborn(size_t /* size_in_bytes */); /* GC_memalign() is not well tested. */ -GC_API void * GC_CALL GC_memalign(size_t /* align */, size_t /* lb */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(2); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(2) void * GC_CALL + GC_memalign(size_t /* align */, size_t /* lb */); GC_API int GC_CALL GC_posix_memalign(void ** /* memptr */, size_t /* align */, size_t /* lb */); @@ -647,10 +648,10 @@ GC_API int GC_CALL GC_collect_a_little(void); /* for arrays likely to be larger than 100K or so. For other systems, */ /* or if the collector is not configured to recognize all interior */ /* pointers, the threshold is normally much higher. */ -GC_API void * GC_CALL GC_malloc_ignore_off_page(size_t /* lb */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API void * GC_CALL GC_malloc_atomic_ignore_off_page(size_t /* lb */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_malloc_ignore_off_page(size_t /* lb */); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_malloc_atomic_ignore_off_page(size_t /* lb */); #ifdef GC_ADD_CALLER # define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__ @@ -662,37 +663,32 @@ GC_API void * GC_CALL GC_malloc_atomic_ignore_off_page(size_t /* lb */) /* The following is only defined if the library has been suitably */ /* compiled: */ -GC_API void * GC_CALL GC_malloc_atomic_uncollectable( - size_t /* size_in_bytes */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API void * GC_CALL GC_debug_malloc_atomic_uncollectable(size_t, - GC_EXTRA_PARAMS) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_malloc_atomic_uncollectable(size_t /* size_in_bytes */); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_debug_malloc_atomic_uncollectable(size_t, GC_EXTRA_PARAMS); /* Debugging (annotated) allocation. GC_gcollect will check */ /* objects allocated in this way for overwrites, etc. */ -GC_API void * GC_CALL GC_debug_malloc(size_t /* size_in_bytes */, - GC_EXTRA_PARAMS) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API void * GC_CALL GC_debug_malloc_atomic(size_t /* size_in_bytes */, - GC_EXTRA_PARAMS) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API char * GC_CALL GC_debug_strdup(const char *, - GC_EXTRA_PARAMS) GC_ATTR_MALLOC; -GC_API char * GC_CALL GC_debug_strndup(const char *, size_t, - GC_EXTRA_PARAMS) GC_ATTR_MALLOC; -GC_API void * GC_CALL GC_debug_malloc_uncollectable( - size_t /* size_in_bytes */, GC_EXTRA_PARAMS) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t /* size_in_bytes */, - GC_EXTRA_PARAMS) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API void * GC_CALL GC_debug_malloc_ignore_off_page( - size_t /* size_in_bytes */, GC_EXTRA_PARAMS) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API void * GC_CALL GC_debug_malloc_atomic_ignore_off_page( - size_t /* size_in_bytes */, GC_EXTRA_PARAMS) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_debug_malloc(size_t /* size_in_bytes */, GC_EXTRA_PARAMS); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_debug_malloc_atomic(size_t /* size_in_bytes */, GC_EXTRA_PARAMS); +GC_API GC_ATTR_MALLOC char * GC_CALL + GC_debug_strdup(const char *, GC_EXTRA_PARAMS); +GC_API GC_ATTR_MALLOC char * GC_CALL + GC_debug_strndup(const char *, size_t, GC_EXTRA_PARAMS); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_debug_malloc_uncollectable(size_t /* size_in_bytes */, + GC_EXTRA_PARAMS); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_debug_malloc_stubborn(size_t /* size_in_bytes */, GC_EXTRA_PARAMS); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_debug_malloc_ignore_off_page(size_t /* size_in_bytes */, + GC_EXTRA_PARAMS); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_debug_malloc_atomic_ignore_off_page(size_t /* size_in_bytes */, + GC_EXTRA_PARAMS); GC_API void GC_CALL GC_debug_free(void *); GC_API void * GC_CALL GC_debug_realloc(void * /* old_object */, size_t /* new_size_in_bytes */, GC_EXTRA_PARAMS) @@ -712,11 +708,11 @@ GC_API void GC_CALL GC_debug_end_stubborn_change(const void *); /* platforms it may be more convenient not to recompile, e.g. for */ /* leak detection. This can be accomplished by instructing the */ /* linker to replace malloc/realloc with these. */ -GC_API void * GC_CALL GC_debug_malloc_replacement(size_t /* size_in_bytes */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); -GC_API void * GC_CALL GC_debug_realloc_replacement(void * /* object_addr */, - size_t /* size_in_bytes */) - /* 'realloc' attr */ GC_ATTR_ALLOC_SIZE(2); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_debug_malloc_replacement(size_t /* size_in_bytes */); +GC_API /* 'realloc' attr */ GC_ATTR_ALLOC_SIZE(2) void * GC_CALL + GC_debug_realloc_replacement(void * /* object_addr */, + size_t /* size_in_bytes */); #ifdef GC_DEBUG_REPLACEMENT # define GC_MALLOC(sz) GC_debug_malloc_replacement(sz) @@ -797,9 +793,10 @@ GC_API void * GC_CALL GC_debug_realloc_replacement(void * /* object_addr */, #ifdef GC_REQUIRE_WCSDUP /* This might be unavailable on some targets (or not needed). */ /* wchar_t should be defined in stddef.h */ - GC_API wchar_t * GC_CALL GC_wcsdup(const wchar_t *) GC_ATTR_MALLOC; - GC_API wchar_t * GC_CALL GC_debug_wcsdup(const wchar_t *, - GC_EXTRA_PARAMS) GC_ATTR_MALLOC; + GC_API GC_ATTR_MALLOC wchar_t * GC_CALL + GC_wcsdup(const wchar_t *); + GC_API GC_ATTR_MALLOC wchar_t * GC_CALL + GC_debug_wcsdup(const wchar_t *, GC_EXTRA_PARAMS); # ifdef GC_DEBUG # define GC_WCSDUP(s) GC_debug_wcsdup(s, GC_EXTRAS) # else diff --git a/include/gc_config_macros.h b/include/gc_config_macros.h index d3b5f6a6..0aab03b1 100644 --- a/include/gc_config_macros.h +++ b/include/gc_config_macros.h @@ -220,9 +220,13 @@ /* non-NULL pointer it returns cannot alias any other pointer valid */ /* when the function returns). If the client code violates this rule */ /* by using custom GC_oom_func then define GC_OOM_FUNC_RETURNS_ALIAS. */ -# if !defined(GC_OOM_FUNC_RETURNS_ALIAS) && defined(__GNUC__) \ - && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +# ifdef GC_OOM_FUNC_RETURNS_ALIAS +# define GC_ATTR_MALLOC /* empty */ +# elif defined(__GNUC__) && (__GNUC__ > 3 \ + || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) # define GC_ATTR_MALLOC __attribute__((__malloc__)) +# elif defined(_MSC_VER) && _MSC_VER >= 14 +# define GC_ATTR_MALLOC __declspec(noalias) __declspec(restrict) # else # define GC_ATTR_MALLOC # endif diff --git a/include/gc_gcj.h b/include/gc_gcj.h index 78658785..eba714c6 100644 --- a/include/gc_gcj.h +++ b/include/gc_gcj.h @@ -72,21 +72,22 @@ GC_API void GC_CALL GC_init_gcj_malloc(int /* mp_index */, /* Allocate an object, clear it, and store the pointer to the */ /* type structure (vtable in gcj). */ /* This adds a byte at the end of the object if GC_malloc would.*/ -GC_API void * GC_CALL GC_gcj_malloc(size_t /* lb */, - void * /* ptr_to_struct_containing_descr */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_gcj_malloc(size_t /* lb */, + void * /* ptr_to_struct_containing_descr */); + /* The debug versions allocate such that the specified mark_proc */ /* is always invoked. */ -GC_API void * GC_CALL GC_debug_gcj_malloc(size_t /* lb */, - void * /* ptr_to_struct_containing_descr */, - GC_EXTRA_PARAMS) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_debug_gcj_malloc(size_t /* lb */, + void * /* ptr_to_struct_containing_descr */, + GC_EXTRA_PARAMS); /* Similar to GC_gcj_malloc, but assumes that a pointer to near the */ /* beginning of the resulting object is always maintained. */ -GC_API void * GC_CALL GC_gcj_malloc_ignore_off_page(size_t /* lb */, - void * /* ptr_to_struct_containing_descr */) - GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1); +GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL + GC_gcj_malloc_ignore_off_page(size_t /* lb */, + void * /* ptr_to_struct_containing_descr */); /* The kind numbers of normal and debug gcj objects. */ /* Useful only for debug support, we hope. */ -- 2.40.0