+2014-09-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix SAFE_ALLOCA to not exhaust the stack when in a loop.
+ Problem reported by Dmietry Antipov in thread leading to:
+ http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html
+ This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP;
+ the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS
+ remain unfixed.
+ * callproc.c (call_process): Save and restore sa_avail.
+ * lisp.h (USE_SAFE_ALLOCA): Define sa_avail.
+ (AVAIL_ALLOCA): New macro.
+ (SAFE_ALLOCA, SAFE_NALLOCA, SAFE_ALLOCA_LISP):
+ Use it, and check against sa_avail rather than MAX_ALLOCA.
+
2014-09-22 Dmitry Antipov <dmantipov@yandex.ru>
On OSX, do not free font-specific data more than once (Bug#18501).
int volatile fd_error_volatile = fd_error;
int volatile filefd_volatile = filefd;
ptrdiff_t volatile count_volatile = count;
+ ptrdiff_t volatile sa_avail_volatile = sa_avail;
ptrdiff_t volatile sa_count_volatile = sa_count;
char **volatile new_argv_volatile = new_argv;
int volatile callproc_fd_volatile[CALLPROC_FDS];
fd_error = fd_error_volatile;
filefd = filefd_volatile;
count = count_volatile;
+ sa_avail = sa_avail_volatile;
sa_count = sa_count_volatile;
new_argv = new_argv_volatile;
extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
#define USE_SAFE_ALLOCA \
+ ptrdiff_t sa_avail = MAX_ALLOCA; \
ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false
+#define AVAIL_ALLOCA(size) (sa_avail -= (size), alloca (size))
+
/* SAFE_ALLOCA allocates a simple buffer. */
-#define SAFE_ALLOCA(size) ((size) <= MAX_ALLOCA \
- ? alloca (size) \
+#define SAFE_ALLOCA(size) ((size) <= sa_avail \
+ ? AVAIL_ALLOCA (size) \
: (sa_must_free = true, record_xmalloc (size)))
/* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER *
#define SAFE_NALLOCA(buf, multiplier, nitems) \
do { \
- if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \
- (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems)); \
+ if ((nitems) <= sa_avail / sizeof *(buf) / (multiplier)) \
+ (buf) = AVAIL_ALLOCA (sizeof *(buf) * (multiplier) * (nitems)); \
else \
{ \
(buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \
#define SAFE_ALLOCA_LISP(buf, nelt) \
do { \
- if ((nelt) <= MAX_ALLOCA / word_size) \
- (buf) = alloca ((nelt) * word_size); \
+ if ((nelt) <= sa_avail / word_size) \
+ (buf) = AVAIL_ALLOCA ((nelt) * word_size); \
else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \
{ \
Lisp_Object arg_; \