1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-10-28 04:49:43 +01:00

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>
This commit is contained in:
Patrick Steinhardt 2024-09-05 12:09:12 +02:00 committed by Junio C Hamano
parent b8849e236f
commit 0d1d22f5a3
6 changed files with 21 additions and 18 deletions

View file

@ -177,7 +177,7 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid)
commit_graft_oid_access); 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); 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; 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 { struct commit_buffer {
void *buffer; void *buffer;
unsigned long size; unsigned long size;

View file

@ -108,6 +108,8 @@ static inline int repo_parse_commit_no_graph(struct repository *r,
void parse_commit_or_die(struct commit *item); 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;
struct buffer_slab *allocate_commit_buffer_slab(void); struct buffer_slab *allocate_commit_buffer_slab(void);
void free_commit_buffer_slab(struct buffer_slab *bs); 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); int register_commit_graft(struct repository *r, struct commit_graft *, int);
void prepare_commit_graft(struct repository *r); void prepare_commit_graft(struct repository *r);
struct commit_graft *lookup_commit_graft(struct repository *r, const struct object_id *oid); 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); struct commit *get_fork_point(const char *refname, struct commit *commit);

View file

@ -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)); struct parsed_object_pool *o = xmalloc(sizeof(*o));
memset(o, 0, sizeof(*o)); memset(o, 0, sizeof(*o));
o->repo = repo;
o->blob_state = allocate_alloc_state(); o->blob_state = allocate_alloc_state();
o->tree_state = allocate_alloc_state(); o->tree_state = allocate_alloc_state();
o->commit_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); 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) 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); free_commit_buffer_slab(o->buffer_slab);
o->buffer_slab = NULL; o->buffer_slab = NULL;
parsed_object_pool_reset_commit_grafts(o);
clear_alloc_state(o->blob_state); clear_alloc_state(o->blob_state);
clear_alloc_state(o->tree_state); clear_alloc_state(o->tree_state);
clear_alloc_state(o->commit_state); clear_alloc_state(o->commit_state);

View file

@ -7,6 +7,7 @@ struct buffer_slab;
struct repository; struct repository;
struct parsed_object_pool { struct parsed_object_pool {
struct repository *repo;
struct object **obj_hash; struct object **obj_hash;
int nr_objs, obj_hash_size; int nr_objs, obj_hash_size;
@ -31,8 +32,9 @@ struct parsed_object_pool {
struct buffer_slab *buffer_slab; 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_clear(struct parsed_object_pool *o);
void parsed_object_pool_reset_commit_grafts(struct parsed_object_pool *o);
struct object_list { struct object_list {
struct object *item; struct object *item;

View file

@ -54,7 +54,7 @@ void initialize_repository(struct repository *repo)
{ {
repo->objects = raw_object_store_new(); repo->objects = raw_object_store_new();
repo->remote_state = remote_state_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); ALLOC_ARRAY(repo->index, 1);
index_state_init(repo->index, repo); index_state_init(repo->index, repo);

View file

@ -97,7 +97,7 @@ static void reset_repository_shallow(struct repository *r)
{ {
r->parsed_objects->is_shallow = -1; r->parsed_objects->is_shallow = -1;
stat_validity_clear(r->parsed_objects->shallow_stat); 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) int commit_shallow_file(struct repository *r, struct shallow_lock *lk)