www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - TypeInfo in struct ABI

reply Teodor Dutu <teodor.dutu gmail.com> writes:
Hi,

In order to allocate a `struct` type, two DRuntime hooks are 
used: `_d_newitemT` for uninitialised structs and `_d_newitemiT` 
for initialised ones. Both hooks call `_d_newitemU`, which 
allocates memory for the struct and [writes the struct’s 
`TypeInfo`](https://github.com/dlang/druntime/blob/9d99b1ccd90d1e66c31e27cc71b8a266612aa14a/src/
t/lifetime.d#L1122) at the end of the allocated chunk.

We now attempt to convert these hooks to templates, with the goal 
of not using `TypeInfo` at all. However, the fact that the ABI of 
a struct contains its `TypeInfo` prevents us from achieving this 
goal. Is this `TypeInfo` object still necessary for anything, or 
are we free to remove it from the ABI altogether so that we have 
cleaner implementations for `_d_newitem{U,iT,T}`?

Thanks,
Teodor
Jan 17 2022
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
TypeInfo is used by a precise GC to determine how to (if it will need 
to) scan memory that is allocated.

But this can be gained by something like typeid(T).

So you should be able to remove the argument if its not used by anything 
if you are templating on the type.

auto blkInf = GC.qalloc(size, flags, typeid(Type));

https://github.com/dlang/druntime/blob/9d99b1ccd90d1e66c31e27cc71b8a266612aa14a/src/rt/lifetime.d#L1116
Jan 17 2022
prev sibling next sibling parent reply max haughton <maxhaton gmail.com> writes:
On Monday, 17 January 2022 at 15:26:46 UTC, Teodor Dutu wrote:
 Hi,

 In order to allocate a `struct` type, two DRuntime hooks are 
 used: `_d_newitemT` for uninitialised structs and 
 `_d_newitemiT` for initialised ones. Both hooks call 
 `_d_newitemU`, which allocates memory for the struct and 
 [writes the struct’s 
 `TypeInfo`](https://github.com/dlang/druntime/blob/9d99b1ccd90d1e66c31e27cc71b8a266612aa14a/src/
t/lifetime.d#L1122) at the end of the allocated chunk.

 We now attempt to convert these hooks to templates, with the 
 goal of not using `TypeInfo` at all. However, the fact that the 
 ABI of a struct contains its `TypeInfo` prevents us from 
 achieving this goal. Is this `TypeInfo` object still necessary 
 for anything, or are we free to remove it from the ABI 
 altogether so that we have cleaner implementations for 
 `_d_newitem{U,iT,T}`?

 Thanks,
 Teodor
What do you mean by ABI here? This sounds like a detail of how the GC allocates memory rather than the ABI strictly - it's certainly not specified under "struct" in the ABI document.
Jan 17 2022
parent reply Teodor Dutu <teodor.dutu gmail.com> writes:
On Monday, 17 January 2022 at 15:36:28 UTC, max haughton wrote:
 What do you mean by ABI here?
I simply meant that the TypeInfo object is written inside the struct object itself.
 This sounds like a detail of how the GC allocates memory rather 
 than the ABI strictly - it's certainly not specified under 
 "struct" in the ABI document.
I understand this now, but one of the goals of replacing the old druntime hooks with templates is using `TypeInfo` as little as possible. Therefore, the essence of my question is: Can we do `_d_newitemU` without `TypeInfo`, without negatively impacting the GC?
Jan 17 2022
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
On 18/01/2022 6:15 AM, Teodor Dutu wrote:
 Therefore, the essence of my question is: Can we do `_d_newitemU` 
 without `TypeInfo`, without negatively impacting the GC?
The need of TypeInfo is an implementation detail of the GC interface. Because you have the actual type, you can use typeid expression to get the TypeInfo class instance as you need it; this will be easy to swap out at a later point. What we need is for it to be removed from the logic of these hooks as well as their function arguments.
Jan 17 2022
prev sibling parent kinke <noone nowhere.com> writes:
On Monday, 17 January 2022 at 17:15:07 UTC, Teodor Dutu wrote:
 I simply meant that the TypeInfo object is written inside the 
 struct object itself.
That sounds definitely wrong. What's happening OTOH is that the GC needs a TypeInfo pointer at the end of each allocated block *if* the allocated struct needs to be destructed later on, when releasing a page. It's the only type info it has at that point, and the TypeInfo knows how to destruct its instances.
Jan 17 2022
prev sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Monday, 17 January 2022 at 15:26:46 UTC, Teodor Dutu wrote:
 Hi,

 In order to allocate a `struct` type, two DRuntime hooks are 
 used: `_d_newitemT` for uninitialised structs and 
 `_d_newitemiT` for initialised ones. Both hooks call 
 `_d_newitemU`, which allocates memory for the struct and 
 [writes the struct’s 
 `TypeInfo`](https://github.com/dlang/druntime/blob/9d99b1ccd90d1e66c31e27cc71b8a266612aa14a/src/
t/lifetime.d#L1122) at the end of the allocated chunk.

 We now attempt to convert these hooks to templates, with the 
 goal of not using `TypeInfo` at all. However, the fact that the 
 ABI of a struct contains its `TypeInfo` prevents us from 
 achieving this goal. Is this `TypeInfo` object still necessary 
 for anything, or are we free to remove it from the ABI 
 altogether so that we have cleaner implementations for 
 `_d_newitem{U,iT,T}`?

 Thanks,
 Teodor
That trailing info seems to be unused. TypeInfo is retrieved using `typeid`. So let's took a closer look at the code generated [for that](https://github.com/dlang/dmd/blob/e4d6fe8ee5af972125624230ded5a81e55b40711/src/dm /e2ir.d#L818-L838), in dmd.e2ir.d, which gives the best idea of the code executed by the program. For structs it's clear that the static type is *always* used and not that trailing stuff that's written passed the actual struct instance space. For structs that uses the code generated in the `if (Type t = isType(e.obj))` branch.
Jan 17 2022
parent Basile B. <b2.temp gmx.com> writes:
On Monday, 17 January 2022 at 18:29:51 UTC, Basile B. wrote:
 For structs it's clear that the static type is *always* used 
 and not that trailing stuff that's written passed the actual 
 struct instance space. For structs that uses the code generated 
 in the `if (Type t = isType(e.obj))` branch.
I tend to doubt, so this clears the [trailing stuff](https://run.dlang.io/is/xXMJHh) and that does not prevent to retrieve the TypeInfo.
Jan 17 2022