Re: Specifying @nogc on structs seems to have no effect

2017-09-19 Thread Craig Black via Digitalmars-d
On Tuesday, 19 September 2017 at 20:57:17 UTC, Neia Neutuladh 
wrote:
On Tuesday, 19 September 2017 at 15:11:31 UTC, Craig Black 
wrote:

[...]


You want to ensure that it can never refer to GC memory. The 
type system does not contain that information. It doesn't say 
whether an object was allocated on the GC heap, on the stack, 
using malloc, using a whole page of memory with mmap, using 
hardware addresses directly on an embedded system with manually 
planned memory layout, using a well-known address range like 
VGA, as part of the binary's static data segment...


[...]


Thank you for the information. I hadn't thought of using 
templates like that.  That might accomplish what I'm trying to 
do.  Much appreciated!


-Craig


Re: Specifying @nogc on structs seems to have no effect

2017-09-19 Thread Craig Black via Digitalmars-d
On Tuesday, 19 September 2017 at 13:59:27 UTC, Jonathan M Davis 
wrote:
On Tuesday, September 19, 2017 13:11:03 Craig Black via 
Digitalmars-d wrote:
I've recently tried coding in D again after some years.  One 
of my earlier concerns was the ability to code without the GC, 
which seemed difficult to pull off.  To be clear, I want my 
programs to be garbage collected, but I want to use the GC 
sparingly so that the mark and sweep collections will be fast.
 So I want guarantees that certain sections of code and 
certain structs will not require the GC in any way.


I realize that you can allocate on the non-GC heap using 
malloc and free and emplace, but I find it troubling that you 
still need to tell the GC to scan your allocation. What I 
would like is, for example, to be able to write a @nogc 
templated struct that guarantees that none of its members 
require GC scanning.  Thus:


@nogc struct Array(T)
{
   ...
}

class GarbageCollectedClass
{
}

void main()
{
   Array!int intArray; // fine


}


@nogc is a function attribute. It has no effect on types except 
on their member functions. All it does is guarantee that a 
function marked with @nogc cannot call any function which is 
not @nogc and cannot do any operation which is not considered 
@nogc. It's to guarantee that a function does not use the GC 
and has nothing more to do with types than attributes like 
@safe or nothrow do.


- Jonathan M Davis


Thank you for your response.  The @nogc attribute is good, but in 
my opinion it is incomplete if all types still require scanning.  
The purpose of not employing GC in certain sections of code is 
performance, and we are sacrificing performance with every 
allocation unit that is needlessly scanned.


-Craig


Re: Specifying @nogc on structs seems to have no effect

2017-09-19 Thread Craig Black via Digitalmars-d

On Tuesday, 19 September 2017 at 13:11:03 UTC, Craig Black wrote:
I've recently tried coding in D again after some years.  One of 
my earlier concerns was the ability to code without the GC, 
which seemed difficult to pull off.  To be clear, I want my 
programs to be garbage collected, but I want to use the GC 
sparingly so that the mark and sweep collections will be fast.  
So I want guarantees that certain sections of code and certain 
structs will not require the GC in any way.


I realize that you can allocate on the non-GC heap using malloc 
and free and emplace, but I find it troubling that you still 
need to tell the GC to scan your allocation. What I would like 
is, for example, to be able to write a @nogc templated struct 
that guarantees that none of its members require GC scanning.  
Thus:


@nogc struct Array(T)
{
  ...
}

class GarbageCollectedClass
{
}

void main()
{
  Array!int intArray; // fine


}


I don't know why send this message out when I was just in the 
middle of typing it out: But the example should read like this:


@nogc struct Array(T)
{
  ...
}

class GarbageCollectedClass
{
}

void main()
{
  Array!int intArray; // fine
  Array!GarbageCollectedClass classArray; // Error: struct Array 
is @nogc


}


Specifying @nogc on structs seems to have no effect

2017-09-19 Thread Craig Black via Digitalmars-d
I've recently tried coding in D again after some years.  One of 
my earlier concerns was the ability to code without the GC, which 
seemed difficult to pull off.  To be clear, I want my programs to 
be garbage collected, but I want to use the GC sparingly so that 
the mark and sweep collections will be fast.  So I want 
guarantees that certain sections of code and certain structs will 
not require the GC in any way.


I realize that you can allocate on the non-GC heap using malloc 
and free and emplace, but I find it troubling that you still need 
to tell the GC to scan your allocation. What I would like is, for 
example, to be able to write a @nogc templated struct that 
guarantees that none of its members require GC scanning.  Thus:


@nogc struct Array(T)
{
  ...
}

class GarbageCollectedClass
{
}

void main()
{
  Array!int intArray; // fine


}


Re: Specifying @nogc on structs seems to have no effect

2017-09-19 Thread Craig Black via Digitalmars-d
On Tuesday, 19 September 2017 at 13:32:59 UTC, Eugene Wissner 
wrote:
On Tuesday, 19 September 2017 at 13:11:03 UTC, Craig Black 
wrote:
I've recently tried coding in D again after some years.  One 
of my earlier concerns was the ability to code without the GC, 
which seemed difficult to pull off.  To be clear, I want my 
programs to be garbage collected, but I want to use the GC 
sparingly so that the mark and sweep collections will be fast.
 So I want guarantees that certain sections of code and 
certain structs will not require the GC in any way.


I realize that you can allocate on the non-GC heap using 
malloc and free and emplace, but I find it troubling that you 
still need to tell the GC to scan your allocation. What I 
would like is, for example, to be able to write a @nogc 
templated struct that guarantees that none of its members 
require GC scanning.  Thus:


@nogc struct Array(T)
{
  ...
}

class GarbageCollectedClass
{
}

void main()
{
  Array!int intArray; // fine


}



struct Array(T)
{
@nogc:
  ...
}
?


Thanks, I didn't know you could to that but it still doesn't give 
me the behavior that I want:


class Foo
{
}

struct MyStruct
{
@nogc:
public:
  Foo foo; // This does not produce an error, but it still 
requires a GC scan

  void Bar()
  {
foo = new Foo; // This produces an error
  }
}


Re: Specifying @nogc on structs seems to have no effect

2017-09-20 Thread Craig Black via Digitalmars-d

On Wednesday, 20 September 2017 at 02:43:44 UTC, B4s1L3 wrote:
On Tuesday, 19 September 2017 at 13:11:03 UTC, Craig Black 
wrote:
I've recently tried coding in D again after some years.  One 
of my earlier concerns was the ability to code without the GC, 
which seemed difficult to pull off.  To be clear, I want my 
programs to be garbage collected, but I want to use the GC 
sparingly so that the mark and sweep collections will be fast.
 So I want guarantees that certain sections of code and 
certain structs will not require the GC in any way.


I realize that you can allocate on the non-GC heap using 
malloc and free and emplace, but I find it troubling that you 
still need to tell the GC to scan your allocation. What I 
would like is, for example, to be able to write a @nogc 
templated struct that guarantees that none of its members 
require GC scanning.  Thus:


@nogc struct Array(T)
{
  ...
}

class GarbageCollectedClass
{
}

void main()
{
  Array!int intArray; // fine


}


I've implemented data annotation in iz, if you want to take a 
look.

It's quite near from what you descibed in a more recent answer:


/+ dub.sdl:
   name "dub_script"
   dependency "iz" version="0.6.0"
+/
module dub_script;

import iz.memory;

// defines a class that has a member
// which is usually handled by the GC
class Foo {void* looks_gc_managed;}
// defines a class and marks member as nogc-"trusted"
class Bar {@NoGc Foo foo;}
// defines a class without annotation
class Baz {Foo foo;}

// verified statically
static assert(!MustAddGcRange!Bar);
static assert( MustAddGcRange!Baz);

void main(string[] args)
{
Foo foo = construct!Foo;
destruct(foo);
}


It's another way of doing things. It's less strict than 
checking all the functions.


note: the script can be run directly by passing the file to DUB 
(single file package).


Wow!  Yeah that seems like almost exactly what I want. Sorry what 
is iz?  Thank you!


-Craig


Re: Specifying @nogc on structs seems to have no effect

2017-09-20 Thread Craig Black via Digitalmars-d

On Wednesday, 20 September 2017 at 02:43:44 UTC, B4s1L3 wrote:
It's another way of doing things. It's less strict than 
checking all the functions.


note: the script can be run directly by passing the file to DUB 
(single file package).



Wow!  Yeah that seems like almost exactly what I want. Sorry what 
is iz?  Thank you!


-Craig


Re: Specifying @nogc on structs seems to have no effect

2017-09-19 Thread Craig Black via Digitalmars-d

On Tuesday, 19 September 2017 at 14:34:10 UTC, Mike Parker wrote:
On Tuesday, 19 September 2017 at 14:22:21 UTC, Craig Black 
wrote:


Thank you for your response.  The @nogc attribute is good, but 
in my opinion it is incomplete if all types still require 
scanning.  The purpose of not employing GC in certain sections 
of code is performance, and we are sacrificing performance 
with every allocation unit that is needlessly scanned.


-Craig


As I wrote in my previous post, *no* GC activity will happen 
inside a @nogc function. The only time any scanning or 
collections can take place is when a allocation is requested. 
If none are requested, there's no activity.


Aside from that, there are other options. If you don't want 
your Foo member variable to be scanned, then allocate it 
outside the GC heap (see Mallocator in std.allocator). You can 
call GC.disable whenever you want (but be wary of the impact 
performance when you later call GC.collect). You can allocate 
outside of your hot loops and use stack allocation where 
possible.


I suggest you take a look at the ongoing GC series on the D 
Blog. The next post (coming later this week) covers heap 
allocations.


https://dlang.org/blog/the-gc-series/


Thank you for the information.  What I would like to do is to 
create an Array template class that doesn't use GC at all.  
Unfortunately I don't think this is possible with D in its 
current state, at least not safely anyway.  As it is, I can't 
prevent someone using my Array template to create an array of 
objects that reference the GC heap.  This means that in order to 
not break the language and avoid memory leaks, I am forced to 
tell the GC to scan all of my allocations.  There seems to be no 
way to avoid this unnecessary overhead.


I realize that the GC will not collect during a @nogc function.  
This is a good guarantee, but I want to reduce the amount of time 
it takes to perform a collection, and there doesn't seem to be a 
good way to do this.


-Craig


Re: Specifying @nogc on structs seems to have no effect

2017-09-19 Thread Craig Black via Digitalmars-d
On Tuesday, 19 September 2017 at 15:15:05 UTC, Steven 
Schveighoffer wrote:

On 9/19/17 10:22 AM, Craig Black wrote:
On Tuesday, 19 September 2017 at 13:59:27 UTC, Jonathan M 
Davis wrote:
On Tuesday, September 19, 2017 13:11:03 Craig Black via 
Digitalmars-d wrote:
I've recently tried coding in D again after some years.  One 
of my earlier concerns was the ability to code without the 
GC, which seemed difficult to pull off.  To be clear, I want 
my programs to be garbage collected, but I want to use the 
GC sparingly so that the mark and sweep collections will be 
fast.
 So I want guarantees that certain sections of code and 
certain structs will not require the GC in any way.


I realize that you can allocate on the non-GC heap using 
malloc and free and emplace, but I find it troubling that 
you still need to tell the GC to scan your allocation. What 
I would like is, for example, to be able to write a @nogc 
templated struct that guarantees that none of its members 
require GC scanning.  Thus:


@nogc struct Array(T)
{
   ...
}

class GarbageCollectedClass
{
}

void main()
{
   Array!int intArray; // fine


}


@nogc is a function attribute. It has no effect on types 
except on their member functions. All it does is guarantee 
that a function marked with @nogc cannot call any function 
which is not @nogc and cannot do any operation which is not 
considered @nogc. It's to guarantee that a function does not 
use the GC and has nothing more to do with types than 
attributes like @safe or nothrow do.



Thank you for your response.  The @nogc attribute is good, but 
in my opinion it is incomplete if all types still require 
scanning. The purpose of not employing GC in certain sections 
of code is performance, and we are sacrificing performance 
with every allocation unit that is needlessly scanned.




From your posts and responses, it looks like you misunderstand 
still what the @nogc attribute does.


Note that a type does not bear any relation to whether the 
memory it lives in is scanned or not -- EXCEPT -- whether the 
type has indirections (pointers or arrays). A type which 
contains indirections is scanned, one that does not contain 
them is not scanned. There is no way to mark a type such that 
it:


1. Cannot be allocated on the GC*
2. Would not be scanned if it has pointers.

You can manually allocate it elsewhere, and you can manually 
tell the GC not to scan that block, but those are low-level 
tools that normally aren't used except by experts.


The @nogc attribute is used to PREVENT any operation that could 
cause a scan to occur. The idea is to mark areas of your code 
in such a way that you can predict the execution expense of 
that code. That is, if you have a tight loop or are in the 
middle of rendering frames to the screen in a game or 
something, you want to have the compiler ensure no GC cycles 
happen. It does not mean "don't ever store this in the GC."


-Steve

* There is a deprecated feature of D that allows specifying how 
to allocate classes other than heap allocation, but I wouldn't 
recommend using it. See: 
https://dlang.org/spec/class.html#allocators


Thank you for the clarification. I understand mow that @nogc is 
only for functions and not for data types.  Thinking out loud, it 
would seem beneficial if there was a way to mark a pointer or 
data structure as not pointing to the GC heap. A guarantee to the 
compiler and run-time to ignore it during GC sweeps.  Now I know 
that pointer arithmetic breaks every kind of guarantee that would 
have with pointers, but aside from that it would seem to me that 
the compiler could help to enforce data marked as non-GC to not 
be assigned GC heap allocations.  This wouldn't be allowed for 
classes or class references, since they are always pointing to GC 
data, but perhaps for pointers and structs.  It seems like it 
would be a helpful feature, but maybe I'm way off base.


-Craig