Re: DIP60: @nogc attribute

2014-04-27 Thread via Digitalmars-d
Here's another thing that should be allowed that doesn't depend 
on optimizations:


Any code path in a @nogc function that is guaranteed to abort the 
program should be exempt from @nogc enforcement. This includes 
assert(0) and throwing an Error.


Take std.exception.assumeWontThrow() as an example:

T assumeWontThrow(T)(lazy T expr,
 string msg = null,
 string file = __FILE__,
 size_t line = __LINE__) nothrow
{
try
{
return expr;
}
catch(Exception e)
{
immutable tail = msg.empty ? . : :  ~ msg;
throw new AssertError(assumeWontThrow failed: Expression 
did throw ~

  tail, file, line);
}
}

Currently, this cannot be @nogc, because it uses `new` and `~`. 
However, this only happens in preparation to throwing the 
AssertError, which in turn causes the program to abort. I guess 
in this situation, it's ok to allocate on the GC heap.


With my proposed rule, assumeWontThrow can be deduced to be @nogc 
iff expr is @nogc. This allows more functions to be @nogc.


Re: DIP60: @nogc attribute

2014-04-27 Thread Jacob Carlborg via Digitalmars-d

On 2014-04-26 16:43, Daniel Murphy wrote:


At least these days it only happens when Walter and Andrei agree instead
of just Walter merging whatever he feels like.


Yeah, but it's still a problem when the rest of the community disagrees.

--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-26 Thread Walter Bright via Digitalmars-d

On 4/25/2014 7:28 AM, bearophile wrote:

Dicebot:


It is unacceptable to have code that fails with one compiler and works with
the other despite the shared frontend version. Such enhanced @nogc
attributes must be placed into compiler-specific attribute space and not as a
core language feature.


This problem was underlined during this thread far before the merging of the
@nogc implementation. Why have Walter  Andrei ignored the problem? What's the
point of creating a DIP if you ignore the problems found in its discussion?
What's the point of 338 comment posts if Walter goes on anyway with the original
idea? There are some problems in the D development method that must be 
addressed.


The @nogc logic is entirely contained in the front end, and is not affected by 
back end logic.




Re: DIP60: @nogc attribute

2014-04-26 Thread Jacob Carlborg via Digitalmars-d
On Friday, 25 April 2014 at 15:29:38 UTC, Steven Schveighoffer 
wrote:


Well, @nogc is not released yet. Please tell me we don't have 
to avoid breaking code based on git HEAD...


We've already done that before, with UDA's. So, you never know.

--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-26 Thread Jacob Carlborg via Digitalmars-d

On 2014-04-25 16:28, bearophile wrote:


This problem was underlined during this thread far before the merging of
the @nogc implementation. Why have Walter  Andrei ignored the problem?
What's the point of creating a DIP if you ignore the problems found in
its discussion? What's the point of 338 comment posts if Walter goes on
anyway with the original idea? There are some problems in the D
development method that must be addressed.


That's a problem. The problem is if someone has an idea/code it wants to 
be merged, it's enough to convince one developer with push right to get 
it merged.


--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-26 Thread bearophile via Digitalmars-d

Walter Bright:

The @nogc logic is entirely contained in the front end, and is 
not affected by back end logic.


Thank you for your answer and sorry for me being sometimes too 
much nervous.

So the problem I was alarmed about doesn't exists.

Some time ago I have filed this ER:
https://issues.dlang.org/show_bug.cgi?id=12642

That shows this rejected code that I thought could be accepted:

__gshared int[1] data1;
int[1] bar() @nogc {
int x;
return [x];
}
void main() @nogc {
int x;
data1 = [x];
int[1] data2;
data2 = [x];
}


So that's an example of what you are talking about. DMD is 
already performing some stack allocation of array literals that 
the @nogc is not seeing and rejecting.


Kenji Hara has commented:


If you remove @nogc annotation, all array literals will be
allocated on stack. So this is pure front-end issue,
and may be fixed easily.


So the ER 12642 should be a wontfix, or a front-end rule should 
be added to be added so all D compilers allocate those cases on 
the stack.


If I am not missing some more point, what is the best solution?

Bye,
bearophile


Re: DIP60: @nogc attribute

2014-04-26 Thread Daniel Murphy via Digitalmars-d

Jacob Carlborg  wrote in message news:ljfvec$126l$1...@digitalmars.com...

That's a problem. The problem is if someone has an idea/code it wants to 
be merged, it's enough to convince one developer with push right to get it 
merged.


At least these days it only happens when Walter and Andrei agree instead of 
just Walter merging whatever he feels like. 



Re: DIP60: @nogc attribute

2014-04-26 Thread bearophile via Digitalmars-d

If I am not missing some more point, what is the best solution?


Before this question gets lost, I'd like to receive some kind of 
answer.


Thank you,
bearophile


Re: DIP60: @nogc attribute

2014-04-26 Thread Timon Gehr via Digitalmars-d

On 04/27/2014 01:32 AM, bearophile wrote:

If I am not missing some more point, what is the best solution?


Before this question gets lost, I'd like to receive some kind of answer.

Thank you,
bearophile


The front end already distinguishes dynamic and static array literals 
(in a limited form), this distinction should simply carry through to 
code generation and static array literals should be allowed in @nogc code.


Re: DIP60: @nogc attribute

2014-04-25 Thread bearophile via Digitalmars-d

Walter Bright:

Pointing out these issues is exactly what @nogc is designed to 
do.


Using @nogc is like putting your code under a newly invented 
microscope, it allows to see things that I missed before :-)


Bye,
bearophile


Re: DIP60: @nogc attribute

2014-04-25 Thread via Digitalmars-d

On Thursday, 24 April 2014 at 13:35:39 UTC, bearophile wrote:

immutable int x = 3;
auto result = data[].map!(y = y * x);
}


test.d(1,6): Error: function D main @nogc function allocates a 
closure with the GC


Such kind of code is common, so a good amount of range-based 
code can't be @nogc.


Why can't this be on the stack if the referenced local function 
(lambda) does not outlive the stack frame?


Re: DIP60: @nogc attribute

2014-04-25 Thread Steven Schveighoffer via Digitalmars-d
On Fri, 25 Apr 2014 07:28:27 -0400, Ola Fosheim Grøstad  
ola.fosheim.grostad+dl...@gmail.com wrote:



On Thursday, 24 April 2014 at 13:35:39 UTC, bearophile wrote:

immutable int x = 3;
auto result = data[].map!(y = y * x);
}


test.d(1,6): Error: function D main @nogc function allocates a closure  
with the GC


Such kind of code is common, so a good amount of range-based code can't  
be @nogc.


Why can't this be on the stack if the referenced local function (lambda)  
does not outlive the stack frame?


It could. I don't think the compiler is smart enough, as it would need to  
verify result doesn't go anywhere (flow analysis).


I wonder if LDC/GDC could do it.

One interesting thing about this is that the compiler implementation may  
make some @nogc code valid on some compilers, and invalid on others, even  
though the resulting execution is the same.


-Steve


Re: DIP60: @nogc attribute

2014-04-25 Thread David Nadlinger via Digitalmars-d
On Friday, 25 April 2014 at 12:07:00 UTC, Steven Schveighoffer 
wrote:
One interesting thing about this is that the compiler 
implementation may make some @nogc code valid on some 
compilers, and invalid on others, even though the resulting 
execution is the same.


I don't think this is a desirable behavior. @nogc should be 
decided in the frontend, before closure allocation optimizations 
take place.


David


Re: DIP60: @nogc attribute

2014-04-25 Thread via Digitalmars-d
On Friday, 25 April 2014 at 12:07:00 UTC, Steven Schveighoffer 
wrote:
It could. I don't think the compiler is smart enough, as it 
would need to verify result doesn't go anywhere (flow analysis).


In that case I'd like to see recursive inlining, if it makes 
stack allocations more probable.


Re: DIP60: @nogc attribute

2014-04-25 Thread via Digitalmars-d

On Friday, 25 April 2014 at 12:21:40 UTC, David Nadlinger wrote:
On Friday, 25 April 2014 at 12:07:00 UTC, Steven Schveighoffer 
wrote:
One interesting thing about this is that the compiler 
implementation may make some @nogc code valid on some 
compilers, and invalid on others, even though the resulting 
execution is the same.


I don't think this is a desirable behavior. @nogc should be 
decided in the frontend, before closure allocation 
optimizations take place.


Yes, but the language specification should guarantee that no heap 
allocation takes place at least for some simple cases. `scope` 
comes to mind... This can apply to other normally allocating 
operations, too, like `new` and array concatenation/appending.


Re: DIP60: @nogc attribute

2014-04-25 Thread Steven Schveighoffer via Digitalmars-d
On Fri, 25 Apr 2014 08:21:38 -0400, David Nadlinger c...@klickverbot.at  
wrote:



On Friday, 25 April 2014 at 12:07:00 UTC, Steven Schveighoffer wrote:
One interesting thing about this is that the compiler implementation  
may make some @nogc code valid on some compilers, and invalid on  
others, even though the resulting execution is the same.


I don't think this is a desirable behavior. @nogc should be decided in  
the frontend, before closure allocation optimizations take place.


I don't know that it's desirable to have @nogc reject code even though an  
allocation does not occur. I agree the situation is not ideal, but @nogc  
is a practical optimization.


I can think of other cases where the GC may be optimized out. To reject  
such code in @nogc would make it much less attractive.


-Steve


Re: DIP60: @nogc attribute

2014-04-25 Thread Dicebot via Digitalmars-d
On Friday, 25 April 2014 at 12:59:55 UTC, Steven Schveighoffer 
wrote:
On Fri, 25 Apr 2014 08:21:38 -0400, David Nadlinger 
c...@klickverbot.at wrote:


On Friday, 25 April 2014 at 12:07:00 UTC, Steven Schveighoffer 
wrote:
One interesting thing about this is that the compiler 
implementation may make some @nogc code valid on some 
compilers, and invalid on others, even though the resulting 
execution is the same.


I don't think this is a desirable behavior. @nogc should be 
decided in the frontend, before closure allocation 
optimizations take place.


I don't know that it's desirable to have @nogc reject code even 
though an allocation does not occur. I agree the situation is 
not ideal, but @nogc is a practical optimization.


I can think of other cases where the GC may be optimized out. 
To reject such code in @nogc would make it much less attractive.


-Steve


It is unacceptable to have code that fails with one compiler and 
works with the other despite the shared frontend version. Such 
enhanced @nogc attributes must be placed into compiler-specific 
attribute space and not as a core language feature.


Re: DIP60: @nogc attribute

2014-04-25 Thread Steven Schveighoffer via Digitalmars-d

On Fri, 25 Apr 2014 09:20:08 -0400, Dicebot pub...@dicebot.lv wrote:


On Friday, 25 April 2014 at 12:59:55 UTC, Steven Schveighoffer wrote:


I don't know that it's desirable to have @nogc reject code even though  
an allocation does not occur. I agree the situation is not ideal, but  
@nogc is a practical optimization.


I can think of other cases where the GC may be optimized out. To reject  
such code in @nogc would make it much less attractive.




It is unacceptable to have code that fails with one compiler and works  
with the other despite the shared frontend version. Such enhanced  
@nogc attributes must be placed into compiler-specific attribute space  
and not as a core language feature.


Like I said, this may be the ideologically correct position, but please  
explain to the poor user that even though the compiler does not invoke the  
GC in his function, it still cannot be @nogc.


I think in this case, @nogc is not a good name.

But what really is the difference between a function that is marked as  
@nogc that compiles on compiler X but not compiler Y, and some custom  
attribute that compiles on X but not Y?


Consider that the fact that compiler X could have compiled a function that  
compiler Y is linking to, may actually be @nogc, because compiler X is  
better at avoiding GC calls. Wouldn't it make sense to be able to mark it  
@nogc and still use it from compiler Y?


-Steve


Re: DIP60: @nogc attribute

2014-04-25 Thread bearophile via Digitalmars-d

Dicebot:

It is unacceptable to have code that fails with one compiler 
and works with the other despite the shared frontend version. 
Such enhanced @nogc attributes must be placed into 
compiler-specific attribute space and not as a core language 
feature.


This problem was underlined during this thread far before the 
merging of the @nogc implementation. Why have Walter  Andrei 
ignored the problem? What's the point of creating a DIP if you 
ignore the problems found in its discussion? What's the point of 
338 comment posts if Walter goes on anyway with the original 
idea? There are some problems in the D development method that 
must be addressed.


Bye,
bearophile


Re: DIP60: @nogc attribute

2014-04-25 Thread Dicebot via Digitalmars-d
On Friday, 25 April 2014 at 14:01:07 UTC, Steven Schveighoffer 
wrote:
It is unacceptable to have code that fails with one compiler 
and works with the other despite the shared frontend version. 
Such enhanced @nogc attributes must be placed into 
compiler-specific attribute space and not as a core language 
feature.


Like I said, this may be the ideologically correct position, 
but please explain to the poor user that even though the 
compiler does not invoke the GC in his function, it still 
cannot be @nogc.


I think in this case, @nogc is not a good name.


Which is the very reason why I was so insisting of defining exact 
set of cases when optimisation is to be guaranteed in spec 
(before releasing @nogc). Unfortunately, with no success.


But what really is the difference between a function that is 
marked as @nogc that compiles on compiler X but not compiler Y, 
and some custom attribute that compiles on X but not Y?


There are no user-defined attributes that can possibly fail on 
only some compiler. And compiler-specific attributes are part of 
that compiler documentation and never part of language spec. This 
is the difference.


Re: DIP60: @nogc attribute

2014-04-25 Thread Steven Schveighoffer via Digitalmars-d

On Fri, 25 Apr 2014 11:12:54 -0400, Dicebot pub...@dicebot.lv wrote:


On Friday, 25 April 2014 at 14:01:07 UTC, Steven Schveighoffer wrote:
It is unacceptable to have code that fails with one compiler and works  
with the other despite the shared frontend version. Such enhanced  
@nogc attributes must be placed into compiler-specific attribute space  
and not as a core language feature.


Like I said, this may be the ideologically correct position, but please  
explain to the poor user that even though the compiler does not invoke  
the GC in his function, it still cannot be @nogc.


I think in this case, @nogc is not a good name.


Which is the very reason why I was so insisting of defining exact set of  
cases when optimisation is to be guaranteed in spec (before releasing  
@nogc). Unfortunately, with no success.


Well, @nogc is not released yet. Please tell me we don't have to avoid  
breaking code based on git HEAD...




But what really is the difference between a function that is marked as  
@nogc that compiles on compiler X but not compiler Y, and some custom  
attribute that compiles on X but not Y?


There are no user-defined attributes that can possibly fail on only some  
compiler. And compiler-specific attributes are part of that compiler  
documentation and never part of language spec. This is the difference.


But such a situation would not violate a spec that says @nogc means there  
are no hidden GC calls. And the end result is identical -- I must compile  
function foo on compiler X only.


I agree there are likely no precedents for this.

Another option would be to put such a compiler-specific attribute around  
the code in question rather than a different attribute than @nogc on the  
function itself. I think there's really no avoiding that this will happen  
some way or another.


-Steve


Re: DIP60: @nogc attribute

2014-04-25 Thread Steven Schveighoffer via Digitalmars-d
On Fri, 25 Apr 2014 11:29:37 -0400, Steven Schveighoffer  
schvei...@yahoo.com wrote:



On Fri, 25 Apr 2014 11:12:54 -0400, Dicebot pub...@dicebot.lv wrote:


On Friday, 25 April 2014 at 14:01:07 UTC, Steven Schveighoffer wrote:
But what really is the difference between a function that is marked as  
@nogc that compiles on compiler X but not compiler Y, and some custom  
attribute that compiles on X but not Y?


There are no user-defined attributes that can possibly fail on only  
some compiler. And compiler-specific attributes are part of that  
compiler documentation and never part of language spec. This is the  
difference.


But such a situation would not violate a spec that says @nogc means  
there are no hidden GC calls. And the end result is identical -- I must  
compile function foo on compiler X only.


You know what, in fact, @nogc may need to be re-branded as  
compiler-specific.


-Steve


Re: DIP60: @nogc attribute

2014-04-25 Thread Dicebot via Digitalmars-d
On Friday, 25 April 2014 at 15:29:38 UTC, Steven Schveighoffer 
wrote:

On Fri, 25 Apr 2014 11:12:54 -0400, Dicebot pub...@dicebot.lv
Which is the very reason why I was so insisting of defining 
exact set of cases when optimisation is to be guaranteed in 
spec (before releasing @nogc). Unfortunately, with no success.


Well, @nogc is not released yet. Please tell me we don't have 
to avoid breaking code based on git HEAD...


It has become a blocker for next release though. It has been 
repeated numerous times that such features need to be developed 
in own feature branches until design is considered at least 
somewhat solid =/




But what really is the difference between a function that is 
marked as @nogc that compiles on compiler X but not compiler 
Y, and some custom attribute that compiles on X but not Y?


There are no user-defined attributes that can possibly fail on 
only some compiler. And compiler-specific attributes are part 
of that compiler documentation and never part of language 
spec. This is the difference.


But such a situation would not violate a spec that says @nogc 
means there are no hidden GC calls. And the end result is 
identical -- I must compile function foo on compiler X only.


It is invalid and useless spec on its own. It would have been a 
valid spec if it also had a chapter with definitive list of all 
cases when hidden GC calls can happen and when are guaranteed to 
be optimized away. Otherwise such spec is as useful as one that 
says Maybe your code will compile.



I agree there are likely no precedents for this.

Another option would be to put such a compiler-specific 
attribute around the code in question rather than a different 
attribute than @nogc on the function itself. I think there's 
really no avoiding that this will happen some way or another.


I think there should be both. Saying that you need to marry 
specific compiler forever once you want to use @nogc is pretty 
much same as saying don't use @nogc.


Re: DIP60: @nogc attribute

2014-04-25 Thread via Digitalmars-d
On Friday, 25 April 2014 at 15:32:40 UTC, Steven Schveighoffer 
wrote:


You know what, in fact, @nogc may need to be re-branded as 
compiler-specific.


You should have a compiler switch that let's you get 
compiler-optimal non-portable @nogc.


Re: DIP60: @nogc attribute

2014-04-25 Thread Steven Schveighoffer via Digitalmars-d
On Fri, 25 Apr 2014 20:50:46 -0400, Ola Fosheim Grøstad  
ola.fosheim.grostad+dl...@gmail.com wrote:



On Friday, 25 April 2014 at 15:32:40 UTC, Steven Schveighoffer wrote:


You know what, in fact, @nogc may need to be re-branded as  
compiler-specific.


You should have a compiler switch that let's you get compiler-optimal  
non-portable @nogc.


I feel like I'm being a nag, but it sure seems to me like having something  
like that is no different than custom behavior of @nogc. Basically, I have  
a file blah.d, which can only be compiled with X, even if it's only with  
the option X -extraNogcFunctionality


In other words, I have this function. It can avoid GC allocations if the  
compiler can do extra steps to prove it. But not all compilers go to these  
lengths.


So if I only care about compiling with savvy enough compilers, why do I  
need to use some special compiler-specific escape? I think the attribute  
is fine being defined as if you can't do this without calling the GC,  
refuse to compile, and the compiler may or may not compile it.


In any case, I don't need another explanation, I don't think it will ever  
make sense to me.


-Steve


Re: DIP60: @nogc attribute

2014-04-25 Thread via Digitalmars-d
On Saturday, 26 April 2014 at 04:49:07 UTC, Steven Schveighoffer 
wrote:
In any case, I don't need another explanation, I don't think it 
will ever make sense to me.


It makes sense because there are two different use cases:

1. Library authors who need a more conservative interpretation of 
@nogc.


2. Binary release productions who only want to be certain that 
the GC is not called where it could lead to a crash.



It would be annoying to have to rewrite code when the compiler 
actually knows that it does not touch the GC. So the latter use 
cases need the less conservative approach.


Re: DIP60: @nogc attribute

2014-04-24 Thread Jacob Carlborg via Digitalmars-d

On 23/04/14 19:12, Walter Bright wrote:


Too many double negatives for me to be sure what you're saying. But it
is clear to me that with Michel's experience with ARC in iOS combined
with Manu's enthusiasm for it suggests that they are the right team to
come up with a workable proposal, where mine failed.


Sorry, now that I read it out loud it is confusing. Here's another try:

You're proposal wasn't compatible with ARC in Objective-C.

I'm not sure if I remember correctly.

--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-24 Thread bearophile via Digitalmars-d

Walter Bright:


http://wiki.dlang.org/DIP60

Start on implementation:

https://github.com/D-Programming-Language/dmd/pull/3455


Currently this code doesn't compile because the lambda allocates 
the closure on the heap:


void main() @nogc {
import std.algorithm: map;
int[3] data = [1, 2, 3];
immutable int x = 3;
auto result = data[].map!(y = y * x);
}


test.d(1,6): Error: function D main @nogc function allocates a 
closure with the GC


Such kind of code is common, so a good amount of range-based code 
can't be @nogc.


---

In the meantime the good Kenji has created a patch for missing 
semantics:

https://github.com/D-Programming-Language/dmd/pull/3493

Bye,
bearophile


Re: DIP60: @nogc attribute

2014-04-24 Thread Walter Bright via Digitalmars-d

On 4/24/2014 6:35 AM, bearophile wrote:

Currently this code doesn't compile because the lambda allocates the closure on
the heap:


Pointing out these issues is exactly what @nogc is designed to do.


void main() @nogc {
 import std.algorithm: map;
 int[3] data = [1, 2, 3];
 immutable int x = 3;
 auto result = data[].map!(y = y * x);
}


test.d(1,6): Error: function D main @nogc function allocates a closure with the 
GC

Such kind of code is common,


True.


so a good amount of range-based code can't be @nogc.


Can't is a bit strong of a word. Needing a workaround that is perhaps a bit 
ugly is more accurate. For your example,


enum int x = 3;

will solve the issue.




Re: DIP60: @nogc attribute

2014-04-24 Thread bearophile via Digitalmars-d

Walter Bright:

Pointing out these issues is exactly what @nogc is designed to 
do.


Right.


Can't is a bit strong of a word. Needing a workaround that is 
perhaps a bit ugly is more accurate. For your example,


enum int x = 3;

will solve the issue.


In most cases that x is a run-time value, as in my example.

Bye,
bearophile


Re: DIP60: @nogc attribute

2014-04-24 Thread Walter Bright via Digitalmars-d

On 4/24/2014 11:49 AM, bearophile wrote:

Walter Bright:

Can't is a bit strong of a word. Needing a workaround that is perhaps a bit
ugly is more accurate. For your example,

enum int x = 3;

will solve the issue.


In most cases that x is a run-time value, as in my example.


You can make it a static and it'll work. Ugly, but it'll work.



Re: DIP60: @nogc attribute

2014-04-23 Thread Jacob Carlborg via Digitalmars-d

On 23/04/14 06:33, Walter Bright wrote:


I repeatedly said that it is not memory safe because you must employ
escapes from it to get performance.


Apparently you need that for the GC as well, that's why this thread was 
started to begin with.


--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-23 Thread Jacob Carlborg via Digitalmars-d

On 22/04/14 20:48, Steven Schveighoffer wrote:


I mean not like I can't because I don't want to or don't have time, but
can't as in I lack the skill set :) It's interesting to debate, and I
get the concepts, but I am not a CPU/cache guy, and these things are
really important to get right for performance, since ref counting would
be used frequently.


That's the worst kind of excuses :) I don't remember the last time I 
started working on a project and know what I was doing/had the right 
skill set. I mean, that's how you learn.


--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-23 Thread Manu via Digitalmars-d
On 22 April 2014 05:03, Walter Bright via Digitalmars-d
digitalmars-d@puremagic.com wrote:
 On 4/21/2014 10:57 AM, Steven Schveighoffer wrote:

 On Mon, 21 Apr 2014 13:28:24 -0400, Walter Bright
 newshou...@digitalmars.com
 wrote:

 On 4/21/2014 5:00 AM, Steven Schveighoffer wrote:

 Total replacement of GC with ARC in D will:

 This is the wrong straw-man, I'm not advocating for this at all.


 Many are when they advocate ARC for D.


 Does that preclude you from accepting any kind of ARC for D?


 No. My objection is to pervasive ARC, i.e. all gc is replaced with ARC, and
 it all magically works.

It's not magic, it's careful engineering, and considering each problem
case one by one as they arise until it's good.


 5. Numerous posters here have posited that the overhead of ARC can be
 eliminated with a sufficiently smart compiler (which does not exist).


 You continue to speak in extremes. People are saying that the compiler can
 eliminate most of the needless ARC increments and decrements, not all of
 them.


 Manu, for example, suggests it is good enough to make the overhead
 insignificant. I'm skeptical.

I didn't quite say that, but let me justify that claim if you want to
put it in those words.

RC fiddling in low-frequency code is insignificant.
High-frequency code doesn't typically allocate, and is also likely to
implement a context specific solution anyway if it is truly
performance sensitive.
In the event of code where RC fiddling is found to make a significant
impact on performance, there are various tools available to address
this directly.

There's a middle-ground that might suffer compared to GC;
moderate-frequency, where code is sloppily written doing whatever it
likes without any real care, and run lots of iterations. But that's
not usually an example of performance sensitive code, it's just crappy
code run many times, and again, they have the tools to improve it
easily if they care enough to do so.

I also believe programmers will learn the performance characteristics
of ARC very quickly, and work with it effectively. The core of my
argument is that it's _possible_ to work with ARC, it's not possible
to work with GC if it is fundamentally incompatible with your
application.


 Compilers that do this do exist.


 I can't reconcile agreeing that ARC isn't good enough to be pervasive with
 compiler technology eliminates unnecessary ARC overhead.

The most important elimination is objects being passed down a
call-tree via args. That can certainly eliminate properly.
High-frequency code always exists nearer to the leaves.
D has pure (which is definitely well employed), and 'shared' is an
explicit attribute, which allows the compiler to make way more
assumptions than O-C.

The ARC optimisations are predictable and reliable. The suggestion
that acceptable code performance relying on specific optimisation is a
concept you can't reconcile is a bit strange. Programmers rely on
optimisation all the time for acceptable performance. This is no
different.


Re: DIP60: @nogc attribute

2014-04-23 Thread Walter Bright via Digitalmars-d
Manu, you obviously believe in ARC. I've made an attempt to do ARC, detailed in 
the other thread here. I failed.


http://forum.dlang.org/thread/l34lei$255v$1...@digitalmars.com

Michel Fortin also wants to bring iOS ARC to D.

I suggest you get together with Michel and work out a detailed design, and 
propose it.


Re: DIP60: @nogc attribute

2014-04-23 Thread Manu via Digitalmars-d
On 23 April 2014 04:28, Steven Schveighoffer via Digitalmars-d
digitalmars-d@puremagic.com wrote:
 On Tue, 22 Apr 2014 14:12:17 -0400, Walter Bright
 newshou...@digitalmars.com wrote:

 On 4/22/2014 6:18 AM, Steven Schveighoffer wrote:

 On Mon, 21 Apr 2014 19:02:53 -0400, Walter Bright
 newshou...@digitalmars.com
 wrote:

 The thing is, with iOS ARC, it cannot be statically guaranteed to be
 memory safe.


 So?


 If you see no value in static guarantees of memory safety, then what can I
 say?


 Seriously, the straw man arguments have to stop.

 There is plenty of valuable D code that is not guaranteed memory safe. For
 example, druntime.

 ARC does not equal guaranteed memory safety. So NO, it cannot replace the GC
 for D @safe code. That doesn't make it useless.

Why not? Assuming that direct access to the refcount is not @safe, why
would ARC be unsafe? What makes it less safe than the GC?


Re: DIP60: @nogc attribute

2014-04-23 Thread via Digitalmars-d

On Tuesday, 22 April 2014 at 19:42:20 UTC, Michel Fortin wrote:
Objective-C isn't memory safe because it lets you play with raw 
pointers too. If you limit yourself to ARC-managed pointers 
(and avoid undefined behaviours inherited from C) everything is 
perfectly memory safe.


I'm not convinced that it is safe in multi-threaded mode. How 
does ARC deal with parallell reads and writes from two different 
threads? IIRC the most common implementations deals with 
read/read and write/write, but read/write is too costly?




Re: DIP60: @nogc attribute

2014-04-23 Thread Jacob Carlborg via Digitalmars-d

On 23/04/14 10:31, Walter Bright wrote:

Manu, you obviously believe in ARC. I've made an attempt to do ARC,
detailed in the other thread here. I failed.

http://forum.dlang.org/thread/l34lei$255v$1...@digitalmars.com


That conversation started out from the D/Objective-C conversations. To 
have ARC in D and be compatible with the one in Objective-C you don't 
have many choices. I'm not sure but I don't think your proposal was not 
compatible with ARC in Objective-C.


--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-23 Thread Michel Fortin via Digitalmars-d
On 2014-04-23 09:50:57 +, Ola Fosheim Grøstad 
ola.fosheim.grostad+dl...@gmail.com said:



On Tuesday, 22 April 2014 at 19:42:20 UTC, Michel Fortin wrote:
Objective-C isn't memory safe because it lets you play with raw 
pointers too. If you limit yourself to ARC-managed pointers (and avoid 
undefined behaviours inherited from C) everything is perfectly memory 
safe.


I'm not convinced that it is safe in multi-threaded mode. How does ARC 
deal with parallell reads and writes from two different threads? IIRC 
the most common implementations deals with read/read and write/write, 
but read/write is too costly?


The answer is that in the general case you should protect reads and 
writes to an ARC pointer with locks. Otherwise the counter risk being 
getting out of sync and later you'll get corruption somewhere.


There are atomic properties which are safe to read and write from 
multiple threads. Internally they use the @synchronized keyword on the 
object.


But since there's no 'shared' attribute in Objective-C, you can't go 
very far if you wanted the compiler to check things for memory safety. 
That said, if you assume a correct implementation of the NSCopying 
protocol (deep copying), objects following that protocol would be safe 
to pass through a std.concurrency-like interface.


In all honesty, I'm not that impressed with the multithreading 
protections in D either. It seems you so often have to bypass the type 
system to make something useful that it doesn't appear very different 
from not having them. And don't get me started with synchronized 
classes...


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: DIP60: @nogc attribute

2014-04-23 Thread Michel Fortin via Digitalmars-d

On 2014-04-23 04:33:00 +, Walter Bright newshou...@digitalmars.com said:


On 4/22/2014 12:42 PM, Michel Fortin wrote:

On 2014-04-22 19:02:05 +, Walter Bright newshou...@digitalmars.com said:


Memory safety is not a strawman. It's a critical feature for a modern
language, and will become ever more important.


What you don't seem to get is that ARC, by itself, is memory-safe.


I repeatedly said that it is not memory safe because you must employ 
escapes from it to get performance.


It wasn't that clear to me you were saying that, but now it makes sense.

In Objective-C, the performance-sensitive parts are going to be 
implemented in C, that's true. But that's rarely going to be more than 
5% of your code, and probably only a few isolated parts where you're 
using preallocated memory blocks retained by ARC while you're playing 
with the content.


If you're writing something that can't tolerate a GC pause, then it 
makes perfect sense to make this performance-critical code unsafe so 
you can write the remaining 95% of your app in a memory-safe 
environment with no GC pause.


D on the other hand forces you to have those GC pauses or have no 
memory management at all. It's a different tradeoff and it isn't 
suitable everywhere, but I acknowledge it makes it easier to make 
performance-sensitive code @safe, something that'd be a shame to lose.



Objective-C isn't memory safe because it lets you play with raw 
pointers too. If

you limit yourself to ARC-managed pointers (and avoid undefined behaviours
inherited from C) everything is perfectly memory safe.


Allow me to make it clear that IF you never convert an ARC reference to 
a raw pointer in userland, I agree that it is memory safe. But this is 
not practical for high performance code.


Framing the problem this way makes it easier to find a solution.

I wonder, would it be acceptable if ARC was used everywhere by default 
but could easily be disabled inside performance-sensitive code by 
allowing the user choose between safe GC-based memory management or 
unsafe manual memory management? I have an idea that'd permit just 
that. Perhaps I should write a DIP about it.




I'm pretty confident that had I continued my work on D/Objective-C we'd now be
able to interact with Objective-C objects using ARC in @safe code. I was
planning for that. Objective-C actually isn't very far from memory safety now
that it has ARC, it just lacks the @safe attribute to enable compiler 
verification.


I wish you would continue that work!


I wish I had the time too.

--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: DIP60: @nogc attribute

2014-04-23 Thread Steven Schveighoffer via Digitalmars-d
On Wed, 23 Apr 2014 05:14:44 -0400, Manu via Digitalmars-d  
digitalmars-d@puremagic.com wrote:



On 23 April 2014 04:28, Steven Schveighoffer via Digitalmars-d
ARC does not equal guaranteed memory safety. So NO, it cannot replace  
the GC

for D @safe code. That doesn't make it useless.


Why not? Assuming that direct access to the refcount is not @safe, why
would ARC be unsafe? What makes it less safe than the GC?


Arguably, it is safe, as long as you only use ARC pointers. I don't know  
that I would ever want or use that in D (or even Objective-C). So it's not  
that it's not safe, it's that it cannot be a drop-in-replacement for the  
GC in existing D @safe code.


For example, you could never use slices or ranges, or these would have to  
be rewritten to keep references to the full object.


-Steve


Re: DIP60: @nogc attribute

2014-04-23 Thread Steven Schveighoffer via Digitalmars-d

On Wed, 23 Apr 2014 02:11:38 -0400, Jacob Carlborg d...@me.com wrote:


On 22/04/14 20:48, Steven Schveighoffer wrote:


I mean not like I can't because I don't want to or don't have time, but
can't as in I lack the skill set :) It's interesting to debate, and I
get the concepts, but I am not a CPU/cache guy, and these things are
really important to get right for performance, since ref counting would
be used frequently.


That's the worst kind of excuses :) I don't remember the last time I  
started working on a project and know what I was doing/had the right  
skill set. I mean, that's how you learn.


Sure, but there are things I CAN do with my limited time, that I do have  
the expertise for. I've already been schooled by the likes of you and  
Michel Fortin on my knowledge of ref counting implementation.


BTW, this is how RedBlackTree (dcollections) came into existence, I had no  
idea what I was doing, just the API that I wanted (and back then, I had  
more time). The code is actually a slightly-hand-optimized copy of my CLR  
book's red-black algorithm.


-Steve


Re: DIP60: @nogc attribute

2014-04-23 Thread Jacob Carlborg via Digitalmars-d

On 2014-04-23 17:57, Steven Schveighoffer wrote:


Sure, but there are things I CAN do with my limited time, that I do have
the expertise for. I've already been schooled by the likes of you and
Michel Fortin on my knowledge of ref counting implementation.


That's completely different. I've felt the same for a long time. Instead 
of working on the compiler I built tools and libraries for D. Then I 
finally couldn't keep my hands off and now I have D/Objective-C working 
for 64bit :)


--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-23 Thread Walter Bright via Digitalmars-d

On 4/23/2014 6:10 AM, Jacob Carlborg wrote:

That conversation started out from the D/Objective-C conversations. To have ARC
in D and be compatible with the one in Objective-C you don't have many choices.
I'm not sure but I don't think your proposal was not compatible with ARC in
Objective-C.


Too many double negatives for me to be sure what you're saying. But it is clear 
to me that with Michel's experience with ARC in iOS combined with Manu's 
enthusiasm for it suggests that they are the right team to come up with a 
workable proposal, where mine failed.




Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d

On Monday, 21 April 2014 at 23:02:54 UTC, Walter Bright wrote:

There is JUST NO WAY that:

struct RefCount {
T* data;
int* count;
}



This is actually quite efficient compared to the standard 
NSObject which uses a hashtable for refcounting:


http://www.opensource.apple.com/source/objc4/objc4-551.1/runtime/NSObject.mm
http://www.opensource.apple.com/source/objc4/objc4-551.1/runtime/llvm-DenseMap.h

This is how Core Foundation does it:

http://www.opensource.apple.com/source/CF/CF-855.11/CFRuntime.c

Pretty longwinded:

CFTypeRef CFRetain(CFTypeRef cf) {
if (NULL == cf) { CRSetCrashLogMessage(*** CFRetain() called 
with NULL ***); HALT; }

if (cf) __CFGenericAssertIsCF(cf);
return _CFRetain(cf, false);
}

static CFTypeRef _CFRetain(CFTypeRef cf, Boolean tryR) {
uint32_t cfinfo = *(uint32_t *)(((CFRuntimeBase 
*)cf)-_cfinfo);

if (cfinfo  0x80) { // custom ref counting for object
...stuff deleted…
refcount(+1, cf);
return cf;
}
…lots of stuff deleted…
return cf;
}


Re: DIP60: @nogc attribute

2014-04-22 Thread Jacob Carlborg via Digitalmars-d

On 21/04/14 19:49, Frustrated wrote:


Not quite. AST macros simply transform code. Attributes attach meta data
to code. While I'm sure there is some overlap they are not the same.

Unless AST macros have the ability to arbitrary add additional
contextual information to meta code then they can't emulate attributes.


I'm not saying we should emulate attributes, we already have those.

BTW, I'm pretty sure they could be implemented with macros. Just return 
the exact same AST that was passed in, but replace the top AST node with 
a node that is a subclass that adds the data for the UDA.



E.g., Suppose you have D with AST macros but not attributes, how can you
add them?

In the dip, you have

macro attr (Context context, Declaration decl)
{
 auto attrName = decl.name;
 auto type = decl.type;

 return [
 private $decl.type _$decl.name;

 $decl.type $decl.name ()
 {
 return _$decl.name;
 }

 $decl.type $decl.name ($decl.type value)
 {
 return _$decl.name = value;
 }
 ];
}

class Foo
{
 @attr int bar;
}

but attr is not an attribute. It is an macro. @attr converts the int
bar field into a private setter and getter. This has nothing to do with
attributes.


Sure it does. @nogc could be implemented with AST macros.

@nogc void foo ()
{
new Object;
}

macro nogc (Context context, Declaration decl)
{
if (containsGCAllocation(decl))
context.compiler.error(decl.name ~  marked with @nogc performs 
GC allocations);


return decl;
}


(just cause you use the attr word and the @ symbol doesn't make it an
attribute)


I don't see how you could ever add attributes to D using AST macros
above unless the definition of an AST macro is modified. [Again,
assuming D didn't have attributes in the first place]

This does not mean that AST macros could not be used to help define the
generalized attributes though.


What I am talking about is instead of hard coding attributes in the
compiler, one abstracts and generalizes the code so that any attribute
could be added in the future with minimal work.

It would simply require one to add the built in attributes list, add the
attribute grammar(which is used to reduce compound attributes), add any
actions that happen when the attribute is used in code.

e.g.,

builtin_attributes = {

 {pureness, pure, !pure/impure,
 attr = any(attr, impure) = impure
 attr = all(attr, pure) = pure
 }

 {gc, gc, !gc/nogc,
 attr = any(attr, gc) = gc
 attr = all(attr, nogc) = nogc
 }
 etc... }

notices that pureness and gc have the same grammatical rules. Code would
be added to handle the pureness and gc attributes when they are come
across for optimization purposes.

The above syntax is just made up and pretty bad but hopefully not too
difficult to get the bigger picture.

Every new built in attribute would just have to be added to the list
above(easy) and code that uses it for whatever purpose would be added in
the code where it belongs.

User define attributes essentially would make the attributes list above
dynamic allowing the user to add to it. The compiler would only be told
how to simplify the attributes using the grammar and would do so but
would not have any code inserted because there is no way for the user to
hook into the compiler properly(I suppose it could be done if the
compiler was written in an oop like way).


The AST macros would provide a way to hook into the compiler. We already 
have a way to define attributes, that is, UDA's. What is missing is a 
way to add semantic meanings the UDA's, that is where macros come in.


--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-22 Thread Jacob Carlborg via Digitalmars-d

On 22/04/14 01:02, Walter Bright wrote:


The thing is, with iOS ARC, it cannot be statically guaranteed to be
memory safe. This makes it simply not acceptable for D in the general
case. It works with iOS because iOS allows all kinds of (unsafe) ways
to escape it, and it must offer those ways because it is not performant.


So does D. That's why there is @safe, @trusted and @system. What is the 
unsafe part of ARC anyway?



--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-22 Thread Walter Bright via Digitalmars-d
On 4/21/2014 11:51 PM, Ola Fosheim Grøstad 
ola.fosheim.grostad+dl...@gmail.com wrote:

This is actually quite efficient compared to the standard NSObject which uses a
hashtable for refcounting:


It's not efficient compared to pointers.



Re: DIP60: @nogc attribute

2014-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2014 12:11 AM, Jacob Carlborg wrote:

On 22/04/14 01:02, Walter Bright wrote:


The thing is, with iOS ARC, it cannot be statically guaranteed to be
memory safe. This makes it simply not acceptable for D in the general
case. It works with iOS because iOS allows all kinds of (unsafe) ways
to escape it, and it must offer those ways because it is not performant.


So does D. That's why there is @safe, @trusted and @system. What is the unsafe
part of ARC anyway?


As I said, it is when it is bypassed for performance reasons.



Re: DIP60: @nogc attribute

2014-04-22 Thread John Colvin via Digitalmars-d

On Tuesday, 22 April 2014 at 09:02:21 UTC, Walter Bright wrote:

On 4/22/2014 12:11 AM, Jacob Carlborg wrote:

On 22/04/14 01:02, Walter Bright wrote:

The thing is, with iOS ARC, it cannot be statically 
guaranteed to be
memory safe. This makes it simply not acceptable for D in the 
general
case. It works with iOS because iOS allows all kinds of 
(unsafe) ways
to escape it, and it must offer those ways because it is not 
performant.


So does D. That's why there is @safe, @trusted and @system. 
What is the unsafe

part of ARC anyway?


As I said, it is when it is bypassed for performance reasons.


A system that is automatically safe but can be manually managed 
for extra performance. That sounds very D-ish.


Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d
On Tuesday, 22 April 2014 at 09:40:15 UTC, Ola Fosheim Grøstad 
wrote:

   if( CAS_SET_BIT(ref+32,THREADID)==THREADID ){


Make that:

 if( CAS_SET_BIT(ref+32,THREADID) == (1THREADID) ){


Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d

On Tuesday, 22 April 2014 at 09:01:20 UTC, Walter Bright wrote:
On 4/21/2014 11:51 PM, Ola Fosheim Grøstad 
ola.fosheim.grostad+dl...@gmail.com wrote:
This is actually quite efficient compared to the standard 
NSObject which uses a

hashtable for refcounting:


It's not efficient compared to pointers.


It isn't efficient compared to pointers if you use a blind ARC 
implementation. If you use ARC to track ownership of regions then 
it can be efficient.


The real culprit is multithreading, it can be resolved though. If 
you put the counters on cachelines that are local to the thread, 
either by offset or TLS.


E.g. pseudocode for 8 refcounted pointers on 4 threads with 32 
bytes cachelines could be something along the lines of:


struct {
   func* destructor[8]; // cacheline -1
   void* ptr[8]; //cacheline 0
   uint bitmask[8]; //cacheline 1
   int refcount[8*4] ; //cacheline2-6 initialized to -1
}

THREADOFFSET = (THREADID+2)*32

retain(ref){ //ref is a pointer to cacheline 0
 if ( increment(ref+THREADOFFSET) == 0) {
   if( CAS_SET_BIT(ref+32,THREADID)==THREADID ){
  HALT_DESTRUCTED()
   }
 }
}

release(ref){
  if( decrement(ref+THREADOFFSET)0 ){
if( CAS_CLR_BIT(ref+32,THREADID)==0){
   call_destructor(ref-32,*ref);
}
  }
}



Re: DIP60: @nogc attribute

2014-04-22 Thread Don via Digitalmars-d

On Thursday, 17 April 2014 at 19:51:38 UTC, Walter Bright wrote:

On 4/17/2014 10:41 AM, Dicebot wrote:
On Thursday, 17 April 2014 at 16:57:32 UTC, Walter Bright 
wrote:
With current limitations @nogc is only useful to verify that 
embedded code which
does not have GC at all does not use any GC-triggering 
language features before
it comes to weird linker errors / rt-asserts. But that does 
not work good either

because of next problem:


Remember that @nogc will be inferred for template functions. 
That means that
whether it is @nogc or not will depend on its arguments being 
@nogc, which is

just what is needed.


No, it looks like I have stated that very wrong because 
everyone understood it
in completely opposite way. What I mean is that `put()` is NOT 
@nogc and it
still should work. Same as weakly pure is kind of pure but 
allowed to mutate its
arguments, proposed weakly @nogc can only call GC via 
functions directly

accessible from its arguments.


I don't see value for this behavior.


It turns out to have enormous value. I will explain this in my 
DConf talk. A little preview:
Almost all of our code at Sociomantic obeys this behaviour, and 
it's probably the most striking feature of our codebase. By 
almost all I mean probably 90% of our code, including all of 
our libraries. Not just the 5% - 10% that could marked as @nogc 
according to your DIP.


The key property it ensures is, if you make N calls to the 
function, the number of GC allocations is in O(1). We don't care 
if makes 0 allocations or 17.


We're not really interested in whether a function uses the GC or 
not, since most interesting functions do need to do some memory 
allocation.


Ideally, we'd want an attribute which could applied to *all* of 
Phobos, except for some convenience functions. We have no 
interest in library code which doesn't behave in that way.




Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Mon, 21 Apr 2014 17:52:30 -0400, Ola Fosheim Grøstad  
ola.fosheim.grostad+dl...@gmail.com wrote:



Here are two very good reasons to avoid extensive ref-counting:

1. transactional memory ( you don't want a lock on two reads )

2. cache coherency ( you don't want barriers everywhere )

Betting everything on ref counting is the same as saying no to upcoming  
CPUs.


IMO that means ARC is DOA. It might be useful for some high level  
objects… but I don't understand why one would think that it is a good  
low level solution. It is a single-threaded solution.


Single threaded ARC can go a long way in D. We statically know whether  
data is shared or not.


-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Mon, 21 Apr 2014 19:02:53 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/21/2014 1:29 PM, Steven Schveighoffer wrote:

I think you are misunderstanding something. This is not for a pervasive
ARC-only, statically guaranteed system. The best example he gives (and  
I agree
with him) is iOS. Just look at the success of iOS, where the entire OS  
API is
based on ARC (actually RC, with an option for both ARC and manual, but  
the
latter is going away). If ARC was so bad, the iOS experience would  
show it.
You may have doubts, but I can assure you I can build very robust and  
performant

code with ARC in iOS.


The thing is, with iOS ARC, it cannot be statically guaranteed to be  
memory safe.


So?


This makes it simply not acceptable for D in the general case.


Because it can't live beside all the other unsafe code in D? I don't get  
it...


It works with iOS because iOS allows all kinds of (unsafe) ways to  
escape it, and it must offer those ways because it is not performant.


I think we're officially going in circles here.

Kinda sorta memory safe, mostly memory safe, etc., is not a static  
guarantee.


There is JUST NO WAY that:

 struct RefCount {
 T* data;
 int* count;
 }

is going to be near as performant as:

 T*


Again with the straw man!


1. A dereference requires two indirections. Cache performance, poof!

2. A copy requires two indirections to inc, two indirections to dec, and  
an exception unwind handler for dec.


3. Those two word structs add to memory consumption.


Consider the straw man destroyed :)

As you pointed out, performant code is going to have to cache the data*  
value. That cannot be guaranteed memory safe.



I can't reconcile agreeing that ARC isn't good enough to be pervasive  
with

compiler technology eliminates unnecessary ARC overhead.
It's pretty pervasive on iOS. ARC has been around since iOS 4.3 (circa  
2011).


Pervasive means for all pointers. This is not true of iOS. It's fine  
for iOS to do a half job of it, because the language makes no  
pretensions about memory safety. It is not fine for D to replace a  
guaranteed memory safe system with an unsafe,  
hope-your-programmers-get-it-right, solution.




Totally agree, which is why nobody is saying that.

-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d
On Tuesday, 22 April 2014 at 13:11:55 UTC, Steven Schveighoffer 
wrote:

Single threaded ARC can go a long way in D.


Not without changing language semantics/mechanisms?


We statically know  whether data is shared or not.


I don't understand how you can know this when you allow foreign 
function invocation.


Even thread local globals can leak into another thread by 
mistake, unnoticed? Meaning random crashes that are hard to debug?




Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Tue, 22 Apr 2014 09:29:28 -0400, Ola Fosheim Grøstad  
ola.fosheim.grostad+dl...@gmail.com wrote:



On Tuesday, 22 April 2014 at 13:11:55 UTC, Steven Schveighoffer wrote:

Single threaded ARC can go a long way in D.


Not without changing language semantics/mechanisms?


We statically know  whether data is shared or not.


I don't understand how you can know this when you allow foreign function  
invocation.


Can you explain this?

Even thread local globals can leak into another thread by mistake,  
unnoticed? Meaning random crashes that are hard to debug?


By mistake? How?

-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d
On Tuesday, 22 April 2014 at 13:39:54 UTC, Steven Schveighoffer 
wrote:
On Tue, 22 Apr 2014 09:29:28 -0400, Ola Fosheim Grøstad Can you 
explain this?


When you use a C/C++ framework you don't know what happens to the 
pointers you hand to it.


You also don't know which threads call your D-functons from that 
framework. (Assuming the framework is multi-threaded). To know 
this you are required to know the internals of the framework you 
are utilizing or inject runtime guards into your D functions?



By mistake? How?


By insertion into a global datastructure that happens at a lower 
layer than the higher level you allocate on.


Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Tue, 22 Apr 2014 09:48:28 -0400, Ola Fosheim Grøstad  
ola.fosheim.grostad+dl...@gmail.com wrote:



On Tuesday, 22 April 2014 at 13:39:54 UTC, Steven Schveighoffer wrote:
On Tue, 22 Apr 2014 09:29:28 -0400, Ola Fosheim Grøstad Can you explain  
this?


When you use a C/C++ framework you don't know what happens to the  
pointers you hand to it.


Those are typically well-documented, but yes, you rely on insider  
knowledge. You can mark C functions with the appropriate attributes so the  
D compiler can enforce this for you. I think we should make reference  
counting work, as long as you don't call mischievous library code. We take  
a similar approach to other safety aspects of D.


You also don't know which threads call your D-functons from that  
framework. (Assuming the framework is multi-threaded). To know this you  
are required to know the internals of the framework you are utilizing or  
inject runtime guards into your D functions?


Or just mark those objects sent into the framework as shared. Having  
multi-threaded RC isn't bad, just not as efficient.


One thing that would be nice is to allow moving a data pointer from one  
thread to another. In other words, as long as your data is contained, it  
can pass from one thread to another, and still be considered unshared.


I think sooner or later, we are going to have to figure that one out.




By mistake? How?


By insertion into a global datastructure that happens at a lower layer  
than the higher level you allocate on.


I think this is what you are talking about above, or is there something  
else?


-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d
On Tuesday, 22 April 2014 at 14:07:47 UTC, Steven Schveighoffer 
wrote:
know this you are required to know the internals of the 
framework you are utilizing or inject runtime guards into your 
D functions?


Or just mark those objects sent into the framework as shared. 
Having multi-threaded RC isn't bad, just not as efficient.


Actually, when I think of it, guards probably would be cheap. All 
you have to do is to store the thread-context-pointer-register 
into a global when the thread starts up. Then just do a simple 
if-test at the function invocation. (assuming the register 
doesn't change over time).


Actually, it could be done as a self-modifying pass at startup… 
That would make it a register test against an immediate value, no 
memory buss implications.


One thing that would be nice is to allow moving a data pointer 
from one thread to another. In other words, as long as your 
data is contained, it can pass from one thread to another, and 
still be considered unshared.


Yes, that sounds plausible.

I think this is what you are talking about above, or is there 
something else?


You are right :).

Ola.


Re: DIP60: @nogc attribute

2014-04-22 Thread Kapps via Digitalmars-d

On Tuesday, 22 April 2014 at 06:51:40 UTC, Ola Fosheim Grøstad
wrote:

On Monday, 21 April 2014 at 23:02:54 UTC, Walter Bright wrote:

There is JUST NO WAY that:

   struct RefCount {
   T* data;
   int* count;
   }



This is actually quite efficient compared to the standard 
NSObject which uses a hashtable for refcounting:


iOS now on 64-bit processors doesn't necessarily use a hashtable
for refcounting. Basically, only 33 bits of the 64-bit pointer
are used to actually refer to an address, then 19 of the
remaining bits are used to store an inline reference count. Only
if the inline reference count exceeds these 19 bits (very rare)
do they switch to using a hashtable. It was one of the large
benefits of switching to ARM64 for the iPhone 5.


Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d

On Tuesday, 22 April 2014 at 16:58:23 UTC, Kapps wrote:

iOS now on 64-bit processors doesn't necessarily use a hashtable
for refcounting. Basically, only 33 bits of the 64-bit pointer
are used to actually refer to an address, then 19 of the
remaining bits are used to store an inline reference count.


I am sure you are right, but how does that work? Do you have a 
link?


Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Tue, 22 Apr 2014 13:22:19 -0400, Ola Fosheim Grøstad  
ola.fosheim.grostad+dl...@gmail.com wrote:



On Tuesday, 22 April 2014 at 16:58:23 UTC, Kapps wrote:

iOS now on 64-bit processors doesn't necessarily use a hashtable
for refcounting. Basically, only 33 bits of the 64-bit pointer
are used to actually refer to an address, then 19 of the
remaining bits are used to store an inline reference count.


I am sure you are right, but how does that work? Do you have a link?


I think what he's saying is the 19 bits are an offset into the global ref  
count container. Some sentinel value means lookup the pointer in a  
hashtable.


-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread Kapps via Digitalmars-d

On Tuesday, 22 April 2014 at 17:22:21 UTC, Ola Fosheim Grøstad
wrote:

On Tuesday, 22 April 2014 at 16:58:23 UTC, Kapps wrote:
iOS now on 64-bit processors doesn't necessarily use a 
hashtable

for refcounting. Basically, only 33 bits of the 64-bit pointer
are used to actually refer to an address, then 19 of the
remaining bits are used to store an inline reference count.


I am sure you are right, but how does that work? Do you have a 
link?


https://www.mikeash.com/pyblog/friday-qa-2013-09-27-arm64-and-you.html
Ctrl +F Repurposed isa Pointer

Details about isa structure:
http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html


Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Tue, 22 Apr 2014 13:35:20 -0400, Steven Schveighoffer  
schvei...@yahoo.com wrote:


On Tue, 22 Apr 2014 13:22:19 -0400, Ola Fosheim Grøstad  
ola.fosheim.grostad+dl...@gmail.com wrote:



On Tuesday, 22 April 2014 at 16:58:23 UTC, Kapps wrote:

iOS now on 64-bit processors doesn't necessarily use a hashtable
for refcounting. Basically, only 33 bits of the 64-bit pointer
are used to actually refer to an address, then 19 of the
remaining bits are used to store an inline reference count.


I am sure you are right, but how does that work? Do you have a link?


I think what he's saying is the 19 bits are an offset into the global  
ref count container. Some sentinel value means lookup the pointer in a  
hashtable.


Sorry, I was wrong. And so was Kapps, according to the article he  
referenced.


The 33 bits of the 64 bit pointer are used to point at a *class*, via the  
object's isa member. The other 19 bits can be used for ref counting. I  
mistakenly thought he meant the pointer to the object.


This is kind of weird though. Why do it this way? If there is such an  
advantage to having the ref count inside the object (and I don't disagree  
with that), why didn't they do that before? Surely adding another 32-bit  
field wouldn't have killed the runtime.


Even doing it the way they have seems unnecessarily complex, given that  
iOS 64-bit was brand new.


-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d

On Tuesday, 22 April 2014 at 17:39:53 UTC, Kapps wrote:

https://www.mikeash.com/pyblog/friday-qa-2013-09-27-arm64-and-you.html
Ctrl +F Repurposed isa Pointer


Ah, ok, the refcount is embedded in the class-table pointer.


Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d
On Tuesday, 22 April 2014 at 17:52:28 UTC, Steven Schveighoffer 
wrote:
Even doing it the way they have seems unnecessarily complex, 
given that iOS 64-bit was brand new.


I dislike this too… The only reason I can think of is that Apple 
themselves have code for OS-X that is optimized 64 bit code and 
that will break if they add another field? The lower bit is used 
for compatibility mode. Hmm…


Re: DIP60: @nogc attribute

2014-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2014 6:18 AM, Steven Schveighoffer wrote:

On Mon, 21 Apr 2014 19:02:53 -0400, Walter Bright newshou...@digitalmars.com
wrote:

The thing is, with iOS ARC, it cannot be statically guaranteed to be memory 
safe.


So?


If you see no value in static guarantees of memory safety, then what can I say?



Re: DIP60: @nogc attribute

2014-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2014 2:20 AM, John Colvin wrote:

A system that is automatically safe but can be manually managed for extra
performance. That sounds very D-ish.


Needing to write @system code with a GC to get performance is rare in D. It's 
normal in O-C, as has been pointed out here a couple times.


Re: DIP60: @nogc attribute

2014-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2014 6:18 AM, Steven Schveighoffer wrote:

Again with the straw man!


If you really believe you can make a performant ARC system, and have it be 
memory safe, feel free to write a complete proposal on it.


Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Tue, 22 Apr 2014 14:12:17 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/22/2014 6:18 AM, Steven Schveighoffer wrote:
On Mon, 21 Apr 2014 19:02:53 -0400, Walter Bright  
newshou...@digitalmars.com

wrote:
The thing is, with iOS ARC, it cannot be statically guaranteed to be  
memory safe.


So?


If you see no value in static guarantees of memory safety, then what can  
I say?


Seriously, the straw man arguments have to stop.

There is plenty of valuable D code that is not guaranteed memory safe. For  
example, druntime.


ARC does not equal guaranteed memory safety. So NO, it cannot replace the  
GC for D @safe code. That doesn't make it useless.


-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Tue, 22 Apr 2014 14:15:35 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/22/2014 6:18 AM, Steven Schveighoffer wrote:

Again with the straw man!


If you really believe you can make a performant ARC system, and have it  
be memory safe, feel free to write a complete proposal on it.


I hope you can understand that from this discussion, I'm not to motivated  
to devote time on it. Not that I could do it anyway :)


Generally, when investing a lot of time and energy into something, you  
want to make sure the market is there first...


-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d
On Tuesday, 22 April 2014 at 18:38:28 UTC, Steven Schveighoffer 
wrote:
I hope you can understand that from this discussion, I'm not to 
motivated to devote time on it. Not that I could do it anyway :)


Do it anyway.

This is such a fun topic and many would be entertained by the 
ensuing excruciating inquisitorial process.


Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Tue, 22 Apr 2014 14:43:04 -0400, Ola Fosheim Grøstad  
ola.fosheim.grostad+dl...@gmail.com wrote:



On Tuesday, 22 April 2014 at 18:38:28 UTC, Steven Schveighoffer wrote:
I hope you can understand that from this discussion, I'm not to  
motivated to devote time on it. Not that I could do it anyway :)


Do it anyway.


I mean not like I can't because I don't want to or don't have time, but  
can't as in I lack the skill set :) It's interesting to debate, and I get  
the concepts, but I am not a CPU/cache guy, and these things are really  
important to get right for performance, since ref counting would be used  
frequently.


-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread Michel Fortin via Digitalmars-d
On 2014-04-22 17:52:27 +, Steven Schveighoffer 
schvei...@yahoo.com said:



Even doing it the way they have seems unnecessarily complex, given that
iOS 64-bit was brand new.


Perhaps it's faster that way due to some caching effect. Or perhaps 
it's to be able to have static constant string objects in the readonly 
segments.


Apple could always change their mind and add another field for the 
reference count. The Modern runtime has non-fragile classes, so you can 
change the base class layout breaking ABI compatibility.


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: DIP60: @nogc attribute

2014-04-22 Thread via Digitalmars-d
On Tuesday, 22 April 2014 at 18:48:04 UTC, Steven Schveighoffer 
wrote:
I mean not like I can't because I don't want to or don't have 
time, but can't as in I lack the skill set :) It's interesting 
to debate, and I get the concepts, but I am not a CPU/cache 
guy, and these things are really important to get right for 
performance, since ref counting would be used frequently.


I think RC performance unfortunately is very hardware dependent. 
So, it involves testing, benchmarking etc… Still, I think these 
discussions are good because they are opportunities to look at 
what others do (like Objective-C) which is educational (at least 
for me).


The trouble I have with ref counting is that the future of HW is 
uncertain, but that can be held against GC too. Take for instance 
Phi with 80 cores and a crossbar interconnects (?), how does that 
affect memory management? Unfortunately I have no personal 
experience with Phi so my take on it is rather vague…


But if ARC takes a long time to get right I think one should 
consider effects of upcoming HW when considering for/against. 
Maybe Go's CSP model is better for Phi. Maybe not.  I don't know, 
but I think it is an interesting topic,  because 4-8 cores is not 
going to be enough in the next decade. I think…


Re: DIP60: @nogc attribute

2014-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2014 11:28 AM, Steven Schveighoffer wrote:

On Tue, 22 Apr 2014 14:12:17 -0400, Walter Bright newshou...@digitalmars.com
wrote:


On 4/22/2014 6:18 AM, Steven Schveighoffer wrote:

On Mon, 21 Apr 2014 19:02:53 -0400, Walter Bright newshou...@digitalmars.com
wrote:

The thing is, with iOS ARC, it cannot be statically guaranteed to be memory
safe.


So?


If you see no value in static guarantees of memory safety, then what can I say?


Seriously, the straw man arguments have to stop.

There is plenty of valuable D code that is not guaranteed memory safe.


Memory safety is not a strawman. It's a critical feature for a modern language, 
and will become ever more important.



 For example, druntime.

Nobody expects a GC's guts to be guaranteed memory safe. But they do expect the 
interface to it to be memory safe, and using GC allocated data to be memory 
safe, and being able to write performant memory safe code.


And by memory safe, I don't mean hand verified. I mean machine verified.


Re: DIP60: @nogc attribute

2014-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2014 11:38 AM, Steven Schveighoffer wrote:

Generally, when investing a lot of time and energy into something, you want to
make sure the market is there first...


Ironic, considering that nobody but me believed there was a market for D before 
it existed :-)


I do believe there is a market for ARC in D. What I don't believe are the 
various claims about how insignificant its costs are, and I'm not so willing to 
give up on memory safety.




Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Tue, 22 Apr 2014 15:02:05 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/22/2014 11:28 AM, Steven Schveighoffer wrote:
On Tue, 22 Apr 2014 14:12:17 -0400, Walter Bright  
newshou...@digitalmars.com

wrote:


On 4/22/2014 6:18 AM, Steven Schveighoffer wrote:
On Mon, 21 Apr 2014 19:02:53 -0400, Walter Bright  
newshou...@digitalmars.com

wrote:
The thing is, with iOS ARC, it cannot be statically guaranteed to be  
memory

safe.


So?


If you see no value in static guarantees of memory safety, then what  
can I say?


Seriously, the straw man arguments have to stop.

There is plenty of valuable D code that is not guaranteed memory safe.


Memory safety is not a strawman. It's a critical feature for a modern  
language, and will become ever more important.


No, a straw man argument is when you imply that I am arguing from a  
position that is similar to my actual position, but obviously flawed. Then  
proceed to attack the straw man.


Example:

A: Sunny days are good.
B: If all days were sunny, we'd never have rain, and without rain,  
we'd have famine and death.


At no time did I ever say I see no value in static guarantees of memory  
safety. But I also see value in ref counting for performance and memory  
purposes in NON memory-safe code.


-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread Steven Schveighoffer via Digitalmars-d
On Tue, 22 Apr 2014 15:10:31 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/22/2014 11:38 AM, Steven Schveighoffer wrote:
Generally, when investing a lot of time and energy into something, you  
want to

make sure the market is there first...


Ironic, considering that nobody but me believed there was a market for D  
before it existed :-)


Sure but I'm not prepared to generate a new language over this. If you  
won't accept it, there's no point in making it.


In other words, YOU are the market ;)

*disclaimer* I am in no shape to actually make such a proposal/change, and  
probably it would come out horribly if I tried, implementation-wise. I  
simply am trying to convince you that it would be a valuable addition to D  
so others may see an opportunity there.


I do believe there is a market for ARC in D. What I don't believe are  
the various claims about how insignificant its costs are, and I'm not so  
willing to give up on memory safety.


You don't have to. Just make ARC not @safe.

-Steve


Re: DIP60: @nogc attribute

2014-04-22 Thread Michel Fortin via Digitalmars-d

On 2014-04-22 19:02:05 +, Walter Bright newshou...@digitalmars.com said:

Memory safety is not a strawman. It's a critical feature for a modern 
language, and will become ever more important.


What you don't seem to get is that ARC, by itself, is memory-safe.

Objective-C isn't memory safe because it lets you play with raw 
pointers too. If you limit yourself to ARC-managed pointers (and avoid 
undefined behaviours inherited from C) everything is perfectly memory 
safe.


I'm pretty confident that had I continued my work on D/Objective-C we'd 
now be able to interact with Objective-C objects using ARC in @safe 
code. I was planning for that. Objective-C actually isn't very far from 
memory safety now that it has ARC, it just lacks the @safe attribute to 
enable compiler verification.


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: DIP60: @nogc attribute

2014-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2014 12:42 PM, Michel Fortin wrote:

On 2014-04-22 19:02:05 +, Walter Bright newshou...@digitalmars.com said:


Memory safety is not a strawman. It's a critical feature for a modern
language, and will become ever more important.


What you don't seem to get is that ARC, by itself, is memory-safe.


I repeatedly said that it is not memory safe because you must employ escapes 
from it to get performance.




Objective-C isn't memory safe because it lets you play with raw pointers too. If
you limit yourself to ARC-managed pointers (and avoid undefined behaviours
inherited from C) everything is perfectly memory safe.


Allow me to make it clear that IF you never convert an ARC reference to a raw 
pointer in userland, I agree that it is memory safe. But this is not practical 
for high performance code.




I'm pretty confident that had I continued my work on D/Objective-C we'd now be
able to interact with Objective-C objects using ARC in @safe code. I was
planning for that. Objective-C actually isn't very far from memory safety now
that it has ARC, it just lacks the @safe attribute to enable compiler 
verification.


I wish you would continue that work!



Re: DIP60: @nogc attribute

2014-04-22 Thread Walter Bright via Digitalmars-d

On 4/22/2014 4:00 AM, Don wrote:

It turns out to have enormous value. I will explain this in my DConf talk. A
little preview:
Almost all of our code at Sociomantic obeys this behaviour, and it's probably
the most striking feature of our codebase. By almost all I mean probably 90%
of our code, including all of our libraries. Not just the 5% - 10% that could
marked as @nogc according to your DIP.

The key property it ensures is, if you make N calls to the function, the number
of GC allocations is in O(1). We don't care if makes 0 allocations or 17.


I don't really understand how dicebot's proposal ensures this property. I guess 
it'll have to wait until Dconf!



We're not really interested in whether a function uses the GC or not, since most
interesting functions do need to do some memory allocation.

Ideally, we'd want an attribute which could applied to *all* of Phobos, except
for some convenience functions. We have no interest in library code which
doesn't behave in that way.





Re: DIP60: @nogc attribute

2014-04-21 Thread bearophile via Digitalmars-d

Timon Gehr:

In which case? In case some version of LDC2 is able to avoid 
the heap allocation using full optimizations? :o)


Please take a look, I have just added one more note in the 
optimizations section:


http://wiki.dlang.org/DIP60#Behaviour_in_presence_of_optimizations

Bye,
bearophile


Re: DIP60: @nogc attribute

2014-04-21 Thread Steven Schveighoffer via Digitalmars-d
On Fri, 18 Apr 2014 20:17:59 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/18/2014 5:30 AM, Steven Schveighoffer wrote:
Absolutely not, the compiler knows whether the count needs to be  
incremented, I

don't need to know.


But there are manual escapes from it, meaning you need to know to use  
them:


unsigned char *vdata = data.data;
// process vdata

I am skeptical that the O-C compiler is sufficiently smart to make ARC  
on all pointers practical. That snippet pretty much proves it.


I finally understand what you are saying.

Yes, when my code devolves into C-land, I have non-ARC pointers. This  
means I cannot store these pointers somewhere if I don't keep a pointer to  
the object that owns them. This is indeed manual memory management.


But, and this is a big but, I DON'T have to care about memory management  
as long as I only store pointers to objects, aside from the stack. Objects  
themselves can store non-ARC pointers and manage them privately, but not  
allow arbitrary setting/getting of pointers. This is not very common.


A great example of where I use arbitrary non-GC pointers, is an object  
that stores a network packet.


unix sockets work just fine in networking and iOS, so I do all of my  
networking with socket, send, recv, etc.


These functions take unmanaged char * pointers.

So an object that stores a single packet does this:

1. read the packet header into a structure overlay. Figure out the length  
(this is a TCP packet).

2. malloc a char array with the proper length, read in the packet.
3. verify the packet is correct, if not, free the buffer.
4. If it's correct, digest the packet (storing fields from the packet data  
itself, byteswap, etc.). Then store the data into an NSData object, giving  
it ownership of the buffer.


All this happens within a factory method. I never directly store the char  
* array inside the object or elsewhere, it gets wrapped into an NSData  
object, which will then free the data once the object is destroyed.


You must be conscious about memory management, because after all,  
Objective-C *is* C, and you are allowed to do stupid things just like in  
C. But you CAN have a certain set of rules, and as long as you follow  
those rules, you will not have to deal with memory management.



Total replacement of GC with ARC in D will:


This is the wrong straw-man, I'm not advocating for this at all.


1. Be a massive change that will break most every D program
2. Require people to use unsafe escapes to recover lost performance
3. Require multiple pointer types


This isn't what I had in mind anyway. I envisioned an ARC system like  
Objective-C, where the type pointed at defines whether it's ARC or GC.


For instance, GC would be *required* for array appending in D, because  
arrays cannot be ARC-managed. You would need a wrapper type for ARC, with  
it's own semantics.



4. Will not be memory safe (see (2))
5. Require the invention of optimization technology that doesn't exist


Besides being a tautology, what does this mean?

6. Become more or less ABI incompatible with C without a long list of  
caveats and translations


Again, this is based on your straw-man which I don't advocate for. The  
change I had in mind was much less invasive.


A much more tractable idea is to implement something like C++'s  
shared_ptr as a library type, with usage strategies paralleling C++'s  
(and yes, use of shared_ptr would be unsafe).


shared_ptr would work (and I've used that extensively too, it's awesome  
for C++), but I feel it's a much less effective solution than a  
compiler-augmented system that can optimize away needless  
increment/decrements.


Note that shared_ptr would never be able to handle D's slice appending  
either.


-Steve


Re: DIP60: @nogc attribute

2014-04-21 Thread Jacob Carlborg via Digitalmars-d

On Sunday, 20 April 2014 at 14:38:47 UTC, Frustrated wrote:


How bout this!

Why not allow one to define their own attributes from a 
generalized subset and then define a few standard ones like 
@nogc.


Sounds like you want AST macros. Have a look at this 
http://wiki.dlang.org/DIP50#Declaration_macros


--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-21 Thread Walter Bright via Digitalmars-d

On 4/21/2014 5:00 AM, Steven Schveighoffer wrote:

Total replacement of GC with ARC in D will:

This is the wrong straw-man, I'm not advocating for this at all.


Many are when they advocate ARC for D.



4. Will not be memory safe (see (2))
5. Require the invention of optimization technology that doesn't exist


Besides being a tautology, what does this mean?


4. There is no language protection against misusing ARC, hence it cannot be 
mechanically verified to be memory safe.
5. Numerous posters here have posited that the overhead of ARC can be eliminated 
with a sufficiently smart compiler (which does not exist).




Note that shared_ptr would never be able to handle D's slice appending either.


I know. shared_ptr would, of course, be used at the specific discretion of the 
programmer. It would not be under the hood, and it would not be memory safe.




Re: DIP60: @nogc attribute

2014-04-21 Thread Frustrated via Digitalmars-d

On Monday, 21 April 2014 at 16:45:15 UTC, Jacob Carlborg wrote:

On Sunday, 20 April 2014 at 14:38:47 UTC, Frustrated wrote:


How bout this!

Why not allow one to define their own attributes from a 
generalized subset and then define a few standard ones like 
@nogc.


Sounds like you want AST macros. Have a look at this 
http://wiki.dlang.org/DIP50#Declaration_macros


--
/Jacob Carlborg


Not quite. AST macros simply transform code. Attributes attach 
meta data to code. While I'm sure there is some overlap they are 
not the same.


Unless AST macros have the ability to arbitrary add additional 
contextual information to meta code then they can't emulate 
attributes.


E.g., Suppose you have D with AST macros but not attributes, how 
can you add them?


In the dip, you have

macro attr (Context context, Declaration decl)
{
auto attrName = decl.name;
auto type = decl.type;

return [
private $decl.type _$decl.name;

$decl.type $decl.name ()
{
return _$decl.name;
}

$decl.type $decl.name ($decl.type value)
{
return _$decl.name = value;
}
];
}

class Foo
{
@attr int bar;
}

but attr is not an attribute. It is an macro. @attr converts the 
int bar field into a private setter and getter. This has 
nothing to do with attributes.


(just cause you use the attr word and the @ symbol doesn't make 
it an attribute)



I don't see how you could ever add attributes to D using AST 
macros above unless the definition of an AST macro is modified. 
[Again, assuming D didn't have attributes in the first place]


This does not mean that AST macros could not be used to help 
define the generalized attributes though.



What I am talking about is instead of hard coding attributes in 
the compiler, one abstracts and generalizes the code so that any 
attribute could be added in the future with minimal work.


It would simply require one to add the built in attributes list, 
add the attribute grammar(which is used to reduce compound 
attributes), add any actions that happen when the attribute is 
used in code.


e.g.,

builtin_attributes = {

{pureness, pure, !pure/impure,
attr = any(attr, impure) = impure
attr = all(attr, pure) = pure
}

{gc, gc, !gc/nogc,
attr = any(attr, gc) = gc
attr = all(attr, nogc) = nogc
}
etc... }

notices that pureness and gc have the same grammatical rules. 
Code would be added to handle the pureness and gc attributes when 
they are come across for optimization purposes.


The above syntax is just made up and pretty bad but hopefully not 
too difficult to get the bigger picture.


Every new built in attribute would just have to be added to the 
list above(easy) and code that uses it for whatever purpose would 
be added in the code where it belongs.


User define attributes essentially would make the attributes list 
above dynamic allowing the user to add to it. The compiler would 
only be told how to simplify the attributes using the grammar and 
would do so but would not have any code inserted because there is 
no way for the user to hook into the compiler properly(I suppose 
it could be done if the compiler was written in an oop like way).


In any case, because the compiler knows how to simplify UDA's by 
using the provided grammar it makes UDA's much more powerful. CT 
reflection and AST macros would make them way more powerful. The 
ability to add hooks into the compiler would nearly give the user 
the same power as the compiler writer. Of course, this would 
probably lead to all kinds of compatibility problems in user code.


Basically, as of now, all we can do is define UDA's, we can't 
define how they relate to each other(the grammar) nor what 
happens when the exist(the behavior). There should not be any 
real difference between UDA's and built in attributes(except 
hooking, only because of complexity issues) and having a 
generalized attribute system in the compiler would go a long way 
to bridging the gap.


The main thing to take away from this is that *if* D had such an 
attribute system, the gc/nogc issue would be virtually 
non-existent. It would only take a few minutes to add a UDA 
@gc/@nogc to D in user code. At least a few people would have 
done it, and it's merits could be seen. Then it would be only a 
matter of copy and pasting the definition of the attribute to 
the compiler code and it would then become a built in making it 
available for everyone.


At some point optimizations in the compiler could potentially be 
added... just for fun. Not really the point of the attribute but 
having it does provide such possibilities.


Also, with such a system, attributes can propagate from the 
bottom up and inference makes it a lot easier.


E.g., atomic statements could be marked with attributes. Blocks 
of statements can be marked but also inherit from the statements 
and blocks they use.


With such a system, one could mark 

Re: DIP60: @nogc attribute

2014-04-21 Thread Steven Schveighoffer via Digitalmars-d
On Mon, 21 Apr 2014 13:28:24 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/21/2014 5:00 AM, Steven Schveighoffer wrote:

Total replacement of GC with ARC in D will:

This is the wrong straw-man, I'm not advocating for this at all.


Many are when they advocate ARC for D.


Does that preclude you from accepting any kind of ARC for D?

5. Numerous posters here have posited that the overhead of ARC can be  
eliminated with a sufficiently smart compiler (which does not exist).


You continue to speak in extremes. People are saying that the compiler can  
eliminate most of the needless ARC increments and decrements, not all of  
them. Compilers that do this do exist.


Note that shared_ptr would never be able to handle D's slice appending  
either.


I know. shared_ptr would, of course, be used at the specific discretion  
of the programmer. It would not be under the hood, and it would not be  
memory safe.


Doesn't RefCounted do this already?

-Steve


Re: DIP60: @nogc attribute

2014-04-21 Thread Walter Bright via Digitalmars-d

On 4/21/2014 10:57 AM, Steven Schveighoffer wrote:

On Mon, 21 Apr 2014 13:28:24 -0400, Walter Bright newshou...@digitalmars.com
wrote:


On 4/21/2014 5:00 AM, Steven Schveighoffer wrote:

Total replacement of GC with ARC in D will:

This is the wrong straw-man, I'm not advocating for this at all.


Many are when they advocate ARC for D.


Does that preclude you from accepting any kind of ARC for D?


No. My objection is to pervasive ARC, i.e. all gc is replaced with ARC, and it 
all magically works.




5. Numerous posters here have posited that the overhead of ARC can be
eliminated with a sufficiently smart compiler (which does not exist).


You continue to speak in extremes. People are saying that the compiler can
eliminate most of the needless ARC increments and decrements, not all of them.


Manu, for example, suggests it is good enough to make the overhead 
insignificant. I'm skeptical.




Compilers that do this do exist.


I can't reconcile agreeing that ARC isn't good enough to be pervasive with 
compiler technology eliminates unnecessary ARC overhead.




I know. shared_ptr would, of course, be used at the specific discretion of the
programmer. It would not be under the hood, and it would not be memory safe.


Doesn't RefCounted do this already?


Yes, but I haven't really looked into RefCounted.



Re: DIP60: @nogc attribute

2014-04-21 Thread Marco Leise via Digitalmars-d
Am Sun, 20 Apr 2014 08:19:45 +
schrieb monarch_dodra monarchdo...@gmail.com:

 D static initialization doesn't work the same way. Everything is 
 initialized as the program is loaded, […]

Ah ok, it's all good then :)

 Also, just doing this is good enough:
 
 //
 void foo() @nogc
 {
 static err = new Error(badthing happened);
 if (badthing)
 throw err;
 }
 //
 
 It does require the message be known before hand, and not custom 
 built. But then again, where were you going to allocate the 
 message, and if allocated, who would clean it up?
 
 
 
 That said, while the approach works, there could be issues with 
 re-entrance, or chaining exceptions.

Yes, we've discussed the issues with that approach in other
threads. At least this allows exceptions to be used at all.

-- 
Marco



Re: DIP60: @nogc attribute

2014-04-21 Thread Steven Schveighoffer via Digitalmars-d
On Mon, 21 Apr 2014 15:03:18 -0400, Walter Bright  
newshou...@digitalmars.com wrote:



On 4/21/2014 10:57 AM, Steven Schveighoffer wrote:
On Mon, 21 Apr 2014 13:28:24 -0400, Walter Bright  
newshou...@digitalmars.com

wrote:


On 4/21/2014 5:00 AM, Steven Schveighoffer wrote:

Total replacement of GC with ARC in D will:

This is the wrong straw-man, I'm not advocating for this at all.


Many are when they advocate ARC for D.


Does that preclude you from accepting any kind of ARC for D?


No. My objection is to pervasive ARC, i.e. all gc is replaced with ARC,  
and it all magically works.


With slicing, I don't think it's possible. Looking up the owner of a block  
for an INTERNAL pointer costs O(lg(n)), where n is all of your memory,  
because you must find out what block the pointer is accessing. Doing this  
during mark and sweep is bad enough, doing it for every ref count add or  
remove would be ghastly.


ARC, and ref counting in general, is MUCH better implemented as having a  
reference count inside the object referenced. This means the type MUST BE  
AWARE of ref counting, or be wrapped in an aware type.


Slices couldn't possibly do this correctly, since they do not point at the  
general block where all the info is maintained, but just at some memory.  
An ARC-aware slice would be fatter, or less performant.



5. Numerous posters here have posited that the overhead of ARC can be
eliminated with a sufficiently smart compiler (which does not exist).


You continue to speak in extremes. People are saying that the compiler  
can
eliminate most of the needless ARC increments and decrements, not all  
of them.


Manu, for example, suggests it is good enough to make the overhead  
insignificant. I'm skeptical.


I think you are misunderstanding something. This is not for a pervasive  
ARC-only, statically guaranteed system. The best example he gives (and I  
agree with him) is iOS. Just look at the success of iOS, where the entire  
OS API is based on ARC (actually RC, with an option for both ARC and  
manual, but the latter is going away). If ARC was so bad, the iOS  
experience would show it. You may have doubts, but I can assure you I can  
build very robust and performant code with ARC in iOS.


Let us consider that the single most difficult thing with memory  
management is giving away a piece of memory you created, never to see  
again, either via pushing into something, or returning it. The code that  
is responsible for creating that memory is not the code that is  
responsible for reclaiming it. This means you need an agreement between  
your code and the code that's accepting it, as to what the recipient needs  
to do once he's done. The giving away piece is easy, it's the when am I  
done with this? that makes it difficult. If it's going to one place,  
that's pretty simple, but if it's going to multiple places, that's where  
it becomes a headache. Basically, as long as someone is looking at this,  
it needs to exist, and you don't know who else is looking!


In that respect, both ARC and GC handle the job admirably. But it so  
happens that some of the load that GC happens to require (more memory;  
infrequent but lagging pauses) is not conducive to the environments Manu  
is targeting (embedded games). The tradeoffs are not a complete win for  
ARC, and I don't think D should switch to ARC (I think it's impossible  
anyway), but providing a builtin compiler-assisted mechanism to use ARC  
would allow a style of coding that would complement D's existing tools.  
Consider that with D's version of pure, I can easily do functional and  
imperative programming, even mixing the two, without even thinking about  
it! I'd like to see something with ARC that makes it easy to intermix with  
GC, and replace some of the Object management in D. It can never be a  
fully generic solution, except by object wrapping, because the type needs  
to be aware of the RC.


Other memory management tasks are simple. For example, owned arrays  
encapsulated inside an object, or temporary buffer space that you free  
before exiting a function. Those don't need complex memory management  
tools to make safe or effective. These have *defined lifetimes*.



Compilers that do this do exist.


I can't reconcile agreeing that ARC isn't good enough to be pervasive  
with compiler technology eliminates unnecessary ARC overhead.


It's pretty pervasive on iOS. ARC has been around since iOS 4.3 (circa  
2011).


It's pretty difficult to use manual RC and beat ARC. In fact in some  
cases, ARC can beat manual, because the compiler has more insight and  
knowledge of the rules being followed.


-Steve


Re: DIP60: @nogc attribute

2014-04-21 Thread via Digitalmars-d
On Monday, 21 April 2014 at 20:29:46 UTC, Steven Schveighoffer 
wrote:
example he gives (and I agree with him) is iOS. Just look at 
the success of iOS, where the entire OS API is based on ARC 
(actually RC, with an option for both ARC and manual, but the 
latter is going away). If ARC was so bad, the iOS experience 
would show it. You may have doubts, but I can assure you I can 
build very robust and performant code with ARC in iOS.


I am sure you are right about the last part, but the entire iOS 
API is not based on ARC.


You only use Objective-C to obtain contexts and configure them. 
After that you do everything performance sensitive in pure C. 
That goes for everything from Quartz (which is C, not 
Objective-C), OpenGL (C, not Objective-C) to AudioUnits (C, not 
Objective-C).


What is true is that you have bridges between manual ref counting 
where it exists in Core Foundation and Foundation, but just 
because you have a counter does not mean that you use it. ;-)


It's pretty pervasive on iOS. ARC has been around since iOS 4.3 
(circa 2011).


Not if you are doing systems level programming. You are talking 
about application level programming and on that level it is 
pervasive, but iOS apps have advanced rendering-engines to rely 
on for audio/video.


Re: DIP60: @nogc attribute

2014-04-21 Thread via Digitalmars-d
On Monday, 21 April 2014 at 20:29:46 UTC, Steven Schveighoffer 
wrote:
It's pretty difficult to use manual RC and beat ARC. In fact in 
some cases, ARC can beat manual, because the compiler has more 
insight and knowledge of the rules being followed.


Are you sure? Have you tried to do it first with 
CFRelease/CFRetain, then with ARC?


I believe this is the real reason (but I could be wrong):

«You can’t implement custom retain or release methods.»

from

https://developer.apple.com/library/mac/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html


Re: DIP60: @nogc attribute

2014-04-21 Thread via Digitalmars-d

Here are two very good reasons to avoid extensive ref-counting:

1. transactional memory ( you don't want a lock on two reads )

2. cache coherency ( you don't want barriers everywhere )

Betting everything on ref counting is the same as saying no to 
upcoming CPUs.


IMO that means ARC is DOA. It might be useful for some high level 
objects… but I don't understand why one would think that it is a 
good low level solution. It is a single-threaded solution.


Re: DIP60: @nogc attribute

2014-04-21 Thread Dicebot via Digitalmars-d

On Sunday, 20 April 2014 at 18:48:49 UTC, John Colvin wrote:
The way I understood your idea, was that a template could be 
marked @nogc, and yet still allow template arguments that 
themselves may gc.


This can be accomplished by creating a unit test that passes 
non-allocating template parameters, and then verifying the 
instantiation is @nogc.


The only way that works is if the unittest has coverage of all 
possible currently non-GC-using instantiations of all templates 
all the way down the call-tree.*


Imagine the case where some function deep down the call-tree 
has a `static if(T == NastyType) doGCStuff();`.


In order to protect against this, you have to check the 
internals of the entire call-tree in order to write the 
required unittest, and verify manually that you haven't missed 
a case every time anything changes.


*alright, technically only those that can be instantiated by 
the function your testing, but this still blows up pretty fast.


Looks like John has similar thinking pattern for this specific 
case :P


Also you proposal does not add any hygiene checks to non-template 
functions _and_ requires to create a boilerplate output range 
mocks (for all possible duck types) and extra static asserts for 
all functions that you may want to mark as weak @nogc. I don't 
see it as clean solution that can actually be used in a library.


The very marketing value of @nogc is not to show that something 
like it is possible (it already is) but to show hey, look how 
easy and clean it is!


Re: DIP60: @nogc attribute

2014-04-21 Thread Walter Bright via Digitalmars-d

On 4/21/2014 1:29 PM, Steven Schveighoffer wrote:

I think you are misunderstanding something. This is not for a pervasive
ARC-only, statically guaranteed system. The best example he gives (and I agree
with him) is iOS. Just look at the success of iOS, where the entire OS API is
based on ARC (actually RC, with an option for both ARC and manual, but the
latter is going away). If ARC was so bad, the iOS experience would show it.
You may have doubts, but I can assure you I can build very robust and performant
code with ARC in iOS.


The thing is, with iOS ARC, it cannot be statically guaranteed to be memory 
safe. This makes it simply not acceptable for D in the general case. It works 
with iOS because iOS allows all kinds of (unsafe) ways to escape it, and it must 
offer those ways because it is not performant.


Kinda sorta memory safe, mostly memory safe, etc., is not a static guarantee.

There is JUST NO WAY that:

struct RefCount {
T* data;
int* count;
}

is going to be near as performant as:

T*

1. A dereference requires two indirections. Cache performance, poof!

2. A copy requires two indirections to inc, two indirections to dec, and an 
exception unwind handler for dec.


3. Those two word structs add to memory consumption.

As you pointed out, performant code is going to have to cache the data* value. 
That cannot be guaranteed memory safe.




I can't reconcile agreeing that ARC isn't good enough to be pervasive with
compiler technology eliminates unnecessary ARC overhead.

It's pretty pervasive on iOS. ARC has been around since iOS 4.3 (circa 2011).


Pervasive means for all pointers. This is not true of iOS. It's fine for iOS 
to do a half job of it, because the language makes no pretensions about memory 
safety. It is not fine for D to replace a guaranteed memory safe system with an 
unsafe, hope-your-programmers-get-it-right, solution.




Re: DIP60: @nogc attribute

2014-04-20 Thread monarch_dodra via Digitalmars-d

On Saturday, 19 April 2014 at 23:44:45 UTC, Marco Leise wrote:

Am Wed, 16 Apr 2014 20:32:20 +
schrieb Peter Alexander peter.alexander...@gmail.com:


On Wednesday, 16 April 2014 at 20:29:17 UTC, bearophile wrote:
 Peter Alexander:

 (I assume that nothrow isn't meant to be there?)

 In D nothrow functions can throw errors.

Of course, ignore me :-)


 You could do something like this:

 void foo() @nogc
 {
static err = new Error();
if (badthing)
{
err.setError(badthing happened);
throw err;
}
 }

 To be mutable err also needs to be __gshared.

But then it isn't thread safe. Two threads trying to set and 
throw the same Error is a recipe for disaster.


Also: As far as I remember from disassembling C++, static
variables in functions are initialized on first access and
guarded by a bool. The first call to foo() would execute
err = new Error(); in that case. This code should not
compile under @nogc.


D static initialization doesn't work the same way. Everything is 
initialized as the program is loaded, and everything must have a 
statically known value. EG: An Error is allocated *somewhere* 
(may or may not actually be the GC), and then the static value of 
the Error is a pointer to that.


It's what allows us to do things like:

class A{}

struct S
{
A a = new A();
}

This is legal. All S.a will point the *same* A. S.init will be 
initialized to point to that a.


Also, just doing this is good enough:

//
void foo() @nogc
{
   static err = new Error(badthing happened);
   if (badthing)
   throw err;
}
//

It does require the message be known before hand, and not custom 
built. But then again, where were you going to allocate the 
message, and if allocated, who would clean it up?




That said, while the approach works, there could be issues with 
re-entrance, or chaining exceptions.


Re: DIP60: @nogc attribute

2014-04-20 Thread Jacob Carlborg via Digitalmars-d

On 2014-04-19 15:40, monarch_dodra wrote:


Nonsense. It still works 99% of the time (I think only a subset of 100
letters in all of Unicode are affect, and even then, another 100 of them
*shrink* on toUpper). It is really useful. It avoids *needles*
allocations. Removing it would be more harmful than useful.


I'm implicitly referring to toLowerInPlace as well.


I'm pretty confident that most of the time it is used, people don't care
*that* much that *absolutely* no allocation takes place. They just don't
want to be wasteful.


It still has a confusing name.


Rename toUpperMaybeInPlace.


Actually, the functionality is useful, it's just the name that is confusing.


Then, for those that absolutely *can't* allocate provide a better
interface. For example:
`void toUpper(S, O)(S s, ref O o);`

Burden on the caller to make it inplace from that (or to allocate
accordingly when inplace is not possible).



--
/Jacob Carlborg


Re: DIP60: @nogc attribute

2014-04-20 Thread Frustrated via Digitalmars-d

On Wednesday, 16 April 2014 at 02:14:18 UTC, Walter Bright wrote:

On 4/15/2014 6:57 PM, Mike wrote:
I suspect some of the motivation for this is to give customers 
faster horses.
I would be surprised if a @nogc attribute increased D's 
appeal, and I think

efforts would be better allocated to some form of the above.


Asking for @nogc comes up *constantly*.


How bout this!

Why not allow one to define their own attributes from a 
generalized subset and then define a few standard ones like @nogc.


i.e., instead of having to define specific attributes every few 
years to satisfy some new thing, why not just abstract the 
process.


Attributes, I believe, are essentially relationships between 
parts of code?


If so, then one simply has to implement some generic way to 
specify the attributes and properties of the relationship to the 
compiler. Then anyone would have the tools to define and use 
these attributes as they wish. (in fact, I think it would just 
involve enhancing the current attribute support, probably just 
need to rewrite it all so that the same code is used for built in 
attributes(@safe, @pure, etc...) and user define attributes.



So, we just need to define the attribute name and the properties 
it has such as:


Assume Y uses X in some way(function call) and X has an attribute 
A defined on it:


Inheritance - Y inherits attribute A.

Exclusion - If Y has attribute B and B is mutually excluded from 
A then error


Composition - If Y also uses Z and Z has attribute B then Y has 
the compound attribute (A:B). Compound attributes can be 
rewritten to other attributes using a grammar/reduction scheme. 
Some compositions can be invalid. E.g., @nogc and @gc, @pure and 
@notpure, etc...


Duality - If an attribute A is not specified for a block of code 
then it's inverse attribute is implicitly specified always. e.g., 
@gc and @!gc = @nogc are duals and one or the other always is 
specified, even if implicit.


etc... [Note, I'm not saying all attributes have these 
properties, just that these the possible properties they can have]




By coming up with a general system(I'm sure there is some 
mathematical structure that describes attributes) it would be 
very easy to add attributes in the future and there would be a 
consistent code backing for them. It would also be easier for CT 
reflection on attributes.



Anyways, just a thought, sounds easy in theory...



  1   2   3   4   >