aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2024-09-05 12:09:12 +0200
committerJunio C Hamano <gitster@pobox.com>2024-09-05 08:49:11 -0700
commit0d1d22f5a385d05bde40303c17483db2eec499b3 (patch)
tree3b6af161c7e9c2ae1b880ec7d585331f0b117d62
parentb8849e236f7a32d43ab3ba087587a336d69329b0 (diff)
downloadgit-0d1d22f5a385d05bde40303c17483db2eec499b3.tar.gz
object: clear grafts when clearing parsed object pool
We do not clear grafts part of the parsed object pool when clearing the pool itself, which can lead to memory leaks when a repository is being cleared. Fix this by moving `reset_commit_grafts()` into "object.c" and making it part of the `struct parsed_object_pool` interface such that we can call it from `parsed_object_pool_clear()`. Adapt `parsed_object_pool_new()` to take and store a reference to its owning repository, which is needed by `unparse_commit()`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--commit.c14
-rw-r--r--commit.h3
-rw-r--r--object.c14
-rw-r--r--object.h4
-rw-r--r--repository.c2
-rw-r--r--shallow.c2
6 files changed, 21 insertions, 18 deletions
diff --git a/commit.c b/commit.c
index ec9efc189d..bbef0e81c6 100644
--- a/commit.c
+++ b/commit.c
@@ -177,7 +177,7 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid)
commit_graft_oid_access);
}
-static void unparse_commit(struct repository *r, const struct object_id *oid)
+void unparse_commit(struct repository *r, const struct object_id *oid)
{
struct commit *c = lookup_commit(r, oid);
@@ -318,18 +318,6 @@ int for_each_commit_graft(each_commit_graft_fn fn, void *cb_data)
return ret;
}
-void reset_commit_grafts(struct repository *r)
-{
- int i;
-
- for (i = 0; i < r->parsed_objects->grafts_nr; i++) {
- unparse_commit(r, &r->parsed_objects->grafts[i]->oid);
- free(r->parsed_objects->grafts[i]);
- }
- r->parsed_objects->grafts_nr = 0;
- r->parsed_objects->commit_graft_prepared = 0;
-}
-
struct commit_buffer {
void *buffer;
unsigned long size;
diff --git a/commit.h b/commit.h
index d62b1d93f9..5ba0f77b1e 100644
--- a/commit.h
+++ b/commit.h
@@ -108,6 +108,8 @@ static inline int repo_parse_commit_no_graph(struct repository *r,
void parse_commit_or_die(struct commit *item);
+void unparse_commit(struct repository *r, const struct object_id *oid);
+
struct buffer_slab;
struct buffer_slab *allocate_commit_buffer_slab(void);
void free_commit_buffer_slab(struct buffer_slab *bs);
@@ -240,7 +242,6 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid);
int register_commit_graft(struct repository *r, struct commit_graft *, int);
void prepare_commit_graft(struct repository *r);
struct commit_graft *lookup_commit_graft(struct repository *r, const struct object_id *oid);
-void reset_commit_grafts(struct repository *r);
struct commit *get_fork_point(const char *refname, struct commit *commit);
diff --git a/object.c b/object.c
index d756c7f2ea..94ea8fb8d2 100644
--- a/object.c
+++ b/object.c
@@ -545,11 +545,12 @@ void repo_clear_commit_marks(struct repository *r, unsigned int flags)
}
}
-struct parsed_object_pool *parsed_object_pool_new(void)
+struct parsed_object_pool *parsed_object_pool_new(struct repository *repo)
{
struct parsed_object_pool *o = xmalloc(sizeof(*o));
memset(o, 0, sizeof(*o));
+ o->repo = repo;
o->blob_state = allocate_alloc_state();
o->tree_state = allocate_alloc_state();
o->commit_state = allocate_alloc_state();
@@ -628,6 +629,16 @@ void raw_object_store_clear(struct raw_object_store *o)
hashmap_clear(&o->pack_map);
}
+void parsed_object_pool_reset_commit_grafts(struct parsed_object_pool *o)
+{
+ for (int i = 0; i < o->grafts_nr; i++) {
+ unparse_commit(o->repo, &o->grafts[i]->oid);
+ free(o->grafts[i]);
+ }
+ o->grafts_nr = 0;
+ o->commit_graft_prepared = 0;
+}
+
void parsed_object_pool_clear(struct parsed_object_pool *o)
{
/*
@@ -659,6 +670,7 @@ void parsed_object_pool_clear(struct parsed_object_pool *o)
free_commit_buffer_slab(o->buffer_slab);
o->buffer_slab = NULL;
+ parsed_object_pool_reset_commit_grafts(o);
clear_alloc_state(o->blob_state);
clear_alloc_state(o->tree_state);
clear_alloc_state(o->commit_state);
diff --git a/object.h b/object.h
index 05691486eb..17f32f1103 100644
--- a/object.h
+++ b/object.h
@@ -7,6 +7,7 @@ struct buffer_slab;
struct repository;
struct parsed_object_pool {
+ struct repository *repo;
struct object **obj_hash;
int nr_objs, obj_hash_size;
@@ -31,8 +32,9 @@ struct parsed_object_pool {
struct buffer_slab *buffer_slab;
};
-struct parsed_object_pool *parsed_object_pool_new(void);
+struct parsed_object_pool *parsed_object_pool_new(struct repository *repo);
void parsed_object_pool_clear(struct parsed_object_pool *o);
+void parsed_object_pool_reset_commit_grafts(struct parsed_object_pool *o);
struct object_list {
struct object *item;
diff --git a/repository.c b/repository.c
index 9825a30899..e6fc2c6aa9 100644
--- a/repository.c
+++ b/repository.c
@@ -54,7 +54,7 @@ void initialize_repository(struct repository *repo)
{
repo->objects = raw_object_store_new();
repo->remote_state = remote_state_new();
- repo->parsed_objects = parsed_object_pool_new();
+ repo->parsed_objects = parsed_object_pool_new(repo);
ALLOC_ARRAY(repo->index, 1);
index_state_init(repo->index, repo);
diff --git a/shallow.c b/shallow.c
index b8cd051e3b..a10cf9e9d5 100644
--- a/shallow.c
+++ b/shallow.c
@@ -97,7 +97,7 @@ static void reset_repository_shallow(struct repository *r)
{
r->parsed_objects->is_shallow = -1;
stat_validity_clear(r->parsed_objects->shallow_stat);
- reset_commit_grafts(r);
+ parsed_object_pool_reset_commit_grafts(r->parsed_objects);
}
int commit_shallow_file(struct repository *r, struct shallow_lock *lk)