Thread overview
TypeInfo in struct ABI
Jan 17, 2022
Teodor Dutu
Jan 17, 2022
rikki cattermole
Jan 17, 2022
max haughton
Jan 17, 2022
Teodor Dutu
Jan 17, 2022
rikki cattermole
Jan 17, 2022
kinke
Jan 17, 2022
Basile B.
Jan 17, 2022
Basile B.
January 17, 2022

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 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

January 18, 2022
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
January 17, 2022

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 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.

January 17, 2022

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?

January 18, 2022
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.
January 17, 2022

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 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, 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.

January 17, 2022

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 and that does not prevent to retrieve the TypeInfo.

January 17, 2022

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.