June 14, 2015
On Sunday, 14 June 2015 at 11:03:00 UTC, Marc Schütz wrote:
> On Saturday, 13 June 2015 at 22:07:26 UTC, deadalnix wrote:
>> On Saturday, 13 June 2015 at 11:32:20 UTC, rsw0x wrote:
>>> http://dlang.org/garbage.html
>>>
>>> Do not take advantage of alignment of pointers to store bit flags in the low order bits:
>>> p = cast(void*)(cast(int)p | 1);  // error: undefined behavior
>>>
>>> if this restriction is actually imposed - why does std.bitmanip.tagged{ClassRef,Pointer} even exist?
>>
>> That seems like an arbitrary limitation. This will create an interior pointer, which the GC needs to recognize anyway.
>>
>> The doc need to be updated.
>
> I see David Nadlinger already said so in the PR, but that's how I understand it:
>
> AFAIU the purpose of this restriction is to allow the GC to take advantage of alignment: a pointer with the lowest bit set cannot point to a 4-byte aligned struct, for example. The GC doc [1] mentions alignment several times, among them:
> "Do not misalign pointers if those pointers may point into the GC heap"
>
> As for arbitrary pointer arithmetic being allowed, I guess that's because the language doesn't distinguish between GC and non-GC pointers. And note that it is un-@safe anyway.
>
> [1] http://dlang.org/garbage.html

Wouldn't it make sense to do so?

Active Oberon, Modula-3 and .NET make such difference in their pointer types.

I would imagine it could help in terms of what is possible for GC improvements.

--
Paulo
June 14, 2015
On Sunday, 14 June 2015 at 11:36:59 UTC, Paulo Pinto wrote:
> On Sunday, 14 June 2015 at 11:03:00 UTC, Marc Schütz wrote:
>> On Saturday, 13 June 2015 at 22:07:26 UTC, deadalnix wrote:
>>> On Saturday, 13 June 2015 at 11:32:20 UTC, rsw0x wrote:
>>>> http://dlang.org/garbage.html
>>>>
>>>> Do not take advantage of alignment of pointers to store bit flags in the low order bits:
>>>> p = cast(void*)(cast(int)p | 1);  // error: undefined behavior
>>>>
>>>> if this restriction is actually imposed - why does std.bitmanip.tagged{ClassRef,Pointer} even exist?
>>>
>>> That seems like an arbitrary limitation. This will create an interior pointer, which the GC needs to recognize anyway.
>>>
>>> The doc need to be updated.
>>
>> I see David Nadlinger already said so in the PR, but that's how I understand it:
>>
>> AFAIU the purpose of this restriction is to allow the GC to take advantage of alignment: a pointer with the lowest bit set cannot point to a 4-byte aligned struct, for example. The GC doc [1] mentions alignment several times, among them:
>> "Do not misalign pointers if those pointers may point into the GC heap"
>>
>> As for arbitrary pointer arithmetic being allowed, I guess that's because the language doesn't distinguish between GC and non-GC pointers. And note that it is un-@safe anyway.
>>
>> [1] http://dlang.org/garbage.html
>
> Wouldn't it make sense to do so?
>
> Active Oberon, Modula-3 and .NET make such difference in their pointer types.
>
> I would imagine it could help in terms of what is possible for GC improvements.
>
> --
> Paulo

But a pointer can already point to a one byte aligned part of an object and keep it alive because internal pointers must be supported. The only alignment enforced is that pointers must be aligned. This is an arbitrary restriction.
June 14, 2015
On Sunday, 14 June 2015 at 11:57:35 UTC, rsw0x wrote:
> On Sunday, 14 June 2015 at 11:36:59 UTC, Paulo Pinto wrote:
>> On Sunday, 14 June 2015 at 11:03:00 UTC, Marc Schütz wrote:
>>> On Saturday, 13 June 2015 at 22:07:26 UTC, deadalnix wrote:
>>>> On Saturday, 13 June 2015 at 11:32:20 UTC, rsw0x wrote:
>>>>> http://dlang.org/garbage.html
>>>>>
>>>>> Do not take advantage of alignment of pointers to store bit flags in the low order bits:
>>>>> p = cast(void*)(cast(int)p | 1);  // error: undefined behavior
>>>>>
>>>>> if this restriction is actually imposed - why does std.bitmanip.tagged{ClassRef,Pointer} even exist?
>>>>
>>>> That seems like an arbitrary limitation. This will create an interior pointer, which the GC needs to recognize anyway.
>>>>
>>>> The doc need to be updated.
>>>
>>> I see David Nadlinger already said so in the PR, but that's how I understand it:
>>>
>>> AFAIU the purpose of this restriction is to allow the GC to take advantage of alignment: a pointer with the lowest bit set cannot point to a 4-byte aligned struct, for example. The GC doc [1] mentions alignment several times, among them:
>>> "Do not misalign pointers if those pointers may point into the GC heap"
>>>
>>> As for arbitrary pointer arithmetic being allowed, I guess that's because the language doesn't distinguish between GC and non-GC pointers. And note that it is un-@safe anyway.
>>>
>>> [1] http://dlang.org/garbage.html
>>
>> Wouldn't it make sense to do so?
>>
>> Active Oberon, Modula-3 and .NET make such difference in their pointer types.
>>
>> I would imagine it could help in terms of what is possible for GC improvements.
>>
>> --
>> Paulo
>
> But a pointer can already point to a one byte aligned part of an object and keep it alive because internal pointers must be supported. The only alignment enforced is that pointers must be aligned. This is an arbitrary restriction.

Woops, replied to the wrong person. My bad.


And yes, you're right that the GC could improve if we went towards "d pointers" like Go did.
June 14, 2015
On Sunday, 14 June 2015 at 11:36:59 UTC, Paulo Pinto wrote:
> On Sunday, 14 June 2015 at 11:03:00 UTC, Marc Schütz wrote:
>> As for arbitrary pointer arithmetic being allowed, I guess that's because the language doesn't distinguish between GC and non-GC pointers. And note that it is un-@safe anyway.
>>
>> [1] http://dlang.org/garbage.html
>
> Wouldn't it make sense to do so?
>
> Active Oberon, Modula-3 and .NET make such difference in their pointer types.
>
> I would imagine it could help in terms of what is possible for GC improvements.

Definitely, but I don't see how it could reasonably be added to the language now.
June 15, 2015
On 6/14/15 7:02 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
> On Saturday, 13 June 2015 at 22:07:26 UTC, deadalnix wrote:
>> On Saturday, 13 June 2015 at 11:32:20 UTC, rsw0x wrote:
>>> http://dlang.org/garbage.html
>>>
>>> Do not take advantage of alignment of pointers to store bit flags in
>>> the low order bits:
>>> p = cast(void*)(cast(int)p | 1);  // error: undefined behavior
>>>
>>> if this restriction is actually imposed - why does
>>> std.bitmanip.tagged{ClassRef,Pointer} even exist?
>>
>> That seems like an arbitrary limitation. This will create an interior
>> pointer, which the GC needs to recognize anyway.
>>
>> The doc need to be updated.
>
> I see David Nadlinger already said so in the PR, but that's how I
> understand it:
>
> AFAIU the purpose of this restriction is to allow the GC to take
> advantage of alignment: a pointer with the lowest bit set cannot point
> to a 4-byte aligned struct, for example.

Huh? Of course it can!

struct S
{
  ubyte[4] arr;
  int x;
}

auto s = new S;
auto p = &s.arr[1]; // points at an S in memory.

I don't see how GC can take any advantage of this.

-Steve
June 15, 2015
On 6/14/15 8:44 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
> On Sunday, 14 June 2015 at 11:36:59 UTC, Paulo Pinto wrote:
>> On Sunday, 14 June 2015 at 11:03:00 UTC, Marc Schütz wrote:
>>> As for arbitrary pointer arithmetic being allowed, I guess that's
>>> because the language doesn't distinguish between GC and non-GC
>>> pointers. And note that it is un-@safe anyway.
>>>
>>> [1] http://dlang.org/garbage.html
>>
>> Wouldn't it make sense to do so?
>>
>> Active Oberon, Modula-3 and .NET make such difference in their pointer
>> types.
>>
>> I would imagine it could help in terms of what is possible for GC
>> improvements.
>
> Definitely, but I don't see how it could reasonably be added to the
> language now.

We can create new types of pointers, remove void * from the language, and get rid of unions, and yes, *ONLY THEN* we can have a GC that takes advantage of this.

These are painful, massively breaking changes. It's not going to happen.

-Steve
June 15, 2015
On 13-Jun-2015 14:32, rsw0x wrote:
> http://dlang.org/garbage.html
>
> Do not take advantage of alignment of pointers to store bit flags in the
> low order bits:
> p = cast(void*)(cast(int)p | 1);  // error: undefined behavior
>
> if this restriction is actually imposed - why does
> std.bitmanip.tagged{ClassRef,Pointer} even exist?

AFAIK the restriction was that pointers _themselves_ have to be stored at word-aligned addresses. This allows GC to scan memory cheaper w/o considering if some misaligned address may contain a pointer.

-- 
Dmitry Olshansky
June 15, 2015
On 6/15/15 8:08 AM, Dmitry Olshansky wrote:
> On 13-Jun-2015 14:32, rsw0x wrote:
>> http://dlang.org/garbage.html
>>
>> Do not take advantage of alignment of pointers to store bit flags in the
>> low order bits:
>> p = cast(void*)(cast(int)p | 1);  // error: undefined behavior
>>
>> if this restriction is actually imposed - why does
>> std.bitmanip.tagged{ClassRef,Pointer} even exist?
>
> AFAIK the restriction was that pointers _themselves_ have to be stored
> at word-aligned addresses. This allows GC to scan memory cheaper w/o
> considering if some misaligned address may contain a pointer.

That doesn't make sense. Why would you want to do this?

The only rational thing I can think of is that you wouldn't want to store the result in an *actual* int pointer (lest it be used thinking it was valid without masking out the lower bits). But the example is storing it in a void *...

-Steve
June 15, 2015
On Mon, 15 Jun 2015 08:01:58 -0400, Steven Schveighoffer wrote:

> We can create new types of pointers, remove void * from the language, and get rid of unions, and yes, *ONLY THEN* we can have a GC that takes advantage of this.
> 
> These are painful, massively breaking changes. It's not going to happen.

i'm dreaming of making unions that contains GC objects invalid. it simply begs for troubles!

June 15, 2015
On 15-Jun-2015 15:49, Steven Schveighoffer wrote:
> On 6/15/15 8:08 AM, Dmitry Olshansky wrote:
>> On 13-Jun-2015 14:32, rsw0x wrote:
>>> http://dlang.org/garbage.html
>>>
>>> Do not take advantage of alignment of pointers to store bit flags in the
>>> low order bits:
>>> p = cast(void*)(cast(int)p | 1);  // error: undefined behavior
>>>
>>> if this restriction is actually imposed - why does
>>> std.bitmanip.tagged{ClassRef,Pointer} even exist?
>>
>> AFAIK the restriction was that pointers _themselves_ have to be stored
>> at word-aligned addresses. This allows GC to scan memory cheaper w/o
>> considering if some misaligned address may contain a pointer.
>
> That doesn't make sense. Why would you want to do this?
>

What exactly? Storing pointer at misaligned memory location - no good reason whatsoever. As in how it may happen - explicitly tightly packed structs with align(1) might end up doing this.

From http://dlang.org/phobos/core_memory.html which seems to be more recent:

Implementations are free to assume that GC pointers are only stored on word boundaries. Unaligned pointers may be ignored entirely.

> The only rational thing I can think of is that you wouldn't want to
> store the result in an *actual* int pointer (lest it be used thinking it
> was valid without masking out the lower bits). But the example is
> storing it in a void *...
>

The example doesn't show what memory location that p refers to thus it's not possible to say if it's valid.


-- 
Dmitry Olshansky