Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
34c5058
Update skip_reason to clarify cancelled leg scenario (#127479)
Copilot Apr 30, 2026
a5ad3cf
Reduce thread count on 32-bit in GetTotalAllocatedBytes.TestAnotherTh…
Copilot Apr 30, 2026
86eee16
Change unique stack trace GC flag from 0xF to 0x10 (#127612)
jtschuster Apr 30, 2026
4f111f8
Implement XmlSerializer end element handling workaround and tests (#1…
StephenMolloy Apr 30, 2026
0fa45b3
Improve GCHeap::Promote debug validation (#127595)
jkotas Apr 30, 2026
550500a
[cDAC] Use locally-built crossgen2 for dump test debuggees (#127561)
max-charlamb Apr 30, 2026
c77572b
Fix Wasm ArgIterator SizeOfArgStack for methods with only hidden args…
davidwrighton Apr 30, 2026
3dd3c88
Remove corert#2785 BadImageFormatException workaround from ILCompiler…
Copilot Apr 30, 2026
e971c0a
Fix ChaCha20Poly1305 IsSupported test on Azure Linux 4
vcsjones Apr 30, 2026
9ef2b5e
[cDAC] Implement GetModuleSimpleName for cDAC (#127415)
barosiak Apr 30, 2026
013ca46
Split the xarch specific data from register.h into its own file to ma…
tannergooding May 1, 2026
84e5e27
[Wasm RyuJit] Use local's register type when loading it's value (#127…
AndyAyersMS May 1, 2026
0e1b3d9
Change commit message topic to 'container image digests' (#127614)
richlander May 1, 2026
6e51115
[cDAC] Stack walk GC reference scanning and bug fixes (1/5) (#127395)
max-charlamb May 1, 2026
6083571
WIP: RuntimeSignatureDecoder, centralized SignatureDecoder contract
May 1, 2026
c468dde
Align RuntimeSignatureDecoder with SRM and move GC decoding to StackWalk
May 1, 2026
112b4be
Address review feedback: split interface, drop dead code, require Met…
May 1, 2026
d5e314a
Capture Target in providers; document signature-based GC scanning
May 1, 2026
bfaf8af
Address PR review: handle StoredSigMethodDesc; cache GcSignatureTypeP…
May 1, 2026
d70e706
Resolve VAR/MVAR via instantiation; normalize enums to underlying pri…
May 1, 2026
ba37f41
Address PR review: visibility, dead state, doc fixes
May 1, 2026
b8179d0
Rename SignatureDecoder contract to Signature
May 1, 2026
e8f72c1
Address review feedback: data-first Signature.md + cross-ref tag
May 1, 2026
08ee9d5
address feedback
May 4, 2026
b696caf
remove all references to number of internal types
May 4, 2026
9872130
Handle array class contexts in GcSignatureTypeProvider
May 4, 2026
4eaf8ee
Use EcmaMetadataUtils for method token constants in GcScanner
May 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ def main():
# Mark pipelines with 0 test results as inconclusive
for name in zero_result_pipelines:
conn.execute(
"UPDATE pipelines SET result = 'inconclusive', skip_reason = 'Build failed but no test failures detected via Test Results API' WHERE name = ?",
"UPDATE pipelines SET result = 'inconclusive', skip_reason = 'Build failed but no test failures detected via Test Results API, e.g., due to a cancelled leg' WHERE name = ?",
(name,)
)
if zero_result_pipelines:
Expand Down
2 changes: 1 addition & 1 deletion docs/design/coreclr/jit/investigate-stress.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Enabling GC Hole Stress causes GCs to always occur in specific locations and tha
- **0x2** – GC on transitions to Preemptive GC.
- **0x4** – GC on every allowable JITed instr.
- **0x8** – GC on every allowable R2R instr.
- **0xF** – GC only on a unique stack trace.
- **0x10** – GC only on a unique stack trace.

### Common combinations

Expand Down
21 changes: 21 additions & 0 deletions docs/design/datacontracts/ExecutionManager.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ struct CodeBlockHandle
bool IsFunclet(CodeBlockHandle codeInfoHandle);
// Returns true if the code block is specifically a filter funclet
bool IsFilterFunclet(CodeBlockHandle codeInfoHandle);

// Finds the ReadyToRun module that contains the given address.
TargetPointer FindReadyToRunModule(TargetPointer address);
```

```csharp
Expand Down Expand Up @@ -501,6 +504,24 @@ After obtaining the clause array bounds, the common iteration logic classifies e

`IsFilterFunclet` first checks `IsFunclet`. If the code block is a funclet, it retrieves the EH clauses for the method and checks whether any filter clause's handler offset matches the funclet's relative offset. If a match is found, the funclet is a filter funclet.

### FindReadyToRunModule

`FindReadyToRunModule` locates the ReadyToRun module whose PE image contains the given address. Unlike `GetCodeBlockHandle` (which only matches code regions), this API matches against the full PE image range - including data sections such as import tables. This is used in GCRefMap resolution as it requires finding the module that owns an import section indirection address, which is in the data section rather than the code section.

```csharp
TargetPointer IExecutionManager.FindReadyToRunModule(TargetPointer address)
{
// Use the RangeSectionMap to find the RangeSection containing the address.
// ReadyToRun range sections cover the entire PE image (code + data),
// so this works for import section addresses used by GCRefMap lookup.
RangeSection range = RangeSection.Find(target, topRangeSectionMap, address);
if (range.Data is null)
return TargetPointer.Null;

return range.Data.R2RModule;
}
```

### EE JIT Manager and Code Heap Info

```csharp
Expand Down
270 changes: 260 additions & 10 deletions docs/design/datacontracts/GCInfo.md

Large diffs are not rendered by default.

9 changes: 3 additions & 6 deletions docs/design/datacontracts/Loader.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ IEnumerable<TargetPointer> GetInstantiatedMethods(ModuleHandle handle);
bool IsProbeExtensionResultValid(ModuleHandle handle);
ModuleFlags GetFlags(ModuleHandle handle);
bool IsReadyToRun(ModuleHandle handle);
bool TryGetSimpleName(ModuleHandle handle, out string simpleName);
string GetSimpleName(ModuleHandle handle);
string GetPath(ModuleHandle handle);
string GetFileName(ModuleHandle handle);
TargetPointer GetLoaderAllocator(ModuleHandle handle);
Expand Down Expand Up @@ -622,14 +622,11 @@ ModuleFlags GetFlags(ModuleHandle handle)
return GetFlags(target.Read<uint>(handle.Address + /* Module::Flags offset */));
}

bool TryGetSimpleName(ModuleHandle handle, out string simpleName)
string GetSimpleName(ModuleHandle handle)
{
TargetPointer simpleNameStart = target.ReadPointer(handle.Address + /* Module::SimpleName offset */);
if (simpleNameStart == TargetPointer.Null)
return false;
byte[] simpleNameBytes = // Read<byte> from target starting at simpleNameStart until null terminator
simpleName = // convert to string, throw on invalid UTF-8
return true;
return // convert to string, throw on invalid UTF-8
}

string GetPath(ModuleHandle handle)
Expand Down
60 changes: 60 additions & 0 deletions docs/design/datacontracts/RuntimeTypeSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,14 @@ partial interface IRuntimeTypeSystem : IContract
// Return true if a MethodDesc represents an IL stub with a special MethodDesc context arg
public virtual bool HasMDContextArg(MethodDescHandle);

// Return true if the method requires a hidden instantiation argument (generic context parameter).
// Corresponds to native MethodDesc::RequiresInstArg().
public virtual bool RequiresInstArg(MethodDescHandle methodDesc);

// Return true if the method uses the async calling convention.
// Corresponds to native MethodDesc::IsAsyncMethod().
public virtual bool IsAsyncMethod(MethodDescHandle methodDesc);

// Return true if a MethodDesc is in a collectible module
public virtual bool IsCollectibleMethod(MethodDescHandle methodDesc);

Expand Down Expand Up @@ -1150,6 +1158,7 @@ And the following enumeration definitions
HasMethodImpl = 0x0010,
HasNativeCodeSlot = 0x0020,
HasAsyncMethodData = 0x0040,
Static = 0x0080,
// Mask for the above flags
MethodDescAdditionalPointersMask = 0x0038,
#endredion Additional pointers
Expand Down Expand Up @@ -1600,6 +1609,57 @@ Determining if a method is an async thunk method:
}
```

Determining if a method requires a hidden instantiation argument (generic context parameter):

```csharp
public bool RequiresInstArg(MethodDescHandle methodDescHandle)
{
MethodDesc md = _methodDescs[methodDescHandle.Address];

// RequiresInstArg = IsSharedByGenericInstantiations && (HasMethodInstantiation || IsStatic || IsValueType || IsInterface)
if (!IsSharedByGenericInstantiations(md))
return false;

if (HasMethodInstantiation(md))
return true;

// md.IsStatic reads from MethodDescFlags.Static (0x0080)
if (md.IsStatic)
return true;

MethodTable mt = _methodTables[md.MethodTable];
return mt.Flags.IsInterface || mt.Flags.IsValueType;
}

private bool IsSharedByGenericInstantiations(MethodDesc md)
{
if (md.Classification == MethodClassification.Instantiated)
{
InstantiatedMethodDesc imd = AsInstantiatedMethodDesc(md);
if (imd.IsWrapperStubWithInstantiations)
return false;
if (/* Flags2 of InstantiatedMethodDesc has SharedMethodInstantiation set */)
return true;
}
MethodTable mt = _methodTables[md.MethodTable];
return mt.IsCanonMT && mt.Flags.HasInstantiation;
}
```

Determining if a method uses the async calling convention:

```csharp
public bool IsAsyncMethod(MethodDescHandle methodDescHandle)
{
MethodDesc md = _methodDescs[methodDescHandle.Address];
if (!md.HasAsyncMethodData)
return false;

Data.AsyncMethodData asyncData = // Read AsyncMethodData from the async method data optional slot
return ((AsyncMethodFlags)asyncData.Flags).HasFlag(AsyncMethodFlags.AsyncCall);
}
```

Determining if a method is a wrapper stub (unboxing or instantiating):

```csharp
Expand Down
71 changes: 71 additions & 0 deletions docs/design/datacontracts/Signature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Contract Signature

This contract describes the format of method, field, and local-variable signatures stored in target memory. Signatures use the ECMA-335 §II.23.2 format with CoreCLR-internal element types added by the runtime.

## Internal element types

The runtime extends the standard ECMA-335 element type encoding with values that may appear in signatures stored in target memory:

| Encoding | Value | Layout following the tag |
| --- | --- | --- |
| `ELEMENT_TYPE_INTERNAL` | `0x21` | a target-sized pointer to a runtime `TypeHandle` |
| `ELEMENT_TYPE_CMOD_INTERNAL` | `0x22` | one byte (`1` = required, `0` = optional), then a target-sized pointer to a runtime `TypeHandle` |

These tags are used in signatures generated internally by the runtime that are not persisted to a managed image. They are defined alongside the standard ECMA-335 element types in `src/coreclr/inc/corhdr.h`. Their literal values are part of this contract -- changing them is a breaking change.

## APIs of contract

```csharp
TypeHandle DecodeFieldSignature(BlobHandle blobHandle, ModuleHandle moduleHandle, TypeHandle ctx);
```

## Version 1

Data descriptors used:
| Data Descriptor Name | Field | Meaning |
| --- | --- | --- |
| _none_ | | |

Global variables used:
| Global Name | Type | Purpose |
| --- | --- | --- |
| _none_ | | |

Contracts used:
| Contract Name |
| --- |
| RuntimeTypeSystem |
| Loader |
| EcmaMetadata |

Constants:
| Constant Name | Meaning | Value |
| --- | --- | --- |
| `ELEMENT_TYPE_INTERNAL` | runtime-internal element type tag for an internal `TypeHandle` | `0x21` |
| `ELEMENT_TYPE_CMOD_INTERNAL` | runtime-internal element type tag for an internal modified type | `0x22` |

Decoding a signature follows the ECMA-335 §II.23.2 grammar. For all standard element types, decoding behaves identically to `System.Reflection.Metadata.SignatureDecoder<TType, TGenericContext>`. When the decoder encounters one of the runtime-internal tags above, it reads the target-sized pointer (and optional `required` byte for `ELEMENT_TYPE_CMOD_INTERNAL`) from the signature blob and resolves it to a runtime `TypeHandle`.

The decoder is implemented as `RuntimeSignatureDecoder<TType, TGenericContext>` -- a clone of SRM's `SignatureDecoder<TType, TGenericContext>` with added support for the runtime-internal element types. The clone takes an additional `Target` so internal-type pointers can be sized for the target architecture. Provider implementations implement `IRuntimeSignatureTypeProvider<TType, TGenericContext>` -- a superset of `System.Reflection.Metadata.ISignatureTypeProvider<TType, TGenericContext>` -- adding methods for the runtime-internal element types:

```csharp
TType GetInternalType(TargetPointer typeHandlePointer);
TType GetInternalModifiedType(TargetPointer typeHandlePointer, TType unmodifiedType, bool isRequired);
```

The contract's provider resolves these pointers through `RuntimeTypeSystem.GetTypeHandle`. Standard ECMA-335 element types resolve through `RuntimeTypeSystem.GetPrimitiveType` and `RuntimeTypeSystem.GetConstructedType`. Generic type parameters (`VAR`) and generic method parameters (`MVAR`) resolve via `RuntimeTypeSystem.GetInstantiation` and `RuntimeTypeSystem.GetGenericMethodInstantiation` respectively, using a `TypeHandle` (for generic types) or `MethodDescHandle` (for generic methods) generic context. `GetTypeFromDefinition` and `GetTypeFromReference` resolve tokens via the module's `TypeDefToMethodTableMap` / `TypeRefToMethodTableMap`; cross-module references and `GetTypeFromSpecification` are not currently implemented.

```csharp
TypeHandle ISignature.DecodeFieldSignature(BlobHandle blobHandle, ModuleHandle moduleHandle, TypeHandle ctx)
{
SignatureTypeProvider<TypeHandle> provider = new(_target, moduleHandle);
MetadataReader mdReader = _target.Contracts.EcmaMetadata.GetMetadata(moduleHandle)!;
BlobReader blobReader = mdReader.GetBlobReader(blobHandle);
RuntimeSignatureDecoder<TypeHandle, TypeHandle> decoder = new(provider, _target, mdReader, ctx);
return decoder.DecodeFieldSignature(ref blobReader);
}
```

### Other consumers

`RuntimeSignatureDecoder` is shared infrastructure within the cDAC. Other contracts construct their own decoder and provider directly when they need to decode method or local signatures rather than going through this contract. For example, the [StackWalk](./StackWalk.md) contract uses `RuntimeSignatureDecoder<GcTypeKind, GcSignatureContext>` with a GC-specific provider to classify method parameters during signature-based GC reference scanning.
70 changes: 0 additions & 70 deletions docs/design/datacontracts/SignatureDecoder.md

This file was deleted.

Loading