Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDolphin Hawkins <dolphin@exitzer0.com>2016-06-22 19:49:12 +0300
committerRodrigo Kumpera <kumpera@gmail.com>2016-07-11 20:23:20 +0300
commit6474f8e6126933773a64374c6a38d662bf80d150 (patch)
treea96aaccb30f39794f6da2c8b2c9fb5d818af9833
parentc516dda69361557004044b2c966a11082177033b (diff)
Enabled g_mem_set_vtable through the configure option --with-overridable-allocators and exposed through mono_set_allocator_vtable
-rw-r--r--eglib/configure.ac13
-rw-r--r--eglib/src/eglib-config.h.in4
-rw-r--r--eglib/src/gerror.c10
-rw-r--r--eglib/src/glib.h17
-rw-r--r--eglib/src/gmarkup.c2
-rw-r--r--eglib/src/gmem.c52
-rw-r--r--eglib/src/gmisc-win32.c5
-rw-r--r--eglib/src/goutput.c12
-rw-r--r--eglib/src/gstr.c6
-rw-r--r--eglib/src/vasprintf.c5
-rw-r--r--eglib/src/vasprintf.h5
-rw-r--r--mono/utils/mono-publib.c6
-rw-r--r--mono/utils/mono-publib.h15
-rw-r--r--msvc/mono.def1
-rw-r--r--msvc/monosgen.def1
-rw-r--r--samples/embed/teste.c14
16 files changed, 127 insertions, 41 deletions
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 <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);
}
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 <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);
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 <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);
}
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 <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 {
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 <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 */
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 <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
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 <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;
}