November 10, 2010
On 10/11/2010 00:16, Jonathan M Davis wrote:
> On Tuesday, November 09, 2010 13:49:12 bearophile wrote:
>> Jonathan M Davis:
>>> it would be possible to make it so that any objects allocated with
>>> new during CTFE would be in the dynamic heap during runtime.
>>
>> This is possible, but it doesn't seem what you usually desire when you
>> allocate an object at compile time.
>
> Why not? CTFE stuff should either disappear in the binary, because it's not
> needed anymore, or it should be the same as if it were created at runtime. CTFE
> is a great opportunity to create more complicated stuff at cheaper cost (since
> the calculations are done at compile time instead of runtime), and more
> importantly, have compile-time constants which are more complex. It's also a
> great way to generate code. But I don't see why you'd want statically-created
> objects to be treated differently once the program is running.
>
> - Jonathan M Davis

No, that's completely wrong.

CTFE should result in constant initialisation values, eg stuff in the .exes read only data segment.

CTFE is the same as:

immutable string _someString = "hello world!";

Expect that it's:

immutable string _someString = reallyComplicatedCTFEfunction();

-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
November 10, 2010
On Tuesday, November 09, 2010 16:24:30 div0 wrote:
> On 10/11/2010 00:16, Jonathan M Davis wrote:
> > On Tuesday, November 09, 2010 13:49:12 bearophile wrote:
> >> Jonathan M Davis:
> >>> it would be possible to make it so that any objects allocated with new during CTFE would be in the dynamic heap during runtime.
> >> 
> >> This is possible, but it doesn't seem what you usually desire when you allocate an object at compile time.
> > 
> > Why not? CTFE stuff should either disappear in the binary, because it's not needed anymore, or it should be the same as if it were created at runtime. CTFE is a great opportunity to create more complicated stuff at cheaper cost (since the calculations are done at compile time instead of runtime), and more importantly, have compile-time constants which are more complex. It's also a great way to generate code. But I don't see why you'd want statically-created objects to be treated differently once the program is running.
> > 
> > - Jonathan M Davis
> 
> No, that's completely wrong.
> 
> CTFE should result in constant initialisation values, eg stuff in the .exes read only data segment.
> 
> CTFE is the same as:
> 
> immutable string _someString = "hello world!";
> 
> Expect that it's:
> 
> immutable string _someString = reallyComplicatedCTFEfunction();

There are plenty of cases where CTFE is used to create constants, but there are also plenty of places where it can create non-constants - such as setting the initial value for a member variable. Personally, I don't want to have to worry about where in memory an object lives. Constants can - to some extent - be treated as special, but CTFE is _not_ only for generating constants.

- Jonathan M Davis
November 10, 2010
On Tue, 09 Nov 2010 15:42:06 -0500, bearophile <bearophileHUGS@lycos.com> wrote:

> Don:
>
>> Yes. The rules will be:
>> * no globals (same as pure).
>> * no unsafe features (eg, no asm).
>> * source code must be available.
>> Everything else should work.
>
> If a class is instantiated at compile-time the memory of its instance goes in the static mutable memory, but then the GC has to manage it differently, because you can't deallocate that memory. Is this a problem? It looks a little like the problems with scoped classes (that are now deprecated by Andrei).

The problem with scoped classes are that they are reference types allocated on the stack.  This is highly prone to memory problems, especially when classes are usually expected to be in the heap (less care about storing into a global).

I'm assuming compile-time classes will be reference types allocated in the data segment.  This is more similar to string literals than scope classes.  I'm guessing that the resulting class must be immutable, no?  Otherwise, how do you allow mutable functions on a class allocated in ROM?

FWIW, I like scope classes for optimization (I use them a few places in dcollections), but emplace should be sufficient to replace it.

-Steve
November 10, 2010
On Tue, 09 Nov 2010 17:14:33 -0500, Don <nospam@nospam.com> wrote:

> bearophile wrote:
>> Jonathan M Davis:
>>
>>> it would be possible to make it so that any objects allocated with new during CTFE would be in the dynamic heap during runtime.
>>  This is possible, but it doesn't seem what you usually desire when you allocate an object at compile time.
>>  Bye,
>> bearophile
>
> If it's mutable, it'll go on the heap. If it's immutable, it could optionally go into read-only memory (it will be exactly like the .init of a class instance). Classes which are used only during execution of CTFE functions will not be instantiated at runtime.

Pardon my ignorance, but how can something evaluated at compile time go on the heap?  The heap doesn't exist yet!

e.g.:

class C
{
  int[] buffer;
  this() pure { buffer = new int[125];}
}

C c = new C;

How does c go on the heap at compile time?  Won't you have to re-run the constructor at runtime to get the right result?  Not only that, but even if you did run the ctor at compile time, how do you make a copy of c for every thread without re-running the ctor?

-Steve
November 10, 2010
On Wednesday, November 10, 2010 07:55:42 Steven Schveighoffer wrote:
> On Tue, 09 Nov 2010 17:14:33 -0500, Don <nospam@nospam.com> wrote:
> > bearophile wrote:
> >> Jonathan M Davis:
> >>> it would be possible to make it so that any objects allocated with new during CTFE would be in the dynamic heap during runtime.
> >>> 
> >>  This is possible, but it doesn't seem what you usually desire when you
> >> 
> >> allocate an object at compile time.
> >> 
> >>  Bye,
> >> 
> >> bearophile
> > 
> > If it's mutable, it'll go on the heap. If it's immutable, it could optionally go into read-only memory (it will be exactly like the .init of a class instance). Classes which are used only during execution of CTFE functions will not be instantiated at runtime.
> 
> Pardon my ignorance, but how can something evaluated at compile time go on the heap?  The heap doesn't exist yet!
> 
> e.g.:
> 
> class C
> {
>    int[] buffer;
>    this() pure { buffer = new int[125];}
> }
> 
> C c = new C;
> 
> How does c go on the heap at compile time?  Won't you have to re-run the constructor at runtime to get the right result?  Not only that, but even if you did run the ctor at compile time, how do you make a copy of c for every thread without re-running the ctor?

You likely end up essentially serializing it. You then deserialized it and bring it into the heap when the program loads. It's not a particularly pretty problem, but it should be quite doable. You certainly wouldn't rerun the constructor or whatnot. What you need is to just transfer its saved state onto the heap, translating any pointers and references that it has to whatever they should be in the current heap.

- Jonathan M Davis
November 10, 2010
On Wed, 10 Nov 2010 13:08:10 -0500, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> On Wednesday, November 10, 2010 07:55:42 Steven Schveighoffer wrote:

>> Pardon my ignorance, but how can something evaluated at compile time go on
>> the heap?  The heap doesn't exist yet!
>>
>> e.g.:
>>
>> class C
>> {
>>    int[] buffer;
>>    this() pure { buffer = new int[125];}
>> }
>>
>> C c = new C;
>>
>> How does c go on the heap at compile time?  Won't you have to re-run the
>> constructor at runtime to get the right result?  Not only that, but even
>> if you did run the ctor at compile time, how do you make a copy of c for
>> every thread without re-running the ctor?
>
> You likely end up essentially serializing it. You then deserialized it and bring
> it into the heap when the program loads. It's not a particularly pretty problem,
> but it should be quite doable. You certainly wouldn't rerun the constructor or
> whatnot. What you need is to just transfer its saved state onto the heap,
> translating any pointers and references that it has to whatever they should be
> in the current heap.

Wow, this seems like a lot of extra effort for zero gain.  Is this really the direction we are going?  Why can't we just say anything decided at compile time must be immutable or implicitly converted to immutable, and anything else you have to do in a static constructor?

-Steve
November 10, 2010
Steven Schveighoffer wrote:
> On Tue, 09 Nov 2010 17:14:33 -0500, Don <nospam@nospam.com> wrote:
> 
>> bearophile wrote:
>>> Jonathan M Davis:
>>>
>>>> it would be possible to make it so that any objects allocated with new during CTFE would be in the dynamic heap during runtime.
>>>  This is possible, but it doesn't seem what you usually desire when you allocate an object at compile time.
>>>  Bye,
>>> bearophile
>>
>> If it's mutable, it'll go on the heap. If it's immutable, it could optionally go into read-only memory (it will be exactly like the .init of a class instance). Classes which are used only during execution of CTFE functions will not be instantiated at runtime.
> 
> Pardon my ignorance, but how can something evaluated at compile time go on the heap?  The heap doesn't exist yet!
> 
> e.g.:
> 
> class C
> {
>   int[] buffer;
>   this() pure { buffer = new int[125];}
> }
> 
> C c = new C;
> 
> How does c go on the heap at compile time?  Won't you have to re-run the constructor at runtime to get the right result?  Not only that, but even if you did run the ctor at compile time, how do you make a copy of c for every thread without re-running the ctor?
> 
> -Steve

The situation isn't any different to what we already have. You can already do:

struct F
{
   int [] w;
}

F[] foo() {
   F[] x = new F[6];
   foreach(i; 0..x.length)
      x[i].w = new int[20];
   return x;
}
and foo() can be run at compile time.

OTOH, I don't know if there is any case where a CTFE value can actually end up on the heap at runtime. CTFE only kicks in when you need a manifest constant, and AFAIK there's no way to require a class manifest constant -- just an element of one.
1 2
Next ›   Last »