Merge branch 'jk/avoid-unbounded-alloca'

* jk/avoid-unbounded-alloca:
  tree-diff: avoid alloca for large allocations
This commit is contained in:
Junio C Hamano 2016-06-27 09:56:48 -07:00
commit 269085e16e

View File

@ -14,6 +14,16 @@
*/
#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(
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) {
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) {
/* same rule as in emitthis */
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_addch(base, '/');
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);
@ -402,8 +412,8 @@ static struct combine_diff_path *ll_diff_tree_paths(
void *ttree, **tptree;
int i;
tp = xalloca(nparent * sizeof(tp[0]));
tptree = xalloca(nparent * sizeof(tptree[0]));
FAST_ARRAY_ALLOC(tp, nparent);
FAST_ARRAY_ALLOC(tptree, nparent);
/*
* load parents first, as they are probably already cached.
@ -531,8 +541,8 @@ static struct combine_diff_path *ll_diff_tree_paths(
free(ttree);
for (i = nparent-1; i >= 0; i--)
free(tptree[i]);
xalloca_free(tptree);
xalloca_free(tp);
FAST_ARRAY_FREE(tptree, nparent);
FAST_ARRAY_FREE(tp, nparent);
return p;
}