Skip to content

Commit 9388349

Browse files
committed
Merge remote-tracking branch 'dotnet/main' into mono-vectoras-3
2 parents d1f1b9f + 55747a5 commit 9388349

File tree

388 files changed

+16822
-6498
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

388 files changed

+16822
-6498
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
# Contract RuntimeTypeSystem
2+
3+
This contract is for exploring the properties of the runtime types of values on the managed heap or on the stack in a .NET process.
4+
5+
## APIs of contract
6+
7+
A `MethodTable` is the runtime representation of the type information about a value. Given a `TargetPointer` address, the `RuntimeTypeSystem` contract provides a `MethodTableHandle` for querying the `MethodTable`.
8+
9+
``` csharp
10+
struct MethodTableHandle
11+
{
12+
// no public properties or constructors
13+
14+
internal TargetPointer Address { get; }
15+
}
16+
```
17+
18+
``` csharp
19+
#region MethodTable inspection APIs
20+
public virtual MethodTableHandle GetMethodTableHandle(TargetPointer targetPointer);
21+
22+
public virtual TargetPointer GetModule(MethodTableHandle methodTable);
23+
// A canonical method table is either the MethodTable itself, or in the case of a generic instantiation, it is the
24+
// MethodTable of the prototypical instance.
25+
public virtual TargetPointer GetCanonicalMethodTable(MethodTableHandle methodTable);
26+
public virtual TargetPointer GetParentMethodTable(MethodTableHandle methodTable);
27+
28+
public virtual uint GetBaseSize(MethodTableHandle methodTable);
29+
// 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)
30+
public virtual uint GetComponentSize(MethodTableHandle methodTable);
31+
32+
// True if the MethodTable is the sentinel value associated with unallocated space in the managed heap
33+
public virtual bool IsFreeObjectMethodTable(MethodTableHandle methodTable);
34+
public virtual bool IsString(MethodTableHandle methodTable);
35+
// True if the MethodTable represents a type that contains managed references
36+
public virtual bool ContainsGCPointers(MethodTableHandle methodTable);
37+
public virtual bool IsDynamicStatics(MethodTableHandle methodTable);
38+
public virtual ushort GetNumMethods(MethodTableHandle methodTable);
39+
public virtual ushort GetNumInterfaces(MethodTableHandle methodTable);
40+
41+
// Returns an ECMA-335 TypeDef table token for this type, or for its generic type definition if it is a generic instantiation
42+
public virtual uint GetTypeDefToken(MethodTableHandle methodTable);
43+
// Returns the ECMA 335 TypeDef table Flags value (a bitmask of TypeAttributes) for this type,
44+
// or for its generic type definition if it is a generic instantiation
45+
public virtual uint GetTypeDefTypeAttributes(MethodTableHandle methodTable);
46+
#endregion MethodTable inspection APIs
47+
```
48+
49+
## Version 1
50+
51+
The `MethodTable` inspection APIs are implemented in terms of the following flags on the runtime `MethodTable` structure:
52+
53+
``` csharp
54+
internal partial struct RuntimeTypeSystem_1
55+
{
56+
// The lower 16-bits of the MTFlags field are used for these flags,
57+
// if WFLAGS_HIGH.HasComponentSize is unset
58+
[Flags]
59+
internal enum WFLAGS_LOW : uint
60+
{
61+
GenericsMask = 0x00000030,
62+
GenericsMask_NonGeneric = 0x00000000, // no instantiation
63+
64+
StringArrayValues = GenericsMask_NonGeneric,
65+
}
66+
67+
// Upper bits of MTFlags
68+
[Flags]
69+
internal enum WFLAGS_HIGH : uint
70+
{
71+
Category_Mask = 0x000F0000,
72+
Category_Array = 0x00080000,
73+
Category_Array_Mask = 0x000C0000,
74+
Category_Interface = 0x000C0000,
75+
ContainsGCPointers = 0x01000000,
76+
HasComponentSize = 0x80000000, // This is set if lower 16 bits is used for the component size,
77+
// otherwise the lower bits are used for WFLAGS_LOW
78+
}
79+
80+
[Flags]
81+
internal enum WFLAGS2_ENUM : uint
82+
{
83+
DynamicStatics = 0x0002,
84+
}
85+
86+
// Encapsulates the MethodTable flags v1 uses
87+
internal struct MethodTableFlags
88+
{
89+
public uint MTFlags { get; }
90+
public uint MTFlags2 { get; }
91+
public uint BaseSize { get; }
92+
93+
public WFLAGS_LOW GetFlag(WFLAGS_LOW mask) { ... /* mask & lower 16 bits of MTFlags */ }
94+
public WFLAGS_HIGH GetFlag(WFLAGS_HIGH mask) { ... /* mask & upper 16 bits of MTFlags */ }
95+
96+
public WFLAGS2_ENUM GetFlag(WFLAGS2_ENUM mask) { ... /* mask & MTFlags2*/ }
97+
98+
private bool TestFlagWithMask(WFLAGS_LOW mask, WFLAGS_LOW flag)
99+
{
100+
if (IsStringOrArray)
101+
{
102+
return (WFLAGS_LOW.StringArrayValues & mask) == flag;
103+
}
104+
else
105+
{
106+
return (FlagsLow & mask) == flag;
107+
}
108+
}
109+
110+
public ushort ComponentSizeBits => (ushort)(MTFlags & 0x0000ffff); // only meaningful if HasComponentSize is set
111+
112+
public bool HasComponentSize => GetFlag(WFLAGS_HIGH.HasComponentSize) != 0;
113+
public bool IsInterface => GetFlag(WFLAGS_HIGH.Category_Mask) == WFLAGS_HIGH.Category_Interface;
114+
public bool IsString => HasComponentSize && !IsArray && ComponentSizeBits == 2;
115+
public bool IsArray => GetFlag(WFLAGS_HIGH.Category_Array_Mask) == WFLAGS_HIGH.Category_Array;
116+
public bool IsStringOrArray => HasComponentSize;
117+
public ushort ComponentSize => HasComponentSize ? ComponentSizeBits : (ushort)0;
118+
public bool HasInstantiation => !TestFlagWithMask(WFLAGS_LOW.GenericsMask, WFLAGS_LOW.GenericsMask_NonGeneric);
119+
public bool ContainsGCPointers => GetFlag(WFLAGS_HIGH.ContainsGCPointers) != 0;
120+
public bool IsDynamicStatics => GetFlag(WFLAGS2_ENUM.DynamicStatics) != 0;
121+
}
122+
123+
[Flags]
124+
internal enum EEClassOrCanonMTBits
125+
{
126+
EEClass = 0,
127+
CanonMT = 1,
128+
Mask = 1,
129+
}
130+
}
131+
```
132+
133+
Internally the contract has a `MethodTable_1` struct that depends on the `MethodTable` data descriptor
134+
135+
```csharp
136+
internal struct MethodTable_1
137+
{
138+
internal RuntimeTypeSystem_1.MethodTableFlags Flags { get; }
139+
internal ushort NumInterfaces { get; }
140+
internal ushort NumVirtuals { get; }
141+
internal TargetPointer ParentMethodTable { get; }
142+
internal TargetPointer Module { get; }
143+
internal TargetPointer EEClassOrCanonMT { get; }
144+
internal MethodTable_1(Data.MethodTable data)
145+
{
146+
Flags = new RuntimeTypeSystem_1.MethodTableFlags
147+
{
148+
MTFlags = data.MTFlags,
149+
MTFlags2 = data.MTFlags2,
150+
BaseSize = data.BaseSize,
151+
};
152+
NumInterfaces = data.NumInterfaces;
153+
NumVirtuals = data.NumVirtuals;
154+
EEClassOrCanonMT = data.EEClassOrCanonMT;
155+
Module = data.Module;
156+
ParentMethodTable = data.ParentMethodTable;
157+
}
158+
}
159+
```
160+
161+
The contract depends on the global pointer value `FreeObjectMethodTablePointer`.
162+
The contract additionally depends on the `EEClass` data descriptor.
163+
164+
```csharp
165+
private readonly Dictionary<TargetPointer, MethodTable_1> _methodTables;
166+
167+
internal TargetPointer FreeObjectMethodTablePointer {get; }
168+
169+
public MethodTableHandle GetMethodTableHandle(TargetPointer methodTablePointer)
170+
{
171+
... // validate that methodTablePointer points to something that looks like a MethodTable.
172+
... // read Data.MethodTable from methodTablePointer.
173+
... // create a MethodTable_1 and add it to _methodTables.
174+
return MethodTableHandle { Address = methodTablePointer }
175+
}
176+
177+
internal static EEClassOrCanonMTBits GetEEClassOrCanonMTBits(TargetPointer eeClassOrCanonMTPtr)
178+
{
179+
return (EEClassOrCanonMTBits)(eeClassOrCanonMTPtr & (ulong)EEClassOrCanonMTBits.Mask);
180+
}
181+
182+
public uint GetBaseSize(MethodTableHandle methodTableHandle) => _methodTables[methodTableHandle.Address].Flags.BaseSize;
183+
184+
public uint GetComponentSize(MethodTableHandle methodTableHandle) => GetComponentSize(_methodTables[methodTableHandle.Address]);
185+
186+
private TargetPointer GetClassPointer(MethodTableHandle methodTableHandle)
187+
{
188+
... // if the MethodTable stores a pointer to the EEClass, return it
189+
// otherwise the MethodTable stores a pointer to the canonical MethodTable
190+
// in that case, return the canonical MethodTable's EEClass.
191+
// Canonical MethodTables always store an EEClass pointer.
192+
}
193+
194+
private Data.EEClass GetClassData(MethodTableHandle methodTableHandle)
195+
{
196+
TargetPointer eeClassPtr = GetClassPointer(methodTableHandle);
197+
... // read Data.EEClass data from eeClassPtr
198+
}
199+
200+
201+
public TargetPointer GetCanonicalMethodTable(MethodTableHandle methodTableHandle) => GetClassData(methodTableHandle).MethodTable;
202+
203+
public TargetPointer GetModule(MethodTableHandle methodTableHandle) => _methodTables[methodTableHandle.Address].Module;
204+
public TargetPointer GetParentMethodTable(MethodTableHandle methodTableHandle) => _methodTables[methodTableHandle.Address].ParentMethodTable;
205+
206+
public bool IsFreeObjectMethodTable(MethodTableHandle methodTableHandle) => FreeObjectMethodTablePointer == methodTableHandle.Address;
207+
208+
public bool IsString(MethodTableHandle methodTableHandle) => _methodTables[methodTableHandle.Address].Flags.IsString;
209+
public bool ContainsGCPointers(MethodTableHandle methodTableHandle) => _methodTables[methodTableHandle.Address].Flags.ContainsGCPointers;
210+
211+
public uint GetTypeDefToken(MethodTableHandle methodTableHandle)
212+
{
213+
MethodTable_1 methodTable = _methodTables[methodTableHandle.Address];
214+
return (uint)(methodTable.Flags.GetTypeDefRid() | ((int)TableIndex.TypeDef << 24));
215+
}
216+
217+
public ushort GetNumMethods(MethodTableHandle methodTableHandle) => GetClassData(methodTableHandle).NumMethods;
218+
219+
public ushort GetNumInterfaces(MethodTableHandle methodTableHandle) => _methodTables[methodTableHandle.Address].NumInterfaces;
220+
221+
public uint GetTypeDefTypeAttributes(MethodTableHandle methodTableHandle) => GetClassData(methodTableHandle).CorTypeAttr;
222+
223+
public bool IsDynamicStatics(MethodTableHandle methodTableHandle) => _methodTables[methodTableHandle.Address].Flags.IsDynamicStatics;
224+
```

docs/project/list-of-diagnostics.md

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ The PR that reveals the implementation of the `<IncludeInternalObsoleteAttribute
110110
| __`SYSLIB0053`__ | AesGcm should indicate the required tag size for encryption and decryption. Use a constructor that accepts the tag size. |
111111
| __`SYSLIB0054`__ | Thread.VolatileRead and Thread.VolatileWrite are obsolete. Use Volatile.Read or Volatile.Write respectively instead. |
112112
| __`SYSLIB0055`__ | The underlying hardware instruction does not perform a signed saturate narrowing operation, and it always returns an unsigned result. Use the unsigned overload instead. |
113+
| __`SYSLIB0057`__ | Loading certificate data through the constructor or Import is obsolete. Use X509CertificateLoader instead to load certificates. |
113114

114115
## Analyzer Warnings
115116

docs/workflow/ci/pr-guide.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Anyone with write access can merge a pull request manually when the following co
3030
* The PR has been approved by at least one reviewer and any other objections are addressed.
3131
* You can request another review from the original reviewer.
3232
* The PR successfully builds and passes all tests in the Continuous Integration (CI) system. In case of failures, refer to the [analyzing build failures](failure-analysis.md) doc.
33+
* The CI results are no more than 1 week old.
3334

3435
Typically, PRs are merged as one commit (squash merges). It creates a simpler history than a Merge Commit. "Special circumstances" are rare, and typically mean that there are a series of cleanly separated changes that will be too hard to understand if squashed together, or for some reason we want to preserve the ability to disect them.
3536

docs/workflow/requirements/linux-requirements.md

+9-17
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,15 @@ Minimum RAM required to build is 1GB. The build is known to fail on 512 MB VMs (
2222

2323
### Toolchain Setup
2424

25-
Install the following packages for the toolchain:
26-
27-
* CMake 3.20 or newer
28-
* llvm
29-
* lld
30-
* clang
31-
* build-essential
32-
* python-is-python3
33-
* curl
34-
* git
35-
* lldb
36-
* libicu-dev
37-
* liblttng-ust-dev
38-
* libssl-dev
39-
* libkrb5-dev
40-
* zlib1g-dev
41-
* ninja-build (optional, enables building native code with ninja instead of make)
25+
Install the packages listed in [debian-reqs.txt](/eng/debian-reqs.txt).
26+
27+
You can install all the above dependencies by running
28+
29+
```bash
30+
sudo ./eng/install-native-dependencies.sh
31+
```
32+
33+
### Community-supported environments
4234

4335
**NOTE**: If you have an Ubuntu version older than 22.04 LTS, or Debian version older than 12, don't install `cmake` using `apt` directly. Follow the note written down below.
4436

eng/DotNetBuild.props

+10
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@
8585
<InnerBuildArgs Condition="'$(SourceBuiltAssetManifestsDir)' != ''">$(InnerBuildArgs) /p:SourceBuiltAssetManifestsDir=$(SourceBuiltAssetManifestsDir)</InnerBuildArgs>
8686
<InnerBuildArgs Condition="'$(SourceBuiltSymbolsDir)' != ''">$(InnerBuildArgs) /p:SourceBuiltSymbolsDir=$(SourceBuiltSymbolsDir)</InnerBuildArgs>
8787
<InnerBuildArgs Condition="'$(GitHubRepositoryName)' != ''">$(InnerBuildArgs) /p:GitHubRepositoryName=$(GitHubRepositoryName)</InnerBuildArgs>
88+
89+
<!-- Handle system libraries -->
90+
<UseSystemLibs Condition="'$(UseSystemLibs)' != ''">+$(UseSystemLibs)+</UseSystemLibs>
91+
<InnerBuildArgs Condition="$(UseSystemLibs.Contains('+brotli+'))">$(InnerBuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_BROTLI=true</InnerBuildArgs>
92+
<InnerBuildArgs Condition="$(UseSystemLibs.Contains('+libunwind+'))">$(InnerBuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=true</InnerBuildArgs>
93+
<!-- TODO: llvm-libunwind -->
94+
<!-- TODO: LinuxTracepoints -->
95+
<InnerBuildArgs Condition="$(UseSystemLibs.Contains('+rapidjson+'))">$(InnerBuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_RAPIDJSON=true</InnerBuildArgs>
96+
<InnerBuildArgs Condition="$(UseSystemLibs.Contains('+zlib+'))">$(InnerBuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_ZLIB=true</InnerBuildArgs>
97+
8898
</PropertyGroup>
8999
</Target>
90100

eng/Subsets.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@
120120
<PropertyGroup>
121121
<!-- CLR NativeAot only builds in a subset of the matrix -->
122122
<_NativeAotSupportedOS Condition="'$(TargetOS)' == 'windows' or '$(TargetOS)' == 'linux' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'maccatalyst' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvossimulator' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'freebsd'">true</_NativeAotSupportedOS>
123-
<_NativeAotSupportedArch Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm' or ('$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'x86')">true</_NativeAotSupportedArch>
123+
<_NativeAotSupportedArch Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'loongarch64' or ('$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'x86')">true</_NativeAotSupportedArch>
124124
<NativeAotSupported Condition="'$(_NativeAotSupportedOS)' == 'true' and '$(_NativeAotSupportedArch)' == 'true'">true</NativeAotSupported>
125125
<UseNativeAotForComponents Condition="'$(NativeAotSupported)' == 'true' and '$(TargetOS)' == '$(HostOS)' and ('$(TargetOS)' != 'windows' or '$(TargetArchitecture)' != 'x86') and '$(TargetsLinuxBionic)' != 'true' and ('$(TargetsLinuxMusl)' != 'true' or '$(TargetArchitecture)' != 'arm')">true</UseNativeAotForComponents>
126126

eng/Version.Details.xml

+8-8
Original file line numberDiff line numberDiff line change
@@ -360,17 +360,17 @@
360360
<Uri>https://github.com/dotnet/runtime-assets</Uri>
361361
<Sha>ec2da34cd7e31a605d6f30f02021a8d76947c99d</Sha>
362362
</Dependency>
363-
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="4.11.0-3.24329.1">
363+
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="4.12.0-1.24355.3">
364364
<Uri>https://github.com/dotnet/roslyn</Uri>
365-
<Sha>92051d4c24bc13ff58232104a647910bf22cd105</Sha>
365+
<Sha>19b5e961ecb97b008106f1b646c077e0bffde4a7</Sha>
366366
</Dependency>
367-
<Dependency Name="Microsoft.CodeAnalysis" Version="4.11.0-3.24329.1">
367+
<Dependency Name="Microsoft.CodeAnalysis" Version="4.12.0-1.24355.3">
368368
<Uri>https://github.com/dotnet/roslyn</Uri>
369-
<Sha>92051d4c24bc13ff58232104a647910bf22cd105</Sha>
369+
<Sha>19b5e961ecb97b008106f1b646c077e0bffde4a7</Sha>
370370
</Dependency>
371-
<Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="4.11.0-3.24329.1">
371+
<Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="4.12.0-1.24355.3">
372372
<Uri>https://github.com/dotnet/roslyn</Uri>
373-
<Sha>92051d4c24bc13ff58232104a647910bf22cd105</Sha>
373+
<Sha>19b5e961ecb97b008106f1b646c077e0bffde4a7</Sha>
374374
</Dependency>
375375
<Dependency Name="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0-beta1.24324.1">
376376
<Uri>https://github.com/dotnet/roslyn-analyzers</Uri>
@@ -381,9 +381,9 @@
381381
<Sha>43709af7570da7140fb3e9a5237f55ffb24677e7</Sha>
382382
</Dependency>
383383
<!-- Intermediate is necessary for source build. -->
384-
<Dependency Name="Microsoft.SourceBuild.Intermediate.roslyn" Version="4.11.0-3.24329.1">
384+
<Dependency Name="Microsoft.SourceBuild.Intermediate.roslyn" Version="4.12.0-1.24355.3">
385385
<Uri>https://github.com/dotnet/roslyn</Uri>
386-
<Sha>92051d4c24bc13ff58232104a647910bf22cd105</Sha>
386+
<Sha>19b5e961ecb97b008106f1b646c077e0bffde4a7</Sha>
387387
<SourceBuild RepoName="roslyn" ManagedOnly="true" />
388388
</Dependency>
389389
<Dependency Name="Microsoft.DotNet.ApiCompat.Task" Version="9.0.100-preview.7.24323.5">

eng/Versions.props

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@
4242
Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure
4343
they do not break the local dev experience.
4444
-->
45-
<MicrosoftCodeAnalysisCSharpVersion>4.11.0-3.24329.1</MicrosoftCodeAnalysisCSharpVersion>
46-
<MicrosoftCodeAnalysisVersion>4.11.0-3.24329.1</MicrosoftCodeAnalysisVersion>
47-
<MicrosoftNetCompilersToolsetVersion>4.11.0-3.24329.1</MicrosoftNetCompilersToolsetVersion>
45+
<MicrosoftCodeAnalysisCSharpVersion>4.12.0-1.24355.3</MicrosoftCodeAnalysisCSharpVersion>
46+
<MicrosoftCodeAnalysisVersion>4.12.0-1.24355.3</MicrosoftCodeAnalysisVersion>
47+
<MicrosoftNetCompilersToolsetVersion>4.12.0-1.24355.3</MicrosoftNetCompilersToolsetVersion>
4848
</PropertyGroup>
4949
<!--
5050
For source generator support we need to target multiple versions of Roslyn in order to be able to run on older versions of Roslyn.

eng/debian-reqs.txt

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
build-essential
2+
clang
3+
cmake
4+
curl
5+
gettext
6+
git
7+
libicu-dev
8+
libkrb5-dev
9+
liblldb-dev
10+
liblttng-ust-dev
11+
libssl-dev
12+
libunwind8-dev
13+
lld
14+
lldb
15+
llvm
16+
locales
17+
ninja-build
18+
python-is-python3
19+
zlib1g-dev

0 commit comments

Comments
 (0)