Re[65]: MS забило на дотнет. Питону - да, сишарпу - нет?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 14.09.21 12:32
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, Serginio1, Вы писали:


S>>Выводы

S>>В ходе нашего маленького исследования были получены следующие выводы:
S>>TypeHandle является указателем либо на MethodTable, либо на TypeDesc (зависит от типа объекта)

V>И в любом случае первое поле объекта указывает на typeinfo, который представлен объектом RuntimeType.


V>Т.е., оно выглядит так:

V>
V>class Object {
V>    private RuntimeType _type;

V>    public Type GetType() => _type;

V>    public virtual void ToString() = _type.ToString();

V>    ...
V>}

V>unsafe class RuntimeType {
V>    ...

V>    // по смещению 0x40 в AMDx64 ссылка на VMT (или TypeDesc)
V>    private IntPtr* _vmt;

V>    ...
V>}
V>


V>Соответственно, адрес, скажем, 4-й виртуальной ф-ии:

V>
V>IntPtr * funcAddr = obj->_type->_vmt[4];
V>


V>В плюсах путь короче:

V>
V>IntPtr * funcAddr = obj->_vmt[4];
V>


V>Еще что забавно, что для пущей эффективности в том лейауте было бы неплохо сделать указатель на VMT первым полем RuntimeType, но RuntimeType — это такой же Object, первое поле уже занято. ))


Ну вот Акиньшин то говорит, что так и сделано
Вся правда о TypeHandle в .NET

// A TypeHandle is the FUNDAMENTAL concept of type identity in the CLR.
// That is two types are equal if and only if their type handles
// are equal. A TypeHandle, is a pointer sized struture that encodes
// everything you need to know to figure out what kind of type you are
// actually dealing with.

// At the present time a TypeHandle can point at two possible things
//
// 1) A MethodTable (Intrinsics, Classes, Value Types and their instantiations)
// 2) A TypeDesc (all other cases: arrays, byrefs, pointer types, function pointers, generic type variables)
//
// or with IL stubs, a third thing:
//
// 3) A MethodTable for a native value type.
//
// MTs that satisfy IsSharedByReferenceArrayTypes are not
// valid TypeHandles: for example no allocated object will
// ever return such a type handle from Object::GetTypeHandle(), and
// these type handles should not be passed across the JIT Interface
// as CORINFO_CLASS_HANDLEs. However some code in the EE does create
// temporary TypeHandles out of these MTs, so we can't yet assert
// !IsSharedByReferenceArrayTypes() in the TypeHandle constructor.
Ага, значит TypeHandle может быть как указателем на MethodTable, так и указателем на TypeDesc, в зависимости от типа объекта. Для массивов он указывает на TypeDesc. Тип object[][] — это массив, элементами которого являются object[], для которых TypeHandle=TypeDesc. Эта информация объясняет наш пример, но всё ещё остаются некоторые вопросы. Например: а как же отличить, на что именно указывает TypeHandle? Поможет нам в этом дальнейшее изучение исходников CLI:

Всё зависит от второго бита в адресе: нулевое значение определяет MethodTable, а единичное — TypeDesc. Если мы работаем с шестнадцатеричными адресами, то можно легко определить вид TypeHandle по последней цифре:

и солнце б утром не вставало, когда бы не было меня
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.