git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 0/4] xdiff: introduce memory allocation macros

From
PGPhillip Wood via GitGitGadget <gitgitgadget@gmail.com>
Date
Jul 8, 2022, 16:25 UTC
Message-ID
<pull.1272.v2.git.1657297519.gitgitgadget@gmail.com>
In-Reply-To
<pull.1272.git.1656516334.gitgitgadget@gmail.com>

This patch series introduces macros for allocating and growing arrays in xdiff. The macros are similar to ALLOC_ARRAY()/ALLOC_GROW() from the rest of the code base but return an error on failure to allow libgit2 to handle memory allocation failures gracefully rather than dying. The macros introduce overflow checks but these checks are currently redundant as we limit the maximum file size passed to xdiff and these checks alone are insufficient to safely remove the size limit. The aim of this series is to make the xdiff code more readable, there should be no change in behavior (as such I'm open to the argument that these are just churn and should be dropped).

Thanks to Junio and Ævar the feedback on V1 Changes since V1:
 * Patch 2: new, it replaces xdl_malloc() followed by memset() with
   xdl_calloc() as suggested by Junio
 * Patch 3: simplified by the new patch 2, the end result is unchanged
 * Patch 4: added a note to the commit message explaining the choice to use
   long rather than size_t
Phillip Wood (4):
  xdiff: introduce XDL_ALLOC_ARRAY()
  xdiff: introduce xdl_calloc
  xdiff: introduce XDL_CALLOC_ARRAY()
  xdiff: introduce XDL_ALLOC_GROW()
 xdiff/xdiff.h      |  1 +
 xdiff/xdiffi.c     |  2 +-
 xdiff/xhistogram.c | 19 ++++++-------------
 xdiff/xmacros.h    | 18 ++++++++++++++++++
 xdiff/xpatience.c  |  9 +++------
 xdiff/xprepare.c   | 41 ++++++++++++-----------------------------
 xdiff/xutils.c     | 17 +++++++++++++++++
 xdiff/xutils.h     |  3 ++-
 8 files changed, 60 insertions(+), 50 deletions(-)
base-commit: e4a4b31577c7419497ac30cebe30d755b97752c5
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1272%2Fphillipwood%2Fwip%2Fxdiff-memory-allocation-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1272/phillipwood/wip/xdiff-memory-allocation-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/1272
Range-diff vs v1:
 1:  55fd62dc27d = 1:  55fd62dc27d xdiff: introduce XDL_ALLOC_ARRAY()
 2:  8bead9856be ! 2:  ea8993a57ef xdiff: introduce XDL_CALLOC_ARRAY()
     @@ Metadata
      Author: Phillip Wood <phillip.wood@dunelm.org.uk>
      
       ## Commit message ##
     -    xdiff: introduce XDL_CALLOC_ARRAY()
     +    xdiff: introduce xdl_calloc
      
     -    Add a helper for allocating an array and initialize the elements to
     -    zero. This is analogous to CALLOC_ARRAY() in the rest of the codebase
     -    but it returns NULL on allocation failures rather than dying to
     -    accommodate other users of libxdiff such as libgit2.
     +    In preparation for introducing XDL_CALLOC_ARRAY() use calloc() to
     +    obtain zeroed out memory rather than malloc() followed by memset(). To
     +    try and keep the lines a reasonable length this commit also stops
     +    casting the pointer returned by calloc() as this is unnecessary.
      
          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
      
     + ## xdiff/xdiff.h ##
     +@@ xdiff/xdiff.h: typedef struct s_bdiffparam {
     + 
     + 
     + #define xdl_malloc(x) xmalloc(x)
     ++#define xdl_calloc(n, sz) xcalloc(n, sz)
     + #define xdl_free(ptr) free(ptr)
     + #define xdl_realloc(ptr,x) xrealloc(ptr,x)
     + 
     +
       ## xdiff/xhistogram.c ##
      @@ xdiff/xhistogram.c: static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
       		    int line1, int count1, int line2, int count2)
     @@ xdiff/xhistogram.c: static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
      -	sz *= sizeof(struct record *);
      -	if (!(index.records = (struct record **) xdl_malloc(sz)))
      +	index.records_size = 1 << index.table_bits;
     -+	if (!XDL_CALLOC_ARRAY(index.records, index.records_size))
     ++	if (!(index.records = xdl_calloc(index.records_size,
     ++					 sizeof(*index.records))))
       		goto cleanup;
      -	memset(index.records, 0, sz);
       
     @@ xdiff/xhistogram.c: static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
      -	sz *= sizeof(struct record *);
      -	if (!(index.line_map = (struct record **) xdl_malloc(sz)))
      +	index.line_map_size = count1;
     -+	if (!XDL_CALLOC_ARRAY(index.line_map, index.line_map_size))
     ++	if (!(index.line_map = xdl_calloc(index.line_map_size,
     ++					  sizeof(*index.line_map))))
       		goto cleanup;
      -	memset(index.line_map, 0, sz);
       
      -	sz = index.line_map_size;
      -	sz *= sizeof(unsigned int);
      -	if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
     -+	if (!XDL_CALLOC_ARRAY(index.next_ptrs, index.line_map_size))
     ++	if (!(index.next_ptrs = xdl_calloc(index.line_map_size,
     ++					   sizeof(*index.next_ptrs))))
       		goto cleanup;
      -	memset(index.next_ptrs, 0, sz);
       
       	/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
       	if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
      
     - ## xdiff/xmacros.h ##
     -@@ xdiff/xmacros.h: do { \
     - 		? xdl_malloc((nr) * sizeof(*(p)))	\
     - 		: NULL)
     - 
     -+/* Allocate an array of nr zeroed out elements, returns NULL on failure */
     -+#define XDL_CALLOC_ARRAY(p, nr)				\
     -+	(XDL_ALLOC_ARRAY((p), (nr))			\
     -+		? memset((p), 0, (nr) * sizeof(*(p)))	\
     -+		: NULL)
     -+
     - #endif /* #if !defined(XMACROS_H) */
     -
       ## xdiff/xpatience.c ##
      @@ xdiff/xpatience.c: static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
       
     @@ xdiff/xpatience.c: static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
       	result->alloc = count1 * 2;
      -	result->entries = (struct entry *)
      -		xdl_malloc(result->alloc * sizeof(struct entry));
     --	if (!result->entries)
     -+	if (!XDL_CALLOC_ARRAY(result->entries, result->alloc))
     ++	result->entries = xdl_calloc(result->alloc, sizeof(*result->entries));
     + 	if (!result->entries)
       		return -1;
      -	memset(result->entries, 0, result->alloc * sizeof(struct entry));
       
     @@ xdiff/xprepare.c: static int xdl_init_classifier(xdlclassifier_t *cf, long size,
       		return -1;
       	}
      -	if (!(cf->rchash = (xdlclass_t **) xdl_malloc(cf->hsize * sizeof(xdlclass_t *)))) {
     -+	if (!XDL_CALLOC_ARRAY(cf->rchash, cf->hsize)) {
     ++	if (!(cf->rchash = xdl_calloc(cf->hsize, sizeof(*cf->rchash)))) {
       
       		xdl_cha_free(&cf->ncha);
       		return -1;
     @@ xdiff/xprepare.c: static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, lo
       	hbits = xdl_hashbits((unsigned int) narec);
       	hsize = 1 << hbits;
      -	if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *))))
     -+	if (!XDL_CALLOC_ARRAY(rhash, hsize))
     ++	if (!(rhash = xdl_calloc(hsize, sizeof(*rhash))))
       		goto abort;
      -	memset(rhash, 0, hsize * sizeof(xrecord_t *));
       
     @@ xdiff/xprepare.c: static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, lo
       	}
       
      -	if (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char))))
     -+	if (!XDL_CALLOC_ARRAY(rchg, nrec + 2))
     ++	if (!(rchg = xdl_calloc((nrec + 2), sizeof(*rchg))))
       		goto abort;
      -	memset(rchg, 0, (nrec + 2) * sizeof(char));
       
     @@ xdiff/xprepare.c: static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *
       	char *dis, *dis1, *dis2;
       
      -	if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) {
     --
     -+	if (!XDL_CALLOC_ARRAY(dis, xdf1->nrec + xdf2->nrec + 2))
     ++	if (!(dis = xdl_calloc(xdf1->nrec + xdf2->nrec + 2, sizeof(*dis)))) {
     + 
       		return -1;
     --	}
     + 	}
      -	memset(dis, 0, xdf1->nrec + xdf2->nrec + 2);
       	dis1 = dis;
       	dis2 = dis1 + xdf1->nrec + 1;
 -:  ----------- > 3:  5490fd22579 xdiff: introduce XDL_CALLOC_ARRAY()
 3:  da996677f07 ! 4:  8c24cd7737b xdiff: introduce XDL_ALLOC_GROW()
     @@ Commit message
          of adding a small amount to the new allocation to avoid a lot of
          reallocations at small sizes.
      
     +    Note that xdl_alloc_grow_helper() uses long rather than size_t for
     +    `nr` and `alloc` to match the existing code.
     +
          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
      
       ## xdiff/xmacros.h ##
      @@ xdiff/xmacros.h: do { \
     - 		? memset((p), 0, (nr) * sizeof(*(p)))	\
     - 		: NULL)
     + /* Allocate an array of nr zeroed out elements, returns NULL on failure */
     + #define XDL_CALLOC_ARRAY(p, nr)	((p) = xdl_calloc(nr, sizeof(*(p))))
       
      +/*
      + * Ensure array p can accommodate at least nr elements, growing the
-- 
gitgitgadget
Previous: Ævar Arnfjörð BjarmasonNext: Phillip Wood via GitGitGadget
Message 44 of 52 in “xdiff: introduce memory allocation macros”
  1. 0/3 xdiff: introduce memory allocation macrosPhillip Wood via GitGitGadget, Jun 29, 2022
  2. 1/3 xdiff: introduce XDL_ALLOC_ARRAY()Phillip Wood via GitGitGadget, Jun 29, 2022
  3. 2/3 xdiff: introduce XDL_CALLOC_ARRAY()Phillip Wood via GitGitGadget, Jun 29, 2022
  4. Junio C HamanoJun 30, 2022
  5. Phillip WoodJul 6, 2022
  6. 3/3 xdiff: introduce XDL_ALLOC_GROW()Phillip Wood via GitGitGadget, Jun 29, 2022
  7. Ævar Arnfjörð BjarmasonJun 30, 2022
  8. Phillip WoodJun 30, 2022
  9. Phillip WoodJun 30, 2022
  10. Ævar Arnfjörð BjarmasonJun 30, 2022
  11. Phillip WoodJul 6, 2022
  12. Ævar Arnfjörð BjarmasonJul 7, 2022
  13. Phillip WoodJul 8, 2022
  14. 0/7 xdiff: use standard alloc macros, share them via git-shared-util.hÆvar Arnfjörð Bjarmason, Jul 8, 2022
  15. 1/7 xdiff: simplify freeing patterns around xdl_free_env()Ævar Arnfjörð Bjarmason, Jul 8, 2022
  16. 2/7 git-shared-util.h: move "shared" allocation utilities hereÆvar Arnfjörð Bjarmason, Jul 8, 2022
  17. 3/7 git-shared-util.h: add G*() versions of *ALLOC_*()Ævar Arnfjörð Bjarmason, Jul 8, 2022
  18. Phillip WoodJul 11, 2022
  19. 5/7 xdiff: use GALLOC_GROW(), not XDL_ALLOC_GROW()Ævar Arnfjörð Bjarmason, Jul 8, 2022
  20. Phillip WoodJul 11, 2022
  21. Ævar Arnfjörð BjarmasonJul 11, 2022
  22. Phillip WoodJul 13, 2022
  23. Ævar Arnfjörð BjarmasonJul 13, 2022
  24. Phillip WoodJul 13, 2022
  25. 4/7 xdiff: use G[C]ALLOC_ARRAY(), not XDL_CALLOC_ARRAY()Ævar Arnfjörð Bjarmason, Jul 8, 2022
  26. Phillip WoodJul 11, 2022
  27. 6/7 xdiff: remove xdl_malloc() wrapper, use malloc(), not xmalloc()Ævar Arnfjörð Bjarmason, Jul 8, 2022
  28. Phillip WoodJul 8, 2022
  29. Ævar Arnfjörð BjarmasonJul 8, 2022
  30. Jeff KingJul 8, 2022
  31. Ævar Arnfjörð BjarmasonJul 8, 2022
  32. Jeff KingJul 11, 2022
  33. 7/7 xdiff: remove xdl_free(), use free() insteadÆvar Arnfjörð Bjarmason, Jul 8, 2022
  34. Phillip WoodJul 8, 2022
  35. Ævar Arnfjörð BjarmasonJul 8, 2022
  36. Phillip WoodJul 11, 2022
  37. Phillip WoodJul 11, 2022
  38. Ævar Arnfjörð BjarmasonJul 11, 2022
  39. Phillip WoodJul 13, 2022
  40. Ævar Arnfjörð BjarmasonJul 13, 2022
  41. Junio C HamanoJun 30, 2022
  42. Phillip WoodJul 6, 2022
  43. Ævar Arnfjörð BjarmasonJun 30, 2022
  44. 0/4 xdiff: introduce memory allocation macrosPhillip Wood via GitGitGadget, Jul 8, 2022
  45. 2/4 xdiff: introduce xdl_callocPhillip Wood via GitGitGadget, Jul 8, 2022
  46. 1/4 xdiff: introduce XDL_ALLOC_ARRAY()Phillip Wood via GitGitGadget, Jul 8, 2022
  47. 4/4 xdiff: introduce XDL_ALLOC_GROW()Phillip Wood via GitGitGadget, Jul 8, 2022
  48. Ævar Arnfjörð BjarmasonJul 8, 2022
  49. Phillip WoodJul 11, 2022
  50. Jeff KingJul 12, 2022
  51. Phillip WoodJul 13, 2022
  52. 3/4 xdiff: introduce XDL_CALLOC_ARRAY()Phillip Wood via GitGitGadget, Jul 8, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.