Re: Garbage collection and closures.

2017-06-19 Thread Adam D. Ruppe via Digitalmars-d-learn

On Monday, 19 June 2017 at 09:18:56 UTC, Dsby wrote:

void uses(scope void delegate() dg);

will it be not alloc memory?


I test it , if use scope it will not alloc memony.


Right, using `scope` at the point the delegate variable is 
defined means it will never allocate.


Re: Garbage collection and closures.

2017-06-19 Thread Dsby via Digitalmars-d-learn

On Monday, 19 June 2017 at 09:10:16 UTC, Dsby wrote:

On Saturday, 17 June 2017 at 17:15:50 UTC, Adam D. Ruppe wrote:

On Saturday, 17 June 2017 at 14:19:34 UTC, ANtlord wrote:

[...]


Where the variable is defined that is referenced in the 
closure.


So:

[...]


if the uses parma is 'scope':

void uses(scope void delegate() dg);

will it be not alloc memory?


I test it , if use scope it will not alloc memony.

import std.stdio;

void call(void delegate() fun)
{
fun();
}

void call2(scope void delegate() fun)
{
fun();
}

void main()
{
int a = 10;
   // call((){writeln(a);});
call2((){writeln(a);});
}
dmd -vgc ./t.d
it will not print anything.

if use call:
void main()
{
int a = 10;
call((){writeln(a);});
   // call2((){writeln(a);});
}

dmd -vgc ./t.d
  
 182ms  2017年06月19日 星期一 17时16分47秒

./t.d(13): vgc: using closure causes GC allocation



Re: Garbage collection and closures.

2017-06-19 Thread Dsby via Digitalmars-d-learn

On Saturday, 17 June 2017 at 17:15:50 UTC, Adam D. Ruppe wrote:

On Saturday, 17 June 2017 at 14:19:34 UTC, ANtlord wrote:

[...]


Where the variable is defined that is referenced in the closure.

So:

[...]


if the uses parma is 'scope':

void uses(scope void delegate() dg);

will it be not alloc memory?





Re: Garbage collection and closures.

2017-06-17 Thread ANtlord via Digitalmars-d-learn

On Saturday, 17 June 2017 at 17:15:50 UTC, Adam D. Ruppe wrote:

On Saturday, 17 June 2017 at 14:19:34 UTC, ANtlord wrote:
Excuse me, I can't get what does it mean "deepest-referenced". 
What the deep you mean? The deep of a closure or deep of the 
function where the variable is defined. Can you give an 
example code?


Where the variable is defined that is referenced in the closure.

So:

---
void uses(void delegate() dg);

void foo() {
   int a;
   foreach(b; 0 .. 10) {
  uses( () { a++; } ); // #1
  uses( () { b++; } ); // #2
   }
}
---


In that case, #1 would only be allocated once, at the start of 
the foo() function. It only uses `a`, so it doesn't have to 
allocate again after the point a is defined.


But #2 might allocate each time through the loop. (It currently 
doesn't, but this is filed as an open bug because it is 
supposed to.) Since it uses `b` which is defined inside the 
loop, it will have to allocate a new copy for each iteration.


Is this function called every time when allocation happens in 
a heap?


Not any allocation, it is just the function the compiler uses 
when it needs to make a closure.


Thanks a lot, Adam! Everything is clear. Except for the bug. I've 
got an expected result of a value of the variable from #2. The 
value equals to number from sequence plus one in each iteration. 
There are ten iterations.


What's wrong? Are there should be five iterations? It doesn't 
make sense for me due to the variable assigned value from the 
sequence 0..10. Or do I look at the wrong place? Can you give me 
a link to the bug?


Thank you again!


Re: Garbage collection and closures.

2017-06-17 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 17 June 2017 at 14:19:34 UTC, ANtlord wrote:
Excuse me, I can't get what does it mean "deepest-referenced". 
What the deep you mean? The deep of a closure or deep of the 
function where the variable is defined. Can you give an example 
code?


Where the variable is defined that is referenced in the closure.

So:

---
void uses(void delegate() dg);

void foo() {
   int a;
   foreach(b; 0 .. 10) {
  uses( () { a++; } ); // #1
  uses( () { b++; } ); // #2
   }
}
---


In that case, #1 would only be allocated once, at the start of 
the foo() function. It only uses `a`, so it doesn't have to 
allocate again after the point a is defined.


But #2 might allocate each time through the loop. (It currently 
doesn't, but this is filed as an open bug because it is supposed 
to.) Since it uses `b` which is defined inside the loop, it will 
have to allocate a new copy for each iteration.


Is this function called every time when allocation happens in a 
heap?


Not any allocation, it is just the function the compiler uses 
when it needs to make a closure.


Re: Garbage collection and closures.

2017-06-17 Thread ANtlord via Digitalmars-d-learn

On Saturday, 17 June 2017 at 13:13:17 UTC, Adam D. Ruppe wrote:

On Saturday, 17 June 2017 at 13:03:28 UTC, ANtlord wrote:

Is GC called every iteration of this loop?


No, it will once on scope entry; where the deepest-referenced 
variable that is actually captured is defined. The compiler 
allocates heap space instead of stack space for the locals, 
then runs the function normally using that space.


Excuse me, I can't get what does it mean "deepest-referenced". 
What the deep you mean? The deep of a closure or deep of the 
function where the variable is defined. Can you give an example 
code?


It will only alloc once. You can prove this with a debugger 
btw, set a breakpoint on `_d_allocmemory`.


Is this function called every time when allocation happens in a 
heap?


Thank you. Sorry if my English is not clear.


Re: Garbage collection and closures.

2017-06-17 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 17 June 2017 at 13:03:28 UTC, ANtlord wrote:

Is GC called every iteration of this loop?


No, it will once on scope entry; where the deepest-referenced 
variable that is actually captured is defined. The compiler 
allocates heap space instead of stack space for the locals, then 
runs the function normally using that space.


The current implementation doesn't quite do this - it actually 
will alloc only once, on function entry, even when there's a 
variable inside a loop that is supposed to be independent. This 
is the cause of the commonly-referenced bug with foreach(i; 
whatever) capture(i); all showing the same number.


When that bug is fixed, it is possible to allocate on each 
loop... but your code doesn't anyway, so you're ok.


It will only alloc once. You can prove this with a debugger btw, 
set a breakpoint on `_d_allocmemory`.