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);
}

Reply via email to