Merge branch 'jk/avoid-unbounded-alloca' into maint

A codepath that used alloca(3) to place an unbounded amount of data
on the stack has been updated to avoid doing so.

* jk/avoid-unbounded-alloca:
  tree-diff: avoid alloca for large allocations
This commit is contained in:
Junio C Hamano 2016-07-06 13:06:39 -07:00
Родитель c0144452ef b8ba412bf7
Коммит 1f5d429e4a
1 изменённых файлов: 16 добавлений и 6 удалений

Просмотреть файл

@ -14,6 +14,16 @@
*/ */
#define S_IFXMIN_NEQ S_DIFFTREE_IFXMIN_NEQ #define S_IFXMIN_NEQ S_DIFFTREE_IFXMIN_NEQ
#define FAST_ARRAY_ALLOC(x, nr) do { \
if ((nr) <= 2) \
(x) = xalloca((nr) * sizeof(*(x))); \
else \
ALLOC_ARRAY((x), nr); \
} while(0)
#define FAST_ARRAY_FREE(x, nr) do { \
if ((nr) > 2) \
free((x)); \
} while(0)
static struct combine_diff_path *ll_diff_tree_paths( static struct combine_diff_path *ll_diff_tree_paths(
struct combine_diff_path *p, const unsigned char *sha1, struct combine_diff_path *p, const unsigned char *sha1,
@ -265,7 +275,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p,
if (recurse) { if (recurse) {
const unsigned char **parents_sha1; const unsigned char **parents_sha1;
parents_sha1 = xalloca(nparent * sizeof(parents_sha1[0])); FAST_ARRAY_ALLOC(parents_sha1, nparent);
for (i = 0; i < nparent; ++i) { for (i = 0; i < nparent; ++i) {
/* same rule as in emitthis */ /* same rule as in emitthis */
int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ); int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);
@ -277,7 +287,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p,
strbuf_add(base, path, pathlen); strbuf_add(base, path, pathlen);
strbuf_addch(base, '/'); strbuf_addch(base, '/');
p = ll_diff_tree_paths(p, sha1, parents_sha1, nparent, base, opt); p = ll_diff_tree_paths(p, sha1, parents_sha1, nparent, base, opt);
xalloca_free(parents_sha1); FAST_ARRAY_FREE(parents_sha1, nparent);
} }
strbuf_setlen(base, old_baselen); strbuf_setlen(base, old_baselen);
@ -402,8 +412,8 @@ static struct combine_diff_path *ll_diff_tree_paths(
void *ttree, **tptree; void *ttree, **tptree;
int i; int i;
tp = xalloca(nparent * sizeof(tp[0])); FAST_ARRAY_ALLOC(tp, nparent);
tptree = xalloca(nparent * sizeof(tptree[0])); FAST_ARRAY_ALLOC(tptree, nparent);
/* /*
* load parents first, as they are probably already cached. * load parents first, as they are probably already cached.
@ -531,8 +541,8 @@ static struct combine_diff_path *ll_diff_tree_paths(
free(ttree); free(ttree);
for (i = nparent-1; i >= 0; i--) for (i = nparent-1; i >= 0; i--)
free(tptree[i]); free(tptree[i]);
xalloca_free(tptree); FAST_ARRAY_FREE(tptree, nparent);
xalloca_free(tp); FAST_ARRAY_FREE(tp, nparent);
return p; return p;
} }