You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Return a handle to the active version of the native code for a given method descriptor and IL code version. The IL code version and method descriptor must represent the same method
### DacEnumerableHash (EETypeHashTable and InstMethodHashTable)
516
+
517
+
Both `EETypeHashTable` and `InstMethodHashTable` are based on the templated `DacEnumerableHash`. Because the base class is templated on the derived type, offsets may be different in derived types.
518
+
519
+
The base implementation of `DacEnumerableHash` uses four datadescriptors:
520
+
| Datadescriptor | Purpose |
521
+
| --- | --- |
522
+
|`Buckets`| Pointer to the bucket array |
523
+
|`Count`| Number of elements in the hash table |
524
+
|`VolatileEntryValue`| The data held by an entry, defined by the derived class |
525
+
|`VolatileEntryNextEntry`| The next pointer on an hash table entry |
526
+
527
+
The hash table is laid out as an array of `VolatileEntry` pointers's (buckets), each possibly forming a chain for values that hash into that bucket. The first three buckets are special and reserved for metadata. Instead of containing a `VolatileEntry`, these pointers are read as values with the following meanings.
528
+
529
+
| Reserved Bucket offset | Purpose |
530
+
| --- | --- |
531
+
|`0`| Length of the Bucket array, this value does not include the first 3 slots which are special |
532
+
|`1`| Pointer to the next bucket array, not currently used in the cDAC |
533
+
|`2`| End sentinel for the current bucket array, not currently used in the cDAC |
534
+
535
+
The current cDAC implementation does not use the 'hash' part of the table at all. Instead it iterates all elements in the table. Following the existing iteration logic in the runtime (and DAC), resizing the table while iterating is not supported. Given this constraint, the pointer to the next bucket array (resized data table) and the current end sentinel are not required to iterate all entries.
536
+
537
+
To read all entries in the hash table:
538
+
1. Read the length bucket to find the number of chains `n`.
539
+
2. Initialize a list of elements `entries = []`.
540
+
3. For each chain, (buckets with offsets `3..n + 3`):
541
+
1. Read the pointer in the bucket as `volatileEntryPtr`.
542
+
2. If `volatileEntryPtr & 0x1 == 0x1`, this is an end sentinel and we stop reading this chain.
543
+
3. Otherwise, add `volatileEntryPtr + /* VolatileEntryValue offset */` to entries. This points to the derived class defined data type.
544
+
4. Set `volatileEntryPtr` to the value of the pointer located at `volatileEntryPtr + /* VolatileEntryNextEntry offset */` and go to step 3.2.
545
+
4. Return `entries` to be further parsed by derived classes.
546
+
547
+
While both EETypeHashTable and InstMethodHashTable store pointer sized data types, they both use the LSBs as special flags.
548
+
549
+
#### EETypeHashTable
550
+
EETypeHashTable uses the LSB to indicate if the TypeHandle is a hot entry. The cDAC implementation separates each value `value` in the table into two parts. The actual TypeHandle pointer and the associated flags.
InstMethodHashTable uses the 2 LSBs as flags for the MethodDesc. The cDAC implementation separates each value `value` in the table into two parts. The actual MethodDesc pointer and the associated flags.
// The component size is only available for strings and arrays. It is the size of the element type of the array, or the size of an ECMA 335 character (2 bytes)
@@ -349,6 +351,7 @@ The contract additionally depends on these data descriptors
349
351
|`MethodTable`|`PerInstInfo`| Either the array element type, or pointer to generic information for `MethodTable`|
350
352
|`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. |
351
353
|`EEClass`|`MethodTable`| Pointer to the canonical MethodTable of this type |
354
+
|`EEClass`|`MethodDescChunk`| Pointer to the first MethodDescChunk of the EEClass |
352
355
|`EEClass`|`NumMethods`| Count of methods attached to the EEClass |
353
356
|`EEClass`|`NumNonVirtualSlots`| Count of non-virtual slots for the EEClass |
354
357
|`EEClass`|`CorTypeAttr`| Various flags |
@@ -645,6 +648,8 @@ The version 1 `MethodDesc` APIs depend on the following globals:
645
648
| --- | --- |
646
649
|`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. |
647
650
|`MethodDescTokenRemainderBitCount`| Number of bits in the token remainder in `MethodDesc`|
651
+
|`MethodDescSizeTable`| A pointer to the MethodDesc size table. The MethodDesc flags are used as an offset into this table to lookup the MethodDesc size. |
652
+
648
653
649
654
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
650
655
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.
@@ -684,6 +689,8 @@ The contract depends on the following other contracts
684
689
| Loader |
685
690
| PlatformMetadata |
686
691
| ReJIT |
692
+
| ExecutionManager |
693
+
| PrecodeStubs |
687
694
688
695
And the following enumeration definitions
689
696
@@ -710,6 +717,7 @@ And the following enumeration definitions
710
717
HasNonVtableSlot=0x0008,
711
718
HasMethodImpl=0x0010,
712
719
HasNativeCodeSlot=0x0020,
720
+
HasAsyncMethodData=0x0040,
713
721
// Mask for the above flags
714
722
MethodDescAdditionalPointersMask=0x0038,
715
723
#endredion Additional pointers
@@ -887,6 +895,23 @@ And the various apis are implemented with the following algorithms
0 commit comments