Enabled g_mem_set_vtable through the configure option --with-overridable-allocators...
authorDolphin Hawkins <dolphin@exitzer0.com>
Wed, 22 Jun 2016 16:49:12 +0000 (09:49 -0700)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 11 Jul 2016 17:23:20 +0000 (13:23 -0400)
16 files changed:
eglib/configure.ac
eglib/src/eglib-config.h.in
eglib/src/gerror.c
eglib/src/glib.h
eglib/src/gmarkup.c
eglib/src/gmem.c
eglib/src/gmisc-win32.c
eglib/src/goutput.c
eglib/src/gstr.c
eglib/src/vasprintf.c
eglib/src/vasprintf.h
mono/utils/mono-publib.c
mono/utils/mono-publib.h
msvc/mono.def
msvc/monosgen.def
samples/embed/teste.c

index 7622701ef455e81d8ce977db10503d84da267ba9..79af2d995bfa3344fc11a24c6c29cae9aae0d5fa 100644 (file)
@@ -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)
 
index ae7b6d45337183fb48d52b2593f26b7d0c0de28f..15d1b022062089b0d97017d5c7461615a71d7c6c 100644 (file)
 #define G_HAVE_ALLOCA_H
 #endif
 
+#if @ENABLE_OVERRIDABLE_ALLOCATORS@ == 1
+#define G_OVERRIDABLE_ALLOCATORS
+#endif
+
 typedef unsigned @GSIZE@ gsize;
 typedef signed   @GSIZE@ gssize;
 
index 2ec089c9956c1053c96bd0b8ea441d2881d54800..43fef97cc434c1a67daa1df2c8e5a8b98f97b439 100644 (file)
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
+#include <config.h>
 #include <glib.h>
-
-#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);
 }
 
index 84ab1ee3f87c0d015302a0993bae88926e9b97a0..74d5be01bab0a8c3e23fc0129d1b8a19d432fc45 100644 (file)
@@ -1,6 +1,5 @@
 #ifndef __GLIB_H
 #define __GLIB_H
-
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
@@ -9,6 +8,7 @@
 #include <ctype.h>
 #include <limits.h>
 
+
 #ifdef _MSC_VER
 #pragma include_alias(<eglib-config.h>, <eglib-config.hw>)
 #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);
index 6a0b246a957bb00a0f814f03948eea3d107e969a..4e6c6641fef542ac4fb758a51d27281baf556340 100644 (file)
@@ -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;
                                        }
                                }
index 565239d1cb81a476030b895e2326d5614441b6b5..93276ed28345caf0c43a5b370c2ed7837538c7c7 100644 (file)
 #include <string.h>
 #include <glib.h>
 
+#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);
 }
index f89f37c22049a780451ff55dcb4d3369ce8d1d10..625fd15a84fa1b81026b732836f9610d10c588ad 100644 (file)
@@ -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;
 }
 
index 779ca96fd217b697b37de49e4fe927d7adc9f478..689493be845202536b599be5f4d646a602ca8db5 100644 (file)
@@ -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
index 3e976c5a2edfe3019a294daad9f45d355f7da250..32430550aaa5a964e4b8c62738fdc8c83d5cf369 100644 (file)
@@ -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;
index 3c21ca4dc0ab9efea7452db19e6fdd0ec78ded91..72820b8e961af577cc0aea2c3dc3bdd66355a62f 100644 (file)
@@ -1,8 +1,9 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <glib.h>
 
-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 {
index 3d294541a5b067ecfc647734550f65861026f5df..74ea6ae790c70f06e0c30ba4609f9d914a9e235a 100644 (file)
@@ -2,10 +2,9 @@
 #define __VASPRINTF_H
 
 #include <stdarg.h>
-#include <config.h>
 
-#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 */
index 70271a57f8f7d48bb7f1ee69c1fc5c73f094a405..0c7b8249a60b2c2b8db69294c79df3245420271c 100644 (file)
@@ -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);
+}
index 53d4aa3ea7f4bed28874b023c70f33b9fd9cd490..df810a98e1ae1c8fccf1e93d7168713b2fc04f5c 100644 (file)
@@ -53,6 +53,8 @@ typedef unsigned __int64      uint64_t;
 
 #endif /* end of compiler-specific stuff */
 
+#include <stdlib.h>
+
 #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
index bbc7249634d1b0d40dfaa9eff49e5e7f819bb33f..2b3f513548304530124e4e8a8aa0bbfe10199769 100644 (file)
@@ -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
index 081051fe5e02ad8f0c9dfa335d0dae455b33f289..faf3f0b0d625e0cd149717401d0bcbeee2f4323b 100644 (file)
@@ -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
index 2183ccbb50bee875511c03a22ae71475208c50fa..6f727a00e1bb0a012ff04ae8ad912981715fbcac 100644 (file)
@@ -1,5 +1,6 @@
 #include <mono/jit/jit.h>
 #include <mono/metadata/environment.h>
+#include <mono/utils/mono-publib.h>
 #include <stdlib.h>
 
 /*
@@ -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;
 }