Skip to content

Commit dd45471

Browse files
jonathantanmygitster
authored andcommitted
grep: allocate subrepos on heap
Currently, struct repository objects corresponding to submodules are allocated on the stack in grep_submodule(). This currently works because they will not be used once grep_submodule() exits, but a subsequent patch will require these structs to be accessible for longer (perhaps even in another thread). Allocate them on the heap and clear them only at the very end. Signed-off-by: Jonathan Tan <[email protected]> Reviewed-by: Matheus Tavares <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 78ca584 commit dd45471

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

builtin/grep.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ static int todo_done;
6565
/* Has all work items been added? */
6666
static int all_work_added;
6767

68+
static struct repository **repos_to_free;
69+
static size_t repos_to_free_nr, repos_to_free_alloc;
70+
6871
/* This lock protects all the variables above. */
6972
static pthread_mutex_t grep_mutex;
7073

@@ -168,6 +171,19 @@ static void work_done(struct work_item *w)
168171
grep_unlock();
169172
}
170173

174+
static void free_repos(void)
175+
{
176+
int i;
177+
178+
for (i = 0; i < repos_to_free_nr; i++) {
179+
repo_clear(repos_to_free[i]);
180+
free(repos_to_free[i]);
181+
}
182+
FREE_AND_NULL(repos_to_free);
183+
repos_to_free_nr = 0;
184+
repos_to_free_alloc = 0;
185+
}
186+
171187
static void *run(void *arg)
172188
{
173189
int hit = 0;
@@ -415,19 +431,24 @@ static int grep_submodule(struct grep_opt *opt,
415431
const struct object_id *oid,
416432
const char *filename, const char *path, int cached)
417433
{
418-
struct repository subrepo;
434+
struct repository *subrepo;
419435
struct repository *superproject = opt->repo;
420436
const struct submodule *sub;
421437
struct grep_opt subopt;
422-
int hit;
438+
int hit = 0;
423439

424440
sub = submodule_from_path(superproject, null_oid(), path);
425441

426442
if (!is_submodule_active(superproject, path))
427443
return 0;
428444

429-
if (repo_submodule_init(&subrepo, superproject, sub))
445+
subrepo = xmalloc(sizeof(*subrepo));
446+
if (repo_submodule_init(subrepo, superproject, sub)) {
447+
free(subrepo);
430448
return 0;
449+
}
450+
ALLOC_GROW(repos_to_free, repos_to_free_nr + 1, repos_to_free_alloc);
451+
repos_to_free[repos_to_free_nr++] = subrepo;
431452

432453
/*
433454
* NEEDSWORK: repo_read_gitmodules() might call
@@ -438,7 +459,7 @@ static int grep_submodule(struct grep_opt *opt,
438459
* subrepo's odbs to the in-memory alternates list.
439460
*/
440461
obj_read_lock();
441-
repo_read_gitmodules(&subrepo, 0);
462+
repo_read_gitmodules(subrepo, 0);
442463

443464
/*
444465
* NEEDSWORK: This adds the submodule's object directory to the list of
@@ -450,11 +471,11 @@ static int grep_submodule(struct grep_opt *opt,
450471
* store is no longer global and instead is a member of the repository
451472
* object.
452473
*/
453-
add_submodule_odb_by_path(subrepo.objects->odb->path);
474+
add_submodule_odb_by_path(subrepo->objects->odb->path);
454475
obj_read_unlock();
455476

456477
memcpy(&subopt, opt, sizeof(subopt));
457-
subopt.repo = &subrepo;
478+
subopt.repo = subrepo;
458479

459480
if (oid) {
460481
enum object_type object_type;
@@ -464,9 +485,9 @@ static int grep_submodule(struct grep_opt *opt,
464485
struct strbuf base = STRBUF_INIT;
465486

466487
obj_read_lock();
467-
object_type = oid_object_info(&subrepo, oid, NULL);
488+
object_type = oid_object_info(subrepo, oid, NULL);
468489
obj_read_unlock();
469-
data = read_object_with_reference(&subrepo,
490+
data = read_object_with_reference(subrepo,
470491
oid, tree_type,
471492
&size, NULL);
472493
if (!data)
@@ -484,7 +505,6 @@ static int grep_submodule(struct grep_opt *opt,
484505
hit = grep_cache(&subopt, pathspec, cached);
485506
}
486507

487-
repo_clear(&subrepo);
488508
return hit;
489509
}
490510

@@ -1182,5 +1202,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
11821202
run_pager(&opt, prefix);
11831203
clear_pathspec(&pathspec);
11841204
free_grep_patterns(&opt);
1205+
free_repos();
11851206
return !hit;
11861207
}

0 commit comments

Comments
 (0)