Thread overview
Information about the 'magic' field in object.Object class
Jan 16, 2020
realhet
Jan 16, 2020
Adam D. Ruppe
Jan 16, 2020
realhet
Jan 16, 2020
kinke
January 16, 2020
Hello,
I'm try to figure out the contents od the base class instance in D, LDC Windows 64bit.
I'm sure that there is a 8 byte VMT pointer.
But unable to fund information about the remaining 8 byte. I guess it must be a unique 8byte (void* ?) identifier that is useful for Monitor. In a video someone mentioned this as 'magic'.

Is there a documentation about that 'magic' field? I'd love to use some bits in it if I'm sure about the consequences.

I have a really small object, only 32 bytes. At this point if I want to add a flag bit I have 3 choices:
- add a new field to the class -> effectively the instanceSize will grow by 50% (16bytes with alignment)
- compress the current 16bytes of data. -> eats more cpu
- Hide it somewhere 'magically'.

Thank You in advance!


January 16, 2020
On Thursday, 16 January 2020 at 14:30:04 UTC, realhet wrote:
> Is there a documentation about that 'magic' field?

I'm pretty sure the only fields in there are pointer to vtable and pointer to monitor object...

> I have a really small object, only 32 bytes. At this point if I want to add a flag bit I have 3 choices:

Do you need virtual functions? If not, you could probably just make a struct instead.
January 16, 2020
On Thursday, 16 January 2020 at 14:32:24 UTC, Adam D. Ruppe wrote:
> On Thursday, 16 January 2020 at 14:30:04 UTC, realhet wrote:
>> Is there a documentation about that 'magic' field?
>
> I'm pretty sure the only fields in there are pointer to vtable and pointer to monitor object...
>
>> I have a really small object, only 32 bytes. At this point if I want to add a flag bit I have 3 choices:
>
> Do you need virtual functions? If not, you could probably just make a struct instead.

Alternatively, the class can be marked as extern(C++).
January 16, 2020
On Thursday, 16 January 2020 at 14:32:24 UTC, Adam D. Ruppe wrote:
> On Thursday, 16 January 2020 at 14:30:04 UTC, realhet wrote:
>> Is there a documentation about that 'magic' field?
>
> I'm pretty sure the only fields in there are pointer to vtable and pointer to monitor object...
>
>> I have a really small object, only 32 bytes. At this point if I want to add a flag bit I have 3 choices:
>
> Do you need virtual functions? If not, you could probably just make a struct instead.

Thank you both for the hints!

Yes I need virtual functions (this is the base class of my layout system: it can be a letter, a picture, or a paragraph of text.).

I've tried extern(C++) and it went down 8 bytes.

But the I tried the following:
synchronized(obj){ ... }
Compiles without a problem. Hmm...

I think I will use extern(C++) and later when I will have a big system to test, I will benchmark it. I'm sure that Monitor functionality is not needed for these objects, so that extra 8 bytes will worth it.

Update:
- All of the child classes needed to be marked with extern(C++)
- static class members are not supported, only __gshared static.
- passing a delegate to a constructor of this class expects a (extern(C++) delegate) too.
- Internal compiler error: string[string] can not be mapped to C++

So extern(C++) is not good in the current case.

I will try to use that 8 byte magic illegally, and will see if it is unstable or not.
I will not do any synchronization, but I think the GC will crash upon releasing these objects.

Thx for the help!
January 16, 2020
On Thursday, 16 January 2020 at 15:28:06 UTC, realhet wrote:
> Update:
> - All of the child classes needed to be marked with extern(C++)
> - static class members are not supported, only __gshared static.
> - passing a delegate to a constructor of this class expects a (extern(C++) delegate) too.
> - Internal compiler error: string[string] can not be mapped to C++
>
> So extern(C++) is not good in the current case.

The 3 latter points can be trivially worked around via extern(D):

extern(C++) class C
{
    extern(D):
    static int tlsGlobal;
    this(void delegate()) {}
    void foo(string[string] aa) {}
}

void main()
{
    C.tlsGlobal = 123;
    auto c = new C(() {});
    c.foo(null);
}

> I will not do any synchronization, but I think the GC will crash upon releasing these objects.

Very likely.