revisions API: have release_revisions() release "topo_walk_info"

Refactor the existing reset_topo_walk() into a thin wrapper for a release_revisions_topo_walk_info() + resetting the member to "NULL", and call release_revisions_topo_walk_info() from release_revisions(). This fixes memory leaks that have been with us ever since "topo_walk_info" was added to revision.[ch] in f0d9cc4196a (revision.c: begin refactoring --topo-order logic, 2018-11-01). Due to various other leaks this makes no tests pass in their entirety, but e.g. before this running this on git.git: ./git -P log --pretty=tformat:"%P %H | %s" --parents --full-history --topo-order -3 -- README.md Would report under SANITIZE=leak: SUMMARY: LeakSanitizer: 531064 byte(s) leaked in 6 allocation(s). Now we'll free all of that memory. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed Apr 14, 2022 at 07:56 UTC ae1b383dfa945d98ec3cedd744619c2028d6edf7
1 file changed +12 -4
revision.c
+12 -4
@@ -2943,6 +2943,8 @@ static void release_revisions_mailmap(struct string_list *mailmap)
2943 free(mailmap);
2944 }
2945
2946 +static void release_revisions_topo_walk_info(struct topo_walk_info *info);
2947 +
2948 void release_revisions(struct rev_info *revs)
2949 {
2950 free_commit_list(revs->commits);
@@ -2956,6 +2958,7 @@ void release_revisions(struct rev_info *revs)
2958 free_grep_patterns(&revs->grep_filter);
2959 diff_free(&revs->pruning);
2960 reflog_walk_info_release(revs->reflog_info);
2961 + release_revisions_topo_walk_info(revs->topo_walk_info);
2962 }
2963
2964 static void add_child(struct rev_info *revs, struct commit *parent, struct commit *child)
@@ -3468,17 +3471,22 @@ static void compute_indegrees_to_depth(struct rev_info *revs,
3471 indegree_walk_step(revs);
3472 }
3473
3471 -static void reset_topo_walk(struct rev_info *revs)
3474 +static void release_revisions_topo_walk_info(struct topo_walk_info *info)
3475 {
3473 - struct topo_walk_info *info = revs->topo_walk_info;
3474 -
3476 + if (!info)
3477 + return;
3478 clear_prio_queue(&info->explore_queue);
3479 clear_prio_queue(&info->indegree_queue);
3480 clear_prio_queue(&info->topo_queue);
3481 clear_indegree_slab(&info->indegree);
3482 clear_author_date_slab(&info->author_date);
3483 + free(info);
3484 +}
3485
3481 - FREE_AND_NULL(revs->topo_walk_info);
3486 +static void reset_topo_walk(struct rev_info *revs)
3487 +{
3488 + release_revisions_topo_walk_info(revs->topo_walk_info);
3489 + revs->topo_walk_info = NULL;
3490 }
3491
3492 static void init_topo_walk(struct rev_info *revs)