Escape analysis

Robert Jacques sandford at jhu.edu
Tue Oct 28 16:38:23 PDT 2008


On Tue, 28 Oct 2008 14:46:34 -0400, Steven Schveighoffer  
<schveiguy at yahoo.com> wrote:
> "Robert Jacques" wrote
>> On Tue, 28 Oct 2008 09:44:28 -0400, Steven Schveighoffer
>> <schveiguy at yahoo.com> wrote:
>>> shared/unshared is not a storage class, it is a type modifier (like
>>> const).
>>
>> No, because shared and local objects get created and garbage collected  
>> on
>> different heaps.
>
> That's an interesting point.  Shared definitely has to be a type  
> modifier,
> otherwise, it cannot do this:
>
> shared int x = 0;
>
> int *xp = &x; // error, xp now is unshared, and points to shared data.
>
> But it probably also has to be a storage class also.  Not sure about  
> that.

This is a desirable error that was discussed back when shared was  
introduced. You can think of shared / local like immutable and mutable.  
The real problem is that a 'const' for shared/local/scope isn't clear yet.

>>
>>> In order for escape analysis to be useful, I need to be able to specify
>>> in a
>>> function such as:
>>>
>>> void foo(int *x, int **y, int **z)
>>>
>>> That x might escape to y's or z's scope.  How do you do allow that
>>> specification without making function signatures dreadfully  
>>> complicated?
>>
>> Well, x escapes to y or z is easy since it's how D works today.
>
> But what if y or z is not in x's scope?

Which is an issue with the user of foo, but not foo's signature.

> For instance:
> void bar(ref int *y, ref int *z)
> {
>    int x = 5;
>    foo(&x, &y, &z);
> }
>
> If y or z gets set to &x, then you have to allocate a closure for bar.
>
> The opposite example:
>
> void bar(int *y, int *z)
> {
>    int x = 5;
>    foo(&x, &y, &z);
> }
>
> No closure necessary.  So you need something to say that y or z can get  
> set
> to x, so the compiler would be smart enough to only allocate a closure  
> if y
> or z exists outside x's scope.  Otherwise, you have unnecessary closures,
> and we are in the same boat as today.

This example, although important is essentially about whether optimizing  
the closure is valid or not and has nothing to do with the behaviour of  
foo. However, this does seem to illustrate a need for three types: global  
escape (variable may escape to anywhere), pure escape (variable may escape  
to other inputs), no escape (variable is guaranteed not to escape). For  
example, if foo saved &x to a static variable (global escape) then is all  
cases it needs to be heap allocated. But if (as in your example) &x is  
saved to one of the function inputs (pure escape), then the caller can  
detect if it can ensure no escape and therefore use the stack.



More information about the Digitalmars-d mailing list