Git fork

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>

authored by

Kirill Smelkov and committed by
Junio C Hamano
61f76a36 12cd8174

+30 -2
+6
Makefile
··· 30 30 # Define LIBPCREDIR=/foo/bar if your libpcre header and library files are in 31 31 # /foo/bar/include and /foo/bar/lib directories. 32 32 # 33 + # Define HAVE_ALLOCA_H if you have working alloca(3) defined in that header. 34 + # 33 35 # Define NO_CURL if you do not have libcurl installed. git-http-fetch and 34 36 # git-http-push are not built, and you cannot use http:// and https:// 35 37 # transports (neither smart nor dumb). ··· 1097 1099 EXTLIBS += -L$(LIBPCREDIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCREDIR)/$(lib) 1098 1100 endif 1099 1101 EXTLIBS += -lpcre 1102 + endif 1103 + 1104 + ifdef HAVE_ALLOCA_H 1105 + BASIC_CFLAGS += -DHAVE_ALLOCA_H 1100 1106 endif 1101 1107 1102 1108 ifdef NO_CURL
+8 -2
config.mak.uname
··· 28 28 NO_NSEC = YesPlease 29 29 endif 30 30 ifeq ($(uname_S),Linux) 31 + HAVE_ALLOCA_H = YesPlease 31 32 NO_STRLCPY = YesPlease 32 33 NO_MKSTEMPS = YesPlease 33 34 HAVE_PATHS_H = YesPlease ··· 35 36 HAVE_DEV_TTY = YesPlease 36 37 endif 37 38 ifeq ($(uname_S),GNU/kFreeBSD) 39 + HAVE_ALLOCA_H = YesPlease 38 40 NO_STRLCPY = YesPlease 39 41 NO_MKSTEMPS = YesPlease 40 42 HAVE_PATHS_H = YesPlease ··· 103 105 NEEDS_NSL = YesPlease 104 106 SHELL_PATH = /bin/bash 105 107 SANE_TOOL_PATH = /usr/xpg6/bin:/usr/xpg4/bin 108 + HAVE_ALLOCA_H = YesPlease 106 109 NO_STRCASESTR = YesPlease 107 110 NO_MEMMEM = YesPlease 108 111 NO_MKDTEMP = YesPlease ··· 146 149 endif 147 150 INSTALL = /usr/ucb/install 148 151 TAR = gtar 149 - BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__ -DHAVE_ALLOCA_H 152 + BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__ 150 153 endif 151 154 ifeq ($(uname_O),Cygwin) 152 155 ifeq ($(shell expr "$(uname_R)" : '1\.[1-6]\.'),4) ··· 166 169 else 167 170 NO_REGEX = UnfortunatelyYes 168 171 endif 172 + HAVE_ALLOCA_H = YesPlease 169 173 NEEDS_LIBICONV = YesPlease 170 174 NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes 171 175 NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease ··· 239 243 endif 240 244 ifeq ($(uname_S),GNU) 241 245 # GNU/Hurd 246 + HAVE_ALLOCA_H = YesPlease 242 247 NO_STRLCPY = YesPlease 243 248 NO_MKSTEMPS = YesPlease 244 249 HAVE_PATHS_H = YesPlease ··· 316 321 ifeq ($(uname_S),Windows) 317 322 GIT_VERSION := $(GIT_VERSION).MSVC 318 323 pathsep = ; 324 + HAVE_ALLOCA_H = YesPlease 319 325 NO_PREAD = YesPlease 320 326 NEEDS_CRYPTO_WITH_SSL = YesPlease 321 327 NO_LIBGEN_H = YesPlease ··· 363 369 COMPAT_OBJS = compat/msvc.o compat/winansi.o \ 364 370 compat/win32/pthread.o compat/win32/syslog.o \ 365 371 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\" 367 373 BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib 368 374 EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib 369 375 PTHREAD_LIBS =
+8
configure.ac
··· 272 272 GIT_CONF_SUBST([LIBPCREDIR]) 273 273 fi) 274 274 # 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 + # 275 283 # Define NO_CURL if you do not have curl installed. git-http-pull and 276 284 # git-http-push are not built, and you cannot use http:// and https:// 277 285 # transports.
+8
git-compat-util.h
··· 526 526 typedef void (*try_to_free_t)(size_t); 527 527 extern try_to_free_t set_try_to_free_routine(try_to_free_t); 528 528 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 529 537 extern char *xstrdup(const char *str); 530 538 extern void *xmalloc(size_t size); 531 539 extern void *xmallocz(size_t size);