| |
 | Posted by Ali Çehreli in reply to H. S. Teoh | Permalink Reply |
|
Ali Çehreli 
Posted in reply to H. S. Teoh
| On 1/4/23 10:48, H. S. Teoh wrote:
> Allocations are not necessarily consecutive; the GC may have its own
> strategy of allocation that doesn't follow a linear sequence.
That was one of my guesses. So, I put the objects into a 2-length static array but the difference was still 0x20. (?)
> Furthermore, GC-allocated blocks may be larger than the request size
> because there may be some extra management information stored in the
> block (but outside the pointer range returned).
Good point. I think the minimum size of a dynamically allocated memory of the current GC implementation is 32 bytes.
I've just realized that I was confusing myself by thinking the object pointer that cast(void*) produces was the first member's address. I was wrong: That is the address of the first of the two hidden members (the vtbl pointer and the monitor).
My current guess is, although it could be a void*, the alignment of the first of those hidden members is 16.
Now that I have a more correct understanding, the following program prints those hidden members. One of the examples shows the monitor of an object used with 'synchronized' is non-null.
import std.stdio, std.traits;
class MyClass {
char[1] c;
}
void main() {
writeln(" Size Alignment Type\n",
"=========================");
size_t size = __traits(classInstanceSize, MyClass);
size_t alignment = classInstanceAlignment!MyClass;
writefln("%4s%8s %s",size, alignment, MyClass.stringof);
// Apologies for using lower-cased variable names. :)
auto a = new MyClass();
auto b = new MyClass();
printObject!a;
printObject!b;
auto withMonitor = new MyClass();
synchronized (withMonitor) {
// This object's "hidden 1" (the monitor) will not be 'null'
printObject!withMonitor;
}
// This object's "hidden 0" (vtbl pointer) will be different:
class SubClass : MyClass {
}
auto sub = new SubClass();
printObject!sub;
}
void printObject(alias obj)() {
writeln("\n");
writeln("name : ", obj.stringof);
const addr = cast(void*)obj;
writeln("address : ", addr);
writeln("hidden 0 : ", hiddenValue(addr, 0));
writeln("hidden 1 : ", hiddenValue(addr, 1));
}
void* hiddenValue(const(void)* obj, size_t index) {
alias HiddenType = void*;
auto ptrToHiddens = cast(HiddenType[2]*)obj;
return (*ptrToHiddens)[index];
}
Here is the output:
Size Alignment Type
=========================
17 8 MyClass
name : a
address : 7F4009D48000
hidden 0 : 558A1E172520
hidden 1 : null
name : b
address : 7F4009D48020
hidden 0 : 558A1E172520
hidden 1 : null
name : withMonitor
address : 7F4009D48040
hidden 0 : 558A1E172520
hidden 1 : 558A20164B80 <-- non-null monitor
name : sub
address : 7F4009D48060
hidden 0 : 558A1E172630 <-- Different vtbl for sub-class
hidden 1 : null
Ali
|