Skip to content

Commit 9efa0b9

Browse files
committed
Merge branch 'main' of github.com:dotnet/runtime into reject-non-zero
2 parents d7f8179 + 4399da8 commit 9efa0b9

File tree

934 files changed

+28695
-12938
lines changed

Some content is hidden

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

934 files changed

+28695
-12938
lines changed

docs/coding-guidelines/api-guidelines/nullability.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ However, for existing virtual APIs that do not have any such strong guarantee do
6767
4. How common is it in the case of (3) for such invocations to then dereference the result rather than passing it off to something else that accepts a `T?`?
6868

6969
`Object.ToString` is arguably the most extreme case. Answering the above questions:
70-
1. It is fairly easy in any reasonably-sized code base to find cases, intentional or otherwise, where `ToString` returns `null` in some cases (we've found examples in dotnet/corefx, dotnet/roslyn, NuGet/NuGet.Client, dotnet/aspnetcore, and so on). One of the most prevalent conditions for this are types that just return the value in a string field which may contain its default value of `null`, and in particular for structs where a ctor may not have even had a chance to run and validate an input. Guidance in the docs suggests that `ToString` shouldn't return `null` or `string.Empty`, but even the docs don't follow its own guidance.
70+
1. It is fairly easy in any reasonably-sized code base to find cases, intentional or otherwise, where `ToString` returns `null` in some cases (we've found examples in dotnet/runtime, dotnet/roslyn, NuGet/NuGet.Client, dotnet/aspnetcore, and so on). One of the most prevalent conditions for this are types that just return the value in a string field which may contain its default value of `null`, and in particular for structs where a ctor may not have even had a chance to run and validate an input. Guidance in the docs suggests that `ToString` shouldn't return `null` or `string.Empty`, but even the docs don't follow its own guidance.
7171
2. Thousands upon thousands of types we don't control override this method today.
7272
3. It's common for helper routines to invoke via the base `object.ToString`, but many `ToString` uses are actually on derived types. This is particularly true when working in a code base that both defines a type and consumes its `ToString`.
7373
4. Based on examination of several large code bases, we believe it to be relatively rare that the result of an `Object.ToString` call (made on the base) to be directly dereferenced. It's much more common to pass it to another method that accepts `string?`, such as `String.Concat`, `String.Format`, `Console.WriteLine`, logging utilities, and so on. And while we advocate that `ToString` results shouldn't be assumed to be in a particular machine-readable format and parsed, it's certainly the case that code bases do, such as using `Substring` on the result, but in such cases, the caller needs to understand the format of what's being rendered, which generally means they're working with a derived type rather than calling through the base `Object.ToString`.

docs/design/coreclr/jit/JitOptimizerTodoAssessment.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ the code quality improvements, though most have issues associated with them.
4949
We may well be able to find some additional benchmarks or real-world-code with some looking,
5050
though it may be the case that current performance-sensitive code avoids structs.
5151

52-
There's also work going on in corefx to use `Span<T>` more broadly. We should
52+
There's also work going on to use `Span<T>` more broadly. We should
5353
make sure we are expanding our span benchmarks appropriately to track and
5454
respond to any particular issues that come out of that work.
5555

docs/design/coreclr/jit/object-stack-allocation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ with version reseliency.
8383
**Pros:**
8484
* ILLInk can afford to spend more time for escape analysis.
8585
* For self-contained apps, ILLink has access to all of application's code and can do full interprocedural analysis.
86-
* ILLink is already a part of System.Private.CoreLib and CoreFX build toolchain so the assemblies built there can benefit
86+
* ILLink is already a part of System.Private.CoreLib and core libraries build toolchain so the assemblies built there can benefit
8787
from this.
8888

8989
**Cons:**
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Contract Object
2+
3+
This contract is for getting information about well-known managed objects
4+
5+
## APIs of contract
6+
7+
``` csharp
8+
// Get the method table address for the object
9+
TargetPointer GetMethodTableAddress(TargetPointer address);
10+
11+
// Get the string corresponding to a managed string object. Error if address does not represent a string.
12+
string GetStringValue(TargetPointer address);
13+
```
14+
15+
## Version 1
16+
17+
Data descriptors used:
18+
| Data Descriptor Name | Field | Meaning |
19+
| --- | --- | --- |
20+
| `Object` | `m_pMethTab` | Method table for the object |
21+
| `String` | `m_FirstChar` | First character of the string - `m_StringLength` can be used to read the full string (encoded in UTF-16) |
22+
| `String` | `m_StringLength` | Length of the string in characters (encoded in UTF-16) |
23+
24+
Global variables used:
25+
| Global Name | Type | Purpose |
26+
| --- | --- | --- |
27+
| `ObjectToMethodTableUnmask` | uint8 | Bits to clear for converting to a method table address |
28+
| `StringMethodTable` | TargetPointer | The method table for System.String |
29+
30+
``` csharp
31+
TargetPointer GetMethodTableAddress(TargetPointer address)
32+
{
33+
TargetPointer mt = _targetPointer.ReadPointer(address + /* Object::m_pMethTab offset */);
34+
return mt.Value & ~target.ReadGlobal<byte>("ObjectToMethodTableUnmask");
35+
}
36+
37+
string GetStringValue(TargetPointer address)
38+
{
39+
TargetPointer mt = GetMethodTableAddress(address);
40+
TargetPointer stringMethodTable = target.ReadPointer(target.ReadGlobalPointer("StringMethodTable"));
41+
if (mt != stringMethodTable)
42+
throw new ArgumentException("Address does not represent a string object", nameof(address));
43+
44+
// Validates the method table
45+
_ = target.Contracts.RuntimeTypeSystem.GetTypeHandle(mt);
46+
47+
Data.String str = _target.ProcessedData.GetOrAdd<Data.String>(address);
48+
uint length = target.Read<uint>(address + /* String::m_StringLength offset */);
49+
Span<byte> span = stackalloc byte[(int)length * sizeof(char)];
50+
target.ReadBuffer(address + /* String::m_FirstChar offset */, span);
51+
return new string(MemoryMarshal.Cast<byte, char>(span));
52+
}
53+
```

docs/design/datacontracts/RuntimeTypeSystem.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ This contract is for exploring the properties of the runtime types of values on
44

55
## APIs of contract
66

7+
### TypeHandle
8+
79
A `TypeHandle` is the runtime representation of the type information about a value which is represented as a TypeHandle.
810
Given a `TargetPointer` address, the `RuntimeTypeSystem` contract provides a `TypeHandle` for querying the details of the `TypeHandle`.
911

10-
1112
``` csharp
1213
struct TypeHandle
1314
{
@@ -28,6 +29,8 @@ internal enum CorElementType
2829
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`.
2930

3031
``` csharp
32+
partial interface IRuntimeTypeSystem : IContract
33+
{
3134
#region TypeHandle inspection APIs
3235
public virtual TypeHandle GetTypeHandle(TargetPointer targetPointer);
3336

@@ -73,10 +76,35 @@ A `TypeHandle` is the runtime representation of the type information about a val
7376
public virtual bool IsFunctionPointer(TypeHandle typeHandle, out ReadOnlySpan<TypeHandle> retAndArgTypes, out byte callConv);
7477

7578
#endregion TypeHandle inspection APIs
79+
}
80+
```
81+
82+
### MethodDesc
83+
84+
A `MethodDesc` is the runtime representation of a managed method (either from IL, from reflection emit, or generated by the runtime).
85+
86+
```csharp
87+
struct MethodDescHandle
88+
{
89+
// no public properties or constructors
90+
91+
internal TargetPointer Address { get; }
92+
}
93+
```
94+
95+
```csharp
96+
partial interface IRuntimeTypeSystem : IContract
97+
{
98+
public virtual MethodDescHandle GetMethodDescHandle(TargetPointer methodDescPointer);
99+
100+
public virtual TargetPointer GetMethodTable(MethodDescHandle methodDesc);
101+
}
76102
```
77103

78104
## Version 1
79105

106+
### TypeHandle
107+
80108
The `MethodTable` inspection APIs are implemented in terms of the following flags on the runtime `MethodTable` structure:
81109

82110
``` csharp
@@ -233,7 +261,11 @@ static class RuntimeTypeSystem_1_Helpers
233261
}
234262
```
235263

236-
The contract depends on the global pointer value `FreeObjectMethodTablePointer`.
264+
The contract depends on the following globals
265+
266+
| Global name | Meaning |
267+
| --- | --- |
268+
| `FreeObjectMethodTablePointer` | A pointer to the address of a `MethodTable` used by the GC to indicate reclaimed memory
237269

238270
The contract additionally depends on these data descriptors
239271

@@ -251,6 +283,7 @@ The contract additionally depends on these data descriptors
251283
| `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. |
252284
| `EEClass` | `MethodTable` | Pointer to the canonical MethodTable of this type |
253285
| `EEClass` | `NumMethods` | Count of methods attached to the EEClass |
286+
| `EEClass` | `NumNonVirtualSlots` | Count of non-virtual slots for the EEClass |
254287
| `EEClass` | `CorTypeAttr` | Various flags |
255288
| `ArrayClass` | `Rank` | Rank of the associated array MethodTable |
256289
| `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
523556
return true;
524557
}
525558
```
559+
560+
### MethodDesc
561+
562+
The version 1 `MethodDesc` APIs depend on the `MethodDescAlignment` global and the `MethodDesc` and `MethodDescChunk` data descriptors.
563+
564+
| Global name | Meaning |
565+
| --- | --- |
566+
| `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.
567+
568+
569+
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
570+
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.
571+
572+
We depend on the following data descriptors:
573+
| Data Descriptor Name | Field | Meaning |
574+
| --- | --- | --- |
575+
| `MethodDesc` | `ChunkIndex` | Offset of this `MethodDesc` relative to the end of its containing `MethodDescChunk` - in multiples of `MethodDescAlignment`
576+
| `MethodDesc` | `Slot` | The method's slot
577+
| `MethodDesc` | `Flags` | The method's flags
578+
| `MethodDescChunk` | `MethodTable` | The method table set of methods belongs to
579+
| `MethodDescChunk` | `Next` | The next chunk of methods
580+
| `MethodDescChunk` | `Size` | The size of this `MethodDescChunk` following this `MethodDescChunk` header, minus 1. In multiples of `MethodDescAlignment`
581+
| `MethodDescChunk` | `Count` | The number of `MethodDesc` entries in this chunk, minus 1.
582+
583+
**TODO(cdac)**

docs/design/features/AssemblyLoadContext.ContextualReflection.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Using `pluginDependency` to determine the `AssemblyLoadContext` used for loading
2222
### Failing Scenarios
2323
#### Xunit story
2424

25-
We have been working on building a test harness in Xunit for running the CoreFX test suite inside `AssemblyLoadContext`s (each test case in its own context). This has proven to be somewhat difficult due to Xunit being a very reflection heavy codebase with tons of instances of types, assemblies, etc. being converted to strings and then fed through `Activator`. One of the main learnings is that it is not always obvious what will stay inside the “bounds” of an `AssemblyLoadContext` and what won’t. The basic rule of thumb is that any `Assembly.Load()` will result in the assembly being loaded onto the `AssemblyLoadContext` of the calling code, so if code loaded by an ALC calls `Assembly.Load(...)`, the resulting assembly will be within the “bounds” of the ALC. This unfortunately breaks down in some cases, specifically when code calls `Activator` which lives in `System.Private.CoreLib` which is always shared.
25+
We have been working on building a test harness in Xunit for running the core libraries test suite inside `AssemblyLoadContext`s (each test case in its own context). This has proven to be somewhat difficult due to Xunit being a very reflection heavy codebase with tons of instances of types, assemblies, etc. being converted to strings and then fed through `Activator`. One of the main learnings is that it is not always obvious what will stay inside the “bounds” of an `AssemblyLoadContext` and what won’t. The basic rule of thumb is that any `Assembly.Load()` will result in the assembly being loaded onto the `AssemblyLoadContext` of the calling code, so if code loaded by an ALC calls `Assembly.Load(...)`, the resulting assembly will be within the “bounds” of the ALC. This unfortunately breaks down in some cases, specifically when code calls `Activator` which lives in `System.Private.CoreLib` which is always shared.
2626

2727
#### System.Xaml
2828
This problem also manifests when using an `Object` deserialization framework which allows specifying assembly qualified type names.

docs/design/features/arm64-intrinsics.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,6 @@ To facilitate incremental progress, initial intrinsic API for a given `static cl
263263

264264
As intrinsic support is added test coverage must be extended to provide basic testing.
265265

266-
Tests should be added as soon as practical. CoreCLR Implementation and CoreFX API will need to be merged before tests
267-
can be merged.
268-
269266
## LSRA changes to allocate contiguous register ranges
270267

271268
Some ARM64 instructions will require allocation of contiguous blocks of registers. These are likely limited to load and

docs/design/features/host-error-codes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Note that the exit code returned by running an application via `dotnet.exe` or `
3131
| `LibHostInvalidArgs` | `0x80008092` | `-2147450734` | `146` | Arguments to `hostpolicy` are invalid. This is used in three unrelated places in the `hostpolicy`, but in all cases it means the component calling `hostpolicy` did something wrong: <ul><li> Command line arguments for the app - the failure would typically mean that wrong argument was passed or such. For example if the application main assembly is not specified on the command line. On its own this should not happen as `hostfxr` should have parsed and validated all command line arguments. </li><li> `hostpolicy` context's `get_delegate` - if the requested delegate enum value is not recognized. Again this would mean `hostfxr` passed the wrong value. </li><li> `corehost_resolve_component_dependencies` - if something went wrong initializing `hostpolicy` internal structures. Would happen for example when the `component_main_assembly_path` argument is wrong. </li></ul> |
3232
| `InvalidConfigFile` | `0x80008093` | `-2147450733` | `147` | The `.runtimeconfig.json` file is invalid. The reasons for this failure can be among these: <ul><li> Failure to read from the file </li><li> Invalid JSON </li><li> Invalid value for a property (for example number for property which requires a string) </li><li> Missing required property </li><li> Other inconsistencies (for example `rollForward` and `applyPatches` are not allowed to be specified in the same config file) </li><li> Any of the above failures reading the `.runtimecofig.dev.json` file </li><li> Self-contained `.runtimeconfig.json` used in `hostfxr_initialize_for_runtime_config`. Note that missing `.runtimconfig.json` is not an error (means self-contained app). This error code is also used when there is a problem reading the CLSID map file in `comhost`. </li></ul> |
3333
| `AppArgNotRunnable` | `0x80008094` | `-2147450732` | `148` | Used internally when the command line for `dotnet.exe` doesn't contain path to the application to run. In such case the command line is considered to be a CLI/SDK command. This error code should never be returned to external caller. |
34-
| `AppHostExeNotBoundFailure` | `0x80008095` | `-2147450731` | `149` | `apphost` failed to determine which application to run. This can mean: <ul><li> The `apphost` binary has not been imprinted with the path to the app to run (so freshly built `apphost.exe` from the branch will fail to run like this) </li><li> The `apphost` is a bundle (single-file exe) and it failed to extract correctly. </li></ul> |
34+
| `AppHostExeNotBoundFailure` | `0x80008095` | `-2147450731` | `149` | `apphost` failed to determine which application to run. This can mean: <ul><li> The `apphost` binary has not been imprinted with the path to the app to run (so freshly built `apphost.exe` from the branch will fail to run like this) </li><li> The `apphost` is a bundle (single-file exe) and it failed to extract correctly. </li><li>The `apphost` binary has been imprinted with invalid .NET search options</li></ul> |
3535
| `FrameworkMissingFailure` | `0x80008096` | `-2147450730` | `150` | It was not possible to find a compatible framework version. This originates in `hostfxr` (`resolve_framework_reference`) and means that the app specified a reference to a framework in its `.runtimeconfig.json` which could not be resolved. The failure to resolve can mean that no such framework is available on the disk, or that the available frameworks don't match the minimum version specified or that the roll forward options specified excluded all available frameworks. Typically this would be used if a 3.0 app is trying to run on a machine which has no 3.0 installed. It would also be used for example if a 32bit 3.0 app is running on a machine which has 3.0 installed but only for 64bit. |
3636
| `HostApiFailed` | `0x80008097` | `-2147450729` | `151` | Returned by `hostfxr_get_native_search_directories` if the `hostpolicy` could not calculate the `NATIVE_DLL_SEARCH_DIRECTORIES`. |
3737
| `HostApiBufferTooSmall` | `0x80008098` | `-2147450728` | `152` | Returned when the buffer specified to an API is not big enough to fit the requested value. Can be returned from: <ul><li> `hostfxr_get_runtime_properties` </li><li> `hostfxr_get_native_search_directories` </li><li> `get_hostfxr_path` </li></ul> |

docs/design/features/hw-intrinsics.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ There is a design document for the Arm64 intrinsics: https://github.com/dotnet/r
1010

1111
## Overview
1212

13-
The reference assemblies for the hardware intrinsics live in corefx, but all of the implementation is in the coreclr repo:
14-
15-
* The C# implementation lives in coreclr/System.Private.CoreLib/shared/System/Runtime/Intrinsics. These are little more than skeleton methods that are only compiled if needed for indirect invocation.
16-
17-
* Note that they are mirrored to other repositories, including corefx, corert and mono.
13+
* The C# implementation lives in src/libraries/System.Private.CoreLib/shared/System/Runtime/Intrinsics. These are little more than skeleton methods that are only compiled if needed for indirect invocation.
1814

1915
## C# Implementation
2016

docs/design/specs/Memory-model.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ void ThreadFunc1()
188188
}
189189

190190
// thread #2
191-
void ThreadFunc1()
191+
void ThreadFunc2()
192192
{
193193
while (true)
194194
{
@@ -197,7 +197,7 @@ void ThreadFunc1()
197197
}
198198

199199
// thread #3
200-
void ThreadFunc2()
200+
void ThreadFunc3()
201201
{
202202
MyClass localObj = obj;
203203
if (localObj != null)

0 commit comments

Comments
 (0)