summaryrefslogtreecommitdiff
path: root/file.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2005-04-13 03:16:33 +0000
committerPaul Smith <psmith@gnu.org>2005-04-13 03:16:33 +0000
commit49ee105c685cb84bc3057e8b7666fc0cc7090047 (patch)
tree178eec81c5e39f56db9ca4b513376b3e1c5d35bf /file.c
parent3daf8df6ee835b9edcc068af33ae97910bb8d934 (diff)
downloadgunmake-49ee105c685cb84bc3057e8b7666fc0cc7090047.tar.gz
Fix performance degradation introduced by the second expansion feature.
I did this by adding intelligence into the algorithm such that the second expansion was only actually performed when the prerequisite list contained at least one "$", so we knew it is actually needed. Without this we were using up a LOT more memory, since every single target (even ones never used by make) had their file variables initialized. This also used a lot more CPU, since we needed to create and populate a new variable hash table for every target. There is one issue remaining with this feature: it leaks memory. In pattern_search() we now initialize the file variables for every pattern target, which allocates a hash table, etc. However, sometimes we recursively invoke pattern_search() (for intermediate files) with an automatic variable (alloca() I believe) as the file. When that function returns, obviously, the file variable hash memory is lost.
Diffstat (limited to 'file.c')
-rw-r--r--file.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/file.c b/file.c
index 1c34ff4..9f9ddb5 100644
--- a/file.c
+++ b/file.c
@@ -418,28 +418,40 @@ set_intermediate (const void *item)
static void
expand_deps (struct file *f)
{
- register struct dep *d, *d1;
+ struct dep *d, *d1;
struct dep *new = 0;
struct dep *old = f->deps;
unsigned int last_dep_has_cmds = f->updating;
+ int initialized = 0;
f->updating = 0;
f->deps = 0;
- /* We are going to do second expansion so initialize file
- variables for the file. */
- initialize_file_variables (f, 0);
-
for (d = old; d != 0; d = d->next)
{
if (d->name != 0)
{
char *p;
- struct dep **d_ptr;
- set_file_variables (f);
+ /* If we need a second expansion on these, set up the file
+ variables, etc. It takes a lot of extra memory and processing
+ to do this, so only do it if it's needed. */
+ if (! d->need_2nd_expansion)
+ p = d->name;
+ else
+ {
+ /* We are going to do second expansion so initialize file
+ variables for the file. */
+ if (!initialized)
+ {
+ initialize_file_variables (f, 0);
+ initialized = 1;
+ }
- p = variable_expand_for_file (d->name, f);
+ set_file_variables (f);
+
+ p = variable_expand_for_file (d->name, f);
+ }
/* Parse the dependencies. */
new = (struct dep *)
@@ -452,8 +464,8 @@ expand_deps (struct file *f)
/* Files that follow '|' are special prerequisites that
need only exist in order to satisfy the dependency.
Their modification times are irrelevant. */
+ struct dep **d_ptr;
- struct dep *d;
for (d_ptr = &new; *d_ptr; d_ptr = &(*d_ptr)->next)
;
++p;
@@ -463,8 +475,8 @@ expand_deps (struct file *f)
parse_file_seq (&p, '\0', sizeof (struct dep), 1),
sizeof (struct dep));
- for (d = *d_ptr; d != 0; d = d->next)
- d->ignore_mtime = 1;
+ for (d1 = *d_ptr; d1 != 0; d1 = d1->next)
+ d1->ignore_mtime = 1;
}
/* Enter them as files. */
@@ -476,6 +488,7 @@ expand_deps (struct file *f)
else
free (d1->name);
d1->name = 0;
+ d1->need_2nd_expansion = 0;
}
/* Add newly parsed deps to f->deps. If this is the last
@@ -492,15 +505,17 @@ expand_deps (struct file *f)
{
if (d->next == 0 && last_dep_has_cmds)
{
+ struct dep **d_ptr;
for (d_ptr = &new; *d_ptr; d_ptr = &(*d_ptr)->next)
- ;
+ ;
*d_ptr = f->deps;
f->deps = new;
}
else
{
- for (d_ptr = &(f->deps); *d_ptr; d_ptr = &(*d_ptr)->next)
+ struct dep **d_ptr;
+ for (d_ptr = &f->deps; *d_ptr; d_ptr = &(*d_ptr)->next)
;
*d_ptr = new;
@@ -509,7 +524,7 @@ expand_deps (struct file *f)
}
}
- free_ns_chain ((struct nameseq*)old);
+ free_ns_chain ((struct nameseq *) old);
}
/* For each dependency of each file, make the `struct dep' point
@@ -521,12 +536,12 @@ expand_deps (struct file *f)
void
snap_deps (void)
{
- register struct file *f;
- register struct file *f2;
- register struct dep *d;
- register struct file **file_slot_0;
- register struct file **file_slot;
- register struct file **file_end;
+ struct file *f;
+ struct file *f2;
+ struct dep *d;
+ struct file **file_slot_0;
+ struct file **file_slot;
+ struct file **file_end;
/* Perform second expansion and enter each dependency
name as a file. */