make-alpha
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: undefine


From: Paul Smith
Subject: Re: undefine
Date: Mon, 5 Oct 2009 11:45:32 -0400

On Mon, 2009-10-05 at 17:16 +0200, Boris Kolpackov wrote:
> So I would like to implement a complimentary directive for 'define',
> called 'undefine', which will allow to completely undefine a variable:
> 
> foo := foo
> define bar
> bar
> endef
> 
> undefine foo
> undefine bar
> 
> $(info $(origin foo))
> $(info $(origin bar))
> 
> This would print:
> 
> undefined
> undefined
> 
> I made a prototype of this feature and it gave me a 20% speedup.
> 
> The only mildly interesting area in the implementation of undefine 
> is undefining of a command line variable. I think for this we should 
> just use the same approach as with define, i.e., it can only be done
> with override:
> 
> override undefine CFLAGS

We don't really have much precedent for combining keywords like this.
What if someone wrote "undefine override CFLAGS" instead?  Does/should
order matter here?

The other thing I wonder about is using undefine in a target-specific
variable context.  Is this allowed?  If so I suppose it undefines the
variable only if it's defined in that target, and not any "global"
setting of the variable?  This might need a bit of detail.


In a way it's a shame we don't have some concept of scope in the
makefile syntax.  We already have a concept of scope in variable
definitions; we can push a new variable context quite easily in the code
and that's done all the time.  If there were syntax brought out into the
makefile to push the variable scope then you could create variables
local to that scope and when it ended, they would be freed up using
existing features of the code.  Of course this is a big change to the
syntax and requires its own set of questions to be answered, such as is
scope only for variables?  What does it mean to define a target inside a
pushed scope?  etc.


Today we "know" that a variable, once defined, can never disappear.  I
think there might be a few places in the code where we try to do some
small performance improvements based on this; for example storing
pointers to variable structures in global variables to allow for faster
checking.  You might take a look at where we use global "struct
variable" variables.  Also, variable names are currently stored in the
string cache so they can never be removed from memory; your change might
save performance but it won't help memory usage (I know that's not why
you suggested it).


I'm actually a bit unhappy with the string cache.  I mean, the cache
itself is fine but it irks me that we have three entirely separate hash
tables: one for the string cache, one for files, and one for variables.
There's a lot of overlap here, IMO: we look up filenames in the string
cache and we also look them up in the file hash.  Ditto for variables.
Also, the set of strings that make up filenames and the set that make up
variable names are extremely unlikely to overlap.  I was toying with the
idea (not for 3.82 but in the future) of creating one string cache for
files and another for variable names, and combining the hash tables
together.  The only good way I can think of to do this is to increase
the size of the hash element to be two pointers: one to the string (for
the lookup etc.) and one to a struct file.  If the file pointer was NULL
then the file doesn't exist (we don't want to create a struct file for
every name in the filename hash).

If we allowed undefining of variables then doing this for variables
would be problematic since we'd lose the pointer to the variable name;
if someone wrote:

        foo = bar
        undefine foo
        foo = bar

then "foo" would be added to the variable string cache twice.  Maybe
that's not a big deal.

Now I'm just babbling :-)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]