mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-09 09:34:49 +09:00
[cdac] Begin adding MethodDesc APIs to the RuntimeTypeSystem contract (#104811)
This is largely a placeholder just to get the MethodDesc/MethodDescChunk infrastructure in place. To further fill out ValidateMethodDesc and to implement the GetMethodDescData DAC API, I also need to add an executable code manager contract for mapping between native code pointer values and methods. I'd like to do that as a separate PR. Debugged WinDbg enough to verify that GetMethodDescData is implemented enough to extract the correct MethodTable pointer value from a MethodDesc. * start GetMethodDescDataImpl * add MethodDesc and MethodDescChunk * checkpoint: MethodDesc validation * update contract * fix RuntimeTypeSystem unit tests mock the additional data and globals * fix GetMethodDescChunkPointerMayThrow * add data descriptor description to the contract * Apply suggestions from code review Co-authored-by: Elinor Fung <elfung@microsoft.com> * MayThrow -> Throwing * Slot is ushort not byte * remove unused property * add TargetPointer 32-/64-bit max constants * use NewArrayHolder * spelling * add globals to RTS contract * remove unused usings * constexpr cdac_offsets, not const * Apply suggestions from code review Co-authored-by: Elinor Fung <elfung@microsoft.com> * make GetNumVtableSlots private --------- Co-authored-by: Elinor Fung <elfung@microsoft.com>
This commit is contained in:
parent
b92fbf67be
commit
27086b7125
19 changed files with 522 additions and 19 deletions
|
@ -4,10 +4,11 @@ This contract is for exploring the properties of the runtime types of values on
|
|||
|
||||
## APIs of contract
|
||||
|
||||
### TypeHandle
|
||||
|
||||
A `TypeHandle` is the runtime representation of the type information about a value which is represented as a TypeHandle.
|
||||
Given a `TargetPointer` address, the `RuntimeTypeSystem` contract provides a `TypeHandle` for querying the details of the `TypeHandle`.
|
||||
|
||||
|
||||
``` csharp
|
||||
struct TypeHandle
|
||||
{
|
||||
|
@ -28,6 +29,8 @@ internal enum CorElementType
|
|||
A `TypeHandle` is the runtime representation of the type information about a value. This can be constructed from the address of a `TypeHandle` or a `MethodTable`.
|
||||
|
||||
``` csharp
|
||||
partial interface IRuntimeTypeSystem : IContract
|
||||
{
|
||||
#region TypeHandle inspection APIs
|
||||
public virtual TypeHandle GetTypeHandle(TargetPointer targetPointer);
|
||||
|
||||
|
@ -73,10 +76,35 @@ A `TypeHandle` is the runtime representation of the type information about a val
|
|||
public virtual bool IsFunctionPointer(TypeHandle typeHandle, out ReadOnlySpan<TypeHandle> retAndArgTypes, out byte callConv);
|
||||
|
||||
#endregion TypeHandle inspection APIs
|
||||
}
|
||||
```
|
||||
|
||||
### MethodDesc
|
||||
|
||||
A `MethodDesc` is the runtime representation of a managed method (either from IL, from reflection emit, or generated by the runtime).
|
||||
|
||||
```csharp
|
||||
struct MethodDescHandle
|
||||
{
|
||||
// no public properties or constructors
|
||||
|
||||
internal TargetPointer Address { get; }
|
||||
}
|
||||
```
|
||||
|
||||
```csharp
|
||||
partial interface IRuntimeTypeSystem : IContract
|
||||
{
|
||||
public virtual MethodDescHandle GetMethodDescHandle(TargetPointer methodDescPointer);
|
||||
|
||||
public virtual TargetPointer GetMethodTable(MethodDescHandle methodDesc);
|
||||
}
|
||||
```
|
||||
|
||||
## Version 1
|
||||
|
||||
### TypeHandle
|
||||
|
||||
The `MethodTable` inspection APIs are implemented in terms of the following flags on the runtime `MethodTable` structure:
|
||||
|
||||
``` csharp
|
||||
|
@ -233,7 +261,11 @@ static class RuntimeTypeSystem_1_Helpers
|
|||
}
|
||||
```
|
||||
|
||||
The contract depends on the global pointer value `FreeObjectMethodTablePointer`.
|
||||
The contract depends on the following globals
|
||||
|
||||
| Global name | Meaning |
|
||||
| --- | --- |
|
||||
| `FreeObjectMethodTablePointer` | A pointer to the address of a `MethodTable` used by the GC to indicate reclaimed memory
|
||||
|
||||
The contract additionally depends on these data descriptors
|
||||
|
||||
|
@ -251,6 +283,7 @@ The contract additionally depends on these data descriptors
|
|||
| `EEClass` | `InternalCorElementType` | An InternalCorElementType uses the enum values of a CorElementType to indicate some of the information about the type of the type which uses the EEClass In particular, all reference types are CorElementType.Class, Enums are the element type of their underlying type and ValueTypes which can exactly be represented as an element type are represented as such, all other values types are represented as CorElementType.ValueType. |
|
||||
| `EEClass` | `MethodTable` | Pointer to the canonical MethodTable of this type |
|
||||
| `EEClass` | `NumMethods` | Count of methods attached to the EEClass |
|
||||
| `EEClass` | `NumNonVirtualSlots` | Count of non-virtual slots for the EEClass |
|
||||
| `EEClass` | `CorTypeAttr` | Various flags |
|
||||
| `ArrayClass` | `Rank` | Rank of the associated array MethodTable |
|
||||
| `TypeDesc` | `TypeAndFlags` | The lower 8 bits are the CorElementType of the `TypeDesc`, the upper 24 bits are reserved for flags |
|
||||
|
@ -523,3 +556,28 @@ The contract additionally depends on these data descriptors
|
|||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
### MethodDesc
|
||||
|
||||
The version 1 `MethodDesc` APIs depend on the `MethodDescAlignment` global and the `MethodDesc` and `MethodDescChunk` data descriptors.
|
||||
|
||||
| Global name | Meaning |
|
||||
| --- | --- |
|
||||
| `MethodDescAlignment` | `MethodDescChunk` trailing data is allocated in multiples of this constant. The size (in bytes) of each `MethodDesc` (or subclass) instance is a multiple of this constant.
|
||||
|
||||
|
||||
In the runtime a `MethodDesc` implicitly belongs to a single `MethodDescChunk` and some common data is shared between method descriptors that belong to the same chunk. A single method table
|
||||
will typically have multiple chunks. There are subkinds of MethodDescs at runtime of varying sizes (but the sizes must be mutliples of `MethodDescAlignment`) and each chunk contains method descriptors of the same size.
|
||||
|
||||
We depend on the following data descriptors:
|
||||
| Data Descriptor Name | Field | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `MethodDesc` | `ChunkIndex` | Offset of this `MethodDesc` relative to the end of its containing `MethodDescChunk` - in multiples of `MethodDescAlignment`
|
||||
| `MethodDesc` | `Slot` | The method's slot
|
||||
| `MethodDesc` | `Flags` | The method's flags
|
||||
| `MethodDescChunk` | `MethodTable` | The method table set of methods belongs to
|
||||
| `MethodDescChunk` | `Next` | The next chunk of methods
|
||||
| `MethodDescChunk` | `Size` | The size of this `MethodDescChunk` following this `MethodDescChunk` header, minus 1. In multiples of `MethodDescAlignment`
|
||||
| `MethodDescChunk` | `Count` | The number of `MethodDesc` entries in this chunk, minus 1.
|
||||
|
||||
**TODO(cdac)**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue