Yasushi SHOJI <[EMAIL PROTECTED]> writes:

> oops.  probably my english wasn't clear. my patch fixes
> diff_free_filepair().

No, my reading of your patch when I wrote that message was
wrong.  The attached is what I ended up doing based on your
patch.  It does not seem to barf with the following test on
either git repository itself nor recent linux-2.6 repository,
which is a good sign.

    $ export MALLOC_CHECK_=2
    $ ./git-rev-list HEAD |
      ./git-diff-tree --stdin -r -B -C --find-copies-harder |
      sed -ne '/^[^:]/p;/ [MRCDA][0-9][0-9]*    /p'

When the command is run on linux-2.6 repository, virtual memory
consumption of git-diff-tree command skyrockets to about half a
gig, because it maps all files in two adjacent revisions of the
entire kernel tree.  But it seems to reclaim things reasonably
well and goes back down to less than 10m when it starts to
process the next commit pair.

Date: 1123930736 +0900
[PATCH] plug memory leak in diff.c::diff_free_filepair()

When I run git-diff-tree on big change, it seems the command eats so
much memory.  so I just put git under valgrind to see what's going on.
diff_free_filespec_data() doesn't free diff_filespec itself.

[jc: I ended up doing things slightly differently from Yasushi's
patch.  The original idea was to use free_filespec_data() only to
free the data portion and keep useing the filespec itself, but
no existing code seems to do things that way, so I just yanked
that part out.]

Signed-off-by: Yasushi SHOJI <[EMAIL PROTECTED]>
Signed-off-by: Junio C Hamano <[EMAIL PROTECTED]>

 diff.c           |    9 ++++-----
 diffcore-break.c |    4 ++--
 diffcore.h       |    2 +-
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/diff.c b/diff.c
--- a/diff.c
+++ b/diff.c
@@ -405,14 +405,13 @@ int diff_populate_filespec(struct diff_f
        return 0;
-void diff_free_filespec_data(struct diff_filespec *s)
+void diff_free_filespec(struct diff_filespec *s)
        if (s->should_free)
        else if (s->should_munmap)
                munmap(s->data, s->size);
-       s->should_free = s->should_munmap = 0;
-       s->data = NULL;
+       free(s);
 static void prep_temp_blob(struct diff_tempfile *temp,
@@ -769,8 +768,8 @@ struct diff_filepair *diff_queue(struct 
 void diff_free_filepair(struct diff_filepair *p)
-       diff_free_filespec_data(p->one);
-       diff_free_filespec_data(p->two);
+       diff_free_filespec(p->one);
+       diff_free_filespec(p->two);
diff --git a/diffcore-break.c b/diffcore-break.c
--- a/diffcore-break.c
+++ b/diffcore-break.c
@@ -231,8 +231,8 @@ static void merge_broken(struct diff_fil
        dp = diff_queue(outq, d->one, c->two);
        dp->score = p->score;
-       diff_free_filespec_data(d->two);
-       diff_free_filespec_data(c->one);
+       diff_free_filespec(d->two);
+       diff_free_filespec(c->one);
diff --git a/diffcore.h b/diffcore.h
--- a/diffcore.h
+++ b/diffcore.h
@@ -43,7 +43,7 @@ extern void fill_filespec(struct diff_fi
                          unsigned short);
 extern int diff_populate_filespec(struct diff_filespec *, int);
-extern void diff_free_filespec_data(struct diff_filespec *);
+extern void diff_free_filespec(struct diff_filespec *);
 struct diff_filepair {
        struct diff_filespec *one;

To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to