On Sun, Nov 10, 2013 at 04:27:00PM +0100, Marc Glisse wrote: > Hello, > > I am posting this patch to get some feedback on the approach. The > goal is to replace malloc+free with a stack allocation (a decl > actually) when the size is a small constant. > Why constraint yourself to small sizes. Stack allocation benefits is speed and less memory comsumption due lack of fragmentation.
A possible way is to have thread local bounds to stack size and call function with custom logic when it is outside of bounds. Below is a simple implementation which creates a separate stack for that (for simplicity and because it does not need to find bounds on thread stack.) With bit of more work it could do allocations in similar way as in splitstack. > For testing, I highjacked the "leaf" attribute, but it isn't right, > I'll remove it from the list (not sure what I'll do for the > testcases then). What I'd want instead is a "returns" attribute that > means the function will return (either by "return" or an exception), > as opposed to having an infinite loop, calling exit or longjmp, etc > (sched-deps.c has a related call_may_noreturn_p). The situation I am > trying to avoid is: > p=malloc(12); > f(p) > free(p) > > where f contains somewhere: > free(p); exit(42); > (or longjmp or something else that takes the regular call to free > out of the execution flow). > One of plans to extend malloc is add custom free handler, interface would be something like dalloc(amount, destructor) which would invoke destructor on free. Main motivation is memory pool that can be returned by free. With that extension it would be possible to mark pointer so its free would be a nop. > > > The size above which the malloc->stack transformation is not applied > should depend on a parameter, I don't know if it should get its own > or depend on an existing one. In any case, I'd like to avoid ending > up with a ridiculously low threshold (my programs use GMP, which > internally uses alloca up to 65536 bytes (even in recursive > functions that have a dozen allocations), so I don't want gcc to > tell me that 50 bytes are too much). > > A program with a double-free may, with this patch, end up crashing > on the first free instead of the second, but that's an invalid > program anyway. > > #include <pthread.h> __thread void *__stack_from; __thread void *__stack_cur; __thread void *__stack_to; #define STACK_ALLOC(size) ({ \ void *__stack_new = __stack_cur + size; \ if (__stack_new < __stack_cur || __stack_to > __stack_new) \ __stack_alloc (size); \ else \ { \ void *__s = __stack_cur; \ __stack_cur = __stack_new; \ __s; \ } \ }) #define STACK_FREE(__stack_new) ({ \ if (__stack_new < __stack_from || __stack_to > __stack_new) \ __stack_free (size); \ else \ __stack_cur = __stack_new; \ }) static pthread_key_t key; void __stack_destroy (void *x) { free (stack_from); } void * __stack_alloc (size_t size) { if (!__stack_from) { __stack_from = malloc (1 << 18); __stack_to = __stack_from + (1 << 18); __stack_cur = __stack_from; _ pthread_key_create (&key, destroy); pthread_setspecific (key, &key); } return malloc (size); } void __stack_free (void *p) { free (p); }