Merge branch 'master' of ssh://sourceware.org/git/glibc
[platform/upstream/glibc.git] / include / alloca.h
1 #ifndef _ALLOCA_H
2
3 #include <stdlib/alloca.h>
4 #include <stackinfo.h>
5
6 #undef  __alloca
7
8 /* Now define the internal interfaces.  */
9 extern void *__alloca (size_t __size);
10
11 #ifdef  __GNUC__
12 # define __alloca(size) __builtin_alloca (size)
13 #endif /* GCC.  */
14
15 extern int __libc_use_alloca (size_t size) __attribute__ ((const));
16 extern int __libc_alloca_cutoff (size_t size) __attribute__ ((const));
17 libc_hidden_proto (__libc_alloca_cutoff)
18
19 #define __MAX_ALLOCA_CUTOFF     65536
20
21 #include <allocalim.h>
22
23 #ifndef stackinfo_alloca_round
24 # define stackinfo_alloca_round(l) (((l) + 15) & -16)
25 #endif
26
27 #if _STACK_GROWS_DOWN
28 # define extend_alloca(buf, len, newlen) \
29   (__typeof (buf)) ({ size_t __newlen = stackinfo_alloca_round (newlen);      \
30                       char *__newbuf = __alloca (__newlen);                   \
31                       if (__newbuf + __newlen == (char *) buf)                \
32                         len += __newlen;                                      \
33                       else                                                    \
34                         len = __newlen;                                       \
35                       __newbuf; })
36 #elif _STACK_GROWS_UP
37 # define extend_alloca(buf, len, newlen) \
38   (__typeof (buf)) ({ size_t __newlen = stackinfo_alloca_round (newlen);      \
39                       char *__newbuf = __alloca (__newlen);                   \
40                       char *__buf = (buf);                                    \
41                       if (__buf + len == __newbuf)                            \
42                         {                                                     \
43                           len += __newlen;                                    \
44                           __newbuf = __buf;                                   \
45                         }                                                     \
46                       else                                                    \
47                         len = __newlen;                                       \
48                       __newbuf; })
49 #else
50 # define extend_alloca(buf, len, newlen) \
51   __alloca (((len) = (newlen)))
52 #endif
53
54 #if defined stackinfo_get_sp && defined stackinfo_sub_sp
55 # define alloca_account(size, avar) \
56   ({ void *old__ = stackinfo_get_sp ();                                       \
57      void *m__ = __alloca (size);                                             \
58      avar += stackinfo_sub_sp (old__);                                        \
59      m__; })
60 # define extend_alloca_account(buf, len, newlen, avar) \
61   ({ void *old__ = stackinfo_get_sp ();                                       \
62      void *m__ = extend_alloca (buf, len, newlen);                            \
63      avar += stackinfo_sub_sp (old__);                                        \
64      m__; })
65 #else
66 # define alloca_account(size, avar) \
67   ({ size_t s__ = (size);                                                     \
68      avar += s__;                                                             \
69      __alloca (s__); })
70 # define extend_alloca_account(buf, len, newlen, avar) \
71   ({ size_t s__ = (newlen);                                                   \
72      avar += s__;                                                             \
73      extend_alloca (buf, len, s__); })
74 #endif
75
76 #endif