Thread overview
Type Aware GC Questions
Jan 28, 2007
Craig Black
Jan 28, 2007
Walter Bright
Jan 29, 2007
Craig Black
Jan 29, 2007
Craig Black
Jan 29, 2007
Sean Kelly
Jan 29, 2007
Craig Black
Jan 29, 2007
Sean Kelly
Jan 30, 2007
Kevin Bealer
Jan 30, 2007
Walter Bright
January 28, 2007
I was wondering, just how smart is the compiler now?  If I define a class that doesn't have any pointers, then will the compiler know that it doesn't have pointers?   If I only have one pointer in my class, will the GC only scan that location?

-Craig


January 28, 2007
Craig Black wrote:
> I was wondering, just how smart is the compiler now?  If I define a class
> that doesn't have any pointers, then will the compiler know that it doesn't
> have pointers? 

Yes.

> If I only have one pointer in my class, will the GC only
> scan that location?

No, it'll scan the whole class. All it has is a bit that says "might have pointers" or "has no pointers".
January 29, 2007
"Walter Bright" <newshound@digitalmars.com> wrote in message news:ephqje$1eje$2@digitaldaemon.com...
> Craig Black wrote:
>> I was wondering, just how smart is the compiler now?  If I define a class
>> that doesn't have any pointers, then will the compiler know that it
>> doesn't
>> have pointers?
>
> Yes.
>
>> If I only have one pointer in my class, will the GC only scan that location?
>
> No, it'll scan the whole class. All it has is a bit that says "might have pointers" or "has no pointers".

If I have such a class, is there something I can do to inform the GC not to scan a certain portiion of memory?


January 29, 2007
> If I have such a class, is there something I can do to inform the GC not to scan a certain portiion of memory?

If I understand that correctly, you can have another class - probably a nested one - that holds the data.

C will be scanned, but not the instance of C.Data

class C {
   // some references
   Object o;
   // Data
   private static class Data{
      // only non-reference types/data
      int a;
   }
   private Data data;

   public this(){
      data = new Data;
      data.a = 3;
   }
}

January 29, 2007
Craig Black wrote:
> "Walter Bright" <newshound@digitalmars.com> wrote in message news:ephqje$1eje$2@digitaldaemon.com...
>> Craig Black wrote:
>>> I was wondering, just how smart is the compiler now?  If I define a class
>>> that doesn't have any pointers, then will the compiler know that it doesn't
>>> have pointers?
>> Yes.
>>
>>> If I only have one pointer in my class, will the GC only
>>> scan that location?
>> No, it'll scan the whole class. All it has is a bit that says "might have pointers" or "has no pointers".
> 
> If I have such a class, is there something I can do to inform the GC not to scan a certain portiion of memory? 

Phobos:

    import std.gc;

    MyClass c = new MyClass;
    hasNoPointers( c );

Tango:

    import Tango.core.Memory;

    MyClass c = new MyClass;
    gc.setAttr( c, GC.BlkAttr.NO_SCAN );

But this still only works for the entire memory block, not a subrange.


Sean
January 29, 2007
"Frank Benoit (keinfarbton)" <benoit@tionex.removethispart.de> wrote in message news:eplfkh$o2g$1@digitaldaemon.com...
>> If I have such a class, is there something I can do to inform the GC not
>> to
>> scan a certain portiion of memory?
>
> If I understand that correctly, you can have another class - probably a nested one - that holds the data.
>
> C will be scanned, but not the instance of C.Data
>
> class C {
>   // some references
>   Object o;
>   // Data
>   private static class Data{
>      // only non-reference types/data
>      int a;
>   }
>   private Data data;
>
>   public this(){
>      data = new Data;
>      data.a = 3;
>   }
> }
>

But that requires another heap allocation.

-Craig


January 29, 2007
Could it be done with an overloaded new somehow?

"Sean Kelly" <sean@f4.ca> wrote in message news:epli16$rvc$1@digitaldaemon.com...
> Craig Black wrote:
>> "Walter Bright" <newshound@digitalmars.com> wrote in message news:ephqje$1eje$2@digitaldaemon.com...
>>> Craig Black wrote:
>>>> I was wondering, just how smart is the compiler now?  If I define a
>>>> class
>>>> that doesn't have any pointers, then will the compiler know that it
>>>> doesn't
>>>> have pointers?
>>> Yes.
>>>
>>>> If I only have one pointer in my class, will the GC only scan that location?
>>> No, it'll scan the whole class. All it has is a bit that says "might have pointers" or "has no pointers".
>>
>> If I have such a class, is there something I can do to inform the GC not to scan a certain portiion of memory?
>
> Phobos:
>
>     import std.gc;
>
>     MyClass c = new MyClass;
>     hasNoPointers( c );
>
> Tango:
>
>     import Tango.core.Memory;
>
>     MyClass c = new MyClass;
>     gc.setAttr( c, GC.BlkAttr.NO_SCAN );
>
> But this still only works for the entire memory block, not a subrange.
>
>
> Sean


January 29, 2007
Frank's suggestion seems reasonable.  There's no way to pass a 'mask' to the GC for a specific block at the moment.

Craig Black wrote:
> Could it be done with an overloaded new somehow?
> 
> "Sean Kelly" <sean@f4.ca> wrote in message news:epli16$rvc$1@digitaldaemon.com...
>> Craig Black wrote:
>>> "Walter Bright" <newshound@digitalmars.com> wrote in message news:ephqje$1eje$2@digitaldaemon.com...
>>>> Craig Black wrote:
>>>>> I was wondering, just how smart is the compiler now?  If I define a class
>>>>> that doesn't have any pointers, then will the compiler know that it doesn't
>>>>> have pointers?
>>>> Yes.
>>>>
>>>>> If I only have one pointer in my class, will the GC only
>>>>> scan that location?
>>>> No, it'll scan the whole class. All it has is a bit that says "might have pointers" or "has no pointers".
>>> If I have such a class, is there something I can do to inform the GC not to scan a certain portiion of memory?
>> Phobos:
>>
>>     import std.gc;
>>
>>     MyClass c = new MyClass;
>>     hasNoPointers( c );
>>
>> Tango:
>>
>>     import Tango.core.Memory;
>>
>>     MyClass c = new MyClass;
>>     gc.setAttr( c, GC.BlkAttr.NO_SCAN );
>>
>> But this still only works for the entire memory block, not a subrange.
>>
>>
>> Sean 
> 
> 
January 30, 2007
Craig Black wrote:
> "Walter Bright" <newshound@digitalmars.com> wrote in message news:ephqje$1eje$2@digitaldaemon.com...
>> Craig Black wrote:
>>> I was wondering, just how smart is the compiler now?  If I define a class
>>> that doesn't have any pointers, then will the compiler know that it doesn't
>>> have pointers?
>> Yes.
>>
>>> If I only have one pointer in my class, will the GC only
>>> scan that location?
>> No, it'll scan the whole class. All it has is a bit that says "might have pointers" or "has no pointers".
> 
> If I have such a class, is there something I can do to inform the GC not to scan a certain portiion of memory? 
> 
> 

See std.gc.hasNoPointers, std.gc.hasPointers.
January 30, 2007
Sean Kelly wrote:
> Frank's suggestion seems reasonable.  There's no way to pass a 'mask' to the GC for a specific block at the moment.
> 

I think some GC designs have exactly that.  I've thought about this and it seems like two cases should cover most of it:

1. Short mask that repeats (to cover larger blocks).
2. Number that describes how much of the class contains pointers.

Item #1 would be a mask of each pointer-sized slice of memory.  The repeat part means that (for example) an array of struct can be represented by one mask, overlaying the size of the struct.

All arrays of non-pointer primitives could be represented as '0' sz=1.
Arrays of arrays could be represented as '01' or '10', sz=2, depending on whether the pointer comes first.

Small struct items (maybe under 16 words) could share the masks to reduce duplication.

Item #2 allows allocations like this, which are common in C:

#define NUM 100

struct Foo {
    int a;
    int * b;
    char * d;
    char buf[NUM];
};

The "size" lets the 'buf' section not be represented in the mask, however because there may be arrays of Foo, it would be good to combine the mask-size and repeat-size elements to use short masks for long objects and still repeat at long intervals.


A corollary of #2 is that the definitions of most classes could be 'sorted' to move pointy stuff toward the top.  This would be 'soft' ie some things cant be rearranged (internal struct members, arrays) even in a class.  It would have two nice effects:

1. Sorted classes will tend to use far fewer mask combinations.
2. GC runs can find all class pointers in fewer L1/L2 cache lines, because the pointers are packed.

Both of these are a strict 'extension' of the current 'might have' bit, since "might_have" represents '1', sz=1, and 'might_not' represents '0', sz=1.

Automatic (and free) memory consistency checking (maybe):

Another neat idea --- you can introduce a 'must-have-pointer' marker for the field mask, which means this field *must* be a valid pointer or null (in debug mode only, or maybe only if enabled by the user?).

This would provide across the board pointer checking (a la valgrind) for essentially zero costs (but only at GC time), because a conservative GC must already be able to test if a pointer is within the allocated heapspace in order to do its mark/sweep, right?

Either the pointer points to a valid object, or you get an assert.  But this would need to special case around deleted objects in case the pointer aliasing is known-but-harmless.

Kevin