gmem: Add an inline definition of g_free() to automatically use g_free_sized()
When using GCC we can take the advantage of __builtin_object_size() to know the allocated size of a memory area, this generally only works when some optimization level enabled (-O1 seems enough here) and can provide us with memory size information for lower-level optimizations.
--
This can't be tested directly easily, unless we do a temporary copy of the macro, but we can trust the compiler.
A simple stand-alone test is:
/* Compile with -O1 at least */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void
free_sized(void *ptr, size_t size)
{
printf("Freeing %p of size %lu\n", ptr, size);
free (ptr);
}
static void
free_unsized(void *ptr)
{
printf("Freeing %p of unknown size\n", ptr);
free (ptr);
}
#define free_value(v) \
__builtin_object_size (v, 0) != ((size_t) - 1) ? \
free_sized (v, __builtin_object_size (v, 0)) : free_unsized (v)
typedef struct {
char *bar;
int foo;
unsigned baz;
} MyData;
typedef struct _MyUnknownData MyUnknownData;
void *malloc(size_t s) __attribute__((alloc_size (1)));
int main(void)
{
char *fooo = strdup("fooo bar");
free_value (fooo);
MyData data = {0};
MyData **data_array = malloc(sizeof(MyData) * 10);
free_value (data_array);
MyData *dataptr = malloc(sizeof(MyData));
dataptr = memcpy(dataptr, &data, sizeof(MyData));
free_value (dataptr);
MyUnknownData *unk = NULL;
free_value(unk);
return 0;
}
which correctly outputs:
Freeing 0x56385f6432a0 of size 9
Freeing 0x56385f6436d0 of size 160
Freeing 0x56385f6432a0 of size 16
Freeing (nil) of unknown size
Generated code is:
int main(void)
{
char *__ptr;
void *__ptr_00;
undefined (*__ptr_01) [16];
__ptr = strdup("fooo bar");
printf("Freeing %p of size %lu\n",__ptr,9);
free(__ptr);
__ptr_00 = malloc(0xa0);
printf("Freeing %p of size %lu\n",__ptr_00,0xa0);
free(__ptr_00);
__ptr_01 = (undefined (*) [16])malloc(0x10);
*__ptr_01 = ZEXT816(0);
printf("Freeing %p of size %lu\n",__ptr_01,0x10);
free(__ptr_01);
printf("Freeing %p of unknown size\n",0);
return 0;
}
/cc @matthiasc