Skip to content

Commit 61f76a3

Browse files
Kirill Smelkovgitster
authored andcommitted
Portable alloca for Git
In the next patch we'll have to use alloca() for performance reasons, but since alloca is non-standardized and is not portable, let's have a trick with compatibility wrappers: 1. at configure time, determine, do we have working alloca() through alloca.h, and define #define HAVE_ALLOCA_H if yes. 2. in code #ifdef HAVE_ALLOCA_H # include <alloca.h> # define xalloca(size) (alloca(size)) # define xalloca_free(p) do {} while(0) #else # define xalloca(size) (xmalloc(size)) # define xalloca_free(p) (free(p)) #endif and use it like func() { p = xalloca(size); ... xalloca_free(p); } This way, for systems, where alloca is available, we'll have optimal on-stack allocations with fast executions. On the other hand, on systems, where alloca is not available, this gracefully fallbacks to xmalloc/free. Both autoconf and config.mak.uname configurations were updated. For autoconf, we are not bothering considering cases, when no alloca.h is available, but alloca() works some other way - its simply alloca.h is available and works or not, everything else is deep legacy. For config.mak.uname, I've tried to make my almost-sure guess for where alloca() is available, but since I only have access to Linux it is the only change I can be sure about myself, with relevant to other changed systems people Cc'ed. NOTE SunOS and Windows had explicit -DHAVE_ALLOCA_H in their configurations. I've changed that to now-common HAVE_ALLOCA_H=YesPlease which should be correct. Cc: Brandon Casey <drafnel@gmail.com> Cc: Marius Storm-Olsen <mstormo@gmail.com> Cc: Johannes Sixt <j6t@kdbg.org> Cc: Johannes Schindelin <Johannes.Schindelin@gmx.de> Cc: Ramsay Jones <ramsay@ramsay1.demon.co.uk> Cc: Gerrit Pape <pape@smarden.org> Cc: Petr Salinger <Petr.Salinger@seznam.cz> Cc: Jonathan Nieder <jrnieder@gmail.com> Acked-by: Thomas Schwinge <thomas@codesourcery.com> (GNU Hurd changes) Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 12cd817 commit 61f76a3

File tree

4 files changed

+30
-2
lines changed

4 files changed

+30
-2
lines changed

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ all::
3030
# Define LIBPCREDIR=/foo/bar if your libpcre header and library files are in
3131
# /foo/bar/include and /foo/bar/lib directories.
3232
#
33+
# Define HAVE_ALLOCA_H if you have working alloca(3) defined in that header.
34+
#
3335
# Define NO_CURL if you do not have libcurl installed. git-http-fetch and
3436
# git-http-push are not built, and you cannot use http:// and https://
3537
# transports (neither smart nor dumb).
@@ -1099,6 +1101,10 @@ ifdef USE_LIBPCRE
10991101
EXTLIBS += -lpcre
11001102
endif
11011103

1104+
ifdef HAVE_ALLOCA_H
1105+
BASIC_CFLAGS += -DHAVE_ALLOCA_H
1106+
endif
1107+
11021108
ifdef NO_CURL
11031109
BASIC_CFLAGS += -DNO_CURL
11041110
REMOTE_CURL_PRIMARY =

config.mak.uname

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ ifeq ($(uname_S),OSF1)
2828
NO_NSEC = YesPlease
2929
endif
3030
ifeq ($(uname_S),Linux)
31+
HAVE_ALLOCA_H = YesPlease
3132
NO_STRLCPY = YesPlease
3233
NO_MKSTEMPS = YesPlease
3334
HAVE_PATHS_H = YesPlease
3435
LIBC_CONTAINS_LIBINTL = YesPlease
3536
HAVE_DEV_TTY = YesPlease
3637
endif
3738
ifeq ($(uname_S),GNU/kFreeBSD)
39+
HAVE_ALLOCA_H = YesPlease
3840
NO_STRLCPY = YesPlease
3941
NO_MKSTEMPS = YesPlease
4042
HAVE_PATHS_H = YesPlease
@@ -103,6 +105,7 @@ ifeq ($(uname_S),SunOS)
103105
NEEDS_NSL = YesPlease
104106
SHELL_PATH = /bin/bash
105107
SANE_TOOL_PATH = /usr/xpg6/bin:/usr/xpg4/bin
108+
HAVE_ALLOCA_H = YesPlease
106109
NO_STRCASESTR = YesPlease
107110
NO_MEMMEM = YesPlease
108111
NO_MKDTEMP = YesPlease
@@ -146,7 +149,7 @@ ifeq ($(uname_S),SunOS)
146149
endif
147150
INSTALL = /usr/ucb/install
148151
TAR = gtar
149-
BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__ -DHAVE_ALLOCA_H
152+
BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__
150153
endif
151154
ifeq ($(uname_O),Cygwin)
152155
ifeq ($(shell expr "$(uname_R)" : '1\.[1-6]\.'),4)
@@ -166,6 +169,7 @@ ifeq ($(uname_O),Cygwin)
166169
else
167170
NO_REGEX = UnfortunatelyYes
168171
endif
172+
HAVE_ALLOCA_H = YesPlease
169173
NEEDS_LIBICONV = YesPlease
170174
NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
171175
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
@@ -239,6 +243,7 @@ ifeq ($(uname_S),AIX)
239243
endif
240244
ifeq ($(uname_S),GNU)
241245
# GNU/Hurd
246+
HAVE_ALLOCA_H = YesPlease
242247
NO_STRLCPY = YesPlease
243248
NO_MKSTEMPS = YesPlease
244249
HAVE_PATHS_H = YesPlease
@@ -316,6 +321,7 @@ endif
316321
ifeq ($(uname_S),Windows)
317322
GIT_VERSION := $(GIT_VERSION).MSVC
318323
pathsep = ;
324+
HAVE_ALLOCA_H = YesPlease
319325
NO_PREAD = YesPlease
320326
NEEDS_CRYPTO_WITH_SSL = YesPlease
321327
NO_LIBGEN_H = YesPlease
@@ -363,7 +369,7 @@ ifeq ($(uname_S),Windows)
363369
COMPAT_OBJS = compat/msvc.o compat/winansi.o \
364370
compat/win32/pthread.o compat/win32/syslog.o \
365371
compat/win32/dirent.o
366-
COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
372+
COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
367373
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib
368374
EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib
369375
PTHREAD_LIBS =

configure.ac

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,14 @@ AS_HELP_STRING([], [ARG can be also prefix for libpcre library and hea
272272
GIT_CONF_SUBST([LIBPCREDIR])
273273
fi)
274274
#
275+
# Define HAVE_ALLOCA_H if you have working alloca(3) defined in that header.
276+
AC_FUNC_ALLOCA
277+
case $ac_cv_working_alloca_h in
278+
yes) HAVE_ALLOCA_H=YesPlease;;
279+
*) HAVE_ALLOCA_H='';;
280+
esac
281+
GIT_CONF_SUBST([HAVE_ALLOCA_H])
282+
#
275283
# Define NO_CURL if you do not have curl installed. git-http-pull and
276284
# git-http-push are not built, and you cannot use http:// and https://
277285
# transports.

git-compat-util.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,14 @@ extern void release_pack_memory(size_t);
526526
typedef void (*try_to_free_t)(size_t);
527527
extern try_to_free_t set_try_to_free_routine(try_to_free_t);
528528

529+
#ifdef HAVE_ALLOCA_H
530+
# include <alloca.h>
531+
# define xalloca(size) (alloca(size))
532+
# define xalloca_free(p) do {} while (0)
533+
#else
534+
# define xalloca(size) (xmalloc(size))
535+
# define xalloca_free(p) (free(p))
536+
#endif
529537
extern char *xstrdup(const char *str);
530538
extern void *xmalloc(size_t size);
531539
extern void *xmallocz(size_t size);

0 commit comments

Comments
 (0)