View mode: basic / threaded / horizontal-split · Log in · Help
November 11, 2009
@safe leak fix?
Consider the code:

  @safe:
    T[] foo(T[] a) { return a; }

    T[] bar()
    {
        T[10] x;
        return foo(x);
    }

Now we've got an escaping reference to bar's stack. This is not memory 
safe. But giving up slices is a heavy burden.

So it occurred to me that the same solution for closures can be used 
here. If the address is taken of a stack variable in a safe function, 
that variable is instead allocated on the heap. If a more advanced 
compiler could prove that the address does not escape, it could be put 
back on the stack.

The code will be a little slower, but it will be memory safe. This 
change wouldn't be done in trusted or unsafe functions.
November 11, 2009
Re: @safe leak fix?
Hello Walter,

> Consider the code:
> 
> @safe:
> T[] foo(T[] a) { return a; }
> T[] bar()
> {
> T[10] x;
> return foo(x);
> }
> Now we've got an escaping reference to bar's stack. This is not memory
> safe. But giving up slices is a heavy burden.
> 
> So it occurred to me that the same solution for closures can be used
> here. If the address is taken of a stack variable in a safe function,
> that variable is instead allocated on the heap. If a more advanced
> compiler could prove that the address does not escape, it could be put
> back on the stack.
> 
> The code will be a little slower, but it will be memory safe. This
> change wouldn't be done in trusted or unsafe functions.
> 

Sounds good. If it happens, I'd vote for a push on the static analysis to 
do those proofs.
November 11, 2009
Re: @safe leak fix?
On 2009-11-11 16:47:10 -0500, Walter Bright <newshound1@digitalmars.com> said:

> Consider the code:
> 
>    @safe:
>      T[] foo(T[] a) { return a; }
> 
>      T[] bar()
>      {
>          T[10] x;
>          return foo(x);
>      }
> 
> Now we've got an escaping reference to bar's stack. This is not memory 
> safe. But giving up slices is a heavy burden.
> 
> So it occurred to me that the same solution for closures can be used 
> here. If the address is taken of a stack variable in a safe function, 
> that variable is instead allocated on the heap. If a more advanced 
> compiler could prove that the address does not escape, it could be put 
> back on the stack.
> 
> The code will be a little slower, but it will be memory safe. This 
> change wouldn't be done in trusted or unsafe functions.

Interesting. This is exactly what I've proposed a few months ago while 
we were endlessly discussing about scope as a function argument 
modifier: automatic heap allocation of all escaping variables.

Of course I'm all for it. :-)

But now you should consider wether or not it should do the same in 
unsafe D. If it doesn't do the same unsafe D will crash for things safe 
D won't crash. If you do this in unsafe D you need a way to force a 
variable not be heap allocated whatever happens. (Perhaps using 'scope' 
as a storage modifier for variables.)

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
November 11, 2009
Re: @safe leak fix?
Walter Bright wrote:
> Consider the code:
> 
>   @safe:
>     T[] foo(T[] a) { return a; }
> 
>     T[] bar()
>     {
>         T[10] x;
>         return foo(x);
>     }
> 
> Now we've got an escaping reference to bar's stack. This is not memory 
> safe. But giving up slices is a heavy burden.
> 
> So it occurred to me that the same solution for closures can be used 
> here. If the address is taken of a stack variable in a safe function, 
> that variable is instead allocated on the heap. If a more advanced 
> compiler could prove that the address does not escape, it could be put 
> back on the stack.
> 
> The code will be a little slower, but it will be memory safe. This 
> change wouldn't be done in trusted or unsafe functions.

That's just idiotic. One of the main uses of static arrays is to _avoid_ 
heap memory allocation in the first place. Do what you want within 
@safe, but leave "unsafe" (oh god what a pejorative) alone.
November 11, 2009
Re: @safe leak fix?
grauzone wrote:
> Walter Bright wrote:
>> The code will be a little slower, but it will be memory safe. This 
>> change wouldn't be done in trusted or unsafe functions.
> That's just idiotic. One of the main uses of static arrays is to _avoid_ 
> heap memory allocation in the first place. Do what you want within 
> @safe,  but leave "unsafe" (oh god what a pejorative) alone.

Well, I did propose only doing this in safe functions!

Also, I agree with "unsafe" being a pejorative. Got any better ideas? 
"unchecked"?
November 11, 2009
Re: @safe leak fix?
Walter Bright wrote:
> grauzone wrote:
>> Walter Bright wrote:
>>> The code will be a little slower, but it will be memory safe. This 
>>> change wouldn't be done in trusted or unsafe functions.
>> That's just idiotic. One of the main uses of static arrays is to 
>> _avoid_ heap memory allocation in the first place. Do what you want 
>> within @safe,  but leave "unsafe" (oh god what a pejorative) alone.
> 
> Well, I did propose only doing this in safe functions!

In this case, the semantic difference between safe and unsafe functions 
will cause trouble, and you'd eventually end up imposing the "safe" 
semantics upon unsafe functions.

I'd vote for disallowing slicing in safe functions. Safe code can just 
use dynamic arrays instead. One other important use of arrays will be 
small SSE optimized vectors (as far as I understood that), but those 
should be fine in safe mode; usually you won't want to slice them.

> Also, I agree with "unsafe" being a pejorative. Got any better ideas? 
> "unchecked"?

Some brainstorming: highperf, fast mode, system mode, lowlevel, 
bare-metal, turbo mode (silly but fun), ...?
November 11, 2009
Re: @safe leak fix?
Walter Bright:

> Also, I agree with "unsafe" being a pejorative. Got any better ideas? 
> "unchecked"?

Naming it "unsafe" is OK because it's already used in C#, and because unsafe code is indeed worse than safe code (because lot of today people want safety), so it's a fit name.

Languages like C#, Java, etc, start being designed for safety from day 0, and then they add optimizations on top to make them fast too (and today Java is sometimes about as fast as C++, despite it lacks things as arrays of structs). D is now doing the opposite, but I think this try to create a SafeD may require a lot of work and in the end holes in the safety net may be possible still... I hope the design of SafeD will go well.

Bye,
bearophile
November 11, 2009
Re: @safe leak fix?
grauzone wrote:
> In this case, the semantic difference between safe and unsafe functions 
> will cause trouble, and you'd eventually end up imposing the "safe" 
> semantics upon unsafe functions.

May be.

> I'd vote for disallowing slicing in safe functions. Safe code can just 
> use dynamic arrays instead. One other important use of arrays will be 
> small SSE optimized vectors (as far as I understood that), but those 
> should be fine in safe mode; usually you won't want to slice them.

I thought of that, but I think it's too restrictive.

> 
>> Also, I agree with "unsafe" being a pejorative. Got any better ideas? 
>> "unchecked"?
> 
> Some brainstorming: highperf, fast mode, system mode, lowlevel, 
> bare-metal, turbo mode (silly but fun), ...?

"system" sounds good.
November 11, 2009
Re: @safe leak fix?
On Wed, 11 Nov 2009, Walter Bright wrote:

> So it occurred to me that the same solution for closures can be used here. If
> the address is taken of a stack variable in a safe function, that variable is
> instead allocated on the heap. If a more advanced compiler could prove that
> the address does not escape, it could be put back on the stack.
> 
> The code will be a little slower, but it will be memory safe. This change
> wouldn't be done in trusted or unsafe functions.

I think safe vs unsafe causing a behavior change is a really bad idea.  
They're contracts / constraints, not modifiers.

- Brad
November 11, 2009
Re: @safe leak fix?
Walter Bright wrote:
> grauzone wrote:
>> In this case, the semantic difference between safe and unsafe 
>> functions will cause trouble, and you'd eventually end up imposing the 
>> "safe" semantics upon unsafe functions.
> 
> May be.

Returning a slice to a local static array would be fine in safe mode, 
but lead to silent corruption in "unsafe" mode. I think everyone would 
assume that, if something works in safe mode, it should also work in 
unsafe mode.

So, it's really a "must", or is there some other way around it?
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home