[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[platform/upstream/glib.git] / glib / gmem.c
index 0e1b5cf..6a108ee 100644 (file)
@@ -12,9 +12,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
@@ -41,8 +39,6 @@
 #include "gtestutils.h"
 #include "gthread.h"
 #include "glib_trace.h"
-#include "glib-ctor.h"
-
 
 #define MEM_PROFILE_TABLE_SIZE 4096
 
 /* notes on macros:
  * having G_DISABLE_CHECKS defined disables use of glib_mem_profiler_table and
  * g_mem_profile().
- * REALLOC_0_WORKS is defined if g_realloc (NULL, x) works.
- * SANE_MALLOC_PROTOS is defined if the systems malloc() and friends functions
- * match the corresponding GLib prototypes, keep configure.ac and gmem.h in sync here.
- * g_mem_gc_friendly is TRUE, freed memory should be 0-wiped.
- */
-
-#ifdef ENABLE_GC_FRIENDLY_DEFAULT
-gboolean g_mem_gc_friendly = TRUE;
-#else
-/**
- * g_mem_gc_friendly:
- * 
- * This variable is %TRUE if the <envar>G_DEBUG</envar> environment variable
- * includes the key <link linkend="G_DEBUG">gc-friendly</link>.
+ * If g_mem_gc_friendly is TRUE, freed memory should be 0-wiped.
  */
-gboolean g_mem_gc_friendly = FALSE;
-#endif
-
-GLIB_CTOR (g_mem_init_nomessage)
-{
-  gchar buffer[1024];
-  const gchar *val;
-  const GDebugKey keys[] = {
-    { "gc-friendly", 1 },
-  };
-  gint flags;
-
-  /* don't use g_malloc/g_message here */
-  val = _g_getenv_nomalloc ("G_DEBUG", buffer);
-  flags = !val ? 0 : g_parse_debug_string (val, keys, G_N_ELEMENTS (keys));
-  if (flags & 1)        /* gc-friendly */
-    {
-      g_mem_gc_friendly = TRUE;
-    }
-}
-
-/* --- malloc wrappers --- */
-#ifndef        REALLOC_0_WORKS
-static gpointer
-standard_realloc (gpointer mem,
-                 gsize    n_bytes)
-{
-  if (!mem)
-    return malloc (n_bytes);
-  else
-    return realloc (mem, n_bytes);
-}
-#endif /* !REALLOC_0_WORKS */
-
-#ifdef SANE_MALLOC_PROTOS
-#  define standard_malloc      malloc
-#  ifdef REALLOC_0_WORKS
-#    define standard_realloc   realloc
-#  endif /* REALLOC_0_WORKS */
-#  define standard_free                free
-#  define standard_calloc      calloc
-#  define standard_try_malloc  malloc
-#  define standard_try_realloc realloc
-#else  /* !SANE_MALLOC_PROTOS */
-static gpointer
-standard_malloc (gsize n_bytes)
-{
-  return malloc (n_bytes);
-}
-#  ifdef REALLOC_0_WORKS
-static gpointer
-standard_realloc (gpointer mem,
-                 gsize    n_bytes)
-{
-  return realloc (mem, n_bytes);
-}
-#  endif /* REALLOC_0_WORKS */
-static void
-standard_free (gpointer mem)
-{
-  free (mem);
-}
-static gpointer
-standard_calloc (gsize n_blocks,
-                gsize n_bytes)
-{
-  return calloc (n_blocks, n_bytes);
-}
-#define        standard_try_malloc     standard_malloc
-#define        standard_try_realloc    standard_realloc
-#endif /* !SANE_MALLOC_PROTOS */
-
 
 /* --- variables --- */
 static GMemVTable glib_mem_vtable = {
-  standard_malloc,
-  standard_realloc,
-  standard_free,
-  standard_calloc,
-  standard_try_malloc,
-  standard_try_realloc,
+  malloc,
+  realloc,
+  free,
+  calloc,
+  malloc,
+  realloc,
 };
 
 /**
@@ -155,18 +66,15 @@ static GMemVTable glib_mem_vtable = {
  * 
  * These functions provide support for allocating and freeing memory.
  * 
- * <note>
  * If any call to allocate memory fails, the application is terminated.
  * This also means that there is no need to check if the call succeeded.
- * </note>
- * 
- * <note>
- * It's important to match g_malloc() with g_free(), plain malloc() with free(),
- * and (if you're using C++) new with delete and new[] with delete[]. Otherwise
- * bad things can happen, since these allocators may use different memory
- * pools (and new/delete call constructors and destructors). See also
- * g_mem_set_vtable().
- * </note>
+ * 
+ * It's important to match g_malloc() (and wrappers such as g_new()) with
+ * g_free(), g_slice_alloc() (and wrappers such as g_slice_new()) with
+ * g_slice_free(), plain malloc() with free(), and (if you're using C++)
+ * new with delete and new[] with delete[]. Otherwise bad things can happen,
+ * since these allocators may use different memory pools (and new/delete call
+ * constructors and destructors). See also g_mem_set_vtable().
  */
 
 /* --- functions --- */
@@ -182,8 +90,6 @@ static GMemVTable glib_mem_vtable = {
 gpointer
 g_malloc (gsize n_bytes)
 {
-  GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
   if (G_LIKELY (n_bytes))
     {
       gpointer mem;
@@ -214,8 +120,6 @@ g_malloc (gsize n_bytes)
 gpointer
 g_malloc0 (gsize n_bytes)
 {
-  GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
   if (G_LIKELY (n_bytes))
     {
       gpointer mem;
@@ -236,7 +140,7 @@ g_malloc0 (gsize n_bytes)
 
 /**
  * g_realloc:
- * @mem: the memory to reallocate
+ * @mem: (allow-none): the memory to reallocate
  * @n_bytes: new size of the memory in bytes
  * 
  * Reallocates the memory pointed to by @mem, so that it now has space for
@@ -253,8 +157,6 @@ g_realloc (gpointer mem,
 {
   gpointer newmem;
 
-  GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
   if (G_LIKELY (n_bytes))
     {
       newmem = glib_mem_vtable.realloc (mem, n_bytes);
@@ -276,7 +178,7 @@ g_realloc (gpointer mem,
 
 /**
  * g_free:
- * @mem: the memory to free
+ * @mem: (allow-none): the memory to free
  * 
  * Frees the memory pointed to by @mem.
  * If @mem is %NULL it simply returns.
@@ -284,14 +186,45 @@ g_realloc (gpointer mem,
 void
 g_free (gpointer mem)
 {
-  GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
   if (G_LIKELY (mem))
     glib_mem_vtable.free (mem);
   TRACE(GLIB_MEM_FREE((void*) mem));
 }
 
 /**
+ * g_clear_pointer: (skip)
+ * @pp: a pointer to a variable, struct member etc. holding a pointer
+ * @destroy: a function to which a gpointer can be passed, to destroy *@pp
+ *
+ * Clears a reference to a variable.
+ *
+ * @pp must not be %NULL.
+ *
+ * If the reference is %NULL then this function does nothing.
+ * Otherwise, the variable is destroyed using @destroy and the
+ * pointer is set to %NULL.
+ *
+ * A macro is also included that allows this function to be used without
+ * pointer casts.
+ *
+ * Since: 2.34
+ **/
+#undef g_clear_pointer
+void
+g_clear_pointer (gpointer      *pp,
+                 GDestroyNotify destroy)
+{
+  gpointer _p;
+
+  _p = *pp;
+  if (_p)
+    {
+      *pp = NULL;
+      destroy (_p);
+    }
+}
+
+/**
  * g_try_malloc:
  * @n_bytes: number of bytes to allocate.
  * 
@@ -305,8 +238,6 @@ g_try_malloc (gsize n_bytes)
 {
   gpointer mem;
 
-  GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
   if (G_LIKELY (n_bytes))
     mem = glib_mem_vtable.try_malloc (n_bytes);
   else
@@ -332,8 +263,6 @@ g_try_malloc0 (gsize n_bytes)
 {
   gpointer mem;
 
-  GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
   if (G_LIKELY (n_bytes))
     mem = glib_mem_vtable.try_malloc (n_bytes);
   else
@@ -347,7 +276,7 @@ g_try_malloc0 (gsize n_bytes)
 
 /**
  * g_try_realloc:
- * @mem: previously-allocated memory, or %NULL.
+ * @mem: (allow-none): previously-allocated memory, or %NULL.
  * @n_bytes: number of bytes to allocate.
  * 
  * Attempts to realloc @mem to a new size, @n_bytes, and returns %NULL
@@ -362,8 +291,6 @@ g_try_realloc (gpointer mem,
 {
   gpointer newmem;
 
-  GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
   if (G_LIKELY (n_bytes))
     newmem = glib_mem_vtable.try_realloc (mem, n_bytes);
   else
@@ -398,8 +325,6 @@ g_malloc_n (gsize n_blocks,
 {
   if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
     {
-      GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
       g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
                G_STRLOC, n_blocks, n_block_bytes);
     }
@@ -424,8 +349,6 @@ g_malloc0_n (gsize n_blocks,
 {
   if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
     {
-      GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
       g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
                G_STRLOC, n_blocks, n_block_bytes);
     }
@@ -435,7 +358,7 @@ g_malloc0_n (gsize n_blocks,
 
 /**
  * g_realloc_n:
- * @mem: the memory to reallocate
+ * @mem: (allow-none): the memory to reallocate
  * @n_blocks: the number of blocks to allocate
  * @n_block_bytes: the size of each block in bytes
  * 
@@ -452,8 +375,6 @@ g_realloc_n (gpointer mem,
 {
   if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
     {
-      GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
       g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
                G_STRLOC, n_blocks, n_block_bytes);
     }
@@ -505,7 +426,7 @@ g_try_malloc0_n (gsize n_blocks,
 
 /**
  * g_try_realloc_n:
- * @mem: previously-allocated memory, or %NULL.
+ * @mem: (allow-none): previously-allocated memory, or %NULL.
  * @n_blocks: the number of blocks to allocate
  * @n_block_bytes: the size of each block in bytes
  * 
@@ -544,7 +465,7 @@ fallback_calloc (gsize n_blocks,
 static gboolean vtable_set = FALSE;
 
 /**
- * g_mem_is_system_malloc
+ * g_mem_is_system_malloc:
  * 
  * Checks whether the allocator used by g_malloc() is the system's
  * malloc implementation. If it returns %TRUE memory allocated with
@@ -554,7 +475,7 @@ static gboolean vtable_set = FALSE;
  *
  * A different allocator can be set using g_mem_set_vtable().
  *
- * Return value: if %TRUE, malloc() and g_malloc() can be mixed.
+ * Returns: if %TRUE, malloc() and g_malloc() can be mixed.
  **/
 gboolean
 g_mem_is_system_malloc (void)
@@ -566,13 +487,17 @@ g_mem_is_system_malloc (void)
  * g_mem_set_vtable:
  * @vtable: table of memory allocation routines.
  * 
- * Sets the #GMemVTable to use for memory allocation. You can use this to provide
- * custom memory allocation routines. <emphasis>This function must be called
- * before using any other GLib functions.</emphasis> The @vtable only needs to
- * provide malloc(), realloc(), and free() functions; GLib can provide default
- * implementations of the others. The malloc() and realloc() implementations
- * should return %NULL on failure, GLib will handle error-checking for you.
- * @vtable is copied, so need not persist after this function has been called.
+ * Sets the #GMemVTable to use for memory allocation. You can use this
+ * to provide custom memory allocation routines.
+ *
+ * The @vtable only needs to provide malloc(), realloc(), and free()
+ * functions; GLib can provide default implementations of the others.
+ * The malloc() and realloc() implementations should return %NULL on
+ * failure, GLib will handle error-checking for you. @vtable is copied,
+ * so need not persist after this function has been called.
+ *
+ * Note that this function must be called before using any other GLib
+ * functions.
  */
 void
 g_mem_set_vtable (GMemVTable *vtable)
@@ -623,12 +548,7 @@ static guint *profile_data = NULL;
 static gsize profile_allocs = 0;
 static gsize profile_zinit = 0;
 static gsize profile_frees = 0;
-static GMutex gmem_profile_mutex = G_MUTEX_INIT;
-#ifdef  G_ENABLE_DEBUG
-static volatile gsize g_trap_free_size = 0;
-static volatile gsize g_trap_realloc_size = 0;
-static volatile gsize g_trap_malloc_size = 0;
-#endif  /* G_ENABLE_DEBUG */
+static GMutex gmem_profile_mutex;
 
 #define        PROFILE_TABLE(f1,f2,f3)   ( ( ((f3) << 2) | ((f2) << 1) | (f1) ) * (MEM_PROFILE_TABLE_SIZE + 1))
 
@@ -640,8 +560,8 @@ profiler_log (ProfilerJob job,
   g_mutex_lock (&gmem_profile_mutex);
   if (!profile_data)
     {
-      profile_data = standard_calloc ((MEM_PROFILE_TABLE_SIZE + 1) * 8, 
-                                      sizeof (profile_data[0]));
+      profile_data = calloc ((MEM_PROFILE_TABLE_SIZE + 1) * 8, 
+                             sizeof (profile_data[0]));
       if (!profile_data)       /* memory system kiddin' me, eh? */
        {
          g_mutex_unlock (&gmem_profile_mutex);
@@ -709,7 +629,6 @@ profile_print_locked (guint   *local_data,
 
 /**
  * g_mem_profile:
- * @void:
  * 
  * Outputs a summary of memory usage.
  * 
@@ -726,13 +645,11 @@ profile_print_locked (guint   *local_data,
 void
 g_mem_profile (void)
 {
-  guint local_data[(MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0])];
+  guint local_data[(MEM_PROFILE_TABLE_SIZE + 1) * 8];
   gsize local_allocs;
   gsize local_zinit;
   gsize local_frees;
 
-  GLIB_ENSURE_CTOR (g_mem_init_nomessage);
-
   g_mutex_lock (&gmem_profile_mutex);
 
   local_allocs = profile_allocs;
@@ -771,12 +688,7 @@ profiler_try_malloc (gsize n_bytes)
 {
   gsize *p;
 
-#ifdef  G_ENABLE_DEBUG
-  if (g_trap_malloc_size == n_bytes)
-    G_BREAKPOINT ();
-#endif  /* G_ENABLE_DEBUG */
-
-  p = standard_malloc (sizeof (gsize) * 2 + n_bytes);
+  p = malloc (sizeof (gsize) * 2 + n_bytes);
 
   if (p)
     {
@@ -809,12 +721,7 @@ profiler_calloc (gsize n_blocks,
   gsize l = n_blocks * n_block_bytes;
   gsize *p;
 
-#ifdef  G_ENABLE_DEBUG
-  if (g_trap_malloc_size == l)
-    G_BREAKPOINT ();
-#endif  /* G_ENABLE_DEBUG */
-  
-  p = standard_calloc (1, sizeof (gsize) * 2 + l);
+  p = calloc (1, sizeof (gsize) * 2 + l);
 
   if (p)
     {
@@ -848,17 +755,12 @@ profiler_free (gpointer mem)
     }
   else
     {
-#ifdef  G_ENABLE_DEBUG
-      if (g_trap_free_size == p[1])
-       G_BREAKPOINT ();
-#endif  /* G_ENABLE_DEBUG */
-
       profiler_log (PROFILER_FREE,
                    p[1],       /* length */
                    TRUE);
       memset (p + 2, 0xaa, p[1]);
 
-      /* for all those that miss standard_free (p); in this place, yes,
+      /* for all those that miss free (p); in this place, yes,
        * we do leak all memory when profiling, and that is intentional
        * to catch double frees. patch submissions are futile.
        */
@@ -873,11 +775,6 @@ profiler_try_realloc (gpointer mem,
   gsize *p = mem;
 
   p -= 2;
-
-#ifdef  G_ENABLE_DEBUG
-  if (g_trap_realloc_size == n_bytes)
-    G_BREAKPOINT ();
-#endif  /* G_ENABLE_DEBUG */
   
   if (mem && p[0])     /* free count */
     {
@@ -890,7 +787,7 @@ profiler_try_realloc (gpointer mem,
     }
   else
     {
-      p = standard_realloc (mem ? p : NULL, sizeof (gsize) * 2 + n_bytes);
+      p = realloc (mem ? p : NULL, sizeof (gsize) * 2 + n_bytes);
 
       if (p)
        {