Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into EnableCountersInEve…
Browse files Browse the repository at this point in the history
…ntPipe
  • Loading branch information
LakshanF committed May 9, 2023
2 parents a6314a3 + 7fb53e8 commit 9c204cd
Show file tree
Hide file tree
Showing 1,353 changed files with 62,683 additions and 31,612 deletions.
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
]
},
"microsoft.dotnet.xharness.cli": {
"version": "1.0.0-prerelease.23212.1",
"version": "8.0.0-prerelease.23253.1",
"commands": [
"xharness"
]
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/04_ci_known_issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ body:
id: background
attributes:
label: Error Blob
description: Please identify a clear error string that can help identify future instances of this issue. For more information on how to fill this check https://github.com/dotnet/arcade/blob/main/Documentation/Projects/Build%20Analysis/KnownIssues.md#filling-out-known-issues-json-blob
description: Please identify a clear error string that can help identify future instances of this issue. For more information on how to fill this check our issue triage guidelines at [Failure Analysis](/dotnet/runtime/blob/main/docs/workflow/ci/failure-analysis.md#what-to-do-if-you-determine-the-failure-is-unrelated)
value: |
```json
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,4 @@ main PR <!-- Link to PR if any that fixed this in the main branch. -->

# Package authoring signed off?


IMPORTANT: If this change touches code that ships in a NuGet package, please make certain that you have added any necessary [package authoring](https://github.com/dotnet/runtime/blob/main/docs/project/library-servicing.md) and gotten it explicitly reviewed.
IMPORTANT: If this change touches code that ships in a NuGet package, please make certain that you have added any necessary [package authoring](../../docs/project/library-servicing.md) and gotten it explicitly reviewed.
4 changes: 3 additions & 1 deletion .github/workflows/check-service-labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ jobs:
check-labels:
runs-on: ubuntu-latest
steps:
- name: Check servicing labels
- name: Check 'Servicing-approved' label
run: |
echo "Merging permission is enabled for servicing PRs when the `Servicing-approved` label is applied."
if [ "${{ contains(github.event.pull_request.labels.*.name, 'Servicing-approved') }}" = "true" ]; then
exit 0
else
echo "::error:: 'Servicing-approved' label not applied to the PR yet. More information: https://github.com/dotnet/runtime/blob/main/docs/project/library-servicing.md#approval-process"
exit 1
fi
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ The best way to create a minimal reproduction is gradually removing code and dep

Project maintainers will merge changes that improve the product significantly.

The [Pull Request Guide](docs/pr-guide.md) and [Copyright](docs/project/copyright.md) docs define additional guidance.
The [Pull Request Guide](docs/workflow/ci/pr-guide.md) and [Copyright](docs/project/copyright.md) docs define additional guidance.

### DOs and DON'Ts

Expand Down Expand Up @@ -113,7 +113,7 @@ We use and recommend the following workflow:
- Make sure that the tests are all passing, including your new tests.
7. Create a pull request (PR) against the dotnet/runtime repository's **main** branch.
- State in the description what issue or improvement your change is addressing.
- Check if all the Continuous Integration checks are passing.
- Check if all the Continuous Integration checks are passing. Refer to [triaging failures in CI](docs/workflow/ci/failure-analysis.md) to check if any outstanding errors are known.
8. Wait for feedback or approval of your changes from the [area owners](docs/area-owners.md).
- Details about the pull request [review procedure](docs/pr-guide.md).
9. When area owners have signed off, and all checks are green, your PR will be merged.
Expand Down Expand Up @@ -165,9 +165,9 @@ The following file header is the used for files in this repo. Please use it for

### PR - CI Process

The [dotnet continuous integration](https://dev.azure.com/dnceng/public/) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean.
The [dotnet continuous integration](https://dev.azure.com/dnceng-public/public/_build) (CI) system will automatically perform the required builds and run tests (including the ones you are expected to run) for PRs. Builds and test runs must be clean or have bugs properly filed against flaky/unexpected failures that are unrelated to your change.

If the CI build fails for any reason, the PR issue will be updated with a link that can be used to determine the cause of the failure.
If the CI build fails for any reason, the PR issue will link to the `Azure DevOps` build with further information on the failure.

### PR Feedback

Expand Down
7 changes: 5 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@
<!-- Detect linux flavors using __PortableTargetOS from the native script. -->
<_portableOS Condition="'$(_portableOS)' == 'linux' and '$(__PortableTargetOS)' == 'linux-musl'">linux-musl</_portableOS>
<_portableOS Condition="'$(_portableOS)' == 'linux' and '$(__PortableTargetOS)' == 'linux-bionic'">linux-bionic</_portableOS>

<!-- On Windows, we can build for Windows and Mobile.
For other TargetOSes, create a "win" build, built from TargetOS sources and "win" pre-built packages. -->
<_portableOS Condition="'$(HostOS)' == 'win' and '$(TargetsMobile)' != 'true'">win</_portableOS>
</PropertyGroup>

<!-- PackageRID is used for packages needed for the target. -->
Expand All @@ -207,7 +211,7 @@

<!-- source-build sets PackageOS to build with non-portable rid packages that were source-built previously. -->
<PackageRID Condition="'$(PackageOS)' != ''">$(PackageOS)-$(TargetArchitecture)</PackageRID>
<PackageRID>$(_packageOS)-$(TargetArchitecture)</PackageRID>
<PackageRID Condition="'$(PackageRID)' == ''">$(_packageOS)-$(TargetArchitecture)</PackageRID>
</PropertyGroup>

<!-- ToolsRID is used for packages needed on the build host. -->
Expand Down Expand Up @@ -236,7 +240,6 @@
For non-portable builds, it uses __DistroRid (from the native build script), or falls back to RuntimeInformation.RuntimeIdentifier.
Source-build sets OutputRID directly. -->
<PropertyGroup Label="CalculateOutputRID">

<_hostRid Condition="'$(MSBuildRuntimeType)' == 'core'">$([System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier)</_hostRid>
<_hostRid Condition="'$(MSBuildRuntimeType)' != 'core'">win-$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant)</_hostRid>

Expand Down
2 changes: 1 addition & 1 deletion docs/area-owners.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Note: Editing this file doesn't update the mapping used by `@msftbot` for area-s
| area-System.Buffers | @jeffhandley | @dotnet/area-system-buffers | |
| area-System.CodeDom | @ericstj | @dotnet/area-system-codedom | |
| area-System.Collections | @jeffhandley | @dotnet/area-system-collections | Excluded:<ul><li>System.Array -> System.Runtime</li></ul> |
| area-System.ComponentModel | @ericstj | @dotnet/area-system-componentmodel | |
| area-System.ComponentModel | @ericstj | @dotnet/area-system-componentmodel | Consultants: @dotnet/dotnet-winforms |
| area-System.ComponentModel.Composition | @ericstj | @dotnet/area-system-componentmodel-composition | |
| area-System.ComponentModel.DataAnnotations | @jeffhandley | @dotnet/area-system-componentmodel-dataannotations | Included:<ul><li>System.ComponentModel.Annotations</li></ul> |
| area-System.Composition | @ericstj | @dotnet/area-system-composition | |
Expand Down
2 changes: 1 addition & 1 deletion docs/design/coreclr/botr/clr-abi.md
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ The extra state created by the JIT for synchronized methods (lock taken flag) mu

## Generics

EnC is not supported for generic methods and methods on generic types.
EnC is supported for adding and editing generic methods and methods on generic types and generic methods on non-generic types.

# System V x86_64 support

Expand Down
8 changes: 4 additions & 4 deletions docs/design/coreclr/botr/method-descriptor.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,10 @@ For example, it may be a bad idea to use the temporary entry point to call the m

The methods to get callable entry points from MethodDesc are:

- MethodDesc::GetSingleCallableAddrOfCode
- MethodDesc::GetMultiCallableAddrOfCode
- MethodDesc::GetSingleCallableAddrOfVirtualizedCode
- MethodDesc::GetMultiCallableAddrOfVirtualizedCode
- `MethodDesc::GetSingleCallableAddrOfCode`
- `MethodDesc::GetMultiCallableAddrOfCode`
- `MethodDesc::GetSingleCallableAddrOfVirtualizedCode`
- `MethodDesc::GetMultiCallableAddrOfVirtualizedCode`

Types of precode
----------------
Expand Down
2 changes: 2 additions & 0 deletions docs/design/coreclr/botr/readytorun-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,8 @@ enum ReadyToRunHelper
READYTORUN_HELPER_GenericNonGcTlsBase = 0x67,
READYTORUN_HELPER_VirtualFuncPtr = 0x68,
READYTORUN_HELPER_IsInstanceOfException = 0x69,
READYTORUN_HELPER_NewMaybeFrozenArray = 0x6A,
READYTORUN_HELPER_NewMaybeFrozenObject = 0x6B,

// Long mul/div/shift ops
READYTORUN_HELPER_LMul = 0xC0,
Expand Down
26 changes: 13 additions & 13 deletions docs/design/coreclr/botr/shared-generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Without shared generics, the code for instantiations like `Method<object>` or `M
ret
```

With shared generics, the canonical code will not have any hard-coded versions of the type handle of List<T>, but instead looks up the exact type handle either through a call to a runtime helper API, or by loading it up from the *generic dictionary* of the instantiation of Method<T> that is executing. The code would look more like the following:
With shared generics, the canonical code will not have any hard-coded versions of the type handle of `List<T>`, but instead looks up the exact type handle either through a call to a runtime helper API, or by loading it up from the *generic dictionary* of the instantiation of `Method<T>` that is executing. The code would look more like the following:
``` asm
mov rcx, generic context // MethodDesc of Method<string> or Method<object>
mov rcx, [rcx + offset of InstantiatedMethodDesc::m_pPerInstInfo] // This is the generic dictionary
Expand All @@ -34,9 +34,9 @@ With shared generics, the canonical code will not have any hard-coded versions o
ret
```

The generic context in this example is the InstantiatedMethodDesc of `Method<object>` or `Method<string>`. The generic dictionary is a data structure used by shared generic code to fetch instantiation-specific information. It is basically an array where the entries are instantiation-specific type handles, method handles, field handles, method entry points, etc... The "PerInstInfo" fields on MethodTable and InstantiatedMethodDesc structures point at the generic dictionary structure for a generic type and method respectively.
The generic context in this example is the `InstantiatedMethodDesc` of `Method<object>` or `Method<string>`. The generic dictionary is a data structure used by shared generic code to fetch instantiation-specific information. It is basically an array where the entries are instantiation-specific type handles, method handles, field handles, method entry points, etc... The "PerInstInfo" fields on MethodTable and `InstantiatedMethodDesc` structures point at the generic dictionary structure for a generic type and method respectively.

In this example, the generic dictionary for Method<object> will contain a slot with the type handle for type List<object>, and the generic dictionary for Method<string> will contain a slot with the type handle for type List<string>.
In this example, the generic dictionary for `Method<object>` will contain a slot with the type handle for type `List<object>`, and the generic dictionary for `Method<string>` will contain a slot with the type handle for type `List<string>`.

This feature is currently only supported for instantiations over reference types because they all have the same size/properties/layout/etc... For instantiations over primitive types or value types, the runtime will generate separate code bodies for each instantiation.

Expand Down Expand Up @@ -89,25 +89,25 @@ Note that `AnotherDerivedClass` doesn't have a dictionary of its own given that

### Dictionary Slots

As described earlier, a generic dictionary is an array of multiple slots containing instantiation-specific information. When a dictionary is initially allocated for a certain generic type or method, all of its slots are initialized to NULL, and are lazily populated on demand as code executes (see: `Dictionary::PopulateEntry(...)`).
As described earlier, a generic dictionary is an array of multiple slots containing instantiation-specific information. When a dictionary is initially allocated for a certain generic type or method, all of its slots are initialized to `NULL`, and are lazily populated on demand as code executes (see: `Dictionary::PopulateEntry(...)`).

The first N slots in an instantiation of N arguments are always going to be the type handles of the instantiation type arguments (this is kind of an optimization as well). The slots that follow contain instantiation-based information.

For instance, here is an example of the contents of the generic dictionary for our `Method<string>` example:

| `Method<string>'s dictionary` |
|--------------------------|
| slot[0]: TypeHandle(`string`) |
| slot[1]: Total dictionary size |
| slot[2]: TypeHandle(`List<string>`) |
| slot[3]: NULL (not used) |
| slot[4]: NULL (not used) |
| `slot[0]: TypeHandle(string)` |
| `slot[1]: Total dictionary size` |
| `slot[2]: TypeHandle(List<string>)` |
| `slot[3]: NULL (not used)` |
| `slot[4]: NULL (not used)` |

*Note: the size slot is never used by generic code, and is part of the dynamic dictionary expansion feature. More on that below.*

When this dictionary is first allocated, only slot[0] is initialized because it contains the instantiation type arguments (and of course the size slot is also initialized with the dictionary expansion feature), but the rest of the slots (example slot[2]) are NULL, and get lazily populated with values if we ever hit a code path that attempts to use them.
When this dictionary is first allocated, only `slot[0]` is initialized because it contains the instantiation type arguments (and of course the size slot is also initialized with the dictionary expansion feature), but the rest of the slots (for example, `slot[2]`) are `NULL`, and get lazily populated with values if we ever hit a code path that attempts to use them.

When loading information from a slot that is still NULL, the generic code will call one of these runtime helper functions to populate the dictionary slot with a value:
When loading information from a slot that is still `NULL`, the generic code will call one of these runtime helper functions to populate the dictionary slot with a value:
- `JIT_GenericHandleClass`: Used to lookup a value in a generic type dictionary. This helper is used by all instance methods on generic types.
- `JIT_GenericHandleMethod`: Used to lookup a value in a generic method dictionary. This helper used by all generic methods, or non-generic static methods on generic types.

Expand All @@ -117,9 +117,9 @@ When generating shared generic code, the JIT knows which slots to use for the va

The `DictionaryLayout` structure is what tells the JIT which slot to use when performing a dictionary lookup. This `DictionaryLayout` structure has a couple of important properties:
- It is shared across all compatible instantiations of a certain type of method. In other words, a dictionary layout is associated with the canonical instantiation of a type or a method. For instance, in our example above, `Method<object>` and `Method<string>` are compatible instantiations, each with their own **separate dictionaries**, however they all share the **same dictionary layout**, which is associated with the canonical instantiation `Method<__Canon>`.
- The dictionaries of generic types or methods have the same number of slots as their dictionary layouts. Note: historically before the introduction of the dynamic dictionary expansion feature, the generic dictionaries could be smaller than their layouts, meaning that for certain lookups, we had to use invoke some runtime helper APIs (slow path).
- The dictionaries of generic types or methods have the same number of slots as their dictionary layouts. Note: historically before the introduction of the dynamic dictionary expansion feature, the generic dictionaries could be smaller than their layouts, meaning that for certain lookups, we had to invoke some runtime helper APIs (slow path).

When a generic type or method is first created, its dictionary layout contains 'unassigned' slots. Assignments happen as part of code generation, whenever the JIT needs to emit a dictionary lookup sequence. This assignment happens during the calls to the `DictionaryLayout::FindToken(...)` APIs. Once a slot has been assigned, it becomes associated with a certain signature, which describes the kind of value that will go in every instantiated dictionary at that slot index.
When a generic type or method is first created, its dictionary layout contains 'unassigned' slots. Assignments happen as part of code generation, whenever the JIT needs to emit a dictionary lookup sequence. This assignment happens during calls to the `DictionaryLayout::FindToken(...)` APIs. Once a slot has been assigned, it becomes associated with a certain signature, which describes the kind of value that will go in every instantiated dictionary at that slot index.

Given an input signature, slot assignment is performed with the following algorithm:

Expand Down
Loading

0 comments on commit 9c204cd

Please sign in to comment.