From: Dolphin Hawkins Date: Wed, 22 Jun 2016 16:49:12 +0000 (-0700) Subject: Enabled g_mem_set_vtable through the configure option --with-overridable-allocators... X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=6474f8e6126933773a64374c6a38d662bf80d150 Enabled g_mem_set_vtable through the configure option --with-overridable-allocators and exposed through mono_set_allocator_vtable --- diff --git a/eglib/configure.ac b/eglib/configure.ac index 7622701ef45..79af2d995bf 100644 --- a/eglib/configure.ac +++ b/eglib/configure.ac @@ -138,6 +138,17 @@ AC_CHECK_FUNCS(strlcpy stpcpy strtok_r rewinddir vasprintf) AC_CHECK_FUNCS(getrlimit) AC_CHECK_FUNCS(fork execv execve) +AC_ARG_WITH([overidable-allocators], [ --with-overridable-allocators allow g_*alloc/g_free to call custom allocators set via g_mem_set_vtable]) + +if test x$with_overridable_allocators == xyes; then + ENABLE_OVERRIDABLE_ALLOCATORS="1" + AC_MSG_NOTICE([Overridable allocator support enabled]) +else + ENABLE_OVERRIDABLE_ALLOCATORS="0" + AC_MSG_NOTICE([Overridable allocator support disabled]) +fi +AC_SUBST(ENABLE_OVERRIDABLE_ALLOCATORS) + # # Mono currently supports 10.6, but strndup is not available prior to 10.7; avoiding # the detection of strndup on OS X so Mono built on 10.7+ still runs on 10.6. This can be @@ -151,7 +162,7 @@ elif test x$target_ios = xno; then AC_CHECK_FUNCS(strndup getpwuid_r) fi -AM_CONDITIONAL(NEED_VASPRINTF, test x$ac_cv_func_vasprintf = xno ) +AM_CONDITIONAL(NEED_VASPRINTF, test x$ac_cv_func_vasprintf = xno || test x$with_overridable_allocators == xyes) AM_ICONV() AC_SEARCH_LIBS(sqrtf, m) diff --git a/eglib/src/eglib-config.h.in b/eglib/src/eglib-config.h.in index ae7b6d45337..15d1b022062 100644 --- a/eglib/src/eglib-config.h.in +++ b/eglib/src/eglib-config.h.in @@ -23,6 +23,10 @@ #define G_HAVE_ALLOCA_H #endif +#if @ENABLE_OVERRIDABLE_ALLOCATORS@ == 1 +#define G_OVERRIDABLE_ALLOCATORS +#endif + typedef unsigned @GSIZE@ gsize; typedef signed @GSIZE@ gssize; diff --git a/eglib/src/gerror.c b/eglib/src/gerror.c index 2ec089c9956..43fef97cc43 100644 --- a/eglib/src/gerror.c +++ b/eglib/src/gerror.c @@ -28,10 +28,8 @@ #include #include #include +#include #include - -#include "vasprintf.h" - GError * g_error_new (gpointer domain, gint code, const char *format, ...) { @@ -42,7 +40,7 @@ g_error_new (gpointer domain, gint code, const char *format, ...) err->code = code; va_start (args, format); - if (vasprintf (&err->message, format, args) == -1) + if (g_vasprintf (&err->message, format, args) == -1) err->message = g_strdup_printf ("internal: invalid format string %s", format); va_end (args); @@ -57,7 +55,7 @@ g_error_vnew (gpointer domain, gint code, const char *format, va_list ap) err->domain = domain; err->code = code; - if (vasprintf (&err->message, format, ap) == -1) + if (g_vasprintf (&err->message, format, ap) == -1) err->message = g_strdup_printf ("internal: invalid format string %s", format); return err; @@ -77,7 +75,7 @@ g_error_free (GError *error) { g_return_if_fail (error != NULL); - free (error->message); + g_free (error->message); g_free (error); } diff --git a/eglib/src/glib.h b/eglib/src/glib.h index 84ab1ee3f87..74d5be01bab 100644 --- a/eglib/src/glib.h +++ b/eglib/src/glib.h @@ -1,6 +1,5 @@ #ifndef __GLIB_H #define __GLIB_H - #include #include #include @@ -9,6 +8,7 @@ #include #include + #ifdef _MSC_VER #pragma include_alias(, ) #endif @@ -126,6 +126,7 @@ void g_free (void *ptr); gpointer g_realloc (gpointer obj, gsize size); gpointer g_malloc (gsize x); gpointer g_malloc0 (gsize x); +gpointer g_calloc (gsize n, gsize x); gpointer g_try_malloc (gsize x); gpointer g_try_realloc (gpointer obj, gsize size); @@ -138,7 +139,7 @@ gpointer g_try_realloc (gpointer obj, gsize size); #define g_alloca(size) alloca (size) gpointer g_memdup (gconstpointer mem, guint byte_size); -static inline gchar *g_strdup (const gchar *str) { if (str) {return strdup (str);} return NULL; } +static inline gchar *g_strdup (const gchar *str) { if (str) { return (gchar*) g_memdup(str, (guint)strlen (str) + 1); } return NULL; } gchar **g_strdupv (gchar **str_array); typedef struct { @@ -146,11 +147,13 @@ typedef struct { gpointer (*realloc) (gpointer mem, gsize n_bytes); void (*free) (gpointer mem); gpointer (*calloc) (gsize n_blocks, gsize n_block_bytes); - gpointer (*try_malloc) (gsize n_bytes); - gpointer (*try_realloc) (gpointer mem, gsize n_bytes); } GMemVTable; -#define g_mem_set_vtable(x) +#if defined (G_OVERRIDABLE_ALLOCATORS) +void g_mem_set_vtable (GMemVTable* vtable); +#else +#define g_mem_set_vtable (x) +#endif struct _GMemChunk { guint alloc_size; @@ -227,7 +230,11 @@ gint g_snprintf (gchar *string, gulong n, gchar const *format, .. #define g_vfprintf vfprintf #define g_vsprintf vsprintf #define g_vsnprintf vsnprintf +#if defined (G_OVERRIDABLE_ALLOCATORS) || !defined (HAVE_VASPRINTF) +gint g_vasprintf (gchar **ret, const gchar *fmt, va_list ap); +#else #define g_vasprintf vasprintf +#endif gsize g_strlcpy (gchar *dest, const gchar *src, gsize dest_size); gchar *g_stpcpy (gchar *dest, const char *src); diff --git a/eglib/src/gmarkup.c b/eglib/src/gmarkup.c index 6a0b246a957..4e6c6641fef 100644 --- a/eglib/src/gmarkup.c +++ b/eglib/src/gmarkup.c @@ -367,7 +367,7 @@ g_markup_parse_context_parse (GMarkupParseContext *context, if (context->parser.end_element != NULL && context->state == START_ELEMENT){ context->parser.end_element (context, ename, context->user_data, error); if (error != NULL && *error != NULL){ - free (ename); + g_free (ename); goto fail; } } diff --git a/eglib/src/gmem.c b/eglib/src/gmem.c index 565239d1cb8..93276ed2834 100644 --- a/eglib/src/gmem.c +++ b/eglib/src/gmem.c @@ -29,11 +29,33 @@ #include #include +#if defined (G_OVERRIDABLE_ALLOCATORS) + +static GMemVTable sGMemVTable = { malloc, realloc, free, calloc }; + +void +g_mem_set_vtable (GMemVTable* vtable) +{ + sGMemVTable.calloc = vtable->calloc ? vtable->calloc : calloc; + sGMemVTable.realloc = vtable->realloc ? vtable->realloc : realloc; + sGMemVTable.malloc = vtable->malloc ? vtable->malloc : malloc; + sGMemVTable.free = vtable->free ? vtable->free : free; +} +#define G_FREE_INTERNAL sGMemVTable.free +#define G_REALLOC_INTERNAL sGMemVTable.realloc +#define G_CALLOC_INTERNAL sGMemVTable.calloc +#define G_MALLOC_INTERNAL sGMemVTable.malloc +#else +#define G_FREE_INTERNAL free +#define G_REALLOC_INTERNAL realloc +#define G_CALLOC_INTERNAL calloc +#define G_MALLOC_INTERNAL malloc +#endif void g_free (void *ptr) { if (ptr != NULL) - free (ptr); + G_FREE_INTERNAL (ptr); } gpointer @@ -58,7 +80,7 @@ gpointer g_realloc (gpointer obj, gsize size) g_free (obj); return 0; } - ptr = realloc (obj, size); + ptr = G_REALLOC_INTERNAL (obj, size); if (ptr) return ptr; g_error ("Could not allocate %i bytes", size); @@ -70,27 +92,31 @@ g_malloc (gsize x) gpointer ptr; if (!x) return 0; - ptr = malloc (x); + ptr = G_MALLOC_INTERNAL (x); if (ptr) return ptr; g_error ("Could not allocate %i bytes", x); } +gpointer g_calloc (gsize n, gsize x) +{ + gpointer ptr; + if (!x || !n) + return 0; + ptr = G_CALLOC_INTERNAL (n, x); + if (ptr) + return ptr; + g_error ("Could not allocate %i (%i * %i) bytes", x*n, n, x); +} gpointer g_malloc0 (gsize x) { - gpointer ptr; - if (!x) - return 0; - ptr = calloc(1,x); - if (ptr) - return ptr; - g_error ("Could not allocate %i bytes", x); + return g_calloc (1,x); } gpointer g_try_malloc (gsize x) { if (x) - return malloc (x); + return G_MALLOC_INTERNAL (x); return 0; } @@ -98,8 +124,8 @@ gpointer g_try_malloc (gsize x) gpointer g_try_realloc (gpointer obj, gsize size) { if (!size) { - g_free (obj); + G_FREE_INTERNAL (obj); return 0; } - return realloc (obj, size); + return G_REALLOC_INTERNAL (obj, size); } diff --git a/eglib/src/gmisc-win32.c b/eglib/src/gmisc-win32.c index f89f37c2204..625fd15a84f 100644 --- a/eglib/src/gmisc-win32.c +++ b/eglib/src/gmisc-win32.c @@ -92,7 +92,7 @@ g_win32_getlocale(void) gint ccBuf = GetLocaleInfo(lcid, LOCALE_SISO639LANGNAME, buf, 9); buf[ccBuf - 1] = '-'; ccBuf += GetLocaleInfo(lcid, LOCALE_SISO3166CTRYNAME, buf + ccBuf, 9); - return strdup(buf); + return g_strdup (buf); } gboolean @@ -128,6 +128,9 @@ g_get_home_dir (void) } } + g_free (drive); + g_free (path); + return home_dir; } diff --git a/eglib/src/goutput.c b/eglib/src/goutput.c index 779ca96fd21..689493be845 100644 --- a/eglib/src/goutput.c +++ b/eglib/src/goutput.c @@ -49,7 +49,7 @@ g_print (const gchar *format, ...) va_list args; va_start (args, format); - if (vasprintf (&msg, format, args) < 0) + if (g_vasprintf (&msg, format, args) < 0) return; va_end (args); @@ -57,7 +57,7 @@ g_print (const gchar *format, ...) stdout_handler = default_stdout_handler; stdout_handler (msg); - free (msg); + g_free (msg); } void @@ -67,7 +67,7 @@ g_printerr (const gchar *format, ...) va_list args; va_start (args, format); - if (vasprintf (&msg, format, args) < 0) + if (g_vasprintf (&msg, format, args) < 0) return; va_end (args); @@ -75,7 +75,7 @@ g_printerr (const gchar *format, ...) stderr_handler = default_stderr_handler; stderr_handler (msg); - free (msg); + g_free (msg); } GLogLevelFlags @@ -107,11 +107,11 @@ g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, if (!default_log_func) default_log_func = g_log_default_handler; - if (vasprintf (&msg, format, args) < 0) + if (g_vasprintf (&msg, format, args) < 0) return; default_log_func (log_domain, log_level, msg, default_log_func_user_data); - free (msg); + g_free (msg); } void diff --git a/eglib/src/gstr.c b/eglib/src/gstr.c index 3e976c5a2ed..32430550aaa 100644 --- a/eglib/src/gstr.c +++ b/eglib/src/gstr.c @@ -38,7 +38,7 @@ gchar * g_strndup (const gchar *str, gsize n) { -#ifdef HAVE_STRNDUP +#if defined (HAVE_STRNDUP) && !defined (G_OVERRIDABLE_ALLOCATORS) return strndup (str, n); #else if (str) { @@ -133,7 +133,7 @@ g_strdup_vprintf (const gchar *format, va_list args) int n; char *ret; - n = vasprintf (&ret, format, args); + n = g_vasprintf (&ret, format, args); if (n == -1) return NULL; @@ -148,7 +148,7 @@ g_strdup_printf (const gchar *format, ...) int n; va_start (args, format); - n = vasprintf (&ret, format, args); + n = g_vasprintf (&ret, format, args); va_end (args); if (n == -1) return NULL; diff --git a/eglib/src/vasprintf.c b/eglib/src/vasprintf.c index 3c21ca4dc0a..72820b8e961 100644 --- a/eglib/src/vasprintf.c +++ b/eglib/src/vasprintf.c @@ -1,8 +1,9 @@ #include #include #include +#include -int vasprintf(char **ret, const char *fmt, va_list ap) +gint g_vasprintf (gchar **ret, const gchar *fmt, va_list ap) { char *buf; int len; @@ -17,7 +18,7 @@ int vasprintf(char **ret, const char *fmt, va_list ap) len = vsnprintf(NULL, 0, fmt, ap2); #endif - if (len >= 0 && (buf = malloc ((buflen = (size_t) (len + 1)))) != NULL) { + if (len >= 0 && (buf = g_malloc ((buflen = (size_t) (len + 1)))) != NULL) { len = vsnprintf(buf, buflen, fmt, ap); *ret = buf; } else { diff --git a/eglib/src/vasprintf.h b/eglib/src/vasprintf.h index 3d294541a5b..74ea6ae790c 100644 --- a/eglib/src/vasprintf.h +++ b/eglib/src/vasprintf.h @@ -2,10 +2,9 @@ #define __VASPRINTF_H #include -#include -#ifndef HAVE_VASPRINTF -int vasprintf(char **ret, const char *fmt, va_list ap); +#if !defined (HAVE_VASPRINTF) || defined (G_OVERRIDABLE_ALLOCATORS) +int g_vasprintf(char **ret, const char *fmt, va_list ap); #endif #endif /* __VASPRINTF_H */ diff --git a/mono/utils/mono-publib.c b/mono/utils/mono-publib.c index 70271a57f8f..0c7b8249a60 100644 --- a/mono/utils/mono-publib.c +++ b/mono/utils/mono-publib.c @@ -8,3 +8,9 @@ mono_free (void *ptr) g_free (ptr); } +void +mono_set_allocator_vtable (MonoAllocatorVTable* vtable) +{ + GMemVTable g_mem_vtable = { vtable->malloc, vtable->realloc, vtable->free, vtable->calloc}; + g_mem_set_vtable (&g_mem_vtable); +} diff --git a/mono/utils/mono-publib.h b/mono/utils/mono-publib.h index 53d4aa3ea7f..df810a98e1a 100644 --- a/mono/utils/mono-publib.h +++ b/mono/utils/mono-publib.h @@ -53,6 +53,8 @@ typedef unsigned __int64 uint64_t; #endif /* end of compiler-specific stuff */ +#include + #if defined(MONO_DLL_EXPORT) #define MONO_API MONO_API_EXPORT #elif defined(MONO_DLL_IMPORT) @@ -69,6 +71,19 @@ typedef uint32_t mono_unichar4; typedef void (*MonoFunc) (void* data, void* user_data); typedef void (*MonoHFunc) (void* key, void* value, void* user_data); +typedef struct { + void* (*malloc) (size_t n_bytes); + void* (*realloc) (void* mem, size_t n_bytes); + void (*free) (void* mem); + void* (*calloc) (size_t n_blocks, size_t n_block_bytes); +} MonoAllocatorVTable; + +/* + * eglib must be built with overridable allocator support (G_OVERRIDABLE_ALLOCATORS=1) + * for mono_set_allocator_vtable to do anything. + */ +MONO_API void mono_set_allocator_vtable (MonoAllocatorVTable* vtable); + MONO_API void mono_free (void *); #define MONO_CONST_RETURN const diff --git a/msvc/mono.def b/msvc/mono.def index bbc7249634d..2b3f5135483 100644 --- a/msvc/mono.def +++ b/msvc/mono.def @@ -2,6 +2,7 @@ EXPORTS MonoFixupCorEE mono_add_internal_call +mono_set_allocator_vtable mono_aot_get_method mono_aot_register_module mono_array_addr_with_size diff --git a/msvc/monosgen.def b/msvc/monosgen.def index 081051fe5e0..faf3f0b0d62 100644 --- a/msvc/monosgen.def +++ b/msvc/monosgen.def @@ -2,6 +2,7 @@ EXPORTS MonoFixupCorEE mono_add_internal_call +mono_set_allocator_vtable mono_aot_get_method mono_aot_register_module mono_array_addr_with_size diff --git a/samples/embed/teste.c b/samples/embed/teste.c index 2183ccbb50b..6f727a00e1b 100644 --- a/samples/embed/teste.c +++ b/samples/embed/teste.c @@ -1,5 +1,6 @@ #include #include +#include #include /* @@ -31,6 +32,13 @@ static void main_function (MonoDomain *domain, const char *file, int argc, char* mono_jit_exec (domain, assembly, argc, argv); } +static int malloc_count = 0; + +static void* custom_malloc(size_t bytes) +{ + ++malloc_count; + return malloc(bytes); +} int main(int argc, char* argv[]) { @@ -44,6 +52,9 @@ main(int argc, char* argv[]) { } file = argv [1]; + MonoAllocatorVTable mem_vtable = {custom_malloc}; + mono_set_allocator_vtable (&mem_vtable); + /* * Load the default Mono configuration file, this is needed * if you are planning on using the dllmaps defined on the @@ -66,6 +77,9 @@ main(int argc, char* argv[]) { retval = mono_environment_exitcode_get (); mono_jit_cleanup (domain); + + fprintf (stdout, "custom malloc calls = %d\n", malloc_count); + return retval; }