diff --git a/.config/CredScanSuppressions.json b/.config/CredScanSuppressions.json
index da14baee20e321..984a86f68e69e6 100644
--- a/.config/CredScanSuppressions.json
+++ b/.config/CredScanSuppressions.json
@@ -1,49 +1,70 @@
{
- "tool": "Credential Scanner",
- "suppressions": [
- {
- "file": [
- "/eng/common/internal-feed-operations.ps1",
- "/eng/common/internal-feed-operations.sh",
- "/src/libraries/Common/src/Interop/Windows/WinHttp/Interop.winhttp_types.cs",
- "/src/libraries/Common/src/System/Security/Cryptography/EccSecurityTransforms.cs",
- "/src/libraries/Common/tests/System/Net/Configuration.Certificates.cs",
- "/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs",
- "/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs",
- "/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.DefaultProxyCredentials.cs",
- "/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Proxy.cs",
- "/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.ServerCertificates.cs",
- "/src/libraries/Common/tests/System/Net/Http/PostScenarioTest.cs",
- "/src/libraries/Common/tests/System/Net/Prerequisites/Deployment/setup_certificates.ps1",
- "/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs",
- "/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.LimitedPrivate.cs",
- "/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs",
- "/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs",
- "/src/libraries/System.Data.Common/tests/System/Data/Common/DbConnectionStringBuilderTest.cs",
- "/src/libraries/System.Diagnostics.Process/tests/ProcessStartInfoTests.cs",
- "/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/constants.cs",
- "/src/libraries/System.DirectoryServices.AccountManagement/tests/PrincipalTest.cs",
- "/src/libraries/System.DirectoryServices.AccountManagement/tests/UserPrincipalTest.cs",
- "/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs",
- "/src/libraries/System.Net.Http/tests/UnitTests/DigestAuthenticationTests.cs",
- "/src/libraries/System.Net.Http/tests/UnitTests/HttpEnvironmentProxyTest.cs",
- "/src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs",
- "/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs",
- "/src/libraries/System.Net.Requests/src/System/Net/FtpWebRequest.cs",
- "/src/libraries/System.Net.WebSockets.Client/tests/ConnectTest.cs",
- "/src/libraries/System.Private.Uri/tests/ExtendedFunctionalTests/UriRelativeResolutionTest.cs",
- "/src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderRefreshTest.cs",
- "/src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs",
- "/src/libraries/System.Private.Uri/tests/FunctionalTests/UriRelativeResolutionTest.cs",
- "/src/libraries/System.Runtime/tests/System/Uri.CreateStringTests.cs",
- "/src/libraries/System.Security.Cryptography.Algorithms/tests/Rfc2898Tests.cs",
- "/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12Documents.cs",
- "/src/libraries/System.Security.Cryptography.X509Certificates/tests/ExportTests.cs",
- "/src/libraries/System.Security.Cryptography.Xml/tests/EncryptedXmlTest.cs",
- "/src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs",
- "/src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs"
- ],
- "_justification": "Mostly test files. Other files contain harmless examples or constants."
- },
- ]
+ "tool": "Credential Scanner",
+ "suppressions": [
+ {
+ "_justification": "Unit test containing connection strings under the test.",
+ "file": [
+ "src/libraries/System.Data.Common/tests/System/Data/Common/DbConnectionStringBuilderTest.cs"
+ ]
+ },
+ {
+ "_justification": "Private key for testing purpose.",
+ "file": [
+ "src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyPemTests.cs",
+ "src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyPemTests.cs",
+ "src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs",
+ "src/libraries/System.Security.Cryptography.X509Certificates/tests/TestData.cs"
+ ],
+ "placeholder": [
+ "-----BEGIN PRIVATE KEY-----",
+ "-----BEGIN * PRIVATE KEY-----"
+ ]
+ },
+ {
+ "_justification": "Test credential for Uri testing",
+ "file": [
+ "src/libraries/System.Net.Http/tests/UnitTests/HttpEnvironmentProxyTest.cs",
+ "src/libraries/System.Private.Uri/tests/ExtendedFunctionalTests/UriRelativeResolutionTest.cs",
+ "src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderRefreshTest.cs",
+ "src/libraries/System.Private.Uri/tests/FunctionalTests/UriBuilderTests.cs",
+ "src/libraries/System.Private.Uri/tests/FunctionalTests/UriRelativeResolutionTest.cs",
+ "src/libraries/System.Runtime/tests/System/Uri.CreateStringTests.cs"
+ ],
+ "placeholder": [
+ "//*:;&$=123USERINFO@",
+ "//*:bar@",
+ "//*:bar1@",
+ "//*:password1@",
+ "//*:psw@",
+ "//*:userinfo2@"
+ ]
+ },
+ {
+ "_justification": "Generic test password.",
+ "file": [
+ "src/libraries/Common/tests/System/Net/Configuration.Certificates.cs",
+ "src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs",
+ "src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs",
+ "src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.DefaultProxyCredentials.cs",
+ "src/libraries/Common/tests/System/Net/Http/PostScenarioTest.cs",
+ "src/libraries/Common/tests/System/Net/Prerequisites/Deployment/setup_certificates.ps1",
+ "src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs",
+ "src/libraries/System.Net.Http/tests/UnitTests/DigestAuthenticationTests.cs",
+ "src/libraries/System.Net.Http/tests/UnitTests/HttpEnvironmentProxyTest.cs",
+ "src/libraries/System.Net.Mail/tests/Functional/SmtpClientTest.cs",
+ "src/libraries/System.Security.Cryptography.Xml/tests/SignedXmlTest.cs",
+ "src/libraries/System.Security.Cryptography.Xml/tests/TestHelpers.cs"
+ ],
+ "placeholder": [
+ "\"anotherpassword\"",
+ "\"bar\"",
+ "\"mono\"",
+ "\"password1\"",
+ "\"rightpassword\"",
+ "\"testcertificate\"",
+ "\"unused\"",
+ "\"wrongpassword\""
+ ]
+ }
+ ]
}
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 5199430949475a..d6009aca5b521f 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -15,7 +15,7 @@
]
},
"microsoft.dotnet.xharness.cli": {
- "version": "1.0.0-prerelease.20352.2",
+ "version": "1.0.0-prerelease.20403.2",
"commands": [
"xharness"
]
diff --git a/.editorconfig b/.editorconfig
index e8c010f6a2e157..9d03bd30636c9f 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -184,6 +184,10 @@ indent_size = 2
[*.{props,targets,config,nuspec}]
indent_size = 2
+# YAML config files
+[*.{yml,yaml}]
+indent_size = 2
+
# Shell scripts
[*.sh]
end_of_line = lf
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 3f2a376ee71129..e5a4552409f541 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -7,6 +7,12 @@
/src/libraries/System.Buffers/ @ahsonkhan
/src/libraries/System.Memory/ @ahsonkhan
+# CoreCLR Code Owners
+
+/src/coreclr/src/inc/corinfo.h @dotnet/jit-contrib
+/src/coreclr/src/inc/corjit.h @dotnet/jit-contrib
+/src/coreclr/src/jit/ @dotnet/jit-contrib
+
# Mono Code Owners
/src/mono @marek-safar
diff --git a/Build.proj b/Build.proj
index dc4a15ab5f413d..2041d3d4fcc1f3 100644
--- a/Build.proj
+++ b/Build.proj
@@ -1,5 +1,9 @@
+
+ BuildTargetFramework=$([MSBuild]::ValueOrDefault('$(BuildTargetFramework)', '$(NetCoreAppCurrent)'))
+
+
$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'installer.tasks'))
$([MSBuild]::NormalizePath('$(InstallerTasksOutputPath)', 'Debug', 'netstandard2.0', 'installer.tasks.dll'))
- $([MSBuild]::NormalizePath('$(InstallerTasksOutputPath)', 'Debug', 'net46', 'installer.tasks.dll'))
+ $([MSBuild]::NormalizePath('$(InstallerTasksOutputPath)', 'Debug', 'net461', 'installer.tasks.dll'))
$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'docs'))
$([MSBuild]::NormalizeDirectory('$(DocsDir)', 'manpages'))
diff --git a/docs/area-owners.md b/docs/area-owners.md
index e696729861dff8..210243387b0ce2 100644
--- a/docs/area-owners.md
+++ b/docs/area-owners.md
@@ -1,4 +1,10 @@
-If you need to tag folks on an issue or PR, you will generally want to tag the owners (not the lead)
+# Pull Requests Tagging
+
+If you need to tag folks on an issue or PR, you will generally want to tag the owners (not the lead) for [area](#areas) to which the change or issue is closest to. For areas which are large and can be operating system or architecture specific it's better to tag owners of [OS](#operating-systems) or [Architecture](#architectures).
+
+## Areas
+
+Note: Editing this file doesn't update the mapping used by the `@msftbot` issue notification bot to tag owners. Some area owners prefer not to get those notifications. To update those notifications, contact any one of `@danmosemsft`, `@jeffschw`, `@marek-safar`, `@ericstj`, or `@karelz`. If you're a community member interested in these notifications, you won't appear in this table but we can add you to notifications - just let us know.
| Area | Lead | Owners (area experts to tag in PR's and issues) | Description |
|------------------------------------------------|---------------|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -118,4 +124,21 @@ If you need to tag folks on an issue or PR, you will generally want to tag the o
| area-TypeSystem-coreclr | @mangod9 | @davidwrighton @MichalStrehovsky @janvorli @mangod9 | |
| area-UWP | @tommcdon | @jashook | UWP-specific issues including Microsoft.NETCore.UniversalWindowsPlatform and Microsoft.Net.UWPCoreRuntimeSdk |
| area-VM-coreclr | @mangod9 | @mangod9 | |
-| area-VM-meta-mono | @SamMonoRT | @lambdageek | |
+| area-VM-meta-mono | @SamMonoRT | @lambdageek @CoffeeFlux | |
+## Operating Systems
+
+| Operating System | Lead | Owners (area experts to tag in PR's and issues) | Description |
+|------------------|---------------|-----------------------------------------------------|--------------|
+| os-alpine | | | |
+| os-android | @steveisok | @akoeplinger | |
+| os-freebsd | | | |
+| os-mac-os-x | @steveisok | | |
+| os-ios | @steveisok | @vargaz | |
+| os-tvos | @steveisok | @vargaz | |
+
+## Architectures
+
+| Architecture | Lead | Owners (area experts to tag in PR's and issues) | Description |
+|-----------------|---------------|-----------------------------------------------------|--------------|
+| arch-wasm | @lewing | @lewing @BrzVlad | |
+
diff --git a/docs/coding-guidelines/api-guidelines/nullability.md b/docs/coding-guidelines/api-guidelines/nullability.md
index 8c029d01fccef7..62e0fe3958884a 100644
--- a/docs/coding-guidelines/api-guidelines/nullability.md
+++ b/docs/coding-guidelines/api-guidelines/nullability.md
@@ -99,6 +99,7 @@ The C# compiler respects a set of attributes that impact its flow analysis. We
- **DO** add `[NotNullIfNotNull(string)]` if nullable ref argument will be non-`null` upon exit, when an other argument passed evaluated to non-`null`, pass that argument name as string. Example: `public void Exchange([NotNullIfNotNull("value")] ref object? location, object? value);`.
- **DO** add `[return: NotNullIfNotNull(string)]` if a method would not return `null` in case an argument passed evaluated to non-`null`, pass that argument name as string. Example: `[return: NotNullIfNotNull("name")] public string? FormatName(string? name);`
- **DO** add `[MemberNotNull(string fieldName)]` to a helper method which initializes member field(s), passing in the field name. Example: `[MemberNotNull("_buffer")] private void InitializeBuffer()`. This will help to avoid spurious warnings at call sites that call the initialization method and then proceed to use the specified field. Note that there are two constructors to `MemberNotNull`; one that takes a single `string`, and one that takes a `params string[]`. When the number of fields initialized is small (e.g. <= 3), it's preferable to use multiple `[MemberNotNull(string)]` attributes on the method rather than one `[MemberNotNull(string, string, string, ...)]` attribute, as the latter is not CLS compliant and will likely require `#pragma warning disable` and `#pragma warning restore` around the line to suppress warnings.
+- **AVOID** using `[MaybeNull]`, not because it's problematic, but because there's almost always a better option, such as `T?` (as of this writing, in all of the dotnet/runtime there are only 7 occurrences of `[MaybeNull]`). One example of where it's applicable is `AsyncLocal.Value`; `[DisallowNull]` can't be used here, because `null` is valid if `T` is nullable, and `T?` shouldn't be used because `Value` shouldn't be set to `null` if `T` isn't nullable. Another is in the relatively rare case where a public or protected field is exposed, may begin life as null, but shouldn't be explicitly set to null.
## Code Review Guidance
diff --git a/docs/coding-guidelines/project-guidelines.md b/docs/coding-guidelines/project-guidelines.md
index 36a43555afff8e..afc05f4037b220 100644
--- a/docs/coding-guidelines/project-guidelines.md
+++ b/docs/coding-guidelines/project-guidelines.md
@@ -1,41 +1,33 @@
# Build Project Guidelines
-In order to work in dotnet/runtime repo you must first run build.cmd/sh from the root of the repo at least
-once before you can iterate and work on a given library project.
+In order to work in the dotnet/runtime repo you must first run build.cmd/sh from the root of the repo at least once before you can iterate and work on a given library project.
## Behind the scenes with build.cmd/sh
-- Setup tools (currently done in restore in build.cmd/sh)
+- Restore tools
- Restore external dependencies
- CoreCLR - Copy to `bin\runtime\$(BuildTargetFramework)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)`
- - Netstandard Library - Copy to `bin\ref\netstandard2.0`
- - NetFx targeting pack - Copy to `bin\ref\net472`
- Build targeting pack
- Build src\libraries\ref.proj which builds all references assembly projects. For reference assembly project information see [ref](#ref)
- Build product
- Build src\libraries\src.proj which builds all the source library projects. For source library project information see [src](#src).
-- Sign product
- - Build src\sign.proj
# Build Pivots
Below is a list of all the various options we pivot the project builds on:
-- **Target Frameworks:** NetFx (aka Desktop), netstandard (aka dotnet/Portable), NETCoreApp (aka .NET Core)
-- **Platform Runtimes:** NetFx (aka CLR/Desktop), CoreCLR, Mono
+- **Target Frameworks:** .NETFramework, .NETStandard, .NETCoreApp
+- **Platform Runtimes:** .NETFramework (aka CLR/Desktop), CoreCLR, Mono
- **OS:** Windows_NT, Linux, OSX, FreeBSD, AnyOS
- **Flavor:** Debug, Release
-- **Architecture:** x86, x64, arm, arm64, AnyCPU
## Individual build properties
The following are the properties associated with each build pivot
-- `$(BuildTargetFramework) -> netstandard2.1 | net5.0 | net472`
+- `$(BuildTargetFramework) -> Any .NETCoreApp or .NETFramework TFM, e.g. net5.0`
- `$(TargetOS) -> Windows | Linux | OSX | FreeBSD | [defaults to running OS when empty]`
- `$(Configuration) -> Release | [defaults to Debug when empty]`
- `$(TargetArchitecture) - x86 | x64 | arm | arm64 | [defaults to x64 when empty]`
- `$(RuntimeOS) - win7 | osx10.10 | ubuntu.14.04 | [any other RID OS+version] | [defaults to running OS when empty]` See [RIDs](https://github.com/dotnet/runtime/tree/master/src/libraries/pkg/Microsoft.NETCore.Platforms) for more info.
-For more information on various targets see also [.NET Standard](https://github.com/dotnet/standard/blob/master/docs/versions.md)
-
## Aggregate build properties
Each project will define a set of supported TargetFrameworks
@@ -60,21 +52,8 @@ Pure netstandard configuration:
All supported targets with unique windows/unix build for netcoreapp:
```
- $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;$(NetFrameworkCurrent)-Windows_NT
-
-```
-
-### Placeholder Target Frameworks
-Placeholder Target Framework can be added to the `` property to indicate the build system that the specific project is inbox in that framework and that Build Setting needs to be ignored.
-
-Placeholder target frameworks start with _ prefix.
-
-Example:
-When we have a project that has a `netstandard2.0` target framework that means that this project is compatible with any build setting. So if we do a vertical build for `net472` this project will be built as part of the vertical because `net472` is compatible with `netstandard2.0`. This means that in the runtime and testhost binaries the netstandard2.0 implementation will be included, and we will test against those assets instead of testing against the framework inbox asset. In order to tell the build system to not include this project as part of the `net472` vertical we need to add a placeholder target framework:
-```
+ $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix;net461-Windows_NT
- netstandard2.0;_net472
-
```
## Options for building
@@ -94,7 +73,7 @@ When building an individual project the `BuildTargetFramework` and `TargetOS` wi
## Supported full build settings
- .NET Core latest on current OS (default) -> `$(NetCoreAppCurrent)-[RunningOS]`
-- .NET Framework latest -> `$(NetFrameworkCurrent)-Windows_NT`
+- .NET Framework latest -> `net48-Windows_NT`
# Library project guidelines
@@ -152,44 +131,34 @@ Reference assemblies are required for any library that has more than one impleme
In the ref directory for the library there should be at most **one** `.csproj` that contains the latest API for the reference assembly for the library. That project can contain multiple entries in its `TargetFrameworks` property. Ref projects should use `` for its dependencies.
### ref output
-The output for the ref project build will be a flat targeting pack folder in the following directory:
+All ref outputs should be under
-`bin\ref\$(TargetFramework)`
-
-
//**CONSIDER**: Do we need a specific BuildTargetFramework version of TargetFramework for this output path to ensure all projects output to same targeting path?
+`bin\$(MSBuildProjectName)\ref\$(TargetFramework)`
## src
In the src directory for a library there should be only **one** `.csproj` file that contains any information necessary to build the library in various target frameworks. All supported target frameworks should be listed in the `TargetFrameworks` property.
-All libraries should use `` for all their project references. That will cause them to be resolved against a targeting pack (i.e. `bin\ref\net5.0` or `\bin\ref\netstandard2.0`) based on the project target framework. There should not be any direct project references to other libraries. The only exception to that rule right now is for partial facades which directly reference System.Private.CoreLib and thus need to directly reference other partial facades to avoid type conflicts.
-
//**CONSIDER**: just using Reference and use a reference to System.Private.CoreLib as a trigger to turn the other References into a ProjectReference automatically. That will allow us to have consistency where all projects just use Reference.
+All libraries should use `` for all their references to libraries that compose the shared framework of the current .NETCoreApp. That will cause them to be resolved against the locally built targeting pack which is located at `artifacts\bin\microsoft.netcore.app.ref`. The only exception to that rule right now is for partial facades which directly reference System.Private.CoreLib and thus need to directly reference other partial facades to avoid type conflicts.
-### src output
-The output for the src product build will be a flat runtime folder into the following directory:
+Other target frameworks than .NETCoreApp latest (i.e. `netstandard2.0`, `net461`, `netcoreapp3.0`) should use ProjectReference items to reference dependencies.
-`bin\runtime\$(BuildSettings)`
+### src output
+All src outputs are under
-Note: The `BuildSettings` is a global property and not the project setting because we need all projects to output to the same runtime directory no matter which compatible target framework we select and build the project with.
-```$(BuildTargetFramework)-$(TargetOS)-(Configuration)-(TargetArchitecture)```
+`bin\$(MSBuildProjectName)\$(TargetFramework)`
## pkg
In the pkg directory for the library there should be only **one** `.pkgproj` for the primary package for the library. If the library has platform-specific implementations those should be split into platform specific projects in a subfolder for each platform. (see [Package projects](./package-projects.md))
-TODO: Outline changes needed for pkgprojs
-
## tests
Similar to the src projects tests projects will define a `TargetFrameworks` property so they can list out the set of target frameworks they support.
-Tests should not have any `` or `` items in their project because they will automatically reference everything in the targeting pack based on the TargetFramework they are building in. The only exception to this is a `` can be used to reference other test helper libraries or assets.
-
-In order to build and run a test project in a given build target framework a root level build.cmd/sh must have been completed for that build target framework first. Tests will run on the live built runtime at `bin\runtime\$(BuildSettings)`.
-TODO: We need update our test host so that it can run from the shared runtime directory as well as resolve assemblies from the test output directory.
+Tests don't need to reference default references which are part of the targeting packs (i.e. `mscorlib` on .NETFramework or `System.Runtime` on .NETCoreApp). Everything on top of targeting packs should be referenced via ProjectReference items for live built assets.
### tests output
All test outputs should be under
-`bin\tests\$(MSBuildProjectName)\$(TargetFramework)` or
-`bin\tests\$(MSBuildProjectName)\netstandard2.0`
+`bin\$(MSBuildProjectName)\$(TargetFramework)`
## Facades
Facade are unique in that they don't have any code and instead are generated by finding a contract reference assembly with the matching identity and generating type forwards for all the types to where they live in the implementation assemblies (aka facade seeds). There are also partial facades which contain some type forwards as well as some code definitions. All the various build configurations should be contained in the one csproj file per library.
diff --git a/docs/design/coreclr/botr/xplat-minidump-generation.md b/docs/design/coreclr/botr/xplat-minidump-generation.md
index f0836ae5c2143b..16b506dbb313f2 100644
--- a/docs/design/coreclr/botr/xplat-minidump-generation.md
+++ b/docs/design/coreclr/botr/xplat-minidump-generation.md
@@ -1,6 +1,6 @@
# Introduction #
-Core dump generation on Linux and other non-Windows platforms has several challenges. Dumps can be very large and the default name/location of a dump is not consistent across all our supported platforms. The size of a full core dumps can be controlled somewhat with the "coredump_filter" file/flags but even with the smallest settings may be still too large and may not contain all the managed state needed for debugging. By default, some platforms use _core_ as the name and place the core dump in the current directory from where the program is launched; others add the _pid_ to the name. Configuring the core name and location requires superuser permission. Requiring superuser to make this consistent is not a satisfactory option.
+Dump generation on Windows, Linux and other non-Windows platforms has several challenges. Dumps can be very large and the default name/location of a dump is not consistent across all our supported platforms. The size of a full core dumps can be controlled somewhat with the "coredump_filter" file/flags but even with the smallest settings may be still too large and may not contain all the managed state needed for debugging. By default, some platforms use _core_ as the name and place the core dump in the current directory from where the program is launched; others add the _pid_ to the name. Configuring the core name and location requires superuser permission. Requiring superuser to make this consistent is not a satisfactory option.
Our goal is to generate core dumps that are on par with WER (Windows Error Reporting) crash dumps on any supported Linux platform. To the very least we want to enable the following:
- automatic generation of minimal size minidumps. The quality and quantity of the information contained in the dump should be on par with the information contained in a traditional Windows mini-dump.
@@ -12,7 +12,7 @@ Our solution at this time is to intercept any unhandled exception in the PAL lay
We looked at the existing technologies like Breakpad and its derivatives (e.g.: an internal MS version called _msbreakpad_ from the SQL team....). Breakpad generates Windows minidumps but they are not compatible with existing tools like Windbg, etc. Msbreakpad even more so. There is a minidump to Linux core conversion utility but it seems like a wasted extra step. _Breakpad_ does allow the minidump to be generated in-process inside the signal handlers. It restricts the APIs to what was allowed in a "async" signal handler (like SIGSEGV) and has a small subset of the C++ runtime that was also similarly constrained. We also need to add the set of memory regions for the "managed" state which requires loading and using the _DAC_'s (*) enumerate memory interfaces. Loading modules is not allowed in an async signal handler but forking/execve is allowed so launching an utility that loads the _DAC_, enumerates the list of memory regions and writes the dump is the only reasonable option. It would also allow uploading the dump to a server too.
-\* The _DAC_ is a special build of parts of the coreclr runtime that allows inspection of the runtime's managed state (stacks, variables, GC state heaps) out of context. One of the many interfaces it provides is [ICLRDataEnumMemoryRegions](https://github.com/dotnet/runtime/blob/master/src/coreclr/src/debug/daccess/dacimpl.h) which enumerates all the managed state a minidump would require to enable a fuitful debugging experience.
+\* The _DAC_ is a special build of parts of the coreclr runtime that allows inspection of the runtime's managed state (stacks, variables, GC state heaps) out of context. One of the many interfaces it provides is [ICLRDataEnumMemoryRegions](https://github.com/dotnet/runtime/blob/master/src/coreclr/src/debug/daccess/dacimpl.h) which enumerates all the managed state a minidump would require to enable a fruitful debugging experience.
_Breakpad_ could have still been used out of context in the generation utility but there seemed no value to their Windows-like minidump format when it would have to be converted to the native Linux core format away because in most scenarios using the platform tools like _lldb_ is necessary. It also adds a coreclr build dependency on Google's _Breakpad_ or SQL's _msbreakpad_ source repo. The only advantage is that the breakpad minidumps may be a little smaller because minidumps memory regions are byte granule and Linux core memory regions need to be page granule.
@@ -42,7 +42,11 @@ There will be some differences gathering the crash information but these platfor
### OS X ###
-Gathering the crash information on OS X will be quite a bit different than Linux and the core dump will be written in the Mach-O format instead of ELF. The OS X support currently has not been implemented.
+As of .NET Core 5.0, createdump is supported on MacOS but instead of the MachO dump format, it generates the ELF coredumps. This is because of time constraints developing a MachO dump writer on the generation side and a MachO reader for the diagnostics tooling side (dotnet-dump and CLRMD). This means the native debuggers like gdb and lldb will not work with these dumps but the dotnet-dump tool will allow the managed state to be analyzed. Because of this behavior an additional environment variable will need to be set (COMPlus_DbgEnableElfDumpOnMacOS=1) along with the ones below in the Configuration/Policy section.
+
+### Windows ###
+
+As of .NET Core 5.0, createdump and the below configuration environment variables are supported on Windows. It is implemented using the Windows MiniDumpWriteDump API. This allows consistent crash/unhandled exception dumps across all of our platforms.
# Configuration/Policy #
diff --git a/docs/project/library-servicing.md b/docs/project/library-servicing.md
index 29934d1606f1f5..3dc16895951d68 100644
--- a/docs/project/library-servicing.md
+++ b/docs/project/library-servicing.md
@@ -4,7 +4,7 @@ This document provides the steps necessary after modifying a CoreFx library in a
## Check for existence of a .pkgproj
-Most CoreFx libraries are not packaged by default. Some libraries have their output packaged in `Microsoft.Private.CoreFx.NetCoreApp`, which is always built, while other libraries have their own specific packages, which are only built on-demand. Your first step is to determine whether or not your library has its own package. To do this, go into the root folder for the library you've made changes to. If there is a `pkg` folder there (which should have a `.pkgproj` file inside of it), your library does have its own package. If there is no `pkg` folder there, the library should be built as part of `Microsoft.Private.CoreFx.NetCoreApp` and shipped as part of `Microsoft.NetCore.App`. To confirm this, check for the `IsNETCoreApp` property being set to `true` in the library's `Directory.Build.props` (or dir.props). If it is, then there is nothing that needs to be done. If it's not, contact a member of the servicing team for guidance, as this situation goes against our convention.
+Most libraries are not packaged by default. Some libraries have their output packaged in `Microsoft.Private.CoreFx.NetCoreApp`, which is always built, while other libraries have their own specific packages, which are only built on-demand. Your first step is to determine whether or not your library has its own package. To do this, go into the root folder for the library you've made changes to. If there is a `pkg` folder there (which should have a `.pkgproj` file inside of it), your library does have its own package. If there is no `pkg` folder there, the library should be built as part of `Microsoft.Private.CoreFx.NetCoreApp` and shipped as part of `Microsoft.NetCore.App`. To confirm this, check if the library is listed in NetCoreAppLibrary.props. If it is, then there is nothing that needs to be done. If it's not, contact a member of the servicing team for guidance, as this situation goes against our convention.
For example, if you made changes to [System.Data.SqlClient](https://github.com/dotnet/runtime/tree/master/src/libraries/Microsoft.Win32.Registry), then you have a .pkgproj, and will have to follow the steps in this document. However, if you made changes to [System.Collections](https://github.com/dotnet/runtime/tree/master/src/libraries/System.Collections), then you don't have a .pkgproj, and you do not need to do any further work for servicing.
diff --git a/docs/project/list-of-obsoletions.md b/docs/project/list-of-obsoletions.md
index 3b7d6696c62da6..35bae5551e4d11 100644
--- a/docs/project/list-of-obsoletions.md
+++ b/docs/project/list-of-obsoletions.md
@@ -24,3 +24,4 @@ Currently the identifiers `SYSLIB0001` through `SYSLIB0999` are carved out for o
| __`SYSLIB0009`__ | The AuthenticationManager Authenticate and PreAuthenticate methods are not supported and throw PlatformNotSupportedException. |
| __`SYSLIB0010`__ | This Remoting API is not supported and throws PlatformNotSupportedException. |
| __`SYSLIB0011`__ | `BinaryFormatter` serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for recommended alternatives. |
+| __`SYSLIB0012`__ | Use Location instead. |
diff --git a/docs/workflow/building/libraries/README.md b/docs/workflow/building/libraries/README.md
index 44eb0eb209eee1..ec0f52388e693a 100644
--- a/docs/workflow/building/libraries/README.md
+++ b/docs/workflow/building/libraries/README.md
@@ -9,7 +9,7 @@ Here is one example of a daily workflow for a developer working mainly on the li
git clean -xdf
git pull upstream master & git push origin master
:: Build Debug libraries on top of Release runtime:
-build -subset clr+libs -runtimeConfiguration Release
+build clr+libs -rc Release
:: The above you may only perform once in a day, or when you pull down significant new changes.
:: If you use Visual Studio, you might open System.Text.RegularExpressions.sln here.
@@ -33,7 +33,7 @@ The instructions for Linux and macOS are essentially the same:
git clean -xdf
git pull upstream master & git push origin master
# Build Debug libraries on top of Release runtime:
-./build.sh -subset clr+libs -runtimeconfiguration Release
+./build.sh clr+libs -rc Release
# The above you may only perform once in a day, or when you pull down significant new changes.
# Switch to working on a given library (RegularExpressions in this case)
@@ -56,12 +56,12 @@ These example commands will build a release CoreCLR (and CoreLib), debug librari
For Linux:
```bash
-./build.sh -runtimeConfiguration Release
+./build.sh -rc Release
```
For Windows:
```bat
-./build.cmd -runtimeConfiguration Release
+./build.cmd -rc Release
```
Detailed information about building and testing runtimes and the libraries is in the documents linked below.
@@ -74,7 +74,7 @@ The libraries build has two logical components, the native build which produces
The build settings (BuildTargetFramework, TargetOS, Configuration, Architecture) are generally defaulted based on where you are building (i.e. which OS or which architecture) but we have a few shortcuts for the individual properties that can be passed to the build scripts:
-- `-framework|-f` identifies the target framework for the build. Possible values include `net5.0` (currently the latest .NET version) or `net472`. (msbuild property `BuildTargetFramework`)
+- `-framework|-f` identifies the target framework for the build. Possible values include `net5.0` (currently the latest .NET version) or `net48` (the latest .NETFramework version). (msbuild property `BuildTargetFramework`)
- `-os` identifies the OS for the build. It defaults to the OS you are running on but possible values include `Windows_NT`, `Unix`, `Linux`, or `OSX`. (msbuild property `TargetOS`)
- `-configuration|-c Debug|Release` controls the optimization level the compilers use for the build. It defaults to `Debug`. (msbuild property `Configuration`)
- `-arch` identifies the architecture for the build. It defaults to `x64` but possible values include `x64`, `x86`, `arm`, or `arm64`. (msbuild property `TargetArchitecture`)
@@ -83,26 +83,20 @@ For more details on the build settings see [project-guidelines](../../../coding-
If you invoke the `build` script without any actions, the default action chain `-restore -build` is executed.
-By default the `build` script only builds the product libraries and none of the tests. If you want to include tests, you want to add the subset `-subset libtests`. If you want to run the tests you want to use the `-test` action instead of the `-build`, e.g. `build.cmd/sh -subset libs.tests -test`. To specify just the libraries, use `-subset libs`.
+By default the `build` script only builds the product libraries and none of the tests. If you want to include tests, you want to add the subset `libs.tests`. If you want to run the tests you want to use the `-test` action instead of the `-build`, e.g. `build.cmd/sh libs.tests -test`. To specify just the libraries, use `libs`.
**Examples**
- Building in release mode for platform x64 (restore and build are implicit here as no actions are passed in)
```bash
-./build.sh -subset libs -c Release -arch x64
+./build.sh libs -c Release -arch x64
```
- Building the src assemblies and build and run tests (running all tests takes a considerable amount of time!)
```bash
-./build.sh -subset libs -test
+./build.sh libs -test
```
-- Building for different target frameworks (restore and build are implicit again as no action is passed in)
-```bash
-./build.sh -subset libs -framework net5.0
-./build.sh -subset libs -framework net472
-```
-
-- Clean the entire solution
+- Clean the entire artifacts folder
```bash
./build.sh -clean
```
@@ -199,24 +193,24 @@ You can use the same workflow for mono runtime by using `mono.corelib+libs.prete
By default the libraries will attempt to build using the CoreCLR version of `System.Private.CoreLib.dll`. In order to build against the Mono version you need to use the `/p:RuntimeFlavor=Mono` argument.
```
-.\build.cmd -subset libs /p:RuntimeFlavor=Mono
+.\build.cmd libs /p:RuntimeFlavor=Mono
```
### Building all for other OSes
By default, building from the root will only build the libraries for the OS you are running on. One can
-build for another OS by specifying `./build.sh -subset libs -os [value]`.
+build for another OS by specifying `./build.sh libs -os [value]`.
Note that you cannot generally build native components for another OS but you can for managed components so if you need to do that you can do it at the individual project level or build all via passing `/p:BuildNative=false`.
### Building in Release or Debug
By default, building from the root or within a project will build the libraries in Debug mode.
-One can build in Debug or Release mode from the root by doing `./build.sh -subset libs -c Release` or `./build.sh -subset libs -c Debug`.
+One can build in Debug or Release mode from the root by doing `./build.sh libs -c Release` or `./build.sh libs`.
### Building other Architectures
-One can build 32- or 64-bit binaries or for any architecture by specifying in the root `./build.sh -subset libs -arch [value]` or in a project `/p:TargetArchitecture=[value]` after the `dotnet build` command.
+One can build 32- or 64-bit binaries or for any architecture by specifying in the root `./build.sh libs -arch [value]` or in a project `/p:TargetArchitecture=[value]` after the `dotnet build` command.
## Working in Visual Studio
@@ -227,3 +221,17 @@ If you are working on Windows, and use Visual Studio, you can open individual li
For more details about running tests inside Visual Studio, [go here](../../testing/visualstudio.md).
For more about running tests, read the [running tests](../../testing/libraries/testing.md) document.
+
+## Build packages
+To build a library's package, simply invoke `dotnet pack` on the src project after you successfully built the .NETCoreApp vertical from root:
+
+```
+build libs
+dotnet pack src\libraries\System.Text.Json\src\
+```
+
+Same as for `dotnet build` or `dotnet publish`, you can specify the desired configuration via the `-c` flag:
+
+```
+dotnet pack src\libraries\System.Text.Json\src\ -c Release
+```
diff --git a/docs/workflow/building/libraries/webassembly-instructions.md b/docs/workflow/building/libraries/webassembly-instructions.md
index c3195a30665e33..408aa4e908270d 100644
--- a/docs/workflow/building/libraries/webassembly-instructions.md
+++ b/docs/workflow/building/libraries/webassembly-instructions.md
@@ -34,12 +34,12 @@ The libraries build contains some native code. This includes shims over libc, op
- Building in debug mode for platform wasm and Browser operating system
```bash
-./build.sh --arch wasm --os Browser --subset Libs.Native --configuration Debug
+./build.sh libs.native --arch wasm --os Browser
```
- Building in release mode for platform wasm and Browser operating system
```bash
-./build.sh --arch wasm --os Browser --subset Libs.Native --configuration Release
+./build.sh libs.native --arch wasm --os Browser -c Release
```
## How to build mono System.Private.CoreLib
@@ -48,20 +48,19 @@ If you are working on core parts of mono libraries you will probably need to bui
```bash
-./build.sh --arch wasm --os Browser --configuration release --subset Mono
+./build.sh mono --arch wasm --os Browser -c Release
```
To build just SPC without mono you can use the Mono.CoreLib subset.
```bash
-./build.sh --arch wasm --os Browser --configuration release --subset Mono.CoreLib
+./build.sh mono.corelib --arch wasm --os Browser -c Release
```
-
Building the managed libraries as well:
```bash
-./build.sh --arch wasm --os Browser --configuration release --subset Mono+Libs
+./build.sh mono+libs --arch wasm --os Browser -c Release
```
## Building individual libraries
@@ -71,16 +70,16 @@ Individual projects and libraries can be build by specifying the build configura
Building individual libraries
**Examples**
-- Build all projects for a given library (e.g.: System.Net.Http) including running the tests
+- Build all projects for a given library (e.g.: System.Net.Http) including the tests
```bash
- ./build.sh --arch wasm --os Browser --configuration release --projects src/libraries/System.Net.Http/System.Net.Http.sln
+ ./build.sh --arch wasm --os Browser -c Release --projects src/libraries/System.Net.Http/System.Net.Http.sln
```
- Build only the source project of a given library (e.g.: System.Net.Http)
```bash
- ./build.sh --arch wasm --os Browser --configuration release --projects src/libraries/System.Net.Http/src/System.Net.Http.csproj
+ ./build.sh --arch wasm --os Browser -c Release --projects src/libraries/System.Net.Http/src/System.Net.Http.csproj
```
More information and examples can be found in the [libraries](./README.md#building-individual-libraries) document.
@@ -91,7 +90,7 @@ The WebAssembly implementation files are built and made available in the artifac
For Linux and MacOSX:
```bash
-./dotnet.sh build /p:Configuration=Debug|Release /p:TargetArchitecture=wasm /p:TargetOS=Browser src/libraries/src.proj /t:NativeBinPlace
+./dotnet.sh build /p:Configuration=Debug|Release /p:TargetArchitecture=wasm /p:TargetOS=Browser src/libraries/src.proj /t:BuildWasmRuntimes
```
__Note__: A `Debug` build sets the following environment variables by default. When built from the command line this way the `Configuration` value is case sensitive.
@@ -155,4 +154,4 @@ container:
registry: mcr
```
-Open a PR request with the new image.
\ No newline at end of file
+Open a PR request with the new image.
diff --git a/docs/workflow/requirements/freebsd-requirements.md b/docs/workflow/requirements/freebsd-requirements.md
index 59b3c64d928f15..66e50ec878b361 100644
--- a/docs/workflow/requirements/freebsd-requirements.md
+++ b/docs/workflow/requirements/freebsd-requirements.md
@@ -21,7 +21,7 @@ with all needed prerequisites to build. As the example bellow may become stale,
```sh
TAG=mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-cross-freebsd-11-20200430154008-a84b0d2
-docker run --rm --volume $(pwd):$(pwd) --workdir $(pwd) --env ROOTFS_DIR=/crossrootfs/x64 -ti $TAG ./build.sh -cross -FreeBSD
+docker run --rm --volume $(pwd):$(pwd) --workdir $(pwd) --env ROOTFS_DIR=/crossrootfs/x64 -ti $TAG ./build.sh -cross -os FreeBSD
```
Build using Toolchain Setup
diff --git a/docs/workflow/testing/using-your-build.md b/docs/workflow/testing/using-your-build.md
index 31a7f6bc8d3fe5..33e5ef19e17409 100644
--- a/docs/workflow/testing/using-your-build.md
+++ b/docs/workflow/testing/using-your-build.md
@@ -1,7 +1,7 @@
# Using your .NET Runtime Build
-We assume that you have successfully built CoreCLR repository and thus have files of the form
+We assume that you have successfully built the repository and thus have files of the form
```
~/runtime/artifacts/bin/coreclr/../
```
@@ -11,7 +11,7 @@ a 'host' program that will load the Runtime as well as all the other .NET librar
code that your application needs. The easiest way to get all this other stuff is to simply use the
standard 'dotnet' host that installs with .NET SDK.
-The released version of 'dotnet' tool may not be compatible with the live CoreCLR repository. The following steps
+The released version of 'dotnet' tool may not be compatible with the live repository. The following steps
assume use of a dogfood build of the .NET SDK.
## Acquire the latest nightly .NET SDK
@@ -157,7 +157,7 @@ Assert failure(PID 13452 [0x0000348c], Thread: 10784 [0x2a20]): Consistency chec
## Using .NET SDK to run your .NET Application
If you don't like the idea of copying files manually you can follow [these instructions](../using-dotnet-cli.md) to use dotnet cli to do this for you.
-However the steps described here are the simplest and most commonly used by CoreCLR developers for ad-hoc testing.
+However the steps described here are the simplest and most commonly used by runtime developers for ad-hoc testing.
## Using CoreRun to run your .NET Application
diff --git a/docs/workflow/testing/visualstudio.md b/docs/workflow/testing/visualstudio.md
index c8c20b9cfc7fa3..106f069f7df78a 100644
--- a/docs/workflow/testing/visualstudio.md
+++ b/docs/workflow/testing/visualstudio.md
@@ -1,9 +1,25 @@
-# Visual Studio Test Explorer support
-For Visual Studio Test Explorer to work in dotnet/runtime, the following test settings need to be enabled:
-- Test parameters (like which `dotnet` host to use) are persisted in an auto-generated .runsettings file. For that to work, make sure that the "Auto detect runsettings Files" (`Options -> Test`) option is enabled.
-- Make sure that the "Processor Architecture for AnyCPU project" (`Test Explore pane -> Test Explorer toolbar options --> Settings`) value is set to `auto`.
+# Working in dotnet/runtime using Visual Studio
+
+Visual Studio is a great tool to use when working in the dotnet/runtime repo.
+
+Almost all its features should work well, but there are a few special considerations to bear in mind:
+
+## Test Explorer
+
+You can run tests from the Visual Studio Test Explorer, but there are a few settings you need:
+- Enable `Auto detect runsettings Files` (`Test Explorer window -> Settings button -> Options`). Test parameters (like which `dotnet` host to use) are persisted in an auto-generated .runsettings file, and it's important that Visual Studio knows to use it.
+- Set `Processor Architecture for AnyCPU project` to `auto` (`Test Explorer window -> Settings button`).
+- Consider whether to disable `Discover tests in real time from C# and Visual Basic .NET source files` (`Test explorer window -> Settings button -> Options`).
+ - You may want it enabled if you're actively writing new tests and want them to show up in Test Explorer without building first.
+ - You may want it disabled if you're mostly running existing tests, and some of them have conditional attributes. Many of our unit tests have attributes, like `[SkipOnTargetFramework]`, to indicate that they're only valid in certain configurations. Because the real-time discovery feature does not currently recognize these attributes the tests will show up in Test Explorer as well, and fail or possibly hang when you try to run them.
+- Consider whether to enable `Run tests in Parallel` (`Test Explorer window -> Settings button`).
+ - You may want it enabled if some of the unit tests you're working with run slowly or there's many of them.
+ - You may want it disabled if you want to simplify debugging or viewing debug output.
+
+If you encounter puzzling behavior while running tests within Visual Studio, first check the settings above, verify they run correctly from the command line, and also make sure you're using the latest Visual Studio. It can be helpful to enable detailed logging of the test runner (`Test explorer window -> Settings button -> Options > Logging Level: Trace`) - it may suggest the problem, or at least provide more information to share.
+
+## Start with Debugging (F5)
-# Visual Studio F5 Debugging support
dotnet/runtime uses `dotnet test` ([VSTest](https://github.com/Microsoft/vstest)) which spawns child processes during test execution.
Visual Studio by default doesn't automatically debug child processes, therefore preliminary steps need to be done to enable Debugging "F5" support.
Note that these steps aren't necessary for Visual Studio Test Explorer support.
@@ -14,3 +30,4 @@ Note that these steps aren't necessary for Visual Studio Test Explorer support.
## References
- https://github.com/dotnet/project-system/issues/6176 tracks enabling the native code debugging functionality for multiple projects without user interaction.
- https://github.com/dotnet/sdk/issues/7419#issuecomment-298261617 explains the necessary steps to install and enable the mentioned extension in more detail.
+- https://github.com/microsoft/vstest/ is the repo for issues with the Visual Studio test execution features.
diff --git a/docs/workflow/trimming/feature-switches.md b/docs/workflow/trimming/feature-switches.md
index ad911e818d7a53..40d3a2299f474b 100644
--- a/docs/workflow/trimming/feature-switches.md
+++ b/docs/workflow/trimming/feature-switches.md
@@ -14,7 +14,7 @@ configurations but their defaults might vary as any SDK can set the defaults dif
| EventSourceSupport | System.Diagnostics.Tracing.EventSource.IsSupported | Any EventSource related code or logic is trimmed when set to false |
| InvariantGlobalization | System.Globalization.Invariant | All globalization specific code and data is trimmed when set to true |
| UseSystemResourceKeys | System.Resources.UseSystemResourceKeys | Any localizable resources for system assemblies is trimmed when set to true |
-| - | System.Net.Http.EnableActivityPropagation | Any dependency related to diagnostics support for System.Net.Http is trimmed when set to false |
+| HttpActivityPropagationSupport | System.Net.Http.EnableActivityPropagation | Any dependency related to diagnostics support for System.Net.Http is trimmed when set to false |
Any feature-switch which defines property can be set in csproj file or
on the command line as any other MSBuild property. Those without predefined property name
diff --git a/docs/workflow/using-dotnet-cli.md b/docs/workflow/using-dotnet-cli.md
index 7c9efa28c829d2..68cadd5bf4f831 100644
--- a/docs/workflow/using-dotnet-cli.md
+++ b/docs/workflow/using-dotnet-cli.md
@@ -1,23 +1,23 @@
# Using your .NET Runtime build with .NET SDK
-This walkthrough explains how to run against your local CoreCLR build using .NET SDK only.
+This walkthrough explains how to run your own app against your local build using only the .NET SDK.
For other walkthroughs see:
-- [Using Your Build - Update CoreCLR from raw binary output](./testing/using-your-build.md)
+- [Using Your Build - Update from raw build output](./testing/using-your-build.md)
- [Using CoreRun To Run .NET Application](./testing/using-corerun.md)
- [Dogfooding .NET SDK](https://github.com/dotnet/runtime/blob/master/docs/project/dogfooding.md).
## Prerequisites
-1. Successfully built CoreCLR repository and thus have files of the form shown below. From now on we call this folder NuGet package folder.
+1. Successfully built this repository and thus have files of the form shown below. From now on we call this folder NuGet package folder.
```
- artifacts\bin\coreclr\..\.nuget\pkg\runtime.-.Microsoft.NETCore.Runtime.CoreCLR..nupkg
+ artifacts\packages\\Shipping\
```
-2. Acquired the latest nightly .NET SDK from [here](https://github.com/dotnet/cli/blob/master/README.md#installers-and-binaries) and added it's root folder to your [path](requirements/windows-requirements.md#adding-to-the-default-path-variable)
+2. Acquired the latest nightly .NET SDK from [here](https://github.com/dotnet/installer) and added its root folder to your [path](requirements/windows-requirements.md#adding-to-the-default-path-variable)
## First Run
@@ -29,13 +29,11 @@ From now on all instructions relate to this folder as "app folder".
### 2. Create NuGet.Config file
-The build script creates NuGet packages and puts them to `artifacts\bin\coreclr\..\.nuget\pkg\`. .NET SDK has no idea about its existence and we need to tell it where to search for the packages.
+The build script creates NuGet packages and puts them to `artifacts\packages\\Shipping\`. .NET SDK has no idea about its existence and we need to tell it where to search for the packages.
Please run `dotnet new nugetconfig` in the app folder and update the created `NuGet.Config` file:
-* **set path to local CoreCLR NuGet folder!!**
-* add address to dotnet core tools NuGet feed
-
+* ** adjust path below to point to your in-repo NuGet folder**
```xml
@@ -44,11 +42,9 @@ Please run `dotnet new nugetconfig` in the app folder and update the created `Nu
-
-
+
-
```
### 3. Create and update the Project file
@@ -60,39 +56,34 @@ Please run `dotnet new console` in the app folder and update the created `.cspro
Exe
- netcoreapp3.0
+ net5.0
win-x64
- 3.0.0-preview1-26210-0
+ 5.0.0-dev
-
-
-
-
-
```
**You have to set the correct values for `RuntimeIdentifier` (RI), `RuntimeFrameworkVersion` and versions of both packages.**
You can generally figure that out by looking at the packages you found in your output.
-In our example you will see there is a package with the name `runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR.3.0.0-preview1-26210-0.nupkg`
+In our example you will see there is a package with the name `Microsoft.NETCore.App.Runtime.win-x64.5.0.0-dev.nupkg`
```
-runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR.3.0.0-preview1-26210-0.nupkg
- ^--RI---^ ^--------version-------^
+Microsoft.NETCore.App.Runtime.win-x64.5.0.0-dev.nupkg
+ ^-RI--^ ^version^
```
### 4. Change Program.cs
-To make sure that you run against your local coreclr build please change your `Main` method in `Program.cs` file to:
+To make sure that you run against your local build of this repo please change your `Main` method in `Program.cs` file to:
```cs
static void Main(string[] args)
{
- var coreAssemblyInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(object).Assembly.Location);
- Console.WriteLine($"Hello World from Core {coreAssemblyInfo.ProductVersion}");
- Console.WriteLine($"The location is {typeof(object).Assembly.Location}");
+ var coreAssemblyInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(typeof(object).Assembly.Location);
+ Console.WriteLine($"Hello World from .NET {coreAssemblyInfo.ProductVersion}");
+ Console.WriteLine($"The location is {typeof(object).Assembly.Location}");
}
```
@@ -108,40 +99,56 @@ dotnet publish
Make sure that restoring done by `dotnet publish` installed the explicit version of the Runtime that you have specified:
```
-PS C:\coreclr\helloWorld> dotnet publish
- Restoring packages for C:\coreclr\helloWorld\helloWorld.csproj...
- Installing runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR 3.0.0-preview1-26210-
+c:\runtime\helloworld>dotnet publish
+Microsoft (R) Build Engine version 16.7.0-preview-20360-03+188921e2f for .NET
+Copyright (C) Microsoft Corporation. All rights reserved.
+
+ Determining projects to restore...
+ Restored c:\runtime\helloworld\helloworld.csproj (in 114 ms).
+ You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
+ helloworld -> c:\runtime\helloworld\bin\Debug\net5.0\win-x64\helloworld.dll
+ helloworld -> c:\runtime\helloworld\bin\Debug\net5.0\win-x64\publish\
```
If you see something like the message below it means that it has failed to restore your local runtime packages. In such case double check your `NuGet.config` file and paths used in it.
```
-C:\coreclr\helloWorld\helloWorld.csproj : warning NU1603: helloWorld depends on runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR (>= 3.0.0-preview1-26210-0) but runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR 3.0.0-preview1-26210-0 was not found. An approximate best match of runtime.win-x64.Microsoft.NETCore.Runtime.CoreCLR 3.0.0-preview2-25501-02 was resolved.
+c:\runtime\helloworld>dotnet publish
+Microsoft (R) Build Engine version 16.7.0-preview-20360-03+188921e2f for .NET
+Copyright (C) Microsoft Corporation. All rights reserved.
+
+ Determining projects to restore...
+c:\runtime\helloworld\helloworld.csproj : error NU1102: Unable to find package Microsoft.NETCore.App.Runtime.win-x64 with version (= 5.0.0-does-not-exist)
+c:\runtime\helloworld\helloworld.csproj : error NU1102: - Found 25 version(s) in nuget [ Nearest version: 5.0.0-preview.1.20120.5 ]
+c:\runtime\helloworld\helloworld.csproj : error NU1102: - Found 1 version(s) in local runtime [ Nearest version: 5.0.0-dev ]
+c:\runtime\helloworld\helloworld.csproj : error NU1102: Unable to find package Microsoft.NETCore.App.Host.win-x64 with version (= 5.0.0-does-not-exist)
+c:\runtime\helloworld\helloworld.csproj : error NU1102: - Found 27 version(s) in nuget [ Nearest version: 5.0.0-preview.1.20120.5 ]
+c:\runtime\helloworld\helloworld.csproj : error NU1102: - Found 1 version(s) in local runtime [ Nearest version: 5.0.0-dev ]
+ Failed to restore c:\runtime\helloworld\helloworld.csproj (in 519 ms).
```
### 6. Run the app
-After you publish you will find all the binaries needed to run your application under `bin\Debug\netcoreapp3.0\win-x64\publish\`.
+After you publish you will find all the binaries needed to run your application under `bin\Debug\net5.0\win-x64\publish\`.
To run the application simply run the EXE that is in this publish directory (it is the name of the app, or specified in the project file).
```
-.\bin\Debug\netcoreapp3.0\win-x64\publish\HelloWorld.exe
+.\bin\Debug\net5.0\win-x64\publish\HelloWorld.exe
```
-Running the app should tell you the version and which user and machine build the assembly as well as the commit hash of the code
-at the time of building:
+Running the app should tell you the version and where the location of System.Private.CoreLib in the publish directory:
```
-Hello World from Core 4.6.26210.0 @BuiltBy: adsitnik-MININT-O513E3V @SrcCode: https://github.com/dotnet/runtime/tree/3d6da797d1f7dc47d5934189787a4e8006ab3a04
-The location is C:\coreclr\helloWorld\bin\Debug\netcoreapp3.0\win-x64\publish\System.Private.CoreLib.dll
+Hello World from .NET 5.0.0-dev
+The location is c:\runtime\helloworld\bin\Debug\net5.0\win-x64\publish\System.Private.CoreLib.dll
```
-**Congratulations! You have just run your first app against local CoreCLR build!**
+**Congratulations! You have just run your first app against your local build of this repo**
-## Update CoreCLR using runtime nuget package
+## Update using runtime nuget package
-Updating CoreCLR from raw binary output is easier for quick one-off testing but using the nuget package is better
-for referencing your CoreCLR build in your actual application because of it does not require manual copying of files
+Updating the runtime from raw binary output is easier for quick one-off testing but using the nuget package is better
+for referencing your build in your actual application because of it does not require manual copying of files
around each time the application is built and plugs into the rest of the tool chain. This set of instructions will cover
the further steps needed to consume the runtime nuget package.
diff --git a/eng/AvoidRestoreCycleOnSelfReference.targets b/eng/AvoidRestoreCycleOnSelfReference.targets
new file mode 100644
index 00000000000000..cb665cb070d988
--- /dev/null
+++ b/eng/AvoidRestoreCycleOnSelfReference.targets
@@ -0,0 +1,14 @@
+
+
+
+ <_PackageIdTemp>$(PackageId)
+ $(PackageId)_temp
+
+
+
+
+ $(_PackageIdTemp)
+
+
+
\ No newline at end of file
diff --git a/eng/BeforeTargetFrameworkInference.targets b/eng/BeforeTargetFrameworkInference.targets
index 92adb5df635380..abef4c8981a28e 100644
--- a/eng/BeforeTargetFrameworkInference.targets
+++ b/eng/BeforeTargetFrameworkInference.targets
@@ -6,10 +6,6 @@
$(TargetFramework.SubString(0, $(TargetFramework.IndexOf('-'))))
-
- $([MSBuild]::NormalizeDirectory('$(RefRootPath)', '$(TargetFramework)'))
-
-
diff --git a/eng/Configurations.props b/eng/Configurations.props
index aa8e9add17dd81..3d123f81972aef 100644
--- a/eng/Configurations.props
+++ b/eng/Configurations.props
@@ -29,9 +29,6 @@
$(NetCoreAppCurrent)
Microsoft.NETCore.App
.NET $(NetCoreAppCurrentVersion)
-
- net472
- WINDOWS7.0
diff --git a/eng/DefaultGenApiDocIds.txt b/eng/DefaultGenApiDocIds.txt
index 5576d9fad6ae21..51ea5986f536fb 100644
--- a/eng/DefaultGenApiDocIds.txt
+++ b/eng/DefaultGenApiDocIds.txt
@@ -1,6 +1,5 @@
// These attributes should be excluded from reference assemblies.
-T:System.ComponentModel.DesignerAttribute
T:System.ComponentModel.Design.Serialization.DesignerSerializerAttribute
T:System.ComponentModel.Design.Serialization.RootDesignerSerializerAttribute
T:System.ComponentModel.EditorAttribute
diff --git a/eng/Subsets.props b/eng/Subsets.props
index b27d1e55a8bdd9..f7f61f98f6e9bf 100644
--- a/eng/Subsets.props
+++ b/eng/Subsets.props
@@ -57,9 +57,9 @@
clr.runtime+linuxdac+clr.corelib+clr.nativecorelib+clr.tools+clr.packages
mono.llvm+
- $(DefaultMonoSubsets)mono.runtime+mono.corelib
+ $(DefaultMonoSubsets)mono.runtime+mono.corelib+mono.packages
- libs.depprojs+libs.native+libs.ref+libs.src+libs.pretest+libs.packages
+ libs.native+libs.ref+libs.src+libs.pretest+libs.packages
corehost+installer.managed+installer.depprojs+installer.pkgprojs+bundles+installers+installer.tests
installer.pkgprojs
@@ -70,6 +70,7 @@
<_subset>$(_subset.Replace('+mono+', '+$(DefaultMonoSubsets)+'))
<_subset>$(_subset.Replace('+libs+', '+$(DefaultLibrariesSubsets)+'))
<_subset>$(_subset.Replace('+installer+', '+$(DefaultInstallerSubsets)+'))
+ <_subset>$(_subset.Replace('+installer.nocorehost+', '+$(DefaultInstallerSubsets.Replace('corehost+', ''))+'))
<_subset>+$(_subset.Trim('+'))+
@@ -79,21 +80,23 @@
-
-
+
+
+
+
-
@@ -104,6 +107,7 @@
+
@@ -136,10 +140,14 @@
-
+
+
+
+
+
@@ -162,6 +170,10 @@
+
+
+
+
@@ -171,12 +183,6 @@
-
-
- Configuration=$(LibrariesConfiguration)
-
-
-
@@ -203,7 +209,7 @@
-
+
@@ -216,15 +222,11 @@
-
-
-
-
@@ -256,9 +258,9 @@
- Configuration=$(CoreCLRConfiguration)
- Configuration=$(MonoConfiguration)
- Configuration=$(LibrariesConfiguration)
+ %(AdditionalProperties);Configuration=$(CoreCLRConfiguration)
+ %(AdditionalProperties);Configuration=$(MonoConfiguration)
+ %(AdditionalProperties);Configuration=$(LibrariesConfiguration)
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 098240ee26cbd9..ea4afb6ae2adce 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -4,67 +4,67 @@
https://github.com/dotnet/standard
cfe95a23647c7de1fe1a349343115bd7720d6949
-
+
https://github.com/dotnet/icu
- 7247fa0d9e8faee2cceee6f04856b2c447f41bca
+ f58ab86d7e07a66ea189859f298843ccf41a0914
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ 39c3b73c4b2b79981405e865e5a4fa096662f13a
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
-
+
https://github.com/dotnet/arcade
- ff5d4b6c8dbdaeacb6e6159d3f8185118dffd915
+ f6192d1e284a08ac05041d05fa6e60dec74b24f5
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
@@ -86,73 +86,73 @@
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
d0bb63d2ec7060714e63ee4082fac48f2e57f3e2
-
+
https://github.com/microsoft/vstest
- b9296fc900e2f2d717d507b4ee2a4306521796d4
+ ddb755f58160c0e7fab50964d665be1bf47ff579
-
+
https://github.com/dotnet/runtime-assets
- b34a70799faa67f13c2e72852e4f3af463ff4d6c
+ 4d5781485294568e51a4673719c8ae5ae8955e70
-
+
https://github.com/dotnet/runtime-assets
- b34a70799faa67f13c2e72852e4f3af463ff4d6c
+ 4d5781485294568e51a4673719c8ae5ae8955e70
-
+
https://github.com/dotnet/runtime-assets
- b34a70799faa67f13c2e72852e4f3af463ff4d6c
+ 4d5781485294568e51a4673719c8ae5ae8955e70
-
+
https://github.com/dotnet/runtime-assets
- b34a70799faa67f13c2e72852e4f3af463ff4d6c
+ 4d5781485294568e51a4673719c8ae5ae8955e70
-
+
https://github.com/dotnet/runtime-assets
- b34a70799faa67f13c2e72852e4f3af463ff4d6c
+ 4d5781485294568e51a4673719c8ae5ae8955e70
-
+
https://github.com/dotnet/runtime-assets
- b34a70799faa67f13c2e72852e4f3af463ff4d6c
+ 4d5781485294568e51a4673719c8ae5ae8955e70
-
+
https://github.com/dotnet/runtime-assets
- b34a70799faa67f13c2e72852e4f3af463ff4d6c
+ 4d5781485294568e51a4673719c8ae5ae8955e70
-
+
https://github.com/dotnet/runtime-assets
- b34a70799faa67f13c2e72852e4f3af463ff4d6c
+ 4d5781485294568e51a4673719c8ae5ae8955e70
-
+
https://github.com/dotnet/llvm-project
- 266c9f5b5c1e94333e01ca77fa74d76563969842
+ 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf
-
+
https://github.com/dotnet/llvm-project
- 266c9f5b5c1e94333e01ca77fa74d76563969842
+ 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf
-
+
https://github.com/dotnet/llvm-project
- 266c9f5b5c1e94333e01ca77fa74d76563969842
+ 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf
-
+
https://github.com/dotnet/llvm-project
- 266c9f5b5c1e94333e01ca77fa74d76563969842
+ 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf
-
+
https://github.com/dotnet/llvm-project
- 266c9f5b5c1e94333e01ca77fa74d76563969842
+ 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf
-
+
https://github.com/dotnet/llvm-project
- 266c9f5b5c1e94333e01ca77fa74d76563969842
+ 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf
-
+
https://github.com/dotnet/llvm-project
- 266c9f5b5c1e94333e01ca77fa74d76563969842
+ 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf
-
+
https://github.com/dotnet/llvm-project
- 266c9f5b5c1e94333e01ca77fa74d76563969842
+ 62d9a4d09b44ebaa1c9f94bca1066aef426a5bbf
https://github.com/dotnet/runtime
@@ -182,17 +182,17 @@
https://github.com/dotnet/runtime
0375524a91a47ca4db3ee1be548f74bab7e26e76
-
+
https://github.com/mono/linker
- e76321851c05c5016df3d1243885c02e875b9912
+ 8f32ed57a05eeb0bae3790c4db75b316c3da76c7
-
+
https://github.com/dotnet/xharness
- 5c95b40b725e1aa9d596411c453900385cf6f84c
+ abc6d581ce00214ef763fb8510d1ba0aa54e7717
-
+
https://github.com/dotnet/xharness
- 5c95b40b725e1aa9d596411c453900385cf6f84c
+ abc6d581ce00214ef763fb8510d1ba0aa54e7717
diff --git a/eng/Versions.props b/eng/Versions.props
index 8366710273c7d5..02bd975b4fa169 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -16,8 +16,11 @@
release
true
+
+ 3.8.0-2.20379.3
true
false
+ true
dotnet
$(ContainerName)
@@ -45,22 +48,19 @@
-
-
-
- 5.0.0-beta.20364.3
- 5.0.0-beta.20364.3
- 5.0.0-beta.20364.3
- 5.0.0-beta.20364.3
- 5.0.0-beta.20364.3
- 5.0.0-beta.20364.3
- 2.5.1-beta.20364.3
- 5.0.0-beta.20364.3
- 5.0.0-beta.20364.3
- 5.0.0-beta.20364.3
+ 5.0.0-beta.20381.6
+ 5.0.0-beta.20374.1
+ 5.0.0-beta.20374.1
+ 5.0.0-beta.20374.1
+ 5.0.0-beta.20374.1
+ 5.0.0-beta.20374.1
+ 2.5.1-beta.20374.1
+ 5.0.0-beta.20374.1
+ 5.0.0-beta.20374.1
+ 5.0.0-beta.20374.1
5.0.0-preview.4.20202.18
5.0.0-preview.4.20202.18
@@ -69,19 +69,49 @@
5.0.0-preview.8.20359.4
+ 4.5.1
+ 4.3.0
+ 4.3.0
+ 4.7.0
+ 4.8.1
+ 4.3.0
+ 4.3.0
+ 4.3.0
+ 4.3.0
+ 4.3.0
+ 4.5.4
+ 4.3.4
+ 4.3.1
+ 4.5.0
+ 4.3.0
+ 4.3.1
+ 4.3.1
+ 4.3.0
+ 4.3.0
+ 4.3.0
+ 4.3.1
+ 4.7.0
+ 4.7.0
+ 4.7.0
5.0.0-preview.4.20202.18
+ 4.3.0
+ 4.5.4
+ 4.5.0
+ 1.1.1
+ 4.3.0
5.0.0-alpha.1.19563.3
- 5.0.0-beta.20360.1
- 5.0.0-beta.20360.1
- 5.0.0-beta.20360.1
- 5.0.0-beta.20360.1
- 5.0.0-beta.20360.1
- 5.0.0-beta.20360.1
- 5.0.0-beta.20360.1
- 5.0.0-beta.20360.1
+ 5.0.0-beta.20377.1
+ 5.0.0-beta.20377.1
+ 5.0.0-beta.20377.1
+ 5.0.0-beta.20377.1
+ 5.0.0-beta.20377.1
+ 5.0.0-beta.20377.1
+ 5.0.0-beta.20377.1
+ 5.0.0-beta.20377.1
2.2.0-prerelease.19564.1
+ 2.0.3
99.99.99-master-20200228.3
99.99.99-master-20200228.3
@@ -101,33 +131,32 @@
$(RefOnlyMicrosoftBuildVersion)
4.9.4
4.9.4
-
- 4.8.0
- 16.8.0-preview-20200708-01
- 1.0.0-prerelease.20352.3
- 1.0.0-prerelease.20352.3
+ 16.8.0-preview-20200730-03
+ 1.0.0-prerelease.20403.2
+ 1.0.0-prerelease.20403.2
2.4.1
2.4.2
1.3.0
2.0.5
12.0.3
4.12.0
+ 2.14.3
3.0.0-preview-20200715.1
- 5.0.0-preview.3.20363.5
+ 5.0.0-preview.3.20403.5
- 5.0.0-preview.8.20365.1
+ 5.0.0-preview.8.20403.1
- 9.0.1-alpha.1.20356.1
- 9.0.1-alpha.1.20356.1
- 9.0.1-alpha.1.20356.1
- 9.0.1-alpha.1.20356.1
- 9.0.1-alpha.1.20356.1
- 9.0.1-alpha.1.20356.1
- 9.0.1-alpha.1.20356.1
- 9.0.1-alpha.1.20356.1
+ 9.0.1-alpha.1.20403.1
+ 9.0.1-alpha.1.20403.1
+ 9.0.1-alpha.1.20403.1
+ 9.0.1-alpha.1.20403.1
+ 9.0.1-alpha.1.20403.1
+ 9.0.1-alpha.1.20403.1
+ 9.0.1-alpha.1.20403.1
+ 9.0.1-alpha.1.20403.1
@@ -146,7 +175,7 @@
Microsoft.NETCore.Runtime.ICU.Transport
$([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', '$(MicrosoftPrivateIntellisensePackage)', '$(MicrosoftPrivateIntellisenseVersion)', 'IntellisenseFiles', 'net'))
diff --git a/eng/build.ps1 b/eng/build.ps1
index f8b205bd3930a1..016ed15d2035a9 100644
--- a/eng/build.ps1
+++ b/eng/build.ps1
@@ -65,7 +65,7 @@ function Get-Help() {
Write-Host "Libraries settings:"
Write-Host " -allconfigurations Build packages for all build configurations."
Write-Host " -coverage Collect code coverage when testing."
- Write-Host " -framework (-f) Build framework: net5.0 or net472."
+ Write-Host " -framework (-f) Build framework: net5.0 or net48."
Write-Host " [Default: net5.0]"
Write-Host " -testnobuild Skip building tests when invoking -test."
Write-Host " -testscope Scope tests, allowed values: innerloop, outerloop, all."
diff --git a/eng/build.sh b/eng/build.sh
index eb0cb586ebf325..da8e3770f595a5 100755
--- a/eng/build.sh
+++ b/eng/build.sh
@@ -60,7 +60,7 @@ usage()
echo "Libraries settings:"
echo " --allconfigurations Build packages for all build configurations."
echo " --coverage Collect code coverage when testing."
- echo " --framework (-f) Build framework: net5.0 or net472."
+ echo " --framework (-f) Build framework: net5.0 or net48."
echo " [Default: net5.0]"
echo " --testnobuild Skip building tests when invoking -test."
echo " --testscope Test scope, allowed values: innerloop, outerloop, all."
diff --git a/eng/codeOptimization.targets b/eng/codeOptimization.targets
index 6ed7e997487bd6..73e19c9560557f 100644
--- a/eng/codeOptimization.targets
+++ b/eng/codeOptimization.targets
@@ -4,12 +4,7 @@
true
false
false
-
- false
+ false
+
+
+ py -3
+ $(HelixPreCommands);call %HELIX_CORRELATION_PAYLOAD%\performance\tools\machine-setup.cmd;set PYTHONPATH=%HELIX_WORKITEM_PAYLOAD%\scripts%3B%HELIX_WORKITEM_PAYLOAD%
+ %HELIX_CORRELATION_PAYLOAD%\artifacts\BenchmarkDotNet.Artifacts
+ $HELIX_CORRELATION_PAYLOAD
+ $(BaseDirectory)/performance
+
+
+
+ $(PerformanceDirectory)/scripts/benchmarks_ci.py --csproj $(PerformanceDirectory)/$(TargetCsproj)
+ --dotnet-versions $DOTNET_VERSION --cli-source-info args --cli-branch $PERFLAB_BRANCH --cli-commit-sha $PERFLAB_HASH --cli-repository https://github.com/$PERFLAB_REPO --cli-source-timestamp $PERFLAB_BUILDTIMESTAMP
+ python3
+ $(BaseDirectory)/Core_Root/corerun
+ $(HelixPreCommands);chmod +x $(PerformanceDirectory)/tools/machine-setup.sh;. $(PerformanceDirectory)/tools/machine-setup.sh
+ $(BaseDirectory)/artifacts/BenchmarkDotNet.Artifacts
+ $(BaseDirectory)/artifacts/BenchmarkDotNet.Artifacts_Baseline
+ $(PerformanceDirectory)/src/tools/ResultsComparer/ResultsComparer.csproj
+ $(PerformanceDirectory)/tools/dotnet/$(Architecture)/dotnet
+ %25
+ $HELIX_WORKITEM_ROOT/testResults.xml
+
+
+
+
+ %(Identity)
+
+
+
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Private.Xml.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Linq.Expressions.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.VisualBasic.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Private.CoreLib.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+
+
+
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Private.Xml.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Linq.Expressions.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single Microsoft.CodeAnalysis.VisualBasic.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Private.CoreLib.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+
+
+ $(WorkItemDirectory)\ScenarioCorrelation
+ $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --composite %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\framework-r2r.dll.rsp --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
+ 1:00
+
+
+
\ No newline at end of file
diff --git a/eng/common/performance/perfhelixpublish.proj b/eng/common/performance/microbenchmarks.proj
similarity index 66%
rename from eng/common/performance/perfhelixpublish.proj
rename to eng/common/performance/microbenchmarks.proj
index 272366da95fca8..71114b074e1b26 100644
--- a/eng/common/performance/perfhelixpublish.proj
+++ b/eng/common/performance/microbenchmarks.proj
@@ -41,6 +41,10 @@
$HELIX_WORKITEM_ROOT/testResults.xml
+
+ $(CliArguments) --wasm
+
+
--corerun %HELIX_CORRELATION_PAYLOAD%\dotnet-mono\shared\Microsoft.NETCore.App\5.0.0\corerun.exe
@@ -65,7 +69,7 @@
- 2:30
+ 12:30
0:15
@@ -137,56 +141,4 @@
4:00
-
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Private.Xml.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Linq.Expressions.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.VisualBasic.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen\test.py crossgen --test-name System.Private.CoreLib.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
-
-
-
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Private.Xml.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Linq.Expressions.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single Microsoft.CodeAnalysis.VisualBasic.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single Microsoft.CodeAnalysis.CSharp.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --single System.Private.CoreLib.dll --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
-
-
- $(WorkItemDirectory)\ScenarioCorrelation
- $(Python) %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\test.py crossgen2 --composite %HELIX_CORRELATION_PAYLOAD%\performance\src\scenarios\crossgen2\framework-r2r.dll.rsp --core-root %HELIX_CORRELATION_PAYLOAD%\Core_Root
- 1:00
-
-
-
\ No newline at end of file
diff --git a/eng/common/performance/performance-setup.sh b/eng/common/performance/performance-setup.sh
index c87cbf0fc23265..66f63a397a0fc0 100755
--- a/eng/common/performance/performance-setup.sh
+++ b/eng/common/performance/performance-setup.sh
@@ -24,6 +24,8 @@ run_from_perf_repo=false
use_core_run=true
use_baseline_core_run=true
using_mono=false
+wasm_runtime_loc=
+using_wasm=false
while (($# > 0)); do
lowerI="$(echo $1 | awk '{print tolower($0)}')"
@@ -70,7 +72,7 @@ while (($# > 0)); do
;;
--kind)
kind=$2
- configurations="CompliationMode=$compilation_mode RunKind=$kind"
+ configurations="CompilationMode=$compilation_mode RunKind=$kind"
shift 2
;;
--runcategories)
@@ -101,6 +103,10 @@ while (($# > 0)); do
mono_dotnet=$2
shift 2
;;
+ --wasm)
+ wasm_runtime_loc=$2
+ shift 2
+ ;;
--compare)
compare=true
shift 1
@@ -130,6 +136,7 @@ while (($# > 0)); do
echo " --runcategories Related to csproj. Categories of benchmarks to run. Defaults to \"coreclr corefx\""
echo " --internal If the benchmarks are running as an official job."
echo " --monodotnet Pass the path to the mono dotnet for mono performance testing."
+ echo " --wasm Path to the unpacled wasm runtime pack."
echo ""
exit 0
;;
@@ -141,7 +148,7 @@ if [ "$repository" == "dotnet/performance" ] || [ "$repository" == "dotnet-perfo
fi
if [ -z "$configurations" ]; then
- configurations="CompliationMode=$compilation_mode"
+ configurations="CompilationMode=$compilation_mode"
fi
if [ -z "$core_root_directory" ]; then
@@ -191,11 +198,15 @@ if [[ "$mono_dotnet" != "" ]]; then
configurations="$configurations LLVM=$llvm MonoInterpreter=$monointerpreter MonoAOT=$monoaot"
fi
+if [[ "$wasm_runtime_loc" != "" ]]; then
+ configurations="CompilationMode=wasm;RunKind=micro"
+fi
+
if [[ "$monointerpreter" == "true" ]]; then
- extra_benchmark_dotnet_arguments="--category-exclusion-filter NoInterpreter"
+ extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --category-exclusion-filter NoInterpreter"
fi
-common_setup_arguments="--channel master --queue $queue --build-number $build_number --build-configs $configurations --architecture $architecture"
+common_setup_arguments="--channel master --queue $queue --build-number $build_number --build-configs \"$configurations\" --architecture $architecture"
setup_arguments="--repository https://github.com/$repository --branch $branch --get-perf-hash --commit-sha $commit_sha $common_setup_arguments"
@@ -217,6 +228,17 @@ else
mv $docs_directory $workitem_directory
fi
+if [[ "$wasm_runtime_loc" != "" ]]; then
+ using_wasm=true
+
+ wasm_dotnet_path=$payload_directory/dotnet-wasm
+
+ mv $wasm_runtime_loc $wasm_dotnet_path
+
+ extra_benchmark_dotnet_arguments="$extra_benchmark_dotnet_arguments --wasmMainJS \$HELIX_CORRELATION_PAYLOAD/dotnet-wasm/runtime-test.js --wasmEngine /home/helixbot/.jsvu/v8 --customRuntimePack \$HELIX_CORRELATION_PAYLOAD/dotnet-wasm"
+
+fi
+
if [[ "$mono_dotnet" != "" ]]; then
using_mono=true
mono_dotnet_path=$payload_directory/dotnet-mono
@@ -259,3 +281,4 @@ Write-PipelineSetVariable -name "Kind" -value "$kind" -is_multi_job_variable fal
Write-PipelineSetVariable -name "_BuildConfig" -value "$architecture.$kind.$framework" -is_multi_job_variable false
Write-PipelineSetVariable -name "Compare" -value "$compare" -is_multi_job_variable false
Write-PipelineSetVariable -name "MonoDotnet" -value "$using_mono" -is_multi_job_variable false
+Write-PipelineSetVariable -name "WasmDotnet" -value "$using_wasm" -is_multi_job_variable false
diff --git a/eng/common/templates/steps/perf-send-to-helix.yml b/eng/common/templates/steps/perf-send-to-helix.yml
index b3ea9acf1f1607..1e3bed764cfaca 100644
--- a/eng/common/templates/steps/perf-send-to-helix.yml
+++ b/eng/common/templates/steps/perf-send-to-helix.yml
@@ -1,10 +1,11 @@
# Please remember to update the documentation if you make changes to these parameters!
parameters:
+ ProjectFile: '' # required -- project file that specifies the helix workitems
HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/
HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/'
HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number
- HelixTargetQueues: '' # required -- semicolon delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues
- HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group
+ HelixTargetQueues: '' # required -- semicolon delimited list of Helix queues to test on; see https://helix.dot.net/ for a list 0of queues
+ HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group
HelixPreCommands: '' # optional -- commands to run before Helix work item execution
HelixPostCommands: '' # optional -- commands to run after Helix work item execution
WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects
@@ -18,9 +19,10 @@ parameters:
DisplayNamePrefix: 'Send job to Helix' # optional -- rename the beginning of the displayName of the steps in AzDO
condition: succeeded() # optional -- condition for step to execute; defaults to succeeded()
continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false
+
steps:
- - powershell: $(Build.SourcesDirectory)\eng\common\msbuild.ps1 $(Build.SourcesDirectory)\eng\common\performance\perfhelixpublish.proj /restore /t:Test /bl:$(Build.SourcesDirectory)\artifacts\log\$env:BuildConfig\SendToHelix.binlog
+ - powershell: $(Build.SourcesDirectory)\eng\common\msbuild.ps1 $(Build.SourcesDirectory)\eng\common\performance\${{ parameters.ProjectFile }} /restore /t:Test /bl:$(Build.SourcesDirectory)\artifacts\log\$env:BuildConfig\SendToHelix.binlog
displayName: ${{ parameters.DisplayNamePrefix }} (Windows)
env:
BuildConfig: $(_BuildConfig)
@@ -42,7 +44,7 @@ steps:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT'))
continueOnError: ${{ parameters.continueOnError }}
- - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/performance/perfhelixpublish.proj /restore /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog
+ - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/performance/${{ parameters.ProjectFile }} /restore /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog
displayName: ${{ parameters.DisplayNamePrefix }} (Unix)
env:
BuildConfig: $(_BuildConfig)
diff --git a/eng/illink.targets b/eng/illink.targets
index 601b0b798fbca7..d27feb5f466242 100644
--- a/eng/illink.targets
+++ b/eng/illink.targets
@@ -27,7 +27,7 @@
$([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NET_ILLink_Tasks)', 'tools'))
$(ILLinkTasksDir)netcoreapp3.0/ILLink.Tasks.dll
- $(ILLinkTasksDir)$(NetFrameworkCurrent)/ILLink.Tasks.dll
+ $(ILLinkTasksDir)net472/ILLink.Tasks.dll
$(IntermediateOutputPath)$(TargetName)$(TargetExt)
$(IntermediateOutputPath)$(TargetName).pdb
$(IntermediateOutputPath)PreTrim/
@@ -184,22 +184,37 @@
+
+
+
+
+ $(ILLinkArgs) -t
+
+
+ $(ILLinkArgs) --strip-link-attributes false --ignore-link-attributes true
+
+ $(ILLinkArgs) --skip-unresolved true
+
+ $(ILLinkArgs) --disable-opt unusedinterfaces
+
+
+
-
+
- $(ILLinkArgs)-r $(TargetName)
+ $(ILLinkArgs) -r $(TargetName)
$(ILLinkArgs) -c skip
$(ILLinkArgs) -u skip
$(ILLinkArgs) -p link $(TargetName)
-
- $(ILLinkArgs) -t
$(ILLinkArgs) -b true
$(ILLinkArgs) --strip-descriptors false
@@ -207,15 +222,21 @@
$(ILLinkArgs) -x "$(ILLinkTrimXmlLibraryBuild)"
$(ILLinkArgs) --strip-substitutions false
-
-
- $(ILLinkArgs) --strip-link-attributes false --ignore-link-attributes true
-
- $(ILLinkArgs) --skip-unresolved true
-
- $(ILLinkArgs) --disable-opt unusedinterfaces
$(ILLinkArgs) --keep-dep-attributes true
+
+ $(ILLinkArgs) --nowarn IL2006;IL2008;IL2009;IL2012;IL2025;IL2026;IL2035;IL2050
@@ -255,9 +276,8 @@
- <_DotNetHostDirectory>$(NetCoreRoot)
- <_DotNetHostFileName>dotnet
- <_DotNetHostFileName Condition=" '$(OS)' == 'Windows_NT' ">dotnet.exe
+ <_DotNetHostDirectory>$(DotNetRoot)
+ <_DotNetHostFileName>$([System.IO.Path]::GetFileName('$(DotNetTool)'))
&1 | grep -q \\-B; then
- echo "Please install cmake v3.14.5 or newer from https://www.cmake.org/download/."
- exit 1
- fi
-
if [[ "$__HostOS" == "OSX" ]]; then
# Check presence of pkg-config on the path
command -v pkg-config 2>/dev/null || { echo >&2 "Please install pkg-config before running this script, see https://github.com/dotnet/runtime/blob/master/docs/workflow/requirements/macos-requirements.md"; exit 1; }
@@ -177,8 +172,8 @@ EOF
cmake_command="emcmake $cmake_command"
fi
- echo "Executing $cmake_command --build \"$intermediatesDir\" --target install -j $__NumProc"
- $cmake_command --build "$intermediatesDir" --target install -j "$__NumProc"
+ echo "Executing $cmake_command --build \"$intermediatesDir\" --target install -- -j $__NumProc"
+ $cmake_command --build "$intermediatesDir" --target install -- -j "$__NumProc"
fi
local exit_code="$?"
@@ -234,6 +229,20 @@ __BuildOS=$os
__msbuildonunsupportedplatform=0
+# Get the number of processors available to the scheduler
+# Other techniques such as `nproc` only get the number of
+# processors available to a single process.
+platform="$(uname)"
+if [[ "$platform" == "FreeBSD" ]]; then
+ __NumProc=$(sysctl hw.ncpu | awk '{ print $2+1 }')
+elif [[ "$platform" == "NetBSD" || "$platform" == "SunOS" ]]; then
+ __NumProc=$(($(getconf NPROCESSORS_ONLN)+1))
+elif [[ "$platform" == "Darwin" ]]; then
+ __NumProc=$(($(getconf _NPROCESSORS_ONLN)+1))
+else
+ __NumProc=$(nproc --all)
+fi
+
while :; do
if [[ "$#" -le 0 ]]; then
break
@@ -400,20 +409,6 @@ while :; do
shift
done
-# Get the number of processors available to the scheduler
-# Other techniques such as `nproc` only get the number of
-# processors available to a single process.
-platform="$(uname)"
-if [[ "$platform" == "FreeBSD" ]]; then
- __NumProc=$(sysctl hw.ncpu | awk '{ print $2+1 }')
-elif [[ "$platform" == "NetBSD" || "$platform" == "SunOS" ]]; then
- __NumProc=$(($(getconf NPROCESSORS_ONLN)+1))
-elif [[ "$platform" == "Darwin" ]]; then
- __NumProc=$(($(getconf _NPROCESSORS_ONLN)+1))
-else
- __NumProc=$(nproc --all)
-fi
-
__CommonMSBuildArgs="/p:TargetArchitecture=$__BuildArch /p:Configuration=$__BuildType /p:TargetOS=$__TargetOS /nodeReuse:false $__OfficialBuildIdArg $__SignTypeArg $__SkipRestoreArg"
# Configure environment if we are doing a verbose build
diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake
index 9d1b88f080113b..02611fa19272e5 100644
--- a/eng/native/configurecompiler.cmake
+++ b/eng/native/configurecompiler.cmake
@@ -8,8 +8,6 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
-cmake_policy(SET CMP0083 NEW)
-
include(CheckCXXCompilerFlag)
# "configureoptimization.cmake" must be included after CLR_CMAKE_HOST_UNIX has been set.
@@ -19,9 +17,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/configureoptimization.cmake)
# Initialize Cmake compiler flags and other variables
#-----------------------------------------------------
-if(MSVC)
- add_compile_options(/Zi /FC /Zc:strictStrings)
-elseif (CLR_CMAKE_HOST_UNIX)
+if (CLR_CMAKE_HOST_UNIX)
add_compile_options(-g)
add_compile_options(-Wall)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
@@ -40,11 +36,18 @@ set(CMAKE_CXX_FLAGS_CHECKED "")
set(CMAKE_EXE_LINKER_FLAGS_CHECKED "")
set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "")
+set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "")
+set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "")
+set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "")
+set(CMAKE_EXE_LINKER_FLAGS_DEBUG "")
+set(CMAKE_EXE_LINKER_FLAGS_DEBUG "")
+set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "")
+
add_compile_definitions("$<$,$>:DEBUG;_DEBUG;_DBG;URTBLDENV_FRIENDLY=Checked;BUILDENV_CHECKED=1>")
add_compile_definitions("$<$,$>:NDEBUG;URTBLDENV_FRIENDLY=Retail>")
if (MSVC)
- add_link_options(/GUARD:CF)
+ add_linker_flag(/GUARD:CF)
# Linker flags
#
@@ -57,48 +60,51 @@ if (MSVC)
endif ()
#Do not create Side-by-Side Assembly Manifest
- add_link_options($<$,SHARED_LIBRARY>:/MANIFEST:NO>)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO")
# can handle addresses larger than 2 gigabytes
- add_link_options($<$,SHARED_LIBRARY>:/LARGEADDRESSAWARE>)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LARGEADDRESSAWARE")
#Compatible with Data Execution Prevention
- add_link_options($<$,SHARED_LIBRARY>:/NXCOMPAT>)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NXCOMPAT")
#Use address space layout randomization
- add_link_options($<$,SHARED_LIBRARY>:/DYNAMICBASE>)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DYNAMICBASE")
#shrink pdb size
- add_link_options($<$,SHARED_LIBRARY>:/PDBCOMPRESS>)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /PDBCOMPRESS")
- add_link_options($<$,SHARED_LIBRARY>:/DEBUG>)
- add_link_options($<$,SHARED_LIBRARY>:/IGNORE:4197,4013,4254,4070,4221>)
- add_link_options($<$,SHARED_LIBRARY>:/SUBSYSTEM:WINDOWS,${WINDOWS_SUBSYSTEM_VERSION}>)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEBUG")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4197,4013,4254,4070,4221")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,${WINDOWS_SUBSYSTEM_VERSION}")
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221")
- add_link_options($<$,EXECUTABLE>:/DEBUG>)
- add_link_options($<$,EXECUTABLE>:/PDBCOMPRESS>)
- add_link_options($<$,EXECUTABLE>:/STACK:1572864>)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /PDBCOMPRESS")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:1572864")
# Debug build specific flags
- add_link_options($<$,$>,$,SHARED_LIBRARY>>:/NOVCFEATURE>)
+ set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /NOVCFEATURE")
+ set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "${CMAKE_SHARED_LINKER_FLAGS_CHECKED} /NOVCFEATURE")
# Checked build specific flags
- add_link_options($<$:/INCREMENTAL:NO>) # prevent "warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:REF' specification"
- add_link_options($<$:/OPT:REF>)
- add_link_options($<$:/OPT:NOICF>)
+ add_linker_flag(/INCREMENTAL:NO CHECKED) # prevent "warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:REF' specification"
+ add_linker_flag(/OPT:REF CHECKED)
+ add_linker_flag(/OPT:NOICF CHECKED)
# Release build specific flags
- add_link_options($<$:/LTCG>)
- add_link_options($<$:/OPT:REF>)
- add_link_options($<$:/OPT:ICF>)
+ add_linker_flag(/LTCG RELEASE)
+ add_linker_flag(/OPT:REF RELEASE)
+ add_linker_flag(/OPT:ICF RELEASE)
+ add_linker_flag(/INCREMENTAL:NO RELEASE)
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
# ReleaseWithDebugInfo build specific flags
- add_link_options($<$:/LTCG>)
- add_link_options($<$:/OPT:REF>)
- add_link_options($<$:/OPT:ICF>)
+ add_linker_flag(/LTCG RELWITHDEBINFO)
+ add_linker_flag(/OPT:REF RELWITHDEBINFO)
+ add_linker_flag(/OPT:ICF RELWITHDEBINFO)
set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
# Force uCRT to be dynamically linked for Release build
- add_link_options("$<$:/NODEFAULTLIB:libucrt.lib;/DEFAULTLIB:ucrt.lib>")
+ add_linker_flag(/NODEFAULTLIB:libucrt.lib RELEASE)
+ add_linker_flag(/DEFAULTLIB:ucrt.lib RELEASE)
elseif (CLR_CMAKE_HOST_UNIX)
# Set the values to display when interactively configuring CMAKE_BUILD_TYPE
@@ -157,11 +163,10 @@ elseif (CLR_CMAKE_HOST_UNIX)
# -fdata-sections -ffunction-sections: each function has own section instead of one per .o file (needed for --gc-sections)
# -O1: optimization level used instead of -O0 to avoid compile error "invalid operand for inline asm constraint"
- add_compile_definitions("$<$,$>:${CLR_SANITIZE_CXX_OPTIONS};-fdata-sections;--ffunction-sections;-O1>")
- add_link_options($<$,$>,$,EXECUTABLE>>:${CLR_SANITIZE_LINK_OPTIONS}>)
-
+ add_compile_options("$<$,$>:${CLR_SANITIZE_CXX_OPTIONS};-fdata-sections;--ffunction-sections;-O1>")
+ add_linker_flag("${CLR_SANITIZE_LINK_OPTIONS}" DEBUG CHECKED)
# -Wl and --gc-sections: drop unused sections\functions (similar to Windows /Gy function-level-linking)
- add_link_options("$<$,$>,$,SHARED_LIBRARY>>:${CLR_SANITIZE_LINK_OPTIONS};-Wl,--gc-sections>")
+ add_linker_flag("-Wl,--gc-sections" DEBUG CHECKED)
endif ()
endif(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL CHECKED)
endif(MSVC)
@@ -173,15 +178,18 @@ endif(MSVC)
# ./build-native.sh cmakeargs "-DCLR_ADDITIONAL_COMPILER_OPTIONS=<...>" cmakeargs "-DCLR_ADDITIONAL_LINKER_FLAGS=<...>"
#
if(CLR_CMAKE_HOST_UNIX)
- add_link_options(${CLR_ADDITIONAL_LINKER_FLAGS})
+ foreach(ADDTL_LINKER_FLAG ${CLR_ADDITIONAL_LINKER_FLAGS})
+ add_linker_flag(${ADDTL_LINKER_FLAG})
+ endforeach()
endif(CLR_CMAKE_HOST_UNIX)
if(CLR_CMAKE_HOST_LINUX)
add_compile_options($<$:-Wa,--noexecstack>)
- add_link_options(-Wl,--build-id=sha1 -Wl,-z,relro,-z,now)
+ add_linker_flag(-Wl,--build-id=sha1)
+ add_linker_flag(-Wl,-z,relro,-z,now)
elseif(CLR_CMAKE_HOST_FREEBSD)
add_compile_options($<$:-Wa,--noexecstack>)
- add_link_options(LINKER:--build-id=sha1)
+ add_linker_flag("-Wl,--build-id=sha1")
elseif(CLR_CMAKE_HOST_SUNOS)
add_compile_options($<$:-Wa,--noexecstack>)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
@@ -361,7 +369,7 @@ if (CLR_CMAKE_HOST_UNIX)
if(CLR_CMAKE_HOST_OSX)
set(MACOS_VERSION_MIN_FLAGS -mmacosx-version-min=10.12)
add_compile_options(${MACOS_VERSION_MIN_FLAGS})
- add_link_options(${MACOS_VERSION_MIN_FLAGS})
+ add_linker_flag(${MACOS_VERSION_MIN_FLAGS})
endif(CLR_CMAKE_HOST_OSX)
endif(CLR_CMAKE_HOST_UNIX)
@@ -417,25 +425,20 @@ endif(CLR_CMAKE_HOST_UNIX)
if (MSVC)
# Compile options for targeting windows
- # The following options are set by the razzle build
add_compile_options(/TP) # compile all files as C++
add_compile_options(/nologo) # Suppress Startup Banner
add_compile_options(/W3) # set warning level to 3
add_compile_options(/WX) # treat warnings as errors
add_compile_options(/Oi) # enable intrinsics
add_compile_options(/Oy-) # disable suppressing of the creation of frame pointers on the call stack for quicker function calls
- add_compile_options(/U_MT) # undefine the predefined _MT macro
- add_compile_options(/GF) # enable read-only string pooling
add_compile_options(/Gm-) # disable minimal rebuild
add_compile_options(/Zp8) # pack structs on 8-byte boundary
add_compile_options(/Gy) # separate functions for linker
- add_compile_options(/Zc:wchar_t-) # C++ language conformance: wchar_t is NOT the native type, but a typedef
- add_compile_options(/Zc:forScope) # C++ language conformance: enforce Standard C++ for scoping rules
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-") # disable C++ RTTI
add_compile_options(/FC) # use full pathnames in diagnostics
add_compile_options(/MP) # Build with Multiple Processes (number of processes equal to the number of processors)
- add_compile_options(/GS) # Buffer Security Check
add_compile_options(/Zm200) # Specify Precompiled Header Memory Allocation Limit of 150MB
+ add_compile_options(/Zc:strictStrings) # Disable string-literal to char* or wchar_t* conversion
add_compile_options(/wd4960 /wd4961 /wd4603 /wd4627 /wd4838 /wd4456 /wd4457 /wd4458 /wd4459 /wd4091 /we4640)
@@ -517,7 +520,7 @@ if(CLR_CMAKE_ENABLE_CODE_COVERAGE)
add_compile_options(-fprofile-arcs)
add_compile_options(-ftest-coverage)
- add_link_options(--coverage)
+ add_linker_flag(--coverage)
else()
message(FATAL_ERROR "Code coverage builds not supported on current platform")
endif(CLR_CMAKE_HOST_UNIX)
diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake
index c65274141dd49c..dbfadfda599146 100644
--- a/eng/native/configureplatform.cmake
+++ b/eng/native/configureplatform.cmake
@@ -1,4 +1,3 @@
-include(CheckPIESupported)
include(${CMAKE_CURRENT_LIST_DIR}/functions.cmake)
# If set, indicates that this is not an officially supported release
@@ -382,24 +381,11 @@ else()
endif()
if(NOT CLR_CMAKE_TARGET_BROWSER)
- # Skip check_pie_supported call on Android as ld from llvm toolchain with NDK API level 21
- # complains about missing linker flag `-no-pie` (while level 28's ld does support this flag,
- # but since we know that PIE is supported, we can safely skip this redundant check).
- #
# The default linker on Solaris also does not support PIE.
- if(NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_SUNOS)
- # All code we build should be compiled as position independent
- get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
- if("CXX" IN_LIST languages)
- set(CLR_PIE_LANGUAGE CXX)
- else()
- set(CLR_PIE_LANGUAGE C)
- endif()
- check_pie_supported(OUTPUT_VARIABLE PIE_SUPPORT_OUTPUT LANGUAGES ${CLR_PIE_LANGUAGE})
- if(NOT MSVC AND NOT CMAKE_${CLR_PIE_LANGUAGE}_LINK_PIE_SUPPORTED)
- message(WARNING "PIE is not supported at link time: ${PIE_SUPPORT_OUTPUT}.\n"
- "PIE link options will not be passed to linker.")
- endif()
+ if(NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_SUNOS AND NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_HOST_TVOS AND NOT CLR_CMAKE_HOST_IOS AND NOT MSVC)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
+ add_compile_options($<$,EXECUTABLE>:-fPIE>)
+ add_compile_options($<$,SHARED_LIBRARY>:-fPIC>)
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
diff --git a/eng/native/functions.cmake b/eng/native/functions.cmake
index 8b73581ed1426a..1509a17fa59b0a 100644
--- a/eng/native/functions.cmake
+++ b/eng/native/functions.cmake
@@ -148,7 +148,7 @@ function(preprocess_compile_asm)
set(options "")
set(oneValueArgs TARGET OUTPUT_OBJECTS)
set(multiValueArgs ASM_FILES)
- cmake_parse_arguments(PARSE_ARGV 0 COMPILE_ASM "${options}" "${oneValueArgs}" "${multiValueArgs}")
+ cmake_parse_arguments(COMPILE_ASM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV})
get_include_directories_asm(ASM_INCLUDE_DIRECTORIES)
@@ -241,7 +241,7 @@ function(target_precompile_header)
set(options "")
set(oneValueArgs TARGET HEADER)
set(multiValueArgs ADDITIONAL_INCLUDE_DIRECTORIES)
- cmake_parse_arguments(PARSE_ARGV 0 PRECOMPILE_HEADERS "${options}" "${oneValueArgs}" "${multiValueArgs}")
+ cmake_parse_arguments(PRECOMPILE_HEADERS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV})
if ("${PRECOMPILE_HEADERS_TARGET}" STREQUAL "")
message(SEND_ERROR "No target supplied to target_precompile_header.")
@@ -360,7 +360,7 @@ endfunction()
function(install_clr)
set(oneValueArgs ADDITIONAL_DESTINATION)
set(multiValueArgs TARGETS)
- cmake_parse_arguments(PARSE_ARGV 0 INSTALL_CLR "${options}" "${oneValueArgs}" "${multiValueArgs}")
+ cmake_parse_arguments(INSTALL_CLR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV})
if ("${INSTALL_CLR_TARGETS}" STREQUAL "")
message(FATAL_ERROR "At least one target must be passed to install_clr(TARGETS )")
@@ -416,6 +416,15 @@ function(disable_pax_mprotect targetName)
endif()
endfunction()
+if (CMAKE_VERSION VERSION_LESS "3.12")
+ # Polyfill add_compile_definitions when it is unavailable
+ function(add_compile_definitions)
+ get_directory_property(DIR_COMPILE_DEFINITIONS COMPILE_DEFINITIONS)
+ list(APPEND DIR_COMPILE_DEFINITIONS ${ARGV})
+ set_directory_properties(PROPERTIES COMPILE_DEFINITIONS "${DIR_COMPILE_DEFINITIONS}")
+ endfunction()
+endif()
+
function(_add_executable)
if(NOT WIN32)
add_executable(${ARGV} ${VERSION_FILE_PATH})
@@ -479,3 +488,16 @@ function(generate_module_index Target ModuleIndexFile)
DEPENDS ${ModuleIndexFile}
)
endfunction(generate_module_index)
+
+# add_linker_flag(Flag [Config1 Config2 ...])
+function(add_linker_flag Flag)
+ if (ARGN STREQUAL "")
+ set("CMAKE_EXE_LINKER_FLAGS" "${CMAKE_EXE_LINKER_FLAGS} ${Flag}" PARENT_SCOPE)
+ set("CMAKE_SHARED_LINKER_FLAGS" "${CMAKE_SHARED_LINKER_FLAGS} ${Flag}" PARENT_SCOPE)
+ else()
+ foreach(Config ${ARGN})
+ set("CMAKE_EXE_LINKER_FLAGS_${Config}" "${CMAKE_EXE_LINKER_FLAGS_${Config}} ${Flag}" PARENT_SCOPE)
+ set("CMAKE_SHARED_LINKER_FLAGS_${Config}" "${CMAKE_SHARED_LINKER_FLAGS_${Config}} ${Flag}" PARENT_SCOPE)
+ endforeach()
+ endif()
+endfunction()
diff --git a/eng/native/gen-buildsys.sh b/eng/native/gen-buildsys.sh
index f27bb33e357785..1b4c2e02c597fd 100755
--- a/eng/native/gen-buildsys.sh
+++ b/eng/native/gen-buildsys.sh
@@ -91,6 +91,9 @@ if [[ "$build_arch" == "wasm" ]]; then
cmake_command="emcmake $cmake_command"
fi
+# We have to be able to build with CMake 3.6.2, so we can't use the -S or -B options
+pushd "$3"
+
# Include CMAKE_USER_MAKE_RULES_OVERRIDE as uninitialized since it will hold its value in the CMake cache otherwise can cause issues when branch switching
$cmake_command \
-G "$generator" \
@@ -98,5 +101,6 @@ $cmake_command \
"-DCMAKE_INSTALL_PREFIX=$__CMakeBinDir" \
$cmake_extra_defines \
$__UnprocessedCMakeArgs \
- -S "$1" \
- -B "$3"
+ "$1"
+
+popd
diff --git a/eng/packaging.targets b/eng/packaging.targets
index e0f7edaeac7f1a..0891a5a2f9f468 100644
--- a/eng/packaging.targets
+++ b/eng/packaging.targets
@@ -26,4 +26,16 @@
'$(_excludeCompile)' == 'true' and
'%(Dependency.Identity)' != '_._'" />
-
\ No newline at end of file
+
+
+ $(MSBuildProjectDirectory)\..\pkg\$(MSBuildProjectName).pkgproj
+
+ _BuildPkgProj
+
+
+
+
+
+
diff --git a/eng/pipelines/common/createdump-entitlements.plist b/eng/pipelines/common/createdump-entitlements.plist
new file mode 100644
index 00000000000000..1f2d3798ee2f6e
--- /dev/null
+++ b/eng/pipelines/common/createdump-entitlements.plist
@@ -0,0 +1,12 @@
+
+
+
+
+ com.apple.security.cs.allow-dyld-environment-variables
+
+ com.apple.security.cs.disable-library-validation
+
+ com.apple.security.cs.debugger
+
+
+
diff --git a/eng/pipelines/common/entitlements.plist b/eng/pipelines/common/entitlements.plist
new file mode 100644
index 00000000000000..f4ea418fb45a8d
--- /dev/null
+++ b/eng/pipelines/common/entitlements.plist
@@ -0,0 +1,18 @@
+
+
+
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.cs.allow-unsigned-executable-memory
+
+ com.apple.security.cs.allow-dyld-environment-variables
+
+ com.apple.security.cs.disable-library-validation
+
+ com.apple.security.cs.debugger
+
+ com.apple.security.get-task-allow
+
+
+
diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml
index dcbba9fb3654f5..3f22f762be8c3d 100644
--- a/eng/pipelines/common/global-build-job.yml
+++ b/eng/pipelines/common/global-build-job.yml
@@ -25,11 +25,17 @@ jobs:
dependsOn: checkout
pool: ${{ parameters.pool }}
container: ${{ parameters.container }}
- timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
condition: and(succeeded(), ${{ parameters.condition }})
workspace:
clean: all
+ # macOS hosted pool machines are slower so we need to give a greater timeout for global-build
+ # which builds multiple subsets.
+ ${{ if and(contains(parameters.pool.vmImage, 'macOS'), eq(parameters.timeoutInMinutes, '')) }}:
+ timeoutInMinutes: 120
+ ${{ if or(not(contains(parameters.pool.vmImage, 'macOS')), ne(parameters.timeoutInMinutes, '')) }}:
+ timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+
variables:
- name: _osParameter
value: -os ${{ parameters.osGroup }}
diff --git a/eng/pipelines/common/macos-sign-with-entitlements.yml b/eng/pipelines/common/macos-sign-with-entitlements.yml
new file mode 100644
index 00000000000000..6c65193845d70c
--- /dev/null
+++ b/eng/pipelines/common/macos-sign-with-entitlements.yml
@@ -0,0 +1,65 @@
+parameters:
+ filesToSign: []
+
+steps:
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core SDK 2.1.808'
+ inputs:
+ packageType: sdk
+ version: 2.1.808
+
+ - ${{ each file in parameters.filesToSign }}:
+ - script: codesign -s - -f --entitlements ${{ file.entitlementsFile }} ${{ file.path }}/${{ file.name }}
+ displayName: 'Add entitlements to ${{ file.name }}'
+
+ - task: CopyFiles@2
+ displayName: 'Copy entitled file ${{ file.name }}'
+ inputs:
+ contents: '${{ file.path }}/${{ file.name }}'
+ targetFolder: '$(Build.ArtifactStagingDirectory)/mac_entitled'
+ overWrite: true
+
+ - task: ArchiveFiles@2
+ displayName: 'Zip MacOS files for signing'
+ inputs:
+ rootFolderOrFile: '$(Build.ArtifactStagingDirectory)/mac_entitled'
+ archiveFile: '$(Build.ArtifactStagingDirectory)/mac_entitled_to_sign.zip'
+ archiveType: zip
+ includeRootFolder: true
+ replaceExistingArchive: true
+
+ - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
+ displayName: 'ESRP CodeSigning'
+ inputs:
+ ConnectedServiceName: 'ESRP CodeSigning'
+ FolderPath: '$(Build.ArtifactStagingDirectory)/'
+ Pattern: 'mac_entitled_to_sign.zip'
+ UseMinimatch: true
+ signConfigType: inlineSignParams
+ inlineOperation: |
+ [
+ {
+ "keyCode": "CP-401337-Apple",
+ "operationCode": "MacAppDeveloperSign",
+ "parameters" : {
+ "hardening": "Enable"
+ },
+ "toolName": "sign",
+ "toolVersion": "1.0"
+ }
+ ]
+
+ - task: ExtractFiles@1
+ displayName: 'Extract MacOS after signing'
+ inputs:
+ archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/mac_entitled_to_sign.zip'
+ destinationFolder: '$(Build.ArtifactStagingDirectory)/mac_entitled_signed'
+
+ - ${{ each file in parameters.filesToSign }}:
+ - task: CopyFiles@2
+ displayName: 'Copy ${{ file.name }} to destination'
+ inputs:
+ contents: ${{ file.name }}
+ sourceFolder: '$(Build.ArtifactStagingDirectory)/mac_entitled_signed'
+ targetFolder: '${{ file.path }}'
+ overWrite: true
diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml
index b4f80202400629..a7a3a167004c22 100644
--- a/eng/pipelines/common/platform-matrix.yml
+++ b/eng/pipelines/common/platform-matrix.yml
@@ -86,11 +86,7 @@ jobs:
archType: x64
platform: Linux_musl_x64
container:
- # alpine coreclr cmake errors on newer builds
- ${{ if eq(parameters.runtimeFlavor, 'mono') }}:
- image: alpine-3.9-WithNode-0fc54a3-20200131134036
- ${{ if eq(parameters.runtimeFlavor, 'coreclr') }}:
- image: alpine-3.9-WithNode-0fc54a3-20190918214015
+ image: alpine-3.9-WithNode-20200602002639-0fc54a3
registry: mcr
jobParameters:
runtimeFlavor: ${{ parameters.runtimeFlavor }}
diff --git a/eng/pipelines/common/templates/runtimes/build-test-job.yml b/eng/pipelines/common/templates/runtimes/build-test-job.yml
index 0f3c188d20e89a..56fa8dffddc1b7 100644
--- a/eng/pipelines/common/templates/runtimes/build-test-job.yml
+++ b/eng/pipelines/common/templates/runtimes/build-test-job.yml
@@ -22,6 +22,7 @@ parameters:
runtimeFlavor: 'coreclr'
runtimeFlavorDisplayName: 'CoreCLR'
runtimeVariant: ''
+ dependsOn: []
### Build managed test components (native components are getting built as part
### of the the product build job).
@@ -63,10 +64,13 @@ jobs:
# See https://docs.microsoft.com/azure/devops/pipelines/process/conditions
condition: and(succeeded(), ${{ parameters.condition }})
+ ${{ if ne(parameters.dependsOn[0], '') }}:
+ dependsOn: ${{ parameters.dependsOn }}
+
# TODO: Build of managed test components currently depends on the corresponding build job
# because it needs System.Private.Corelib; we should be able to remove this dependency
# by switching over to using reference assembly.
- ${{ if ne(parameters.stagedBuild, true) }}:
+ ${{ if and(ne(parameters.stagedBuild, true), eq(parameters.dependsOn[0], '')) }}:
dependsOn:
- ${{ format('coreclr_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, coalesce(parameters.liveRuntimeBuildConfig, parameters.buildConfig)) }}
- ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}:
diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml
index 39616a833b0e4c..4d93701584fe62 100644
--- a/eng/pipelines/common/templates/runtimes/run-test-job.yml
+++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml
@@ -20,6 +20,7 @@ parameters:
pool: ''
runtimeFlavor: 'coreclr'
runtimeFlavorDisplayName: 'CoreCLR'
+ dependsOn: []
### Test run job
@@ -47,15 +48,19 @@ jobs:
${{ if eq(variables['System.TeamProject'], 'internal') }}:
continueOnError: true
- dependsOn:
- - ${{ if in(parameters.testGroup, 'innerloop', 'clrinterpreter') }}:
- - '${{ parameters.runtimeFlavor }}_common_test_build_p0_AnyOS_AnyCPU_${{parameters.buildConfig }}'
- - ${{ if notIn(parameters.testGroup, 'innerloop', 'clrinterpreter') }}:
- - '${{ parameters.runtimeFlavor }}_common_test_build_p1_AnyOS_AnyCPU_${{parameters.buildConfig }}'
- - ${{ if ne(parameters.stagedBuild, true) }}:
- - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
- - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}:
- - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }}
+ ${{ if ne(parameters.dependsOn[0], '') }}:
+ dependsOn: ${{ parameters.dependsOn }}
+
+ ${{ if eq(parameters.dependsOn[0], '') }}:
+ dependsOn:
+ - ${{ if in(parameters.testGroup, 'innerloop', 'clrinterpreter') }}:
+ - '${{ parameters.runtimeFlavor }}_common_test_build_p0_AnyOS_AnyCPU_${{parameters.buildConfig }}'
+ - ${{ if notIn(parameters.testGroup, 'innerloop', 'clrinterpreter') }}:
+ - '${{ parameters.runtimeFlavor }}_common_test_build_p1_AnyOS_AnyCPU_${{parameters.buildConfig }}'
+ - ${{ if ne(parameters.stagedBuild, true) }}:
+ - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
+ - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}:
+ - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }}
# Compute job name from template parameters
${{ if in(parameters.testGroup, 'innerloop', 'clrinterpreter') }}:
diff --git a/eng/pipelines/coreclr/ci.yml b/eng/pipelines/coreclr/ci.yml
index 7e72c87e16b866..c58c4804174b15 100644
--- a/eng/pipelines/coreclr/ci.yml
+++ b/eng/pipelines/coreclr/ci.yml
@@ -164,4 +164,5 @@ jobs:
jobTemplate: /eng/pipelines/coreclr/templates/format-job.yml
platforms:
- Linux_x64
- - Windows_NT_x64
+ # Isssue: https://github.com/dotnet/runtime/issues/40034
+ #- Windows_NT_x64
diff --git a/eng/pipelines/coreclr/crossgen2-gcstress.yml b/eng/pipelines/coreclr/crossgen2-gcstress.yml
new file mode 100644
index 00000000000000..7942e747e26f64
--- /dev/null
+++ b/eng/pipelines/coreclr/crossgen2-gcstress.yml
@@ -0,0 +1,60 @@
+trigger: none
+
+pr: none
+
+schedules:
+- cron: "0 6 * * 0,1"
+ displayName: Sat and Sun at 10:00 PM (UTC-8:00)
+ branches:
+ include:
+ - master
+ always: true
+
+jobs:
+#
+# Checkout repository
+#
+- template: /eng/pipelines/common/checkout-job.yml
+
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/build-coreclr-and-libraries-job.yml
+ buildConfig: checked
+ platforms:
+ - Linux_x64
+ - Linux_arm64
+ - OSX_x64
+ - Windows_NT_x64
+ - Windows_NT_arm64
+ - CoreClrTestBuildHost # Either OSX_x64 or Linux_x64
+ jobParameters:
+ testGroup: gcstress-extra
+
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/templates/runtimes/build-test-job.yml
+ buildConfig: checked
+ platforms:
+ - CoreClrTestBuildHost # Either OSX_x64 or Linux_x64
+ jobParameters:
+ testGroup: gcstress-extra
+ liveLibrariesBuildConfig: Release
+
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
+ buildConfig: checked
+ platforms:
+ - Linux_x64
+ - Linux_arm64
+ - OSX_x64
+ - Windows_NT_x64
+ - Windows_NT_arm64
+ jobParameters:
+ testGroup: gcstress-extra
+ readyToRun: true
+ crossgen2: true
+ compositeBuildMode: true
+ displayNameArgs: Composite
+ liveLibrariesBuildConfig: Release
diff --git a/eng/pipelines/coreclr/jitstress.yml b/eng/pipelines/coreclr/jitstress.yml
index 5bd57f564e4c4b..adb906ea7bf26d 100644
--- a/eng/pipelines/coreclr/jitstress.yml
+++ b/eng/pipelines/coreclr/jitstress.yml
@@ -28,7 +28,6 @@ jobs:
- Linux_x64
- Windows_NT_x64
- Windows_NT_x86
- - Windows_NT_arm
- Windows_NT_arm64
- CoreClrTestBuildHost # Either OSX_x64 or Linux_x64
jobParameters:
@@ -56,7 +55,6 @@ jobs:
- Linux_x64
- Windows_NT_x64
- Windows_NT_x86
- - Windows_NT_arm
- Windows_NT_arm64
helixQueueGroup: ci
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
diff --git a/eng/pipelines/coreclr/jitstress2-jitstressregs.yml b/eng/pipelines/coreclr/jitstress2-jitstressregs.yml
index b163671960a1df..743e071e08e899 100644
--- a/eng/pipelines/coreclr/jitstress2-jitstressregs.yml
+++ b/eng/pipelines/coreclr/jitstress2-jitstressregs.yml
@@ -28,7 +28,6 @@ jobs:
- Linux_x64
- Windows_NT_x64
- Windows_NT_x86
- - Windows_NT_arm
- Windows_NT_arm64
- CoreClrTestBuildHost # Either OSX_x64 or Linux_x64
jobParameters:
@@ -56,7 +55,6 @@ jobs:
- Linux_x64
- Windows_NT_x64
- Windows_NT_x86
- - Windows_NT_arm
- Windows_NT_arm64
helixQueueGroup: ci
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
diff --git a/eng/pipelines/coreclr/jitstressregs.yml b/eng/pipelines/coreclr/jitstressregs.yml
index 6df9790231a92f..12c8fc5158873f 100644
--- a/eng/pipelines/coreclr/jitstressregs.yml
+++ b/eng/pipelines/coreclr/jitstressregs.yml
@@ -28,7 +28,6 @@ jobs:
- Linux_x64
- Windows_NT_x64
- Windows_NT_x86
- - Windows_NT_arm
- Windows_NT_arm64
- CoreClrTestBuildHost # Either OSX_x64 or Linux_x64
jobParameters:
@@ -56,7 +55,6 @@ jobs:
- Linux_x64
- Windows_NT_x64
- Windows_NT_x86
- - Windows_NT_arm
- Windows_NT_arm64
helixQueueGroup: ci
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
diff --git a/eng/pipelines/coreclr/perf.yml b/eng/pipelines/coreclr/perf.yml
index 149eb1aed6fb85..dd120af2255e4b 100644
--- a/eng/pipelines/coreclr/perf.yml
+++ b/eng/pipelines/coreclr/perf.yml
@@ -17,25 +17,8 @@ trigger:
- README.md
- SECURITY.md
- THIRD-PARTY-NOTICES.TXT
-
-
-pr:
- branches:
- include:
- - master
- paths:
- include:
- - '*'
- - src/libraries/System.Private.CoreLib/*
- exclude:
- - docs/*
- - CODE-OF-CONDUCT.md
- - CONTRIBUTING.md
- - LICENSE.TXT
- - PATENTS.TXT
- - README.md
- - SECURITY.md
- - THIRD-PARTY-NOTICES.TXT
+
+pr: none
jobs:
#
@@ -43,6 +26,7 @@ jobs:
#
- template: /eng/pipelines/common/checkout-job.yml
+# build coreclr and libraries
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/build-coreclr-and-libraries-job.yml
@@ -54,6 +38,22 @@ jobs:
jobParameters:
testGroup: perf
+# build mono
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ buildConfig: release
+ runtimeFlavor: mono
+ platforms:
+ - Browser_wasm
+ jobParameters:
+ buildArgs: -s mono+libs+installer -c $(_BuildConfig)
+ nameSuffix: wasm
+ isOfficialBuild: ${{ variables.isOfficialBuild }}
+ extraStepsTemplate: /eng/pipelines/common/upload-unsigned-artifacts-step.yml
+ extraStepsParameters:
+ name: MonoRuntimePacks
+
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/mono/templates/build-job.yml
@@ -62,6 +62,7 @@ jobs:
platforms:
- Linux_x64
+# run mono perf job
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml
@@ -73,21 +74,42 @@ jobs:
testGroup: perf
liveLibrariesBuildConfig: Release
runtimeType: mono
+ projectFile: microbenchmarks.proj
+ runKind: micro_mono
-- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - template: /eng/pipelines/common/platform-matrix.yml
- parameters:
- jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml
- buildConfig: release
- runtimeFlavor: mono
- platforms:
- - Linux_x64
- jobParameters:
- testGroup: perf
- liveLibrariesBuildConfig: Release
- runtimeType: mono
- codeGenType: 'Interpreter'
+# run mono interpreter job
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml
+ buildConfig: release
+ runtimeFlavor: mono
+ platforms:
+ - Linux_x64
+ jobParameters:
+ testGroup: perf
+ liveLibrariesBuildConfig: Release
+ runtimeType: mono
+ codeGenType: 'Interpreter'
+ projectFile: microbenchmarks.proj
+ runKind: micro_mono
+# run mono wasm microbenchmarks perf job
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml
+ buildConfig: release
+ runtimeFlavor: wasm
+ platforms:
+ - Linux_x64
+ jobParameters:
+ testGroup: perf
+ liveLibrariesBuildConfig: Release
+ runtimeType: wasm
+ codeGenType: 'wasm'
+ projectFile: microbenchmarks.proj
+ runKind: micro
+
+# run coreclr microbenchmarks perf job
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml
@@ -100,3 +122,22 @@ jobs:
jobParameters:
testGroup: perf
liveLibrariesBuildConfig: Release
+ projectFile: microbenchmarks.proj
+ runKind: micro
+
+# run coreclr crossgen perf job
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/coreclr/templates/perf-job.yml
+ buildConfig: release
+ runtimeFlavor: coreclr
+ platforms:
+ #- Linux_x64
+ - Windows_NT_x64
+ - Windows_NT_x86
+ jobParameters:
+ testGroup: perf
+ liveLibrariesBuildConfig: Release
+ projectFile: crossgen_perf.proj
+ runKind: crossgen_scenarios
+
diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml
index 9b7975156ab6e6..f56c06f56ad6f5 100644
--- a/eng/pipelines/coreclr/templates/build-job.yml
+++ b/eng/pipelines/coreclr/templates/build-job.yml
@@ -133,7 +133,7 @@ jobs:
- ${{ if and(eq(variables['System.TeamProject'], 'internal'), ne(variables['Build.Reason'], 'PullRequest')) }}:
- template: /eng/pipelines/common/restore-internal-tools.yml
- - ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}:
+ - ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}:
- script: |
du -sh $(Build.SourcesDirectory)/*
df -h
@@ -147,16 +147,12 @@ jobs:
- script: set __TestIntermediateDir=int&&$(coreClrRepoRootDir)build-runtime$(scriptExt) $(buildConfig) $(archType) -ci $(enforcePgoArg) $(officialBuildIdArg) $(clrInterpreterBuildArg)
displayName: Build CoreCLR Runtime
- - ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}:
+ - ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}:
- script: |
du -sh $(Build.SourcesDirectory)/*
df -h
displayName: Disk Usage after Build
- - ${{ if and(eq(parameters.osGroup, 'Windows_NT'), ne(parameters.archType, 'x86')) }}:
- - script: set __TestIntermediateDir=int&&$(coreClrRepoRootDir)build-runtime$(scriptExt) $(buildConfig) $(archType) -ci -linuxdac $(officialBuildIdArg)
- displayName: Build Cross OS Linux DAC for Windows
-
# Build CoreCLR Managed Components
- script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib+clr.nativecorelib+clr.tools+clr.packages $(crossArg) -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) -ci
displayName: Build managed product components and packages
@@ -171,6 +167,28 @@ jobs:
- script: $(coreClrRepoRootDir)build-test$(scriptExt) skipstressdependencies skipmanaged skipgeneratelayout $(buildConfig) $(archType) $(crossArg) $(osArg) $(priorityArg) $(compilerArg)
displayName: Build native test components
+ # Sign and add entitlements to these MacOS binaries
+ - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - ${{ if eq(parameters.osGroup, 'OSX') }}:
+
+ - template: /eng/pipelines/common/macos-sign-with-entitlements.yml
+ parameters:
+ filesToSign:
+ - name: createdump
+ path: $(buildProductRootFolderPath)
+ entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/createdump-entitlements.plist
+ - name: corerun
+ path: $(buildProductRootFolderPath)
+ entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist
+
+ - task: CopyFiles@2
+ displayName: 'Copy signed createdump to sharedFramework'
+ inputs:
+ contents: createdump
+ sourceFolder: $(buildProductRootFolderPath)
+ targetFolder: $(buildProductRootFolderPath)/sharedFramework
+ overWrite: true
+
# Sign on Windows
- ${{ if and(eq(parameters.osGroup, 'Windows_NT'), eq(parameters.signBinaries, 'true'), ne(parameters.testGroup, 'clrTools')) }}:
- powershell: eng\common\build.ps1 -ci -sign -restore -configuration:$(buildConfig) -warnaserror:0 /p:ArcadeBuild=true /p:OfficialBuild=true /p:TargetOS=$(osGroup) /p:TargetArchitecture=$(archType) /p:Configuration=$(_BuildConfig) /p:DotNetSignType=$env:_SignType -projects $(Build.SourcesDirectory)\eng\empty.csproj
@@ -197,6 +215,13 @@ jobs:
artifactName: $(buildProductArtifactName)
displayName: 'product build'
+ - ${{ if and(ne(parameters.osGroup, 'OSX'), ne(parameters.archType, 'x86'), ne(parameters.compilerName, 'gcc'), ne(parameters.testGroup, 'clrTools')) }}:
+ - template: /eng/pipelines/coreclr/templates/crossdac-build.yml
+ parameters:
+ archType: ${{ parameters.archType }}
+ osGroup: ${{ parameters.osGroup }}
+ osSubgroup: ${{ parameters.osSubgroup }}
+
- ${{ if and(ne(parameters.compilerName, 'gcc'), ne(parameters.testGroup, ''), ne(parameters.testGroup, 'clrTools')) }}:
# Publish test native components for consumption by test execution.
- ${{ if ne(parameters.isOfficialBuild, true) }}:
diff --git a/eng/pipelines/coreclr/templates/crossdac-build.yml b/eng/pipelines/coreclr/templates/crossdac-build.yml
new file mode 100644
index 00000000000000..b17b72af8325ca
--- /dev/null
+++ b/eng/pipelines/coreclr/templates/crossdac-build.yml
@@ -0,0 +1,53 @@
+parameters:
+ archType: ''
+ osGroup: ''
+ osSubgroup: ''
+
+steps:
+ # Always build the crossdac, that way we know in CI/PR if things break to build.
+ - ${{ if eq(parameters.osGroup, 'Windows_NT') }}:
+ - ${{ if notin(parameters.archType, 'x86') }}:
+ - script: set __TestIntermediateDir=int&&$(coreClrRepoRootDir)build-runtime$(scriptExt) $(buildConfig) $(archType) -ci -linuxdac $(officialBuildIdArg)
+ displayName: Build Cross OS Linux DAC for Windows
+
+
+ # Make the assets available in a single container for the packaging job.
+ - ${{ if and(ne(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ - ${{ if eq(parameters.osGroup, 'Windows_NT') }}:
+ - ${{ if notin(parameters.archType, 'x86', 'arm') }}:
+ - script: set __TestIntermediateDir=int&&$(coreClrRepoRootDir)build-runtime$(scriptExt) $(buildConfig) $(archType) -ci -alpinedac $(officialBuildIdArg)
+ displayName: Build Cross OS Linux-musl DAC for Windows
+
+ - task: CopyFiles@2
+ displayName: Gather CrossDac Artifacts (Linux)
+ inputs:
+ SourceFolder: $(buildLinuxDacRootFolderPath)
+ Contents: |
+ **/*
+ !**/sharedFramework/**/*
+ TargetFolder: $(buildLinuxDacStagingPath)
+
+ - ${{ if ne(parameters.archType, 'arm') }}:
+ - task: CopyFiles@2
+ displayName: Gather CrossDac Artifacts (Linux_musl)
+ inputs:
+ SourceFolder: $(buildMuslDacRootFolderPath)
+ Contents: |
+ **/*
+ !**/sharedFramework/**/*
+ TargetFolder: '$(buildMuslDacStagingPath)'
+
+ - ${{ if eq(parameters.osGroup, 'Linux') }}:
+ - task: CopyFiles@2
+ displayName: Gather runtime for CrossDac
+ inputs:
+ SourceFolder: $(coreClrProductRootFolderPath)
+ Contents: libcoreclr.so
+ TargetFolder: '$(crossDacArtifactPath)/${{ parameters.osGroup }}${{ parameters.osSubgroup }}.$(archType).$(buildConfigUpper)/$(crossDacHostArch)'
+
+ - task: PublishBuildArtifacts@1
+ displayName: Publish runtime for CrossDac
+ inputs:
+ pathtoPublish: $(crossDacArtifactPath)
+ PublishLocation: Container
+ artifactName: $(buildCrossDacArtifactName)
diff --git a/eng/pipelines/coreclr/templates/crossdac-pack.yml b/eng/pipelines/coreclr/templates/crossdac-pack.yml
new file mode 100644
index 00000000000000..f876a85d33febb
--- /dev/null
+++ b/eng/pipelines/coreclr/templates/crossdac-pack.yml
@@ -0,0 +1,74 @@
+parameters:
+ archType: ''
+ buildConfig: ''
+ container: ''
+ crossDacPlatforms: {}
+ isOfficialBuild: false
+ osGroup: ''
+ osSubgroup: ''
+ platform: ''
+ pool: ''
+ runtimeVariant: ''
+ stagedBuild: false
+ testGroup: ''
+ timeoutInMinutes: ''
+ variables: {}
+
+jobs:
+- template: xplat-pipeline-job.yml
+ parameters:
+ archType: ${{ parameters.archType }}
+ buildConfig: ${{ parameters.buildConfig }}
+ container: ${{ parameters.container }}
+ condition: ${{ parameters.isOfficialBuild }}
+ helixType: 'build/product/'
+ osGroup: ${{ parameters.osGroup }}
+ osSubgroup: ${{ parameters.osSubgroup }}
+ pool: ${{ parameters.pool }}
+ runtimeVariant: ${{ parameters.runtimeVariant }}
+ stagedBuild: ${{ parameters.stagedBuild }}
+ timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+
+ name: crossdacpack
+ displayName: CrossDac Packaging
+
+ variables:
+ - name: officialBuildIdArg
+ value: ''
+ - name: crossDacArgs
+ value: ''
+ - ${{ if and(eq(variables['System.TeamProject'], 'internal'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: officialBuildIdArg
+ value: '/p:OfficialBuildId=$(Build.BuildNumber)'
+ - name: crossDacArgs
+ value: '/p:CrossDacArtifactsDir=$(crossDacArtifactPath)/$(buildCrossDacArtifactName)'
+ - ${{ parameters.variables }}
+
+ dependsOn:
+ - ${{ if ne(parameters.crossDacPlatforms, '') }}:
+ - ${{ each platform in parameters.crossDacPlatforms }}:
+ - ${{ parameters.runtimeFlavor }}_${{ parameters.runtimeVariant }}_product_build_${{ platform }}_${{ parameters.buildConfig }}
+
+ steps:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download CrossDac artifacts
+ inputs:
+ artifactName: $(buildCrossDacArtifactName)
+ downloadPath: $(crossDacArtifactPath)
+
+ - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset crossdacpack -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) $(crossDacArgs) -ci
+ displayName: Build crossdac packaging
+
+ # Save packages using the prepare-signed-artifacts format.
+ - template: /eng/pipelines/common/upload-unsigned-artifacts-step.yml
+ parameters:
+ name: ${{ parameters.platform }}
+
+ # Upload to artifacts to be signed
+ - task: PublishPipelineArtifact@1
+ displayName: Publish Logs
+ inputs:
+ targetPath: $(Build.SourcesDirectory)/artifacts/log
+ artifactName: 'CrossDacPackagingLogs'
+ continueOnError: true
+ condition: always()
diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml
index c7c62451b779dc..caebaea069a026 100644
--- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml
+++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml
@@ -124,7 +124,7 @@ jobs:
# Windows_NT arm64
- ${{ if eq(parameters.platform, 'Windows_NT_arm64') }}:
- ${{ if and(eq(variables['System.TeamProject'], 'public'), in(parameters.jobParameters.helixQueueGroup, 'pr', 'ci', 'libraries')) }}:
- - Windows.10.Arm64.Open
+ - Windows.10.Arm64v8.Open
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- Windows.10.Arm64
diff --git a/eng/pipelines/coreclr/templates/perf-job.yml b/eng/pipelines/coreclr/templates/perf-job.yml
index 4284a79368f907..21799d64354d5c 100644
--- a/eng/pipelines/coreclr/templates/perf-job.yml
+++ b/eng/pipelines/coreclr/templates/perf-job.yml
@@ -11,6 +11,8 @@ parameters:
runtimeType: 'coreclr'
pool: ''
codeGenType: 'JIT'
+ projetFile: ''
+ runKind: ''
### Perf job
@@ -21,8 +23,8 @@ jobs:
- template: run-performance-job.yml
parameters:
# Compute job name from template parameters
- jobName: ${{ format('perfbuild_{0}{1}_{2}_{3}_{4}_{5}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType, parameters.codeGenType) }}
- displayName: ${{ format('Performance {0}{1} {2} {3} {4} {5}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType, parameters.codeGenType) }}
+ jobName: ${{ format('perfbuild_{0}{1}_{2}_{3}_{4}_{5}_{6}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType, parameters.codeGenType, parameters.runKind) }}
+ displayName: ${{ format('Performance {0}{1} {2} {3} {4} {5} {6}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.runtimeType, parameters.codeGenType, parameters.runKind) }}
pool: ${{ parameters.pool }}
buildConfig: ${{ parameters.buildConfig }}
archType: ${{ parameters.archType }}
@@ -32,6 +34,8 @@ jobs:
liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }}
runtimeType: ${{ parameters.runtimeType }}
codeGenType: ${{ parameters.codeGenType }}
+ projectFile: ${{ parameters.projectFile }}
+ runKind: ${{ parameters.runKind }}
# Test job depends on the corresponding build job
dependsOn:
- ${{ format('coreclr_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
@@ -39,6 +43,8 @@ jobs:
- ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }}
- ${{ if eq(parameters.runtimeType, 'mono') }}:
- ${{ format('mono_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
+ - ${{ if eq(parameters.runtimeType, 'wasm') }}:
+ - ${{ format('build_{0}{1}_{2}_{3}_{4}', 'Browser', '', 'wasm', parameters.buildConfig, parameters.runtimeType) }}
${{ if eq(parameters.osGroup, 'Windows_NT') }}:
${{ if eq(parameters.runtimeType, 'mono') }}:
@@ -48,7 +54,9 @@ jobs:
${{ if ne(parameters.osGroup, 'Windows_NT') }}:
${{ if eq(parameters.runtimeType, 'mono') }}:
extraSetupParameters: --architecture ${{ parameters.archType }} --monodotnet $(Build.SourcesDirectory)/.dotnet-mono --kind micro_mono
- ${{ if ne(parameters.runtimeType, 'mono') }}:
+ ${{ if eq(parameters.runtimeType, 'wasm') }}:
+ extraSetupParameters: --architecture ${{ parameters.archType }} --wasm $(librariesDownloadDir)/bin/wasm --kind micro
+ ${{ if eq(parameters.runtimeType, 'coreclr') }}:
extraSetupParameters: --corerootdirectory $(Build.SourcesDirectory)/artifacts/tests/coreclr/${{ parameters.osGroup }}.${{ parameters.archType }}.Release/Tests/Core_Root --architecture ${{ parameters.archType }}
variables: ${{ parameters.variables }}
@@ -86,15 +94,30 @@ jobs:
artifactName: 'MonoProduct_${{ parameters.runtimeVariant }}_$(osGroup)_$(archType)_$(buildConfig)'
displayName: 'Mono runtime'
+ - ${{ if eq(parameters.runtimeType, 'wasm') }}:
+ # Download artifact
+ - task: DownloadBuildArtifacts@0
+ displayName: 'Download WASM Runtime Pack'
+ inputs:
+ buildType: current
+ downloadType: single
+ downloadPath: '$(Build.SourcesDirectory)/__download__'
+ artifactName: 'IntermediateUnsignedArtifacts'
+
+ - script: "mkdir $(librariesDownloadDir)/bin/wasm;unzip -o $(Build.SourcesDirectory)/__download__/IntermediateUnsignedArtifacts/MonoRuntimePacks/Shipping/Microsoft.NETCore.App.Runtime.browser-wasm.5.0.0-ci.nupkg data/* runtimes/* -d $(librariesDownloadDir)/bin/wasm;cp src/mono/wasm/runtime-test.js $(librariesDownloadDir)/bin/wasm/runtime-test.js;find $(librariesDownloadDir)/bin/wasm -type f -exec chmod 664 {} \\;"
+ displayName: "Create wasm directory (Linux)"
+
# Create Core_Root
- script: $(coreClrRepoRootDir)build-test$(scriptExt) $(buildConfig) $(archType) generatelayoutonly $(librariesOverrideArg)
displayName: Create Core_Root
condition: and(succeeded(), ne(variables.runtimeFlavorName, 'Mono'))
- - script: "build.cmd -subset libs.pretest -configuration release -ci -arch $(archType) -testscope innerloop /p:RuntimeArtifactsPath=$(librariesDownloadDir)\\bin\\mono\\$(osGroup).$(archType).$(buildConfigUpper) /p:RuntimeFlavor=mono;xcopy $(Build.SourcesDirectory)\\artifacts\\bin\\testhost\\$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)\\* $(Build.SourcesDirectory)\\.dotnet-mono /E /I /Y;copy $(Build.SourcesDirectory)\\artifacts\\bin\\coreclr\\$(osGroup).$(archType).$(buildConfigUpper)\\corerun.exe $(Build.SourcesDirectory)\\.dotnet-mono\\shared\\Microsoft.NETCore.App\\5.0.0\\corerun.exe"
+ # Copy the runtime directory into the testhost folder to include OOBs.
+
+ - script: "build.cmd -subset libs.pretest -configuration release -ci -arch $(archType) -testscope innerloop /p:RuntimeArtifactsPath=$(librariesDownloadDir)\\bin\\mono\\$(osGroup).$(archType).$(buildConfigUpper) /p:RuntimeFlavor=mono;xcopy $(Build.SourcesDirectory)\\artifacts\\bin\\runtime\\$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)\\* $(Build.SourcesDirectory)\\artifacts\\bin\\testhost\\$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)\\shared\\Microsoft.NETCore.App\\5.0.0 /E /I /Y;xcopy $(Build.SourcesDirectory)\\artifacts\\bin\\testhost\\$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)\\* $(Build.SourcesDirectory)\\.dotnet-mono /E /I /Y;copy $(Build.SourcesDirectory)\\artifacts\\bin\\coreclr\\$(osGroup).$(archType).$(buildConfigUpper)\\corerun.exe $(Build.SourcesDirectory)\\.dotnet-mono\\shared\\Microsoft.NETCore.App\\5.0.0\\corerun.exe"
displayName: "Create mono dotnet (Windows)"
condition: and(and(succeeded(), eq(variables.runtimeFlavorName, 'Mono')), eq(variables.osGroup, 'Windows_NT'))
- - script: "mkdir $(Build.SourcesDirectory)/.dotnet-mono;./build.sh -subset libs.pretest -configuration release -ci -arch $(archType) -testscope innerloop /p:RuntimeArtifactsPath=$(librariesDownloadDir)/bin/mono/$(osGroup).$(archType).$(buildConfigUpper) /p:RuntimeFlavor=mono;cp $(Build.SourcesDirectory)/artifacts/bin/testhost/$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)/* $(Build.SourcesDirectory)/.dotnet-mono -r;cp $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)/corerun $(Build.SourcesDirectory)/.dotnet-mono/shared/Microsoft.NETCore.App/5.0.0/corerun"
+ - script: "mkdir $(Build.SourcesDirectory)/.dotnet-mono;./build.sh -subset libs.pretest -configuration release -ci -arch $(archType) -testscope innerloop /p:RuntimeArtifactsPath=$(librariesDownloadDir)/bin/mono/$(osGroup).$(archType).$(buildConfigUpper) /p:RuntimeFlavor=mono;cp $(Build.SourcesDirectory)/artifacts/bin/runtime/$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)/* $(Build.SourcesDirectory)/artifacts/bin/testhost/$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)/shared/Microsoft.NETCore.App/5.0.0 -rf;cp $(Build.SourcesDirectory)/artifacts/bin/testhost/$(_Framework)-$(osGroup)-$(buildConfigUpper)-$(archType)/* $(Build.SourcesDirectory)/.dotnet-mono -r;cp $(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)/corerun $(Build.SourcesDirectory)/.dotnet-mono/shared/Microsoft.NETCore.App/5.0.0/corerun"
displayName: "Create mono dotnet (Linux)"
condition: and(and(succeeded(), eq(variables.runtimeFlavorName, 'Mono')), ne(variables.osGroup, 'Windows_NT'))
diff --git a/eng/pipelines/coreclr/templates/run-performance-job.yml b/eng/pipelines/coreclr/templates/run-performance-job.yml
index 7dadb9bd5eee02..c38d33405cca44 100644
--- a/eng/pipelines/coreclr/templates/run-performance-job.yml
+++ b/eng/pipelines/coreclr/templates/run-performance-job.yml
@@ -18,6 +18,8 @@ parameters:
liveLibrariesBuildConfig: '' # optional -- live-live libraries configuration to use for the run
runtimeType: 'coreclr' # optional -- Sets the runtime as coreclr or mono
codeGenType: 'JIT' # optional -- Decides on the codegen technology if running on mono
+ projectFile: '' # required -- project file to build helix workitems
+ runKind: '' # required -- test category
jobs:
- template: xplat-pipeline-job.yml
@@ -51,7 +53,7 @@ jobs:
- IsInternal: ''
- HelixApiAccessToken: ''
- HelixPreCommandStemWindows: 'py -3 -m venv %HELIX_WORKITEM_PAYLOAD%\.venv;call %HELIX_WORKITEM_PAYLOAD%\.venv\Scripts\activate.bat;set PYTHONPATH=;py -3 -m pip install --user azure.storage.blob==12.0.0 --force-reinstall;py -3 -m pip install --user azure.storage.queue==12.0.0 --force-reinstall;set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"'
- - HelixPreCommandStemLinux: 'sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/Scripts/activate;export PYTHONPATH=;pip3 install --user azure.storage.blob==12.0.0 --force-reinstall;pip3 install --user azure.storage.queue==12.0.0 --force-reinstall;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"'
+ - HelixPreCommandStemLinux: 'sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/Scripts/activate;export PYTHONPATH=;pip3 install --user azure.storage.blob==12.0.0 --force-reinstall;pip3 install --user azure.storage.queue==12.0.0 --force-reinstall;sudo apt-get -y install nodejs;sudo apt-get -y install npm;npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"'
- ExtraMSBuildLogsWindows: 'set MSBUILDDEBUGCOMM=1;set "MSBUILDDEBUGPATH=%HELIX_WORKITEM_UPLOAD_ROOT%"'
- ExtraMSBuildLogsLinux: 'export MSBUILDDEBUGCOMM=1;export "MSBUILDDEBUGPATH=$HELIX_WORKITEM_UPLOAD_ROOT"'
- HelixPreCommand: ''
@@ -71,7 +73,7 @@ jobs:
- ${{ if eq( parameters.osGroup, 'Windows_NT') }}:
- HelixPreCommand: $(ExtraMSBuildLogsWindows)
- ${{ if ne(parameters.osGroup, 'Windows_NT') }}:
- - HelixPreCommand: $(ExtraMSBuildLogsLinux)
+ - HelixPreCommand: $(ExtraMSBuildLogsLinux);npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8
- ${{ if and(eq(parameters.codeGenType, 'Interpreter'), eq(parameters.runtimeType, 'mono')) }}:
@@ -102,11 +104,11 @@ jobs:
_Framework: ${{ framework }}
steps:
- ${{ parameters.steps }}
- - powershell: $(Build.SourcesDirectory)\eng\common\performance\performance-setup.ps1 $(IsInternal)$(Interpreter) -Framework $(_Framework) ${{ parameters.extraSetupParameters }}
+ - powershell: $(Build.SourcesDirectory)\eng\common\performance\performance-setup.ps1 $(IsInternal)$(Interpreter) -Framework $(_Framework) -Kind ${{ parameters.runKind }} ${{ parameters.extraSetupParameters }}
displayName: Performance Setup (Windows)
condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT'))
continueOnError: ${{ parameters.continueOnError }}
- - script: $(Build.SourcesDirectory)/eng/common/performance/performance-setup.sh $(IsInternal)$(Interpreter) --framework $(_Framework) ${{ parameters.extraSetupParameters }}
+ - script: $(Build.SourcesDirectory)/eng/common/performance/performance-setup.sh $(IsInternal)$(Interpreter) --framework $(_Framework) --kind ${{ parameters.runKind }} ${{ parameters.extraSetupParameters }}
displayName: Performance Setup (Unix)
condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))
continueOnError: ${{ parameters.continueOnError }}
@@ -132,10 +134,11 @@ jobs:
WorkItemTimeout: 4:00 # 4 hours
WorkItemDirectory: '$(WorkItemDirectory)' # WorkItemDirectory can not be empty, so we send it some docs to keep it happy
CorrelationPayloadDirectory: '$(PayloadDirectory)' # it gets checked out to a folder with shorter path than WorkItemDirectory so we can avoid file name too long exceptions
+ ProjectFile: ${{ parameters.projectFile }}
- task: PublishPipelineArtifact@1
displayName: Publish Logs
inputs:
targetPath: $(Build.SourcesDirectory)/artifacts/log
- artifactName: 'Performance_Run_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_${{ parameters.runtimeType }}_${{ parameters.codeGenType }}'
+ artifactName: 'Performance_Run_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)_${{ parameters.runtimeType }}_${{ parameters.codeGenType }}_${{ parameters.runKind }}'
continueOnError: true
condition: always()
diff --git a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml
index dfcf6652e25e4b..0e789b84e91991 100644
--- a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml
+++ b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml
@@ -65,7 +65,7 @@ jobs:
- name: binTestsPath
value: '$(Build.SourcesDirectory)/artifacts/tests/coreclr'
-
+
# Build product defines what we are trying to build, either coreclr or mono
- name: buildProductArtifactName
value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)'
@@ -73,6 +73,31 @@ jobs:
- name: buildProductRootFolderPath
value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)'
+ - name: buildCrossDacArtifactName
+ value: CoreCLRCrossDacArtifacts
+
+ - name: crossDacArtifactPath
+ value: $(Build.SourcesDirectory)/artifacts/$(buildCrossDacArtifactName)
+
+ - name: buildMuslDacRootFolderPath
+ value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/alpine.$(archType).$(buildConfigUpper)'
+
+ - name: buildMuslDacStagingPath
+ value: '$(crossDacArtifactPath)/Linux_musl.$(archType).$(buildConfigUpper)'
+
+ - name: buildLinuxDacRootFolderPath
+ value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/Linux.$(archType).$(buildConfigUpper)'
+
+ - name: buildLinuxDacStagingPath
+ value: '$(crossDacArtifactPath)/Linux.$(archType).$(buildConfigUpper)'
+
+ - name: crossDacHostArch
+ value: x64
+
+ - ${{ if eq(parameters.archType, 'arm') }}:
+ - name: crossDacHostArch
+ value: x86
+
# We need this because both mono and coreclr build currently depends on CoreClr
- name: coreClrProductArtifactName
value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)'
diff --git a/eng/pipelines/installer/jobs/base-job.yml b/eng/pipelines/installer/jobs/base-job.yml
index b74bf18fb60ce6..9ad565067c7481 100644
--- a/eng/pipelines/installer/jobs/base-job.yml
+++ b/eng/pipelines/installer/jobs/base-job.yml
@@ -132,7 +132,7 @@ jobs:
- name: BaseJobBuildCommand
value: >-
- $(Build.SourcesDirectory)/build.sh -subset installer -ci
+ $(Build.SourcesDirectory)/build.sh -ci
$(BuildAction)
-configuration $(_BuildConfig)
$(LiveOverridePathArgs)
@@ -456,8 +456,29 @@ jobs:
df -h
displayName: Disk Usage before Build
- - script: $(BaseJobBuildCommand)
- displayName: Build
+ # Build the default subset non-MacOS platforms
+ - ${{ if ne(parameters.osGroup, 'OSX') }}:
+ - script: $(BaseJobBuildCommand)
+ displayName: Build
+
+ # Build corehost, sign and add entitlements to MacOS binaries
+ - ${{ if eq(parameters.osGroup, 'OSX') }}:
+ - script: $(BaseJobBuildCommand) -subset corehost
+ displayName: Build CoreHost
+
+ - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - template: /eng/pipelines/common/macos-sign-with-entitlements.yml
+ parameters:
+ filesToSign:
+ - name: dotnet
+ path: $(Build.SourcesDirectory)/artifacts/bin/osx-${{ parameters.archType }}.$(_BuildConfig)/corehost
+ entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist
+ - name: apphost
+ path: $(Build.SourcesDirectory)/artifacts/bin/osx-${{ parameters.archType }}.$(_BuildConfig)/corehost
+ entitlementsFile: $(Build.SourcesDirectory)/eng/pipelines/common/entitlements.plist
+
+ - script: $(BaseJobBuildCommand) -subset installer.nocorehost
+ displayName: Build and Package
- ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}:
- script: |
diff --git a/eng/pipelines/libraries/base-job.yml b/eng/pipelines/libraries/base-job.yml
index 99e62714189943..2ae778e893939a 100644
--- a/eng/pipelines/libraries/base-job.yml
+++ b/eng/pipelines/libraries/base-job.yml
@@ -4,7 +4,7 @@ parameters:
archType: ''
osSubgroup: ''
crossrootfsDir: ''
- framework: ''
+ framework: 'net5.0'
isOfficialAllConfigurations: false
isSourceBuild: false
liveRuntimeBuildConfig: ''
@@ -20,14 +20,15 @@ parameters:
testDisplayName: ''
testScope: ''
pool: ''
+ runTests: false
jobs:
- template: /eng/common/templates/job/job.yml
parameters:
- ${{ if notIn(parameters.framework, 'allConfigurations', 'net472') }}:
+ ${{ if notIn(parameters.framework, 'allConfigurations', 'net48') }}:
displayName: ${{ format('Libraries {0} {1}{2} {3} {4}', parameters.displayName, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
name: ${{ format('libraries_{0}_{1}{2}_{3}_{4}', parameters.name, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
- ${{ if in(parameters.framework, 'allConfigurations', 'net472') }}:
+ ${{ if in(parameters.framework, 'allConfigurations', 'net48') }}:
displayName: ${{ format('Libraries {0} {1} {2} {3} {4}', parameters.displayName, parameters.osGroup, parameters.framework, parameters.archType, parameters.buildConfig) }}
name: ${{ format('libraries_{0}_{1}_{2}{3}_{4}_{5}', parameters.name, parameters.framework, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
@@ -91,6 +92,9 @@ jobs:
- ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}:
- _runtimeDownloadPath: '$(Build.SourcesDirectory)/artifacts/transport/${{ parameters.runtimeFlavor }}'
- _runtimeConfigurationArg: -rc ${{ parameters.liveRuntimeBuildConfig }}
+ - ${{ if eq(parameters.runTests, true) }}:
+ - _runtimeArtifactName: '$(runtimeFlavorName)Product_${{ parameters.runtimeVariant}}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.liveRuntimeBuildConfig }}'
+ - _runtimeArtifactsPathArg: ' /p:RuntimeArtifactsPath=$(_runtimeDownloadPath)'
- ${{ if eq(parameters.testDisplayName, '') }}:
- _testRunNamePrefixSuffix: $(runtimeFlavorName)_${{ parameters.liveRuntimeBuildConfig }}
- ${{ if ne(parameters.testDisplayName, '') }}:
@@ -121,4 +125,13 @@ jobs:
steps:
- template: /eng/pipelines/common/clone-checkout-bundle-step.yml
+
+ - ${{ if and(ne(parameters.liveRuntimeBuildConfig, ''), eq(parameters.runTests, true)) }}:
+ - template: /eng/pipelines/common/download-artifact-step.yml
+ parameters:
+ unpackFolder: $(_runtimeDownloadPath)
+ artifactFileName: '$(_runtimeArtifactName)$(archiveExtension)'
+ artifactName: '$(_runtimeArtifactName)'
+ displayName: '$(runtimeFlavorName) build drop'
+
- ${{ parameters.steps }}
diff --git a/eng/pipelines/libraries/build-job.yml b/eng/pipelines/libraries/build-job.yml
index f2e8ff21683c4c..4854b682716afa 100644
--- a/eng/pipelines/libraries/build-job.yml
+++ b/eng/pipelines/libraries/build-job.yml
@@ -4,7 +4,7 @@ parameters:
osSubgroup: ''
archType: ''
crossrootfsDir: ''
- framework: ''
+ framework: 'net5.0'
isOfficialBuild: false
isOfficialAllConfigurations: false
runtimeVariant: ''
@@ -41,6 +41,7 @@ jobs:
isOfficialAllConfigurations: ${{ parameters.isOfficialAllConfigurations }}
liveRuntimeBuildConfig: ${{ parameters.liveRuntimeBuildConfig }}
runtimeFlavor: ${{ parameters.runtimeFlavor }}
+ runTests: ${{ parameters.runTests }}
timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
preBuildSteps: ${{ parameters.preBuildSteps }}
container: ${{ parameters.container }}
@@ -51,6 +52,11 @@ jobs:
name: build
displayName: 'Build'
+ ${{ if and(ne(parameters.liveRuntimeBuildConfig, ''), eq(parameters.runTests, true)) }}:
+ dependsOn:
+ # Use full product dependency for test runs
+ - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }}
+
variables:
- librariesTestsArtifactName: ${{ format('libraries_test_assets_{0}_{1}_{2}', parameters.osGroup, parameters.archType, parameters.buildConfig) }}
- _subset: libs
@@ -59,7 +65,7 @@ jobs:
- ${{ if eq(parameters.osGroup, 'Browser') }}:
- EMSDK_PATH: /usr/local/emscripten
- # Tests only run for 'allConfiguration' and 'net472' build-jobs
+ # Tests only run for 'allConfiguration' and 'net48' build-jobs
# If platform is in testBuildPlatforms we build tests as well.
- ${{ if or(eq(parameters.runTests, true), containsValue(parameters.testBuildPlatforms, parameters.platform)) }}:
- _subset: libs+libs.tests
@@ -93,55 +99,9 @@ jobs:
displayName: Disk Usage after Build
- ${{ if eq(parameters.runTests, false) }}:
- - ${{ if ne(parameters.isOfficialBuild, true) }}:
- - task: CopyFiles@2
- displayName: Prepare testhost folder to publish
- inputs:
- sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/testhost
- targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/testhost
-
- - task: CopyFiles@2
- displayName: Prepare runtime folder to publish
- inputs:
- sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/runtime
- targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/runtime
-
- - task: CopyFiles@2
- displayName: Prepare ref folder to publish
- inputs:
- sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/ref
- targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/ref
-
- - task: CopyFiles@2
- displayName: Prepare shared framework ref assemblies to publish
- inputs:
- sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/ref/microsoft.netcore.app
- targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/ref/microsoft.netcore.app
-
- - task: CopyFiles@2
- displayName: Prepare shared framework runtime folder to publish
- inputs:
- sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/pkg
- targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/pkg
-
- - task: CopyFiles@2
- displayName: Prepare docs folder to publish
- inputs:
- sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/docs
- targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/docs
-
- - task: CopyFiles@2
- displayName: Prepare native folder to publish
- inputs:
- sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/native
- targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/native
-
- - task: CopyFiles@2
- displayName: Prepare artifacts packages folder to publish
- inputs:
- sourceFolder: $(Build.SourcesDirectory)/artifacts/packages
- targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/packages
- condition: and(succeeded(), eq(variables['_librariesBuildProducedPackages'], true))
+ - template: /eng/pipelines/libraries/prepare-for-bin-publish.yml
+ parameters:
+ isOfficialBuild: ${{ parameters.isOfficialBuild }}
- template: /eng/pipelines/common/upload-artifact-step.yml
parameters:
diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml
index 58d1f89fe3c08a..33d0ea5aa9dbdd 100644
--- a/eng/pipelines/libraries/helix-queues-setup.yml
+++ b/eng/pipelines/libraries/helix-queues-setup.yml
@@ -88,7 +88,7 @@ jobs:
# Windows_NT x64
- ${{ if eq(parameters.platform, 'Windows_NT_x64') }}:
# netcoreapp
- - ${{ if notIn(parameters.jobParameters.framework, 'allConfigurations', 'net472') }}:
+ - ${{ if notIn(parameters.jobParameters.framework, 'allConfigurations', 'net48') }}:
- ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}:
- Windows.81.Amd64.Open
- Windows.10.Amd64.ServerRS5.Open
@@ -101,8 +101,8 @@ jobs:
- ${{ if ne(parameters.jobParameters.runtimeFlavor, 'mono') }}:
- (Windows.Nano.1809.Amd64.Open)windows.10.amd64.serverrs5.open@mcr.microsoft.com/dotnet-buildtools/prereqs:nanoserver-1809-helix-amd64-08e8e40-20200107182504
- # NET472
- - ${{ if eq(parameters.jobParameters.framework, 'net472') }}:
+ # .NETFramework
+ - ${{ if eq(parameters.jobParameters.framework, 'net48') }}:
- Windows.10.Amd64.Client19H1.Open
# AllConfigurations
@@ -112,7 +112,7 @@ jobs:
# Windows_NT x86
- ${{ if eq(parameters.platform, 'Windows_NT_x86') }}:
# netcoreapp
- - ${{ if notIn(parameters.jobParameters.framework, 'allConfigurations', 'net472') }}:
+ - ${{ if notIn(parameters.jobParameters.framework, 'allConfigurations', 'net48') }}:
- ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}:
- Windows.7.Amd64.Open
- Windows.10.Amd64.ServerRS5.Open
@@ -124,8 +124,8 @@ jobs:
- Windows.7.Amd64.Open
- Windows.10.Amd64.Server19H1.Open
- # NET472
- - ${{ if eq(parameters.jobParameters.framework, 'net472') }}:
+ # .NETFramework
+ - ${{ if eq(parameters.jobParameters.framework, 'net48') }}:
- Windows.10.Amd64.Client19H1.Open
# Windows_NT arm
diff --git a/eng/pipelines/libraries/outerloop.yml b/eng/pipelines/libraries/outerloop.yml
index 9afbf206e5f369..d88481ea37dd4b 100644
--- a/eng/pipelines/libraries/outerloop.yml
+++ b/eng/pipelines/libraries/outerloop.yml
@@ -99,6 +99,6 @@ jobs:
jobParameters:
isOfficialBuild: ${{ variables['isOfficialBuild'] }}
isFullMatrix: ${{ variables['isFullMatrix'] }}
- framework: net472
+ framework: net48
runTests: true
testScope: outerloop
\ No newline at end of file
diff --git a/eng/pipelines/libraries/prepare-for-bin-publish.yml b/eng/pipelines/libraries/prepare-for-bin-publish.yml
new file mode 100644
index 00000000000000..fa71beaae65fd1
--- /dev/null
+++ b/eng/pipelines/libraries/prepare-for-bin-publish.yml
@@ -0,0 +1,55 @@
+# Steps used to prepare the Artifacts Staging Directory with required files for
+# executing libraries tests as well as shared framework assets
+parameters:
+ isOfficialBuild: ''
+
+steps:
+ - ${{ if ne(parameters.isOfficialBuild, true) }}:
+ - task: CopyFiles@2
+ displayName: Prepare testhost folder to publish
+ inputs:
+ sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/testhost
+ targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/testhost
+
+ - task: CopyFiles@2
+ displayName: Prepare runtime folder to publish
+ inputs:
+ sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/runtime
+ targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/runtime
+
+ - task: CopyFiles@2
+ displayName: Prepare ref folder to publish
+ inputs:
+ sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/ref
+ targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/ref
+
+ - task: CopyFiles@2
+ displayName: Prepare shared framework ref assemblies to publish
+ inputs:
+ sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/ref/microsoft.netcore.app
+ targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/ref/microsoft.netcore.app
+
+ - task: CopyFiles@2
+ displayName: Prepare docs folder to publish
+ inputs:
+ sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/docs
+ targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/docs
+
+ - task: CopyFiles@2
+ displayName: Prepare shared framework runtime folder to publish
+ inputs:
+ sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/pkg
+ targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/pkg
+
+ - task: CopyFiles@2
+ displayName: Prepare native folder to publish
+ inputs:
+ sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/native
+ targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/native
+
+ - task: CopyFiles@2
+ displayName: Prepare artifacts packages folder to publish
+ inputs:
+ sourceFolder: $(Build.SourcesDirectory)/artifacts/packages
+ targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/packages
+ condition: and(succeeded(), eq(variables['_librariesBuildProducedPackages'], true))
diff --git a/eng/pipelines/libraries/run-test-job.yml b/eng/pipelines/libraries/run-test-job.yml
index cf6324e790685e..faa5ab29e30029 100644
--- a/eng/pipelines/libraries/run-test-job.yml
+++ b/eng/pipelines/libraries/run-test-job.yml
@@ -3,7 +3,7 @@ parameters:
osGroup: ''
osSubgroup: ''
archType: ''
- framework: ''
+ framework: 'net5.0'
isOfficialBuild: false
liveRuntimeBuildConfig: ''
runtimeFlavor: 'coreclr'
@@ -22,6 +22,7 @@ parameters:
# stress modes that each test will be run with. This is the same usage as 'testGroup' in
# eng/pipelines/common/templates/runtimes/run-test-job.yml.
coreclrTestGroup: ''
+ dependsOn: []
jobs:
- template: /eng/pipelines/libraries/base-job.yml
@@ -40,6 +41,7 @@ jobs:
condition: ${{ parameters.condition }}
pool: ${{ parameters.pool }}
testScope: ${{ parameters.testScope }}
+ runTests: true
${{ if ne(parameters.liveRuntimeBuildConfig, '') }}:
displayName: ${{ format('Test Run {0} {1}', parameters.liveRuntimeBuildConfig, parameters.runtimeDisplayName) }}
name: ${{ format('test_run_{0}_{1}', parameters.liveRuntimeBuildConfig, parameters.runtimeDisplayName) }}
@@ -50,21 +52,20 @@ jobs:
testDisplayName: ${{ parameters.runtimeFlavor }}_interpreter_${{ parameters.liveRuntimeBuildConfig }}
dependsOn:
- - ${{ if notIn(parameters.framework, 'allConfigurations', 'net472') }}:
- - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
- # tests are built as part of product build
- - ${{ if or(ne(parameters.archType, parameters.dependsOnTestArchitecture), ne(parameters.buildConfig, parameters.dependsOnTestBuildConfiguration)) }}:
- - ${{ format('libraries_build_{0}_{1}_{2}', parameters.osGroup, parameters.dependsOnTestArchitecture, parameters.dependsOnTestBuildConfiguration) }}
- - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}:
- - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }}
+ - ${{ if ne(parameters.dependsOn[0], '') }}:
+ - ${{ parameters.dependsOn }}
+ - ${{ if eq(parameters.dependsOn[0], '') }}:
+ - ${{ if notIn(parameters.framework, 'allConfigurations', 'net48') }}:
+ - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
+ # tests are built as part of product build
+ - ${{ if or(ne(parameters.archType, parameters.dependsOnTestArchitecture), ne(parameters.buildConfig, parameters.dependsOnTestBuildConfiguration)) }}:
+ - ${{ format('libraries_build_{0}_{1}_{2}', parameters.osGroup, parameters.dependsOnTestArchitecture, parameters.dependsOnTestBuildConfiguration) }}
+ - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}:
+ - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }}
variables:
- librariesTestsArtifactName: ${{ format('libraries_test_assets_{0}_{1}_{2}', parameters.osGroup, parameters.dependsOnTestArchitecture, parameters.dependsOnTestBuildConfiguration) }}
- _archiveTestsParameter: /p:ArchiveTests=true
-
- - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}:
- - _runtimeArtifactName: '$(runtimeFlavorName)Product_${{ parameters.runtimeVariant}}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.liveRuntimeBuildConfig }}'
- - _runtimeArtifactsPathArg: ' /p:RuntimeArtifactsPath=$(_runtimeDownloadPath)'
- ${{ parameters.variables }}
@@ -84,14 +85,6 @@ jobs:
artifactName: $(librariesTestsArtifactName)
artifactFileName: $(librariesTestsArtifactName)$(archiveExtension)
unpackFolder: $(Build.SourcesDirectory)/artifacts
-
- - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}:
- - template: /eng/pipelines/common/download-artifact-step.yml
- parameters:
- unpackFolder: $(_runtimeDownloadPath)
- artifactFileName: '$(_runtimeArtifactName)$(archiveExtension)'
- artifactName: '$(_runtimeArtifactName)'
- displayName: '$(runtimeFlavorName) build drop'
- ${{ if in(parameters.coreclrTestGroup, 'gcstress0x3-gcstress0xc', 'gcstress-extra') }}:
# We need to find and download the GC stress dependencies (namely, coredistools). Put them
diff --git a/eng/pipelines/runtime-linker-tests.yml b/eng/pipelines/runtime-linker-tests.yml
index ceffb1e237e76c..bb51f3c0c73655 100644
--- a/eng/pipelines/runtime-linker-tests.yml
+++ b/eng/pipelines/runtime-linker-tests.yml
@@ -64,6 +64,7 @@ jobs:
- Linux_x64
jobParameters:
testGroup: innerloop
+ timeoutInMinutes: 120
nameSuffix: Runtime_Release
buildArgs: -s clr+libs -c $(_BuildConfig)
extraStepsTemplate: /eng/pipelines/libraries/execute-trimming-tests-steps.yml
diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml
index 3d335e198d7d4f..e1a3f8e7eefb1d 100644
--- a/eng/pipelines/runtime-official.yml
+++ b/eng/pipelines/runtime-official.yml
@@ -4,6 +4,7 @@ trigger:
include:
- master
- release/*
+ - internal/release/*
paths:
include:
- '*'
@@ -61,6 +62,23 @@ stages:
jobParameters:
isOfficialBuild: ${{ variables.isOfficialBuild }}
+ - template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/coreclr/templates/crossdac-pack.yml
+ buildConfig: release
+ platforms:
+ - Linux_musl_x64
+ jobParameters:
+ isOfficialBuild: ${{ variables.isOfficialBuild }}
+ crossDacPlatforms:
+ - Linux_x64
+ - Linux_arm
+ - Linux_arm64
+ - Linux_musl_x64
+ - Linux_musl_arm64
+ - Windows_NT_x64
+ - Windows_NT_arm
+ - Windows_NT_arm64
#
# Build Mono runtime packs
#
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index 6d70e6cd190dbc..3dcbae5869842c 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -226,7 +226,8 @@ jobs:
jobTemplate: /eng/pipelines/coreclr/templates/format-job.yml
platforms:
- Linux_x64
- - Windows_NT_x64
+ # Isssue: https://github.com/dotnet/runtime/issues/40034
+ #- Windows_NT_x64
jobParameters:
condition: >-
and(
@@ -576,7 +577,7 @@ jobs:
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
isFullMatrix: ${{ variables.isFullMatrix }}
- framework: net472
+ framework: net48
runTests: true
testScope: innerloop
condition: >-
@@ -595,7 +596,6 @@ jobs:
isFullMatrix: ${{ variables.isFullMatrix }}
framework: allConfigurations
runTests: true
- liveRuntimeBuildConfig: release
condition: >-
or(
eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true),
@@ -682,7 +682,6 @@ jobs:
platforms:
- Linux_arm
- Windows_NT_x86
- - Windows_NT_arm
- Windows_NT_arm64
helixQueueGroup: pr
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
@@ -850,7 +849,6 @@ jobs:
platforms:
- Windows_NT_x86
- ${{ if eq(variables['isFullMatrix'], true) }}:
- - Windows_NT_arm
- Windows_NT_arm64
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
diff --git a/eng/pipelines/runtimelab.yml b/eng/pipelines/runtimelab.yml
new file mode 100644
index 00000000000000..6f00e775b943dd
--- /dev/null
+++ b/eng/pipelines/runtimelab.yml
@@ -0,0 +1,185 @@
+# Setting batch to true, triggers one build at a time.
+# if there is a push while a build in progress, it will wait,
+# until the running build finishes, and produce a build with all the changes
+# that happened during the last build.
+trigger:
+ batch: true
+ branches:
+ include:
+ # Add Experiment branch here
+ paths:
+ include:
+ - '*'
+ - docs/manpages/*
+ exclude:
+ - eng/Version.Details.xml
+ - .github/*
+ - docs/*
+ - CODE-OF-CONDUCT.md
+ - CONTRIBUTING.md
+ - LICENSE.TXT
+ - PATENTS.TXT
+ - README.md
+ - SECURITY.md
+ - THIRD-PARTY-NOTICES.TXT
+
+pr:
+ branches:
+ include:
+ # Add Experiment branch here
+ paths:
+ include:
+ - '*'
+ - docs/manpages/*
+ exclude:
+ - eng/Version.Details.xml
+ - .github/*
+ - docs/*
+ - CODE-OF-CONDUCT.md
+ - CONTRIBUTING.md
+ - LICENSE.TXT
+ - PATENTS.TXT
+ - README.md
+ - SECURITY.md
+ - THIRD-PARTY-NOTICES.TXT
+
+variables:
+ - template: /eng/pipelines/common/variables.yml
+
+jobs:
+#
+# Checkout repository
+#
+- template: /eng/pipelines/common/checkout-job.yml
+
+#
+# Build with Debug config and Checked runtimeConfiguration
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ buildConfig: Checked
+ platforms:
+ - Linux_x64
+ - Windows_NT_x64
+ jobParameters:
+ testGroup: innerloop
+ buildArgs: -s clr+libs+installer -c debug -runtimeConfiguration Checked
+ extraStepsTemplate: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml
+
+#
+# Build with Release config and Release runtimeConfiguration
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ buildConfig: Release
+ platforms:
+ - Linux_x64
+ - Windows_NT_x64
+ jobParameters:
+ testGroup: innerloop
+ buildArgs: -s clr+libs+libs.tests+installer -c $(_BuildConfig) /p:ArchiveTests=true
+ extraStepsTemplate: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml
+ extraStepsParameters:
+ uploadTests: true
+
+#
+# Build with Release allConfigurations to produce packages
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ buildConfig: release
+ platforms:
+ - Windows_NT_x64
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: All_Configurations
+ buildArgs: -s libs -c $(_BuildConfig) -allConfigurations
+
+#
+# CoreCLR Test builds using live libraries release build
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/templates/runtimes/build-test-job.yml
+ buildConfig: Checked
+ platforms:
+ - Linux_x64
+ jobParameters:
+ testGroup: innerloop
+ liveLibrariesBuildConfig: Release
+ dependsOn:
+ - build_Linux_x64_Checked_
+ - build_Linux_x64_Release_
+
+#
+# CoreCLR Test executions using live libraries
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml
+ buildConfig: Checked
+ platforms:
+ - Linux_x64
+ helixQueueGroup: pr
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
+ jobParameters:
+ testGroup: innerloop
+ liveLibrariesBuildConfig: Release
+ dependsOn:
+ - coreclr_common_test_build_p0_AnyOS_AnyCPU_Checked
+
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml
+ buildConfig: Checked
+ platforms:
+ - Windows_NT_x64
+ helixQueueGroup: pr
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
+ jobParameters:
+ testGroup: innerloop
+ liveLibrariesBuildConfig: Release
+ dependsOn:
+ - coreclr_common_test_build_p0_AnyOS_AnyCPU_Checked
+ - build_Windows_NT_x64_Checked_
+ - build_Windows_NT_x64_Release_
+
+#
+# Libraries Release Test Execution against a release coreclr runtime
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/libraries/run-test-job.yml
+ buildConfig: Release
+ platforms:
+ - Linux_x64
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ jobParameters:
+ isFullMatrix: false
+ isOfficialBuild: false
+ testScope: innerloop
+ liveRuntimeBuildConfig: Release
+ dependsOnTestBuildConfiguration: Release
+ dependsOnTestArchitecture: x64
+ dependsOn:
+ - build_Linux_x64_Release_
+
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/libraries/run-test-job.yml
+ buildConfig: Release
+ platforms:
+ - Windows_NT_x64
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ jobParameters:
+ isFullMatrix: false
+ isOfficialBuild: false
+ testScope: innerloop
+ liveRuntimeBuildConfig: Release
+ dependsOnTestBuildConfiguration: Release
+ dependsOnTestArchitecture: x64
+ dependsOn:
+ - build_Windows_NT_x64_Release_
diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml
new file mode 100644
index 00000000000000..e5fbcba7bc9515
--- /dev/null
+++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml
@@ -0,0 +1,59 @@
+parameters:
+ buildConfig: ''
+ archType: ''
+ osGroup: ''
+ osSubgroup: ''
+ uploadTests: false
+
+steps:
+ # Build coreclr native test output
+ - script: $(Build.SourcesDirectory)/src/coreclr/build-test$(scriptExt) skipstressdependencies skipmanaged skipgeneratelayout $(buildConfigUpper) ${{ parameters.archType }}
+ displayName: Build native test components
+
+ # Copy all build output into artifacts staging directory
+ - template: /eng/pipelines/libraries/prepare-for-bin-publish.yml
+
+ # Zip CoreCLR Build Output
+ - template: /eng/pipelines/common/upload-artifact-step.yml
+ parameters:
+ rootFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr/${{ parameters.osGroup }}.${{ parameters.archType }}.$(buildConfigUpper)
+ archiveType: $(archiveType)
+ tarCompression: $(tarCompression)
+ includeRootFolder: false
+ archiveExtension: $(archiveExtension)
+ artifactName: CoreCLRProduct__${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}
+ displayName: 'CoreCLR product build'
+
+ # Zip Test Build
+ - ${{ if eq(parameters.uploadTests, true) }}:
+ - template: /eng/pipelines/common/upload-artifact-step.yml
+ parameters:
+ rootFolder: $(Build.SourcesDirectory)/artifacts/helix
+ includeRootFolder: true
+ archiveType: $(archiveType)
+ archiveExtension: $(archiveExtension)
+ tarCompression: $(tarCompression)
+ artifactName: libraries_test_assets_${{ parameters.osGroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}
+ displayName: Test Assets
+
+ # Zip product native assets for use by Tests
+ - template: /eng/pipelines/common/upload-artifact-step.yml
+ parameters:
+ rootFolder: $(Build.SourcesDirectory)/artifacts/tests/coreclr/obj/${{ parameters.osGroup }}.${{ parameters.archType }}.$(buildConfigUpper)
+ includeRootFolder: false
+ archiveType: $(archiveType)
+ tarCompression: $(tarCompression)
+ archiveExtension: $(archiveExtension)
+ artifactName: CoreCLRNativeTestArtifacts_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}
+ displayName: 'native test components'
+
+ # Zip Libraries Build Output
+ - template: /eng/pipelines/common/upload-artifact-step.yml
+ parameters:
+ rootFolder: $(Build.ArtifactStagingDirectory)/artifacts
+ archiveType: $(archiveType)
+ tarCompression: $(tarCompression)
+ includeRootFolder: false
+ archiveExtension: $(archiveExtension)
+ artifactName: libraries_bin_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}
+ displayName: Build Assets
diff --git a/eng/referenceAssemblies.props b/eng/referenceAssemblies.props
index a5e0e553f12f7a..94508fa244ad3d 100644
--- a/eng/referenceAssemblies.props
+++ b/eng/referenceAssemblies.props
@@ -1,9 +1,9 @@
- $(AdditionalBuildTargetFrameworks);netstandard2.0
- $(AdditionalBuildTargetFrameworks);netstandard2.1
+ !$(BuildTargetFramework.StartsWith('netstandard')) and
+ !$(BuildTargetFramework.StartsWith('net4'))">
+ $(AdditionalBuildTargetFrameworks);netstandard2.0
+ $(AdditionalBuildTargetFrameworks);netstandard2.1
diff --git a/eng/referenceFromRuntime.targets b/eng/referenceFromRuntime.targets
deleted file mode 100644
index 34d0eb49199c8c..00000000000000
--- a/eng/referenceFromRuntime.targets
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-
- AddRuntimeProjectReference;
- $(PrepareProjectReferencesDependsOn);
-
-
- AddRuntimeProjectReference;
- $(ResolveReferencesDependsOn);
-
-
- AddRuntimeProjectReference;
- $(CleanDependsOn)
-
-
-
-
- $([MSBuild]::NormalizePath('$(LibrariesProjectRoot)', 'restore', 'runtime', 'runtime.depproj'))
-
-
-
-
-
-
-
- false
- _referencePathFromRestoredRuntime
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_referencePathFromRuntime Include="@(RuntimeFiles)" Private="false" />
- <_referencePathFromRuntime Include="@(_referencePathFromRestoredRuntime)" Private="false" />
-
- <_referencePathFromRuntime Include="@(ReferenceFromRuntime->'$(RuntimePath)%(Identity).dll')" Condition="'$(IsTestProject)' == 'true' or '$(IsTestSupportProject)' == 'true'" />
-
- <_referencePathFromRuntimeByFileName Include="@(_referencePathFromRuntime->'%(FileName)')" Condition="'%(_referencePathFromRuntime.Extension)' == '.dll'" >
- %(Identity)
-
-
-
-
-
-
-
-
-
-
- <_filteredReferencePathFromRuntimeByFileName Include="@(_referencePathFromRuntimeByFileNameFiltered)"
- Condition="'@(_referencePathFromRuntimeByFileNameFiltered)' == '@(ReferenceFromRuntime)' and '%(Identity)' != ''">
- @(ReferenceFromRuntime->'%(Aliases)')
-
-
- <_remainingReferenceFromRuntime Include="@(ReferenceFromRuntime)" Exclude="@(_filteredReferencePathFromRuntimeByFileName)" />
-
-
- <_remainingReferenceFromRuntimeWithNI Include="@(_remainingReferenceFromRuntime->'%(Identity).ni')">
- %(Identity)
-
-
- <_filteredReferencePathFromRuntimeByFileName Include="@(_referencePathFromRuntimeByFileNameFiltered)"
- Condition="'@(_referencePathFromRuntimeByFileNameFiltered)' == '@(_remainingReferenceFromRuntimeWithNI)' and '%(Identity)' != ''">
- @(_remainingReferenceFromRuntimeWithNI->'%(Aliases)')
-
-
- <_missingReferenceFromRuntime Include="@(_remainingReferenceFromRuntimeWithNI)" Exclude="@(_filteredReferencePathFromRuntimeByFileName)" />
-
-
-
-
-
-
-
- <_aliasedReferencePathFromRuntime Include="@(_filteredReferencePathFromRuntimeByFileName->'%(ReferencePath)')" Condition="'%(_filteredReferencePathFromRuntimeByFileName.Aliases)' != ''" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/eng/references.targets b/eng/references.targets
index efcac7d0515214..38037cf78ab022 100644
--- a/eng/references.targets
+++ b/eng/references.targets
@@ -1,67 +1,56 @@
- $(RefPath)
- $(RefPath)
- $(AssemblySearchPaths);$(RefPath);{RawFileName}
<_FindDependencies>false
-
- <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory)
- <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)
-
-
- true
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
-
-
-
+
+
+
+
-
-
-
+
+
+
+
-
-
-
+
+
+
+ false
+
+
-
- %(DefaultReferenceDirs.Identity)
-
- <_defaultReferenceExclusionsFullPath Include="%(DefaultReferenceExclusions.RefDir)%(DefaultReferenceExclusions.Identity).dll" />
-
-
-
+
+
+
+ <_transitiveProjectReferenceWithExclusion Include="@(ProjectReference)">
+ %(DefaultReferenceExclusion.Identity)
+
+
-
+
+
-
+
-
-
\ No newline at end of file
+
diff --git a/eng/resolveContract.targets b/eng/resolveContract.targets
index 2f59f5d9a51734..6f4bb0e253ee30 100644
--- a/eng/resolveContract.targets
+++ b/eng/resolveContract.targets
@@ -1,8 +1,18 @@
+
+ $(MicrosoftNetCoreAppRefPackRefDir)
+
+ $(ContractDependencyPaths);@(ReferencePath->'%(RelativeDir)'->Distinct())
+
+
- $(LibrariesProjectRoot)$(MSBuildProjectName)/ref/$(MSBuildProjectName).csproj
+ $(LibrariesProjectRoot)$(MSBuildProjectName)\ref\$(MSBuildProjectName).csproj
true
- $(RefPath)/$(MSBuildProjectName).dll
+ $(NetCoreAppCurrentRefPath)$(TargetFileName)
+ $([MSBuild]::NormalizePath('$(BaseOutputPath)', 'ref', '$(TargetFramework)-$(Configuration)', '$(TargetFileName)'))
false
@@ -10,8 +20,43 @@
+
+
+ false
+ ResolvedMatchingContract
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+ <_resolvedP2PFiltered Include="@(ProjectReference)">
+ $([System.IO.Path]::GetFullPath('%(ProjectReference.Identity)'))
+ %(ProjectReference.SkipUseReferenceAssembly)
+
+ <_ResolvedProjectReferencePaths Update="@(_resolvedProjectReferenceFiltred)"
+ Condition="'%(_resolvedP2PFiltered.ProjectReferenceItemSpec)' == '%(_resolvedP2PFiltered.MSBuildSourceProjectFile)' and
+ '%(_resolvedP2PFiltered.SkipUseReferenceAssembly)' == 'true'"
+ ReferenceAssembly="" />
+
+
\ No newline at end of file
diff --git a/eng/restore/repoRestore.props b/eng/restore/repoRestore.props
index 300c542e8cbe1c..d2ca92d6db0131 100644
--- a/eng/restore/repoRestore.props
+++ b/eng/restore/repoRestore.props
@@ -1,5 +1,6 @@
+ $(RepoRoot)artifacts\toolset\Common\
false
unused
diff --git a/eng/targetingpacks.targets b/eng/targetingpacks.targets
new file mode 100644
index 00000000000000..e39ce8fdada6b0
--- /dev/null
+++ b/eng/targetingpacks.targets
@@ -0,0 +1,106 @@
+
+
+ <_UseLocalTargetingRuntimePack>true
+ false
+
+
+
+
+
+
+ $(PkgMicrosoft_NETCore_App)\ref\$(_ShortFrameworkIdentifier)$(_ShortFrameworkVersion)\
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+ %(ResolvedFrameworkReference.TargetingPackPath)\ref\$(_ShortFrameworkIdentifier)$(_ShortFrameworkVersion)\
+
+
+
+
+
+
+
+
+
+ $(AssemblySearchPaths);$(MicrosoftNetCoreAppRefPackRefDir.TrimEnd('/\'))
+ $(DesignTimeAssemblySearchPaths);$(MicrosoftNetCoreAppRefPackRefDir.TrimEnd('/\'))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_targetingPackReferenceExclusion Include="$(TargetName)" />
+ <_targetingPackReferenceExclusion Include="@(_ResolvedProjectReferencePaths->'%(Filename)')" />
+ <_targetingPackReferenceExclusion Include="@(DefaultReferenceExclusion)" />
+
+
+
+ <_targetingPackReferenceWithExclusion Include="@(Reference)">
+ %(_targetingPackReferenceExclusion.Identity)
+
+
+
+
+
\ No newline at end of file
diff --git a/eng/testing/.runsettings b/eng/testing/.runsettings
index fabc0310a7aa51..cf00c4a467379f 100644
--- a/eng/testing/.runsettings
+++ b/eng/testing/.runsettings
@@ -18,10 +18,6 @@
$$TESTCASEFILTER$$
$$DOTNETHOSTPATH$$
-
-
- $$DEVPATH$$
-
diff --git a/eng/testing/RunnerTemplate.cmd b/eng/testing/RunnerTemplate.cmd
index fe28e9157a6e2b..10737eabe70950 100644
--- a/eng/testing/RunnerTemplate.cmd
+++ b/eng/testing/RunnerTemplate.cmd
@@ -41,12 +41,6 @@ set EXECUTION_DIR=%~dp0
:argparser_end
-if not defined RUNTIME_PATH (
- echo error: -r^|--runtime-path argument is required.
- call :usage
- exit /b -1
-)
-
:: Don't use a globally installed SDK.
set DOTNET_MULTILEVEL_LOOKUP=0
diff --git a/eng/testing/linker/SupportFiles/Directory.Build.targets b/eng/testing/linker/SupportFiles/Directory.Build.targets
index 49422a33b9be30..a9dfda8012d9fa 100644
--- a/eng/testing/linker/SupportFiles/Directory.Build.targets
+++ b/eng/testing/linker/SupportFiles/Directory.Build.targets
@@ -20,11 +20,14 @@
+ BeforeTargets="PrepareForILLink">
link
+
+
+
diff --git a/eng/testing/linker/project.csproj.template b/eng/testing/linker/project.csproj.template
index ef63096e8019c0..2f1f26c2fd875e 100644
--- a/eng/testing/linker/project.csproj.template
+++ b/eng/testing/linker/project.csproj.template
@@ -6,9 +6,17 @@
{RuntimeIdentifier}
{RuntimePackDir}
{TargetingPackDir}
- <_ExtraTrimmerArgs>{ExtraTrimmerArgs} $(_ExtraTrimmerArgs)
+
+ IL2006;IL2026
+
+ $(LinkerNoWarn);IL2008;IL2009;IL2037
+ <_ExtraTrimmerArgs>{ExtraTrimmerArgs} $(_ExtraTrimmerArgs) --nowarn $(LinkerNoWarn)
+
+ {AdditionalProjectReferences}
+
+
@@ -28,4 +36,4 @@
GeneratePathProperty="true" />
-
\ No newline at end of file
+
diff --git a/eng/testing/linker/trimmingTests.targets b/eng/testing/linker/trimmingTests.targets
index 3729bd306bca94..6d89002d9e0c6a 100644
--- a/eng/testing/linker/trimmingTests.targets
+++ b/eng/testing/linker/trimmingTests.targets
@@ -57,6 +57,15 @@
<_projectSourceFile>%(TestConsoleApps.ProjectCompileItems)
+
+ <_additionalProjectReferenceTemp Include="$(AdditionalProjectReferences)" />
+ <_additionalProjectReference Include="<ProjectReference Include="$(LibrariesProjectRoot)%(_additionalProjectReferenceTemp.Identity)\src\%(_additionalProjectReferenceTemp.Identity).csproj" SkipUseReferenceAssembly="true" />" />
+
+
+
+ <_additionalProjectReferencesString>@(_additionalProjectReference, '%0a')
+
+
<_additionalProjectSourceFiles Include="%(TestConsoleApps.AdditionalSourceFiles)" />
@@ -69,7 +78,8 @@
.Replace('{TargetingPackDir}','$(MicrosoftNetCoreAppRefPackDir)')
.Replace('{RuntimeIdentifier}','%(TestConsoleApps.TestRuntimeIdentifier)')
.Replace('{MicrosoftNETILLinkTasksVersion}', '$(MicrosoftNETILLinkTasksVersion)')
- .Replace('{ExtraTrimmerArgs}', '%(TestConsoleApps.ExtraTrimmerArgs)'))"
+ .Replace('{ExtraTrimmerArgs}', '%(TestConsoleApps.ExtraTrimmerArgs)')
+ .Replace('{AdditionalProjectReferences}', '$(_additionalProjectReferencesString)'))"
Overwrite="true" />
diff --git a/eng/testing/netfx.exe.config b/eng/testing/netfx.exe.config
index ed7d7d082438c8..e131497fc76118 100644
--- a/eng/testing/netfx.exe.config
+++ b/eng/testing/netfx.exe.config
@@ -1,7 +1,6 @@
-
\ No newline at end of file
diff --git a/eng/testing/outerBuild.targets b/eng/testing/outerBuild.targets
index 4623b0e54d2504..c071944c21d93d 100644
--- a/eng/testing/outerBuild.targets
+++ b/eng/testing/outerBuild.targets
@@ -1,8 +1,12 @@
+ Targets="Test">
+
+
+
+
\ No newline at end of file
diff --git a/eng/testing/runsettings.targets b/eng/testing/runsettings.targets
index 10496127b8a90a..5a2c9a84d6893d 100644
--- a/eng/testing/runsettings.targets
+++ b/eng/testing/runsettings.targets
@@ -36,7 +36,6 @@
.Replace('$$DISABLEPARALLELIZATION$$', '$([MSBuild]::ValueOrDefault('$(TestDisableParallelization)', 'false'))')
.Replace('$$DISABLEAPPDOMAIN$$', '$([MSBuild]::ValueOrDefault('$(TestDisableAppDomain)', 'false'))')
.Replace('$$TESTCASEFILTER$$', '$(_testFilter)')
- .Replace('$$DEVPATH$$', '$(TestHostRootPath)')
.Replace('$$DOTNETHOSTPATH$$', '$(TestHostRootPath)$([System.IO.Path]::GetFileName('$(DotNetTool)'))'))
diff --git a/eng/testing/runtimeConfiguration.targets b/eng/testing/runtimeConfiguration.targets
index f687adfad40f97..d69182992c7b30 100644
--- a/eng/testing/runtimeConfiguration.targets
+++ b/eng/testing/runtimeConfiguration.targets
@@ -1,45 +1,31 @@
-
- $(MSBuildThisFileDirectory)netfx.exe.config
-
- true
+ true
+ true
+ true
+ $(MSBuildThisFileDirectory)netfx.exe.config
+
+ $(TargetPath).config
-
-
+
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets
index 266a6d37be6518..84b8337494a465 100644
--- a/eng/testing/tests.mobile.targets
+++ b/eng/testing/tests.mobile.targets
@@ -14,7 +14,7 @@
- $HARNESS_RUNNER wasm test --engine=$(JSEngine) $(JSEngineArgs) --js-file=runtime.js -v --output-directory=$XHARNESS_OUT -- --enable-zoneinfo --run WasmTestRunner.dll $(AssemblyName).dll
+ $HARNESS_RUNNER wasm test --engine=$(JSEngine) $(JSEngineArgs) --js-file=runtime.js -v --output-directory=$XHARNESS_OUT -- --run WasmTestRunner.dll $(AssemblyName).dll
@@ -132,30 +132,23 @@
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+ AssemblySearchPaths="@(AssemblySearchPaths)" />
-
-
-
-
-
-
-
-
-
-
-
-
+ DependsOnTargets="Publish;BundleTestAppleApp;BundleTestAndroidApp;BundleTestWasmApp;ArchiveTests" />
diff --git a/eng/testing/tests.props b/eng/testing/tests.props
index bf2f93fcceb39b..65664f7f74992b 100644
--- a/eng/testing/tests.props
+++ b/eng/testing/tests.props
@@ -29,8 +29,6 @@
$(PackageRID)
true
- false
-
diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets
index 1534c3aa0dadd9..2fe669a10ba05a 100644
--- a/eng/testing/tests.targets
+++ b/eng/testing/tests.targets
@@ -19,11 +19,6 @@
$(RunScriptHostDir)dotnet
-
-
-
-
-
PrepareForRun
@@ -41,7 +36,6 @@
- $([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle'))
<_ZipSourceDirectory>$(OutDir)
<_ZipSourceDirectory Condition="'$(TargetOS)' == 'Browser'">$(BundleDir)
@@ -50,6 +44,8 @@
+
+
@@ -95,7 +91,10 @@
- "$(RunScriptOutputPath)" --runtime-path "$(TestHostRootPath.TrimEnd('\/'))"
+ "$(RunScriptOutputPath)"
+
+ $(RunTestsCommand) --runtime-path "$(TestHostRootPath.TrimEnd('\/'))"
$(RunTestsCommand) --rsp-file "$(TestRspFile)"
"$(RunScriptOutputPath)" $(AssemblyName) $(TargetArchitecture)
"$(RunScriptOutputPath)" $(JSEngine) $(AssemblyName).dll $(_withoutCategories.Replace(';', ' -notrait category='))
diff --git a/eng/testing/xunit/xunit.console.targets b/eng/testing/xunit/xunit.console.targets
index 837b432a99eb7d..5b71327e96450b 100644
--- a/eng/testing/xunit/xunit.console.targets
+++ b/eng/testing/xunit/xunit.console.targets
@@ -37,24 +37,23 @@
Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'" />
-
- <_testRunnerConfigSourceFile Include="$(TargetDir)$(TargetName).exe.config" />
<_testRunnerConfigDestFile Include="$(TargetDir)xunit.console.exe.config" />
-
-
@@ -62,7 +61,9 @@
@@ -74,5 +75,13 @@
CopyToOutputDirectory="PreserveNewest"
Visible="false" />
+
+
+
+
+
+
+
+
diff --git a/eng/testing/xunit/xunit.props b/eng/testing/xunit/xunit.props
index 8b21cecac618e3..69355a452a48ee 100644
--- a/eng/testing/xunit/xunit.props
+++ b/eng/testing/xunit/xunit.props
@@ -16,7 +16,7 @@
-
+
+
+
+
$(OutDir)
diff --git a/eng/versioning.targets b/eng/versioning.targets
index 1eba158bb6beae..2a2f10dbcafb90 100644
--- a/eng/versioning.targets
+++ b/eng/versioning.targets
@@ -22,10 +22,17 @@
-
+
-
- <_Parameter1>$(MinimiumSupportedWindowsPlatform)
+
+ <_Parameter1>windows
+
+
+
+
+
+
+ <_Parameter1>$(UnsupportedOSPlatform)
diff --git a/global.json b/global.json
index 64916dd7429cba..5d4b27ae61c0c7 100644
--- a/global.json
+++ b/global.json
@@ -12,10 +12,10 @@
"python3": "3.7.1"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20364.3",
- "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20364.3",
- "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20364.3",
- "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20364.3",
+ "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "5.0.0-beta.20374.1",
+ "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20374.1",
+ "Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.20374.1",
+ "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20374.1",
"Microsoft.FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0",
"Microsoft.NET.Sdk.IL": "5.0.0-preview.8.20359.4",
"Microsoft.Build.NoTargets": "1.0.53",
diff --git a/src/coreclr/CMakeLists.txt b/src/coreclr/CMakeLists.txt
index 0d60cf16fc1066..b94eb54a671540 100644
--- a/src/coreclr/CMakeLists.txt
+++ b/src/coreclr/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.14.5)
+cmake_minimum_required(VERSION 3.6.2)
cmake_policy(SET CMP0042 NEW)
diff --git a/src/coreclr/build-test.cmd b/src/coreclr/build-test.cmd
index 62fe83149b50e5..d0d1a333196792 100644
--- a/src/coreclr/build-test.cmd
+++ b/src/coreclr/build-test.cmd
@@ -653,17 +653,14 @@ if defined __CompositeBuildMode (
)
for %%F in ("%CORE_ROOT%\System.*.dll";"%CORE_ROOT%\Microsoft.*.dll";%CORE_ROOT%\netstandard.dll;%CORE_ROOT%\mscorlib.dll) do (
- if not "%%~nxF"=="Microsoft.CodeAnalysis.VisualBasic.dll" (
- if not "%%~nxF"=="Microsoft.CodeAnalysis.CSharp.dll" (
- if not "%%~nxF"=="Microsoft.CodeAnalysis.dll" (
if not "%%~nxF"=="System.Runtime.WindowsRuntime.dll" (
if defined __CompositeBuildMode (
echo %%F>>!__CompositeResponseFile!
) else (
- call :PrecompileAssembly "%%F" %%~nxF __TotalPrecompiled __FailedToPrecompile __FailedAssemblies
+ call :PrecompileAssembly %%F %%~nxF __TotalPrecompiled __FailedToPrecompile __FailedAssemblies
echo Processed: !__TotalPrecompiled!, failed !__FailedToPrecompile!
)
- )))))
+ ))
)
if defined __CompositeBuildMode (
@@ -695,19 +692,33 @@ set AssemblyName=%2
REM Intentionally avoid using the .dll extension to prevent
REM subsequent compilations from picking it up as a reference
-set __CrossgenOutputFile="%CORE_ROOT%\temp.ni._dll"
+set __CrossgenOutputFile=%CORE_ROOT%\temp.ni._dll
+set __CrossgenResponseFile="%CORE_ROOT%\%AssemblyName%.rsp
set __CrossgenCmd=
+del /Q %__CrossgenResponseFile%
+
if defined __DoCrossgen (
- set __CrossgenCmd=!__CrossgenExe! /Platform_Assemblies_Paths "!CORE_ROOT!" /in !AssemblyPath! /out !__CrossgenOutputFile!
- echo !__CrossgenCmd!
- !__CrossgenCmd!
+ set __CrossgenCmd=!__CrossgenExe! @!__CrossgenResponseFile!
+ echo /Platform_Assemblies_Paths "!CORE_ROOT!">>!__CrossgenResponseFile!
+ echo /in !AssemblyPath!>>!__CrossgenResponseFile!
+ echo /out !__CrossgenOutputFile!>>!__CrossgenResponseFile!
) else (
- set __CrossgenCmd=!__Crossgen2Dll! -r:"!CORE_ROOT!\System.*.dll" -r:"!CORE_ROOT!\Microsoft.*.dll" -r:"!CORE_ROOT!\mscorlib.dll" -r:"!CORE_ROOT!\netstandard.dll" -O --inputbubble --out:!__CrossgenOutputFile! !AssemblyPath! --targetarch %__BuildArch%
- echo !__CrossgenCmd!
- call !__CrossgenCmd!
+ set __CrossgenCmd=!__Crossgen2Dll! @!__CrossgenResponseFile!
+ echo -r:!CORE_ROOT!\System.*.dll>>!__CrossgenResponseFile!
+ echo -r:!CORE_ROOT!\Microsoft.*.dll>>!__CrossgenResponseFile!
+ echo -r:!CORE_ROOT!\mscorlib.dll>>!__CrossgenResponseFile!
+ echo -r:!CORE_ROOT!\netstandard.dll>>!__CrossgenResponseFile!
+ echo -O>>!__CrossgenResponseFile!
+ echo --inputbubble>>!__CrossgenResponseFile!
+ echo --out:!__CrossgenOutputFile!>>!__CrossgenResponseFile!
+ echo !AssemblyPath!>>!__CrossgenResponseFile!
+ echo --targetarch:!__BuildArch!>>!__CrossgenResponseFile!
)
+echo !__CrossgenCmd!
+call !__CrossgenCmd!
+
set /a __exitCode = !errorlevel!
set /a "%~3+=1"
diff --git a/src/coreclr/build-test.sh b/src/coreclr/build-test.sh
index f1a26c565e3b02..b67fbef45f92ad 100755
--- a/src/coreclr/build-test.sh
+++ b/src/coreclr/build-test.sh
@@ -131,7 +131,6 @@ generate_layout()
mkdir -p "$CORE_ROOT"
chmod +x "$__BinDir"/corerun
- chmod +x "$__CrossgenExe"
build_MSBuild_projects "Tests_Overlay_Managed" "${__ProjectDir}/tests/src/runtest.proj" "Creating test overlay" "/t:CreateTestOverlay"
@@ -149,6 +148,7 @@ generate_layout()
# Precompile framework assemblies with crossgen if required
if [[ "$__DoCrossgen" != 0 || "$__DoCrossgen2" != 0 ]]; then
+ chmod +x "$__CrossgenExe"
if [[ "$__SkipCrossgenFramework" == 0 ]]; then
precompile_coreroot_fx
fi
@@ -168,35 +168,30 @@ precompile_coreroot_fx()
local outputDir="$overlayDir"/out
# Delete previously crossgened assemblies
- rm "$overlayDir"/*.ni.dll
-
- # Collect reference assemblies for Crossgen2
- local crossgen2References=""
+ rm "$overlayDir"/*.ni.dll 2>/dev/null
if [[ "$__DoCrossgen2" != 0 ]]; then
compilerName=Crossgen2
mkdir "$outputDir"
-
- skipCrossGenFiles+=('Microsoft.CodeAnalysis.CSharp.dll')
- skipCrossGenFiles+=('Microsoft.CodeAnalysis.dll')
- skipCrossGenFiles+=('Microsoft.CodeAnalysis.VisualBasic.dll')
-
- for reference in "$overlayDir"/*.dll; do
- crossgen2References+=" -r:${reference}"
- done
fi
echo "${__MsgPrefix}Running ${compilerName} on framework assemblies in CORE_ROOT: '${CORE_ROOT}'"
local totalPrecompiled=0
local failedToPrecompile=0
- local compositeCommandLine="${__DotNetCli}"
- compositeCommandLine+=" $__Crossgen2Dll"
- compositeCommandLine+=" --composite"
- compositeCommandLine+=" -O"
- compositeCommandLine+=" --out:$outputDir/framework-r2r.dll"
- compositeCommandLine+=" --targetarch ${__BuildArch}"
+ local compositeOutputFile=$outputDir/framework-r2r.dll
+ local compositeResponseFile=$compositeOutputFile.rsp
+ local compositeCommandLine="${__DotNetCli} $__Crossgen2Dll @$compositeResponseFile"
+
+ if [[ "$__CompositeBuildMode" != 0 ]]; then
+ rm $compositeResponseFile 2>/dev/null
+ echo --composite>>$compositeResponseFile
+ echo -O>>$compositeResponseFile
+ echo --out:$compositeOutputFile>>$compositeResponseFile
+ echo --targetarch:${__BuildArch}>>$compositeResponseFile
+ fi
+
declare -a failedAssemblies
filesToPrecompile=$(find -L "$overlayDir" -maxdepth 1 -iname Microsoft.\*.dll -o -iname System.\*.dll -o -iname netstandard.dll -o -iname mscorlib.dll -type f)
@@ -207,18 +202,32 @@ precompile_coreroot_fx()
fi
if [[ "$__CompositeBuildMode" != 0 ]]; then
- compositeCommandLine+=" $filename"
+ echo $filename>>$compositeResponseFile
continue
fi
local commandLine=""
+ local responseFile="$overlayDir/$(basename $filename).rsp"
+
+ rm $responseFile 2>/dev/null
if [[ "$__DoCrossgen" != 0 ]]; then
- commandLine="$__CrossgenExe /Platform_Assemblies_Paths $overlayDir $filename"
+ commandLine="$__CrossgenExe @$responseFile"
+ echo /Platform_Assemblies_Paths>>$responseFile
+ echo $overlayDir>>$responseFile
+ echo $filename>>$responseFile
fi
if [[ "$__DoCrossgen2" != 0 ]]; then
- commandLine="${__DotNetCli} $__Crossgen2Dll $crossgen2References -O --inputbubble --out $outputDir/$(basename $filename) $filename --targetarch ${__BuildArch}"
+ commandLine="${__DotNetCli} $__Crossgen2Dll @$responseFile"
+ echo -O>>$responseFile
+ echo --inputbubble>>$responseFile
+ echo --out:$outputDir/$(basename $filename)>>$responseFile
+ echo --targetarch:${__BuildArch}>>$responseFile
+ echo $filename>>$responseFile
+ for reference in $overlayDir/*.dll; do
+ echo -r:$reference>>$responseFile
+ done
fi
echo Precompiling "$filename"
@@ -245,6 +254,8 @@ precompile_coreroot_fx()
if [[ "$__CompositeBuildMode" != 0 ]]; then
# Compile the entire framework in composite build mode
+ echo "Response file: $compositeResponseFile"
+ cat $compositeResponseFile
echo "Compiling composite R2R framework: $compositeCommandLine"
$compositeCommandLine
local exitCode="$?"
diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props
index b5979c8d239013..c5119c80424d23 100644
--- a/src/coreclr/clr.featuredefines.props
+++ b/src/coreclr/clr.featuredefines.props
@@ -66,9 +66,5 @@
$(DefineConstants);PROFILING_SUPPORTED
$(DefineConstants);FEATURE_PROFAPI_ATTACH_DETACH
-
- $(DefineConstants);TARGET_UNIX
- $(DefineConstants);TARGET_WINDOWS
- $(DefineConstants);TARGET_OSX
diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake
index 7be0a6915051af..b717c10d840a40 100644
--- a/src/coreclr/clrdefinitions.cmake
+++ b/src/coreclr/clrdefinitions.cmake
@@ -30,7 +30,6 @@ if (CLR_CMAKE_TARGET_UNIX)
if(CLR_CMAKE_TARGET_OSX)
add_definitions(-D_XOPEN_SOURCE)
- add_definitions(-DFEATURE_DATATARGET4)
endif(CLR_CMAKE_TARGET_OSX)
if (CLR_CMAKE_TARGET_ARCH_AMD64)
@@ -173,9 +172,9 @@ set(FEATURE_READYTORUN 1)
add_compile_definitions($<$>>:FEATURE_REJIT>)
-if (CLR_CMAKE_HOST_UNIX AND CLR_CMAKE_TARGET_UNIX AND NOT CLR_CMAKE_TARGET_OSX)
+if (CLR_CMAKE_HOST_UNIX AND CLR_CMAKE_TARGET_UNIX)
add_definitions(-DFEATURE_REMOTE_PROC_MEM)
-endif (CLR_CMAKE_HOST_UNIX AND CLR_CMAKE_TARGET_UNIX AND NOT CLR_CMAKE_TARGET_OSX)
+endif (CLR_CMAKE_HOST_UNIX AND CLR_CMAKE_TARGET_UNIX)
if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_ARCH_ARM64)
add_definitions(-DFEATURE_STUBS_AS_IL)
diff --git a/src/coreclr/pgosupport.cmake b/src/coreclr/pgosupport.cmake
index 4b11980901712d..04bde2bc20bca0 100644
--- a/src/coreclr/pgosupport.cmake
+++ b/src/coreclr/pgosupport.cmake
@@ -1,5 +1,18 @@
-include(CheckIPOSupported)
-check_ipo_supported(RESULT HAVE_LTO)
+include(CheckCXXSourceCompiles)
+include(CheckCXXCompilerFlag)
+
+# VC++ guarantees support for LTCG (LTO's equivalent)
+if(NOT WIN32)
+ # Function required to give CMAKE_REQUIRED_* local scope
+ function(check_have_lto)
+ set(CMAKE_REQUIRED_FLAGS -flto)
+ set(CMAKE_REQUIRED_LIBRARIES -flto -fuse-ld=gold)
+ check_cxx_source_compiles("int main() { return 0; }" HAVE_LTO)
+ endfunction(check_have_lto)
+ check_have_lto()
+
+ check_cxx_compiler_flag(-faligned-new COMPILER_SUPPORTS_F_ALIGNED_NEW)
+endif(NOT WIN32)
# Adds Profile Guided Optimization (PGO) flags to the current target
function(add_pgo TargetName)
diff --git a/src/coreclr/scripts/superpmi.py b/src/coreclr/scripts/superpmi.py
index fa0f3e2f165ded..12be260c67a91b 100755
--- a/src/coreclr/scripts/superpmi.py
+++ b/src/coreclr/scripts/superpmi.py
@@ -860,7 +860,8 @@ def replay(self):
altjit_string = "*" if self.coreclr_args.altjit else ""
altjit_flags = [
"-jitoption", "force", "AltJit=" + altjit_string,
- "-jitoption", "force", "AltJitNgen=" + altjit_string
+ "-jitoption", "force", "AltJitNgen=" + altjit_string,
+ "-jitoption", "force", "EnableExtraSuperPmiQueries=0"
]
flags += altjit_flags
@@ -1032,8 +1033,10 @@ def replay_with_asm_diffs(self):
altjit_flags = [
"-jitoption", "force", "AltJit=" + altjit_string,
"-jitoption", "force", "AltJitNgen=" + altjit_string,
+ "-jitoption", "force", "EnableExtraSuperPmiQueries=0",
"-jit2option", "force", "AltJit=" + altjit_string,
- "-jit2option", "force", "AltJitNgen=" + altjit_string
+ "-jit2option", "force", "AltJitNgen=" + altjit_string,
+ "-jit2option", "force", "EnableExtraSuperPmiQueries=0"
]
flags += altjit_flags
@@ -1208,7 +1211,8 @@ def replay_with_asm_diffs(self):
altjit_string = "*" if self.coreclr_args.altjit else ""
altjit_flags = [
"-jitoption", "force", "AltJit=" + altjit_string,
- "-jitoption", "force", "AltJitNgen=" + altjit_string
+ "-jitoption", "force", "AltJitNgen=" + altjit_string,
+ "-jitoption", "force", "EnableExtraSuperPmiQueries=0"
]
async def create_asm(print_prefix, item, self, text_differences, base_asm_location, diff_asm_location):
@@ -2128,7 +2132,7 @@ def verify_superpmi_common_args():
# yielding
# [0]: ""
# [1]: "\Windows_NT.x64.Checked"
- standard_location_split = os.path.dirname(coreclr_args.jit_path).split(os.path.dirname(coreclr_args.product_location))
+ standard_location_split = os.path.dirname(coreclr_args.base_jit_path).split(os.path.dirname(coreclr_args.product_location))
assert(coreclr_args.host_os in standard_location_split[1])
# Get arch/flavor. Remove leading slash.
diff --git a/src/coreclr/src/.nuget/Directory.Build.props b/src/coreclr/src/.nuget/Directory.Build.props
index 1a8f5c0d7414b4..257da02a7ffc9a 100644
--- a/src/coreclr/src/.nuget/Directory.Build.props
+++ b/src/coreclr/src/.nuget/Directory.Build.props
@@ -3,14 +3,19 @@
+
+
+
AnyCPU
-
- true
+
+ false
true
diff --git a/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.pkgproj b/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.pkgproj
new file mode 100644
index 00000000000000..54a1cc17dfbc4a
--- /dev/null
+++ b/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.pkgproj
@@ -0,0 +1,21 @@
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+ runtimes/$(PackageTargetRuntime)/native
+
+
+
+
+
+
+
diff --git a/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.proj b/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.proj
new file mode 100644
index 00000000000000..037a6b102605b5
--- /dev/null
+++ b/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.proj
@@ -0,0 +1,35 @@
+
+
+
+
+ false
+ linux-x64;linux-musl-x64;linux-arm64;linux-musl-arm64;linux-arm;
+
+
+
+
+
+
+
+
+ <_projectsToBuild Include="@(Project)" Condition="$(SupportedRids.Contains('%(Project.PackageTargetRuntime)'))">
+ %(AdditionalProperties);CrossDacBinRoot=$(CrossDacArtifactsDir)/Linux.x64.$(Configuration)/x64
+ %(AdditionalProperties);CrossDacBinRoot=$(CrossDacArtifactsDir)/Linux_musl.x64.$(Configuration)/x64
+ %(AdditionalProperties);CrossDacBinRoot=$(CrossDacArtifactsDir)/Linux.arm64.$(Configuration)/x64
+ %(AdditionalProperties);CrossDacBinRoot=$(CrossDacArtifactsDir)/Linux_musl.arm64.$(Configuration)/x64
+ %(AdditionalProperties);CrossDacBinRoot=$(CrossDacArtifactsDir)/Linux.arm.$(Configuration)/x86
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/coreclr/src/.nuget/coreclr-packages.proj b/src/coreclr/src/.nuget/coreclr-packages.proj
index f460db9bcd3d1b..83b95cd3748202 100644
--- a/src/coreclr/src/.nuget/coreclr-packages.proj
+++ b/src/coreclr/src/.nuget/coreclr-packages.proj
@@ -13,36 +13,8 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/src/coreclr/src/.nuget/descriptions.json b/src/coreclr/src/.nuget/descriptions.json
index e9ac7c58fcc1fc..c172fed61b84c8 100644
--- a/src/coreclr/src/.nuget/descriptions.json
+++ b/src/coreclr/src/.nuget/descriptions.json
@@ -9,6 +9,11 @@
"Description": "When using NuGet 3.x this package requires at least version {0}.",
"CommonTypes": [ ]
},
+ {
+ "Name": "Microsoft.CrossOsDiag.Private.CoreCLR",
+ "Description": "Private transport package for .NET Core cross OS diagnostic tooling.",
+ "CommonTypes": [ ]
+ },
{
"Name": "Microsoft.NETCore.ILAsm",
"Description": "The .NET IL Assembler.",
diff --git a/src/coreclr/src/.nuget/versioning.targets b/src/coreclr/src/.nuget/versioning.targets
new file mode 100644
index 00000000000000..9b5ea266a93f12
--- /dev/null
+++ b/src/coreclr/src/.nuget/versioning.targets
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets b/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets
index 18a6d21e57dcb7..4b232bbfdc21e0 100644
--- a/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets
+++ b/src/coreclr/src/System.Private.CoreLib/CreateRuntimeRootILLinkDescriptorFile.targets
@@ -7,12 +7,12 @@
<_ILLinkRuntimeRootDescriptorFilePath>$(ILLinkTrimXml)
<_NamespaceFilePath Condition=" '$(_NamespaceFilePath)' == '' ">$(MSBuildThisFileDirectory)..\vm\namespace.h
- <_MscorlibFilePath Condition=" '$(_MscorlibFilePath)' == '' ">$(MSBuildThisFileDirectory)..\vm\mscorlib.h
+ <_MscorlibFilePath Condition=" '$(_MscorlibFilePath)' == '' ">$(MSBuildThisFileDirectory)..\vm\corelib.h
<_CortypeFilePath Condition=" '$(_CortypeFilePath)' == '' ">$(MSBuildThisFileDirectory)..\inc\cortypeinfo.h
<_RexcepFilePath Condition=" '$(_RexcepFilePath)' == '' ">$(MSBuildThisFileDirectory)..\vm\rexcep.h
<_ILLinkDescriptorsIntermediatePath>$(IntermediateOutputPath)ILLink.Descriptors.Combined.xml
<_ILLinkTasksToolsDir>$(PkgMicrosoft_NET_ILLink_Tasks)/tools
- <_ILLinkTasksDir>$(_ILLinkTasksToolsDir)/$(NetFrameworkCurrent)/
+ <_ILLinkTasksDir>$(_ILLinkTasksToolsDir)/net472/
<_ILLinkTasksDir Condition="'$(MSBuildRuntimeType)' == 'Core'">$(_ILLinkTasksToolsDir)/netcoreapp3.0/
<_ILLinkTasksPath>$(_ILLinkTasksDir)ILLink.Tasks.dll
diff --git a/src/coreclr/src/System.Private.CoreLib/ILLinkTrim.xml b/src/coreclr/src/System.Private.CoreLib/ILLinkTrim.xml
index 11a67fdac31329..8031688ca0b98b 100644
--- a/src/coreclr/src/System.Private.CoreLib/ILLinkTrim.xml
+++ b/src/coreclr/src/System.Private.CoreLib/ILLinkTrim.xml
@@ -17,5 +17,12 @@
+
+
+
+
+
+
+
diff --git a/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj
index 501487c6a111bb..1665f9ac692502 100644
--- a/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj
+++ b/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj
@@ -224,6 +224,7 @@
+
diff --git a/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs b/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs
index 45f4d4839fb864..c41d4dd966169d 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs
@@ -25,7 +25,7 @@ public interface IClassFactory
void CreateInstance(
[MarshalAs(UnmanagedType.Interface)] object? pUnkOuter,
ref Guid riid,
- [MarshalAs(UnmanagedType.Interface)] out object? ppvObject);
+ out IntPtr ppvObject);
void LockServer([MarshalAs(UnmanagedType.Bool)] bool fLock);
}
@@ -51,7 +51,7 @@ internal interface IClassFactory2 : IClassFactory
new void CreateInstance(
[MarshalAs(UnmanagedType.Interface)] object? pUnkOuter,
ref Guid riid,
- [MarshalAs(UnmanagedType.Interface)] out object? ppvObject);
+ out IntPtr ppvObject);
new void LockServer([MarshalAs(UnmanagedType.Bool)] bool fLock);
@@ -66,7 +66,7 @@ void CreateInstanceLic(
[MarshalAs(UnmanagedType.Interface)] object? pUnkReserved,
ref Guid riid,
[MarshalAs(UnmanagedType.BStr)] string bstrKey,
- [MarshalAs(UnmanagedType.Interface)] out object ppvObject);
+ out IntPtr ppvObject);
}
[StructLayout(LayoutKind.Sequential)]
@@ -493,28 +493,32 @@ public static Type GetValidatedInterfaceType(Type classType, ref Guid riid, obje
#endif
}
- public static void ValidateObjectIsMarshallableAsInterface(object obj, Type interfaceType)
+ public static IntPtr GetObjectAsInterface(object obj, Type interfaceType)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
- // If the requested "interface type" is type object then return
- // because type object is always marshallable.
+ // If the requested "interface type" is type object then return as IUnknown
if (interfaceType == typeof(object))
{
- return;
+ return Marshal.GetIUnknownForObject(obj);
}
Debug.Assert(interfaceType.IsInterface);
- // The intent of this call is to validate the interface can be
+ // The intent of this call is to get AND validate the interface can be
// marshalled to native code. An exception will be thrown if the
// type is unable to be marshalled to native code.
// Scenarios where this is relevant:
// - Interfaces that use Generics
// - Interfaces that define implementation
- IntPtr ptr = Marshal.GetComInterfaceForObject(obj, interfaceType, CustomQueryInterfaceMode.Ignore);
+ IntPtr interfaceMaybe = Marshal.GetComInterfaceForObject(obj, interfaceType, CustomQueryInterfaceMode.Ignore);
- // Decrement the above 'Marshal.GetComInterfaceForObject()'
- Marshal.Release(ptr);
+ if (interfaceMaybe == IntPtr.Zero)
+ {
+ // E_NOINTERFACE
+ throw new InvalidCastException();
+ }
+
+ return interfaceMaybe;
#else
throw new PlatformNotSupportedException();
#endif
@@ -544,18 +548,18 @@ public static object CreateAggregatedObject(object pUnkOuter, object comObject)
public void CreateInstance(
[MarshalAs(UnmanagedType.Interface)] object? pUnkOuter,
ref Guid riid,
- [MarshalAs(UnmanagedType.Interface)] out object? ppvObject)
+ out IntPtr ppvObject)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
Type interfaceType = BasicClassFactory.GetValidatedInterfaceType(_classType, ref riid, pUnkOuter);
- ppvObject = Activator.CreateInstance(_classType)!;
+ object obj = Activator.CreateInstance(_classType)!;
if (pUnkOuter != null)
{
- ppvObject = BasicClassFactory.CreateAggregatedObject(pUnkOuter, ppvObject);
+ obj = BasicClassFactory.CreateAggregatedObject(pUnkOuter, obj);
}
- BasicClassFactory.ValidateObjectIsMarshallableAsInterface(ppvObject, interfaceType);
+ ppvObject = BasicClassFactory.GetObjectAsInterface(obj, interfaceType);
#else
throw new PlatformNotSupportedException();
#endif
@@ -593,7 +597,7 @@ public LicenseClassFactory(Guid clsid, Type classType)
public void CreateInstance(
[MarshalAs(UnmanagedType.Interface)] object? pUnkOuter,
ref Guid riid,
- [MarshalAs(UnmanagedType.Interface)] out object? ppvObject)
+ out IntPtr ppvObject)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
CreateInstanceInner(pUnkOuter, ref riid, key: null, isDesignTime: true, out ppvObject);
@@ -640,7 +644,7 @@ public void CreateInstanceLic(
[MarshalAs(UnmanagedType.Interface)] object? pUnkReserved,
ref Guid riid,
[MarshalAs(UnmanagedType.BStr)] string bstrKey,
- [MarshalAs(UnmanagedType.Interface)] out object ppvObject)
+ out IntPtr ppvObject)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
Debug.Assert(pUnkReserved == null);
@@ -655,18 +659,18 @@ private void CreateInstanceInner(
ref Guid riid,
string? key,
bool isDesignTime,
- out object ppvObject)
+ out IntPtr ppvObject)
{
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
Type interfaceType = BasicClassFactory.GetValidatedInterfaceType(_classType, ref riid, pUnkOuter);
- ppvObject = _licenseProxy.AllocateAndValidateLicense(_classType, key, isDesignTime);
+ object obj = _licenseProxy.AllocateAndValidateLicense(_classType, key, isDesignTime);
if (pUnkOuter != null)
{
- ppvObject = BasicClassFactory.CreateAggregatedObject(pUnkOuter, ppvObject);
+ obj = BasicClassFactory.CreateAggregatedObject(pUnkOuter, obj);
}
- BasicClassFactory.ValidateObjectIsMarshallableAsInterface(ppvObject, interfaceType);
+ ppvObject = BasicClassFactory.GetObjectAsInterface(obj, interfaceType);
#else
throw new PlatformNotSupportedException();
#endif
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Environment.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Environment.CoreCLR.cs
index d2ea1e3fbdd0a0..82d9af92c643ff 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Environment.CoreCLR.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Environment.CoreCLR.cs
@@ -83,9 +83,7 @@ public static string[] GetCommandLineArgs()
[DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern int GetProcessorCount();
- // If you change this method's signature then you must change the code that calls it
- // in excep.cpp and probably you will have to visit mscorlib.h to add the new signature
- // as well as metasig.h to create the new signature type
+ // Used by VM
internal static string? GetResourceStringLocal(string key) => SR.GetResourceString(key);
public static string StackTrace
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs
index c3f1e5b4fd43fd..d6bb435387b07c 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs
@@ -266,8 +266,8 @@ private string? SerializationStackTraceString
}
// This piece of infrastructure exists to help avoid deadlocks
- // between parts of mscorlib that might throw an exception while
- // holding a lock that are also used by mscorlib's ResourceManager
+ // between parts of CoreLib that might throw an exception while
+ // holding a lock that are also used by CoreLib's ResourceManager
// instance. As a special case of code that may throw while holding
// a lock, we also need to fix our asynchronous exceptions to use
// Win32 resources as well (assuming we ever call a managed
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs
index 865600fe8d2db0..cb011de2ef2b19 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/GC.cs
@@ -294,7 +294,7 @@ public static int GetGeneration(WeakReference wo)
public static void WaitForPendingFinalizers()
{
- // QCalls can not be exposed from mscorlib directly, need to wrap it.
+ // QCalls can not be exposed directly, need to wrap it.
_WaitForPendingFinalizers();
}
@@ -659,7 +659,7 @@ internal static void UnregisterMemoryLoadChangeNotification(Action notification)
/// If pinned is set to true, must not be a reference type or a type that contains object references.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)] // forced to ensure no perf drop for small memory buffers (hot path)
- public static T[] AllocateUninitializedArray(int length, bool pinned = false)
+ public static T[] AllocateUninitializedArray(int length, bool pinned = false) // T[] rather than T?[] to match `new T[length]` behavior
{
if (!pinned)
{
@@ -705,7 +705,7 @@ static T[] AllocateNewUninitializedArray(int length, bool pinned)
///
/// If pinned is set to true, must not be a reference type or a type that contains object references.
///
- public static T[] AllocateArray(int length, bool pinned = false)
+ public static T[] AllocateArray(int length, bool pinned = false) // T[] rather than T?[] to match `new T[length]` behavior
{
GC_ALLOC_FLAGS flags = GC_ALLOC_FLAGS.GC_ALLOC_NO_FLAGS;
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs
index 74aca4342ee39f..beeb322b52c0cd 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Math.CoreCLR.cs
@@ -56,6 +56,7 @@ public static partial class Math
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern double Cbrt(double d);
+ [Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern double Ceiling(double a);
@@ -71,6 +72,7 @@ public static partial class Math
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern double Exp(double d);
+ [Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern double Floor(double d);
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs
index 371780f6abe02e..f3dd3289c1c26d 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/MathF.CoreCLR.cs
@@ -45,6 +45,7 @@ public static partial class MathF
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern float Cbrt(float x);
+ [Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern float Ceiling(float x);
@@ -60,6 +61,7 @@ public static partial class MathF
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern float Exp(float x);
+ [Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern float Floor(float x);
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
index e1ce8a9f61f926..7313b405bf0ef7 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
@@ -105,6 +105,7 @@ public override FileStream[] GetFiles(bool getResourceModules)
public override string? CodeBase => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type[] GetExportedTypes()
{
throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
@@ -477,12 +478,14 @@ public override FileStream[] GetFiles(bool getResourceModules)
///
/// Get an array of all the public types defined in this assembly.
///
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type[] GetExportedTypes() => InternalAssembly.GetExportedTypes();
public override AssemblyName GetName(bool copiedName) => InternalAssembly.GetName(copiedName);
public override string? FullName => InternalAssembly.FullName;
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type? GetType(string name, bool throwOnError, bool ignoreCase)
{
return InternalAssembly.GetType(name, throwOnError, ignoreCase);
@@ -494,6 +497,7 @@ public override FileStream[] GetFiles(bool getResourceModules)
public override Module? GetModule(string name) => InternalAssembly.GetModule(name);
+ [RequiresUnreferencedCode("Assembly references might be removed")]
public override AssemblyName[] GetReferencedAssemblies()
{
return InternalAssembly.GetReferencedAssemblies();
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs
index 788969f7209774..4d52ddcb876f81 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs
@@ -63,6 +63,7 @@ public FieldBuilder DefineLiteral(string literalName, object? literalValue)
///
public override Guid GUID => m_typeBuilder.GUID;
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override object? InvokeMember(
string name,
BindingFlags invokeAttr,
@@ -92,6 +93,7 @@ public FieldBuilder DefineLiteral(string literalName, object? literalValue)
public override bool IsByRefLike => false;
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
protected override ConstructorInfo? GetConstructorImpl(BindingFlags bindingAttr, Binder? binder,
CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers)
{
@@ -99,11 +101,13 @@ public FieldBuilder DefineLiteral(string literalName, object? literalValue)
types, modifiers);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
{
return m_typeBuilder.GetConstructors(bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder,
CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers)
{
@@ -113,16 +117,19 @@ public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
return m_typeBuilder.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
{
return m_typeBuilder.GetMethods(bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo? GetField(string name, BindingFlags bindingAttr)
{
return m_typeBuilder.GetField(name, bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
{
return m_typeBuilder.GetFields(bindingAttr);
@@ -138,42 +145,50 @@ public override Type[] GetInterfaces()
return m_typeBuilder.GetInterfaces();
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo? GetEvent(string name, BindingFlags bindingAttr)
{
return m_typeBuilder.GetEvent(name, bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)]
public override EventInfo[] GetEvents()
{
return m_typeBuilder.GetEvents();
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder,
Type? returnType, Type[]? types, ParameterModifier[]? modifiers)
{
throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
return m_typeBuilder.GetProperties(bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type[] GetNestedTypes(BindingFlags bindingAttr)
{
return m_typeBuilder.GetNestedTypes(bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type? GetNestedType(string name, BindingFlags bindingAttr)
{
return m_typeBuilder.GetNestedType(name, bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
{
return m_typeBuilder.GetMember(name, type, bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
{
return m_typeBuilder.GetMembers(bindingAttr);
@@ -184,6 +199,7 @@ public override InterfaceMapping GetInterfaceMap(Type interfaceType)
return m_typeBuilder.GetInterfaceMap(interfaceType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo[] GetEvents(BindingFlags bindingAttr)
{
return m_typeBuilder.GetEvents(bindingAttr);
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs
index ffa61eaa0a706f..e21b2c1a6a84bd 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs
@@ -82,6 +82,7 @@ public override Type MakeArrayType(int rank)
public override Guid GUID => throw new NotSupportedException();
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { throw new NotSupportedException(); }
public override Assembly Assembly => m_type.Assembly;
@@ -96,40 +97,55 @@ public override Type MakeArrayType(int rank)
public override Type? BaseType => m_type.BaseType;
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); }
public override Type GetInterface(string name, bool ignoreCase) { throw new NotSupportedException(); }
public override Type[] GetInterfaces() { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo GetEvent(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)]
public override EventInfo[] GetEvents() { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type[] GetNestedTypes(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type GetNestedType(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(); }
public override InterfaceMapping GetInterfaceMap(Type interfaceType) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo[] GetEvents(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw new NotSupportedException(); }
protected override TypeAttributes GetAttributeFlagsImpl() { return TypeAttributes.Public; }
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs
index 4a719065ba42c5..aec1ca393d4cd8 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs
@@ -524,6 +524,7 @@ public override IList GetCustomAttributesData()
#region Module Overrides
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type[] GetTypes()
{
lock (SyncRoot)
@@ -558,16 +559,19 @@ internal Type[] GetTypesNoLock()
return typeList;
}
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type? GetType(string className)
{
return GetType(className, false, false);
}
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type? GetType(string className, bool ignoreCase)
{
return GetType(className, false, ignoreCase);
}
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type? GetType(string className, bool throwOnError, bool ignoreCase)
{
lock (SyncRoot)
@@ -677,31 +681,37 @@ internal Type[] GetTypesNoLock()
public override string FullyQualifiedName => _moduleData._moduleName;
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override byte[] ResolveSignature(int metadataToken)
{
return InternalModule.ResolveSignature(metadataToken);
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override MethodBase? ResolveMethod(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments)
{
return InternalModule.ResolveMethod(metadataToken, genericTypeArguments, genericMethodArguments);
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override FieldInfo? ResolveField(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments)
{
return InternalModule.ResolveField(metadataToken, genericTypeArguments, genericMethodArguments);
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override Type ResolveType(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments)
{
return InternalModule.ResolveType(metadataToken, genericTypeArguments, genericMethodArguments);
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override MemberInfo? ResolveMember(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments)
{
return InternalModule.ResolveMember(metadataToken, genericTypeArguments, genericMethodArguments);
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override string ResolveString(int metadataToken)
{
return InternalModule.ResolveString(metadataToken);
@@ -720,21 +730,25 @@ public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFile
public override bool IsResource() => InternalModule.IsResource();
+ [RequiresUnreferencedCode("Fields might be removed")]
public override FieldInfo[] GetFields(BindingFlags bindingFlags)
{
return InternalModule.GetFields(bindingFlags);
}
+ [RequiresUnreferencedCode("Fields might be removed")]
public override FieldInfo? GetField(string name, BindingFlags bindingAttr)
{
return InternalModule.GetField(name, bindingAttr);
}
+ [RequiresUnreferencedCode("Methods might be removed")]
public override MethodInfo[] GetMethods(BindingFlags bindingFlags)
{
return InternalModule.GetMethods(bindingFlags);
}
+ [RequiresUnreferencedCode("Methods might be removed")]
protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder,
CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers)
{
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SymbolType.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SymbolType.cs
index fa49a2256681e7..fbd9102b894beb 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SymbolType.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SymbolType.cs
@@ -300,6 +300,7 @@ public override int GetArrayRank()
public override Guid GUID => throw new NotSupportedException(SR.NotSupported_NonReflectedType);
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target,
object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters)
{
@@ -358,33 +359,39 @@ public override string ToString()
public override Type BaseType => typeof(System.Array);
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder,
CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder,
CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo GetField(string name, BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
@@ -400,42 +407,50 @@ public override Type[] GetInterfaces()
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo GetEvent(string name, BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)]
public override EventInfo[] GetEvents()
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder,
Type? returnType, Type[]? types, ParameterModifier[]? modifiers)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type[] GetNestedTypes(BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type GetNestedType(string name, BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
@@ -446,6 +461,7 @@ public override InterfaceMapping GetInterfaceMap(Type interfaceType)
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo[] GetEvents(BindingFlags bindingAttr)
{
throw new NotSupportedException(SR.NotSupported_NonReflectedType);
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs
index 47c3dea104ee3c..5b2acd1605bb24 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs
@@ -744,6 +744,7 @@ public override Guid GUID
}
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target,
object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters)
{
@@ -765,6 +766,7 @@ public override Guid GUID
public override Type? BaseType => m_typeParent;
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
protected override ConstructorInfo? GetConstructorImpl(BindingFlags bindingAttr, Binder? binder,
CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers)
{
@@ -774,6 +776,7 @@ public override Guid GUID
return m_bakedRuntimeType.GetConstructor(bindingAttr, binder, callConvention, types, modifiers);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
{
if (!IsCreated())
@@ -782,6 +785,7 @@ public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetConstructors(bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder,
CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers)
{
@@ -798,6 +802,7 @@ public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
}
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
{
if (!IsCreated())
@@ -806,6 +811,7 @@ public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetMethods(bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo? GetField(string name, BindingFlags bindingAttr)
{
if (!IsCreated())
@@ -814,6 +820,7 @@ public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetField(name, bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
{
if (!IsCreated())
@@ -845,6 +852,7 @@ public override Type[] GetInterfaces()
return m_typeInterfaces.ToArray();
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo? GetEvent(string name, BindingFlags bindingAttr)
{
if (!IsCreated())
@@ -853,6 +861,7 @@ public override Type[] GetInterfaces()
return m_bakedRuntimeType.GetEvent(name, bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)]
public override EventInfo[] GetEvents()
{
if (!IsCreated())
@@ -861,12 +870,14 @@ public override EventInfo[] GetEvents()
return m_bakedRuntimeType.GetEvents();
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder,
Type? returnType, Type[]? types, ParameterModifier[]? modifiers)
{
throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
if (!IsCreated())
@@ -875,6 +886,7 @@ public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetProperties(bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type[] GetNestedTypes(BindingFlags bindingAttr)
{
if (!IsCreated())
@@ -883,6 +895,7 @@ public override Type[] GetNestedTypes(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetNestedTypes(bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type? GetNestedType(string name, BindingFlags bindingAttr)
{
if (!IsCreated())
@@ -891,6 +904,7 @@ public override Type[] GetNestedTypes(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetNestedType(name, bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
{
if (!IsCreated())
@@ -907,6 +921,7 @@ public override InterfaceMapping GetInterfaceMap(Type interfaceType)
return m_bakedRuntimeType.GetInterfaceMap(interfaceType);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo[] GetEvents(BindingFlags bindingAttr)
{
if (!IsCreated())
@@ -915,6 +930,7 @@ public override EventInfo[] GetEvents(BindingFlags bindingAttr)
return m_bakedRuntimeType.GetEvents(bindingAttr);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
{
if (!IsCreated())
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs
index 1a6e10196af898..4e3844dac940cd 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs
@@ -97,7 +97,10 @@ public override Type MakeArrayType(int rank)
return SymbolType.FormCompoundType(s, this, 0)!;
}
public override Guid GUID => throw new NotSupportedException();
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { throw new NotSupportedException(); }
+
public override Assembly Assembly => m_type.Assembly;
public override RuntimeTypeHandle TypeHandle => throw new NotSupportedException();
public override string? FullName => m_strFullQualName ??= TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName);
@@ -152,26 +155,56 @@ public override Type? BaseType
return typeBldrBaseAs.Substitute(GetGenericArguments());
}
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); }
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+
public override Type GetInterface(string name, bool ignoreCase) { throw new NotSupportedException(); }
public override Type[] GetInterfaces() { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo GetEvent(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)]
public override EventInfo[] GetEvents() { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type[] GetNestedTypes(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type GetNestedType(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(); }
public override InterfaceMapping GetInterfaceMap(Type interfaceType) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo[] GetEvents(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw new NotSupportedException(); }
+
protected override TypeAttributes GetAttributeFlagsImpl() { return m_type.Attributes; }
public override bool IsTypeDefinition => false;
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/INVOCATION_FLAGS.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/INVOCATION_FLAGS.cs
index e7d9b97ac5c6c5..b6a55518914a22 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/INVOCATION_FLAGS.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/INVOCATION_FLAGS.cs
@@ -14,7 +14,8 @@ internal enum INVOCATION_FLAGS : uint
INVOCATION_FLAGS_INITIALIZED = 0x00000001,
// it's used for both method and field to signify that no access is allowed
INVOCATION_FLAGS_NO_INVOKE = 0x00000002,
- /* unused 0x00000004 */
+ // Set for static ctors, to ensure that the static ctor is run as a static ctor before it is explicitly executed via reflection
+ INVOCATION_FLAGS_RUN_CLASS_CONSTRUCTOR = 0x00000004,
// Set for static ctors and ctors on abstract types, which
// can be invoked only if the "this" object is provided (even if it's null).
INVOCATION_FLAGS_NO_CTOR_INVOKE = 0x00000008,
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
index 4aa7b486c723fa..d2476660973fd3 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using CultureInfo = System.Globalization.CultureInfo;
using System.IO;
using System.Configuration.Assemblies;
@@ -158,6 +159,7 @@ private static extern void GetType(QCallAssembly assembly,
ObjectHandleOnStack keepAlive,
ObjectHandleOnStack assemblyLoadContext);
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type? GetType(string name, bool throwOnError, bool ignoreCase)
{
// throw on null strings regardless of the value of "throwOnError"
@@ -184,6 +186,7 @@ private static extern void GetType(QCallAssembly assembly,
[DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern void GetExportedTypes(QCallAssembly assembly, ObjectHandleOnStack retTypes);
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type[] GetExportedTypes()
{
Type[]? types = null;
@@ -194,6 +197,7 @@ public override Type[] GetExportedTypes()
public override IEnumerable DefinedTypes
{
+ [RequiresUnreferencedCode("Types might be removed")]
get
{
RuntimeModule[] modules = GetModulesInternal(true, false);
@@ -394,6 +398,7 @@ public override string[] GetManifestResourceNames()
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern AssemblyName[] GetReferencedAssemblies(RuntimeAssembly assembly);
+ [RequiresUnreferencedCode("Assembly references might be removed")]
public override AssemblyName[] GetReferencedAssemblies()
{
return GetReferencedAssemblies(GetNativeHandle());
@@ -607,6 +612,7 @@ public override Module[] GetLoadedModules(bool getResourceModules)
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern int GetToken(RuntimeAssembly assembly);
+ [RequiresUnreferencedCode("Types might be removed")]
public sealed override Type[] GetForwardedTypes()
{
List types = new List();
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs
index 9d0086ca442536..e06251e6ad851b 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs
@@ -5,6 +5,7 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
+using System.Runtime.CompilerServices;
using System.Text;
using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
@@ -47,7 +48,12 @@ internal INVOCATION_FLAGS InvocationFlags
// We don't need other flags if this method cannot be invoked
invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE;
}
- else if (IsStatic || declaringType != null && declaringType.IsAbstract)
+ else if (IsStatic)
+ {
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_RUN_CLASS_CONSTRUCTOR |
+ INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE;
+ }
+ else if (declaringType != null && declaringType.IsAbstract)
{
invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE;
}
@@ -280,6 +286,21 @@ internal void ThrowNoInvokeException()
// check basic method consistency. This call will throw if there are problems in the target/method relationship
CheckConsistency(obj);
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_RUN_CLASS_CONSTRUCTOR) != 0)
+ {
+ // Run the class constructor through the class constructor mechanism instead of the Invoke path.
+ // This avoids allowing mutation of readonly static fields, and initializes the type correctly.
+
+ var declaringType = DeclaringType;
+
+ if (declaringType != null)
+ RuntimeHelpers.RunClassConstructor(declaringType.TypeHandle);
+ else
+ RuntimeHelpers.RunModuleConstructor(Module.ModuleHandle);
+
+ return null;
+ }
+
Signature sig = Signature;
// get the signature
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs
index 3835866b99bfd5..990b52854a05fb 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Collections.Generic;
@@ -60,6 +61,7 @@ internal RuntimeType[] GetDefinedTypes()
return typeHandleArgs;
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override byte[] ResolveSignature(int metadataToken)
{
MetadataToken tk = new MetadataToken(metadataToken);
@@ -86,6 +88,7 @@ public override byte[] ResolveSignature(int metadataToken)
return sig;
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override MethodBase? ResolveMethod(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments)
{
MetadataToken tk = new MetadataToken(metadataToken);
@@ -165,6 +168,7 @@ public override byte[] ResolveSignature(int metadataToken)
}
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override FieldInfo? ResolveField(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments)
{
MetadataToken tk = new MetadataToken(metadataToken);
@@ -219,6 +223,7 @@ public override byte[] ResolveSignature(int metadataToken)
}
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override Type ResolveType(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments)
{
MetadataToken tk = new MetadataToken(metadataToken);
@@ -251,6 +256,7 @@ public override Type ResolveType(int metadataToken, Type[]? genericTypeArguments
}
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override MemberInfo? ResolveMember(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments)
{
MetadataToken tk = new MetadataToken(metadataToken);
@@ -295,6 +301,7 @@ public override Type ResolveType(int metadataToken, Type[]? genericTypeArguments
nameof(metadataToken));
}
+ [RequiresUnreferencedCode("Trimming changes metadata tokens")]
public override string ResolveString(int metadataToken)
{
MetadataToken tk = new MetadataToken(metadataToken);
@@ -336,6 +343,7 @@ public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFile
#endregion
#region Protected Virtuals
+ [RequiresUnreferencedCode("Methods might be removed")]
protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder,
CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers)
{
@@ -415,6 +423,7 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
throw new PlatformNotSupportedException();
}
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type? GetType(string className, bool throwOnError, bool ignoreCase)
{
// throw on null strings regardless of the value of "throwOnError"
@@ -439,6 +448,7 @@ internal string GetFullyQualifiedName()
public override string FullyQualifiedName => GetFullyQualifiedName();
+ [RequiresUnreferencedCode("Types might be removed")]
public override Type[] GetTypes()
{
return GetTypes(GetNativeHandle());
@@ -464,6 +474,7 @@ public override bool IsResource()
return IsResource(GetNativeHandle());
}
+ [RequiresUnreferencedCode("Fields might be removed")]
public override FieldInfo[] GetFields(BindingFlags bindingFlags)
{
if (RuntimeType == null)
@@ -472,6 +483,7 @@ public override FieldInfo[] GetFields(BindingFlags bindingFlags)
return RuntimeType.GetFields(bindingFlags);
}
+ [RequiresUnreferencedCode("Fields might be removed")]
public override FieldInfo? GetField(string name, BindingFlags bindingAttr)
{
if (name == null)
@@ -483,6 +495,7 @@ public override FieldInfo[] GetFields(BindingFlags bindingFlags)
return RuntimeType.GetField(name, bindingAttr);
}
+ [RequiresUnreferencedCode("Methods might be removed")]
public override MethodInfo[] GetMethods(BindingFlags bindingFlags)
{
if (RuntimeType == null)
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs
index 513a96b668cfbf..016d9502d694ec 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs
@@ -5,6 +5,7 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.ComTypes;
+using System.Runtime.Versioning;
using System.StubHelpers;
namespace System.Runtime.InteropServices
@@ -306,6 +307,7 @@ public static IntPtr ReAllocHGlobal(IntPtr pv, IntPtr cb)
///
/// Given a managed object that wraps an ITypeInfo, return its name.
///
+ [SupportedOSPlatform("windows")]
public static string GetTypeInfoName(ITypeInfo typeInfo)
{
if (typeInfo is null)
@@ -319,12 +321,14 @@ public static string GetTypeInfoName(ITypeInfo typeInfo)
// This method is identical to Type.GetTypeFromCLSID. Since it's interop specific, we expose it
// on Marshal for more consistent API surface.
+ [SupportedOSPlatform("windows")]
public static Type? GetTypeFromCLSID(Guid clsid) => RuntimeType.GetTypeFromCLSIDImpl(clsid, null, throwOnError: false);
///
/// Return the IUnknown* for an Object if the current context is the one
/// where the RCW was first seen. Will return null otherwise.
///
+ [SupportedOSPlatform("windows")]
public static IntPtr /* IUnknown* */ GetIUnknownForObject(object o)
{
if (o is null)
@@ -348,6 +352,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo)
///
/// Return the IDispatch* for an Object.
///
+ [SupportedOSPlatform("windows")]
public static IntPtr /* IDispatch */ GetIDispatchForObject(object o)
{
if (o is null)
@@ -365,6 +370,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo)
/// Return the IUnknown* representing the interface for the Object.
/// Object o should support Type T
///
+ [SupportedOSPlatform("windows")]
public static IntPtr /* IUnknown* */ GetComInterfaceForObject(object o, Type T)
{
if (o is null)
@@ -380,6 +386,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo)
return GetComInterfaceForObjectNative(o, T, false, true);
}
+ [SupportedOSPlatform("windows")]
public static IntPtr GetComInterfaceForObject([DisallowNull] T o) => GetComInterfaceForObject(o!, typeof(TInterface));
///
@@ -387,6 +394,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo)
/// Object o should support Type T, it refer the value of mode to
/// invoke customized QueryInterface or not.
///
+ [SupportedOSPlatform("windows")]
public static IntPtr /* IUnknown* */ GetComInterfaceForObject(object o, Type T, CustomQueryInterfaceMode mode)
{
if (o is null)
@@ -409,6 +417,7 @@ public static string GetTypeInfoName(ITypeInfo typeInfo)
///
/// Return the managed object representing the IUnknown*
///
+ [SupportedOSPlatform("windows")]
public static object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk)
{
if (pUnk == IntPtr.Zero)
@@ -422,6 +431,7 @@ public static object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk)
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object GetObjectForIUnknownNative(IntPtr /* IUnknown* */ pUnk);
+ [SupportedOSPlatform("windows")]
public static object GetUniqueObjectForIUnknown(IntPtr unknown)
{
if (unknown == IntPtr.Zero)
@@ -445,12 +455,15 @@ public static object GetUniqueObjectForIUnknown(IntPtr unknown)
/// Return an Object for IUnknown, using the Type T.
/// Type T should be either a COM imported Type or a sub-type of COM imported Type
///
+ [SupportedOSPlatform("windows")]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern object GetTypedObjectForIUnknown(IntPtr /* IUnknown* */ pUnk, Type t);
+ [SupportedOSPlatform("windows")]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern IntPtr CreateAggregatedObject(IntPtr pOuter, object o);
+ [SupportedOSPlatform("windows")]
public static IntPtr CreateAggregatedObject(IntPtr pOuter, T o) where T : notnull
{
return CreateAggregatedObject(pOuter, (object)o);
@@ -549,6 +562,7 @@ public static string PtrToStringBSTR(IntPtr ptr)
/// Release the COM component and if the reference hits 0 zombie this object.
/// Further usage of this Object might throw an exception
///
+ [SupportedOSPlatform("windows")]
public static int ReleaseComObject(object o)
{
if (o is null)
@@ -571,6 +585,7 @@ public static int ReleaseComObject(object o)
/// Release the COM component and zombie this object.
/// Further usage of this Object might throw an exception
///
+ [SupportedOSPlatform("windows")]
public static int FinalReleaseComObject(object o)
{
if (o is null)
@@ -589,6 +604,7 @@ public static int FinalReleaseComObject(object o)
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern void InternalFinalReleaseComObject(object o);
+ [SupportedOSPlatform("windows")]
public static object? GetComObjectData(object obj, object key)
{
if (obj is null)
@@ -614,6 +630,7 @@ public static int FinalReleaseComObject(object o)
/// false if the data could not be added because there already was data for the
/// specified key.
///
+ [SupportedOSPlatform("windows")]
public static bool SetComObjectData(object obj, object key, object? data)
{
if (obj is null)
@@ -637,6 +654,7 @@ public static bool SetComObjectData(object obj, object key, object? data)
/// This method takes the given COM object and wraps it in an object
/// of the specified type. The type must be derived from __ComObject.
///
+ [SupportedOSPlatform("windows")]
[return: NotNullIfNotNull("o")]
public static object? CreateWrapperOfType(object? o, Type t)
{
@@ -687,7 +705,8 @@ public static bool SetComObjectData(object obj, object key, object? data)
return Wrapper;
}
- public static TWrapper CreateWrapperOfType([AllowNull] T o)
+ [SupportedOSPlatform("windows")]
+ public static TWrapper CreateWrapperOfType(T? o)
{
return (TWrapper)CreateWrapperOfType(o, typeof(TWrapper))!;
}
@@ -701,35 +720,62 @@ public static TWrapper CreateWrapperOfType([AllowNull] T o)
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern bool IsTypeVisibleFromCom(Type t);
- [MethodImpl(MethodImplOptions.InternalCall)]
- public static extern int /* HRESULT */ QueryInterface(IntPtr /* IUnknown */ pUnk, ref Guid iid, out IntPtr ppv);
+ [SupportedOSPlatform("windows")]
+ public static unsafe int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr ppv)
+ {
+ if (pUnk == IntPtr.Zero)
+ throw new ArgumentNullException(nameof(pUnk));
- [MethodImpl(MethodImplOptions.InternalCall)]
- public static extern int /* ULONG */ AddRef(IntPtr /* IUnknown */ pUnk);
+ fixed (Guid* pIID = &iid)
+ fixed (IntPtr* p = &ppv)
+ {
+ return ((delegate * stdcall )(*(*(void***)pUnk + 0 /* IUnknown.QueryInterface slot */)))(pUnk, pIID, p);
+ }
+ }
- [MethodImpl(MethodImplOptions.InternalCall)]
- public static extern int /* ULONG */ Release(IntPtr /* IUnknown */ pUnk);
+ [SupportedOSPlatform("windows")]
+ public static unsafe int AddRef(IntPtr pUnk)
+ {
+ if (pUnk == IntPtr.Zero)
+ throw new ArgumentNullException(nameof(pUnk));
+
+ return ((delegate * stdcall )(*(*(void***)pUnk + 1 /* IUnknown.AddRef slot */)))(pUnk);
+ }
+
+ [SupportedOSPlatform("windows")]
+ public static unsafe int Release(IntPtr pUnk)
+ {
+ if (pUnk == IntPtr.Zero)
+ throw new ArgumentNullException(nameof(pUnk));
+
+ return ((delegate * stdcall )(*(*(void***)pUnk + 2 /* IUnknown.Release slot */)))(pUnk);
+ }
+ [SupportedOSPlatform("windows")]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void GetNativeVariantForObject(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant);
- public static void GetNativeVariantForObject([AllowNull] T obj, IntPtr pDstNativeVariant)
+ [SupportedOSPlatform("windows")]
+ public static void GetNativeVariantForObject(T? obj, IntPtr pDstNativeVariant)
{
GetNativeVariantForObject((object?)obj, pDstNativeVariant);
}
+ [SupportedOSPlatform("windows")]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern object? GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant);
- [return: MaybeNull]
- public static T GetObjectForNativeVariant(IntPtr pSrcNativeVariant)
+ [SupportedOSPlatform("windows")]
+ public static T? GetObjectForNativeVariant(IntPtr pSrcNativeVariant)
{
- return (T)GetObjectForNativeVariant(pSrcNativeVariant)!;
+ return (T?)GetObjectForNativeVariant(pSrcNativeVariant);
}
+ [SupportedOSPlatform("windows")]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern object?[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars);
+ [SupportedOSPlatform("windows")]
public static T[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int cVars)
{
object?[] objects = GetObjectsForNativeVariants(aSrcNativeVariant, cVars);
@@ -744,15 +790,18 @@ public static T[] GetObjectsForNativeVariants(IntPtr aSrcNativeVariant, int c
/// Returns the first valid COM slot that GetMethodInfoForSlot will work on
/// This will be 3 for IUnknown based interfaces and 7 for IDispatch based interfaces.
///
+ [SupportedOSPlatform("windows")]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern int GetStartComSlot(Type t);
///
/// Returns the last valid COM slot that GetMethodInfoForSlot will work on.
///
+ [SupportedOSPlatform("windows")]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern int GetEndComSlot(Type t);
+ [SupportedOSPlatform("windows")]
public static object BindToMoniker(string monikerName)
{
CreateBindCtx(0, out IBindCtx bindctx);
@@ -772,6 +821,7 @@ public static object BindToMoniker(string monikerName)
[DllImport(Interop.Libraries.Ole32, PreserveSig = false)]
private static extern void BindMoniker(IMoniker pmk, uint grfOpt, ref Guid iidResult, [MarshalAs(UnmanagedType.Interface)] out object ppvResult);
+ [SupportedOSPlatform("windows")]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void ChangeWrapperHandleStrength(object otp, bool fIsWeak);
#endif // FEATURE_COMINTEROP
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.CoreCLR.cs
new file mode 100644
index 00000000000000..e523487f0d6b65
--- /dev/null
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.CoreCLR.cs
@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace System.Runtime.Intrinsics.X86
+{
+ public abstract partial class X86Base
+ {
+ [DllImport(RuntimeHelpers.QCall)]
+ private static extern unsafe void __cpuidex(int* cpuInfo, int functionId, int subFunctionId);
+ }
+}
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Versioning/CompatibilitySwitch.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Versioning/CompatibilitySwitch.cs
index 3b69f789e61c68..d90f81d48e986d 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Versioning/CompatibilitySwitch.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/Versioning/CompatibilitySwitch.cs
@@ -7,24 +7,7 @@ namespace System.Runtime.Versioning
{
internal static class CompatibilitySwitch
{
- /* This class contains 3 sets of api:
- * 1. internal apis : These apis are supposed to be used by mscorlib.dll and other assemblies which use the section in config
- * These apis query for the value of quirk not only in windows quirk DB but also in runtime section of config files,
- * registry and environment vars.
- * 2. public apis : These apis are supposed to be used by FX assemblies which do not read the runtime section of config files and have
- * have their own section in config files or do not use configs at all.
- *
- * 3. specialized apis: These apis are defined in order to retrieve a specific value defined in CLR Config. That value can have specific look-up rules
- * for the order and location of the config sources used.
- *
- * These apis are for internal use only for FX assemblies. It has not been decided if they can be used by OOB components due to EULA restrictions
- */
- internal static string? GetValueInternal(string compatibilitySwitchName)
- {
- return GetValueInternalCall(compatibilitySwitchName, false);
- }
-
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern string? GetValueInternalCall(string compatibilitySwitchName, bool onlyDB);
+ internal static extern string? GetValueInternal(string compatibilitySwitchName);
}
}
diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
index f4e9ac9829664a..0dbfbf7f0c6193 100644
--- a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
+++ b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
@@ -234,6 +234,48 @@ internal MemberInfoCache(RuntimeTypeCache runtimeTypeCache)
internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method, CacheType cacheType)
{
+ // First, see if we've already cached an RuntimeMethodInfo or
+ // RuntimeConstructorInfo that corresponds to this member. Since another
+ // thread could be updating the backing store at the same time it's
+ // possible that the check below will result in a false negative. That's
+ // ok; we'll handle any concurrency issues in the later call to Insert.
+
+ T?[]? allMembersLocal = m_allMembers;
+ if (allMembersLocal != null)
+ {
+ // if not a Method or a Constructor, fall through
+ if (cacheType == CacheType.Method)
+ {
+ foreach (T? candidate in allMembersLocal)
+ {
+ if (candidate is null)
+ {
+ break; // end of list; stop iteration and fall through to slower path
+ }
+
+ if (candidate is RuntimeMethodInfo candidateRMI && candidateRMI.MethodHandle.Value == method.Value)
+ {
+ return candidateRMI; // match!
+ }
+ }
+ }
+ else if (cacheType == CacheType.Constructor)
+ {
+ foreach (T? candidate in allMembersLocal)
+ {
+ if (candidate is null)
+ {
+ break; // end of list; stop iteration and fall through to slower path
+ }
+
+ if (candidate is RuntimeConstructorInfo candidateRCI && candidateRCI.MethodHandle.Value == method.Value)
+ {
+ return candidateRCI; // match!
+ }
+ }
+ }
+ }
+
T[] list = null!;
MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(method);
bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
@@ -264,6 +306,29 @@ internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInte
internal FieldInfo AddField(RuntimeFieldHandleInternal field)
{
+ // First, see if we've already cached an RtFieldInfo that corresponds
+ // to this field. Since another thread could be updating the backing
+ // store at the same time it's possible that the check below will
+ // result in a false negative. That's ok; we'll handle any concurrency
+ // issues in the later call to Insert.
+
+ T?[]? allMembersLocal = m_allMembers;
+ if (allMembersLocal != null)
+ {
+ foreach (T? candidate in allMembersLocal)
+ {
+ if (candidate is null)
+ {
+ break; // end of list; stop iteration and fall through to slower path
+ }
+
+ if (candidate is RtFieldInfo candidateRtFI && candidateRtFI.GetFieldHandle() == field.Value)
+ {
+ return candidateRtFI; // match!
+ }
+ }
+ }
+
// create the runtime field info
FieldAttributes fieldAttributes = RuntimeFieldHandle.GetAttributes(field);
bool isPublic = (fieldAttributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public;
@@ -507,7 +572,7 @@ private void MergeWithGlobalList(T[] list)
}
Debug.Assert(cachedMembers![freeSlotIndex] == null);
- cachedMembers[freeSlotIndex] = newMemberInfo;
+ Volatile.Write(ref cachedMembers[freeSlotIndex], newMemberInfo); // value may be read outside of lock
freeSlotIndex++;
}
}
@@ -2532,26 +2597,31 @@ private ListBuilder GetNestedTypeCandidates(string? fullname, BindingFlags
#endregion
#region Get All XXXInfos
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
{
return GetMethodCandidates(null, GenericParameterCountAny, bindingAttr, CallingConventions.Any, null, false).ToArray();
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
{
return GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false).ToArray();
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
return GetPropertyCandidates(null, bindingAttr, null, false).ToArray();
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo[] GetEvents(BindingFlags bindingAttr)
{
return GetEventCandidates(null, bindingAttr, false).ToArray();
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
{
return GetFieldCandidates(null, bindingAttr, false).ToArray();
@@ -2563,11 +2633,13 @@ public override Type[] GetInterfaces()
return new ReadOnlySpan(candidates).ToArray();
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type[] GetNestedTypes(BindingFlags bindingAttr)
{
return GetNestedTypeCandidates(null, bindingAttr, false).ToArray();
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
{
ListBuilder methods = GetMethodCandidates(null, GenericParameterCountAny, bindingAttr, CallingConventions.Any, null, false);
@@ -2663,6 +2735,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType)
#region Find XXXInfo
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
protected override MethodInfo? GetMethodImpl(
string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConv,
Type[]? types, ParameterModifier[]? modifiers)
@@ -2670,6 +2743,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType)
return GetMethodImplCommon(name, GenericParameterCountAny, bindingAttr, binder, callConv, types, modifiers);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
protected override MethodInfo? GetMethodImpl(
string name, int genericParameterCount, BindingFlags bindingAttr, Binder? binder, CallingConventions callConv,
Type[]? types, ParameterModifier[]? modifiers)
@@ -2714,6 +2788,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType)
return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as MethodInfo;
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
protected override ConstructorInfo? GetConstructorImpl(
BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention,
Type[] types, ParameterModifier[]? modifiers)
@@ -2741,6 +2816,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType)
return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as ConstructorInfo;
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
protected override PropertyInfo? GetPropertyImpl(
string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers)
{
@@ -2778,6 +2854,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType)
return binder.SelectProperty(bindingAttr, candidates.ToArray(), returnType, types, modifiers);
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)]
public override EventInfo? GetEvent(string name, BindingFlags bindingAttr)
{
if (name is null) throw new ArgumentNullException(nameof(name));
@@ -2804,6 +2881,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType)
return match;
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
public override FieldInfo? GetField(string name, BindingFlags bindingAttr)
{
if (name is null) throw new ArgumentNullException();
@@ -2875,6 +2953,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType)
return match;
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)]
public override Type? GetNestedType(string fullname, BindingFlags bindingAttr)
{
if (fullname is null) throw new ArgumentNullException(nameof(fullname));
@@ -2903,6 +2982,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType)
return match;
}
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
{
if (name is null) throw new ArgumentNullException(nameof(name));
diff --git a/src/coreclr/src/ToolBox/SOS/DacTableGen/CMakeLists.txt b/src/coreclr/src/ToolBox/SOS/DacTableGen/CMakeLists.txt
index e3fc3ed9e3a5e1..98cc178b8a3005 100644
--- a/src/coreclr/src/ToolBox/SOS/DacTableGen/CMakeLists.txt
+++ b/src/coreclr/src/ToolBox/SOS/DacTableGen/CMakeLists.txt
@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 3.8)
# Quick note: The CMake C# support is using the CSC bundled with the MSBuild that the native build runs on, not the one supplied by the local .NET SDK.
project(DacTableGen LANGUAGES CSharp)
diff --git a/src/coreclr/src/binder/CMakeLists.txt b/src/coreclr/src/binder/CMakeLists.txt
index 9c242ed1518df0..208f1214dd0da5 100644
--- a/src/coreclr/src/binder/CMakeLists.txt
+++ b/src/coreclr/src/binder/CMakeLists.txt
@@ -82,11 +82,13 @@ endif(CLR_CMAKE_TARGET_WIN32)
convert_to_absolute_path(BINDER_SOURCES ${BINDER_SOURCES})
convert_to_absolute_path(BINDER_CROSSGEN_SOURCES ${BINDER_CROSSGEN_SOURCES})
-add_library_clr(v3binder
+add_library_clr(v3binder_obj
OBJECT
${BINDER_SOURCES}
)
-add_dependencies(v3binder eventing_headers)
+add_dependencies(v3binder_obj eventing_headers)
+add_library(v3binder INTERFACE)
+target_sources(v3binder INTERFACE $)
add_library_clr(v3binder_crossgen
STATIC
diff --git a/src/coreclr/src/binder/assemblybinder.cpp b/src/coreclr/src/binder/assemblybinder.cpp
index 5f13adc7b2c826..02a3646dab4a16 100644
--- a/src/coreclr/src/binder/assemblybinder.cpp
+++ b/src/coreclr/src/binder/assemblybinder.cpp
@@ -447,25 +447,25 @@ namespace BINDER_SPACE
// Satellite assembly's path:
// * Absolute path when looking for a file on disk
// * Bundle-relative path when looking within the single-file bundle.
- StackSString sMscorlibSatellite;
+ StackSString sCoreLibSatellite;
BinderTracing::PathSource pathSource = BinderTracing::PathSource::Bundle;
BundleFileLocation bundleFileLocation = Bundle::ProbeAppBundle(relativePath, /*pathIsBundleRelative */ true);
if (!bundleFileLocation.IsValid())
{
- sMscorlibSatellite.Set(systemDirectory);
+ sCoreLibSatellite.Set(systemDirectory);
pathSource = BinderTracing::PathSource::ApplicationAssemblies;
}
- CombinePath(sMscorlibSatellite, relativePath, sMscorlibSatellite);
+ CombinePath(sCoreLibSatellite, relativePath, sCoreLibSatellite);
ReleaseHolder pSystemAssembly;
- IF_FAIL_GO(AssemblyBinder::GetAssembly(sMscorlibSatellite,
+ IF_FAIL_GO(AssemblyBinder::GetAssembly(sCoreLibSatellite,
TRUE /* fIsInGAC */,
FALSE /* fExplicitBindToNativeImage */,
&pSystemAssembly,
NULL /* szMDAssemblyPath */,
bundleFileLocation));
- BinderTracing::PathProbed(sMscorlibSatellite, pathSource, hr);
+ BinderTracing::PathProbed(sCoreLibSatellite, pathSource, hr);
*ppSystemAssembly = pSystemAssembly.Extract();
diff --git a/src/coreclr/src/binder/assemblyname.cpp b/src/coreclr/src/binder/assemblyname.cpp
index b073dc66f88b1d..71e70283c0b313 100644
--- a/src/coreclr/src/binder/assemblyname.cpp
+++ b/src/coreclr/src/binder/assemblyname.cpp
@@ -315,10 +315,10 @@ namespace BINDER_SPACE
return ulRef;
}
- BOOL AssemblyName::IsMscorlib()
+ BOOL AssemblyName::IsCoreLib()
{
// TODO: Is this simple comparison enough?
- return EqualsCaseInsensitive(GetSimpleName(), g_BinderVariables->mscorlib);
+ return EqualsCaseInsensitive(GetSimpleName(), g_BinderVariables->corelib);
}
ULONG AssemblyName::Hash(DWORD dwIncludeFlags)
diff --git a/src/coreclr/src/binder/bindertracing.cpp b/src/coreclr/src/binder/bindertracing.cpp
index 2e5c83d7b09bd2..29ba819ee6c9e7 100644
--- a/src/coreclr/src/binder/bindertracing.cpp
+++ b/src/coreclr/src/binder/bindertracing.cpp
@@ -216,14 +216,14 @@ namespace BinderTracing
AssemblyBindOperation::~AssemblyBindOperation()
{
- if (!BinderTracing::IsEnabled() || ShouldIgnoreBind())
- return;
-
- // Make sure the bind request is populated. Tracing may have been enabled mid-bind.
- if (!m_populatedBindRequest)
- PopulateBindRequest(m_bindRequest);
+ if (BinderTracing::IsEnabled() && !ShouldIgnoreBind())
+ {
+ // Make sure the bind request is populated. Tracing may have been enabled mid-bind.
+ if (!m_populatedBindRequest)
+ PopulateBindRequest(m_bindRequest);
- FireAssemblyLoadStop(m_bindRequest, m_resultAssembly, m_cached);
+ FireAssemblyLoadStop(m_bindRequest, m_resultAssembly, m_cached);
+ }
if (m_resultAssembly != nullptr)
m_resultAssembly->Release();
@@ -246,7 +246,7 @@ namespace BinderTracing
// ActivityTracker or EventSource may have triggered the system satellite load.
// Don't track system satellite binding to avoid potential infinite recursion.
- m_ignoreBind = m_bindRequest.AssemblySpec->IsMscorlibSatellite();
+ m_ignoreBind = m_bindRequest.AssemblySpec->IsCoreLibSatellite();
m_checkedIgnoreBind = true;
return m_ignoreBind;
}
diff --git a/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp b/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp
index f492adfab28b45..69d8d83372893e 100644
--- a/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp
+++ b/src/coreclr/src/binder/clrprivbinderassemblyloadcontext.cpp
@@ -20,8 +20,8 @@ HRESULT CLRPrivBinderAssemblyLoadContext::BindAssemblyByNameWorker(BINDER_SPACE:
HRESULT hr = S_OK;
#ifdef _DEBUG
- // MSCORLIB should be bound using BindToSystem
- _ASSERTE(!pAssemblyName->IsMscorlib());
+ // CoreLib should be bound using BindToSystem
+ _ASSERTE(!pAssemblyName->IsCoreLib());
#endif
// Do we have the assembly already loaded in the context of the current binder?
@@ -145,7 +145,7 @@ HRESULT CLRPrivBinderAssemblyLoadContext::BindUsingPEImage( /* in */ PEImage *pP
// Disallow attempt to bind to the core library. Aside from that,
// the LoadContext can load any assembly (even if it was in a different LoadContext like TPA).
- if (pAssemblyName->IsMscorlib())
+ if (pAssemblyName->IsCoreLib())
{
IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
}
diff --git a/src/coreclr/src/binder/clrprivbindercoreclr.cpp b/src/coreclr/src/binder/clrprivbindercoreclr.cpp
index 1045cb93e76da5..292ad99fd85543 100644
--- a/src/coreclr/src/binder/clrprivbindercoreclr.cpp
+++ b/src/coreclr/src/binder/clrprivbindercoreclr.cpp
@@ -20,8 +20,8 @@ HRESULT CLRPrivBinderCoreCLR::BindAssemblyByNameWorker(BINDER_SPACE::AssemblyNam
HRESULT hr = S_OK;
#ifdef _DEBUG
- // MSCORLIB should be bound using BindToSystem
- _ASSERTE(!pAssemblyName->IsMscorlib());
+ // CoreLib should be bound using BindToSystem
+ _ASSERTE(!pAssemblyName->IsCoreLib());
#endif
hr = AssemblyBinder::BindAssembly(&m_appContext,
@@ -155,8 +155,8 @@ HRESULT CLRPrivBinderCoreCLR::BindUsingPEImage( /* in */ PEImage *pPEImage,
IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_BAD_FORMAT));
}
- // Easy out for mscorlib
- if (pAssemblyName->IsMscorlib())
+ // Easy out for CoreLib
+ if (pAssemblyName->IsCoreLib())
{
IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
}
diff --git a/src/coreclr/src/binder/inc/assemblyname.hpp b/src/coreclr/src/binder/inc/assemblyname.hpp
index 38590e09f78a6b..fb66d9830e0a3a 100644
--- a/src/coreclr/src/binder/inc/assemblyname.hpp
+++ b/src/coreclr/src/binder/inc/assemblyname.hpp
@@ -65,7 +65,7 @@ namespace BINDER_SPACE
inline void SetHave(DWORD dwIdentityFlags);
- BOOL IsMscorlib();
+ BOOL IsCoreLib();
ULONG Hash(/* in */ DWORD dwIncludeFlags);
BOOL Equals(/* in */ AssemblyName *pAssemblyName,
diff --git a/src/coreclr/src/binder/inc/variables.hpp b/src/coreclr/src/binder/inc/variables.hpp
index 50f392d0366ed0..d060a691bbecca 100644
--- a/src/coreclr/src/binder/inc/variables.hpp
+++ b/src/coreclr/src/binder/inc/variables.hpp
@@ -31,7 +31,7 @@ namespace BINDER_SPACE
// AssemblyName string constants
SString cultureNeutral;
- SString mscorlib;
+ SString corelib;
};
extern Variables *g_BinderVariables;
diff --git a/src/coreclr/src/binder/variables.cpp b/src/coreclr/src/binder/variables.cpp
index d9c3f672657de0..fbdd106b4dd2fe 100644
--- a/src/coreclr/src/binder/variables.cpp
+++ b/src/coreclr/src/binder/variables.cpp
@@ -40,7 +40,7 @@ namespace BINDER_SPACE
// AssemblyName string constants
cultureNeutral.SetLiteral(W("neutral"));
- mscorlib.SetLiteral(CoreLibName_W);
+ corelib.SetLiteral(CoreLibName_W);
}
EX_CATCH_HRESULT(hr);
diff --git a/src/coreclr/src/classlibnative/bcltype/CMakeLists.txt b/src/coreclr/src/classlibnative/bcltype/CMakeLists.txt
index c3122ec12ec3d8..fdcf344c16ac56 100644
--- a/src/coreclr/src/classlibnative/bcltype/CMakeLists.txt
+++ b/src/coreclr/src/classlibnative/bcltype/CMakeLists.txt
@@ -10,9 +10,11 @@ set(BCLTYPE_SOURCES
variant.cpp
)
-add_library_clr(bcltype
+add_library_clr(bcltype_obj
OBJECT
${BCLTYPE_SOURCES}
)
-add_dependencies(bcltype eventing_headers)
+add_dependencies(bcltype_obj eventing_headers)
+add_library(bcltype INTERFACE)
+target_sources(bcltype INTERFACE $)
diff --git a/src/coreclr/src/classlibnative/bcltype/system.cpp b/src/coreclr/src/classlibnative/bcltype/system.cpp
index c037236f695960..6bd072f13ea847 100644
--- a/src/coreclr/src/classlibnative/bcltype/system.cpp
+++ b/src/coreclr/src/classlibnative/bcltype/system.cpp
@@ -607,9 +607,17 @@ BOOL QCALLTYPE SystemNative::WinRTSupported()
#endif // FEATURE_COMINTEROP
+#if defined(TARGET_X86) || defined(TARGET_AMD64)
+void QCALLTYPE SystemNative::X86BaseCpuId(int cpuInfo[4], int functionId, int subFunctionId)
+{
+ QCALL_CONTRACT;
+ BEGIN_QCALL;
+ __cpuidex(cpuInfo, functionId, subFunctionId);
+ END_QCALL;
+}
-
+#endif // defined(TARGET_X86) || defined(TARGET_AMD64)
diff --git a/src/coreclr/src/classlibnative/bcltype/system.h b/src/coreclr/src/classlibnative/bcltype/system.h
index 20d357c17302df..ff6720f0a8c09f 100644
--- a/src/coreclr/src/classlibnative/bcltype/system.h
+++ b/src/coreclr/src/classlibnative/bcltype/system.h
@@ -81,6 +81,10 @@ class SystemNative
// Return a method info for the method were the exception was thrown
static FCDECL1(ReflectMethodObject*, GetMethodFromStackTrace, ArrayBase* pStackTraceUNSAFE);
+#if defined(TARGET_X86) || defined(TARGET_AMD64)
+ static void QCALLTYPE X86BaseCpuId(int cpuInfo[4], int functionId, int subFunctionId);
+#endif // defined(TARGET_X86) || defined(TARGET_AMD64)
+
private:
// Common processing code for FailFast
static void GenericFailFast(STRINGREF refMesgString, EXCEPTIONREF refExceptionForWatsonBucketing, UINT_PTR retAddress, UINT exitCode, STRINGREF errorSource);
diff --git a/src/coreclr/src/classlibnative/bcltype/varargsnative.cpp b/src/coreclr/src/classlibnative/bcltype/varargsnative.cpp
index fb2c1aefe3c760..3a9ed227cfdd25 100644
--- a/src/coreclr/src/classlibnative/bcltype/varargsnative.cpp
+++ b/src/coreclr/src/classlibnative/bcltype/varargsnative.cpp
@@ -502,7 +502,7 @@ VarArgsNative::GetNextArgHelper(
value->data = (BYTE*)origArgPtr + (sizeof(void*)-1);
}
#endif
- value->type = MscorlibBinder::GetElementType(elemType);
+ value->type = CoreLibBinder::GetElementType(elemType);
break;
case ELEMENT_TYPE_I2:
@@ -513,7 +513,7 @@ VarArgsNative::GetNextArgHelper(
value->data = (BYTE*)origArgPtr + (sizeof(void*)-2);
}
#endif
- value->type = MscorlibBinder::GetElementType(elemType);
+ value->type = CoreLibBinder::GetElementType(elemType);
break;
case ELEMENT_TYPE_I4:
@@ -522,13 +522,13 @@ VarArgsNative::GetNextArgHelper(
case ELEMENT_TYPE_STRING:
case ELEMENT_TYPE_I:
case ELEMENT_TYPE_U:
- value->type = MscorlibBinder::GetElementType(elemType);
+ value->type = CoreLibBinder::GetElementType(elemType);
break;
case ELEMENT_TYPE_I8:
case ELEMENT_TYPE_U8:
case ELEMENT_TYPE_R8:
- value->type = MscorlibBinder::GetElementType(elemType);
+ value->type = CoreLibBinder::GetElementType(elemType);
#if !defined(HOST_64BIT) && (DATA_ALIGNMENT > 4)
if ( fData && origArgPtr == value->data ) {
// allocate an aligned copy of the value
diff --git a/src/coreclr/src/classlibnative/float/CMakeLists.txt b/src/coreclr/src/classlibnative/float/CMakeLists.txt
index 2345ad0b91354b..b2c47ea39b65ea 100644
--- a/src/coreclr/src/classlibnative/float/CMakeLists.txt
+++ b/src/coreclr/src/classlibnative/float/CMakeLists.txt
@@ -7,9 +7,12 @@ set(FLOAT_SOURCES
floatsingle.cpp
)
-add_library_clr(comfloat_wks
+add_library_clr(comfloat_wks_obj
OBJECT
${FLOAT_SOURCES}
)
-add_dependencies(comfloat_wks eventing_headers)
+add_dependencies(comfloat_wks_obj eventing_headers)
+
+add_library(comfloat_wks INTERFACE)
+target_sources(comfloat_wks INTERFACE $)
\ No newline at end of file
diff --git a/src/coreclr/src/debug/createdump/main.cpp b/src/coreclr/src/debug/createdump/main.cpp
index 626175c2903c09..902ee1a693fa4b 100644
--- a/src/coreclr/src/debug/createdump/main.cpp
+++ b/src/coreclr/src/debug/createdump/main.cpp
@@ -35,10 +35,20 @@ int __cdecl main(const int argc, const char* argv[])
MiniDumpWithFullMemoryInfo |
MiniDumpWithThreadInfo |
MiniDumpWithTokenInformation);
+ const char* dumpType = "minidump with heap";
const char* dumpPathTemplate = nullptr;
int exitCode = 0;
int pid = 0;
+#ifdef __APPLE__
+ char* enabled = getenv("COMPlus_DbgEnableElfDumpOnMacOS");
+ if (enabled == nullptr || strcmp(enabled, "1") != 0)
+ {
+ fprintf(stderr, "MachO coredumps are not supported. To enable ELF coredumps on MacOS, set the COMPlus_DbgEnableElfDumpOnMacOS environment variable to 1.\n");
+ return -1;
+ }
+#endif
+
#ifdef HOST_UNIX
exitCode = PAL_InitializeDLL();
if (exitCode != 0)
@@ -60,11 +70,13 @@ int __cdecl main(const int argc, const char* argv[])
}
else if ((strcmp(*argv, "-n") == 0) || (strcmp(*argv, "--normal") == 0))
{
+ dumpType = "minidump";
minidumpType = (MINIDUMP_TYPE)(MiniDumpNormal |
MiniDumpWithThreadInfo);
}
else if ((strcmp(*argv, "-h") == 0) || (strcmp(*argv, "--withheap") == 0))
{
+ dumpType = "minidump with heap";
minidumpType = (MINIDUMP_TYPE)(MiniDumpWithPrivateReadWriteMemory |
MiniDumpWithDataSegs |
MiniDumpWithHandleData |
@@ -75,11 +87,13 @@ int __cdecl main(const int argc, const char* argv[])
}
else if ((strcmp(*argv, "-t") == 0) || (strcmp(*argv, "--triage") == 0))
{
+ dumpType = "triage minidump";
minidumpType = (MINIDUMP_TYPE)(MiniDumpFilterTriage |
MiniDumpWithThreadInfo);
}
else if ((strcmp(*argv, "-u") == 0) || (strcmp(*argv, "--full") == 0))
{
+ dumpType = "full dump";
minidumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory |
MiniDumpWithDataSegs |
MiniDumpWithHandleData |
@@ -122,24 +136,6 @@ int __cdecl main(const int argc, const char* argv[])
snprintf(dumpPath, MAX_LONGPATH, dumpPathTemplate, pid);
- const char* dumpType = "minidump";
- switch (minidumpType)
- {
- case MiniDumpWithPrivateReadWriteMemory:
- dumpType = "minidump with heap";
- break;
-
- case MiniDumpFilterTriage:
- dumpType = "triage minidump";
- break;
-
- case MiniDumpWithFullMemory:
- dumpType = "full dump";
- break;
-
- default:
- break;
- }
printf("Writing %s to file %s\n", dumpType, (char*)dumpPath);
if (CreateDump(dumpPath, pid, minidumpType))
diff --git a/src/coreclr/src/debug/daccess/daccess.cpp b/src/coreclr/src/debug/daccess/daccess.cpp
index 1e40f07a5c5e2c..e999ec866f7d04 100644
--- a/src/coreclr/src/debug/daccess/daccess.cpp
+++ b/src/coreclr/src/debug/daccess/daccess.cpp
@@ -3293,6 +3293,10 @@ ClrDataAccess::QueryInterface(THIS_
{
ifaceRet = static_cast(this);
}
+ else if (IsEqualIID(interfaceId, __uuidof(ISOSDacInterface9)))
+ {
+ ifaceRet = static_cast(this);
+ }
else
{
*iface = NULL;
diff --git a/src/coreclr/src/debug/daccess/dacdbiimpl.cpp b/src/coreclr/src/debug/daccess/dacdbiimpl.cpp
index 4bcd6f2ff4cbe8..c0e0a23f53a330 100644
--- a/src/coreclr/src/debug/daccess/dacdbiimpl.cpp
+++ b/src/coreclr/src/debug/daccess/dacdbiimpl.cpp
@@ -2399,7 +2399,7 @@ TypeHandle DacDbiInterfaceImpl::FindLoadedElementType(CorElementType elementType
// Lookup operations run the class loader in non-load mode.
ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE();
- MethodTable * pMethodTable = (&g_Mscorlib)->GetElementType(elementType);
+ MethodTable * pMethodTable = (&g_CoreLib)->GetElementType(elementType);
return TypeHandle(pMethodTable);
} // DacDbiInterfaceImpl::FindLoadedElementType
@@ -4272,6 +4272,30 @@ void DacDbiInterfaceImpl::GetModuleSimpleName(VMPTR_Module vmModule, IStringHold
IfFailThrow(pStrFilename->AssignCopy(convert.GetUnicode()));
}
+HRESULT DacDbiInterfaceImpl::IsModuleMapped(VMPTR_Module pModule, OUT BOOL *isModuleMapped)
+{
+ LOG((LF_CORDB, LL_INFO10000, "DDBII::IMM - TADDR 0x%x\n", pModule));
+ DD_ENTER_MAY_THROW;
+
+ HRESULT hr = S_FALSE;
+ PTR_Module pTargetModule = pModule.GetDacPtr();
+
+ EX_TRY
+ {
+ PTR_PEFile pPEFile = pTargetModule->GetFile();
+ _ASSERTE(pPEFile != NULL);
+
+ if (pPEFile->HasLoadedIL())
+ {
+ *isModuleMapped = pPEFile->GetLoadedIL()->IsMapped();
+ hr = S_OK;
+ }
+ }
+ EX_CATCH_HRESULT(hr);
+
+ return hr;
+}
+
// Helper to intialize a TargetBuffer from a MemoryRange
//
// Arguments:
@@ -7240,7 +7264,7 @@ HRESULT DacDbiInterfaceImpl::GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT *pLa
if (mt->IsString())
{
COR_TYPEID token;
- token.token1 = MscorlibBinder::GetElementType(ELEMENT_TYPE_CHAR).GetAddr();
+ token.token1 = CoreLibBinder::GetElementType(ELEMENT_TYPE_CHAR).GetAddr();
token.token2 = 0;
pLayout->componentID = token;
diff --git a/src/coreclr/src/debug/daccess/dacdbiimpl.h b/src/coreclr/src/debug/daccess/dacdbiimpl.h
index 9178e71736260f..219b51dc77af16 100644
--- a/src/coreclr/src/debug/daccess/dacdbiimpl.h
+++ b/src/coreclr/src/debug/daccess/dacdbiimpl.h
@@ -363,6 +363,8 @@ class DacDbiInterfaceImpl :
HRESULT GetLoaderHeapMemoryRanges(OUT DacDbiArrayList * pRanges);
+ HRESULT IsModuleMapped(VMPTR_Module pModule, OUT BOOL *isModuleMapped);
+
// retrieves the list of COM interfaces implemented by vmObject, as it is known at
// the time of the call (the list may change as new interface types become available
// in the runtime)
diff --git a/src/coreclr/src/debug/daccess/dacimpl.h b/src/coreclr/src/debug/daccess/dacimpl.h
index efbd19da6f1a58..c0809924bc3e1d 100644
--- a/src/coreclr/src/debug/daccess/dacimpl.h
+++ b/src/coreclr/src/debug/daccess/dacimpl.h
@@ -840,7 +840,8 @@ class ClrDataAccess
public ISOSDacInterface5,
public ISOSDacInterface6,
public ISOSDacInterface7,
- public ISOSDacInterface8
+ public ISOSDacInterface8,
+ public ISOSDacInterface9
{
public:
ClrDataAccess(ICorDebugDataTarget * pTarget, ICLRDataTarget * pLegacyTarget=0);
@@ -1205,6 +1206,9 @@ class ClrDataAccess
virtual HRESULT STDMETHODCALLTYPE GetAssemblyLoadContext(CLRDATA_ADDRESS methodTable, CLRDATA_ADDRESS* assemblyLoadContext);
+ // ISOSDacInterface9
+ virtual HRESULT STDMETHODCALLTYPE GetBreakingChangeVersion(int* pVersion);
+
//
// ClrDataAccess.
//
diff --git a/src/coreclr/src/debug/daccess/enummem.cpp b/src/coreclr/src/debug/daccess/enummem.cpp
index 95909b89e3f8d4..a746aa46b3d13d 100644
--- a/src/coreclr/src/debug/daccess/enummem.cpp
+++ b/src/coreclr/src/debug/daccess/enummem.cpp
@@ -276,7 +276,7 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)
}
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pEEDbgInterfaceImpl.EnumMem(); )
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_CORDebuggerControlFlags.EnumMem(); )
- CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_Mscorlib.EnumMem(); )
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_CoreLib.EnumMem(); )
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT].EnumMemoryRegions(flags); )
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( StubManager::EnumMemoryRegions(flags); )
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pFinalizerThread.EnumMem(); )
diff --git a/src/coreclr/src/debug/daccess/inspect.cpp b/src/coreclr/src/debug/daccess/inspect.cpp
index 75cfcc3cadcea2..28375862bd38a9 100644
--- a/src/coreclr/src/debug/daccess/inspect.cpp
+++ b/src/coreclr/src/debug/daccess/inspect.cpp
@@ -136,7 +136,7 @@ GetTypeFieldValueFlags(TypeHandle typeHandle,
// Perform extra checks to identify well-known classes.
//
- if ((&g_Mscorlib)->IsClass(typeHandle.GetMethodTable(), CLASS__STRING))
+ if ((&g_CoreLib)->IsClass(typeHandle.GetMethodTable(), CLASS__STRING))
{
otherFlags |= CLRDATA_VALUE_IS_STRING;
}
diff --git a/src/coreclr/src/debug/daccess/nidump.cpp b/src/coreclr/src/debug/daccess/nidump.cpp
index 5a0bbfd81006f4..b385e278d69842 100644
--- a/src/coreclr/src/debug/daccess/nidump.cpp
+++ b/src/coreclr/src/debug/daccess/nidump.cpp
@@ -477,7 +477,7 @@ NativeImageDumper::NativeImageDumper(PTR_VOID loadedBase,
m_dis(dis),
m_MetadataSize(0),
m_ILHostCopy(NULL),
- m_isMscorlibHardBound(false),
+ m_isCoreLibHardBound(false),
m_sectionAlignment(0)
{
IfFailThrow(m_display->GetDumpOptions(&m_dumpOptions));
@@ -1132,54 +1132,54 @@ NativeImageDumper::DumpNativeImage()
/* XXX Wed 12/14/2005
* Now for the real insanity. I need to initialize static classes in
- * the DAC. First I need to find mscorlib's dependency entry. Search
+ * the DAC. First I need to find CoreLib's dependency entry. Search
* through all of the dependencies to find the one marked as
- * fIsMscorlib. If I don't find anything marked that way, then "self"
- * is mscorlib.
+ * fIsCoreLib. If I don't find anything marked that way, then "self"
+ * is CoreLib.
*/
- Dependency * mscorlib = NULL;
+ Dependency * corelib = NULL;
for( COUNT_T i = 0; i < m_numDependencies; ++i )
{
- if( m_dependencies[i].fIsMscorlib )
+ if( m_dependencies[i].fIsCoreLib )
{
- mscorlib = &m_dependencies[i];
+ corelib = &m_dependencies[i];
break;
}
}
- //If we're actually dumping mscorlib, remap the mscorlib dependency to our own native image.
- if( (mscorlib == NULL) || !wcscmp(m_name, CoreLibName_W))
+ //If we're actually dumping CoreLib, remap the CoreLib dependency to our own native image.
+ if( (corelib == NULL) || !wcscmp(m_name, CoreLibName_W))
{
- mscorlib = GetDependency(0);
- mscorlib->fIsMscorlib = TRUE;
- _ASSERTE(mscorlib->fIsHardbound);
+ corelib = GetDependency(0);
+ corelib->fIsCoreLib = TRUE;
+ _ASSERTE(corelib->fIsHardbound);
}
- _ASSERTE(mscorlib != NULL);
- if( mscorlib->fIsHardbound )
+ _ASSERTE(corelib != NULL);
+ if( corelib->fIsHardbound )
{
- m_isMscorlibHardBound = true;
+ m_isCoreLibHardBound = true;
}
- if( m_isMscorlibHardBound )
+ if( m_isCoreLibHardBound )
{
//go through the module to the binder.
- PTR_Module mscorlibModule = mscorlib->pModule;
+ PTR_Module corelibModule = corelib->pModule;
- PTR_MscorlibBinder binder = mscorlibModule->m_pBinder;
- g_Mscorlib = *binder;
+ PTR_CoreLibBinder binder = corelibModule->m_pBinder;
+ g_CoreLib = *binder;
- PTR_MethodTable mt = MscorlibBinder::GetExistingClass(CLASS__OBJECT);
+ PTR_MethodTable mt = CoreLibBinder::GetExistingClass(CLASS__OBJECT);
g_pObjectClass = mt;
}
if (g_pObjectClass == NULL)
{
- //if mscorlib is not hard bound, then warn the user (many features of nidump are shut off)
- m_display->ErrorPrintF( "Assembly %S is soft bound to mscorlib. nidump cannot dump MethodTables completely.\n", m_name );
+ //if CoreLib is not hard bound, then warn the user (many features of nidump are shut off)
+ m_display->ErrorPrintF( "Assembly %S is soft bound to CoreLib. nidump cannot dump MethodTables completely.\n", m_name );
// TritonTODO: reason?
// reset "hard bound state"
- m_isMscorlibHardBound = false;
+ m_isCoreLibHardBound = false;
}
}
@@ -1267,8 +1267,8 @@ void NativeImageDumper::TraceDumpDependency(int idx, NativeImageDumper::Dependen
m_display->ErrorPrintF("\tSize: %x (%d)\n", dependency->size, dependency->size);
m_display->ErrorPrintF("\tModule: P=%p, L=%p\n", DataPtrToDisplay(dac_cast(dependency->pModule)),
PTR_TO_TADDR(dependency->pModule));
- m_display->ErrorPrintF("Mscorlib=%s, Hardbound=%s\n",
- (dependency->fIsMscorlib ? "true" : "false"),
+ m_display->ErrorPrintF("CoreLib=%s, Hardbound=%s\n",
+ (dependency->fIsCoreLib ? "true" : "false"),
(dependency->fIsHardbound ? "true" : "false"));
m_display->ErrorPrintF("Name: %S\n", dependency->name);
}
@@ -2391,7 +2391,7 @@ mdAssemblyRef NativeImageDumper::MapAssemblyRefToManifest(mdAssemblyRef token, I
}
else if (wcscmp(szAssemblyName, CoreLibName_W) == 0)
{
- // Mscorlib is special - version number and public key token are ignored.
+ // CoreLib is special - version number and public key token are ignored.
ret = currentRef;
break;
}
@@ -2400,7 +2400,7 @@ mdAssemblyRef NativeImageDumper::MapAssemblyRefToManifest(mdAssemblyRef token, I
metadata.usBuildNumber == 255 &&
metadata.usRevisionNumber == 255)
{
- // WinMDs encode all assemblyrefs with version 255.255.255.255 including CLR assembly dependencies (mscorlib, System).
+ // WinMDs encode all assemblyrefs with version 255.255.255.255 including CLR assembly dependencies (corelib, System).
ret = currentRef;
}
else
@@ -2602,8 +2602,8 @@ NativeImageDumper::Dependency *NativeImageDumper::OpenDependency(int index)
Dependency& dependency = m_dependencies[index];
AppendTokenName(entry->dwAssemblyRef, buf, m_manifestImport, true);
bool isHardBound = !!(entry->signNativeImage != INVALID_NGEN_SIGNATURE);
- SString mscorlibStr(SString::Literal, CoreLibName_W);
- bool isMscorlib = (0 == buf.Compare( mscorlibStr ));
+ SString corelibStr(SString::Literal, CoreLibName_W);
+ bool isCoreLib = (0 == buf.Compare( corelibStr ));
dependency.fIsHardbound = isHardBound;
wcscpy_s(dependency.name, _countof(dependency.name),
(const WCHAR*)buf);
@@ -2703,7 +2703,7 @@ NativeImageDumper::Dependency *NativeImageDumper::OpenDependency(int index)
ofRead,
IID_IMetaDataImport2,
(IUnknown **) &dependency.pImport));
- dependency.fIsMscorlib = isMscorlib;
+ dependency.fIsCoreLib = isCoreLib;
}
m_dependencies[index].entry = entry;
@@ -3716,7 +3716,7 @@ void NativeImageDumper::DumpModule( PTR_Module module )
/* REVISIT_TODO Fri 10/14/2005
* Dump the binder
*/
- PTR_MscorlibBinder binder = module->m_pBinder;
+ PTR_CoreLibBinder binder = module->m_pBinder;
if( NULL != binder )
{
DisplayStartStructureWithOffset( m_pBinder, DPtrToPreferredAddr(binder),
@@ -3726,38 +3726,38 @@ void NativeImageDumper::DumpModule( PTR_Module module )
//these four fields don't have anything useful in ngen images.
DisplayWriteFieldPointer( m_classDescriptions,
DPtrToPreferredAddr(binder->m_classDescriptions),
- MscorlibBinder, MODULE );
+ CoreLibBinder, MODULE );
DisplayWriteFieldPointer( m_methodDescriptions,
DPtrToPreferredAddr(binder->m_methodDescriptions),
- MscorlibBinder, MODULE );
+ CoreLibBinder, MODULE );
DisplayWriteFieldPointer( m_fieldDescriptions,
DPtrToPreferredAddr(binder->m_fieldDescriptions),
- MscorlibBinder, MODULE );
+ CoreLibBinder, MODULE );
DisplayWriteFieldPointer( m_pModule,
DPtrToPreferredAddr(binder->m_pModule),
- MscorlibBinder, MODULE );
+ CoreLibBinder, MODULE );
- DisplayWriteFieldInt( m_cClasses, binder->m_cClasses, MscorlibBinder,
+ DisplayWriteFieldInt( m_cClasses, binder->m_cClasses, CoreLibBinder,
MODULE );
DisplayWriteFieldAddress( m_pClasses,
DPtrToPreferredAddr(binder->m_pClasses),
sizeof(*binder->m_pClasses)
* binder->m_cClasses,
- MscorlibBinder, MODULE );
- DisplayWriteFieldInt( m_cFields, binder->m_cFields, MscorlibBinder,
+ CoreLibBinder, MODULE );
+ DisplayWriteFieldInt( m_cFields, binder->m_cFields, CoreLibBinder,
MODULE );
DisplayWriteFieldAddress( m_pFields,
DPtrToPreferredAddr(binder->m_pFields),
sizeof(*binder->m_pFields)
* binder->m_cFields,
- MscorlibBinder, MODULE );
- DisplayWriteFieldInt( m_cMethods, binder->m_cMethods, MscorlibBinder,
+ CoreLibBinder, MODULE );
+ DisplayWriteFieldInt( m_cMethods, binder->m_cMethods, CoreLibBinder,
MODULE );
DisplayWriteFieldAddress( m_pMethods,
DPtrToPreferredAddr(binder->m_pMethods),
sizeof(*binder->m_pMethods)
* binder->m_cMethods,
- MscorlibBinder, MODULE );
+ CoreLibBinder, MODULE );
DisplayEndStructure( MODULE ); //m_pBinder
}
@@ -6766,11 +6766,11 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name,
MethodTableToString( mt, buf );
m_display->ErrorPrintF( "WARNING! MethodTable %S is generic but is not hard bound to its EEClass. Cannot compute generic dictionary sizes.\n", (const WCHAR *)buf );
}
- else if( !m_isMscorlibHardBound )
+ else if( !m_isCoreLibHardBound )
{
/* REVISIT_TODO Mon 8/20/2007
- * If we're not hard bound to mscorlib, most things don't work. They depend on knowing what
- * g_pObjectClass is. Without the hard binding to mscorlib, I can't figure that out.
+ * If we're not hard bound to CoreLib, most things don't work. They depend on knowing what
+ * g_pObjectClass is. Without the hard binding to CoreLib, I can't figure that out.
*/
haveCompleteExtents = false;
}
@@ -7996,7 +7996,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
InstantiatedMethodDesc, METHODDESCS );
#ifdef FEATURE_COMINTEROP
- if (imd->IMD_HasComPlusCallInfo())
+ if (imd->IsGenericComPlusCall())
{
PTR_ComPlusCallInfo compluscall = imd->IMD_GetComPlusCallInfo();
DumpComPlusCallInfo( compluscall, METHODDESCS );
diff --git a/src/coreclr/src/debug/daccess/nidump.h b/src/coreclr/src/debug/daccess/nidump.h
index b8c0a04ddb4170..a6e9461a475ae6 100644
--- a/src/coreclr/src/debug/daccess/nidump.h
+++ b/src/coreclr/src/debug/daccess/nidump.h
@@ -305,7 +305,7 @@ class NativeImageDumper
TADDR pMetadataStartTarget;
TADDR pMetadataStartHost;
SIZE_T MetadataSize;
- bool fIsMscorlib;
+ bool fIsCoreLib;
bool fIsHardbound;
WCHAR name[128];
};
@@ -548,9 +548,9 @@ class NativeImageDumper
COUNT_T m_ILSectionSize;
#endif
- //This is true if we are hard bound to mscorlib. This enables various forms of generics dumping and MT
+ //This is true if we are hard bound to corelib. This enables various forms of generics dumping and MT
//dumping that require g_pObjectClass to be set.
- bool m_isMscorlibHardBound;
+ bool m_isCoreLibHardBound;
#if 0
PTR_CCOR_SIGNATURE metadataToHostDAC( PCCOR_SIGNATURE pSig,
diff --git a/src/coreclr/src/debug/daccess/request.cpp b/src/coreclr/src/debug/daccess/request.cpp
index b9a589fd609fa3..5047421d595970 100644
--- a/src/coreclr/src/debug/daccess/request.cpp
+++ b/src/coreclr/src/debug/daccess/request.cpp
@@ -1058,7 +1058,7 @@ HRESULT ClrDataAccess::GetMethodDescData(
OBJECTREF value = pResolver->GetManagedResolver();
if (value)
{
- FieldDesc *pField = (&g_Mscorlib)->GetField(FIELD__DYNAMICRESOLVER__DYNAMIC_METHOD);
+ FieldDesc *pField = (&g_CoreLib)->GetField(FIELD__DYNAMICRESOLVER__DYNAMIC_METHOD);
_ASSERTE(pField);
value = pField->GetRefValue(value);
if (value)
@@ -4732,3 +4732,12 @@ HRESULT ClrDataAccess::GetAssemblyLoadContext(CLRDATA_ADDRESS methodTable, CLRDA
SOSDacLeave();
return hr;
}
+
+HRESULT ClrDataAccess::GetBreakingChangeVersion(int* pVersion)
+{
+ if (pVersion == nullptr)
+ return E_INVALIDARG;
+
+ *pVersion = SOS_BREAKING_CHANGE_VERSION;
+ return S_OK;
+}
diff --git a/src/coreclr/src/debug/daccess/stack.cpp b/src/coreclr/src/debug/daccess/stack.cpp
index 09e16b4979ab1c..94ef49b972ad23 100644
--- a/src/coreclr/src/debug/daccess/stack.cpp
+++ b/src/coreclr/src/debug/daccess/stack.cpp
@@ -1391,7 +1391,7 @@ ClrDataFrame::ValueFromDebugInfo(MetaSig* sig,
// XXX Microsoft - Sometimes types can't be looked
// up and this at least allows the value to be used,
// but is it the right behavior?
- argType = TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_U8));
+ argType = TypeHandle(CoreLibBinder::GetElementType(ELEMENT_TYPE_U8));
valueFlags = 0;
}
else
diff --git a/src/coreclr/src/debug/dbgutil/machoreader.cpp b/src/coreclr/src/debug/dbgutil/machoreader.cpp
index 155ec15a3af004..fa94b49b8d4a40 100644
--- a/src/coreclr/src/debug/dbgutil/machoreader.cpp
+++ b/src/coreclr/src/debug/dbgutil/machoreader.cpp
@@ -401,6 +401,7 @@ MachOReader::ReadString(const char* address, std::string& str)
char c = 0;
if (!ReadMemory((void*)(address + i), &c, sizeof(char)))
{
+ Trace("ERROR: Failed to read string at %p\n", (void*)(address + i));
return false;
}
if (c == '\0')
diff --git a/src/coreclr/src/debug/debug-pal/CMakeLists.txt b/src/coreclr/src/debug/debug-pal/CMakeLists.txt
index 12a0005c053220..213fa59e784c51 100644
--- a/src/coreclr/src/debug/debug-pal/CMakeLists.txt
+++ b/src/coreclr/src/debug/debug-pal/CMakeLists.txt
@@ -34,4 +34,6 @@ if(CLR_CMAKE_HOST_UNIX)
endif(CLR_CMAKE_HOST_UNIX)
-_add_library(debug-pal OBJECT ${TWO_WAY_PIPE_SOURCES})
+_add_library(debug-pal_obj OBJECT ${TWO_WAY_PIPE_SOURCES})
+add_library(debug-pal INTERFACE)
+target_sources(debug-pal INTERFACE $)
diff --git a/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp b/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp
index e8830422930aac..a718c2bc34e2d0 100644
--- a/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp
+++ b/src/coreclr/src/debug/debug-pal/unix/diagnosticsipc.cpp
@@ -187,6 +187,10 @@ IpcStream *IpcStream::DiagnosticsIpc::Connect(ErrorCallback callback)
{
if (callback != nullptr)
callback(strerror(errno), errno);
+
+ const bool fCloseSuccess = ::close(clientSocket) == 0;
+ if (!fCloseSuccess && callback != nullptr)
+ callback(strerror(errno), errno);
return nullptr;
}
@@ -223,12 +227,11 @@ int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_
// Check results
if (retval < 0)
{
- for (uint32_t i = 0; i < nHandles; i++)
- {
- if ((pollfds[i].revents & POLLERR) && callback != nullptr)
- callback(strerror(errno), errno);
- rgIpcPollHandles[i].revents = (uint8_t)PollEvents::ERR;
- }
+ // If poll() returns with an error, including one due to an interrupted call, the fds
+ // array will be unmodified and the global variable errno will be set to indicate the error.
+ // - POLL(2)
+ if (callback != nullptr)
+ callback(strerror(errno), errno);
delete[] pollfds;
return -1;
}
@@ -243,6 +246,8 @@ int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_
{
if (pollfds[i].revents != 0)
{
+ if (callback != nullptr)
+ callback("IpcStream::DiagnosticsIpc::Poll - poll revents", (uint32_t)pollfds[i].revents);
// error check FIRST
if (pollfds[i].revents & POLLHUP)
{
@@ -250,21 +255,22 @@ int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_
// will technically meet the requirements for POLLIN
// i.e., a call to recv/read won't block
rgIpcPollHandles[i].revents = (uint8_t)PollEvents::HANGUP;
- delete[] pollfds;
- return -1;
}
else if ((pollfds[i].revents & (POLLERR|POLLNVAL)))
{
if (callback != nullptr)
callback("Poll error", (uint32_t)pollfds[i].revents);
rgIpcPollHandles[i].revents = (uint8_t)PollEvents::ERR;
- delete[] pollfds;
- return -1;
}
- else if (pollfds[i].revents & POLLIN)
+ else if (pollfds[i].revents & (POLLIN|POLLPRI))
{
rgIpcPollHandles[i].revents = (uint8_t)PollEvents::SIGNALED;
- break;
+ }
+ else
+ {
+ rgIpcPollHandles[i].revents = (uint8_t)PollEvents::UNKNOWN;
+ if (callback != nullptr)
+ callback("unkown poll response", (uint32_t)pollfds[i].revents);
}
}
}
@@ -338,7 +344,7 @@ bool IpcStream::Read(void *lpBuffer, const uint32_t nBytesToRead, uint32_t &nByt
pfd.fd = _clientSocket;
pfd.events = POLLIN;
int retval = poll(&pfd, 1, timeoutMs);
- if (retval <= 0 || pfd.revents != POLLIN)
+ if (retval <= 0 || !(pfd.revents & POLLIN))
{
// timeout or error
return false;
@@ -379,7 +385,7 @@ bool IpcStream::Write(const void *lpBuffer, const uint32_t nBytesToWrite, uint32
pfd.fd = _clientSocket;
pfd.events = POLLOUT;
int retval = poll(&pfd, 1, timeoutMs);
- if (retval <= 0 || pfd.revents != POLLOUT)
+ if (retval <= 0 || !(pfd.revents & POLLOUT))
{
// timeout or error
return false;
diff --git a/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp b/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp
index 6c1b55e3111843..2b6c38463c1bf2 100644
--- a/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp
+++ b/src/coreclr/src/debug/debug-pal/win/diagnosticsipc.cpp
@@ -119,6 +119,7 @@ bool IpcStream::DiagnosticsIpc::Listen(ErrorCallback callback)
_hPipe = INVALID_HANDLE_VALUE;
::CloseHandle(_oOverlap.hEvent);
_oOverlap.hEvent = INVALID_HANDLE_VALUE;
+ memset(&_oOverlap, 0, sizeof(OVERLAPPED)); // clear the overlapped objects state
return false;
}
}
@@ -193,11 +194,15 @@ IpcStream *IpcStream::DiagnosticsIpc::Connect(ErrorCallback callback)
return new IpcStream(hPipe, mode);
}
-void IpcStream::DiagnosticsIpc::Close(bool isShutdown, ErrorCallback)
+void IpcStream::DiagnosticsIpc::Close(bool isShutdown, ErrorCallback callback)
{
// don't attempt cleanup on shutdown and let the OS handle it
if (isShutdown)
+ {
+ if (callback != nullptr)
+ callback("Closing without cleaning underlying handles", 100);
return;
+ }
if (_hPipe != INVALID_HANDLE_VALUE)
{
@@ -205,15 +210,22 @@ void IpcStream::DiagnosticsIpc::Close(bool isShutdown, ErrorCallback)
{
const BOOL fSuccessDisconnectNamedPipe = ::DisconnectNamedPipe(_hPipe);
_ASSERTE(fSuccessDisconnectNamedPipe != 0);
+ if (fSuccessDisconnectNamedPipe != 0 && callback != nullptr)
+ callback("Failed to disconnect NamedPipe", ::GetLastError());
}
const BOOL fSuccessCloseHandle = ::CloseHandle(_hPipe);
_ASSERTE(fSuccessCloseHandle != 0);
+ if (fSuccessCloseHandle != 0 && callback != nullptr)
+ callback("Failed to close pipe handle", ::GetLastError());
}
if (_oOverlap.hEvent != INVALID_HANDLE_VALUE)
{
- ::CloseHandle(_oOverlap.hEvent);
+ const BOOL fSuccessCloseEvent = ::CloseHandle(_oOverlap.hEvent);
+ _ASSERTE(fSuccessCloseEvent != 0);
+ if (fSuccessCloseEvent != 0 && callback != nullptr)
+ callback("Failed to close overlap event handle", ::GetLastError());
}
}
@@ -230,7 +242,7 @@ IpcStream::~IpcStream()
Close();
}
-void IpcStream::Close(ErrorCallback)
+void IpcStream::Close(ErrorCallback callback)
{
if (_hPipe != INVALID_HANDLE_VALUE)
{
@@ -240,15 +252,22 @@ void IpcStream::Close(ErrorCallback)
{
const BOOL fSuccessDisconnectNamedPipe = ::DisconnectNamedPipe(_hPipe);
_ASSERTE(fSuccessDisconnectNamedPipe != 0);
+ if (fSuccessDisconnectNamedPipe != 0 && callback != nullptr)
+ callback("Failed to disconnect NamedPipe", ::GetLastError());
}
const BOOL fSuccessCloseHandle = ::CloseHandle(_hPipe);
_ASSERTE(fSuccessCloseHandle != 0);
+ if (fSuccessCloseHandle != 0 && callback != nullptr)
+ callback("Failed to close pipe handle", ::GetLastError());
}
if (_oOverlap.hEvent != INVALID_HANDLE_VALUE)
{
- ::CloseHandle(_oOverlap.hEvent);
+ const BOOL fSuccessCloseEvent = ::CloseHandle(_oOverlap.hEvent);
+ _ASSERTE(fSuccessCloseEvent != 0);
+ if (fSuccessCloseEvent != 0 && callback != nullptr)
+ callback("Failed to close overlapped event handle", ::GetLastError());
}
}
@@ -302,6 +321,11 @@ int32_t IpcStream::DiagnosticsIpc::Poll(IpcPollHandle *rgIpcPollHandles, uint32_
return -1;
}
}
+ else
+ {
+ // there's already data to be read
+ pHandles[i] = rgIpcPollHandles[i].pStream->_oOverlap.hEvent;
+ }
}
else
{
diff --git a/src/coreclr/src/debug/di/module.cpp b/src/coreclr/src/debug/di/module.cpp
index d02dfdd08146a9..9554f61dc86060 100644
--- a/src/coreclr/src/debug/di/module.cpp
+++ b/src/coreclr/src/debug/di/module.cpp
@@ -1200,6 +1200,10 @@ HRESULT CordbModule::QueryInterface(REFIID id, void **pInterface)
{
*pInterface = static_cast(this);
}
+ else if (id == IID_ICorDebugModule4)
+ {
+ *pInterface = static_cast(this);
+ }
else if (id == IID_IUnknown)
{
*pInterface = static_cast(static_cast(this));
@@ -2752,6 +2756,24 @@ HRESULT CordbModule::GetJITCompilerFlags(DWORD *pdwFlags )
return hr;
}
+HRESULT CordbModule::IsMappedLayout(BOOL *isMapped)
+{
+ VALIDATE_POINTER_TO_OBJECT(isMapped, BOOL*);
+ FAIL_IF_NEUTERED(this);
+
+ HRESULT hr = S_OK;
+ CordbProcess *pProcess = GetProcess();
+
+ ATT_REQUIRE_STOPPED_MAY_FAIL(pProcess);
+ PUBLIC_API_BEGIN(pProcess);
+ {
+ hr = pProcess->GetDAC()->IsModuleMapped(m_vmModule, isMapped);
+ }
+ PUBLIC_API_END(hr);
+
+ return hr;
+}
+
/* ------------------------------------------------------------------------- *
* CordbCode class
* ------------------------------------------------------------------------- */
diff --git a/src/coreclr/src/debug/di/rspriv.h b/src/coreclr/src/debug/di/rspriv.h
index 1bb48df2356c2c..4dc93ebf731729 100644
--- a/src/coreclr/src/debug/di/rspriv.h
+++ b/src/coreclr/src/debug/di/rspriv.h
@@ -4139,7 +4139,8 @@ class CordbProcess :
class CordbModule : public CordbBase,
public ICorDebugModule,
public ICorDebugModule2,
- public ICorDebugModule3
+ public ICorDebugModule3,
+ public ICorDebugModule4
{
public:
CordbModule(CordbProcess * process,
@@ -4234,6 +4235,11 @@ class CordbModule : public CordbBase,
COM_METHOD CreateReaderForInMemorySymbols(REFIID riid,
void** ppObj);
+ //-----------------------------------------------------------
+ // ICorDebugModule4
+ //-----------------------------------------------------------
+ COM_METHOD IsMappedLayout(BOOL *isMapped);
+
//-----------------------------------------------------------
// Internal members
//-----------------------------------------------------------
diff --git a/src/coreclr/src/debug/di/rstype.cpp b/src/coreclr/src/debug/di/rstype.cpp
index 36b137949664ce..a7412dea57134e 100644
--- a/src/coreclr/src/debug/di/rstype.cpp
+++ b/src/coreclr/src/debug/di/rstype.cpp
@@ -683,7 +683,7 @@ HRESULT CordbType::GetType(CorElementType *pType)
// Determining if something is a VC or not can involve asking the EE.
// We could do it ourselves based on the metadata but it's non-trivial
// determining if a class has System.ValueType as a parent (we have
- // to find and OpenScope the mscorlib.dll which we don't currently do
+ // to find and OpenScope the System.Private.CoreLib.dll which we don't currently do
// on the right-side). But the IsValueClass call can fail if the
// class is not yet loaded on the right side. In that case we
// ignore the failure and return ELEMENT_TYPE_CLASS
diff --git a/src/coreclr/src/debug/di/shimremotedatatarget.cpp b/src/coreclr/src/debug/di/shimremotedatatarget.cpp
index 38bf162e430f05..9a01508e211585 100644
--- a/src/coreclr/src/debug/di/shimremotedatatarget.cpp
+++ b/src/coreclr/src/debug/di/shimremotedatatarget.cpp
@@ -68,7 +68,7 @@ class ShimRemoteDataTarget : public ShimDataTarget
DbgTransportTarget * m_pProxy;
DbgTransportSession * m_pTransport;
#ifdef FEATURE_REMOTE_PROC_MEM
- int m_fd; // /proc//mem handle
+ DWORD m_memoryHandle; // PAL_ReadProcessMemory handle or UINT32_MAX if fallback
#endif
};
@@ -106,9 +106,7 @@ ShimRemoteDataTarget::ShimRemoteDataTarget(DWORD processId,
m_pContinueStatusChangedUserData = NULL;
#ifdef FEATURE_REMOTE_PROC_MEM
- char memPath[128];
- _snprintf_s(memPath, sizeof(memPath), sizeof(memPath), "/proc/%lu/mem", m_processId);
- m_fd = _open(memPath, 0); // O_RDONLY
+ PAL_OpenProcessMemory(m_processId, &m_memoryHandle);
#endif
}
@@ -135,11 +133,8 @@ ShimRemoteDataTarget::~ShimRemoteDataTarget()
void ShimRemoteDataTarget::Dispose()
{
#ifdef FEATURE_REMOTE_PROC_MEM
- if (m_fd != -1)
- {
- _close(m_fd);
- m_fd = -1;
- }
+ PAL_CloseProcessMemory(m_memoryHandle);
+ m_memoryHandle = UINT32_MAX;
#endif
if (m_pTransport != NULL)
{
@@ -269,10 +264,9 @@ ShimRemoteDataTarget::ReadVirtual(
HRESULT hr = S_OK;
#ifdef FEATURE_REMOTE_PROC_MEM
- if (m_fd != -1)
+ if (m_memoryHandle != UINT32_MAX)
{
- read = _pread(m_fd, pBuffer, cbRequestSize, (ULONG64)address);
- if (read == (size_t)-1)
+ if (!PAL_ReadProcessMemory(m_memoryHandle, (ULONG64)address, pBuffer, cbRequestSize, &read))
{
hr = E_FAIL;
}
diff --git a/src/coreclr/src/debug/ee/debugger.cpp b/src/coreclr/src/debug/ee/debugger.cpp
index 7b2cd48b22ed55..5ead858581acac 100644
--- a/src/coreclr/src/debug/ee/debugger.cpp
+++ b/src/coreclr/src/debug/ee/debugger.cpp
@@ -3458,14 +3458,14 @@ void Debugger::getBoundaries(MethodDesc * md,
if (pModule == SystemDomain::SystemModule())
{
- // We don't look up PDBs for mscorlib. This is not quite right, but avoids
+ // We don't look up PDBs for CoreLib. This is not quite right, but avoids
// a bootstrapping problem. When an EXE loads, it has the option of setting
// the COM apartment model to STA if we need to. It is important that no
// other Coinitialize happens before this. Since loading the PDB reader uses
// com we can not come first. However managed code IS run before the COM
// apartment model is set, and thus we have a problem since this code is
// called for when JITTing managed code. We avoid the problem by just
- // bailing for mscorlib.
+ // bailing for CoreLib.
return;
}
@@ -15242,15 +15242,6 @@ HRESULT Debugger::FuncEvalSetup(DebuggerIPCE_FuncEvalInfo *pEvalInfo,
return CORDBG_E_FUNC_EVAL_BAD_START_POINT;
}
- if (MethodDescBackpatchInfoTracker::IsLockOwnedByAnyThread())
- {
- // A thread may have suspended for the debugger while holding the slot backpatching lock while trying to enter
- // cooperative GC mode. If the FuncEval calls a method that is eligible for slot backpatching (virtual or interface
- // methods that are eligible for tiering), the FuncEval may deadlock on trying to acquire the same lock. Fail the
- // FuncEval to avoid the issue.
- return CORDBG_E_FUNC_EVAL_BAD_START_POINT;
- }
-
// Create a DebuggerEval to hold info about this eval while its in progress. Constructor copies the thread's
// CONTEXT.
DebuggerEval *pDE = new (interopsafe, nothrow) DebuggerEval(filterContext, pEvalInfo, fInException);
diff --git a/src/coreclr/src/debug/ee/debugger.h b/src/coreclr/src/debug/ee/debugger.h
index 2450ab65d4f9ef..6c113315852b13 100644
--- a/src/coreclr/src/debug/ee/debugger.h
+++ b/src/coreclr/src/debug/ee/debugger.h
@@ -725,37 +725,6 @@ class DebuggerRCThread
return GetRCThreadSendBuffer();
}
- DebuggerIPCEvent *GetIPCEventSendBufferContinuation(
- DebuggerIPCEvent *eventCur)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- PRECONDITION(eventCur != NULL);
- PRECONDITION(eventCur->next == NULL);
- }
- CONTRACTL_END;
-
- DebuggerIPCEvent *dipce = (DebuggerIPCEvent *) new (nothrow) BYTE [CorDBIPC_BUFFER_SIZE];
- dipce->next = NULL;
-
- LOG((LF_CORDB,LL_INFO1000000, "About to GIPCESBC 0x%x\n",dipce));
-
- if (dipce != NULL)
- {
- eventCur->next = dipce;
- }
-#ifdef _DEBUG
- else
- {
- _ASSERTE( !"GetIPCEventSendBufferContinuation failed to allocate mem!" );
- }
-#endif //_DEBUG
-
- return dipce;
- }
-
// Send an IPCEvent once we're ready for sending. This should be done inbetween
// SENDIPCEVENT_BEGIN & SENDIPCEVENT_END. See definition of SENDIPCEVENT_BEGIN
// for usage pattern
diff --git a/src/coreclr/src/debug/ee/wks/CMakeLists.txt b/src/coreclr/src/debug/ee/wks/CMakeLists.txt
index a6891ebb052cb3..3dd5e3612dfc8a 100644
--- a/src/coreclr/src/debug/ee/wks/CMakeLists.txt
+++ b/src/coreclr/src/debug/ee/wks/CMakeLists.txt
@@ -9,9 +9,9 @@ if (CLR_CMAKE_TARGET_WIN32)
if(CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARM64)
- preprocess_compile_asm(TARGET cordbee_wks ASM_FILES ${ASM_FILE} OUTPUT_OBJECTS ASM_OBJECTS)
+ preprocess_compile_asm(TARGET cordbee_wks_obj ASM_FILES ${ASM_FILE} OUTPUT_OBJECTS ASM_OBJECTS)
- add_library_clr(cordbee_wks OBJECT ${CORDBEE_SOURCES_WKS} ${ASM_FILE} ${ASM_OBJECTS})
+ add_library_clr(cordbee_wks_obj OBJECT ${CORDBEE_SOURCES_WKS} ${ASM_FILE} ${ASM_OBJECTS})
else ()
@@ -23,19 +23,21 @@ if (CLR_CMAKE_TARGET_WIN32)
set_source_files_properties(${ASM_FILE} PROPERTIES COMPILE_OPTIONS "${ASM_OPTIONS}")
- add_library_clr(cordbee_wks OBJECT ${CORDBEE_SOURCES_WKS} ${ASM_FILE})
+ add_library_clr(cordbee_wks_obj OBJECT ${CORDBEE_SOURCES_WKS} ${ASM_FILE})
endif()
else ()
if(CLR_CMAKE_HOST_ARCH_AMD64 OR CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARM64 OR CLR_CMAKE_HOST_ARCH_I386)
- add_library_clr(cordbee_wks OBJECT ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S)
+ add_library_clr(cordbee_wks_obj OBJECT ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S)
else()
message(FATAL_ERROR "Unknown platform")
endif()
endif (CLR_CMAKE_TARGET_WIN32)
-target_precompile_header(TARGET cordbee_wks HEADER stdafx.h)
-add_dependencies(cordbee_wks eventing_headers)
+target_precompile_header(TARGET cordbee_wks_obj HEADER stdafx.h)
+add_dependencies(cordbee_wks_obj eventing_headers)
+add_library(cordbee_wks INTERFACE)
+target_sources(cordbee_wks INTERFACE $)
diff --git a/src/coreclr/src/debug/ildbsymlib/CMakeLists.txt b/src/coreclr/src/debug/ildbsymlib/CMakeLists.txt
index b5b249228d26f6..362da1f6483020 100644
--- a/src/coreclr/src/debug/ildbsymlib/CMakeLists.txt
+++ b/src/coreclr/src/debug/ildbsymlib/CMakeLists.txt
@@ -10,5 +10,6 @@ set( ILDBSYMLIB_SOURCES
symwrite.cpp
)
-add_library_clr(ildbsymlib OBJECT ${ILDBSYMLIB_SOURCES})
-
+add_library_clr(ildbsymlib_obj OBJECT ${ILDBSYMLIB_SOURCES})
+add_library(ildbsymlib INTERFACE)
+target_sources(ildbsymlib INTERFACE $)
diff --git a/src/coreclr/src/debug/inc/amd64/primitives.h b/src/coreclr/src/debug/inc/amd64/primitives.h
index d1e02238ece842..a119c2b3639fe3 100644
--- a/src/coreclr/src/debug/inc/amd64/primitives.h
+++ b/src/coreclr/src/debug/inc/amd64/primitives.h
@@ -53,7 +53,7 @@ inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr)
CORDbgInsertBreakpoint((CORDB_ADDRESS_TYPE *)((_buffer) + ((_patchAddr) - (_requestedAddr))));
-SELECTANY const CorDebugRegister g_JITToCorDbgReg[] =
+constexpr CorDebugRegister g_JITToCorDbgReg[] =
{
REGISTER_AMD64_RAX,
REGISTER_AMD64_RCX,
diff --git a/src/coreclr/src/debug/inc/arm/primitives.h b/src/coreclr/src/debug/inc/arm/primitives.h
index a360737b89734e..269281eb006bed 100644
--- a/src/coreclr/src/debug/inc/arm/primitives.h
+++ b/src/coreclr/src/debug/inc/arm/primitives.h
@@ -63,7 +63,7 @@ inline T _ClearThumbBit(T addr)
CORDbgInsertBreakpointExImpl((CORDB_ADDRESS_TYPE *)((_buffer) + (_ClearThumbBit(_patchAddr) - (_requestedAddr))));
-SELECTANY const CorDebugRegister g_JITToCorDbgReg[] =
+constexpr CorDebugRegister g_JITToCorDbgReg[] =
{
REGISTER_ARM_R0,
REGISTER_ARM_R1,
diff --git a/src/coreclr/src/debug/inc/arm64/primitives.h b/src/coreclr/src/debug/inc/arm64/primitives.h
index b0ab65bac15e23..f359680370dfe5 100644
--- a/src/coreclr/src/debug/inc/arm64/primitives.h
+++ b/src/coreclr/src/debug/inc/arm64/primitives.h
@@ -56,7 +56,7 @@ inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr)
CORDbgInsertBreakpointExImpl((CORDB_ADDRESS_TYPE *)((_buffer) + (_patchAddr) - (_requestedAddr)));
-SELECTANY const CorDebugRegister g_JITToCorDbgReg[] =
+constexpr CorDebugRegister g_JITToCorDbgReg[] =
{
REGISTER_ARM64_X0,
REGISTER_ARM64_X1,
diff --git a/src/coreclr/src/debug/inc/dacdbiinterface.h b/src/coreclr/src/debug/inc/dacdbiinterface.h
index 79405d60e3d841..1f99f5f2966587 100644
--- a/src/coreclr/src/debug/inc/dacdbiinterface.h
+++ b/src/coreclr/src/debug/inc/dacdbiinterface.h
@@ -2733,6 +2733,9 @@ class IDacDbiInterface
virtual
HRESULT GetLoaderHeapMemoryRanges(OUT DacDbiArrayList *pRanges) = 0;
+ virtual
+ HRESULT IsModuleMapped(VMPTR_Module pModule, OUT BOOL *isModuleMapped) = 0;
+
// The following tag tells the DD-marshalling tool to stop scanning.
// END_MARSHAL
diff --git a/src/coreclr/src/debug/inc/dbgipcevents.h b/src/coreclr/src/debug/inc/dbgipcevents.h
index 5c433c2bf6131a..6fd2cf197c65af 100644
--- a/src/coreclr/src/debug/inc/dbgipcevents.h
+++ b/src/coreclr/src/debug/inc/dbgipcevents.h
@@ -848,7 +848,7 @@ typedef VMPTR_Base VMPTR_CONTEXT;
#endif
// DomainFile is a base-class for a CLR module, with app-domain affinity.
-// For domain-neutral modules (like mscorlib), there is a DomainFile instance
+// For domain-neutral modules (like CoreLib), there is a DomainFile instance
// for each appdomain the module lives in.
// This is the canonical handle ICorDebug uses to a CLR module.
DEFINE_VMPTR(class DomainFile, PTR_DomainFile, VMPTR_DomainFile);
@@ -984,20 +984,9 @@ struct MSLAYOUT IPCEventTypeNameMapping
const char * eventName;
};
-extern const IPCEventTypeNameMapping DECLSPEC_SELECTANY DbgIPCEventTypeNames[] =
-{
- #define IPC_EVENT_TYPE0(type, val) { type, #type },
- #define IPC_EVENT_TYPE1(type, val) { type, #type },
- #define IPC_EVENT_TYPE2(type, val) { type, #type },
- #include "dbgipceventtypes.h"
- #undef IPC_EVENT_TYPE2
- #undef IPC_EVENT_TYPE1
- #undef IPC_EVENT_TYPE0
- { DB_IPCE_INVALID_EVENT, "DB_IPCE_Error" }
-};
-
-const size_t nameCount = sizeof(DbgIPCEventTypeNames) / sizeof(DbgIPCEventTypeNames[0]);
+extern const IPCEventTypeNameMapping DbgIPCEventTypeNames[];
+extern const size_t nameCount;
struct MSLAYOUT IPCENames // We use a class/struct so that the function can remain in a shared header file
{
@@ -1028,7 +1017,7 @@ struct MSLAYOUT IPCENames // We use a class/struct so that the function can rema
#undef IPC_EVENT_TYPE0
};
- unsigned int i, lim;
+ size_t i, lim;
if (eventType < DB_IPCE_DEBUGGER_FIRST)
{
diff --git a/src/coreclr/src/debug/inc/diagnosticsipc.h b/src/coreclr/src/debug/inc/diagnosticsipc.h
index 57c0576b9447ed..ecbf9db7dfef83 100644
--- a/src/coreclr/src/debug/inc/diagnosticsipc.h
+++ b/src/coreclr/src/debug/inc/diagnosticsipc.h
@@ -16,6 +16,7 @@ typedef void (*ErrorCallback)(const char *szMessage, uint32_t code);
class IpcStream final
{
+ friend class IpcStreamFactory;
public:
static constexpr int32_t InfiniteTimeout = -1;
~IpcStream();
@@ -26,6 +27,7 @@ class IpcStream final
class DiagnosticsIpc final
{
+ friend class IpcStreamFactory;
public:
enum ConnectionMode
{
@@ -35,10 +37,11 @@ class IpcStream final
enum class PollEvents : uint8_t
{
- TIMEOUT = 0x00, // implies timeout
+ NONE = 0x00, // no events
SIGNALED = 0x01, // ready for use
HANGUP = 0x02, // connection remotely closed
- ERR = 0x04 // other error
+ ERR = 0x04, // error
+ UNKNOWN = 0x80 // unknown state
};
// The bookeeping struct used for polling on server and client structs
@@ -125,7 +128,7 @@ class IpcStream final
private:
#ifdef TARGET_UNIX
int _clientSocket = -1;
- IpcStream(int clientSocket, int serverSocket, DiagnosticsIpc::ConnectionMode mode = DiagnosticsIpc::ConnectionMode::SERVER)
+ IpcStream(int clientSocket, DiagnosticsIpc::ConnectionMode mode = DiagnosticsIpc::ConnectionMode::SERVER)
: _clientSocket(clientSocket), _mode(mode) {}
#else
HANDLE _hPipe = INVALID_HANDLE_VALUE;
diff --git a/src/coreclr/src/debug/inc/i386/primitives.h b/src/coreclr/src/debug/inc/i386/primitives.h
index 05b696a4a0f692..980dc2707bb0f6 100644
--- a/src/coreclr/src/debug/inc/i386/primitives.h
+++ b/src/coreclr/src/debug/inc/i386/primitives.h
@@ -48,7 +48,7 @@ inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr)
CORDbgInsertBreakpoint((CORDB_ADDRESS_TYPE *)((_buffer) + ((_patchAddr) - (_requestedAddr))));
-SELECTANY const CorDebugRegister g_JITToCorDbgReg[] =
+constexpr CorDebugRegister g_JITToCorDbgReg[] =
{
REGISTER_X86_EAX,
REGISTER_X86_ECX,
diff --git a/src/coreclr/src/debug/shared/utils.cpp b/src/coreclr/src/debug/shared/utils.cpp
index 5363e30ee8a88d..b9c7d72db3f703 100644
--- a/src/coreclr/src/debug/shared/utils.cpp
+++ b/src/coreclr/src/debug/shared/utils.cpp
@@ -200,3 +200,17 @@ void ExportILToNativeMap(ULONG32 cMap, // [in] Min size of mapExt, m
#endif // _DEBUG
}
}
+
+const IPCEventTypeNameMapping DbgIPCEventTypeNames[] =
+{
+ #define IPC_EVENT_TYPE0(type, val) { type, #type },
+ #define IPC_EVENT_TYPE1(type, val) { type, #type },
+ #define IPC_EVENT_TYPE2(type, val) { type, #type },
+ #include "dbgipceventtypes.h"
+ #undef IPC_EVENT_TYPE2
+ #undef IPC_EVENT_TYPE1
+ #undef IPC_EVENT_TYPE0
+ { DB_IPCE_INVALID_EVENT, "DB_IPCE_Error" }
+};
+
+const size_t nameCount = sizeof(DbgIPCEventTypeNames) / sizeof(DbgIPCEventTypeNames[0]);
diff --git a/src/coreclr/src/dlls/mscordac/mscordac_unixexports.src b/src/coreclr/src/dlls/mscordac/mscordac_unixexports.src
index 29c010b9e84909..31dd9ea4875e99 100644
--- a/src/coreclr/src/dlls/mscordac/mscordac_unixexports.src
+++ b/src/coreclr/src/dlls/mscordac/mscordac_unixexports.src
@@ -43,6 +43,9 @@ nativeStringResourceTable_mscorrc
#PAL_InitializeDLL
#PAL_TerminateEx
#PAL_IsDebuggerPresent
+#PAL_OpenProcessMemory
+#PAL_CloseProcessMemory
+#PAL_ReadProcessMemory
#PAL_ProbeMemory
#PAL_Random
#PAL_memcpy
diff --git a/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt
index f01133ce40ffbc..2a25b2119b366b 100644
--- a/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt
+++ b/src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt
@@ -10,17 +10,17 @@ if (CLR_CMAKE_HOST_WIN32)
list(APPEND CLR_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/coreclr.def)
- add_link_options(/ENTRY:CoreDllMain)
+ add_linker_flag("/ENTRY:CoreDllMain")
# Incremental linking results in the linker inserting extra padding and routing function calls via thunks that can break the
# invariants (e.g. size of region between Jit_PatchedCodeLast-Jit_PatchCodeStart needs to fit in a page).
- add_link_options(/INCREMENTAL:NO)
+ add_linker_flag("/INCREMENTAL:NO")
# Delay load libraries required for WinRT as that is not supported on all platforms
- add_link_options("/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll")
+ add_linker_flag("/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll")
# Delay load version.dll so that we can specify how to search when loading it as it is not part of Windows' known DLLs
- add_link_options("/DELAYLOAD:version.dll")
+ add_linker_flag("/DELAYLOAD:version.dll")
# No library groups for Win32
set(START_LIBRARY_GROUP)
@@ -33,7 +33,7 @@ else(CLR_CMAKE_HOST_WIN32)
if(CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_FREEBSD OR CLR_CMAKE_TARGET_NETBSD OR CLR_CMAKE_TARGET_SUNOS)
# This option is necessary to ensure that the overloaded delete operator defined inside
# of the utilcode will be used instead of the standard library delete operator.
- add_link_options("LINKER:-Bsymbolic")
+ add_linker_flag("-Wl,-Bsymbolic")
# The following linked options can be inserted into the linker libraries list to
# ensure proper resolving of circular references between a subset of the libraries.
@@ -109,7 +109,7 @@ set(CORECLR_LIBRARIES
ildbsymlib
utilcode
v3binder
- System.Globalization.Native-Static
+ System.Globalization.Native-static
interop
)
@@ -168,8 +168,10 @@ if(FEATURE_MERGE_JIT_AND_ENGINE)
set(CLRJIT_STATIC clrjit_static)
endif(FEATURE_MERGE_JIT_AND_ENGINE)
-target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks cee_wks_core)
-target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} clrjit_static cee_wks_mergeable cee_wks_core)
+target_sources(coreclr PUBLIC $)
+target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks)
+target_sources(coreclr_static PUBLIC $)
+target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} clrjit_static cee_wks_mergeable)
# Create the runtime module index header file containing the coreclr build id
# for xplat and the timestamp/size on Windows.
diff --git a/src/coreclr/src/dlls/mscoree/mscoree.cpp b/src/coreclr/src/dlls/mscoree/mscoree.cpp
index 810a3e88f3fed0..f9e1e3d89ef68c 100644
--- a/src/coreclr/src/dlls/mscoree/mscoree.cpp
+++ b/src/coreclr/src/dlls/mscoree/mscoree.cpp
@@ -444,7 +444,7 @@ HRESULT SetInternalSystemDirectory()
}
#if defined(CROSSGEN_COMPILE)
-void SetMscorlibPath(LPCWSTR wzSystemDirectory)
+void SetCoreLibPath(LPCWSTR wzSystemDirectory)
{
DWORD len = (DWORD)wcslen(wzSystemDirectory);
bool appendSeparator = wzSystemDirectory[len-1] != DIRECTORY_SEPARATOR_CHAR_W;
diff --git a/src/coreclr/src/dlls/mscoree/unixinterface.cpp b/src/coreclr/src/dlls/mscoree/unixinterface.cpp
index def87726531269..e23ece98722448 100644
--- a/src/coreclr/src/dlls/mscoree/unixinterface.cpp
+++ b/src/coreclr/src/dlls/mscoree/unixinterface.cpp
@@ -27,6 +27,9 @@ typedef NewArrayHolder ConstWStringHolder;
// Specifies whether coreclr is embedded or standalone
extern bool g_coreclr_embedded;
+// Specifies whether hostpolicy is embedded in executable or standalone
+extern bool g_hostpolicy_embedded;
+
// Holder for array of wide strings
class ConstWStringArrayHolder : public NewArrayHolder
{
@@ -116,7 +119,8 @@ static void ConvertConfigPropertiesToUnicode(
int propertyCount,
LPCWSTR** propertyKeysWRef,
LPCWSTR** propertyValuesWRef,
- BundleProbe** bundleProbe)
+ BundleProbe** bundleProbe,
+ bool* hostPolicyEmbedded)
{
LPCWSTR* propertyKeysW = new (nothrow) LPCWSTR[propertyCount];
ASSERTE_ALL_BUILDS(propertyKeysW != nullptr);
@@ -135,6 +139,11 @@ static void ConvertConfigPropertiesToUnicode(
// is passed in as the value of "BUNDLE_PROBE" property (encoded as a string).
*bundleProbe = (BundleProbe*)_wcstoui64(propertyValuesW[propertyIndex], nullptr, 0);
}
+ else if (strcmp(propertyKeys[propertyIndex], "HOSTPOLICY_EMBEDDED") == 0)
+ {
+ // The HOSTPOLICY_EMBEDDED property indicates if the executable has hostpolicy statically linked in
+ *hostPolicyEmbedded = (wcscmp(propertyValuesW[propertyIndex], W("true")) == 0);
+ }
}
*propertyKeysWRef = propertyKeysW;
@@ -177,6 +186,7 @@ int coreclr_initialize(
LPCWSTR* propertyKeysW;
LPCWSTR* propertyValuesW;
BundleProbe* bundleProbe = nullptr;
+ bool hostPolicyEmbedded = false;
ConvertConfigPropertiesToUnicode(
propertyKeys,
@@ -184,7 +194,8 @@ int coreclr_initialize(
propertyCount,
&propertyKeysW,
&propertyValuesW,
- &bundleProbe);
+ &bundleProbe,
+ &hostPolicyEmbedded);
#ifdef TARGET_UNIX
DWORD error = PAL_InitializeCoreCLR(exePath, g_coreclr_embedded);
@@ -198,6 +209,8 @@ int coreclr_initialize(
}
#endif
+ g_hostpolicy_embedded = hostPolicyEmbedded;
+
ReleaseHolder host;
hr = CorHost2::CreateObject(IID_ICLRRuntimeHost4, (void**)&host);
diff --git a/src/coreclr/src/dlls/mscorpe/ceefilegenwriter.cpp b/src/coreclr/src/dlls/mscorpe/ceefilegenwriter.cpp
index 77afa5a83024cf..0fb18b0629b2a8 100644
--- a/src/coreclr/src/dlls/mscorpe/ceefilegenwriter.cpp
+++ b/src/coreclr/src/dlls/mscorpe/ceefilegenwriter.cpp
@@ -12,10 +12,168 @@
#include
#include "corerror.h"
-#include "stubs.h"
#include
#include
+// The following block contains a template for the default entry point stubs of a COM+
+// IL only program. One can emit these stubs (with some fix-ups) and make
+// the code supplied the entry point value for the image. The fix-ups will
+// in turn cause mscoree.dll to be loaded and the correct entry point to be
+// called.
+//
+// Note: Although these stubs contain x86 specific code, they are used
+// for all platforms
+
+
+//*****************************************************************************
+// This stub is designed for a x86 Windows application. It will call the
+// _CorExeMain function in mscoree.dll. This entry point will in turn load
+// and run the IL program.
+//
+// jump _CorExeMain();
+//
+// The code jumps to the imported function _CorExeMain using the iat.
+// The address in the template is address of the iat entry which is
+// fixed up by the loader when the image is paged in.
+//*****************************************************************************
+
+const BYTE ExeMainX86Template[] =
+{
+ // Jump through IAT to _CorExeMain
+ 0xFF, 0x25, // jmp [iat:_CorDllMain entry]
+ 0x00, 0x00, 0x00, 0x00, // address to replace
+
+};
+
+#define ExeMainX86TemplateSize sizeof(ExeMainX86Template)
+#define CorExeMainX86IATOffset 2
+
+//*****************************************************************************
+// This stub is designed for a x86 Windows application. It will call the
+// _CorDllMain function in mscoree.dll with with the base entry point for
+// the loaded DLL. This entry point will in turn load and run the IL program.
+//
+// jump _CorDllMain
+//
+// The code jumps to the imported function _CorExeMain using the iat.
+// The address in the template is address of the iat entry which is
+// fixed up by the loader when the image is paged in.
+//*****************************************************************************
+
+const BYTE DllMainX86Template[] =
+{
+ // Jump through IAT to CorDllMain
+ 0xFF, 0x25, // jmp [iat:_CorDllMain entry]
+ 0x00, 0x00, 0x00, 0x00, // address to replace
+};
+
+#define DllMainX86TemplateSize sizeof(DllMainX86Template)
+#define CorDllMainX86IATOffset 2
+
+//*****************************************************************************
+// This stub is designed for a AMD64 Windows application. It will call the
+// _CorExeMain function in mscoree.dll. This entry point will in turn load
+// and run the IL program.
+//
+// mov rax, _CorExeMain();
+// jmp [rax]
+//
+// The code jumps to the imported function _CorExeMain using the iat.
+// The address in the template is address of the iat entry which is
+// fixed up by the loader when the image is paged in.
+//*****************************************************************************
+
+const BYTE ExeMainAMD64Template[] =
+{
+ // Jump through IAT to _CorExeMain
+ 0x48, 0xA1, // rex.w rex.b mov rax,[following address]
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of iat:_CorExeMain entry
+ 0xFF, 0xE0 // jmp [rax]
+};
+
+#define ExeMainAMD64TemplateSize sizeof(ExeMainAMD64Template)
+#define CorExeMainAMD64IATOffset 2
+
+//*****************************************************************************
+// This stub is designed for a AMD64 Windows application. It will call the
+// _CorDllMain function in mscoree.dll with with the base entry point for
+// the loaded DLL. This entry point will in turn load and run the IL program.
+//
+// mov rax, _CorDllMain();
+// jmp [rax]
+//
+// The code jumps to the imported function _CorDllMain using the iat.
+// The address in the template is address of the iat entry which is
+// fixed up by the loader when the image is paged in.
+//*****************************************************************************
+
+const BYTE DllMainAMD64Template[] =
+{
+ // Jump through IAT to CorDllMain
+ 0x48, 0xA1, // rex.w rex.b mov rax,[following address]
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of iat:_CorDllMain entry
+ 0xFF, 0xE0 // jmp [rax]
+};
+
+#define DllMainAMD64TemplateSize sizeof(DllMainAMD64Template)
+#define CorDllMainAMD64IATOffset 2
+
+//*****************************************************************************
+// This stub is designed for an ia64 Windows application. It will call the
+// _CorExeMain function in mscoree.dll. This entry point will in turn load
+// and run the IL program.
+//
+// jump _CorExeMain();
+//
+// The code jumps to the imported function _CorExeMain using the iat.
+// We set the value of gp to point at the iat table entry for _CorExeMain
+//*****************************************************************************
+
+const BYTE ExeMainIA64Template[] =
+{
+ // ld8 r9 = [gp] ;;
+ // ld8 r10 = [r9],8
+ // nop.i ;;
+ // ld8 gp = [r9]
+ // mov b6 = r10
+ // br.cond.sptk.few b6
+ //
+ 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40,
+ 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50,
+ 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00
+};
+
+#define ExeMainIA64TemplateSize sizeof(ExeMainIA64Template)
+
+//*****************************************************************************
+// This stub is designed for an ia64 Windows application. It will call the
+// _CorDllMain function in mscoree.dll with with the base entry point for
+// the loaded DLL. This entry point will in turn load and run the IL program.
+//
+// jump _CorDllMain
+//
+// The code jumps to the imported function _CorExeMain using the iat.
+// We set the value of gp to point at the iat table entry for _CorExeMain
+//*****************************************************************************
+
+const BYTE DllMainIA64Template[] =
+{
+ // ld8 r9 = [gp] ;;
+ // ld8 r10 = [r9],8
+ // nop.i ;;
+ // ld8 gp = [r9]
+ // mov b6 = r10
+ // br.cond.sptk.few b6
+ //
+ 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40,
+ 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50,
+ 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00
+};
+
+#define DllMainIA64TemplateSize sizeof(DllMainIA64Template)
+
#ifdef EMIT_FIXUPS
// Emitted PEFIXUP structure looks like this
diff --git a/src/coreclr/src/dlls/mscorpe/stubs.h b/src/coreclr/src/dlls/mscorpe/stubs.h
deleted file mode 100644
index 893fc4783a2758..00000000000000
--- a/src/coreclr/src/dlls/mscorpe/stubs.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-//*****************************************************************************
-// Stubs.h
-//
-// This file contains a template for the default entry point stubs of a COM+
-// IL only program. One can emit these stubs (with some fix-ups) and make
-// the code supplied the entry point value for the image. The fix-ups will
-// in turn cause mscoree.dll to be loaded and the correct entry point to be
-// called.
-//
-// Note: Although these stubs contain x86 specific code, they are used
-// for all platforms
-//
-//*****************************************************************************
-#ifndef __STUBS_H__
-#define __STUBS_H__
-
-//*****************************************************************************
-// This stub is designed for a x86 Windows application. It will call the
-// _CorExeMain function in mscoree.dll. This entry point will in turn load
-// and run the IL program.
-//
-// jump _CorExeMain();
-//
-// The code jumps to the imported function _CorExeMain using the iat.
-// The address in the template is address of the iat entry which is
-// fixed up by the loader when the image is paged in.
-//*****************************************************************************
-
-SELECTANY const BYTE ExeMainX86Template[] =
-{
- // Jump through IAT to _CorExeMain
- 0xFF, 0x25, // jmp [iat:_CorDllMain entry]
- 0x00, 0x00, 0x00, 0x00, // address to replace
-
-};
-
-#define ExeMainX86TemplateSize sizeof(ExeMainX86Template)
-#define CorExeMainX86IATOffset 2
-
-//*****************************************************************************
-// This stub is designed for a x86 Windows application. It will call the
-// _CorDllMain function in mscoree.dll with with the base entry point for
-// the loaded DLL. This entry point will in turn load and run the IL program.
-//
-// jump _CorDllMain
-//
-// The code jumps to the imported function _CorExeMain using the iat.
-// The address in the template is address of the iat entry which is
-// fixed up by the loader when the image is paged in.
-//*****************************************************************************
-
-SELECTANY const BYTE DllMainX86Template[] =
-{
- // Jump through IAT to CorDllMain
- 0xFF, 0x25, // jmp [iat:_CorDllMain entry]
- 0x00, 0x00, 0x00, 0x00, // address to replace
-};
-
-#define DllMainX86TemplateSize sizeof(DllMainX86Template)
-#define CorDllMainX86IATOffset 2
-
-//*****************************************************************************
-// This stub is designed for a AMD64 Windows application. It will call the
-// _CorExeMain function in mscoree.dll. This entry point will in turn load
-// and run the IL program.
-//
-// mov rax, _CorExeMain();
-// jmp [rax]
-//
-// The code jumps to the imported function _CorExeMain using the iat.
-// The address in the template is address of the iat entry which is
-// fixed up by the loader when the image is paged in.
-//*****************************************************************************
-
-SELECTANY const BYTE ExeMainAMD64Template[] =
-{
- // Jump through IAT to _CorExeMain
- 0x48, 0xA1, // rex.w rex.b mov rax,[following address]
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of iat:_CorExeMain entry
- 0xFF, 0xE0 // jmp [rax]
-};
-
-#define ExeMainAMD64TemplateSize sizeof(ExeMainAMD64Template)
-#define CorExeMainAMD64IATOffset 2
-
-//*****************************************************************************
-// This stub is designed for a AMD64 Windows application. It will call the
-// _CorDllMain function in mscoree.dll with with the base entry point for
-// the loaded DLL. This entry point will in turn load and run the IL program.
-//
-// mov rax, _CorDllMain();
-// jmp [rax]
-//
-// The code jumps to the imported function _CorDllMain using the iat.
-// The address in the template is address of the iat entry which is
-// fixed up by the loader when the image is paged in.
-//*****************************************************************************
-
-SELECTANY const BYTE DllMainAMD64Template[] =
-{
- // Jump through IAT to CorDllMain
- 0x48, 0xA1, // rex.w rex.b mov rax,[following address]
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//address of iat:_CorDllMain entry
- 0xFF, 0xE0 // jmp [rax]
-};
-
-#define DllMainAMD64TemplateSize sizeof(DllMainAMD64Template)
-#define CorDllMainAMD64IATOffset 2
-
-//*****************************************************************************
-// This stub is designed for an ia64 Windows application. It will call the
-// _CorExeMain function in mscoree.dll. This entry point will in turn load
-// and run the IL program.
-//
-// jump _CorExeMain();
-//
-// The code jumps to the imported function _CorExeMain using the iat.
-// We set the value of gp to point at the iat table entry for _CorExeMain
-//*****************************************************************************
-
-SELECTANY const BYTE ExeMainIA64Template[] =
-{
- // ld8 r9 = [gp] ;;
- // ld8 r10 = [r9],8
- // nop.i ;;
- // ld8 gp = [r9]
- // mov b6 = r10
- // br.cond.sptk.few b6
- //
- 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40,
- 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50,
- 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00
-};
-
-#define ExeMainIA64TemplateSize sizeof(ExeMainIA64Template)
-
-//*****************************************************************************
-// This stub is designed for an ia64 Windows application. It will call the
-// _CorDllMain function in mscoree.dll with with the base entry point for
-// the loaded DLL. This entry point will in turn load and run the IL program.
-//
-// jump _CorDllMain
-//
-// The code jumps to the imported function _CorExeMain using the iat.
-// We set the value of gp to point at the iat table entry for _CorExeMain
-//*****************************************************************************
-
-SELECTANY const BYTE DllMainIA64Template[] =
-{
- // ld8 r9 = [gp] ;;
- // ld8 r10 = [r9],8
- // nop.i ;;
- // ld8 gp = [r9]
- // mov b6 = r10
- // br.cond.sptk.few b6
- //
- 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40,
- 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00,
- 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50,
- 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00
-};
-
-#define DllMainIA64TemplateSize sizeof(DllMainIA64Template)
-
-#endif // __STUBS_H__
diff --git a/src/coreclr/src/dlls/mscorrc/CMakeLists.txt b/src/coreclr/src/dlls/mscorrc/CMakeLists.txt
index ed5ee887650877..e114ec19cea63e 100644
--- a/src/coreclr/src/dlls/mscorrc/CMakeLists.txt
+++ b/src/coreclr/src/dlls/mscorrc/CMakeLists.txt
@@ -19,7 +19,9 @@ if(CLR_CMAKE_HOST_WIN32)
else()
build_resources(${CMAKE_CURRENT_SOURCE_DIR}/include.rc mscorrc TARGET_CPP_FILE)
- add_library_clr(mscorrc OBJECT
+ add_library_clr(mscorrc_obj OBJECT
${TARGET_CPP_FILE}
)
+ add_library(mscorrc INTERFACE)
+ target_sources(mscorrc INTERFACE $)
endif(CLR_CMAKE_HOST_WIN32)
diff --git a/src/coreclr/src/dlls/mscorrc/mscorrc.rc b/src/coreclr/src/dlls/mscorrc/mscorrc.rc
index a50f742cef007c..360442044ca439 100644
--- a/src/coreclr/src/dlls/mscorrc/mscorrc.rc
+++ b/src/coreclr/src/dlls/mscorrc/mscorrc.rc
@@ -182,6 +182,7 @@ BEGIN
IDS_EE_NDIRECT_UNSUPPORTED_SIG "Method's type signature is not PInvoke compatible."
IDS_EE_COM_UNSUPPORTED_SIG "Method's type signature is not Interop compatible."
IDS_EE_COM_UNSUPPORTED_TYPE "The method returned a COM Variant type that is not Interop compatible."
+ IDS_EE_MULTIPLE_CALLCONV_UNSUPPORTED "Multiple unmanaged calling conventions are specified. Only a single calling convention is supported."
IDS_EE_NDIRECT_BADNATL "Invalid PInvoke or UnmanagedFunctionPointer metadata format."
IDS_EE_NDIRECT_BADNATL_CALLCONV "Invalid PInvoke or UnmanagedFunctionPointer calling convention."
IDS_EE_NDIRECT_BADNATL_VARARGS_CALLCONV "Invalid PInvoke calling convention. Vararg functions must use the cdecl calling convention."
diff --git a/src/coreclr/src/dlls/mscorrc/resource.h b/src/coreclr/src/dlls/mscorrc/resource.h
index 738b751c7faec9..b78c5d84c304a0 100644
--- a/src/coreclr/src/dlls/mscorrc/resource.h
+++ b/src/coreclr/src/dlls/mscorrc/resource.h
@@ -43,6 +43,7 @@
#define IDS_EE_COM_UNSUPPORTED_SIG 0x170d
#define IDS_EE_NOSYNCHRONIZED 0x170f
#define IDS_EE_NDIRECT_BADNATL_THISCALL 0x1710
+#define IDS_EE_MULTIPLE_CALLCONV_UNSUPPORTED 0x1711
#define IDS_EE_LOAD_BAD_MAIN_SIG 0x1712
#define IDS_EE_COM_UNSUPPORTED_TYPE 0x1713
diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp
index 6bf8e51a6bcefb..e20daab80ed273 100644
--- a/src/coreclr/src/gc/gc.cpp
+++ b/src/coreclr/src/gc/gc.cpp
@@ -8347,6 +8347,8 @@ void gc_heap::sort_mark_list()
{
if (settings.condemned_generation >= max_generation)
{
+ // fake a mark list overflow so merge_mark_lists knows to quit early
+ mark_list_index = mark_list_end + 1;
return;
}
@@ -8397,7 +8399,7 @@ void gc_heap::sort_mark_list()
high = max (high, heap_segment_allocated (hp->ephemeral_heap_segment));
}
- // give up if this is not an ephemeral GC or the mark list size is unreasonably large
+ // give up if the mark list size is unreasonably large
if (total_mark_list_size > (total_ephemeral_size / 256))
{
mark_list_index = mark_list_end + 1;
@@ -18088,12 +18090,12 @@ uint8_t* gc_heap::find_object (uint8_t* interior)
{
// this is a pointer to a UOH object
heap_segment* seg = find_segment (interior, FALSE);
- if (seg
+ if (seg)
+ {
#ifdef FEATURE_CONSERVATIVE_GC
- && (GCConfig::GetConservativeGC() || interior <= heap_segment_allocated(seg))
+ if (interior >= heap_segment_allocated(seg))
+ return 0;
#endif
- )
- {
// If interior falls within the first free object at the beginning of a generation,
// we don't have brick entry for it, and we may incorrectly treat it as on large object heap.
int align_const = get_alignment_constant (heap_segment_read_only_p (seg)
@@ -38607,8 +38609,8 @@ void gc_heap::walk_heap_per_heap (walk_fn fn, void* context, int gen_number, BOO
generation_allocation_start (gen));
uint8_t* end = heap_segment_allocated (seg);
- BOOL small_object_segments = TRUE;
- int align_const = get_alignment_constant (small_object_segments);
+ int align_const = get_alignment_constant (TRUE);
+ BOOL walk_pinned_object_heap = walk_large_object_heap_p;
while (1)
@@ -38623,20 +38625,25 @@ void gc_heap::walk_heap_per_heap (walk_fn fn, void* context, int gen_number, BOO
}
else
{
- if (small_object_segments && walk_large_object_heap_p)
-
+ if (walk_large_object_heap_p)
{
- small_object_segments = FALSE;
- align_const = get_alignment_constant (small_object_segments);
+ walk_large_object_heap_p = FALSE;
seg = generation_start_segment (large_object_generation);
- x = heap_segment_mem (seg);
- end = heap_segment_allocated (seg);
- continue;
+ }
+ else if (walk_pinned_object_heap)
+ {
+ walk_pinned_object_heap = FALSE;
+ seg = generation_start_segment (pinned_object_generation);
}
else
{
break;
}
+
+ align_const = get_alignment_constant (FALSE);
+ x = heap_segment_mem (seg);
+ end = heap_segment_allocated (seg);
+ continue;
}
}
diff --git a/src/coreclr/src/gc/gcconfig.h b/src/coreclr/src/gc/gcconfig.h
index 085562f56dd486..7d667b6a15ea6d 100644
--- a/src/coreclr/src/gc/gcconfig.h
+++ b/src/coreclr/src/gc/gcconfig.h
@@ -75,7 +75,7 @@ class GCConfigStringHolder
BOOL_CONFIG (LogEnabled, "GCLogEnabled", NULL, false, "Specifies if you want to turn on logging in GC") \
BOOL_CONFIG (ConfigLogEnabled, "GCConfigLogEnabled", NULL, false, "Specifies the name of the GC config log file") \
BOOL_CONFIG (GCNumaAware, "GCNumaAware", NULL, true, "Enables numa allocations in the GC") \
- BOOL_CONFIG (GCCpuGroup, "GCCpuGroup", NULL, false, "Enables CPU groups in the GC") \
+ BOOL_CONFIG (GCCpuGroup, "GCCpuGroup", "System.GC.CpuGroup", false, "Enables CPU groups in the GC") \
BOOL_CONFIG (GCLargePages, "GCLargePages", "System.GC.LargePages", false, "Enables using Large Pages in the GC") \
INT_CONFIG (HeapVerifyLevel, "HeapVerify", NULL, HEAPVERIFY_NONE, "When set verifies the integrity of the managed heap on entry and exit of each GC") \
INT_CONFIG (LOHCompactionMode, "GCLOHCompact", NULL, 0, "Specifies the LOH compaction mode") \
@@ -92,13 +92,13 @@ class GCConfigStringHolder
INT_CONFIG (LogFileSize, "GCLogFileSize", NULL, 0, "Specifies the GC log file size") \
INT_CONFIG (CompactRatio, "GCCompactRatio", NULL, 0, "Specifies the ratio compacting GCs vs sweeping") \
INT_CONFIG (GCHeapAffinitizeMask, "GCHeapAffinitizeMask", "System.GC.HeapAffinitizeMask", 0, "Specifies processor mask for Server GC threads") \
- STRING_CONFIG(GCHeapAffinitizeRanges, "GCHeapAffinitizeRanges", NULL, "Specifies list of processors for Server GC threads. The format is a comma separated " \
+ STRING_CONFIG(GCHeapAffinitizeRanges, "GCHeapAffinitizeRanges", "System.GC.HeapAffinitizeRanges", "Specifies list of processors for Server GC threads. The format is a comma separated " \
"list of processor numbers or ranges of processor numbers. On Windows, each entry is " \
"prefixed by the CPU group number. Example: Unix - 1,3,5,7-9,12, Windows - 0:1,1:7-9") \
- INT_CONFIG (GCHighMemPercent, "GCHighMemPercent", NULL, 0, "The percent for GC to consider as high memory") \
+ INT_CONFIG (GCHighMemPercent, "GCHighMemPercent", "System.GC.HighMemoryPercent", 0, "The percent for GC to consider as high memory") \
INT_CONFIG (GCProvModeStress, "GCProvModeStress", NULL, 0, "Stress the provisional modes") \
INT_CONFIG (GCGen0MaxBudget, "GCGen0MaxBudget", NULL, 0, "Specifies the largest gen0 allocation budget") \
- INT_CONFIG (GCHeapHardLimit, "GCHeapHardLimit", NULL, 0, "Specifies a hard limit for the GC heap") \
+ INT_CONFIG (GCHeapHardLimit, "GCHeapHardLimit", "System.GC.HeapHardLimit", 0, "Specifies a hard limit for the GC heap") \
INT_CONFIG (GCHeapHardLimitPercent, "GCHeapHardLimitPercent", "System.GC.HeapHardLimitPercent", 0, "Specifies the GC heap usage as a percentage of the total memory") \
INT_CONFIG (GCTotalPhysicalMemory, "GCTotalPhysicalMemory", NULL, 0, "Specifies what the GC should consider to be total physical memory") \
STRING_CONFIG(LogFile, "GCLogFile", NULL, "Specifies the name of the GC log file") \
@@ -122,13 +122,13 @@ class GCConfigStringHolder
INT_CONFIG (BGCFLEnableTBH, "BGCFLEnableTBH", NULL, 0, "Enables TBH") \
INT_CONFIG (BGCFLEnableFF, "BGCFLEnableFF", NULL, 0, "Enables FF") \
INT_CONFIG (BGCG2RatioStep, "BGCG2RatioStep", NULL, 5, "Ratio correction factor for ML loop") \
- INT_CONFIG (GCHeapHardLimitSOH, "GCHeapHardLimitSOH", NULL, 0, "Specifies a hard limit for the GC heap SOH") \
- INT_CONFIG (GCHeapHardLimitLOH, "GCHeapHardLimitLOH", NULL, 0, "Specifies a hard limit for the GC heap LOH") \
- INT_CONFIG (GCHeapHardLimitPOH, "GCHeapHardLimitPOH", NULL, 0, "Specifies a hard limit for the GC heap POH") \
- INT_CONFIG (GCHeapHardLimitSOHPercent, "GCHeapHardLimitSOHPercent", NULL, 0, "Specifies the GC heap SOH usage as a percentage of the total memory") \
- INT_CONFIG (GCHeapHardLimitLOHPercent, "GCHeapHardLimitLOHPercent", NULL, 0, "Specifies the GC heap LOH usage as a percentage of the total memory") \
- INT_CONFIG (GCHeapHardLimitPOHPercent, "GCHeapHardLimitPOHPercent", NULL, 0, "Specifies the GC heap POH usage as a percentage of the total memory") \
- INT_CONFIG (GCEnabledInstructionSets, "GCEnabledInstructionSets", NULL, -1, "Specifies whether GC can use AVX2 or AVX512F - 0 for neither, 1 for AVX2, 3 for AVX512F")\
+ INT_CONFIG (GCHeapHardLimitSOH, "GCHeapHardLimitSOH", "System.GC.HeapHardLimitSOH", 0, "Specifies a hard limit for the GC heap SOH") \
+ INT_CONFIG (GCHeapHardLimitLOH, "GCHeapHardLimitLOH", "System.GC.HeapHardLimitLOH", 0, "Specifies a hard limit for the GC heap LOH") \
+ INT_CONFIG (GCHeapHardLimitPOH, "GCHeapHardLimitPOH", "System.GC.HeapHardLimitPOH", 0, "Specifies a hard limit for the GC heap POH") \
+ INT_CONFIG (GCHeapHardLimitSOHPercent, "GCHeapHardLimitSOHPercent", "System.GC.HeapHardLimitSOHPercent", 0, "Specifies the GC heap SOH usage as a percentage of the total memory") \
+ INT_CONFIG (GCHeapHardLimitLOHPercent, "GCHeapHardLimitLOHPercent", "System.GC.HeapHardLimitLOHPercent", 0, "Specifies the GC heap LOH usage as a percentage of the total memory") \
+ INT_CONFIG (GCHeapHardLimitPOHPercent, "GCHeapHardLimitPOHPercent", "System.GC.HeapHardLimitPOHPercent", 0, "Specifies the GC heap POH usage as a percentage of the total memory") \
+ INT_CONFIG (GCEnabledInstructionSets, "GCEnabledInstructionSets", NULL, -1, "Specifies whether GC can use AVX2 or AVX512F - 0 for neither, 1 for AVX2, 3 for AVX512F")\
// This class is responsible for retreiving configuration information
// for how the GC should operate.
diff --git a/src/coreclr/src/gc/gcinterface.h b/src/coreclr/src/gc/gcinterface.h
index 331f8e12210842..bfe02b7db9da3b 100644
--- a/src/coreclr/src/gc/gcinterface.h
+++ b/src/coreclr/src/gc/gcinterface.h
@@ -396,7 +396,7 @@ typedef enum
* They are currently used for EnC for adding new field members to existing instantiations under EnC modes where
* the primary object is the original instantiation and the secondary represents the added field.
*
- * They are also used to implement the ConditionalWeakTable class in mscorlib.dll. If you want to use
+ * They are also used to implement the managed ConditionalWeakTable class. If you want to use
* these from managed code, they are exposed to BCL through the managed DependentHandle class.
*
*
@@ -587,7 +587,7 @@ class IGCHeap {
/*
===========================================================================
- BCL routines. These are routines that are directly exposed by mscorlib
+ BCL routines. These are routines that are directly exposed by CoreLib
as a part of the `System.GC` class. These routines behave in the same
manner as the functions on `System.GC`.
===========================================================================
@@ -640,14 +640,14 @@ class IGCHeap {
virtual int GetGcLatencyMode() = 0;
// Sets the current GC latency mode. newLatencyMode has already been
- // verified by mscorlib to be valid.
+ // verified by CoreLib to be valid.
virtual int SetGcLatencyMode(int newLatencyMode) = 0;
// Gets the current LOH compaction mode.
virtual int GetLOHCompactionMode() = 0;
// Sets the current LOH compaction mode. newLOHCompactionMode has
- // already been verified by mscorlib to be valid.
+ // already been verified by CoreLib to be valid.
virtual void SetLOHCompactionMode(int newLOHCompactionMode) = 0;
// Registers for a full GC notification, raising a notification if the gen 2 or
diff --git a/src/coreclr/src/gc/unix/config.gc.h.in b/src/coreclr/src/gc/unix/config.gc.h.in
index 954176f74a346b..42b6429be80e58 100644
--- a/src/coreclr/src/gc/unix/config.gc.h.in
+++ b/src/coreclr/src/gc/unix/config.gc.h.in
@@ -18,7 +18,8 @@
#cmakedefine01 HAVE_PTHREAD_CONDATTR_SETCLOCK
#cmakedefine01 HAVE_MACH_ABSOLUTE_TIME
#cmakedefine01 HAVE_SCHED_GETAFFINITY
-#cmakedefine01 HAVE_PTHREAD_GETAFFINITY_NP
+#cmakedefine01 HAVE_SCHED_SETAFFINITY
+#cmakedefine01 HAVE_PTHREAD_SETAFFINITY_NP
#cmakedefine01 HAVE_PTHREAD_NP_H
#cmakedefine01 HAVE_CPUSET_T
#cmakedefine01 HAVE__SC_AVPHYS_PAGES
diff --git a/src/coreclr/src/gc/unix/configure.cmake b/src/coreclr/src/gc/unix/configure.cmake
index cc7fb90265d8be..6d190a8c467350 100644
--- a/src/coreclr/src/gc/unix/configure.cmake
+++ b/src/coreclr/src/gc/unix/configure.cmake
@@ -86,6 +86,7 @@ check_cxx_source_runs("
check_library_exists(c sched_getaffinity "" HAVE_SCHED_GETAFFINITY)
+check_library_exists(c sched_setaffinity "" HAVE_SCHED_SETAFFINITY)
check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD)
if (HAVE_LIBPTHREAD)
@@ -94,7 +95,7 @@ elseif (HAVE_PTHREAD_IN_LIBC)
set(PTHREAD_LIBRARY c)
endif()
-check_library_exists(${PTHREAD_LIBRARY} pthread_getaffinity_np "" HAVE_PTHREAD_GETAFFINITY_NP)
+check_library_exists(${PTHREAD_LIBRARY} pthread_setaffinity_np "" HAVE_PTHREAD_SETAFFINITY_NP)
check_cxx_symbol_exists(_SC_PHYS_PAGES unistd.h HAVE__SC_PHYS_PAGES)
check_cxx_symbol_exists(_SC_AVPHYS_PAGES unistd.h HAVE__SC_AVPHYS_PAGES)
diff --git a/src/coreclr/src/gc/unix/gcenv.unix.cpp b/src/coreclr/src/gc/unix/gcenv.unix.cpp
index e7a12249869987..76a9efaf36e56e 100644
--- a/src/coreclr/src/gc/unix/gcenv.unix.cpp
+++ b/src/coreclr/src/gc/unix/gcenv.unix.cpp
@@ -985,19 +985,32 @@ size_t GCToOSInterface::GetCacheSizePerLogicalCpu(bool trueSize)
// true if setting the affinity was successful, false otherwise.
bool GCToOSInterface::SetThreadAffinity(uint16_t procNo)
{
-#if HAVE_PTHREAD_GETAFFINITY_NP
+#if HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP
cpu_set_t cpuSet;
CPU_ZERO(&cpuSet);
CPU_SET((int)procNo, &cpuSet);
+ // Snap's default strict confinement does not allow sched_setaffinity(, ...) without manually connecting the
+ // process-control plug. sched_setaffinity(, ...) is also currently not allowed, only
+ // sched_setaffinity(0, ...). pthread_setaffinity_np(pthread_self(), ...) seems to call
+ // sched_setaffinity(, ...) in at least one implementation, and does not work. To work around those
+ // issues, use sched_setaffinity(0, ...) if available and only otherwise fall back to pthread_setaffinity_np(). See the
+ // following for more information:
+ // - https://github.com/dotnet/runtime/pull/38795
+ // - https://github.com/dotnet/runtime/issues/1634
+ // - https://forum.snapcraft.io/t/requesting-autoconnect-for-interfaces-in-pigmeat-process-control-home/17987/13
+#if HAVE_SCHED_SETAFFINITY
+ int st = sched_setaffinity(0, sizeof(cpu_set_t), &cpuSet);
+#else
int st = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuSet);
+#endif
return (st == 0);
-#else // HAVE_PTHREAD_GETAFFINITY_NP
+#else // !(HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP)
// There is no API to manage thread affinity, so let's ignore the request
return false;
-#endif // HAVE_PTHREAD_GETAFFINITY_NP
+#endif // HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP
}
// Boosts the calling thread's thread priority to a level higher than the default
diff --git a/src/coreclr/src/gcinfo/CMakeLists.txt b/src/coreclr/src/gcinfo/CMakeLists.txt
index 3862de8633d0cb..f40ff3deb83a0b 100644
--- a/src/coreclr/src/gcinfo/CMakeLists.txt
+++ b/src/coreclr/src/gcinfo/CMakeLists.txt
@@ -3,6 +3,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set( GCINFO_SOURCES
arraylist.cpp
gcinfoencoder.cpp
+ simplerhash.cpp
)
@@ -16,11 +17,14 @@ endif(CLR_CMAKE_TARGET_ARCH_I386)
convert_to_absolute_path(GCINFO_SOURCES ${GCINFO_SOURCES})
-add_library_clr(gcinfo
+add_library_clr(gcinfo_obj
OBJECT
${GCINFO_SOURCES}
)
+add_library(gcinfo INTERFACE)
+target_sources(gcinfo INTERFACE $)
+
add_library_clr(gcinfo_crossgen
STATIC
${GCINFO_SOURCES}
diff --git a/src/coreclr/src/gcinfo/simplerhash.cpp b/src/coreclr/src/gcinfo/simplerhash.cpp
new file mode 100644
index 00000000000000..1233b91538c263
--- /dev/null
+++ b/src/coreclr/src/gcinfo/simplerhash.cpp
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#include "simplerhash.h"
+
+// Table of primes and their magic-number-divide constant.
+// For more info see the book "Hacker's Delight" chapter 10.9 "Unsigned Division by Divisors >= 1"
+// These were selected by looking for primes, each roughly twice as big as the next, having
+// 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower).
+//
+
+const PrimeInfo primeInfo[] =
+{
+ PrimeInfo(9, 0x38e38e39, 1),
+ PrimeInfo(23, 0xb21642c9, 4),
+ PrimeInfo(59, 0x22b63cbf, 3),
+ PrimeInfo(131, 0xfa232cf3, 7),
+ PrimeInfo(239, 0x891ac73b, 7),
+ PrimeInfo(433, 0x975a751, 4),
+ PrimeInfo(761, 0x561e46a5, 8),
+ PrimeInfo(1399, 0xbb612aa3, 10),
+ PrimeInfo(2473, 0x6a009f01, 10),
+ PrimeInfo(4327, 0xf2555049, 12),
+ PrimeInfo(7499, 0x45ea155f, 11),
+ PrimeInfo(12973, 0x1434f6d3, 10),
+ PrimeInfo(22433, 0x2ebe18db, 12),
+ PrimeInfo(46559, 0xb42bebd5, 15),
+ PrimeInfo(96581, 0xadb61b1b, 16),
+ PrimeInfo(200341, 0x29df2461, 15),
+ PrimeInfo(415517, 0xa181c46d, 18),
+ PrimeInfo(861719, 0x4de0bde5, 18),
+ PrimeInfo(1787021, 0x9636c46f, 20),
+ PrimeInfo(3705617, 0x4870adc1, 20),
+ PrimeInfo(7684087, 0x8bbc5b83, 22),
+ PrimeInfo(15933877, 0x86c65361, 23),
+ PrimeInfo(33040633, 0x40fec79b, 23),
+ PrimeInfo(68513161, 0x7d605cd1, 25),
+ PrimeInfo(142069021, 0xf1da390b, 27),
+ PrimeInfo(294594427, 0x74a2507d, 27),
+ PrimeInfo(733045421, 0x5dbec447, 28),
+};
diff --git a/src/coreclr/src/ildasm/dasm.cpp b/src/coreclr/src/ildasm/dasm.cpp
index da3d12f0f33684..eecd1edbf263fe 100644
--- a/src/coreclr/src/ildasm/dasm.cpp
+++ b/src/coreclr/src/ildasm/dasm.cpp
@@ -3300,7 +3300,9 @@ void DumpGenericParsCA(mdToken tok, void* GUICookie/*=NULL*/)
} //end if(g_fShowCA)
}
-// Sets *pbOverridingTypeSpec to TRUE if we are overriding a method declared by a type spec.
+// Sets *pbOverridingTypeSpec to TRUE if we are overriding a method declared by a type spec or
+// if the method has a signature which does not exactly match between the overrider and overridee.
+// That case is commonly caused by covariant overrides.
// In that case the syntax is slightly different (there are additional 'method' keywords).
// Refer to Expert .NET 2.0 IL Assembler page 242.
void PrettyPrintOverrideDecl(ULONG i, __inout __nullterminated char* szString, void* GUICookie, mdToken tkOverrider,
@@ -3320,6 +3322,11 @@ void PrettyPrintOverrideDecl(ULONG i, __inout __nullterminated char* szString, v
if(g_pImport->IsValidToken(tkDecl))
{
+ bool needsFullTokenPrint = false;
+ bool hasTkDeclParent = false;
+
+ // Determine if the decl is a typespec method, in which case the "method" syntax + full token print
+ // must be used to generate the disassembly.
if(SUCCEEDED(g_pImport->GetParentToken(tkDecl,&tkDeclParent)))
{
if(g_pImport->IsValidToken(tkDeclParent))
@@ -3334,20 +3341,99 @@ void PrettyPrintOverrideDecl(ULONG i, __inout __nullterminated char* szString, v
{
if(TypeFromToken(tkDeclParent)==mdtTypeSpec)
{
- szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr), " %s ",KEYWORD("method"));
- PrettyPrintToken(szString,tkDecl,g_pImport,GUICookie,tkOverrider);
-
- *pbOverridingTypeSpec = TRUE;
- return;
+ needsFullTokenPrint = true;
}
- PrettyPrintToken(szString, tkDeclParent, g_pImport,GUICookie,tkOverrider);
- strcat_s(szString, SZSTRING_SIZE,"::");
- szptr = &szString[strlen(szString)];
+ hasTkDeclParent = true;
}
}
else
szptr+=sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"%s",ERRORMSG("INVALID OVERRIDDEN METHOD'S PARENT TOKEN"));
}
+
+ // Determine if the sig of the decl does not match the sig of the body
+ // In that case the full "method" syntax must be used
+ if ((TypeFromToken(tkOverrider) == mdtMethodDef) && !needsFullTokenPrint)
+ {
+ PCCOR_SIGNATURE pComSigDecl;
+ ULONG cComSigDecl;
+ mdToken tkDeclSigTok = tkDecl;
+ bool successfullyGotDeclSig = false;
+ bool successfullyGotBodySig = false;
+
+ if (TypeFromToken(tkDeclSigTok) == mdtMethodSpec)
+ {
+ mdToken meth=0;
+ if (SUCCEEDED(g_pImport->GetMethodSpecProps(tkDeclSigTok, &meth, NULL, NULL)))
+ {
+ tkDeclSigTok = meth;
+ }
+ }
+
+ if (TypeFromToken(tkDeclSigTok) == mdtMethodDef)
+ {
+ if (SUCCEEDED(g_pImport->GetSigOfMethodDef(tkDeclSigTok, &cComSigDecl, &pComSigDecl)))
+ {
+ successfullyGotDeclSig = true;
+ }
+ }
+ else if (TypeFromToken(tkDeclSigTok) == mdtMemberRef)
+ {
+ const char *pszMemberNameUnused;
+ if (SUCCEEDED(g_pImport->GetNameAndSigOfMemberRef(
+ tkDeclSigTok,
+ &pComSigDecl,
+ &cComSigDecl,
+ &pszMemberNameUnused)))
+ {
+ successfullyGotDeclSig = true;
+ }
+ }
+
+ PCCOR_SIGNATURE pComSigBody;
+ ULONG cComSigBody;
+ if (SUCCEEDED(g_pImport->GetSigOfMethodDef(tkOverrider, &cComSigBody, &pComSigBody)))
+ {
+ successfullyGotBodySig = true;
+ }
+
+ if (successfullyGotDeclSig && successfullyGotBodySig)
+ {
+ if (cComSigBody != cComSigDecl)
+ {
+ needsFullTokenPrint = true;
+ }
+ else if (memcmp(pComSigBody, pComSigDecl, cComSigBody) != 0)
+ {
+ needsFullTokenPrint = true;
+ }
+
+ // Signature are binary identical, full sig printing not needed
+ }
+ else
+ {
+ szptr+=sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),"%s",ERRORMSG("INVALID BODY OR DECL SIG"));
+ }
+ }
+
+ if (needsFullTokenPrint)
+ {
+ // In this case, the shortcut syntax cannot be used, and a full token must be printed.
+ // Print the full token and return.
+ szptr += sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr), " %s ",KEYWORD("method"));
+ PrettyPrintToken(szString,tkDecl,g_pImport,GUICookie,tkOverrider);
+
+ *pbOverridingTypeSpec = TRUE;
+ return;
+ }
+
+ if (hasTkDeclParent)
+ {
+ // If the tkDeclParent was successfully retrieved during parent discovery print it here.
+ PrettyPrintToken(szString, tkDeclParent, g_pImport,GUICookie,tkOverrider);
+ strcat_s(szString, SZSTRING_SIZE,"::");
+ szptr = &szString[strlen(szString)];
+ }
+
if(TypeFromToken(tkDecl) == mdtMethodSpec)
{
mdToken meth=0;
diff --git a/src/coreclr/src/inc/CMakeLists.txt b/src/coreclr/src/inc/CMakeLists.txt
index 81762201251665..4f75d3a882d4c1 100644
--- a/src/coreclr/src/inc/CMakeLists.txt
+++ b/src/coreclr/src/inc/CMakeLists.txt
@@ -58,7 +58,9 @@ if(FEATURE_JIT_PITCHING)
endif(FEATURE_JIT_PITCHING)
# Compile *_i.cpp to lib
-_add_library(corguids OBJECT ${CORGUIDS_SOURCES})
+_add_library(corguids_obj OBJECT ${CORGUIDS_SOURCES})
+add_library(corguids INTERFACE)
+target_sources(corguids INTERFACE $)
# Binplace the inc files for packaging later.
@@ -75,4 +77,3 @@ _install (FILES cfi.h
gcinfoencoder.h
gcinfotypes.h
DESTINATION inc)
-_install (TARGETS corguids DESTINATION lib)
diff --git a/src/coreclr/src/inc/clr/fs/path.h b/src/coreclr/src/inc/clr/fs/path.h
index 7f1d0e00d73823..efc21a5cdd4392 100644
--- a/src/coreclr/src/inc/clr/fs/path.h
+++ b/src/coreclr/src/inc/clr/fs/path.h
@@ -9,7 +9,6 @@
#define _clr_fs_Path_h_
#include "clrtypes.h"
-#include "cor.h" // SELECTANY
#include "strsafe.h"
diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h
index ddb1db3ce647d8..3cd7db89bb7e9e 100644
--- a/src/coreclr/src/inc/clrconfigvalues.h
+++ b/src/coreclr/src/inc/clrconfigvalues.h
@@ -553,6 +553,8 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadSuspendInjection, W("INTERNAL_ThreadSusp
RETAIL_CONFIG_DWORD_INFO(INTERNAL_DefaultStackSize, W("DefaultStackSize"), 0, "Stack size to use for new VM threads when thread is created with default stack size (dwStackSize == 0).")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_Thread_DeadThreadCountThresholdForGCTrigger, W("Thread_DeadThreadCountThresholdForGCTrigger"), 75, "In the heuristics to clean up dead threads, this threshold must be reached before triggering a GC will be considered. Set to 0 to disable triggering a GC based on dead threads.")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_Thread_DeadThreadGCTriggerPeriodMilliseconds, W("Thread_DeadThreadGCTriggerPeriodMilliseconds"), 1000 * 60 * 30, "In the heuristics to clean up dead threads, this much time must have elapsed since the previous max-generation GC before triggering another GC will be considered")
+RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_UseAllCpuGroups, W("Thread_UseAllCpuGroups"), 0, "Specifies whether to query and use CPU group information for determining the processor count.")
+RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_AssignCpuGroups, W("Thread_AssignCpuGroups"), 1, "Specifies whether to automatically distribute threads created by the CLR across CPU Groups. Effective only when Thread_UseAllCpuGroups and GCCpuGroup are enabled.")
///
/// Threadpool
@@ -568,7 +570,6 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_UnfairSemaphoreSpinLimit, W("Thread
#else // !TARGET_ARM64
RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_UnfairSemaphoreSpinLimit, W("ThreadPool_UnfairSemaphoreSpinLimit"), 0x46, "Maximum number of spins a thread pool worker thread performs before waiting for work")
#endif // TARGET_ARM64
-RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_UseAllCpuGroups, W("Thread_UseAllCpuGroups"), 0, "Specifies if to automatically distribute thread across CPU Groups")
CONFIG_DWORD_INFO(INTERNAL_ThreadpoolTickCountAdjustment, W("ThreadpoolTickCountAdjustment"), 0, "")
@@ -691,7 +692,6 @@ RETAIL_CONFIG_STRING_INFO(INTERNAL_EventNameFilter, W("EventNameFilter"), "")
/// Interop
///
CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_ExposeExceptionsInCOM, W("ExposeExceptionsInCOM"), "")
-RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_PInvokeInline, W("PInvokeInline"), "", CLRConfig::EEConfig_default)
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_InteropValidatePinnedObjects, W("InteropValidatePinnedObjects"), 0, "After returning from a managed-to-unmanaged interop call, validate GC heap around objects pinned by IL stubs.")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_InteropLogArguments, W("InteropLogArguments"), 0, "Log all pinned arguments passed to an interop call")
RETAIL_CONFIG_STRING_INFO(UNSUPPORTED_LogCCWRefCountChange, W("LogCCWRefCountChange"), "Outputs debug information and calls LogCCWRefCountChange_BREAKPOINT when AddRef or Release is called on a CCW.")
diff --git a/src/coreclr/src/inc/cor.h b/src/coreclr/src/inc/cor.h
index 9625641288ca6b..035ba44e7f87f4 100644
--- a/src/coreclr/src/inc/cor.h
+++ b/src/coreclr/src/inc/cor.h
@@ -2093,15 +2093,7 @@ inline ULONG CorSigUncompressData( // return number of bytes of that compre
}
-#if !defined(SELECTANY)
-#if defined(__GNUC__)
- #define SELECTANY extern __attribute__((weak))
-#else
- #define SELECTANY extern __declspec(selectany)
-#endif
-#endif
-
-SELECTANY const mdToken g_tkCorEncodeToken[4] ={mdtTypeDef, mdtTypeRef, mdtTypeSpec, mdtBaseType};
+extern const mdToken g_tkCorEncodeToken[];
// uncompress a token
inline mdToken CorSigUncompressToken( // return the token.
diff --git a/src/coreclr/src/inc/corcompile.h b/src/coreclr/src/inc/corcompile.h
index f02a7a1475d003..82308d7b899acc 100644
--- a/src/coreclr/src/inc/corcompile.h
+++ b/src/coreclr/src/inc/corcompile.h
@@ -1412,7 +1412,7 @@ class ICorCompileInfo
// So, the host must call StartupAsCompilationProcess before compiling
// any code, and Shutdown after finishing.
//
- // The arguments control which native image of mscorlib to use.
+ // The arguments control which native image of CoreLib to use.
// This matters for hardbinding.
//
@@ -1548,8 +1548,8 @@ class ICorCompileInfo
mdFieldDef *token
) = 0;
- // Get the loader module for mscorlib
- virtual CORINFO_MODULE_HANDLE GetLoaderModuleForMscorlib() = 0;
+ // Get the loader module for CoreLib
+ virtual CORINFO_MODULE_HANDLE GetLoaderModuleForCoreLib() = 0;
// Get the loader module for a type (where the type is regarded as
// living for the purposes of loading, unloading, and ngen).
diff --git a/src/coreclr/src/inc/cordebug.idl b/src/coreclr/src/inc/cordebug.idl
index 7ab2867d9f2827..efecf3b55063c3 100644
--- a/src/coreclr/src/inc/cordebug.idl
+++ b/src/coreclr/src/inc/cordebug.idl
@@ -2361,7 +2361,7 @@ interface ICorDebugAppDomain4 : IUnknown
* Assembly interface
* An ICorDebugAssembly instance corresponds to a a managed assembly loaded
* into a specific AppDomain in the CLR. For assemblies shared between multiple
- * AppDomains (eg. mscorlib), there will be a separate ICorDebugAssembly instance
+ * AppDomains (eg. CoreLib), there will be a separate ICorDebugAssembly instance
* per AppDomain in which it is used.
* ------------------------------------------------------------------------- */
[
@@ -5173,6 +5173,30 @@ interface ICorDebugModule3 : IUnknown
[out][iid_is(riid)] void **ppObj);
}
+/*
+ * ICorDebugModule4 is a logical extension to ICorDebugModule.
+ */
+[
+ object,
+ local,
+ uuid(FF8B8EAF-25CD-4316-8859-84416DE4402E),
+ pointer_default(unique)
+]
+interface ICorDebugModule4 : IUnknown
+{
+ /*
+ * Query to see if the module is loaded into memory in mapped/hydrated format
+ *
+ * Arguments:
+ * pIsMapped - BOOL to store mapping information. TRUE will represent mapped
+ format while FALSE represents flat format.
+ * Return Value:
+ * S_OK in successful case.
+ * Notes:
+ */
+ HRESULT IsMappedLayout([out] BOOL *pIsMapped);
+}
+
/*
* ICorDebugRuntimeUnwindableFrame is a specialized interface of ICorDebugFrame for unmanaged methods
* which requires special knowledge to unwind. They are not jitted code. When the debugger sees this type
@@ -5196,7 +5220,7 @@ interface ICorDebugRuntimeUnwindableFrame : ICorDebugFrame
* specific AppDomain. Normally this is an executable or a DLL, but it may also be
* some other file of a multi-module assembly. There is an ICorDebugModule instance
* for each AppDomain a module is loaded into, even in the case of shared modules like
- * mscorlib.
+ * CoreLib.
*/
[
diff --git a/src/coreclr/src/inc/corerror.xml b/src/coreclr/src/inc/corerror.xml
index 94fe6a1ddceaef..b1a0b5b53ca090 100644
--- a/src/coreclr/src/inc/corerror.xml
+++ b/src/coreclr/src/inc/corerror.xml
@@ -2201,12 +2201,6 @@
File is PE32
-
- NGEN_E_SYS_ASM_NI_MISSING
- "NGen cannot proceed because Mscorlib.dll does not have a native image"
- Compiling any assembly other than mscorlib in the absence of mscorlib.ni.dll is not allowed.
-
-
CLDB_E_INTERNALERROR
@@ -2249,8 +2243,8 @@
CLR_E_BIND_SYS_ASM_NI_MISSING
- "Could not use native image because Mscorlib.dll is missing a native image"
- Returned when loading an assembly that only has a native image and no IL and cannot hardbind to mscorlib.ni.dll.
+ "Could not use native image because System.Private.CoreLib.dll is missing a native image"
+ Returned when loading an assembly that only has a native image and no IL and cannot hardbind to System.Private.CoreLib.ni.dll.
diff --git a/src/coreclr/src/inc/corexcep.h b/src/coreclr/src/inc/corexcep.h
index faca6b49c593be..e1c00b50b32175 100644
--- a/src/coreclr/src/inc/corexcep.h
+++ b/src/coreclr/src/inc/corexcep.h
@@ -13,7 +13,7 @@
// All COM+ exceptions are expressed as a RaiseException with this exception
// code. If you change this value, you must also change
-// mscorlib\src\system\Exception.cs's _COMPlusExceptionCode value.
+// Exception.cs's _COMPlusExceptionCode value.
#define EXCEPTION_MSVC 0xe06d7363 // 0xe0000000 | 'msc'
diff --git a/src/coreclr/src/inc/corinfo.h b/src/coreclr/src/inc/corinfo.h
index f7f6d8ecf2ea4e..7870683ecf4399 100644
--- a/src/coreclr/src/inc/corinfo.h
+++ b/src/coreclr/src/inc/corinfo.h
@@ -208,19 +208,11 @@ TODO: Talk about initializing strutures before use
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if !defined(SELECTANY)
-#if defined(__GNUC__)
- #define SELECTANY extern __attribute__((weak))
-#else
- #define SELECTANY extern __declspec(selectany)
-#endif
-#endif
-
-SELECTANY const GUID JITEEVersionIdentifier = { /* 7af97117-55be-4c76-afb2-e26261cb140e */
- 0x7af97117,
- 0x55be,
- 0x4c76,
- { 0xaf, 0xb2, 0xe2, 0x62, 0x61, 0xcb, 0x14, 0x0e }
+constexpr GUID JITEEVersionIdentifier = { /* a5eec3a4-4176-43a7-8c2b-a05b551d4f49 */
+ 0xa5eec3a4,
+ 0x4176,
+ 0x43a7,
+ {0x8c, 0x2b, 0xa0, 0x5b, 0x55, 0x1d, 0x4f, 0x49}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -899,28 +891,6 @@ enum CorInfoException
enum CorInfoIntrinsics
{
- CORINFO_INTRINSIC_Sin,
- CORINFO_INTRINSIC_Cos,
- CORINFO_INTRINSIC_Cbrt,
- CORINFO_INTRINSIC_Sqrt,
- CORINFO_INTRINSIC_Abs,
- CORINFO_INTRINSIC_Round,
- CORINFO_INTRINSIC_Cosh,
- CORINFO_INTRINSIC_Sinh,
- CORINFO_INTRINSIC_Tan,
- CORINFO_INTRINSIC_Tanh,
- CORINFO_INTRINSIC_Asin,
- CORINFO_INTRINSIC_Asinh,
- CORINFO_INTRINSIC_Acos,
- CORINFO_INTRINSIC_Acosh,
- CORINFO_INTRINSIC_Atan,
- CORINFO_INTRINSIC_Atan2,
- CORINFO_INTRINSIC_Atanh,
- CORINFO_INTRINSIC_Log10,
- CORINFO_INTRINSIC_Pow,
- CORINFO_INTRINSIC_Exp,
- CORINFO_INTRINSIC_Ceiling,
- CORINFO_INTRINSIC_Floor,
CORINFO_INTRINSIC_GetChar, // fetch character out of string
CORINFO_INTRINSIC_Array_GetDimLength, // Get number of elements in a given dimension of an array
CORINFO_INTRINSIC_Array_Get, // Get the value of an element in an array
diff --git a/src/coreclr/src/inc/corpriv.h b/src/coreclr/src/inc/corpriv.h
index 52cf63a0ee07b5..fb0b39924cc877 100644
--- a/src/coreclr/src/inc/corpriv.h
+++ b/src/coreclr/src/inc/corpriv.h
@@ -235,7 +235,7 @@ typedef enum CorElementTypeZapSig
// where the encoding/decoding takes place.
ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG = 0x3d,
- ELEMENT_TYPE_CANON_ZAPSIG = 0x3e, // zapsig encoding for [mscorlib]System.__Canon
+ ELEMENT_TYPE_CANON_ZAPSIG = 0x3e, // zapsig encoding for System.__Canon
ELEMENT_TYPE_MODULE_ZAPSIG = 0x3f, // zapsig encoding for external module id#
} CorElementTypeZapSig;
diff --git a/src/coreclr/src/inc/dacvars.h b/src/coreclr/src/inc/dacvars.h
index f480851e1b27fb..92f3edf77855bc 100644
--- a/src/coreclr/src/inc/dacvars.h
+++ b/src/coreclr/src/inc/dacvars.h
@@ -144,7 +144,7 @@ DEFINE_DACVAR(ULONG, PTR_GcNotification, dac__g_pGcNotificationTable, ::g_pGcNot
DEFINE_DACVAR(ULONG, PTR_EEConfig, dac__g_pConfig, ::g_pConfig)
-DEFINE_DACVAR(ULONG, MscorlibBinder, dac__g_Mscorlib, ::g_Mscorlib)
+DEFINE_DACVAR(ULONG, CoreLibBinder, dac__g_CoreLib, ::g_CoreLib)
#if defined(PROFILING_SUPPORTED) || defined(PROFILING_SUPPORTED_DATA)
DEFINE_DACVAR(ULONG, ProfControlBlock, dac__g_profControlBlock, ::g_profControlBlock)
diff --git a/src/coreclr/src/inc/delayloadhelpers.h b/src/coreclr/src/inc/delayloadhelpers.h
deleted file mode 100644
index 740999926a28cd..00000000000000
--- a/src/coreclr/src/inc/delayloadhelpers.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-//
-
-//
-// Contains convenience functionality for lazily loading modules
-// and getting entrypoints within them.
-//
-
-#ifndef DelayLoadHelpers_h
-#define DelayLoadHelpers_h
-
-#include "volatile.h"
-
-namespace DelayLoad
-{
- //=================================================================================================================
- // Contains information needed to load and cache a module. Use through
- // the DELAY_LOADED_MODULE macro defined below.
- struct Module
- {
- LPCWSTR const m_wzDllName;
- HMODULE m_hMod;
- HRESULT m_hr;
- Volatile m_fInitialized;
-
- // Returns a non-ref-counted HMODULE; will load the module if necessary.
- // Do not FreeLibrary the returned value.
- HRESULT GetValue(HMODULE *pHMODULE);
- };
-}
-
-//=====================================================================================================================
-// Use at global scope to declare a delay loaded module represented as a
-// DelayLoad::Module instance. The module may then be accessed as
-// 'DelayLoad::Modules::DLL_NAME'.
-//
-// Parameters:
-// DLL_NAME - the simple name (without extension) of the DLL.
-//
-// Example:
-// DELAY_LOADED_MODULE(Kernel32);
-// void Foo() {
-// HMODULE hModKernel32 = nullptr;
-// IfFailThrow(DelayLoad::Modules::Kernel32.GetValue(&hModKernel32));
-// // Use hModKernel32 as needed. Do not FreeLibrary the value!
-// }
-
-#define DELAY_LOADED_MODULE(DLL_NAME) \
- namespace DelayLoad { \
- namespace Modules { \
- SELECTANY Module DLL_NAME = { L#DLL_NAME W(".dll"), nullptr, S_OK, false }; \
- } \
- }
-
-namespace DelayLoad
-{
- //=================================================================================================================
- // Contains information needed to load a function pointer from a DLL. Builds
- // on the DelayLoad::Module functionality, and should be used through
- // the DELAY_LOADED_FUNCTION macro defined below.
- struct Function
- {
- Module * const m_pModule;
- LPCSTR const m_szFunctionName;
- PVOID m_pvFunction;
- HRESULT m_hr;
- Volatile m_fInitialized;
-
- // On success, ppvFunc is set to point to the entrypoint corresponding to
- // m_szFunctionName as exported from m_pModule.
- HRESULT GetValue(LPVOID * ppvFunc);
-
- // Convenience function that does the necessary casting for you.
- template inline
- HRESULT GetValue(FnT ** ppFunc)
- {
- return GetValue(reinterpret_cast(ppFunc));
- }
- };
-}
-
-//=====================================================================================================================
-// Use at global scope to declare a delay loaded function and its associated module,
-// represented as DelayLoad::Function and DelayLoad::Module instances, respectively.
-// The function may then be accessed as 'DelayLoad::DLL_NAME::FUNC_NAME', and the
-// module may be access as described in DELAY_LOADED_MODULE's comment.
-//
-// Parameters:
-// DLL_NAME - unquoted simple name (without extension) of the DLL containing
-// the function.
-// FUNC_NAME - unquoted entrypoint name exported from the DLL.
-//
-// Example:
-// DELAY_LOADED_FUNCTION(MyDll, MyFunction);
-// HRESULT Foo(...) {
-// typedef HRESULT MyFunction_t();
-// MyFunction_t * pFunc = nullptr;
-// IfFailRet(DelayLoad::WinTypes::RoResolveNamespace.GetValue(&pFunc));
-// return (*pFunc)(...);
-// }
-
-#define DELAY_LOADED_FUNCTION(DLL_NAME, FUNC_NAME) \
- DELAY_LOADED_MODULE(DLL_NAME) \
- namespace DelayLoad { \
- namespace DLL_NAME { \
- SELECTANY Function FUNC_NAME = { &Modules::##DLL_NAME, #FUNC_NAME, nullptr, S_OK, false }; \
- } \
- }
-
-#endif // DelayLoadHelpers_h
-
diff --git a/src/coreclr/src/inc/eventtrace.h b/src/coreclr/src/inc/eventtrace.h
index ef999a716c6943..1a930deebfa3e1 100644
--- a/src/coreclr/src/inc/eventtrace.h
+++ b/src/coreclr/src/inc/eventtrace.h
@@ -172,6 +172,8 @@ namespace ETW
static void Cleanup();
static VOID DeleteTypeHashNoLock(AllLoggedTypes **ppAllLoggedTypes);
static VOID FlushObjectAllocationEvents();
+ static UINT32 TypeLoadBegin();
+ static VOID TypeLoadEnd(UINT32 typeLoad, TypeHandle th, UINT16 loadLevel);
private:
static BOOL ShouldLogType(TypeHandle th);
diff --git a/src/coreclr/src/inc/eventtracebase.h b/src/coreclr/src/inc/eventtracebase.h
index 771460b2db14de..863f704ab87b57 100644
--- a/src/coreclr/src/inc/eventtracebase.h
+++ b/src/coreclr/src/inc/eventtracebase.h
@@ -918,6 +918,7 @@ namespace ETW
static const UINT8 MethodFlagsJitOptimizationTierShift = 7;
static const unsigned int MethodFlagsJitOptimizationTierLowMask = 0x7;
+ static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc);
static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint);
static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig);
@@ -928,6 +929,7 @@ namespace ETW
static VOID DynamicMethodDestroyed(MethodDesc *pMethodDesc);
#else // FEATURE_EVENT_TRACE
public:
+ static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc) {};
static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint) {};
static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig);
diff --git a/src/coreclr/src/inc/palclr.h b/src/coreclr/src/inc/palclr.h
index 40a68dd91384c1..2ab9c62c3e8446 100644
--- a/src/coreclr/src/inc/palclr.h
+++ b/src/coreclr/src/inc/palclr.h
@@ -485,26 +485,6 @@
#define PAL_CPP_CATCH_EXCEPTION_NOARG catch (Exception *)
-// SELECTANY macro is intended to prevent duplication of static const
-// arrays declared in .h files in binary modules.
-// The problem is that const variables have static internal linkage
-// in C++. That means that if a const variable is declared in a .h file
-// the compiler will emit it into every translation unit that uses that .h file.
-// That will cause duplication of the data when those translation units
-// are linked into a binary module.
-// SELECTANY declares a variable as extern to give it external linkage
-// and it provides __declspec(selectany) to instruct the linker to merge
-// duplicate external const static data copies into one.
-//
-#if defined(SOURCE_FORMATTING)
-#define SELECTANY extern
-#else
-#if defined(__GNUC__)
-#define SELECTANY extern __attribute__((weak))
-#else
-#define SELECTANY extern __declspec(selectany)
-#endif
-#endif
#if defined(SOURCE_FORMATTING)
#define __annotation(x)
#endif
diff --git a/src/coreclr/src/inc/random.h b/src/coreclr/src/inc/random.h
index 53cc17d64908fa..f2501c356832c4 100644
--- a/src/coreclr/src/inc/random.h
+++ b/src/coreclr/src/inc/random.h
@@ -5,8 +5,7 @@
//
//
-// Defines a random number generator, initially from the System.Random code in the BCL. If you notice any problems,
-// please compare to the implementation in src\mscorlib\src\system\random.cs.
+// Defines a random number generator, initially from the System.Random code in the BCL.
//
// Main advantages over rand() are:
//
diff --git a/src/coreclr/src/inc/readytorun.h b/src/coreclr/src/inc/readytorun.h
index b883f4b558e9b5..e1719a2843eb74 100644
--- a/src/coreclr/src/inc/readytorun.h
+++ b/src/coreclr/src/inc/readytorun.h
@@ -395,4 +395,13 @@ enum ReadyToRunRuntimeConstants : DWORD
READYTORUN_ReversePInvokeTransitionFrameSizeInPointerUnits = 2
};
+enum ReadyToRunHFAElemType : DWORD
+{
+ READYTORUN_HFA_ELEMTYPE_None = 0,
+ READYTORUN_HFA_ELEMTYPE_Float32 = 1,
+ READYTORUN_HFA_ELEMTYPE_Float64 = 2,
+ READYTORUN_HFA_ELEMTYPE_Vector64 = 3,
+ READYTORUN_HFA_ELEMTYPE_Vector128 = 4,
+};
+
#endif // __READYTORUN_H__
diff --git a/src/coreclr/src/inc/safemath.h b/src/coreclr/src/inc/safemath.h
index 84ea377c54b826..d93e4a57011e53 100644
--- a/src/coreclr/src/inc/safemath.h
+++ b/src/coreclr/src/inc/safemath.h
@@ -154,8 +154,7 @@ inline bool DoubleFitsInIntType(double val)
//-----------------------------------------------------------------------------
//
-// Liberally lifted from the Office example on MSDN and modified.
-// http://msdn.microsoft.com/library/en-us/dncode/html/secure01142004.asp
+// Liberally lifted from https://github.com/dcleblanc/SafeInt and modified.
//
// Modified to track an overflow bit instead of throwing exceptions. In most
// cases the Visual C++ optimizer (Whidbey beta1 - v14.00.40607) is able to
diff --git a/src/coreclr/src/inc/simplerhash.h b/src/coreclr/src/inc/simplerhash.h
index ebd8a3e6871ee7..83c552eda19f74 100644
--- a/src/coreclr/src/inc/simplerhash.h
+++ b/src/coreclr/src/inc/simplerhash.h
@@ -68,8 +68,8 @@ class DefaultSimplerHashBehavior
class PrimeInfo
{
public:
- PrimeInfo() : prime(0), magic(0), shift(0) {}
- PrimeInfo(unsigned p, unsigned m, unsigned s) : prime(p), magic(m), shift(s) {}
+ constexpr PrimeInfo() : prime(0), magic(0), shift(0) {}
+ constexpr PrimeInfo(unsigned p, unsigned m, unsigned s) : prime(p), magic(m), shift(s) {}
unsigned prime;
unsigned magic;
unsigned shift;
diff --git a/src/coreclr/src/inc/simplerhash.inl b/src/coreclr/src/inc/simplerhash.inl
index 10a6b157ce99cd..6694ab61212bcc 100644
--- a/src/coreclr/src/inc/simplerhash.inl
+++ b/src/coreclr/src/inc/simplerhash.inl
@@ -303,36 +303,7 @@ void SimplerHashTable::Reallocate(unsigned newTable
// 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower).
//
-SELECTANY const PrimeInfo primeInfo[] =
-{
- PrimeInfo(9, 0x38e38e39, 1),
- PrimeInfo(23, 0xb21642c9, 4),
- PrimeInfo(59, 0x22b63cbf, 3),
- PrimeInfo(131, 0xfa232cf3, 7),
- PrimeInfo(239, 0x891ac73b, 7),
- PrimeInfo(433, 0x975a751, 4),
- PrimeInfo(761, 0x561e46a5, 8),
- PrimeInfo(1399, 0xbb612aa3, 10),
- PrimeInfo(2473, 0x6a009f01, 10),
- PrimeInfo(4327, 0xf2555049, 12),
- PrimeInfo(7499, 0x45ea155f, 11),
- PrimeInfo(12973, 0x1434f6d3, 10),
- PrimeInfo(22433, 0x2ebe18db, 12),
- PrimeInfo(46559, 0xb42bebd5, 15),
- PrimeInfo(96581, 0xadb61b1b, 16),
- PrimeInfo(200341, 0x29df2461, 15),
- PrimeInfo(415517, 0xa181c46d, 18),
- PrimeInfo(861719, 0x4de0bde5, 18),
- PrimeInfo(1787021, 0x9636c46f, 20),
- PrimeInfo(3705617, 0x4870adc1, 20),
- PrimeInfo(7684087, 0x8bbc5b83, 22),
- PrimeInfo(15933877, 0x86c65361, 23),
- PrimeInfo(33040633, 0x40fec79b, 23),
- PrimeInfo(68513161, 0x7d605cd1, 25),
- PrimeInfo(142069021, 0xf1da390b, 27),
- PrimeInfo(294594427, 0x74a2507d, 27),
- PrimeInfo(733045421, 0x5dbec447, 28),
-};
+extern const PrimeInfo primeInfo[27];
template
PrimeInfo SimplerHashTable::NextPrime(unsigned number)
diff --git a/src/coreclr/src/inc/sospriv.idl b/src/coreclr/src/inc/sospriv.idl
index d5a5913f736fe5..770d5b56f749cc 100644
--- a/src/coreclr/src/inc/sospriv.idl
+++ b/src/coreclr/src/inc/sospriv.idl
@@ -409,3 +409,18 @@ interface ISOSDacInterface8 : IUnknown
HRESULT GetAssemblyLoadContext(CLRDATA_ADDRESS methodTable, CLRDATA_ADDRESS* assemblyLoadContext);
}
+
+// Increment anytime there is a change in the data structures that SOS depends on like
+// stress log structs (StressMsg, StressLogChunck, ThreadStressLog, etc), exception
+// stack traces (StackTraceElement), the PredefinedTlsSlots enums, etc.
+cpp_quote("#define SOS_BREAKING_CHANGE_VERSION 1")
+
+[
+ object,
+ local,
+ uuid(4eca42d8-7e7b-4c8a-a116-7bfbf6929267)
+]
+interface ISOSDacInterface9 : IUnknown
+{
+ HRESULT GetBreakingChangeVersion(int* pVersion);
+}
diff --git a/src/coreclr/src/inc/utilcode.h b/src/coreclr/src/inc/utilcode.h
index f02e58aeaf7db0..4ed456df94c7e1 100644
--- a/src/coreclr/src/inc/utilcode.h
+++ b/src/coreclr/src/inc/utilcode.h
@@ -1272,6 +1272,7 @@ class CPUGroupInfo
static WORD m_nProcessors;
static BOOL m_enableGCCPUGroups;
static BOOL m_threadUseAllCpuGroups;
+ static BOOL m_threadAssignCpuGroups;
static WORD m_initialGroup;
static CPU_Group_Info *m_CPUGroupInfoArray;
static bool s_hadSingleProcessorAtStartup;
@@ -1285,6 +1286,7 @@ class CPUGroupInfo
static void EnsureInitialized();
static BOOL CanEnableGCCPUGroups();
static BOOL CanEnableThreadUseAllCpuGroups();
+ static BOOL CanAssignCpuGroupsToThreads();
static WORD GetNumActiveProcessors();
static void GetGroupForProcessor(WORD processor_number,
WORD *group_number, WORD *group_processor_number);
@@ -4071,13 +4073,14 @@ HRESULT GetImageRuntimeVersionString(PVOID pMetaData, LPCSTR* pString);
// The registry keys and values that contain the information regarding
// the default registered unmanaged debugger.
//*****************************************************************************
-SELECTANY const WCHAR kDebugApplicationsPoliciesKey[] = W("SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications");
-SELECTANY const WCHAR kDebugApplicationsKey[] = W("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications");
-SELECTANY const WCHAR kUnmanagedDebuggerKey[] = W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug");
-SELECTANY const WCHAR kUnmanagedDebuggerValue[] = W("Debugger");
-SELECTANY const WCHAR kUnmanagedDebuggerAutoValue[] = W("Auto");
-SELECTANY const WCHAR kUnmanagedDebuggerAutoExclusionListKey[] = W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList");
+#define kDebugApplicationsPoliciesKey W("SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications")
+#define kDebugApplicationsKey W("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications")
+
+#define kUnmanagedDebuggerKey W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug")
+#define kUnmanagedDebuggerValue W("Debugger")
+#define kUnmanagedDebuggerAutoValue W("Auto")
+#define kUnmanagedDebuggerAutoExclusionListKey W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList")
BOOL GetRegistryLongValue(HKEY hKeyParent, // Parent key.
LPCWSTR szKey, // Key name to look at.
diff --git a/src/coreclr/src/inc/zapper.h b/src/coreclr/src/inc/zapper.h
index ba4f65b15dd916..b88d4d51b676fb 100644
--- a/src/coreclr/src/inc/zapper.h
+++ b/src/coreclr/src/inc/zapper.h
@@ -285,7 +285,7 @@ class Zapper
~Zapper();
- // The arguments control which native image of mscorlib to use.
+ // The arguments control which native image of CoreLib to use.
// This matters for hardbinding.
void InitEE(BOOL fForceDebug, BOOL fForceProfile, BOOL fForceInstrument);
void LoadAndInitializeJITForNgen(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT ICorJitCompiler** ppICorJitCompiler);
diff --git a/src/coreclr/src/interop/CMakeLists.txt b/src/coreclr/src/interop/CMakeLists.txt
index b8a0e769318db3..1642f55a04da5f 100644
--- a/src/coreclr/src/interop/CMakeLists.txt
+++ b/src/coreclr/src/interop/CMakeLists.txt
@@ -30,7 +30,10 @@ endif(WIN32)
convert_to_absolute_path(INTEROP_SOURCES ${INTEROP_SOURCES})
-add_library_clr(interop
+add_library_clr(interop_obj
OBJECT
${INTEROP_SOURCES}
)
+
+add_library(interop INTERFACE)
+target_sources(interop INTERFACE $)
\ No newline at end of file
diff --git a/src/coreclr/src/jit/CMakeLists.txt b/src/coreclr/src/jit/CMakeLists.txt
index 15aa4d59b63ccd..3f695823be4f63 100644
--- a/src/coreclr/src/jit/CMakeLists.txt
+++ b/src/coreclr/src/jit/CMakeLists.txt
@@ -54,6 +54,7 @@ set( JIT_SOURCES
instr.cpp
jitconfig.cpp
jiteh.cpp
+ jithashtable.cpp
jittelemetry.cpp
lclmorph.cpp
lclvars.cpp
diff --git a/src/coreclr/src/jit/_typeinfo.h b/src/coreclr/src/jit/_typeinfo.h
index 4aa38c540b220b..26173db3fae494 100644
--- a/src/coreclr/src/jit/_typeinfo.h
+++ b/src/coreclr/src/jit/_typeinfo.h
@@ -42,7 +42,7 @@ enum ti_types
namespace
{
#endif // _MSC_VER
-SELECTANY const char* g_ti_type_names_map[] = {
+const char* g_ti_type_names_map[] = {
#define DEF_TI(ti, nm) nm,
#include "titypes.h"
#undef DEF_TI
@@ -57,7 +57,7 @@ SELECTANY const char* g_ti_type_names_map[] = {
namespace
{
#endif // _MSC_VER
-SELECTANY const ti_types g_jit_types_map[] = {
+const ti_types g_jit_types_map[] = {
#define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) verType,
#include "typelist.h"
#undef DEF_TP
@@ -92,7 +92,7 @@ inline ti_types varType2tiType(var_types type)
namespace
{
#endif // _MSC_VER
-SELECTANY const ti_types g_ti_types_map[CORINFO_TYPE_COUNT] = {
+const ti_types g_ti_types_map[CORINFO_TYPE_COUNT] = {
// see the definition of enum CorInfoType in file inc/corinfo.h
TI_ERROR, // CORINFO_TYPE_UNDEF = 0x0,
TI_ERROR, // CORINFO_TYPE_VOID = 0x1,
diff --git a/src/coreclr/src/jit/codegen.h b/src/coreclr/src/jit/codegen.h
index d6e14d7a308c18..e876b155ce3546 100644
--- a/src/coreclr/src/jit/codegen.h
+++ b/src/coreclr/src/jit/codegen.h
@@ -341,12 +341,12 @@ class CodeGen final : public CodeGenInterface
void genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowestCalleeSavedOffset, int spDelta);
void genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, int lowestCalleeSavedOffset, int spDelta);
- void genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegModified);
+ void genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroed);
#else
void genPushCalleeSavedRegisters();
#endif
- void genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegModified, regMaskTP maskArgRegsLiveIn);
+ void genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn);
#if defined(TARGET_ARM)
@@ -434,18 +434,18 @@ class CodeGen final : public CodeGenInterface
void genZeroInitFltRegs(const regMaskTP& initFltRegs, const regMaskTP& initDblRegs, const regNumber& initReg);
- regNumber genGetZeroReg(regNumber initReg, bool* pInitRegModified);
+ regNumber genGetZeroReg(regNumber initReg, bool* pInitRegZeroed);
- void genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegModified);
+ void genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegZeroed);
- void genReportGenericContextArg(regNumber initReg, bool* pInitRegModified);
+ void genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed);
- void genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified);
+ void genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed);
void genFinalizeFrame();
#ifdef PROFILING_SUPPORTED
- void genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified);
+ void genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed);
void genProfilingLeaveCallback(unsigned helper);
#endif // PROFILING_SUPPORTED
@@ -511,7 +511,7 @@ class CodeGen final : public CodeGenInterface
void genFuncletEpilog();
void genCaptureFuncletPrologEpilogInfo();
- void genSetPSPSym(regNumber initReg, bool* pInitRegModified);
+ void genSetPSPSym(regNumber initReg, bool* pInitRegZeroed);
void genUpdateCurrentFunclet(BasicBlock* block);
#if defined(TARGET_ARM)
diff --git a/src/coreclr/src/jit/codegenarm.cpp b/src/coreclr/src/jit/codegenarm.cpp
index 0407c710e4041d..2eaa80862396dd 100644
--- a/src/coreclr/src/jit/codegenarm.cpp
+++ b/src/coreclr/src/jit/codegenarm.cpp
@@ -45,7 +45,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// if caller knows for certain the constant will fit.
//
// Return Value:
-// returns true if the immediate was too large and tmpReg was used and modified.
+// returns true if the immediate was small enough to be encoded inside instruction. If not,
+// returns false meaning the immediate was too large and tmpReg was used and modified.
//
bool CodeGen::genInstrWithConstant(
instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, ssize_t imm, insFlags flags, regNumber tmpReg)
@@ -100,7 +101,8 @@ bool CodeGen::genInstrWithConstant(
// tmpReg - an available temporary register
//
// Return Value:
-// true if `tmpReg` was used.
+// returns true if the immediate was small enough to be encoded inside instruction. If not,
+// returns false meaning the immediate was too large and tmpReg was used and modified.
//
bool CodeGen::genStackPointerAdjustment(ssize_t spDelta, regNumber tmpReg)
{
@@ -1650,14 +1652,14 @@ void CodeGen::genCodeForMulLong(GenTreeMultiRegOp* node)
// genProfilingEnterCallback: Generate the profiling function enter callback.
//
// Arguments:
-// initReg - register to use as scratch register
-// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if and only if
-// this call sets 'initReg' to a non-zero value.
+// initReg - register to use as scratch register
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is
+// not zero after this call.
//
// Return Value:
// None
//
-void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified)
+void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);
@@ -1690,7 +1692,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModifie
if (initReg == argReg)
{
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
}
@@ -1820,17 +1822,14 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper)
// Arguments:
// frameSize - the size of the stack frame being allocated.
// initReg - register to use as a scratch register.
-// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if
// this call sets 'initReg' to a non-zero value.
// maskArgRegsLiveIn - incoming argument registers that are currently live.
//
// Return value:
// None
//
-void CodeGen::genAllocLclFrame(unsigned frameSize,
- regNumber initReg,
- bool* pInitRegModified,
- regMaskTP maskArgRegsLiveIn)
+void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn)
{
assert(compiler->compGeneratingProlog);
@@ -1860,7 +1859,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize,
}
regSet.verifyRegUsed(initReg);
- *pInitRegModified = true;
+ *pInitRegZeroed = false; // The initReg does not contain zero
instGen_Set_Reg_To_Imm(EA_PTRSIZE, initReg, frameSize);
compiler->unwindPadding();
@@ -1880,7 +1879,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize,
if ((genRegMask(initReg) & (RBM_STACK_PROBE_HELPER_ARG | RBM_STACK_PROBE_HELPER_CALL_TARGET |
RBM_STACK_PROBE_HELPER_TRASH)) != RBM_NONE)
{
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
}
diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp
index 8ce7617de5d0ed..a85e2ce06bf957 100644
--- a/src/coreclr/src/jit/codegenarm64.cpp
+++ b/src/coreclr/src/jit/codegenarm64.cpp
@@ -156,7 +156,9 @@ void CodeGen::genStackPointerAdjustment(ssize_t spDelta, regNumber tmpReg, bool*
// Even though INS_add is specified here, the encoder will choose either
// an INS_add or an INS_sub and encode the immediate as a positive value
//
- if (genInstrWithConstant(INS_add, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, spDelta, tmpReg, true))
+ bool wasTempRegisterUsedForImm =
+ !genInstrWithConstant(INS_add, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, spDelta, tmpReg, true);
+ if (wasTempRegisterUsedForImm)
{
if (pTmpRegIsZero != nullptr)
{
@@ -4699,7 +4701,7 @@ void CodeGen::genStoreIndTypeSIMD12(GenTree* treeNode)
genConsumeOperands(treeNode->AsOp());
- // Need an addtional integer register to extract upper 4 bytes from data.
+ // Need an additional integer register to extract upper 4 bytes from data.
regNumber tmpReg = treeNode->GetSingleTempReg();
assert(tmpReg != addr->GetRegNum());
@@ -4766,16 +4768,13 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode)
{
assert((treeNode->OperGet() == GT_STORE_LCL_FLD) || (treeNode->OperGet() == GT_STORE_LCL_VAR));
- unsigned offs = 0;
- unsigned varNum = treeNode->AsLclVarCommon()->GetLclNum();
- assert(varNum < compiler->lvaCount);
+ GenTreeLclVarCommon* lclVar = treeNode->AsLclVarCommon();
- if (treeNode->OperGet() == GT_STORE_LCL_FLD)
- {
- offs = treeNode->AsLclFld()->GetLclOffs();
- }
+ unsigned offs = lclVar->GetLclOffs();
+ unsigned varNum = lclVar->GetLclNum();
+ assert(varNum < compiler->lvaCount);
- GenTree* op1 = treeNode->AsOp()->gtOp1;
+ GenTree* op1 = lclVar->gtGetOp1();
if (op1->isContained())
{
@@ -4792,8 +4791,8 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode)
}
regNumber operandReg = genConsumeReg(op1);
- // Need an addtional integer register to extract upper 4 bytes from data.
- regNumber tmpReg = treeNode->GetSingleTempReg();
+ // Need an additional integer register to extract upper 4 bytes from data.
+ regNumber tmpReg = lclVar->GetSingleTempReg();
// store lower 8 bytes
GetEmitter()->emitIns_S_R(INS_str, EA_8BYTE, operandReg, varNum, offs);
@@ -4813,14 +4812,14 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode)
// genProfilingEnterCallback: Generate the profiling function enter callback.
//
// Arguments:
-// initReg - register to use as scratch register
-// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if 'initReg' is
-// not zero after this call.
+// initReg - register to use as scratch register
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is
+// set to non-zero value after this call.
//
// Return Value:
// None
//
-void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified)
+void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);
@@ -4848,7 +4847,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModifie
if ((genRegMask(initReg) & RBM_PROFILER_ENTER_TRASH) != RBM_NONE)
{
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
}
@@ -9595,19 +9594,16 @@ void CodeGen::genArm64EmitterUnitTests()
// on Windows as well just to be consistent, even though it should not be necessary.
//
// Arguments:
-// frameSize - the size of the stack frame being allocated.
-// initReg - register to use as a scratch register.
-// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if
-// this call sets 'initReg' to a non-zero value.
-// maskArgRegsLiveIn - incoming argument registers that are currently live.
+// frameSize - the size of the stack frame being allocated.
+// initReg - register to use as a scratch register.
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if
+// this call sets 'initReg' to a non-zero value. Otherwise, it is unchanged.
+// maskArgRegsLiveIn - incoming argument registers that are currently live.
//
// Return value:
// None
//
-void CodeGen::genAllocLclFrame(unsigned frameSize,
- regNumber initReg,
- bool* pInitRegModified,
- regMaskTP maskArgRegsLiveIn)
+void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn)
{
assert(compiler->compGeneratingProlog);
@@ -9644,7 +9640,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize,
instGen_Set_Reg_To_Imm(EA_PTRSIZE, initReg, -(ssize_t)probeOffset);
GetEmitter()->emitIns_R_R_R(INS_ldr, EA_4BYTE, REG_ZR, REG_SPBASE, initReg);
regSet.verifyRegUsed(initReg);
- *pInitRegModified = true;
+ *pInitRegZeroed = false; // The initReg does not contain zero
lastTouchDelta -= pageSize;
}
@@ -9704,7 +9700,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize,
GetEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, rLimit, rOffset); // If equal, we need to probe again
GetEmitter()->emitIns_J(INS_bls, NULL, -4);
- *pInitRegModified = true;
+ *pInitRegZeroed = false; // The initReg does not contain zero
compiler->unwindPadding();
@@ -9719,7 +9715,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize,
compiler->unwindPadding();
regSet.verifyRegUsed(initReg);
- *pInitRegModified = true;
+ *pInitRegZeroed = false; // The initReg does not contain zero
}
}
diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp
index 7dd95d2fdab6b8..c1dcc7319afca8 100644
--- a/src/coreclr/src/jit/codegenarmarch.cpp
+++ b/src/coreclr/src/jit/codegenarmarch.cpp
@@ -561,14 +561,14 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla
// genSetGSSecurityCookie: Set the "GS" security cookie in the prolog.
//
// Arguments:
-// initReg - register to use as a scratch register
-// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if
-// this call sets 'initReg' to a non-zero value.
+// initReg - register to use as a scratch register
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if
+// this call sets 'initReg' to a non-zero value.
//
// Return Value:
// None
//
-void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified)
+void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);
@@ -593,7 +593,7 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified)
GetEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, initReg, compiler->lvaGSSecurityCookie, 0);
}
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
//---------------------------------------------------------------------
@@ -616,31 +616,31 @@ void CodeGen::genIntrinsic(GenTree* treeNode)
// Right now only Abs/Ceiling/Floor/Round/Sqrt are treated as math intrinsics.
//
- switch (treeNode->AsIntrinsic()->gtIntrinsicId)
+ switch (treeNode->AsIntrinsic()->gtIntrinsicName)
{
- case CORINFO_INTRINSIC_Abs:
+ case NI_System_Math_Abs:
genConsumeOperands(treeNode->AsOp());
GetEmitter()->emitInsBinary(INS_ABS, emitActualTypeSize(treeNode), treeNode, srcNode);
break;
#ifdef TARGET_ARM64
- case CORINFO_INTRINSIC_Ceiling:
+ case NI_System_Math_Ceiling:
genConsumeOperands(treeNode->AsOp());
GetEmitter()->emitInsBinary(INS_frintp, emitActualTypeSize(treeNode), treeNode, srcNode);
break;
- case CORINFO_INTRINSIC_Floor:
+ case NI_System_Math_Floor:
genConsumeOperands(treeNode->AsOp());
GetEmitter()->emitInsBinary(INS_frintm, emitActualTypeSize(treeNode), treeNode, srcNode);
break;
- case CORINFO_INTRINSIC_Round:
+ case NI_System_Math_Round:
genConsumeOperands(treeNode->AsOp());
GetEmitter()->emitInsBinary(INS_frintn, emitActualTypeSize(treeNode), treeNode, srcNode);
break;
#endif // TARGET_ARM64
- case CORINFO_INTRINSIC_Sqrt:
+ case NI_System_Math_Sqrt:
genConsumeOperands(treeNode->AsOp());
GetEmitter()->emitInsBinary(INS_SQRT, emitActualTypeSize(treeNode), treeNode, srcNode);
break;
@@ -815,11 +815,15 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
// so update 'source' to point this GT_LCL_VAR_ADDR node
// and continue to the codegen for the LCL_VAR node below
//
+ assert(addrNode->isContained());
varNode = addrNode->AsLclVarCommon();
addrNode = nullptr;
}
else // addrNode is used
{
+ // TODO-Cleanup: `Lowering::NewPutArg` marks only `LCL_VAR_ADDR` as contained nowadays,
+ // but we use `genConsumeAddress` as a precaution, use `genConsumeReg()` instead.
+ assert(!addrNode->isContained());
// Generate code to load the address that we need into a register
genConsumeAddress(addrNode);
addrReg = addrNode->GetRegNum();
@@ -1253,6 +1257,7 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)
if (varNode != nullptr)
{
+ assert(varNode->isContained());
srcVarNum = varNode->GetLclNum();
assert(srcVarNum < compiler->lvaCount);
@@ -1270,6 +1275,9 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)
else // addrNode is used
{
assert(addrNode != nullptr);
+ // TODO-Cleanup: `Lowering::NewPutArg` marks only `LCL_VAR_ADDR` as contained nowadays,
+ // but we use `genConsumeAddress` as a precaution, use `genConsumeReg()` instead.
+ assert(!addrNode->isContained());
// Generate code to load the address that we need into a register
genConsumeAddress(addrNode);
@@ -1959,11 +1967,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node)
{
assert(dstAddr->OperIsLocalAddr());
dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum();
-
- if (dstAddr->OperIs(GT_LCL_FLD_ADDR))
- {
- dstOffset = dstAddr->AsLclFld()->GetLclOffs();
- }
+ dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs();
}
regNumber srcReg;
@@ -2095,11 +2099,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
assert(dstAddr->OperIsLocalAddr());
dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum();
-
- if (dstAddr->OperIs(GT_LCL_FLD_ADDR))
- {
- dstOffset = dstAddr->AsLclFld()->GetLclOffs();
- }
+ dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs();
}
unsigned srcLclNum = BAD_VAR_NUM;
@@ -2112,11 +2112,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
if (src->OperIs(GT_LCL_VAR, GT_LCL_FLD))
{
srcLclNum = src->AsLclVarCommon()->GetLclNum();
-
- if (src->OperIs(GT_LCL_FLD))
- {
- srcOffset = src->AsLclFld()->GetLclOffs();
- }
+ srcOffset = src->AsLclVarCommon()->GetLclOffs();
}
else
{
@@ -2136,11 +2132,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
{
assert(srcAddr->OperIsLocalAddr());
srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum();
-
- if (srcAddr->OperIs(GT_LCL_FLD_ADDR))
- {
- srcOffset = srcAddr->AsLclFld()->GetLclOffs();
- }
+ srcOffset = srcAddr->AsLclVarCommon()->GetLclOffs();
}
}
diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp
index ccfd7567f46ae6..5923e6512f406e 100644
--- a/src/coreclr/src/jit/codegencommon.cpp
+++ b/src/coreclr/src/jit/codegencommon.cpp
@@ -4821,7 +4821,7 @@ void CodeGen::genCheckUseBlockInit()
*/
#if defined(TARGET_ARM64)
-void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegModified)
+void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroed)
#else
void CodeGen::genPushCalleeSavedRegisters()
#endif
@@ -4873,7 +4873,7 @@ void CodeGen::genPushCalleeSavedRegisters()
// - Generate fully interruptible code for loops that contains calls
// - Generate fully interruptible code for leaf methods
//
- // Given the limited benefit from this optimization (<10k for mscorlib NGen image), the extra complexity
+ // Given the limited benefit from this optimization (<10k for CoreLib NGen image), the extra complexity
// is not worth it.
//
rsPushRegs |= RBM_LR; // We must save the return address (in the LR register)
@@ -5310,8 +5310,7 @@ void CodeGen::genPushCalleeSavedRegisters()
JITDUMP(" spAdjustment2=%d\n", spAdjustment2);
- genPrologSaveRegPair(REG_FP, REG_LR, alignmentAdjustment2, -spAdjustment2, false, initReg,
- pInitRegModified);
+ genPrologSaveRegPair(REG_FP, REG_LR, alignmentAdjustment2, -spAdjustment2, false, initReg, pInitRegZeroed);
offset += spAdjustment2;
// Now subtract off the #outsz (or the rest of the #outsz if it was unaligned, and the above "sub"
@@ -5331,13 +5330,13 @@ void CodeGen::genPushCalleeSavedRegisters()
// We've already established the frame pointer, so no need to report the stack pointer change to unwind
// info.
- genStackPointerAdjustment(-spAdjustment3, initReg, pInitRegModified, /* reportUnwindData */ false);
+ genStackPointerAdjustment(-spAdjustment3, initReg, pInitRegZeroed, /* reportUnwindData */ false);
offset += spAdjustment3;
}
else
{
genPrologSaveRegPair(REG_FP, REG_LR, compiler->lvaOutgoingArgSpaceSize, -remainingFrameSz, false, initReg,
- pInitRegModified);
+ pInitRegZeroed);
offset += remainingFrameSz;
offsetSpToSavedFp = compiler->lvaOutgoingArgSpaceSize;
@@ -5369,7 +5368,7 @@ void CodeGen::genPushCalleeSavedRegisters()
JITDUMP(" remainingFrameSz=%d\n", remainingFrameSz);
// We've already established the frame pointer, so no need to report the stack pointer change to unwind info.
- genStackPointerAdjustment(-remainingFrameSz, initReg, pInitRegModified, /* reportUnwindData */ false);
+ genStackPointerAdjustment(-remainingFrameSz, initReg, pInitRegZeroed, /* reportUnwindData */ false);
offset += remainingFrameSz;
}
else
@@ -6098,17 +6097,17 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog)
#endif // TARGET*
-// We need a register with value zero. Zero the initReg, if necessary, and set *pInitRegModified if so.
+// We need a register with value zero. Zero the initReg, if necessary, and set *pInitRegZeroed if so.
// Return the register to use. On ARM64, we never touch the initReg, and always just return REG_ZR.
-regNumber CodeGen::genGetZeroReg(regNumber initReg, bool* pInitRegModified)
+regNumber CodeGen::genGetZeroReg(regNumber initReg, bool* pInitRegZeroed)
{
#ifdef TARGET_ARM64
return REG_ZR;
#else // !TARGET_ARM64
- if (*pInitRegModified)
+ if (*pInitRegZeroed == false)
{
instGen_Set_Reg_To_Zero(EA_PTRSIZE, initReg);
- *pInitRegModified = false;
+ *pInitRegZeroed = true;
}
return initReg;
#endif // !TARGET_ARM64
@@ -6118,14 +6117,14 @@ regNumber CodeGen::genGetZeroReg(regNumber initReg, bool* pInitRegModified)
// genZeroInitFrame: Zero any untracked pointer locals and/or initialize memory for locspace
//
// Arguments:
-// untrLclHi - (Untracked locals High-Offset) The upper bound offset at which the zero init
-// code will end initializing memory (not inclusive).
-// untrLclLo - (Untracked locals Low-Offset) The lower bound at which the zero init code will
-// start zero initializing memory.
-// initReg - A scratch register (that gets set to zero on some platforms).
-// pInitRegModified - Sets a flag that tells the callee whether or not the initReg register got zeroed.
-//
-void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegModified)
+// untrLclHi - (Untracked locals High-Offset) The upper bound offset at which the zero init
+// code will end initializing memory (not inclusive).
+// untrLclLo - (Untracked locals Low-Offset) The lower bound at which the zero init code will
+// start zero initializing memory.
+// initReg - A scratch register (that gets set to zero on some platforms).
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'true' if this method sets initReg register to zero,
+// 'false' if initReg was set to a non-zero value, and left unchanged if initReg was not touched.
+void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);
@@ -6200,8 +6199,8 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
#else // !define(TARGET_ARM)
- rAddr = initReg;
- *pInitRegModified = true;
+ rAddr = initReg;
+ *pInitRegZeroed = false;
#endif // !defined(TARGET_ARM)
@@ -6242,7 +6241,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
// Load immediate into the InitReg register
instGen_Set_Reg_To_Imm(EA_PTRSIZE, initReg, (ssize_t)untrLclLo);
GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, rAddr, genFramePointerReg(), initReg);
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
if (useLoop)
@@ -6254,7 +6253,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
}
#if defined(TARGET_ARM)
- rZero1 = genGetZeroReg(initReg, pInitRegModified);
+ rZero1 = genGetZeroReg(initReg, pInitRegZeroed);
instGen_Set_Reg_To_Zero(EA_PTRSIZE, rZero2);
target_ssize_t stmImm = (target_ssize_t)(genRegMask(rZero1) | genRegMask(rZero2));
#endif // TARGET_ARM
@@ -6343,7 +6342,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
#endif
if (blkSize < minSimdSize)
{
- zeroReg = genGetZeroReg(initReg, pInitRegModified);
+ zeroReg = genGetZeroReg(initReg, pInitRegZeroed);
int i = 0;
for (; i + REGSIZE_BYTES <= blkSize; i += REGSIZE_BYTES)
@@ -6405,7 +6404,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
assert(alignmentLoBlkSize < XMM_REGSIZE_BYTES);
assert((alignedLclLo - alignmentLoBlkSize) == untrLclLo);
- zeroReg = genGetZeroReg(initReg, pInitRegModified);
+ zeroReg = genGetZeroReg(initReg, pInitRegZeroed);
int i = 0;
for (; i + REGSIZE_BYTES <= alignmentLoBlkSize; i += REGSIZE_BYTES)
@@ -6513,7 +6512,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
emit->emitIns_J(INS_jne, nullptr, -5);
// initReg will be zero at end of the loop
- *pInitRegModified = false;
+ *pInitRegZeroed = true;
}
if (untrLclHi != alignedLclHi)
@@ -6522,7 +6521,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
assert(alignmentHiBlkSize < XMM_REGSIZE_BYTES);
assert((alignedLclHi + alignmentHiBlkSize) == untrLclHi);
- zeroReg = genGetZeroReg(initReg, pInitRegModified);
+ zeroReg = genGetZeroReg(initReg, pInitRegZeroed);
int i = 0;
for (; i + REGSIZE_BYTES <= alignmentHiBlkSize; i += REGSIZE_BYTES)
@@ -6589,13 +6588,13 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
if (layout->IsGCPtr(i))
{
GetEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE,
- genGetZeroReg(initReg, pInitRegModified), varNum, i * REGSIZE_BYTES);
+ genGetZeroReg(initReg, pInitRegZeroed), varNum, i * REGSIZE_BYTES);
}
}
}
else
{
- regNumber zeroReg = genGetZeroReg(initReg, pInitRegModified);
+ regNumber zeroReg = genGetZeroReg(initReg, pInitRegZeroed);
// zero out the whole thing rounded up to a single stack slot size
unsigned lclSize = roundUp(compiler->lvaLclSize(varNum), (unsigned)sizeof(int));
@@ -6627,7 +6626,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
// printf("initialize untracked spillTmp [EBP-%04X]\n", stkOffs);
- inst_ST_RV(ins_Store(TYP_I_IMPL), tempThis, 0, genGetZeroReg(initReg, pInitRegModified), TYP_I_IMPL);
+ inst_ST_RV(ins_Store(TYP_I_IMPL), tempThis, 0, genGetZeroReg(initReg, pInitRegZeroed), TYP_I_IMPL);
}
}
@@ -6762,7 +6761,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
* ICodeManager::GetParamTypeArg().
*/
-void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegModified)
+void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed)
{
// For OSR the original method has set this up for us.
if (compiler->opts.IsOSR())
@@ -6827,8 +6826,8 @@ void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegModifi
// We will just use the initReg since it is an available register
// and we are probably done using it anyway...
- reg = initReg;
- *pInitRegModified = true;
+ reg = initReg;
+ *pInitRegZeroed = false;
// mov reg, [compiler->info.compTypeCtxtArg]
GetEmitter()->emitIns_R_AR(ins_Load(TYP_I_IMPL), EA_PTRSIZE, reg, genFramePointerReg(), varDsc->lvStkOffs);
@@ -7672,9 +7671,13 @@ void CodeGen::genFnProlog()
/* Choose the register to use for zero initialization */
- regNumber initReg = REG_SCRATCH; // Unless we find a better register below
- bool initRegModified = true;
- regMaskTP excludeMask = intRegState.rsCalleeRegArgMaskLiveIn;
+ regNumber initReg = REG_SCRATCH; // Unless we find a better register below
+
+ // Track if initReg holds non-zero value. Start conservative and assume it has non-zero value.
+ // If initReg is ever set to zero, this variable is set to true and zero initializing initReg
+ // will be skipped.
+ bool initRegZeroed = false;
+ regMaskTP excludeMask = intRegState.rsCalleeRegArgMaskLiveIn;
regMaskTP tempMask;
// We should not use the special PINVOKE registers as the initReg
@@ -7807,11 +7810,11 @@ void CodeGen::genFnProlog()
// been calculated to be one of the callee-saved registers (say, if all the integer argument registers are
// in use, and perhaps with other conditions being satisfied). This is ok in other cases, after the callee-saved
// registers have been saved. So instead of letting genAllocLclFrame use initReg as a temporary register,
- // always use REG_SCRATCH. We don't care if it trashes it, so ignore the initRegModified output argument.
- bool ignoreInitRegModified = true;
- genAllocLclFrame(compiler->compLclFrameSize, REG_SCRATCH, &ignoreInitRegModified,
+ // always use REG_SCRATCH. We don't care if it trashes it, so ignore the initRegZeroed output argument.
+ bool ignoreInitRegZeroed = false;
+ genAllocLclFrame(compiler->compLclFrameSize, REG_SCRATCH, &ignoreInitRegZeroed,
intRegState.rsCalleeRegArgMaskLiveIn);
- genPushCalleeSavedRegisters(initReg, &initRegModified);
+ genPushCalleeSavedRegisters(initReg, &initRegZeroed);
#else // !TARGET_ARM64
genPushCalleeSavedRegisters();
#endif // !TARGET_ARM64
@@ -7855,7 +7858,7 @@ void CodeGen::genFnProlog()
if (maskStackAlloc == RBM_NONE)
{
- genAllocLclFrame(compiler->compLclFrameSize, initReg, &initRegModified, intRegState.rsCalleeRegArgMaskLiveIn);
+ genAllocLclFrame(compiler->compLclFrameSize, initReg, &initRegZeroed, intRegState.rsCalleeRegArgMaskLiveIn);
}
#endif // !TARGET_ARM64
@@ -7918,11 +7921,11 @@ void CodeGen::genFnProlog()
// Zero out the frame as needed
//
- genZeroInitFrame(untrLclHi, untrLclLo, initReg, &initRegModified);
+ genZeroInitFrame(untrLclHi, untrLclLo, initReg, &initRegZeroed);
#if defined(FEATURE_EH_FUNCLETS)
- genSetPSPSym(initReg, &initRegModified);
+ genSetPSPSym(initReg, &initRegZeroed);
#else // !FEATURE_EH_FUNCLETS
@@ -7935,10 +7938,10 @@ void CodeGen::genFnProlog()
// Zero out the slot for nesting level 0
unsigned firstSlotOffs = filterEndOffsetSlotOffs - TARGET_POINTER_SIZE;
- if (initRegModified)
+ if (!initRegZeroed)
{
instGen_Set_Reg_To_Zero(EA_PTRSIZE, initReg);
- initRegModified = false;
+ initRegZeroed = true;
}
GetEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, initReg, compiler->lvaShadowSPslotsVar,
@@ -7947,7 +7950,7 @@ void CodeGen::genFnProlog()
#endif // !FEATURE_EH_FUNCLETS
- genReportGenericContextArg(initReg, &initRegModified);
+ genReportGenericContextArg(initReg, &initRegZeroed);
#ifdef JIT32_GCENCODER
// Initialize the LocalAllocSP slot if there is localloc in the function.
@@ -7959,7 +7962,7 @@ void CodeGen::genFnProlog()
// Set up the GS security cookie
- genSetGSSecurityCookie(initReg, &initRegModified);
+ genSetGSSecurityCookie(initReg, &initRegZeroed);
#ifdef PROFILING_SUPPORTED
@@ -7967,7 +7970,7 @@ void CodeGen::genFnProlog()
// OSR methods aren't called, so don't have enter hooks.
if (!compiler->opts.IsOSR())
{
- genProfilingEnterCallback(initReg, &initRegModified);
+ genProfilingEnterCallback(initReg, &initRegZeroed);
}
#endif // PROFILING_SUPPORTED
@@ -8029,15 +8032,15 @@ void CodeGen::genFnProlog()
}
else
{
- xtraReg = REG_SCRATCH;
- initRegModified = true;
+ xtraReg = REG_SCRATCH;
+ initRegZeroed = false;
}
genFnPrologCalleeRegArgs(xtraReg, &xtraRegClobbered, regState);
if (xtraRegClobbered)
{
- initRegModified = true;
+ initRegZeroed = false;
}
}
}
@@ -8057,7 +8060,7 @@ void CodeGen::genFnProlog()
if (regMask & initRegs)
{
// Check if we have already zeroed this register
- if ((reg == initReg) && !initRegModified)
+ if ((reg == initReg) && initRegZeroed)
{
continue;
}
@@ -8066,7 +8069,7 @@ void CodeGen::genFnProlog()
instGen_Set_Reg_To_Zero(EA_PTRSIZE, reg);
if (reg == initReg)
{
- initRegModified = false;
+ initRegZeroed = true;
}
}
}
@@ -8078,17 +8081,17 @@ void CodeGen::genFnProlog()
// If initReg is not in initRegs then we will use REG_SCRATCH
if ((genRegMask(initReg) & initRegs) == 0)
{
- initReg = REG_SCRATCH;
- initRegModified = true;
+ initReg = REG_SCRATCH;
+ initRegZeroed = false;
}
#ifdef TARGET_ARM
// This is needed only for Arm since it can use a zero initialized int register
// to initialize vfp registers.
- if (initRegModified)
+ if (!initRegZeroed)
{
instGen_Set_Reg_To_Zero(EA_PTRSIZE, initReg);
- initRegModified = false;
+ initRegZeroed = true;
}
#endif // TARGET_ARM
@@ -9095,12 +9098,12 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
maskArgRegsLiveIn = RBM_R0;
}
- regNumber initReg = REG_R3; // R3 is never live on entry to a funclet, so it can be trashed
- bool initRegModified = true;
+ regNumber initReg = REG_R3; // R3 is never live on entry to a funclet, so it can be trashed
+ bool initRegZeroed = false;
if (maskStackAlloc == RBM_NONE)
{
- genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegModified, maskArgRegsLiveIn);
+ genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegZeroed, maskArgRegsLiveIn);
}
// This is the end of the OS-reported prolog for purposes of unwinding
@@ -9397,10 +9400,10 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
maskArgRegsLiveIn = RBM_ARG_0 | RBM_ARG_2;
}
- regNumber initReg = REG_EBP; // We already saved EBP, so it can be trashed
- bool initRegModified = true;
+ regNumber initReg = REG_EBP; // We already saved EBP, so it can be trashed
+ bool initRegZeroed = false;
- genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegModified, maskArgRegsLiveIn);
+ genAllocLclFrame(genFuncletInfo.fiSpDelta, initReg, &initRegZeroed, maskArgRegsLiveIn);
// Callee saved float registers are copied to stack in their assigned stack slots
// after allocating space for them as part of funclet frame.
@@ -9739,7 +9742,7 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
* correctly reported, the PSPSym could be omitted in some cases.)
***********************************
*/
-void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegModified)
+void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);
@@ -9785,8 +9788,8 @@ void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegModified)
// We will just use the initReg since it is an available register
// and we are probably done using it anyway...
- regNumber regTmp = initReg;
- *pInitRegModified = true;
+ regNumber regTmp = initReg;
+ *pInitRegZeroed = false;
GetEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, regTmp, regBase, callerSPOffs);
GetEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, regTmp, compiler->lvaPSPSym, 0);
@@ -9797,8 +9800,8 @@ void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegModified)
// We will just use the initReg since it is an available register
// and we are probably done using it anyway...
- regNumber regTmp = initReg;
- *pInitRegModified = true;
+ regNumber regTmp = initReg;
+ *pInitRegZeroed = false;
GetEmitter()->emitIns_R_R_Imm(INS_add, EA_PTRSIZE, regTmp, REG_SPBASE, SPtoCallerSPdelta);
GetEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, regTmp, compiler->lvaPSPSym, 0);
diff --git a/src/coreclr/src/jit/codegenlinear.cpp b/src/coreclr/src/jit/codegenlinear.cpp
index 94306e936549fe..cf0d1cd149a00a 100644
--- a/src/coreclr/src/jit/codegenlinear.cpp
+++ b/src/coreclr/src/jit/codegenlinear.cpp
@@ -344,7 +344,6 @@ void CodeGen::genCodeForBBlist()
needLabel = true;
}
-#if defined(DEBUG) || defined(LATE_DISASM)
// We also want to start a new Instruction group by calling emitAddLabel below,
// when we need accurate bbWeights for this block in the emitter. We force this
// whenever our previous block was a BBJ_COND and it has a different weight than us.
@@ -356,7 +355,6 @@ void CodeGen::genCodeForBBlist()
{
needLabel = true;
}
-#endif // DEBUG || LATE_DISASM
if (needLabel)
{
@@ -1741,15 +1739,11 @@ void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode,
{
// The OperLocalAddr is always contained.
assert(srcAddr->isContained());
- GenTreeLclVarCommon* lclNode = srcAddr->AsLclVarCommon();
+ const GenTreeLclVarCommon* lclNode = srcAddr->AsLclVarCommon();
// Generate LEA instruction to load the LclVar address in RSI.
// Source is known to be on the stack. Use EA_PTRSIZE.
- unsigned int offset = 0;
- if (srcAddr->OperGet() == GT_LCL_FLD_ADDR)
- {
- offset = srcAddr->AsLclFld()->GetLclOffs();
- }
+ unsigned int offset = lclNode->GetLclOffs();
GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, lclNode->GetLclNum(), offset);
}
else
diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp
index 207cef87d94e38..88c021ac73d016 100644
--- a/src/coreclr/src/jit/codegenxarch.cpp
+++ b/src/coreclr/src/jit/codegenxarch.cpp
@@ -53,14 +53,14 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla
// genSetGSSecurityCookie: Set the "GS" security cookie in the prolog.
//
// Arguments:
-// initReg - register to use as a scratch register
-// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if
-// this call sets 'initReg' to a non-zero value.
+// initReg - register to use as a scratch register
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if
+// this call sets 'initReg' to a non-zero value.
//
// Return Value:
// None
//
-void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified)
+void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);
@@ -84,7 +84,7 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified)
// initReg = #GlobalSecurityCookieVal64; [frame.GSSecurityCookie] = initReg
genSetRegToIcon(initReg, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL);
GetEmitter()->emitIns_S_R(INS_mov, EA_PTRSIZE, initReg, compiler->lvaGSSecurityCookie, 0);
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
else
#endif
@@ -105,7 +105,7 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegModified)
GetEmitter()->emitIns_S_R(INS_mov, EA_PTRSIZE, REG_EAX, compiler->lvaGSSecurityCookie, 0);
if (initReg == REG_EAX)
{
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
}
}
@@ -1950,19 +1950,16 @@ void CodeGen::genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode)
// genAllocLclFrame: Probe the stack and allocate the local stack frame - subtract from SP.
//
// Arguments:
-// frameSize - the size of the stack frame being allocated.
-// initReg - register to use as a scratch register.
-// pInitRegModified - OUT parameter. *pInitRegModified is set to 'true' if and only if
-// this call sets 'initReg' to a non-zero value.
-// maskArgRegsLiveIn - incoming argument registers that are currently live.
+// frameSize - the size of the stack frame being allocated.
+// initReg - register to use as a scratch register.
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if
+// this call sets 'initReg' to a non-zero value.
+// maskArgRegsLiveIn - incoming argument registers that are currently live.
//
// Return value:
// None
//
-void CodeGen::genAllocLclFrame(unsigned frameSize,
- regNumber initReg,
- bool* pInitRegModified,
- regMaskTP maskArgRegsLiveIn)
+void CodeGen::genAllocLclFrame(unsigned frameSize, regNumber initReg, bool* pInitRegZeroed, regMaskTP maskArgRegsLiveIn)
{
assert(compiler->compGeneratingProlog);
@@ -2046,7 +2043,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize,
if (initReg == REG_DEFAULT_HELPER_CALL_TARGET)
{
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
static_assert_no_msg((RBM_STACK_PROBE_HELPER_TRASH & RBM_STACK_PROBE_HELPER_ARG) == RBM_NONE);
@@ -2056,7 +2053,7 @@ void CodeGen::genAllocLclFrame(unsigned frameSize,
if (initReg == REG_STACK_PROBE_HELPER_ARG)
{
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
}
@@ -2694,11 +2691,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node)
{
assert(dstAddr->OperIsLocalAddr());
dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum();
-
- if (dstAddr->OperIs(GT_LCL_FLD_ADDR))
- {
- dstOffset = dstAddr->AsLclFld()->GetLclOffs();
- }
+ dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs();
}
regNumber srcIntReg = REG_NA;
@@ -2819,11 +2812,9 @@ void CodeGen::genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst
if (baseNode->OperIsLocalAddr())
{
- if (baseNode->gtOper == GT_LCL_FLD_ADDR)
- {
- offset += baseNode->AsLclFld()->GetLclOffs();
- }
- emit->emitIns_R_S(ins, size, dst, baseNode->AsLclVarCommon()->GetLclNum(), offset);
+ const GenTreeLclVarCommon* lclVar = baseNode->AsLclVarCommon();
+ offset += lclVar->GetLclOffs();
+ emit->emitIns_R_S(ins, size, dst, lclVar->GetLclNum(), offset);
}
else
{
@@ -2873,12 +2864,9 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
else
{
assert(dstAddr->OperIsLocalAddr());
- dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum();
-
- if (dstAddr->OperIs(GT_LCL_FLD_ADDR))
- {
- dstOffset = dstAddr->AsLclFld()->GetLclOffs();
- }
+ const GenTreeLclVarCommon* lclVar = dstAddr->AsLclVarCommon();
+ dstLclNum = lclVar->GetLclNum();
+ dstOffset = lclVar->GetLclOffs();
}
unsigned srcLclNum = BAD_VAR_NUM;
@@ -2893,11 +2881,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
if (src->OperIs(GT_LCL_VAR, GT_LCL_FLD))
{
srcLclNum = src->AsLclVarCommon()->GetLclNum();
-
- if (src->OperIs(GT_LCL_FLD))
- {
- srcOffset = src->AsLclFld()->GetLclOffs();
- }
+ srcOffset = src->AsLclVarCommon()->GetLclOffs();
}
else
{
@@ -2929,11 +2913,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
{
assert(srcAddr->OperIsLocalAddr());
srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum();
-
- if (srcAddr->OperIs(GT_LCL_FLD_ADDR))
- {
- srcOffset = srcAddr->AsLclFld()->GetLclOffs();
- }
+ srcOffset = srcAddr->AsLclVarCommon()->GetLclOffs();
}
}
@@ -6798,7 +6778,7 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode)
break;
case GT_INTRINSIC:
- assert(treeNode->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Abs);
+ assert(treeNode->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Abs);
// Abs(x) = set sign-bit to zero
// Abs(f) = f & 0x7fffffff
@@ -6876,7 +6856,7 @@ void CodeGen::genSSE2BitwiseOp(GenTree* treeNode)
// ii) treeNode oper is a GT_INTRINSIC
// iii) treeNode type is a floating point type
// iv) treeNode is not used from memory
-// v) tree oper is CORINFO_INTRINSIC_Round, _Ceiling, or _Floor
+// v) tree oper is NI_System_Math{F}_Round, _Ceiling, or _Floor
// vi) caller of this routine needs to call genProduceReg()
void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode)
{
@@ -6904,18 +6884,18 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode)
unsigned ival = 0;
- // v) tree oper is CORINFO_INTRINSIC_Round, _Ceiling, or _Floor
- switch (treeNode->AsIntrinsic()->gtIntrinsicId)
+ // v) tree oper is NI_System_Math{F}_Round, _Ceiling, or _Floor
+ switch (treeNode->AsIntrinsic()->gtIntrinsicName)
{
- case CORINFO_INTRINSIC_Round:
+ case NI_System_Math_Round:
ival = 4;
break;
- case CORINFO_INTRINSIC_Ceiling:
+ case NI_System_Math_Ceiling:
ival = 10;
break;
- case CORINFO_INTRINSIC_Floor:
+ case NI_System_Math_Floor:
ival = 9;
break;
@@ -6951,9 +6931,11 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode)
switch (memBase->OperGet())
{
case GT_LCL_VAR_ADDR:
+ case GT_LCL_FLD_ADDR:
{
+ assert(memBase->isContained());
varNum = memBase->AsLclVarCommon()->GetLclNum();
- offset = 0;
+ offset = memBase->AsLclVarCommon()->GetLclOffs();
// Ensure that all the GenTreeIndir values are set to their defaults.
assert(memBase->GetRegNum() == REG_NA);
@@ -7037,9 +7019,9 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode)
void CodeGen::genIntrinsic(GenTree* treeNode)
{
// Right now only Sqrt/Abs are treated as math intrinsics.
- switch (treeNode->AsIntrinsic()->gtIntrinsicId)
+ switch (treeNode->AsIntrinsic()->gtIntrinsicName)
{
- case CORINFO_INTRINSIC_Sqrt:
+ case NI_System_Math_Sqrt:
{
// Both operand and its result must be of the same floating point type.
GenTree* srcNode = treeNode->AsOp()->gtOp1;
@@ -7051,13 +7033,13 @@ void CodeGen::genIntrinsic(GenTree* treeNode)
break;
}
- case CORINFO_INTRINSIC_Abs:
+ case NI_System_Math_Abs:
genSSE2BitwiseOp(treeNode);
break;
- case CORINFO_INTRINSIC_Round:
- case CORINFO_INTRINSIC_Ceiling:
- case CORINFO_INTRINSIC_Floor:
+ case NI_System_Math_Round:
+ case NI_System_Math_Ceiling:
+ case NI_System_Math_Floor:
genSSE41RoundOp(treeNode->AsOp());
break;
@@ -7941,11 +7923,8 @@ void CodeGen::genPutStructArgStk(GenTreePutArgStk* putArgStk)
{
assert(srcAddr->OperIsLocalAddr());
- srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum();
- if (srcAddr->OperGet() == GT_LCL_FLD_ADDR)
- {
- srcLclOffset = srcAddr->AsLclFld()->GetLclOffs();
- }
+ srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum();
+ srcLclOffset = srcAddr->AsLclVarCommon()->GetLclOffs();
}
for (int i = numSlots - 1; i >= 0; --i)
@@ -8470,9 +8449,8 @@ void CodeGen::genAmd64EmitterUnitTests()
// genProfilingEnterCallback: Generate the profiling function enter callback.
//
// Arguments:
-// initReg - register to use as scratch register
-// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if 'initReg' is
-// not zero after this call.
+// initReg - register to use as scratch register
+// pInitRegZeroed - OUT parameter. This variable remains unchanged.
//
// Return Value:
// None
@@ -8491,7 +8469,7 @@ void CodeGen::genAmd64EmitterUnitTests()
// 4. All registers are preserved.
// 5. The helper pops the FunctionIDOrClientID argument from the stack.
//
-void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified)
+void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);
@@ -8636,14 +8614,14 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper)
// genProfilingEnterCallback: Generate the profiling function enter callback.
//
// Arguments:
-// initReg - register to use as scratch register
-// pInitRegModified - OUT parameter. *pInitRegModified set to 'true' if 'initReg' is
-// not zero after this call.
+// initReg - register to use as scratch register
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if
+// this call sets 'initReg' to a non-zero value.
//
// Return Value:
// None
//
-void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModified)
+void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);
@@ -8780,7 +8758,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModifie
// If initReg is one of RBM_CALLEE_TRASH, then it needs to be zero'ed before using.
if ((RBM_CALLEE_TRASH & genRegMask(initReg)) != 0)
{
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
#else // !defined(UNIX_AMD64_ABI)
@@ -8829,7 +8807,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegModifie
// If initReg is one of RBM_CALLEE_TRASH, then it needs to be zero'ed before using.
if ((RBM_CALLEE_TRASH & genRegMask(initReg)) != 0)
{
- *pInitRegModified = true;
+ *pInitRegZeroed = false;
}
#endif // !defined(UNIX_AMD64_ABI)
diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp
index c78ee4477e0d80..b836a2efa2f2c7 100644
--- a/src/coreclr/src/jit/compiler.cpp
+++ b/src/coreclr/src/jit/compiler.cpp
@@ -1764,6 +1764,10 @@ void Compiler::compInit(ArenaAllocator* pAlloc,
info.compPerfScore = 0.0;
#endif // defined(DEBUG) || defined(LATE_DISASM)
+#if defined(DEBUG) || defined(INLINE_DATA)
+ info.compMethodHashPrivate = 0;
+#endif // defined(DEBUG) || defined(INLINE_DATA)
+
#ifdef DEBUG
// Opt-in to jit stress based on method hash ranges.
//
@@ -5287,10 +5291,6 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr,
verbose = compIsForInlining() ? impInlineInfo->InlinerCompiler->verbose : false;
#endif
-#if defined(DEBUG) || defined(INLINE_DATA)
- info.compMethodHashPrivate = 0;
-#endif // defined(DEBUG) || defined(INLINE_DATA)
-
#if FUNC_INFO_LOGGING
LPCWSTR tmpJitFuncInfoFilename = JitConfig.JitFuncInfoFile();
@@ -9285,3 +9285,24 @@ bool Compiler::lvaIsOSRLocal(unsigned varNum)
return false;
}
+
+//------------------------------------------------------------------------------
+// gtChangeOperToNullCheck: helper to change tree oper to a NULLCHECK.
+//
+// Arguments:
+// tree - the node to change;
+// basicBlock - basic block of the node.
+//
+// Notes:
+// the function should not be called after lowering for platforms that do not support
+// emitting NULLCHECK nodes, like arm32. Use `Lowering::TransformUnusedIndirection`
+// that handles it and calls this function when appropriate.
+//
+void Compiler::gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block)
+{
+ assert(tree->OperIs(GT_FIELD, GT_IND, GT_OBJ, GT_BLK, GT_DYN_BLK));
+ tree->ChangeOper(GT_NULLCHECK);
+ tree->ChangeType(TYP_INT);
+ block->bbFlags |= BBF_HAS_NULLCHECK;
+ optMethodFlags |= OMF_HAS_NULLCHECK;
+}
diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h
index c5f571838d4b29..9924c5ffe1db71 100644
--- a/src/coreclr/src/jit/compiler.h
+++ b/src/coreclr/src/jit/compiler.h
@@ -2701,6 +2701,8 @@ class Compiler
GenTree* gtNewNullCheck(GenTree* addr, BasicBlock* basicBlock);
+ void gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block);
+
GenTreeArgList* gtNewArgList(GenTree* op);
GenTreeArgList* gtNewArgList(GenTree* op1, GenTree* op2);
GenTreeArgList* gtNewArgList(GenTree* op1, GenTree* op2, GenTree* op3);
@@ -3741,7 +3743,7 @@ class Compiler
GenTree* impMathIntrinsic(CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
var_types callType,
- CorInfoIntrinsics intrinsicID,
+ NamedIntrinsic intrinsicName,
bool tailCall);
NamedIntrinsic lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method);
GenTree* impUnsupportedNamedIntrinsic(unsigned helper,
@@ -3937,9 +3939,9 @@ class Compiler
bool VarTypeIsMultiByteAndCanEnreg(
var_types type, CORINFO_CLASS_HANDLE typeClass, unsigned* typeSize, bool forReturn, bool isVarArg);
- bool IsIntrinsicImplementedByUserCall(CorInfoIntrinsics intrinsicId);
- bool IsTargetIntrinsic(CorInfoIntrinsics intrinsicId);
- bool IsMathIntrinsic(CorInfoIntrinsics intrinsicId);
+ bool IsIntrinsicImplementedByUserCall(NamedIntrinsic intrinsicName);
+ bool IsTargetIntrinsic(NamedIntrinsic intrinsicName);
+ bool IsMathIntrinsic(NamedIntrinsic intrinsicName);
bool IsMathIntrinsic(GenTree* tree);
private:
@@ -4633,6 +4635,9 @@ class Compiler
void fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALARG_TP volatileVars);
+ bool fgTryRemoveNonLocal(GenTree* node, LIR::Range* blockRange);
+
+ void fgRemoveDeadStoreLIR(GenTree* store, BasicBlock* block);
bool fgRemoveDeadStore(GenTree** pTree,
LclVarDsc* varDsc,
VARSET_VALARG_TP life,
@@ -4964,7 +4969,7 @@ class Compiler
// When the flow graph changes, we need to update the block numbers, predecessor lists, reachability sets, and
// dominators.
- void fgUpdateChangedFlowGraph();
+ void fgUpdateChangedFlowGraph(bool computeDoms = true);
public:
// Compute the predecessors of the blocks in the control flow graph.
@@ -6326,11 +6331,12 @@ class Compiler
struct CSEdsc
{
- CSEdsc* csdNextInBucket; // used by the hash table
-
- unsigned csdHashKey; // the orginal hashkey
-
- unsigned csdIndex; // 1..optCSECandidateCount
+ CSEdsc* csdNextInBucket; // used by the hash table
+ size_t csdHashKey; // the orginal hashkey
+ ssize_t csdConstDefValue; // When we CSE similar constants, this is the value that we use as the def
+ ValueNum csdConstDefVN; // When we CSE similar constants, this is the ValueNumber that we use for the LclVar
+ // assignment
+ unsigned csdIndex; // 1..optCSECandidateCount
bool csdLiveAcrossCall;
unsigned short csdDefCount; // definition count
@@ -6359,9 +6365,15 @@ class Compiler
ValueNum defConservNormVN; // if all def occurrences share the same conservative normal value
// number, this will reflect it; otherwise, NoVN.
+ // not used for shared const CSE's
};
- static const size_t s_optCSEhashSize;
+ static const size_t s_optCSEhashSizeInitial;
+ static const size_t s_optCSEhashGrowthFactor;
+ static const size_t s_optCSEhashBucketSize;
+ size_t optCSEhashSize; // The current size of hashtable
+ size_t optCSEhashCount; // Number of entries in hashtable
+ size_t optCSEhashMaxCountBeforeResize; // Number of entries before resize
CSEdsc** optCSEhash;
CSEdsc** optCSEtab;
@@ -6406,6 +6418,16 @@ class Compiler
void optEnsureClearCSEInfo();
#endif // DEBUG
+ static bool Is_Shared_Const_CSE(size_t key)
+ {
+ return ((key & TARGET_SIGN_BIT) != 0);
+ }
+
+ static size_t Decode_Shared_Const_CSE_Value(size_t key)
+ {
+ return (key & ~TARGET_SIGN_BIT) << CSE_CONST_SHARED_LOW_BITS;
+ }
+
#endif // FEATURE_ANYCSE
#if FEATURE_VALNUM_CSE
@@ -8190,7 +8212,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#if defined(TARGET_XARCH)
if (getSIMDSupportLevel() == SIMD_AVX2_Supported)
{
- return TYP_SIMD32;
+ return JitConfig.EnableHWIntrinsic() ? TYP_SIMD32 : TYP_SIMD16;
}
else
{
@@ -8231,7 +8253,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#if defined(TARGET_XARCH)
if (getSIMDSupportLevel() == SIMD_AVX2_Supported)
{
- return YMM_REGSIZE_BYTES;
+ return JitConfig.EnableHWIntrinsic() ? YMM_REGSIZE_BYTES : XMM_REGSIZE_BYTES;
}
else
{
@@ -8261,7 +8283,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#if defined(FEATURE_HW_INTRINSICS) && defined(TARGET_XARCH)
if (compOpportunisticallyDependsOn(InstructionSet_AVX))
{
- return YMM_REGSIZE_BYTES;
+ return JitConfig.EnableHWIntrinsic() ? YMM_REGSIZE_BYTES : XMM_REGSIZE_BYTES;
}
else
{
@@ -8802,8 +8824,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
bool doLateDisasm; // Run the late disassembler
#endif // LATE_DISASM
-#if DUMP_GC_TABLES && !defined(DEBUG) && defined(JIT32_GCENCODER)
-// Only the JIT32_GCENCODER implements GC dumping in non-DEBUG code.
+#if DUMP_GC_TABLES && !defined(DEBUG)
#pragma message("NOTE: this non-debug build has GC ptr table dumping always enabled!")
static const bool dspGCtbls = true;
#endif
@@ -9001,7 +9022,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
{
#if 0
// Switching between size & speed has measurable throughput impact
- // (3.5% on NGen mscorlib when measured). It used to be enabled for
+ // (3.5% on NGen CoreLib when measured). It used to be enabled for
// DEBUG, but should generate identical code between CHK & RET builds,
// so that's not acceptable.
// TODO-Throughput: Figure out what to do about size vs. speed & throughput.
@@ -9067,7 +9088,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
bool compIsVarArgs : 1; // Does the method have varargs parameters?
bool compInitMem : 1; // Is the CORINFO_OPT_INIT_LOCALS bit set in the method info options?
bool compProfilerCallback : 1; // JIT inserted a profiler Enter callback
- bool compPublishStubParam : 1; // EAX captured in prolog will be available through an instrinsic
+ bool compPublishStubParam : 1; // EAX captured in prolog will be available through an intrinsic
bool compRetBuffDefStack : 1; // The ret buff argument definitely points into the stack.
bool compHasNextCallRetAddr : 1; // The NextCallReturnAddress intrinsic is used.
diff --git a/src/coreclr/src/jit/compiler.hpp b/src/coreclr/src/jit/compiler.hpp
index c12bacd94d7a96..ca3ed3c6fc668b 100644
--- a/src/coreclr/src/jit/compiler.hpp
+++ b/src/coreclr/src/jit/compiler.hpp
@@ -3169,6 +3169,7 @@ inline regMaskTP genIntAllRegArgMask(unsigned numRegs)
inline regMaskTP genFltAllRegArgMask(unsigned numRegs)
{
+#ifndef TARGET_X86
assert(numRegs <= MAX_FLOAT_REG_ARG);
regMaskTP result = RBM_NONE;
@@ -3177,6 +3178,10 @@ inline regMaskTP genFltAllRegArgMask(unsigned numRegs)
result |= fltArgMasks[i];
}
return result;
+#else
+ assert(!"no x86 float arg regs\n");
+ return RBM_NONE;
+#endif
}
/*
diff --git a/src/coreclr/src/jit/ee_il_dll.cpp b/src/coreclr/src/jit/ee_il_dll.cpp
index 150efed411f6af..bfd80ffb120005 100644
--- a/src/coreclr/src/jit/ee_il_dll.cpp
+++ b/src/coreclr/src/jit/ee_il_dll.cpp
@@ -316,7 +316,8 @@ unsigned CILJit::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags)
// ensure that AVX2 is actually supported. Otherwise, we will end up getting asserts downstream.
if ((JitConfig.EnableAVX2() != 0) && (JitConfig.EnableAVX() != 0) && (JitConfig.EnableSSE42() != 0) &&
(JitConfig.EnableSSE41() != 0) && (JitConfig.EnableSSSE3() != 0) && (JitConfig.EnableSSE3_4() != 0) &&
- (JitConfig.EnableSSE3() != 0) && (JitConfig.EnableSSE2() != 0) && (JitConfig.EnableSSE() != 0))
+ (JitConfig.EnableSSE3() != 0) && (JitConfig.EnableSSE2() != 0) && (JitConfig.EnableSSE() != 0) &&
+ (JitConfig.EnableHWIntrinsic() != 0))
{
if (GetJitTls() != nullptr && JitTls::GetCompiler() != nullptr)
{
diff --git a/src/coreclr/src/jit/emit.cpp b/src/coreclr/src/jit/emit.cpp
index cc12dabc5492eb..ab1c281ea5eb99 100644
--- a/src/coreclr/src/jit/emit.cpp
+++ b/src/coreclr/src/jit/emit.cpp
@@ -7692,7 +7692,12 @@ regMaskTP emitter::emitGetGCRegsKilledByNoGCCall(CorInfoHelpFunc helper)
break;
case CORINFO_HELP_PROF_FCN_LEAVE:
+#if defined(TARGET_ARM)
+ // profiler scratch remains gc live
+ result = RBM_PROFILER_LEAVE_TRASH & ~RBM_PROFILER_RET_SCRATCH;
+#else
result = RBM_PROFILER_LEAVE_TRASH;
+#endif
break;
case CORINFO_HELP_PROF_FCN_TAILCALL:
diff --git a/src/coreclr/src/jit/emitarm64.cpp b/src/coreclr/src/jit/emitarm64.cpp
index 9a82b01063b710..a23aef5812a618 100644
--- a/src/coreclr/src/jit/emitarm64.cpp
+++ b/src/coreclr/src/jit/emitarm64.cpp
@@ -13396,11 +13396,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR
{
GenTreeLclVarCommon* varNode = addr->AsLclVarCommon();
unsigned lclNum = varNode->GetLclNum();
- unsigned offset = 0;
- if (addr->OperIs(GT_LCL_FLD_ADDR))
- {
- offset = varNode->AsLclFld()->GetLclOffs();
- }
+ unsigned offset = varNode->GetLclOffs();
if (emitInsIsStore(ins))
{
emitIns_S_R(ins, attr, dataReg, lclNum, offset);
diff --git a/src/coreclr/src/jit/emitxarch.cpp b/src/coreclr/src/jit/emitxarch.cpp
index 81f9ce8ef68108..f21b1170eb83cc 100644
--- a/src/coreclr/src/jit/emitxarch.cpp
+++ b/src/coreclr/src/jit/emitxarch.cpp
@@ -163,8 +163,10 @@ bool emitter::IsDstSrcSrcAVXInstruction(instruction ins)
bool emitter::AreUpper32BitsZero(regNumber reg)
{
- // Don't look back across IG boundaries (possible control flow)
- if (emitCurIGinsCnt == 0)
+ // If there are no instructions in this IG, we can look back at
+ // the previous IG's instructions if this IG is an extension.
+ //
+ if ((emitCurIGinsCnt == 0) && ((emitCurIG->igFlags & IGF_EXTEND) == 0))
{
return false;
}
@@ -2956,24 +2958,27 @@ void emitter::emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt,
}
else
{
+ regNumber amBaseReg = REG_NA;
if (memBase != nullptr)
{
- id->idAddr()->iiaAddrMode.amBaseReg = memBase->GetRegNum();
- }
- else
- {
- id->idAddr()->iiaAddrMode.amBaseReg = REG_NA;
+ assert(!memBase->isContained());
+ amBaseReg = memBase->GetRegNum();
+ assert(amBaseReg != REG_NA);
}
+ regNumber amIndxReg = REG_NA;
if (indir->HasIndex())
{
- id->idAddr()->iiaAddrMode.amIndxReg = indir->Index()->GetRegNum();
- }
- else
- {
- id->idAddr()->iiaAddrMode.amIndxReg = REG_NA;
+ GenTree* index = indir->Index();
+ assert(!index->isContained());
+ amIndxReg = index->GetRegNum();
+ assert(amIndxReg != REG_NA);
}
- id->idAddr()->iiaAddrMode.amScale = emitEncodeScale(indir->Scale());
+
+ assert((amBaseReg != REG_NA) || (amIndxReg != REG_NA) || (indir->Offset() != 0)); // At least one should be set.
+ id->idAddr()->iiaAddrMode.amBaseReg = amBaseReg;
+ id->idAddr()->iiaAddrMode.amIndxReg = amIndxReg;
+ id->idAddr()->iiaAddrMode.amScale = emitEncodeScale(indir->Scale());
id->idInsFmt(emitMapFmtForIns(fmt, ins));
@@ -3043,11 +3048,7 @@ void emitter::emitInsLoadInd(instruction ins, emitAttr attr, regNumber dstReg, G
if (addr->OperIs(GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR))
{
GenTreeLclVarCommon* varNode = addr->AsLclVarCommon();
- unsigned offset = 0;
- if (addr->OperIs(GT_LCL_FLD_ADDR))
- {
- offset = varNode->AsLclFld()->GetLclOffs();
- }
+ unsigned offset = varNode->GetLclOffs();
emitIns_R_S(ins, attr, dstReg, varNode->GetLclNum(), offset);
// Updating variable liveness after instruction was emitted
@@ -3100,11 +3101,7 @@ void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* m
if (addr->OperIs(GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR))
{
GenTreeLclVarCommon* varNode = addr->AsLclVarCommon();
- unsigned offset = 0;
- if (addr->OperIs(GT_LCL_FLD_ADDR))
- {
- offset = varNode->AsLclFld()->GetLclOffs();
- }
+ unsigned offset = varNode->GetLclOffs();
if (data->isContainedIntOrIImmed())
{
emitIns_S_I(ins, attr, varNode->GetLclNum(), offset, (int)data->AsIntConCommon()->IconValue());
@@ -3292,9 +3289,11 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G
switch (memBase->OperGet())
{
case GT_LCL_VAR_ADDR:
+ case GT_LCL_FLD_ADDR:
{
+ assert(memBase->isContained());
varNum = memBase->AsLclVarCommon()->GetLclNum();
- offset = 0;
+ offset = memBase->AsLclVarCommon()->GetLclOffs();
// Ensure that all the GenTreeIndir values are set to their defaults.
assert(!memIndir->HasIndex());
@@ -3605,8 +3604,7 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI
{
GenTree* addr = storeInd->Addr();
addr = addr->gtSkipReloadOrCopy();
- assert(addr->OperGet() == GT_LCL_VAR || addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_LEA ||
- addr->OperGet() == GT_CLS_VAR_ADDR || addr->OperGet() == GT_CNS_INT);
+ assert(addr->OperIs(GT_LCL_VAR, GT_LCL_VAR_ADDR, GT_LEA, GT_CLS_VAR_ADDR, GT_CNS_INT));
instrDesc* id = nullptr;
UNATIVE_OFFSET sz;
@@ -3685,8 +3683,7 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI
{
GenTree* addr = storeInd->Addr();
addr = addr->gtSkipReloadOrCopy();
- assert(addr->OperGet() == GT_LCL_VAR || addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_CLS_VAR_ADDR ||
- addr->OperGet() == GT_LEA || addr->OperGet() == GT_CNS_INT);
+ assert(addr->OperIs(GT_LCL_VAR, GT_LCL_VAR_ADDR, GT_CLS_VAR_ADDR, GT_LEA, GT_CNS_INT));
ssize_t offset = 0;
if (addr->OperGet() != GT_CLS_VAR_ADDR)
diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp
index e870a8f4c0fe63..242a4c56791e2e 100644
--- a/src/coreclr/src/jit/flowgraph.cpp
+++ b/src/coreclr/src/jit/flowgraph.cpp
@@ -175,6 +175,8 @@ void Compiler::fgInit()
#ifdef FEATURE_SIMD
fgPreviousCandidateSIMDFieldAsgStmt = nullptr;
#endif
+
+ fgHasSwitch = false;
}
bool Compiler::fgHaveProfileData()
@@ -476,7 +478,8 @@ void Compiler::fgEnsureFirstBBisScratch()
noway_assert(fgLastBB != nullptr);
- block->bbFlags |= (BBF_INTERNAL | BBF_IMPORTED);
+ // Set the expected flags
+ block->bbFlags |= (BBF_INTERNAL | BBF_IMPORTED | BBF_JMP_TARGET | BBF_HAS_LABEL);
// This new first BB has an implicit ref, and no others.
block->bbRefs = 1;
@@ -1865,7 +1868,7 @@ bool Compiler::fgReachable(BasicBlock* b1, BasicBlock* b2)
* it again.
*/
-void Compiler::fgUpdateChangedFlowGraph()
+void Compiler::fgUpdateChangedFlowGraph(bool computeDoms)
{
// We need to clear this so we don't hit an assert calling fgRenumberBlocks().
fgDomsComputed = false;
@@ -1876,7 +1879,10 @@ void Compiler::fgUpdateChangedFlowGraph()
fgComputePreds();
fgComputeEnterBlocksSet();
fgComputeReachabilitySets();
- fgComputeDoms();
+ if (computeDoms)
+ {
+ fgComputeDoms();
+ }
}
/*****************************************************************************
@@ -3650,6 +3656,7 @@ PhaseStatus Compiler::fgInsertGCPolls()
case BBJ_SWITCH:
case BBJ_NONE:
case BBJ_THROW:
+ case BBJ_CALLFINALLY:
break;
default:
assert(!"Unexpected block kind");
@@ -3698,6 +3705,18 @@ PhaseStatus Compiler::fgInsertGCPolls()
// We don't want to deal with all the outgoing edges of a switch block.
pollType = GCPOLL_CALL;
}
+ else if ((block->bbFlags & BBF_COLD) != 0)
+ {
+#ifdef DEBUG
+ if (verbose)
+ {
+ printf("Selecting CALL poll in block " FMT_BB " because it is a cold block\n", block->bbNum);
+ }
+#endif // DEBUG
+
+ // We don't want to split a cold block.
+ pollType = GCPOLL_CALL;
+ }
BasicBlock* curBasicBlock = fgCreateGCPoll(pollType, block);
createdPollBlocks |= (block != curBasicBlock);
@@ -3710,7 +3729,8 @@ PhaseStatus Compiler::fgInsertGCPolls()
{
noway_assert(opts.OptimizationEnabled());
fgReorderBlocks();
- fgUpdateChangedFlowGraph();
+ constexpr bool computeDoms = false;
+ fgUpdateChangedFlowGraph(computeDoms);
}
#ifdef DEBUG
if (verbose)
@@ -4058,9 +4078,11 @@ BasicBlock* Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block)
createdPollBlocks = false;
Statement* newStmt = nullptr;
- if (block->bbJumpKind == BBJ_ALWAYS)
+ if ((block->bbJumpKind == BBJ_ALWAYS) || (block->bbJumpKind == BBJ_CALLFINALLY) ||
+ (block->bbJumpKind == BBJ_NONE))
{
- // for BBJ_ALWAYS I don't need to insert it before the condition. Just append it.
+ // For BBJ_ALWAYS, BBJ_CALLFINALLY, and BBJ_NONE and we don't need to insert it before the condition.
+ // Just append it.
newStmt = fgNewStmtAtEnd(block, call);
}
else
@@ -4138,9 +4160,12 @@ BasicBlock* Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block)
// We are allowed to split loops and we need to keep a few other flags...
//
- noway_assert((originalFlags & (BBF_SPLIT_NONEXIST & ~(BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1))) == 0);
- top->bbFlags = originalFlags & (~BBF_SPLIT_LOST | BBF_GC_SAFE_POINT);
- bottom->bbFlags |= originalFlags & (BBF_SPLIT_GAINED | BBF_IMPORTED | BBF_GC_SAFE_POINT);
+ noway_assert((originalFlags & (BBF_SPLIT_NONEXIST &
+ ~(BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1 | BBF_LOOP_PREHEADER |
+ BBF_RETLESS_CALL))) == 0);
+ top->bbFlags = originalFlags & (~(BBF_SPLIT_LOST | BBF_LOOP_PREHEADER | BBF_RETLESS_CALL) | BBF_GC_SAFE_POINT);
+ bottom->bbFlags |= originalFlags & (BBF_SPLIT_GAINED | BBF_IMPORTED | BBF_GC_SAFE_POINT | BBF_LOOP_PREHEADER |
+ BBF_RETLESS_CALL);
bottom->inheritWeight(top);
poll->bbFlags |= originalFlags & (BBF_SPLIT_GAINED | BBF_IMPORTED | BBF_GC_SAFE_POINT);
@@ -4265,6 +4290,7 @@ BasicBlock* Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block)
__fallthrough;
case BBJ_ALWAYS:
+ case BBJ_CALLFINALLY:
fgReplacePred(bottom->bbJumpDest, top, bottom);
break;
case BBJ_SWITCH:
@@ -7232,7 +7258,7 @@ bool Compiler::fgIsThrow(GenTree* tree)
return true;
}
- // TODO-CQ: there are a bunch of managed methods in [mscorlib]System.ThrowHelper
+ // TODO-CQ: there are a bunch of managed methods in System.ThrowHelper
// that would be nice to recognize.
return false;
@@ -14678,9 +14704,9 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block)
LIR::ReadOnlyRange range(zeroConstNode, switchTree);
m_pLowering->LowerRange(block, range);
}
- else
+ else if (fgStmtListThreaded)
{
- // Re-link the nodes for this statement.
+ gtSetStmtInfo(switchStmt);
fgSetStmtSeq(switchStmt);
}
diff --git a/src/coreclr/src/jit/gcencode.cpp b/src/coreclr/src/jit/gcencode.cpp
index 3c45137b059367..81edb0b0d29e13 100644
--- a/src/coreclr/src/jit/gcencode.cpp
+++ b/src/coreclr/src/jit/gcencode.cpp
@@ -3633,7 +3633,10 @@ void GCInfo::gcFindPtrsInFrame(const void* infoBlock, const void* codeBlock, uns
template class JitHashTable;
template class JitHashTable;
-#ifdef DEBUG
+#if defined(DEBUG) || DUMP_GC_TABLES
+
+// This is a copy of GcStackSlotBaseNames from gcinfotypes.h so we can compile in to non-DEBUG builds.
+const char* const JitGcStackSlotBaseNames[] = {"caller.sp", "sp", "frame"};
static const char* const GcSlotFlagsNames[] = {"",
"(byref) ",
@@ -3652,7 +3655,7 @@ class GcInfoEncoderWithLogging
public:
GcInfoEncoderWithLogging(GcInfoEncoder* gcInfoEncoder, bool verbose)
- : m_gcInfoEncoder(gcInfoEncoder), m_doLogging(verbose || JitConfig.JitGCInfoLogging() != 0)
+ : m_gcInfoEncoder(gcInfoEncoder), m_doLogging(verbose INDEBUG(|| JitConfig.JitGCInfoLogging() != 0))
{
}
@@ -3662,7 +3665,7 @@ class GcInfoEncoderWithLogging
if (m_doLogging)
{
printf("Stack slot id for offset %d (0x%x) (%s) %s= %d.\n", spOffset, spOffset,
- GcStackSlotBaseNames[spBase], GcSlotFlagsNames[flags & 7], newSlotId);
+ JitGcStackSlotBaseNames[spBase], GcSlotFlagsNames[flags & 7], newSlotId);
}
return newSlotId;
}
@@ -3827,14 +3830,14 @@ class GcInfoEncoderWithLogging
};
#define GCENCODER_WITH_LOGGING(withLog, realEncoder) \
- GcInfoEncoderWithLogging withLog##Var(realEncoder, compiler->verbose || compiler->opts.dspGCtbls); \
+ GcInfoEncoderWithLogging withLog##Var(realEncoder, INDEBUG(compiler->verbose ||) compiler->opts.dspGCtbls); \
GcInfoEncoderWithLogging* withLog = &withLog##Var;
-#else // DEBUG
+#else // !(defined(DEBUG) || DUMP_GC_TABLES)
#define GCENCODER_WITH_LOGGING(withLog, realEncoder) GcInfoEncoder* withLog = realEncoder;
-#endif // DEBUG
+#endif // !(defined(DEBUG) || DUMP_GC_TABLES)
void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSize, unsigned prologSize)
{
@@ -4006,7 +4009,7 @@ void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSiz
#endif // DISPLAY_SIZES
}
-#ifdef DEBUG
+#if defined(DEBUG) || DUMP_GC_TABLES
#define Encoder GcInfoEncoderWithLogging
#else
#define Encoder GcInfoEncoder
diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp
index 8ca9a49a2ce7db..2e0e96a0e9a61b 100644
--- a/src/coreclr/src/jit/gentree.cpp
+++ b/src/coreclr/src/jit/gentree.cpp
@@ -3250,78 +3250,138 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
switch (oper)
{
#ifdef TARGET_ARM
- case GT_CNS_LNG:
- costSz = 9;
- costEx = 4;
- goto COMMON_CNS;
-
case GT_CNS_STR:
// Uses movw/movt
- costSz = 7;
- costEx = 3;
+ costSz = 8;
+ costEx = 2;
goto COMMON_CNS;
+ case GT_CNS_LNG:
+ {
+ GenTreeIntConCommon* con = tree->AsIntConCommon();
+
+ INT64 lngVal = con->LngValue();
+ INT32 loVal = (INT32)(lngVal & 0xffffffff);
+ INT32 hiVal = (INT32)(lngVal >> 32);
+
+ if (lngVal == 0)
+ {
+ costSz = 1;
+ costEx = 1;
+ }
+ else
+ {
+ // Minimum of one instruction to setup hiVal,
+ // and one instruction to setup loVal
+ costSz = 4 + 4;
+ costEx = 1 + 1;
+
+ if (!codeGen->validImmForInstr(INS_mov, (target_ssize_t)hiVal) &&
+ !codeGen->validImmForInstr(INS_mvn, (target_ssize_t)hiVal))
+ {
+ // Needs extra instruction: movw/movt
+ costSz += 4;
+ costEx += 1;
+ }
+
+ if (!codeGen->validImmForInstr(INS_mov, (target_ssize_t)loVal) &&
+ !codeGen->validImmForInstr(INS_mvn, (target_ssize_t)loVal))
+ {
+ // Needs extra instruction: movw/movt
+ costSz += 4;
+ costEx += 1;
+ }
+ }
+ goto COMMON_CNS;
+ }
+
case GT_CNS_INT:
{
// If the constant is a handle then it will need to have a relocation
// applied to it.
// Any constant that requires a reloc must use the movw/movt sequence
//
- GenTreeIntConCommon* con = tree->AsIntConCommon();
+ GenTreeIntConCommon* con = tree->AsIntConCommon();
+ INT32 conVal = con->IconValue();
- if (con->ImmedValNeedsReloc(this) ||
- !codeGen->validImmForInstr(INS_mov, (target_ssize_t)tree->AsIntCon()->gtIconVal))
+ if (con->ImmedValNeedsReloc(this))
{
- // Uses movw/movt
- costSz = 7;
- costEx = 3;
+ // Requires movw/movt
+ costSz = 8;
+ costEx = 2;
}
- else if (((unsigned)tree->AsIntCon()->gtIconVal) <= 0x00ff)
+ else if (codeGen->validImmForInstr(INS_add, (target_ssize_t)conVal))
{
- // mov Rd,
- costSz = 1;
+ // Typically included with parent oper
+ costSz = 2;
costEx = 1;
}
- else
+ else if (codeGen->validImmForInstr(INS_mov, (target_ssize_t)conVal) &&
+ codeGen->validImmForInstr(INS_mvn, (target_ssize_t)conVal))
{
- // Uses movw/mvn
- costSz = 3;
+ // Uses mov or mvn
+ costSz = 4;
costEx = 1;
}
+ else
+ {
+ // Needs movw/movt
+ costSz = 8;
+ costEx = 2;
+ }
goto COMMON_CNS;
}
#elif defined TARGET_XARCH
- case GT_CNS_LNG:
- costSz = 10;
- costEx = 3;
- goto COMMON_CNS;
-
case GT_CNS_STR:
+#ifdef TARGET_AMD64
+ costSz = 10;
+ costEx = 2;
+#else // TARGET_X86
costSz = 4;
costEx = 1;
+#endif
goto COMMON_CNS;
+ case GT_CNS_LNG:
case GT_CNS_INT:
{
+ GenTreeIntConCommon* con = tree->AsIntConCommon();
+ ssize_t conVal = (oper == GT_CNS_LNG) ? (ssize_t)con->LngValue() : con->IconValue();
+ bool fitsInVal = true;
+
+#ifdef TARGET_X86
+ if (oper == GT_CNS_LNG)
+ {
+ INT64 lngVal = con->LngValue();
+
+ conVal = (ssize_t)lngVal; // truncate to 32-bits
+
+ fitsInVal = ((INT64)conVal == lngVal);
+ }
+#endif // TARGET_X86
+
// If the constant is a handle then it will need to have a relocation
// applied to it.
//
- GenTreeIntConCommon* con = tree->AsIntConCommon();
-
bool iconNeedsReloc = con->ImmedValNeedsReloc(this);
- if (!iconNeedsReloc && con->FitsInI8())
+ if (iconNeedsReloc)
+ {
+ costSz = 4;
+ costEx = 1;
+ }
+ else if (fitsInVal && GenTreeIntConCommon::FitsInI8(conVal))
{
costSz = 1;
costEx = 1;
}
-#if defined(TARGET_AMD64)
- else if (iconNeedsReloc || !con->FitsInI32())
+#ifdef TARGET_AMD64
+ else if (!GenTreeIntConCommon::FitsInI32(conVal))
{
costSz = 10;
- costEx = 3;
+ costEx = 2;
}
#endif // TARGET_AMD64
else
@@ -3329,21 +3389,83 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
costSz = 4;
costEx = 1;
}
+#ifdef TARGET_X86
+ if (oper == GT_CNS_LNG)
+ {
+ costSz += fitsInVal ? 1 : 4;
+ costEx += 1;
+ }
+#endif // TARGET_X86
+
goto COMMON_CNS;
}
#elif defined(TARGET_ARM64)
- case GT_CNS_LNG:
+
case GT_CNS_STR:
+ case GT_CNS_LNG:
case GT_CNS_INT:
- // TODO-ARM64-NYI: Need cost estimates.
- costSz = 1;
- costEx = 1;
+ {
+ GenTreeIntConCommon* con = tree->AsIntConCommon();
+ bool iconNeedsReloc = con->ImmedValNeedsReloc(this);
+ INT64 imm = con->LngValue();
+ emitAttr size = EA_SIZE(emitActualTypeSize(tree));
+
+ if (iconNeedsReloc)
+ {
+ costSz = 8;
+ costEx = 2;
+ }
+ else if (emitter::emitIns_valid_imm_for_add(imm, size))
+ {
+ costSz = 2;
+ costEx = 1;
+ }
+ else if (emitter::emitIns_valid_imm_for_mov(imm, size))
+ {
+ costSz = 4;
+ costEx = 1;
+ }
+ else
+ {
+ // Arm64 allows any arbitrary 16-bit constant to be loaded into a register halfword
+ // There are three forms
+ // movk which loads into any halfword preserving the remaining halfwords
+ // movz which loads into any halfword zeroing the remaining halfwords
+ // movn which loads into any halfword zeroing the remaining halfwords then bitwise inverting
+ // the register
+ // In some cases it is preferable to use movn, because it has the side effect of filling the
+ // other halfwords
+ // with ones
+
+ // Determine whether movn or movz will require the fewest instructions to populate the immediate
+ bool preferMovz = false;
+ bool preferMovn = false;
+ int instructionCount = 4;
+
+ for (int i = (size == EA_8BYTE) ? 48 : 16; i >= 0; i -= 16)
+ {
+ if (!preferMovn && (uint16_t(imm >> i) == 0x0000))
+ {
+ preferMovz = true; // by using a movk to start we can save one instruction
+ instructionCount--;
+ }
+ else if (!preferMovz && (uint16_t(imm >> i) == 0xffff))
+ {
+ preferMovn = true; // by using a movn to start we can save one instruction
+ instructionCount--;
+ }
+ }
+
+ costEx = instructionCount;
+ costSz = 4 * instructionCount;
+ }
+ }
goto COMMON_CNS;
#else
- case GT_CNS_LNG:
case GT_CNS_STR:
+ case GT_CNS_LNG:
case GT_CNS_INT:
#error "Unknown TARGET"
#endif
@@ -3502,6 +3624,8 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
level = gtSetEvalOrder(op1);
+ GenTreeIntrinsic* intrinsic;
+
/* Special handling for some operators */
switch (oper)
@@ -3563,54 +3687,82 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
break;
case GT_INTRINSIC:
- // GT_INTRINSIC intrinsics Sin, Cos, Sqrt, Abs ... have higher costs.
- // TODO: tune these costs target specific as some of these are
- // target intrinsics and would cost less to generate code.
- switch (tree->AsIntrinsic()->gtIntrinsicId)
+ intrinsic = tree->AsIntrinsic();
+ if (intrinsic->gtIntrinsicId == CORINFO_INTRINSIC_Illegal)
{
- default:
- assert(!"missing case for gtIntrinsicId");
- costEx = 12;
- costSz = 12;
- break;
+ // named intrinsic
+ assert(intrinsic->gtIntrinsicName != NI_Illegal);
- case CORINFO_INTRINSIC_Sin:
- case CORINFO_INTRINSIC_Cos:
- case CORINFO_INTRINSIC_Sqrt:
- case CORINFO_INTRINSIC_Cbrt:
- case CORINFO_INTRINSIC_Cosh:
- case CORINFO_INTRINSIC_Sinh:
- case CORINFO_INTRINSIC_Tan:
- case CORINFO_INTRINSIC_Tanh:
- case CORINFO_INTRINSIC_Asin:
- case CORINFO_INTRINSIC_Asinh:
- case CORINFO_INTRINSIC_Acos:
- case CORINFO_INTRINSIC_Acosh:
- case CORINFO_INTRINSIC_Atan:
- case CORINFO_INTRINSIC_Atanh:
- case CORINFO_INTRINSIC_Atan2:
- case CORINFO_INTRINSIC_Log10:
- case CORINFO_INTRINSIC_Pow:
- case CORINFO_INTRINSIC_Exp:
- case CORINFO_INTRINSIC_Ceiling:
- case CORINFO_INTRINSIC_Floor:
- case CORINFO_INTRINSIC_Object_GetType:
- // Giving intrinsics a large fixed execution cost is because we'd like to CSE
- // them, even if they are implemented by calls. This is different from modeling
- // user calls since we never CSE user calls.
- costEx = 36;
- costSz = 4;
- break;
+ // GT_INTRINSIC intrinsics Sin, Cos, Sqrt, Abs ... have higher costs.
+ // TODO: tune these costs target specific as some of these are
+ // target intrinsics and would cost less to generate code.
+ switch (intrinsic->gtIntrinsicName)
+ {
+ default:
+ assert(!"missing case for gtIntrinsicName");
+ costEx = 12;
+ costSz = 12;
+ break;
- case CORINFO_INTRINSIC_Abs:
- costEx = 5;
- costSz = 15;
- break;
+ case NI_System_Math_Sin:
+ case NI_System_Math_Cos:
+ case NI_System_Math_Sqrt:
+ case NI_System_Math_Cbrt:
+ case NI_System_Math_Cosh:
+ case NI_System_Math_Sinh:
+ case NI_System_Math_Tan:
+ case NI_System_Math_Tanh:
+ case NI_System_Math_Asin:
+ case NI_System_Math_Asinh:
+ case NI_System_Math_Acos:
+ case NI_System_Math_Acosh:
+ case NI_System_Math_Atan:
+ case NI_System_Math_Atanh:
+ case NI_System_Math_Atan2:
+ case NI_System_Math_Log10:
+ case NI_System_Math_Pow:
+ case NI_System_Math_Exp:
+ case NI_System_Math_Ceiling:
+ case NI_System_Math_Floor:
+ // Giving intrinsics a large fixed execution cost is because we'd like to CSE
+ // them, even if they are implemented by calls. This is different from modeling
+ // user calls since we never CSE user calls.
+ costEx = 36;
+ costSz = 4;
+ break;
- case CORINFO_INTRINSIC_Round:
- costEx = 3;
- costSz = 4;
- break;
+ case NI_System_Math_Abs:
+ costEx = 5;
+ costSz = 15;
+ break;
+
+ case NI_System_Math_Round:
+ costEx = 3;
+ costSz = 4;
+ break;
+ }
+ }
+ else
+ {
+ // old style intrinsic
+ assert(intrinsic->gtIntrinsicName == NI_Illegal);
+
+ switch (intrinsic->gtIntrinsicId)
+ {
+ default:
+ assert(!"missing case for gtIntrinsicId");
+ costEx = 12;
+ costSz = 12;
+ break;
+
+ case CORINFO_INTRINSIC_Object_GetType:
+ // Giving intrinsics a large fixed execution cost is because we'd like to CSE
+ // them, even if they are implemented by calls. This is different from modeling
+ // user calls since we never CSE user calls.
+ costEx = 36;
+ costSz = 4;
+ break;
+ }
}
level++;
break;
@@ -4093,10 +4245,10 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
case GT_INTRINSIC:
- switch (tree->AsIntrinsic()->gtIntrinsicId)
+ switch (tree->AsIntrinsic()->gtIntrinsicName)
{
- case CORINFO_INTRINSIC_Atan2:
- case CORINFO_INTRINSIC_Pow:
+ case NI_System_Math_Atan2:
+ case NI_System_Math_Pow:
// These math intrinsics are actually implemented by user calls.
// Increase the Sethi 'complexity' by two to reflect the argument
// register requirement.
@@ -4153,7 +4305,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
// so if possible it was set above.
tryToSwap = false;
}
- else if ((oper == GT_INTRINSIC) && IsIntrinsicImplementedByUserCall(tree->AsIntrinsic()->gtIntrinsicId))
+ else if ((oper == GT_INTRINSIC) && IsIntrinsicImplementedByUserCall(tree->AsIntrinsic()->gtIntrinsicName))
{
// We do not swap operand execution order for intrinsics that are implemented by user calls
// because of trickiness around ensuring the execution order does not change during rationalization.
@@ -5355,7 +5507,7 @@ bool GenTree::OperRequiresCallFlag(Compiler* comp)
return true;
case GT_INTRINSIC:
- return comp->IsIntrinsicImplementedByUserCall(this->AsIntrinsic()->gtIntrinsicId);
+ return comp->IsIntrinsicImplementedByUserCall(this->AsIntrinsic()->gtIntrinsicName);
#if FEATURE_FIXED_OUT_ARGS && !defined(TARGET_64BIT)
case GT_LSH:
@@ -7577,7 +7729,8 @@ GenTree* Compiler::gtCloneExpr(
case GT_INTRINSIC:
copy = new (this, GT_INTRINSIC)
GenTreeIntrinsic(tree->TypeGet(), tree->AsOp()->gtOp1, tree->AsOp()->gtOp2,
- tree->AsIntrinsic()->gtIntrinsicId, tree->AsIntrinsic()->gtMethodHandle);
+ tree->AsIntrinsic()->gtIntrinsicId, tree->AsIntrinsic()->gtIntrinsicName,
+ tree->AsIntrinsic()->gtMethodHandle);
#ifdef FEATURE_READYTORUN_COMPILER
copy->AsIntrinsic()->gtEntryPoint = tree->AsIntrinsic()->gtEntryPoint;
#endif
@@ -11338,80 +11491,98 @@ void Compiler::gtDispTree(GenTree* tree,
if (tree->gtOper == GT_INTRINSIC)
{
- switch (tree->AsIntrinsic()->gtIntrinsicId)
+ GenTreeIntrinsic* intrinsic = tree->AsIntrinsic();
+
+ if (intrinsic->gtIntrinsicId == CORINFO_INTRINSIC_Illegal)
{
- case CORINFO_INTRINSIC_Sin:
- printf(" sin");
- break;
- case CORINFO_INTRINSIC_Cos:
- printf(" cos");
- break;
- case CORINFO_INTRINSIC_Cbrt:
- printf(" cbrt");
- break;
- case CORINFO_INTRINSIC_Sqrt:
- printf(" sqrt");
- break;
- case CORINFO_INTRINSIC_Abs:
- printf(" abs");
- break;
- case CORINFO_INTRINSIC_Round:
- printf(" round");
- break;
- case CORINFO_INTRINSIC_Cosh:
- printf(" cosh");
- break;
- case CORINFO_INTRINSIC_Sinh:
- printf(" sinh");
- break;
- case CORINFO_INTRINSIC_Tan:
- printf(" tan");
- break;
- case CORINFO_INTRINSIC_Tanh:
- printf(" tanh");
- break;
- case CORINFO_INTRINSIC_Asin:
- printf(" asin");
- break;
- case CORINFO_INTRINSIC_Asinh:
- printf(" asinh");
- break;
- case CORINFO_INTRINSIC_Acos:
- printf(" acos");
- break;
- case CORINFO_INTRINSIC_Acosh:
- printf(" acosh");
- break;
- case CORINFO_INTRINSIC_Atan:
- printf(" atan");
- break;
- case CORINFO_INTRINSIC_Atan2:
- printf(" atan2");
- break;
- case CORINFO_INTRINSIC_Atanh:
- printf(" atanh");
- break;
- case CORINFO_INTRINSIC_Log10:
- printf(" log10");
- break;
- case CORINFO_INTRINSIC_Pow:
- printf(" pow");
- break;
- case CORINFO_INTRINSIC_Exp:
- printf(" exp");
- break;
- case CORINFO_INTRINSIC_Ceiling:
- printf(" ceiling");
- break;
- case CORINFO_INTRINSIC_Floor:
- printf(" floor");
- break;
- case CORINFO_INTRINSIC_Object_GetType:
- printf(" objGetType");
- break;
+ // named intrinsic
+ assert(intrinsic->gtIntrinsicName != NI_Illegal);
+ switch (intrinsic->gtIntrinsicName)
+ {
+ case NI_System_Math_Sin:
+ printf(" sin");
+ break;
+ case NI_System_Math_Cos:
+ printf(" cos");
+ break;
+ case NI_System_Math_Cbrt:
+ printf(" cbrt");
+ break;
+ case NI_System_Math_Sqrt:
+ printf(" sqrt");
+ break;
+ case NI_System_Math_Abs:
+ printf(" abs");
+ break;
+ case NI_System_Math_Round:
+ printf(" round");
+ break;
+ case NI_System_Math_Cosh:
+ printf(" cosh");
+ break;
+ case NI_System_Math_Sinh:
+ printf(" sinh");
+ break;
+ case NI_System_Math_Tan:
+ printf(" tan");
+ break;
+ case NI_System_Math_Tanh:
+ printf(" tanh");
+ break;
+ case NI_System_Math_Asin:
+ printf(" asin");
+ break;
+ case NI_System_Math_Asinh:
+ printf(" asinh");
+ break;
+ case NI_System_Math_Acos:
+ printf(" acos");
+ break;
+ case NI_System_Math_Acosh:
+ printf(" acosh");
+ break;
+ case NI_System_Math_Atan:
+ printf(" atan");
+ break;
+ case NI_System_Math_Atan2:
+ printf(" atan2");
+ break;
+ case NI_System_Math_Atanh:
+ printf(" atanh");
+ break;
+ case NI_System_Math_Log10:
+ printf(" log10");
+ break;
+ case NI_System_Math_Pow:
+ printf(" pow");
+ break;
+ case NI_System_Math_Exp:
+ printf(" exp");
+ break;
+ case NI_System_Math_Ceiling:
+ printf(" ceiling");
+ break;
+ case NI_System_Math_Floor:
+ printf(" floor");
+ break;
- default:
- unreached();
+ default:
+ unreached();
+ }
+ }
+ else
+ {
+ // old style intrinsic
+ assert(intrinsic->gtIntrinsicName == NI_Illegal);
+ switch (intrinsic->gtIntrinsicId)
+ {
+ case CORINFO_INTRINSIC_Object_GetType:
+ printf(" objGetType");
+ break;
+
+ default:
+ unreached();
+ }
}
}
@@ -13611,16 +13782,13 @@ GenTree* Compiler::gtTryRemoveBoxUpstreamEffects(GenTree* op, BoxRemovalOptions
// For struct types read the first byte of the
// source struct; there's no need to read the
// entire thing, and no place to put it.
- assert(copySrc->gtOper == GT_OBJ || copySrc->gtOper == GT_IND || copySrc->gtOper == GT_FIELD);
+ assert(copySrc->OperIs(GT_OBJ, GT_IND, GT_FIELD));
copyStmt->SetRootNode(copySrc);
if (options == BR_REMOVE_AND_NARROW || options == BR_REMOVE_AND_NARROW_WANT_TYPE_HANDLE)
{
JITDUMP(" to read first byte of struct via modified [%06u]\n", dspTreeID(copySrc));
- copySrc->ChangeOper(GT_NULLCHECK);
- copySrc->gtType = TYP_BYTE;
- compCurBB->bbFlags |= BBF_HAS_NULLCHECK;
- optMethodFlags |= OMF_HAS_NULLCHECK;
+ gtChangeOperToNullCheck(copySrc, compCurBB);
}
else
{
@@ -15799,6 +15967,11 @@ void Compiler::gtExtractSideEffList(GenTree* expr,
if (m_compiler->gtNodeHasSideEffects(node, m_flags))
{
m_sideEffects.Push(node);
+ if (node->OperIsBlk() && !node->OperIsStoreBlk())
+ {
+ JITDUMP("Replace an unused OBJ/BLK node [%06d] with a NULLCHECK\n", dspTreeID(node));
+ m_compiler->gtChangeOperToNullCheck(node, m_compiler->compCurBB);
+ }
return Compiler::WALK_SKIP_SUBTREES;
}
@@ -16365,11 +16538,7 @@ bool GenTree::DefinesLocalAddr(Compiler* comp, unsigned width, GenTreeLclVarComm
*pLclVarTree = addrArgLcl;
if (pIsEntire != nullptr)
{
- unsigned lclOffset = 0;
- if (addrArg->OperIsLocalField())
- {
- lclOffset = addrArg->AsLclFld()->GetLclOffs();
- }
+ unsigned lclOffset = addrArgLcl->GetLclOffs();
if (lclOffset != 0)
{
@@ -17475,7 +17644,9 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleIfPresent(GenTree* tree)
{
CORINFO_FIELD_HANDLE fieldHnd = fieldSeq->m_fieldHnd;
CorInfoType fieldCorType = info.compCompHnd->getFieldType(fieldHnd, &structHnd);
- assert(fieldCorType == CORINFO_TYPE_VALUECLASS);
+ // With unsafe code and type casts
+ // this can return a primitive type and have nullptr for structHnd
+ // see runtime/issues/38541
}
}
}
@@ -18638,7 +18809,7 @@ bool GenTree::isCommutativeSIMDIntrinsic()
}
}
-// Returns true for the SIMD Instrinsic instructions that have MemoryLoad semantics, false otherwise
+// Returns true for the SIMD Intrinsic instructions that have MemoryLoad semantics, false otherwise
bool GenTreeSIMD::OperIsMemoryLoad() const
{
if (gtSIMDIntrinsicID == SIMDIntrinsicInitArray)
@@ -18860,7 +19031,7 @@ GenTreeHWIntrinsic* Compiler::gtNewScalarHWIntrinsicNode(
GenTreeHWIntrinsic(type, gtNewArgList(op1, op2, op3), hwIntrinsicID, TYP_UNKNOWN, 0);
}
-// Returns true for the HW Instrinsic instructions that have MemoryLoad semantics, false otherwise
+// Returns true for the HW Intrinsic instructions that have MemoryLoad semantics, false otherwise
bool GenTreeHWIntrinsic::OperIsMemoryLoad() const
{
#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
@@ -18903,7 +19074,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad() const
return false;
}
-// Returns true for the HW Instrinsic instructions that have MemoryStore semantics, false otherwise
+// Returns true for the HW Intrinsic instructions that have MemoryStore semantics, false otherwise
bool GenTreeHWIntrinsic::OperIsMemoryStore() const
{
#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
@@ -18939,7 +19110,7 @@ bool GenTreeHWIntrinsic::OperIsMemoryStore() const
return false;
}
-// Returns true for the HW Instrinsic instructions that have MemoryLoad semantics, false otherwise
+// Returns true for the HW Intrinsic instructions that have MemoryLoad semantics, false otherwise
bool GenTreeHWIntrinsic::OperIsMemoryLoadOrStore() const
{
#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
@@ -19350,6 +19521,25 @@ regNumber GenTree::ExtractTempReg(regMaskTP mask /* = (regMaskTP)-1 */)
return genRegNumFromMask(tempRegMask);
}
+//------------------------------------------------------------------------
+// GetLclOffs: if `this` is a field or a field address it returns offset
+// of the field inside the struct, for not a field it returns 0.
+//
+// Return Value:
+// The offset value.
+//
+uint16_t GenTreeLclVarCommon::GetLclOffs() const
+{
+ if (OperIsLocalField())
+ {
+ return AsLclFld()->GetLclOffs();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
#ifdef TARGET_ARM
//------------------------------------------------------------------------
// IsOffsetMisaligned: check if the field needs a special handling on arm.
diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h
index 5e51988d76686c..7e25365730720c 100644
--- a/src/coreclr/src/jit/gentree.h
+++ b/src/coreclr/src/jit/gentree.h
@@ -3180,6 +3180,8 @@ struct GenTreeLclVarCommon : public GenTreeUnOp
_gtSsaNum = SsaConfig::RESERVED_SSA_NUM;
}
+ uint16_t GetLclOffs() const;
+
unsigned GetSsaNum() const
{
return _gtSsaNum;
@@ -4727,6 +4729,7 @@ struct GenTreeQmark : public GenTreeOp
struct GenTreeIntrinsic : public GenTreeOp
{
CorInfoIntrinsics gtIntrinsicId;
+ NamedIntrinsic gtIntrinsicName;
CORINFO_METHOD_HANDLE gtMethodHandle; // Method handle of the method which is treated as an intrinsic.
#ifdef FEATURE_READYTORUN_COMPILER
@@ -4734,15 +4737,31 @@ struct GenTreeIntrinsic : public GenTreeOp
CORINFO_CONST_LOOKUP gtEntryPoint;
#endif
- GenTreeIntrinsic(var_types type, GenTree* op1, CorInfoIntrinsics intrinsicId, CORINFO_METHOD_HANDLE methodHandle)
- : GenTreeOp(GT_INTRINSIC, type, op1, nullptr), gtIntrinsicId(intrinsicId), gtMethodHandle(methodHandle)
+ GenTreeIntrinsic(var_types type,
+ GenTree* op1,
+ CorInfoIntrinsics intrinsicId,
+ NamedIntrinsic intrinsicName,
+ CORINFO_METHOD_HANDLE methodHandle)
+ : GenTreeOp(GT_INTRINSIC, type, op1, nullptr)
+ , gtIntrinsicId(intrinsicId)
+ , gtIntrinsicName(intrinsicName)
+ , gtMethodHandle(methodHandle)
{
+ assert(intrinsicId != CORINFO_INTRINSIC_Illegal || intrinsicName != NI_Illegal);
}
- GenTreeIntrinsic(
- var_types type, GenTree* op1, GenTree* op2, CorInfoIntrinsics intrinsicId, CORINFO_METHOD_HANDLE methodHandle)
- : GenTreeOp(GT_INTRINSIC, type, op1, op2), gtIntrinsicId(intrinsicId), gtMethodHandle(methodHandle)
+ GenTreeIntrinsic(var_types type,
+ GenTree* op1,
+ GenTree* op2,
+ CorInfoIntrinsics intrinsicId,
+ NamedIntrinsic intrinsicName,
+ CORINFO_METHOD_HANDLE methodHandle)
+ : GenTreeOp(GT_INTRINSIC, type, op1, op2)
+ , gtIntrinsicId(intrinsicId)
+ , gtIntrinsicName(intrinsicName)
+ , gtMethodHandle(methodHandle)
{
+ assert(intrinsicId != CORINFO_INTRINSIC_Illegal || intrinsicName != NI_Illegal);
}
#if DEBUGGABLE_GENTREE
@@ -4846,7 +4865,7 @@ struct GenTreeSIMD : public GenTreeJitIntrinsic
gtSIMDIntrinsicID = simdIntrinsicID;
}
- bool OperIsMemoryLoad() const; // Returns true for the SIMD Instrinsic instructions that have MemoryLoad semantics,
+ bool OperIsMemoryLoad() const; // Returns true for the SIMD Intrinsic instructions that have MemoryLoad semantics,
// false otherwise
#if DEBUGGABLE_GENTREE
@@ -4887,15 +4906,15 @@ struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic
}
}
- // Note that HW Instrinsic instructions are a sub class of GenTreeOp which only supports two operands
- // However there are HW Instrinsic instructions that have 3 or even 4 operands and this is
+ // Note that HW Intrinsic instructions are a sub class of GenTreeOp which only supports two operands
+ // However there are HW Intrinsic instructions that have 3 or even 4 operands and this is
// supported using a single op1 and using an ArgList for it: gtNewArgList(op1, op2, op3)
- bool OperIsMemoryLoad() const; // Returns true for the HW Instrinsic instructions that have MemoryLoad semantics,
+ bool OperIsMemoryLoad() const; // Returns true for the HW Intrinsic instructions that have MemoryLoad semantics,
// false otherwise
- bool OperIsMemoryStore() const; // Returns true for the HW Instrinsic instructions that have MemoryStore semantics,
+ bool OperIsMemoryStore() const; // Returns true for the HW Intrinsic instructions that have MemoryStore semantics,
// false otherwise
- bool OperIsMemoryLoadOrStore() const; // Returns true for the HW Instrinsic instructions that have MemoryLoad or
+ bool OperIsMemoryLoadOrStore() const; // Returns true for the HW Intrinsic instructions that have MemoryLoad or
// MemoryStore semantics, false otherwise
#if DEBUGGABLE_GENTREE
diff --git a/src/coreclr/src/jit/hwintrinsic.cpp b/src/coreclr/src/jit/hwintrinsic.cpp
index 5e7eda61c30d26..5723ac8f322b41 100644
--- a/src/coreclr/src/jit/hwintrinsic.cpp
+++ b/src/coreclr/src/jit/hwintrinsic.cpp
@@ -202,7 +202,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, va
{
int numArgs = HWIntrinsicInfo::lookupNumArgs(hwIntrinsicID);
- // HW Instrinsic's with -1 for numArgs have a varying number of args, so we currently
+ // HW Intrinsic's with -1 for numArgs have a varying number of args, so we currently
// give themm a unique value number them, and don't add an extra argument.
//
if (numArgs == -1)
@@ -210,7 +210,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, va
return false;
}
- // We iterate over all of the different baseType's for this instrinsic in the HWIntrinsicInfo table
+ // We iterate over all of the different baseType's for this intrinsic in the HWIntrinsicInfo table
// We set diffInsCount to the number of instructions that can execute differently.
//
unsigned diffInsCount = 0;
diff --git a/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp
index 574e8c48d15f89..ddca579f34ab11 100644
--- a/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp
+++ b/src/coreclr/src/jit/hwintrinsiccodegenxarch.cpp
@@ -469,9 +469,11 @@ void CodeGen::genHWIntrinsic_R_RM(
switch (addr->OperGet())
{
case GT_LCL_VAR_ADDR:
+ case GT_LCL_FLD_ADDR:
{
+ assert(addr->isContained());
varNum = addr->AsLclVarCommon()->GetLclNum();
- offset = 0;
+ offset = addr->AsLclVarCommon()->GetLclOffs();
break;
}
@@ -698,9 +700,11 @@ void CodeGen::genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins,
switch (addr->OperGet())
{
case GT_LCL_VAR_ADDR:
+ case GT_LCL_FLD_ADDR:
{
+ assert(addr->isContained());
varNum = addr->AsLclVarCommon()->GetLclNum();
- offset = 0;
+ offset = addr->AsLclVarCommon()->GetLclOffs();
break;
}
@@ -861,9 +865,11 @@ void CodeGen::genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins)
switch (addr->OperGet())
{
case GT_LCL_VAR_ADDR:
+ case GT_LCL_FLD_ADDR:
{
+ assert(addr->isContained());
varNum = addr->AsLclVarCommon()->GetLclNum();
- offset = 0;
+ offset = addr->AsLclVarCommon()->GetLclOffs();
break;
}
@@ -986,9 +992,11 @@ void CodeGen::genHWIntrinsic_R_R_R_RM(
switch (addr->OperGet())
{
case GT_LCL_VAR_ADDR:
+ case GT_LCL_FLD_ADDR:
{
+ assert(addr->isContained());
varNum = addr->AsLclVarCommon()->GetLclNum();
- offset = 0;
+ offset = addr->AsLclVarCommon()->GetLclOffs();
break;
}
diff --git a/src/coreclr/src/jit/hwintrinsicxarch.cpp b/src/coreclr/src/jit/hwintrinsicxarch.cpp
index 8d7824ea189b64..e624f18e713f94 100644
--- a/src/coreclr/src/jit/hwintrinsicxarch.cpp
+++ b/src/coreclr/src/jit/hwintrinsicxarch.cpp
@@ -405,11 +405,12 @@ bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa)
case InstructionSet_BMI2_X64:
case InstructionSet_LZCNT:
case InstructionSet_LZCNT_X64:
- case InstructionSet_POPCNT:
- case InstructionSet_POPCNT_X64:
case InstructionSet_X86Base:
case InstructionSet_X86Base_X64:
{
+ // InstructionSet_POPCNT and InstructionSet_POPCNT_X64 are excluded
+ // even though they are "scalar" ISA because they depend on SSE4.2
+ // and Popcnt.IsSupported implies Sse42.IsSupported
return true;
}
diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp
index e3efd08dbe309e..463054b9b989ad 100644
--- a/src/coreclr/src/jit/importer.cpp
+++ b/src/coreclr/src/jit/importer.cpp
@@ -1392,8 +1392,8 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr,
}
else if (asgType == TYP_STRUCT)
{
- asgType = impNormStructType(structHnd);
- src->gtType = asgType;
+ // It should already have the appropriate type.
+ assert(asgType == impNormStructType(structHnd));
}
if ((dest == nullptr) && (destAddr->OperGet() == GT_ADDR))
{
@@ -2117,11 +2117,18 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken
nullptr DEBUGARG("impRuntimeLookup indirectOffset"));
}
+ // The last indirection could be subject to a size check (dynamic dictionary expansion)
+ bool isLastIndirectionWithSizeCheck =
+ ((i == pRuntimeLookup->indirections - 1) && (pRuntimeLookup->sizeOffset != CORINFO_NO_SIZE_CHECK));
+
if (i != 0)
{
slotPtrTree = gtNewOperNode(GT_IND, TYP_I_IMPL, slotPtrTree);
slotPtrTree->gtFlags |= GTF_IND_NONFAULTING;
- slotPtrTree->gtFlags |= GTF_IND_INVARIANT;
+ if (!isLastIndirectionWithSizeCheck)
+ {
+ slotPtrTree->gtFlags |= GTF_IND_INVARIANT;
+ }
}
if ((i == 1 && pRuntimeLookup->indirectFirstOffset) || (i == 2 && pRuntimeLookup->indirectSecondOffset))
@@ -2131,8 +2138,7 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken
if (pRuntimeLookup->offsets[i] != 0)
{
- // The last indirection could be subject to a size check (dynamic dictionary expansion)
- if (i == pRuntimeLookup->indirections - 1 && pRuntimeLookup->sizeOffset != CORINFO_NO_SIZE_CHECK)
+ if (isLastIndirectionWithSizeCheck)
{
lastIndOfTree = impCloneExpr(slotPtrTree, &slotPtrTree, NO_CLASS_HANDLE, (unsigned)CHECK_SPILL_ALL,
nullptr DEBUGARG("impRuntimeLookup indirectOffset"));
@@ -3623,31 +3629,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
GenTree* op1;
GenTree* op2;
- case CORINFO_INTRINSIC_Sin:
- case CORINFO_INTRINSIC_Cbrt:
- case CORINFO_INTRINSIC_Sqrt:
- case CORINFO_INTRINSIC_Abs:
- case CORINFO_INTRINSIC_Cos:
- case CORINFO_INTRINSIC_Round:
- case CORINFO_INTRINSIC_Cosh:
- case CORINFO_INTRINSIC_Sinh:
- case CORINFO_INTRINSIC_Tan:
- case CORINFO_INTRINSIC_Tanh:
- case CORINFO_INTRINSIC_Asin:
- case CORINFO_INTRINSIC_Asinh:
- case CORINFO_INTRINSIC_Acos:
- case CORINFO_INTRINSIC_Acosh:
- case CORINFO_INTRINSIC_Atan:
- case CORINFO_INTRINSIC_Atan2:
- case CORINFO_INTRINSIC_Atanh:
- case CORINFO_INTRINSIC_Log10:
- case CORINFO_INTRINSIC_Pow:
- case CORINFO_INTRINSIC_Exp:
- case CORINFO_INTRINSIC_Ceiling:
- case CORINFO_INTRINSIC_Floor:
- retNode = impMathIntrinsic(method, sig, callType, intrinsicID, tailCall);
- break;
-
#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
// TODO-ARM-CQ: reenable treating Interlocked operation as intrinsic
@@ -3921,7 +3902,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
{
JITDUMP("Expanding as special intrinsic\n");
impPopStack();
- op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, intrinsicID, method);
+ op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, intrinsicID, ni, method);
// Set the CALL flag to indicate that the operator is implemented by a call.
// Set also the EXCEPTION flag because the native implementation of
@@ -4218,7 +4199,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
#ifdef FEATURE_HW_INTRINSICS
case NI_System_Math_FusedMultiplyAdd:
- case NI_System_MathF_FusedMultiplyAdd:
{
#ifdef TARGET_XARCH
if (compExactlyDependsOn(InstructionSet_FMA) && supportSIMDTypes())
@@ -4227,9 +4207,9 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
// We are constructing a chain of intrinsics similar to:
// return FMA.MultiplyAddScalar(
- // Vector128.CreateScalar(x),
- // Vector128.CreateScalar(y),
- // Vector128.CreateScalar(z)
+ // Vector128.CreateScalarUnsafe(x),
+ // Vector128.CreateScalarUnsafe(y),
+ // Vector128.CreateScalarUnsafe(z)
// ).ToScalar();
GenTree* op3 = gtNewSimdHWIntrinsicNode(TYP_SIMD16, impPopStack().val,
@@ -4243,20 +4223,66 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
retNode = gtNewSimdHWIntrinsicNode(callType, res, NI_Vector128_ToScalar, callType, 16);
}
-#endif // TARGET_XARCH
+#elif defined(TARGET_ARM64)
+ if (compExactlyDependsOn(InstructionSet_AdvSimd))
+ {
+ assert(varTypeIsFloating(callType));
+
+ // We are constructing a chain of intrinsics similar to:
+ // return AdvSimd.FusedMultiplyAddScalar(
+ // Vector64.Create{ScalarUnsafe}(z),
+ // Vector64.Create{ScalarUnsafe}(y),
+ // Vector64.Create{ScalarUnsafe}(x)
+ // ).ToScalar();
+
+ NamedIntrinsic createVector64 =
+ (callType == TYP_DOUBLE) ? NI_Vector64_Create : NI_Vector64_CreateScalarUnsafe;
+
+ constexpr unsigned int simdSize = 8;
+
+ GenTree* op3 =
+ gtNewSimdHWIntrinsicNode(TYP_SIMD8, impPopStack().val, createVector64, callType, simdSize);
+ GenTree* op2 =
+ gtNewSimdHWIntrinsicNode(TYP_SIMD8, impPopStack().val, createVector64, callType, simdSize);
+ GenTree* op1 =
+ gtNewSimdHWIntrinsicNode(TYP_SIMD8, impPopStack().val, createVector64, callType, simdSize);
+
+ // Note that AdvSimd.FusedMultiplyAddScalar(op1,op2,op3) corresponds to op1 + op2 * op3
+ // while Math{F}.FusedMultiplyAddScalar(op1,op2,op3) corresponds to op1 * op2 + op3
+ retNode = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op3, op2, op1, NI_AdvSimd_FusedMultiplyAddScalar,
+ callType, simdSize);
+
+ retNode = gtNewSimdHWIntrinsicNode(callType, retNode, NI_Vector64_ToScalar, callType, simdSize);
+ }
+#endif
break;
}
#endif // FEATURE_HW_INTRINSICS
+ case NI_System_Math_Sin:
+ case NI_System_Math_Cbrt:
+ case NI_System_Math_Sqrt:
+ case NI_System_Math_Abs:
+ case NI_System_Math_Cos:
case NI_System_Math_Round:
- case NI_System_MathF_Round:
- {
- // Math.Round and MathF.Round used to be a traditional JIT intrinsic. In order
- // to simplify the transition, we will just treat it as if it was still the
- // old intrinsic, CORINFO_INTRINSIC_Round. This should end up flowing properly
- // everywhere else.
-
- retNode = impMathIntrinsic(method, sig, callType, CORINFO_INTRINSIC_Round, tailCall);
+ case NI_System_Math_Cosh:
+ case NI_System_Math_Sinh:
+ case NI_System_Math_Tan:
+ case NI_System_Math_Tanh:
+ case NI_System_Math_Asin:
+ case NI_System_Math_Asinh:
+ case NI_System_Math_Acos:
+ case NI_System_Math_Acosh:
+ case NI_System_Math_Atan:
+ case NI_System_Math_Atan2:
+ case NI_System_Math_Atanh:
+ case NI_System_Math_Log10:
+ case NI_System_Math_Pow:
+ case NI_System_Math_Exp:
+ case NI_System_Math_Ceiling:
+ case NI_System_Math_Floor:
+ {
+ retNode = impMathIntrinsic(method, sig, callType, ni, tailCall);
break;
}
@@ -4345,14 +4371,14 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
var_types callType,
- CorInfoIntrinsics intrinsicID,
+ NamedIntrinsic intrinsicName,
bool tailCall)
{
GenTree* op1;
GenTree* op2;
assert(callType != TYP_STRUCT);
- assert(IsMathIntrinsic(intrinsicID));
+ assert(IsMathIntrinsic(intrinsicName));
op1 = nullptr;
@@ -4363,12 +4389,12 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method,
// a) For back compatibility reasons on desktop .NET Framework 4.6 / 4.6.1
// b) It will be non-trivial task or too late to re-materialize a surviving
// tail prefixed GT_INTRINSIC as tail call in rationalizer.
- if (!IsIntrinsicImplementedByUserCall(intrinsicID) || !tailCall)
+ if (!IsIntrinsicImplementedByUserCall(intrinsicName) || !tailCall)
#else
// On x86 RyuJIT, importing intrinsics that are implemented as user calls can cause incorrect calculation
// of the depth of the stack if these intrinsics are used as arguments to another call. This causes bad
// code generation for certain EH constructs.
- if (!IsIntrinsicImplementedByUserCall(intrinsicID))
+ if (!IsIntrinsicImplementedByUserCall(intrinsicName))
#endif
{
switch (sig->numArgs)
@@ -4383,7 +4409,8 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method,
op1 = gtNewCastNode(callType, op1, false, callType);
}
- op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, intrinsicID, method);
+ op1 = new (this, GT_INTRINSIC)
+ GenTreeIntrinsic(genActualType(callType), op1, CORINFO_INTRINSIC_Illegal, intrinsicName, method);
break;
case 2:
@@ -4402,14 +4429,15 @@ GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method,
op1 = gtNewCastNode(callType, op1, false, callType);
}
- op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, op2, intrinsicID, method);
+ op1 = new (this, GT_INTRINSIC) GenTreeIntrinsic(genActualType(callType), op1, op2,
+ CORINFO_INTRINSIC_Illegal, intrinsicName, method);
break;
default:
- NO_WAY("Unsupported number of args for Math Instrinsic");
+ NO_WAY("Unsupported number of args for Math Intrinsic");
}
- if (IsIntrinsicImplementedByUserCall(intrinsicID))
+ if (IsIntrinsicImplementedByUserCall(intrinsicName))
{
op1->gtFlags |= GTF_CALL;
}
@@ -4474,31 +4502,99 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
{
result = NI_System_Enum_HasFlag;
}
- else if (strncmp(className, "Math", 4) == 0)
+ else if (strcmp(className, "Math") == 0 || strcmp(className, "MathF") == 0)
{
- className += 4;
-
- if (className[0] == '\0')
+ if (strcmp(methodName, "FusedMultiplyAdd") == 0)
{
- if (strcmp(methodName, "FusedMultiplyAdd") == 0)
- {
- result = NI_System_Math_FusedMultiplyAdd;
- }
- else if (strcmp(methodName, "Round") == 0)
- {
- result = NI_System_Math_Round;
- }
+ result = NI_System_Math_FusedMultiplyAdd;
}
- else if (strcmp(className, "F") == 0)
+ else if (strcmp(methodName, "Round") == 0)
{
- if (strcmp(methodName, "FusedMultiplyAdd") == 0)
- {
- result = NI_System_MathF_FusedMultiplyAdd;
- }
- else if (strcmp(methodName, "Round") == 0)
- {
- result = NI_System_MathF_Round;
- }
+ result = NI_System_Math_Round;
+ }
+ else if (strcmp(methodName, "Sin") == 0)
+ {
+ result = NI_System_Math_Sin;
+ }
+ else if (strcmp(methodName, "Cos") == 0)
+ {
+ result = NI_System_Math_Cos;
+ }
+ else if (strcmp(methodName, "Cbrt") == 0)
+ {
+ result = NI_System_Math_Cbrt;
+ }
+ else if (strcmp(methodName, "Sqrt") == 0)
+ {
+ result = NI_System_Math_Sqrt;
+ }
+ else if (strcmp(methodName, "Abs") == 0)
+ {
+ result = NI_System_Math_Abs;
+ }
+ else if (strcmp(methodName, "Cosh") == 0)
+ {
+ result = NI_System_Math_Cosh;
+ }
+ else if (strcmp(methodName, "Sinh") == 0)
+ {
+ result = NI_System_Math_Sinh;
+ }
+ else if (strcmp(methodName, "Tan") == 0)
+ {
+ result = NI_System_Math_Tan;
+ }
+ else if (strcmp(methodName, "Tanh") == 0)
+ {
+ result = NI_System_Math_Tanh;
+ }
+ else if (strcmp(methodName, "Asin") == 0)
+ {
+ result = NI_System_Math_Asin;
+ }
+ else if (strcmp(methodName, "Asinh") == 0)
+ {
+ result = NI_System_Math_Asinh;
+ }
+ else if (strcmp(methodName, "Acos") == 0)
+ {
+ result = NI_System_Math_Acos;
+ }
+ else if (strcmp(methodName, "Acosh") == 0)
+ {
+ result = NI_System_Math_Acosh;
+ }
+ else if (strcmp(methodName, "Atan") == 0)
+ {
+ result = NI_System_Math_Atan;
+ }
+ else if (strcmp(methodName, "Atan2") == 0)
+ {
+ result = NI_System_Math_Atan2;
+ }
+ else if (strcmp(methodName, "Atanh") == 0)
+ {
+ result = NI_System_Math_Atanh;
+ }
+ else if (strcmp(methodName, "Log10") == 0)
+ {
+ result = NI_System_Math_Log10;
+ }
+ else if (strcmp(methodName, "Pow") == 0)
+ {
+ result = NI_System_Math_Pow;
+ }
+ else if (strcmp(methodName, "Exp") == 0)
+ {
+ result = NI_System_Math_Exp;
+ }
+ else if (strcmp(methodName, "Ceiling") == 0)
+ {
+ result = NI_System_Math_Ceiling;
+ }
+ else if (strcmp(methodName, "Floor") == 0)
+ {
+ result = NI_System_Math_Floor;
}
}
else if (strcmp(className, "GC") == 0)
@@ -4796,7 +4892,14 @@ GenTree* Compiler::impArrayAccessIntrinsic(
if (intrinsicID != CORINFO_INTRINSIC_Array_Address)
{
- arrElem = gtNewOperNode(GT_IND, elemType, arrElem);
+ if (varTypeIsStruct(elemType))
+ {
+ arrElem = gtNewObjNode(sig->retTypeClass, arrElem);
+ }
+ else
+ {
+ arrElem = gtNewOperNode(GT_IND, elemType, arrElem);
+ }
}
if (intrinsicID == CORINFO_INTRINSIC_Array_Set)
@@ -7709,7 +7812,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
// If this is a call to JitTestLabel.Mark, do "early inlining", and record the test attribute.
// This recognition should really be done by knowing the methHnd of the relevant Mark method(s).
- // These should be in mscorlib.h, and available through a JIT/EE interface call.
+ // These should be in corelib.h, and available through a JIT/EE interface call.
const char* modName;
const char* className;
const char* methodName;
@@ -7944,9 +8047,9 @@ var_types Compiler::impImportCall(OPCODE opcode,
// This is for a non-virtual, non-interface etc. call
call = gtNewCallNode(CT_USER_FUNC, callInfo->hMethod, callRetTyp, nullptr, ilOffset);
- // We remove the nullcheck for the GetType call instrinsic.
+ // We remove the nullcheck for the GetType call intrinsic.
// TODO-CQ: JIT64 does not introduce the null check for many more helper calls
- // and instrinsics.
+ // and intrinsics.
if (callInfo->nullInstanceCheck &&
!((mflags & CORINFO_FLG_INTRINSIC) != 0 && (intrinsicID == CORINFO_INTRINSIC_Object_GetType)))
{
@@ -8577,7 +8680,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
if (canTailCall &&
!impTailCallRetTypeCompatible(info.compRetType, info.compMethodInfo->args.retTypeClass, callRetTyp,
- callInfo->sig.retTypeClass))
+ sig->retTypeClass))
{
canTailCall = false;
szCanTailCallFailReason = "Return types are not tail call compatible";
@@ -13188,10 +13291,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// via an underlying address, just null check the address.
if (op1->OperIs(GT_FIELD, GT_IND, GT_OBJ))
{
- op1->ChangeOper(GT_NULLCHECK);
- block->bbFlags |= BBF_HAS_NULLCHECK;
- optMethodFlags |= OMF_HAS_NULLCHECK;
- op1->gtType = TYP_BYTE;
+ gtChangeOperToNullCheck(op1, block);
}
else
{
@@ -20072,10 +20172,10 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call,
// Returns true if the given intrinsic will be implemented by target-specific
// instructions
-bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId)
+bool Compiler::IsTargetIntrinsic(NamedIntrinsic intrinsicName)
{
#if defined(TARGET_XARCH)
- switch (intrinsicId)
+ switch (intrinsicName)
{
// AMD64/x86 has SSE2 instructions to directly compute sqrt/abs and SSE4.1
// instructions to directly compute round/ceiling/floor.
@@ -20086,37 +20186,37 @@ bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId)
// a CQ problem, it may be necessary to change the implementation of
// the helper calls to decrease call overhead or switch back to the
// x87 instructions. This is tracked by #7097.
- case CORINFO_INTRINSIC_Sqrt:
- case CORINFO_INTRINSIC_Abs:
+ case NI_System_Math_Sqrt:
+ case NI_System_Math_Abs:
return true;
- case CORINFO_INTRINSIC_Round:
- case CORINFO_INTRINSIC_Ceiling:
- case CORINFO_INTRINSIC_Floor:
+ case NI_System_Math_Round:
+ case NI_System_Math_Ceiling:
+ case NI_System_Math_Floor:
return compOpportunisticallyDependsOn(InstructionSet_SSE41);
default:
return false;
}
#elif defined(TARGET_ARM64)
- switch (intrinsicId)
+ switch (intrinsicName)
{
- case CORINFO_INTRINSIC_Sqrt:
- case CORINFO_INTRINSIC_Abs:
- case CORINFO_INTRINSIC_Round:
- case CORINFO_INTRINSIC_Floor:
- case CORINFO_INTRINSIC_Ceiling:
+ case NI_System_Math_Sqrt:
+ case NI_System_Math_Abs:
+ case NI_System_Math_Round:
+ case NI_System_Math_Floor:
+ case NI_System_Math_Ceiling:
return true;
default:
return false;
}
#elif defined(TARGET_ARM)
- switch (intrinsicId)
+ switch (intrinsicName)
{
- case CORINFO_INTRINSIC_Sqrt:
- case CORINFO_INTRINSIC_Abs:
- case CORINFO_INTRINSIC_Round:
+ case NI_System_Math_Sqrt:
+ case NI_System_Math_Abs:
+ case NI_System_Math_Round:
return true;
default:
@@ -20134,41 +20234,41 @@ bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId)
// Returns true if the given intrinsic will be implemented by calling System.Math
// methods.
-bool Compiler::IsIntrinsicImplementedByUserCall(CorInfoIntrinsics intrinsicId)
+bool Compiler::IsIntrinsicImplementedByUserCall(NamedIntrinsic intrinsicName)
{
// Currently, if a math intrinsic is not implemented by target-specific
// instructions, it will be implemented by a System.Math call. In the
// future, if we turn to implementing some of them with helper calls,
// this predicate needs to be revisited.
- return !IsTargetIntrinsic(intrinsicId);
+ return !IsTargetIntrinsic(intrinsicName);
}
-bool Compiler::IsMathIntrinsic(CorInfoIntrinsics intrinsicId)
+bool Compiler::IsMathIntrinsic(NamedIntrinsic intrinsicName)
{
- switch (intrinsicId)
- {
- case CORINFO_INTRINSIC_Sin:
- case CORINFO_INTRINSIC_Cbrt:
- case CORINFO_INTRINSIC_Sqrt:
- case CORINFO_INTRINSIC_Abs:
- case CORINFO_INTRINSIC_Cos:
- case CORINFO_INTRINSIC_Round:
- case CORINFO_INTRINSIC_Cosh:
- case CORINFO_INTRINSIC_Sinh:
- case CORINFO_INTRINSIC_Tan:
- case CORINFO_INTRINSIC_Tanh:
- case CORINFO_INTRINSIC_Asin:
- case CORINFO_INTRINSIC_Asinh:
- case CORINFO_INTRINSIC_Acos:
- case CORINFO_INTRINSIC_Acosh:
- case CORINFO_INTRINSIC_Atan:
- case CORINFO_INTRINSIC_Atan2:
- case CORINFO_INTRINSIC_Atanh:
- case CORINFO_INTRINSIC_Log10:
- case CORINFO_INTRINSIC_Pow:
- case CORINFO_INTRINSIC_Exp:
- case CORINFO_INTRINSIC_Ceiling:
- case CORINFO_INTRINSIC_Floor:
+ switch (intrinsicName)
+ {
+ case NI_System_Math_Sin:
+ case NI_System_Math_Cbrt:
+ case NI_System_Math_Sqrt:
+ case NI_System_Math_Abs:
+ case NI_System_Math_Cos:
+ case NI_System_Math_Round:
+ case NI_System_Math_Cosh:
+ case NI_System_Math_Sinh:
+ case NI_System_Math_Tan:
+ case NI_System_Math_Tanh:
+ case NI_System_Math_Asin:
+ case NI_System_Math_Asinh:
+ case NI_System_Math_Acos:
+ case NI_System_Math_Acosh:
+ case NI_System_Math_Atan:
+ case NI_System_Math_Atan2:
+ case NI_System_Math_Atanh:
+ case NI_System_Math_Log10:
+ case NI_System_Math_Pow:
+ case NI_System_Math_Exp:
+ case NI_System_Math_Ceiling:
+ case NI_System_Math_Floor:
return true;
default:
return false;
@@ -20177,7 +20277,7 @@ bool Compiler::IsMathIntrinsic(CorInfoIntrinsics intrinsicId)
bool Compiler::IsMathIntrinsic(GenTree* tree)
{
- return (tree->OperGet() == GT_INTRINSIC) && IsMathIntrinsic(tree->AsIntrinsic()->gtIntrinsicId);
+ return (tree->OperGet() == GT_INTRINSIC) && IsMathIntrinsic(tree->AsIntrinsic()->gtIntrinsicName);
}
//------------------------------------------------------------------------
diff --git a/src/coreclr/src/jit/inline.cpp b/src/coreclr/src/jit/inline.cpp
index 9b4d6f1686145f..759a6e36618129 100644
--- a/src/coreclr/src/jit/inline.cpp
+++ b/src/coreclr/src/jit/inline.cpp
@@ -1624,7 +1624,7 @@ void InlineStrategy::DumpXml(FILE* file, unsigned indent)
// Root context will be null if we're not optimizing the method.
//
- // Note there are cases of this in mscorlib even in release builds,
+ // Note there are cases of this in System.Private.CoreLib even in release builds,
// eg Task.NotifyDebuggerOfWaitCompletion.
//
// For such methods there aren't any inlines.
diff --git a/src/coreclr/src/jit/inlinepolicy.cpp b/src/coreclr/src/jit/inlinepolicy.cpp
index 8852991cf20010..09a029f9966382 100644
--- a/src/coreclr/src/jit/inlinepolicy.cpp
+++ b/src/coreclr/src/jit/inlinepolicy.cpp
@@ -1700,7 +1700,7 @@ void DiscretionaryPolicy::MethodInfoObservations(CORINFO_METHOD_INFO* methodInfo
// 0.100 * m_CalleeNativeSizeEstimate +
// -0.100 * m_CallsiteNativeSizeEstimate
//
-// On the inlines in CoreCLR's mscorlib, release windows x64, this
+// On the inlines in CoreCLR's CoreLib, release windows x64, this
// yields scores of R=0.42, MSE=228, and MAE=7.25.
//
// This estimate can be improved slighly by refitting, resulting in
diff --git a/src/coreclr/src/jit/instr.cpp b/src/coreclr/src/jit/instr.cpp
index a13887baa0f6dc..d6f4c98f6b9470 100644
--- a/src/coreclr/src/jit/instr.cpp
+++ b/src/coreclr/src/jit/instr.cpp
@@ -478,7 +478,7 @@ void CodeGen::inst_IV_handle(instruction ins, int val)
void CodeGen::inst_set_SV_var(GenTree* tree)
{
#ifdef DEBUG
- assert(tree && (tree->gtOper == GT_LCL_VAR || tree->gtOper == GT_LCL_VAR_ADDR || tree->gtOper == GT_STORE_LCL_VAR));
+ assert((tree != nullptr) && tree->OperIs(GT_LCL_VAR, GT_LCL_VAR_ADDR, GT_STORE_LCL_VAR));
assert(tree->AsLclVarCommon()->GetLclNum() < compiler->lvaCount);
GetEmitter()->emitVarRefOffs = tree->AsLclVar()->gtLclILoffs;
@@ -1019,9 +1019,11 @@ void CodeGen::inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenT
switch (addr->OperGet())
{
case GT_LCL_VAR_ADDR:
+ case GT_LCL_FLD_ADDR:
{
+ assert(addr->isContained());
varNum = addr->AsLclVarCommon()->GetLclNum();
- offset = 0;
+ offset = addr->AsLclVarCommon()->GetLclOffs();
break;
}
@@ -1146,9 +1148,11 @@ void CodeGen::inst_RV_RV_TT(
switch (addr->OperGet())
{
case GT_LCL_VAR_ADDR:
+ case GT_LCL_FLD_ADDR:
{
+ assert(addr->isContained());
varNum = addr->AsLclVarCommon()->GetLclNum();
- offset = 0;
+ offset = addr->AsLclVarCommon()->GetLclOffs();
break;
}
diff --git a/src/coreclr/src/jit/jitconfigvalues.h b/src/coreclr/src/jit/jitconfigvalues.h
index e6c1ab307e460a..329f526e90046d 100644
--- a/src/coreclr/src/jit/jitconfigvalues.h
+++ b/src/coreclr/src/jit/jitconfigvalues.h
@@ -285,6 +285,20 @@ CONFIG_INTEGER(JitDisableSimdVN, W("JitDisableSimdVN"), 0) // Default 0, ValueNu
// If 3, disable both SIMD and HW Intrinsic nodes
#endif // FEATURE_SIMD
+// Default 0, enable the CSE of Constants, including nearby offsets. (only for ARM64)
+// If 1, disable all the CSE of Constants
+// If 2, enable the CSE of Constants but don't combine with nearby offsets. (only for ARM64)
+// If 3, enable the CSE of Constants including nearby offsets. (all platforms)
+// If 4, enable the CSE of Constants but don't combine with nearby offsets. (all platforms)
+//
+CONFIG_INTEGER(JitConstCSE, W("JitConstCSE"), 0)
+
+#define CONST_CSE_ENABLE_ARM64 0
+#define CONST_CSE_DISABLE_ALL 1
+#define CONST_CSE_ENABLE_ARM64_NO_SHARING 2
+#define CONST_CSE_ENABLE_ALL 3
+#define CONST_CSE_ENABLE_ALL_NO_SHARING 4
+
///
/// JIT
///
diff --git a/src/coreclr/src/jit/jithashtable.cpp b/src/coreclr/src/jit/jithashtable.cpp
new file mode 100644
index 00000000000000..cf9f22639efe16
--- /dev/null
+++ b/src/coreclr/src/jit/jithashtable.cpp
@@ -0,0 +1,53 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#include "jitpch.h"
+
+#if defined(_MSC_VER)
+#pragma hdrstop
+#endif // defined(_MSC_VER)
+
+// Table of primes and their magic-number-divide constant.
+// For more info see the book "Hacker's Delight" chapter 10.9 "Unsigned Division by Divisors >= 1"
+// These were selected by looking for primes, each roughly twice as big as the next, having
+// 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower).
+
+#include "jithashtable.h"
+
+// Table of primes and their magic-number-divide constant.
+// For more info see the book "Hacker's Delight" chapter 10.9 "Unsigned Division by Divisors >= 1"
+// These were selected by looking for primes, each roughly twice as big as the next, having
+// 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower).
+
+// clang-format off
+const JitPrimeInfo jitPrimeInfo[]
+{
+ JitPrimeInfo(9, 0x38e38e39, 1),
+ JitPrimeInfo(23, 0xb21642c9, 4),
+ JitPrimeInfo(59, 0x22b63cbf, 3),
+ JitPrimeInfo(131, 0xfa232cf3, 7),
+ JitPrimeInfo(239, 0x891ac73b, 7),
+ JitPrimeInfo(433, 0x975a751, 4),
+ JitPrimeInfo(761, 0x561e46a5, 8),
+ JitPrimeInfo(1399, 0xbb612aa3, 10),
+ JitPrimeInfo(2473, 0x6a009f01, 10),
+ JitPrimeInfo(4327, 0xf2555049, 12),
+ JitPrimeInfo(7499, 0x45ea155f, 11),
+ JitPrimeInfo(12973, 0x1434f6d3, 10),
+ JitPrimeInfo(22433, 0x2ebe18db, 12),
+ JitPrimeInfo(46559, 0xb42bebd5, 15),
+ JitPrimeInfo(96581, 0xadb61b1b, 16),
+ JitPrimeInfo(200341, 0x29df2461, 15),
+ JitPrimeInfo(415517, 0xa181c46d, 18),
+ JitPrimeInfo(861719, 0x4de0bde5, 18),
+ JitPrimeInfo(1787021, 0x9636c46f, 20),
+ JitPrimeInfo(3705617, 0x4870adc1, 20),
+ JitPrimeInfo(7684087, 0x8bbc5b83, 22),
+ JitPrimeInfo(15933877, 0x86c65361, 23),
+ JitPrimeInfo(33040633, 0x40fec79b, 23),
+ JitPrimeInfo(68513161, 0x7d605cd1, 25),
+ JitPrimeInfo(142069021, 0xf1da390b, 27),
+ JitPrimeInfo(294594427, 0x74a2507d, 27),
+ JitPrimeInfo(733045421, 0x5dbec447, 28),
+};
+// clang-format on
diff --git a/src/coreclr/src/jit/jithashtable.h b/src/coreclr/src/jit/jithashtable.h
index 4d2d19d1389ff4..131f804a1127fd 100644
--- a/src/coreclr/src/jit/jithashtable.h
+++ b/src/coreclr/src/jit/jithashtable.h
@@ -57,10 +57,10 @@ class JitHashTableBehavior
class JitPrimeInfo
{
public:
- JitPrimeInfo() : prime(0), magic(0), shift(0)
+ constexpr JitPrimeInfo() : prime(0), magic(0), shift(0)
{
}
- JitPrimeInfo(unsigned p, unsigned m, unsigned s) : prime(p), magic(m), shift(s)
+ constexpr JitPrimeInfo(unsigned p, unsigned m, unsigned s) : prime(p), magic(m), shift(s)
{
}
unsigned prime;
@@ -91,38 +91,7 @@ class JitPrimeInfo
// These were selected by looking for primes, each roughly twice as big as the next, having
// 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower).
-// clang-format off
-SELECTANY const JitPrimeInfo jitPrimeInfo[]
-{
- JitPrimeInfo(9, 0x38e38e39, 1),
- JitPrimeInfo(23, 0xb21642c9, 4),
- JitPrimeInfo(59, 0x22b63cbf, 3),
- JitPrimeInfo(131, 0xfa232cf3, 7),
- JitPrimeInfo(239, 0x891ac73b, 7),
- JitPrimeInfo(433, 0x975a751, 4),
- JitPrimeInfo(761, 0x561e46a5, 8),
- JitPrimeInfo(1399, 0xbb612aa3, 10),
- JitPrimeInfo(2473, 0x6a009f01, 10),
- JitPrimeInfo(4327, 0xf2555049, 12),
- JitPrimeInfo(7499, 0x45ea155f, 11),
- JitPrimeInfo(12973, 0x1434f6d3, 10),
- JitPrimeInfo(22433, 0x2ebe18db, 12),
- JitPrimeInfo(46559, 0xb42bebd5, 15),
- JitPrimeInfo(96581, 0xadb61b1b, 16),
- JitPrimeInfo(200341, 0x29df2461, 15),
- JitPrimeInfo(415517, 0xa181c46d, 18),
- JitPrimeInfo(861719, 0x4de0bde5, 18),
- JitPrimeInfo(1787021, 0x9636c46f, 20),
- JitPrimeInfo(3705617, 0x4870adc1, 20),
- JitPrimeInfo(7684087, 0x8bbc5b83, 22),
- JitPrimeInfo(15933877, 0x86c65361, 23),
- JitPrimeInfo(33040633, 0x40fec79b, 23),
- JitPrimeInfo(68513161, 0x7d605cd1, 25),
- JitPrimeInfo(142069021, 0xf1da390b, 27),
- JitPrimeInfo(294594427, 0x74a2507d, 27),
- JitPrimeInfo(733045421, 0x5dbec447, 28),
-};
-// clang-format on
+extern const JitPrimeInfo jitPrimeInfo[27];
// Hash table class definition
diff --git a/src/coreclr/src/jit/liveness.cpp b/src/coreclr/src/jit/liveness.cpp
index feb8f23a222eda..cbc4ebbd05af51 100644
--- a/src/coreclr/src/jit/liveness.cpp
+++ b/src/coreclr/src/jit/liveness.cpp
@@ -1980,17 +1980,13 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR
GenTree* data =
store->OperIs(GT_STOREIND) ? store->AsStoreInd()->Data() : store->AsBlk()->Data();
data->SetUnusedValue();
+
if (data->isIndir())
{
- // This is a block assignment. An indirection of the rhs is not considered
- // to happen until the assignment so mark it as non-faulting.
- data->gtFlags |= GTF_IND_NONFAULTING;
+ Lowering::TransformUnusedIndirection(data->AsIndir(), this, block);
}
- blockRange.Remove(store);
-
- assert(!opts.MinOpts());
- fgStmtRemoved = true;
+ fgRemoveDeadStoreLIR(store, block);
}
}
}
@@ -2019,25 +2015,7 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR
// Remove the store. DCE will iteratively clean up any ununsed operands.
lclVarNode->gtOp1->SetUnusedValue();
- // If the store is marked as a late argument, it is referenced by a call. Instead of removing
- // it, bash it to a NOP.
- if ((node->gtFlags & GTF_LATE_ARG) != 0)
- {
- JITDUMP("node is a late arg; replacing with NOP\n");
- node->gtBashToNOP();
-
- // NOTE: this is a bit of a hack. We need to keep these nodes around as they are
- // referenced by the call, but they're considered side-effect-free non-value-producing
- // nodes, so they will be removed if we don't do this.
- node->gtFlags |= GTF_ORDER_SIDEEFF;
- }
- else
- {
- blockRange.Remove(node);
- }
-
- assert(!opts.MinOpts());
- fgStmtRemoved = true;
+ fgRemoveDeadStoreLIR(node, block);
}
break;
@@ -2109,40 +2087,112 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR
break;
case GT_NOP:
+ {
// NOTE: we need to keep some NOPs around because they are referenced by calls. See the dead store
// removal code above (case GT_STORE_LCL_VAR) for more explanation.
if ((node->gtFlags & GTF_ORDER_SIDEEFF) != 0)
{
break;
}
- __fallthrough;
+ fgTryRemoveNonLocal(node, &blockRange);
+ }
+ break;
- default:
- assert(!node->OperIsLocal());
- if (!node->IsValue() || node->IsUnusedValue())
+ case GT_BLK:
+ case GT_OBJ:
+ case GT_DYN_BLK:
+ {
+ bool removed = fgTryRemoveNonLocal(node, &blockRange);
+ if (!removed && node->IsUnusedValue())
{
- // We are only interested in avoiding the removal of nodes with direct side-effects
- // (as opposed to side effects of their children).
- // This default case should never include calls or assignments.
- assert(!node->OperRequiresAsgFlag() && !node->OperIs(GT_CALL));
- if (!node->gtSetFlags() && !node->OperMayThrow(this))
- {
- JITDUMP("Removing dead node:\n");
- DISPNODE(node);
-
- node->VisitOperands([](GenTree* operand) -> GenTree::VisitResult {
- operand->SetUnusedValue();
- return GenTree::VisitResult::Continue;
- });
-
- blockRange.Remove(node);
- }
+ // IR doesn't expect dummy uses of `GT_OBJ/BLK/DYN_BLK`.
+ JITDUMP("Transform an unused OBJ/BLK node [%06d]\n", dspTreeID(node));
+ Lowering::TransformUnusedIndirection(node->AsIndir(), this, block);
}
+ }
+ break;
+
+ default:
+ fgTryRemoveNonLocal(node, &blockRange);
break;
}
}
}
+//---------------------------------------------------------------------
+// fgTryRemoveNonLocal - try to remove a node if it is unused and has no direct
+// side effects.
+//
+// Arguments
+// node - the non-local node to try;
+// blockRange - the block range that contains the node.
+//
+// Return value:
+// None
+//
+// Notes: local nodes are processed independently and are not expected in this function.
+//
+bool Compiler::fgTryRemoveNonLocal(GenTree* node, LIR::Range* blockRange)
+{
+ assert(!node->OperIsLocal());
+ if (!node->IsValue() || node->IsUnusedValue())
+ {
+ // We are only interested in avoiding the removal of nodes with direct side effects
+ // (as opposed to side effects of their children).
+ // This default case should never include calls or assignments.
+ assert(!node->OperRequiresAsgFlag() && !node->OperIs(GT_CALL));
+ if (!node->gtSetFlags() && !node->OperMayThrow(this))
+ {
+ JITDUMP("Removing dead node:\n");
+ DISPNODE(node);
+
+ node->VisitOperands([](GenTree* operand) -> GenTree::VisitResult {
+ operand->SetUnusedValue();
+ return GenTree::VisitResult::Continue;
+ });
+
+ blockRange->Remove(node);
+ return true;
+ }
+ }
+ return false;
+}
+
+//---------------------------------------------------------------------
+// fgRemoveDeadStoreSimple - remove a dead store
+//
+// pTree - GenTree** to local, including store-form local or local addr (post-rationalize)
+// varDsc - var that is being stored to
+// life - current live tracked vars (maintained as we walk backwards)
+// doAgain - out parameter, true if we should restart the statement
+// pStmtInfoDirty - should defer the cost computation to the point after the reverse walk is completed?
+//
+void Compiler::fgRemoveDeadStoreLIR(GenTree* store, BasicBlock* block)
+{
+ LIR::Range& blockRange = LIR::AsRange(block);
+
+ // If the store is marked as a late argument, it is referenced by a call.
+ // Instead of removing it, bash it to a NOP.
+ if ((store->gtFlags & GTF_LATE_ARG) != 0)
+ {
+ JITDUMP("node is a late arg; replacing with NOP\n");
+ store->gtBashToNOP();
+
+ // NOTE: this is a bit of a hack. We need to keep these nodes around as they are
+ // referenced by the call, but they're considered side-effect-free non-value-producing
+ // nodes, so they will be removed if we don't do this.
+ store->gtFlags |= GTF_ORDER_SIDEEFF;
+ }
+ else
+ {
+ blockRange.Remove(store);
+ }
+
+ assert(!opts.MinOpts());
+ fgStmtRemoved = true;
+}
+
+//---------------------------------------------------------------------
// fgRemoveDeadStore - remove a store to a local which has no exposed uses.
//
// pTree - GenTree** to local, including store-form local or local addr (post-rationalize)
@@ -2285,17 +2335,6 @@ bool Compiler::fgRemoveDeadStore(GenTree** pTree,
}
#endif // DEBUG
// Extract the side effects
- if (rhsNode->TypeGet() == TYP_STRUCT)
- {
- // This is a block assignment. An indirection of the rhs is not considered to
- // happen until the assignment, so we will extract the side effects from only
- // the address.
- if (rhsNode->OperIsIndir())
- {
- assert(rhsNode->OperGet() != GT_NULLCHECK);
- rhsNode = rhsNode->AsIndir()->Addr();
- }
- }
gtExtractSideEffList(rhsNode, &sideEffList);
}
diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp
index cc9e2891e9a47c..a401a843dd0a54 100644
--- a/src/coreclr/src/jit/lower.cpp
+++ b/src/coreclr/src/jit/lower.cpp
@@ -3181,7 +3181,9 @@ void Lowering::LowerStoreLocCommon(GenTreeLclVarCommon* lclStore)
// Create the assignment node.
lclStore->ChangeOper(GT_STORE_OBJ);
GenTreeBlk* objStore = lclStore->AsObj();
- objStore->gtFlags = GTF_ASG | GTF_IND_NONFAULTING | GTF_IND_TGT_NOT_HEAP;
+ // Only the GTF_LATE_ARG flag (if present) is preserved.
+ objStore->gtFlags &= GTF_LATE_ARG;
+ objStore->gtFlags |= GTF_ASG | GTF_IND_NONFAULTING | GTF_IND_TGT_NOT_HEAP;
#ifndef JIT32_GCENCODER
objStore->gtBlkOpGcUnsafe = false;
#endif
@@ -6450,41 +6452,7 @@ void Lowering::LowerIndir(GenTreeIndir* ind)
if (ind->OperIs(GT_NULLCHECK) || ind->IsUnusedValue())
{
- // A nullcheck is essentially the same as an indirection with no use.
- // The difference lies in whether a target register must be allocated.
- // On XARCH we can generate a compare with no target register as long as the addresss
- // is not contained.
- // On ARM64 we can generate a load to REG_ZR in all cases.
- // However, on ARM we must always generate a load to a register.
- // In the case where we require a target register, it is better to use GT_IND, since
- // GT_NULLCHECK is a non-value node and would therefore require an internal register
- // to use as the target. That is non-optimal because it will be modeled as conflicting
- // with the source register(s).
- // So, to summarize:
- // - On ARM64, always use GT_NULLCHECK for a dead indirection.
- // - On ARM, always use GT_IND.
- // - On XARCH, use GT_IND if we have a contained address, and GT_NULLCHECK otherwise.
- // In all cases, change the type to TYP_INT.
- //
- ind->gtType = TYP_INT;
-#ifdef TARGET_ARM64
- bool useNullCheck = true;
-#elif TARGET_ARM
- bool useNullCheck = false;
-#else // TARGET_XARCH
- bool useNullCheck = !ind->Addr()->isContained();
-#endif // !TARGET_XARCH
-
- if (useNullCheck && ind->OperIs(GT_IND))
- {
- ind->ChangeOper(GT_NULLCHECK);
- ind->ClearUnusedValue();
- }
- else if (!useNullCheck && ind->OperIs(GT_NULLCHECK))
- {
- ind->ChangeOper(GT_IND);
- ind->SetUnusedValue();
- }
+ TransformUnusedIndirection(ind, comp, m_block);
}
}
else
@@ -6496,6 +6464,55 @@ void Lowering::LowerIndir(GenTreeIndir* ind)
}
}
+//------------------------------------------------------------------------
+// TransformUnusedIndirection: change the opcode and the type of the unused indirection.
+//
+// Arguments:
+// ind - Indirection to transform.
+// comp - Compiler instance.
+// block - Basic block of the indirection.
+//
+void Lowering::TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, BasicBlock* block)
+{
+ // A nullcheck is essentially the same as an indirection with no use.
+ // The difference lies in whether a target register must be allocated.
+ // On XARCH we can generate a compare with no target register as long as the addresss
+ // is not contained.
+ // On ARM64 we can generate a load to REG_ZR in all cases.
+ // However, on ARM we must always generate a load to a register.
+ // In the case where we require a target register, it is better to use GT_IND, since
+ // GT_NULLCHECK is a non-value node and would therefore require an internal register
+ // to use as the target. That is non-optimal because it will be modeled as conflicting
+ // with the source register(s).
+ // So, to summarize:
+ // - On ARM64, always use GT_NULLCHECK for a dead indirection.
+ // - On ARM, always use GT_IND.
+ // - On XARCH, use GT_IND if we have a contained address, and GT_NULLCHECK otherwise.
+ // In all cases, change the type to TYP_INT.
+ //
+ assert(ind->OperIs(GT_NULLCHECK, GT_IND, GT_BLK, GT_OBJ));
+
+ ind->gtType = TYP_INT;
+#ifdef TARGET_ARM64
+ bool useNullCheck = true;
+#elif TARGET_ARM
+ bool useNullCheck = false;
+#else // TARGET_XARCH
+ bool useNullCheck = !ind->Addr()->isContained();
+#endif // !TARGET_XARCH
+
+ if (useNullCheck && !ind->OperIs(GT_NULLCHECK))
+ {
+ comp->gtChangeOperToNullCheck(ind, block);
+ ind->ClearUnusedValue();
+ }
+ else if (!useNullCheck && !ind->OperIs(GT_IND))
+ {
+ ind->ChangeOper(GT_IND);
+ ind->SetUnusedValue();
+ }
+}
+
//------------------------------------------------------------------------
// LowerBlockStoreCommon: a common logic to lower STORE_OBJ/BLK/DYN_BLK.
//
diff --git a/src/coreclr/src/jit/lower.h b/src/coreclr/src/jit/lower.h
index 0c620aebeb0f6b..ff13302c1ba992 100644
--- a/src/coreclr/src/jit/lower.h
+++ b/src/coreclr/src/jit/lower.h
@@ -8,6 +8,7 @@ XX Lower XX
XX XX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
#ifndef _LOWER_H_
@@ -326,12 +327,12 @@ class Lowering final : public Phase
void LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cmpOp);
void LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node);
void LowerHWIntrinsicDot(GenTreeHWIntrinsic* node);
- void LowerFusedMultiplyAdd(GenTreeHWIntrinsic* node);
-
#if defined(TARGET_XARCH)
+ void LowerFusedMultiplyAdd(GenTreeHWIntrinsic* node);
void LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node);
#elif defined(TARGET_ARM64)
bool IsValidConstForMovImm(GenTreeHWIntrinsic* node);
+ void LowerHWIntrinsicFusedMultiplyAddScalar(GenTreeHWIntrinsic* node);
#endif // !TARGET_XARCH && !TARGET_ARM64
union VectorConstant {
@@ -532,6 +533,8 @@ class Lowering final : public Phase
bool IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode, GenTree* node, bool* supportsRegOptional);
#endif // FEATURE_HW_INTRINSICS
+ static void TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, BasicBlock* block);
+
private:
static bool NodesAreEquivalentLeaves(GenTree* candidate, GenTree* storeInd);
diff --git a/src/coreclr/src/jit/lowerarmarch.cpp b/src/coreclr/src/jit/lowerarmarch.cpp
index 2ab6fa947822e0..6d46545f718d3d 100644
--- a/src/coreclr/src/jit/lowerarmarch.cpp
+++ b/src/coreclr/src/jit/lowerarmarch.cpp
@@ -517,6 +517,76 @@ void Lowering::LowerSIMD(GenTreeSIMD* simdNode)
#endif // FEATURE_SIMD
#ifdef FEATURE_HW_INTRINSICS
+
+//----------------------------------------------------------------------------------------------
+// LowerHWIntrinsicFusedMultiplyAddScalar: Lowers AdvSimd_FusedMultiplyAddScalar intrinsics
+// when some of the operands are negated by "containing" such negation.
+//
+// Arguments:
+// node - The original hardware intrinsic node
+//
+// | op1 | op2 | op3 |
+// | + | + | + | AdvSimd_FusedMultiplyAddScalar
+// | + | + | - | AdvSimd_FusedMultiplySubtractScalar
+// | + | - | + | AdvSimd_FusedMultiplySubtractScalar
+// | + | - | - | AdvSimd_FusedMultiplyAddScalar
+// | - | + | + | AdvSimd_FusedMultiplySubtractNegatedScalar
+// | - | + | - | AdvSimd_FusedMultiplyAddNegatedScalar
+// | - | - | + | AdvSimd_FusedMultiplyAddNegatedScalar
+// | - | - | - | AdvSimd_FusedMultiplySubtractNegatedScalar
+//
+void Lowering::LowerHWIntrinsicFusedMultiplyAddScalar(GenTreeHWIntrinsic* node)
+{
+ assert(node->gtHWIntrinsicId == NI_AdvSimd_FusedMultiplyAddScalar);
+
+ const HWIntrinsic intrin(node);
+
+ GenTree* op1 = intrin.op1;
+ GenTree* op2 = intrin.op2;
+ GenTree* op3 = intrin.op3;
+
+ auto lowerOperand = [this](GenTree* op) {
+ bool wasNegated = false;
+
+ if (op->OperIsHWIntrinsic() &&
+ ((op->AsHWIntrinsic()->gtHWIntrinsicId == NI_AdvSimd_Arm64_DuplicateToVector64) ||
+ (op->AsHWIntrinsic()->gtHWIntrinsicId == NI_Vector64_CreateScalarUnsafe)))
+ {
+ GenTreeHWIntrinsic* createVector64 = op->AsHWIntrinsic();
+ GenTree* valueOp = createVector64->gtGetOp1();
+
+ if (valueOp->OperIs(GT_NEG))
+ {
+ createVector64->gtOp1 = valueOp->gtGetOp1();
+ BlockRange().Remove(valueOp);
+ wasNegated = true;
+ }
+ }
+
+ return wasNegated;
+ };
+
+ const bool op1WasNegated = lowerOperand(op1);
+ const bool op2WasNegated = lowerOperand(op2);
+ const bool op3WasNegated = lowerOperand(op3);
+
+ if (op1WasNegated)
+ {
+ if (op2WasNegated != op3WasNegated)
+ {
+ node->gtHWIntrinsicId = NI_AdvSimd_FusedMultiplyAddNegatedScalar;
+ }
+ else
+ {
+ node->gtHWIntrinsicId = NI_AdvSimd_FusedMultiplySubtractNegatedScalar;
+ }
+ }
+ else if (op2WasNegated != op3WasNegated)
+ {
+ node->gtHWIntrinsicId = NI_AdvSimd_FusedMultiplySubtractScalar;
+ }
+}
+
//----------------------------------------------------------------------------------------------
// Lowering::LowerHWIntrinsic: Perform containment analysis for a hardware intrinsic node.
//
@@ -573,6 +643,10 @@ void Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
return;
}
+ case NI_AdvSimd_FusedMultiplyAddScalar:
+ LowerHWIntrinsicFusedMultiplyAddScalar(node);
+ break;
+
default:
break;
}
diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp
index 331c674eab9e7f..5266da117cf844 100644
--- a/src/coreclr/src/jit/lowerxarch.cpp
+++ b/src/coreclr/src/jit/lowerxarch.cpp
@@ -592,7 +592,7 @@ void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk)
*
* TODO-XArch-CQ: (Low-pri): Jit64 generates in-line code of 8 instructions for (i) above.
* There are hardly any occurrences of this conversion operation in platform
- * assemblies or in CQ perf benchmarks (1 occurrence in mscorlib, microsoft.jscript,
+ * assemblies or in CQ perf benchmarks (1 occurrence in corelib, microsoft.jscript,
* 1 occurence in Roslyn and no occurrences in system, system.core, system.numerics
* system.windows.forms, scimark, fractals, bio mums). If we ever find evidence that
* doing this optimization is a win, should consider generating in-lined code.
@@ -3439,8 +3439,7 @@ bool Lowering::IsRMWMemOpRootedAtStoreInd(GenTree* tree, GenTree** outIndirCandi
assert(storeInd->IsRMWStatusUnknown());
// Early out if indirDst is not one of the supported memory operands.
- if (indirDst->OperGet() != GT_LEA && indirDst->OperGet() != GT_LCL_VAR && indirDst->OperGet() != GT_LCL_VAR_ADDR &&
- indirDst->OperGet() != GT_CLS_VAR_ADDR && indirDst->OperGet() != GT_CNS_INT)
+ if (!indirDst->OperIs(GT_LEA, GT_LCL_VAR, GT_LCL_VAR_ADDR, GT_CLS_VAR_ADDR, GT_CNS_INT))
{
storeInd->SetRMWStatus(STOREIND_RMW_UNSUPPORTED_ADDR);
return false;
@@ -4452,14 +4451,13 @@ bool Lowering::LowerRMWMemOp(GenTreeIndir* storeInd)
}
else
{
- assert(indirCandidateChild->OperGet() == GT_LCL_VAR || indirCandidateChild->OperGet() == GT_LCL_VAR_ADDR ||
- indirCandidateChild->OperGet() == GT_CLS_VAR_ADDR || indirCandidateChild->OperGet() == GT_CNS_INT);
+ assert(indirCandidateChild->OperIs(GT_LCL_VAR, GT_LCL_VAR_ADDR, GT_CLS_VAR_ADDR, GT_CNS_INT));
// If it is a GT_LCL_VAR, it still needs the reg to hold the address.
// We would still need a reg for GT_CNS_INT if it doesn't fit within addressing mode base.
// For GT_CLS_VAR_ADDR, we don't need a reg to hold the address, because field address value is known at jit
// time. Also, we don't need a reg for GT_CLS_VAR_ADDR.
- if (indirCandidateChild->OperGet() == GT_LCL_VAR_ADDR || indirCandidateChild->OperGet() == GT_CLS_VAR_ADDR)
+ if (indirCandidateChild->OperIs(GT_LCL_VAR_ADDR, GT_CLS_VAR_ADDR))
{
indirDst->SetContained();
}
@@ -4616,10 +4614,10 @@ void Lowering::ContainCheckIntrinsic(GenTreeOp* node)
{
assert(node->OperIs(GT_INTRINSIC));
- CorInfoIntrinsics intrinsicId = node->AsIntrinsic()->gtIntrinsicId;
+ NamedIntrinsic intrinsicName = node->AsIntrinsic()->gtIntrinsicName;
- if (intrinsicId == CORINFO_INTRINSIC_Sqrt || intrinsicId == CORINFO_INTRINSIC_Round ||
- intrinsicId == CORINFO_INTRINSIC_Ceiling || intrinsicId == CORINFO_INTRINSIC_Floor)
+ if (intrinsicName == NI_System_Math_Sqrt || intrinsicName == NI_System_Math_Round ||
+ intrinsicName == NI_System_Math_Ceiling || intrinsicName == NI_System_Math_Floor)
{
GenTree* op1 = node->gtGetOp1();
if (IsContainableMemoryOp(op1) || op1->IsCnsNonZeroFltOrDbl())
@@ -5138,7 +5136,7 @@ void Lowering::ContainCheckHWIntrinsicAddr(GenTreeHWIntrinsic* node, GenTree* ad
{
assert((addr->TypeGet() == TYP_I_IMPL) || (addr->TypeGet() == TYP_BYREF));
TryCreateAddrMode(addr, true);
- if ((addr->OperIs(GT_CLS_VAR_ADDR, GT_LCL_VAR_ADDR, GT_LEA) ||
+ if ((addr->OperIs(GT_CLS_VAR_ADDR, GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR, GT_LEA) ||
(addr->IsCnsIntOrI() && addr->AsIntConCommon()->FitsInAddrBase(comp))) &&
IsSafeToContainMem(node, addr))
{
diff --git a/src/coreclr/src/jit/lsraarm.cpp b/src/coreclr/src/jit/lsraarm.cpp
index f3b480fddd6d01..8402bcdefc0fe4 100644
--- a/src/coreclr/src/jit/lsraarm.cpp
+++ b/src/coreclr/src/jit/lsraarm.cpp
@@ -290,10 +290,10 @@ int LinearScan::BuildNode(GenTree* tree)
BuildUse(op1);
srcCount = 1;
- switch (tree->AsIntrinsic()->gtIntrinsicId)
+ switch (tree->AsIntrinsic()->gtIntrinsicName)
{
- case CORINFO_INTRINSIC_Abs:
- case CORINFO_INTRINSIC_Sqrt:
+ case NI_System_Math_Abs:
+ case NI_System_Math_Sqrt:
assert(dstCount == 1);
BuildDef(tree);
break;
@@ -491,6 +491,8 @@ int LinearScan::BuildNode(GenTree* tree)
case GT_RETURN:
srcCount = BuildReturn(tree);
+ killMask = getKillSetForReturn();
+ BuildDefsWithKills(tree, 0, RBM_NONE, killMask);
break;
case GT_RETFILT:
diff --git a/src/coreclr/src/jit/lsraarm64.cpp b/src/coreclr/src/jit/lsraarm64.cpp
index 514ed90feef468..2138b782c53e49 100644
--- a/src/coreclr/src/jit/lsraarm64.cpp
+++ b/src/coreclr/src/jit/lsraarm64.cpp
@@ -319,11 +319,11 @@ int LinearScan::BuildNode(GenTree* tree)
case GT_INTRINSIC:
{
- noway_assert((tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Abs) ||
- (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Ceiling) ||
- (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Floor) ||
- (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Round) ||
- (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Sqrt));
+ noway_assert((tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Abs) ||
+ (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Ceiling) ||
+ (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Floor) ||
+ (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Round) ||
+ (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Sqrt));
// Both operand and its result must be of the same floating point type.
GenTree* op1 = tree->gtGetOp1();
@@ -1050,9 +1050,24 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
if (intrin.op1 != nullptr)
{
- // If we have an RMW intrinsic, we want to preference op1Reg to the target if
- // op1 is not contained.
- if (isRMW)
+ bool simdRegToSimdRegMove = false;
+
+ if ((intrin.id == NI_Vector64_CreateScalarUnsafe) || (intrin.id == NI_Vector128_CreateScalarUnsafe))
+ {
+ simdRegToSimdRegMove = varTypeIsFloating(intrin.op1);
+ }
+ else if (intrin.id == NI_AdvSimd_Arm64_DuplicateToVector64)
+ {
+ simdRegToSimdRegMove = (intrin.op1->TypeGet() == TYP_DOUBLE);
+ }
+ else if ((intrin.id == NI_Vector64_ToScalar) || (intrin.id == NI_Vector128_ToScalar))
+ {
+ simdRegToSimdRegMove = varTypeIsFloating(intrinsicTree);
+ }
+
+ // If we have an RMW intrinsic or an intrinsic with simple move semantic between two SIMD registers,
+ // we want to preference op1Reg to the target if op1 is not contained.
+ if (isRMW || simdRegToSimdRegMove)
{
tgtPrefOp1 = !intrin.op1->isContained();
}
diff --git a/src/coreclr/src/jit/lsraxarch.cpp b/src/coreclr/src/jit/lsraxarch.cpp
index 8895dc95ecec9f..e0be880d16d757 100644
--- a/src/coreclr/src/jit/lsraxarch.cpp
+++ b/src/coreclr/src/jit/lsraxarch.cpp
@@ -1779,9 +1779,9 @@ int LinearScan::BuildIntrinsic(GenTree* tree)
assert(op1->TypeGet() == tree->TypeGet());
RefPosition* internalFloatDef = nullptr;
- switch (tree->AsIntrinsic()->gtIntrinsicId)
+ switch (tree->AsIntrinsic()->gtIntrinsicName)
{
- case CORINFO_INTRINSIC_Abs:
+ case NI_System_Math_Abs:
// Abs(float x) = x & 0x7fffffff
// Abs(double x) = x & 0x7ffffff ffffffff
@@ -1798,16 +1798,16 @@ int LinearScan::BuildIntrinsic(GenTree* tree)
break;
#ifdef TARGET_X86
- case CORINFO_INTRINSIC_Cos:
- case CORINFO_INTRINSIC_Sin:
+ case NI_System_Math_Cos:
+ case NI_System_Math_Sin:
NYI_X86("Math intrinsics Cos and Sin");
break;
#endif // TARGET_X86
- case CORINFO_INTRINSIC_Sqrt:
- case CORINFO_INTRINSIC_Round:
- case CORINFO_INTRINSIC_Ceiling:
- case CORINFO_INTRINSIC_Floor:
+ case NI_System_Math_Sqrt:
+ case NI_System_Math_Round:
+ case NI_System_Math_Ceiling:
+ case NI_System_Math_Floor:
break;
default:
diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp
index 4d420dabaa8091..81342722a3807e 100644
--- a/src/coreclr/src/jit/morph.cpp
+++ b/src/coreclr/src/jit/morph.cpp
@@ -2707,6 +2707,13 @@ void Compiler::fgInitArgInfo(GenTreeCall* call)
indirectCellAddress->AsIntCon()->gtTargetHandle = (size_t)call->gtCallMethHnd;
#endif
indirectCellAddress->SetRegNum(REG_R2R_INDIRECT_PARAM);
+#ifdef TARGET_ARM
+ // Issue #xxxx : Don't attempt to CSE this constant on ARM32
+ //
+ // This constant has specific register requirements, and LSRA doesn't currently correctly
+ // handle them when the value is in a CSE'd local.
+ indirectCellAddress->SetDoNotCSE();
+#endif // TARGET_ARM
// Push the stub address onto the list of arguments.
call->gtCallArgs = gtPrependNewCallArg(indirectCellAddress, call->gtCallArgs);
@@ -4602,7 +4609,7 @@ GenTree* Compiler::fgMorphMultiregStructArg(GenTree* arg, fgArgTabEntry* fgEntry
assert(varNum < lvaCount);
LclVarDsc* varDsc = &lvaTable[varNum];
- unsigned baseOffset = argValue->OperIs(GT_LCL_FLD) ? argValue->AsLclFld()->GetLclOffs() : 0;
+ unsigned baseOffset = varNode->GetLclOffs();
unsigned lastOffset = baseOffset + structSize;
// The allocated size of our LocalVar must be at least as big as lastOffset
@@ -5735,7 +5742,9 @@ GenTree* Compiler::fgMorphStackArgForVarArgs(unsigned lclNum, var_types varType,
GenTree* tree;
if (varTypeIsStruct(varType))
{
- tree = new (this, GT_BLK) GenTreeBlk(GT_BLK, TYP_STRUCT, ptrArg, typGetBlkLayout(varDsc->lvExactSize));
+ CORINFO_CLASS_HANDLE typeHnd = varDsc->lvVerTypeInfo.GetClassHandle();
+ assert(typeHnd != nullptr);
+ tree = gtNewObjNode(typeHnd, ptrArg);
}
else
{
@@ -5883,7 +5892,7 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac)
}
#ifdef FEATURE_SIMD
- // if this field belongs to simd struct, translate it to simd instrinsic.
+ // if this field belongs to simd struct, translate it to simd intrinsic.
if (mac == nullptr)
{
GenTree* newTree = fgMorphFieldToSIMDIntrinsicGet(tree);
@@ -7894,21 +7903,54 @@ GenTree* Compiler::fgCreateCallDispatcherAndGetResult(GenTreeCall* orig
// Add return value arg.
GenTree* retValArg;
- GenTree* retVal = nullptr;
- unsigned int newRetLcl = BAD_VAR_NUM;
+ GenTree* retVal = nullptr;
+ unsigned int newRetLcl = BAD_VAR_NUM;
+ GenTree* copyToRetBufNode = nullptr;
- // Use existing retbuf if there is one.
if (origCall->HasRetBufArg())
{
JITDUMP("Transferring retbuf\n");
GenTree* retBufArg = origCall->gtCallArgs->GetNode();
- assert((info.compRetBuffArg != BAD_VAR_NUM) && retBufArg->OperIsLocal() &&
- (retBufArg->AsLclVarCommon()->GetLclNum() == info.compRetBuffArg));
- retValArg = retBufArg;
+ assert(info.compRetBuffArg != BAD_VAR_NUM);
+ assert(retBufArg->OperIsLocal());
+ assert(retBufArg->AsLclVarCommon()->GetLclNum() == info.compRetBuffArg);
+
+ if (info.compRetBuffDefStack)
+ {
+ // Use existing retbuf.
+ retValArg = retBufArg;
+ }
+ else
+ {
+ // Caller return buffer argument retBufArg can point to GC heap while the dispatcher expects
+ // the return value argument retValArg to point to the stack.
+ // We use a temporary stack allocated return buffer to hold the value during the dispatcher call
+ // and copy the value back to the caller return buffer after that.
+ unsigned int tmpRetBufNum = lvaGrabTemp(true DEBUGARG("substitute local for return buffer"));
+
+ constexpr bool unsafeValueClsCheck = false;
+ lvaSetStruct(tmpRetBufNum, origCall->gtRetClsHnd, unsafeValueClsCheck);
+ lvaSetVarAddrExposed(tmpRetBufNum);
+
+ var_types tmpRetBufType = lvaGetDesc(tmpRetBufNum)->TypeGet();
+
+ retValArg = gtNewOperNode(GT_ADDR, TYP_I_IMPL, gtNewLclvNode(tmpRetBufNum, tmpRetBufType));
+
+ var_types callerRetBufType = lvaGetDesc(info.compRetBuffArg)->TypeGet();
+
+ GenTree* dstAddr = gtNewLclvNode(info.compRetBuffArg, callerRetBufType);
+ GenTree* dst = gtNewObjNode(info.compMethodInfo->args.retTypeClass, dstAddr);
+ GenTree* src = gtNewLclvNode(tmpRetBufNum, tmpRetBufType);
+
+ constexpr bool isVolatile = false;
+ constexpr bool isCopyBlock = true;
+ copyToRetBufNode = gtNewBlkOpNode(dst, src, isVolatile, isCopyBlock);
+ }
+
if (origCall->gtType != TYP_VOID)
{
- retVal = gtClone(retValArg);
+ retVal = gtClone(retBufArg);
}
}
else if (origCall->gtType != TYP_VOID)
@@ -7962,22 +8004,30 @@ GenTree* Compiler::fgCreateCallDispatcherAndGetResult(GenTreeCall* orig
GenTree* retAddrSlot = gtNewOperNode(GT_ADDR, TYP_I_IMPL, gtNewLclvNode(lvaRetAddrVar, TYP_I_IMPL));
callDispatcherNode->gtCallArgs = gtPrependNewCallArg(retAddrSlot, callDispatcherNode->gtCallArgs);
+ GenTree* finalTree = callDispatcherNode;
+
+ if (copyToRetBufNode != nullptr)
+ {
+ finalTree = gtNewOperNode(GT_COMMA, TYP_VOID, callDispatcherNode, copyToRetBufNode);
+ }
+
if (origCall->gtType == TYP_VOID)
{
- return callDispatcherNode;
+ return finalTree;
}
assert(retVal != nullptr);
- GenTree* comma = gtNewOperNode(GT_COMMA, origCall->TypeGet(), callDispatcherNode, retVal);
+ finalTree = gtNewOperNode(GT_COMMA, origCall->TypeGet(), finalTree, retVal);
+
// The JIT seems to want to CSE this comma and messes up multi-reg ret
// values in the process. Just avoid CSE'ing this tree entirely in that
// case.
if (origCall->HasMultiRegRetVal())
{
- comma->gtFlags |= GTF_DONT_CSE;
+ finalTree->gtFlags |= GTF_DONT_CSE;
}
- return comma;
+ return finalTree;
}
//------------------------------------------------------------------------
@@ -8898,7 +8948,7 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call)
GenTree* dest = call->gtCallArgs->GetNode();
assert(dest->OperGet() != GT_ARGPLACE); // If it was, we'd be in a remorph, which we've already excluded above.
- if (dest->gtType == TYP_BYREF && !(dest->OperGet() == GT_ADDR && dest->AsOp()->gtOp1->OperGet() == GT_LCL_VAR))
+ if (dest->TypeIs(TYP_BYREF) && !dest->IsLocalAddrExpr())
{
// We'll exempt helper calls from this, assuming that the helper implementation
// follows the old convention, and does whatever barrier is required.
@@ -12159,7 +12209,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
#ifdef TARGET_ARM
case GT_INTRINSIC:
- if (tree->AsIntrinsic()->gtIntrinsicId == CORINFO_INTRINSIC_Round)
+ if (tree->AsIntrinsic()->gtIntrinsicName == NI_System_Math_Round)
{
switch (tree->TypeGet())
{
diff --git a/src/coreclr/src/jit/namedintrinsiclist.h b/src/coreclr/src/jit/namedintrinsiclist.h
index 63d79fbeff19d0..bc84f851deac8a 100644
--- a/src/coreclr/src/jit/namedintrinsiclist.h
+++ b/src/coreclr/src/jit/namedintrinsiclist.h
@@ -12,9 +12,28 @@ enum NamedIntrinsic : unsigned short
NI_System_Enum_HasFlag,
NI_System_Math_FusedMultiplyAdd,
+ NI_System_Math_Sin,
+ NI_System_Math_Cos,
+ NI_System_Math_Cbrt,
+ NI_System_Math_Sqrt,
+ NI_System_Math_Abs,
NI_System_Math_Round,
- NI_System_MathF_FusedMultiplyAdd,
- NI_System_MathF_Round,
+ NI_System_Math_Cosh,
+ NI_System_Math_Sinh,
+ NI_System_Math_Tan,
+ NI_System_Math_Tanh,
+ NI_System_Math_Asin,
+ NI_System_Math_Asinh,
+ NI_System_Math_Acos,
+ NI_System_Math_Acosh,
+ NI_System_Math_Atan,
+ NI_System_Math_Atan2,
+ NI_System_Math_Atanh,
+ NI_System_Math_Log10,
+ NI_System_Math_Pow,
+ NI_System_Math_Exp,
+ NI_System_Math_Ceiling,
+ NI_System_Math_Floor,
NI_System_Collections_Generic_EqualityComparer_get_Default,
NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness,
NI_System_GC_KeepAlive,
diff --git a/src/coreclr/src/jit/optcse.cpp b/src/coreclr/src/jit/optcse.cpp
index 46e834df0dc4f0..06339353826b3b 100644
--- a/src/coreclr/src/jit/optcse.cpp
+++ b/src/coreclr/src/jit/optcse.cpp
@@ -20,7 +20,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
/*****************************************************************************/
/* static */
-const size_t Compiler::s_optCSEhashSize = EXPSET_SZ * 2;
+const size_t Compiler::s_optCSEhashSizeInitial = EXPSET_SZ * 2;
+const size_t Compiler::s_optCSEhashGrowthFactor = 2;
+const size_t Compiler::s_optCSEhashBucketSize = 4;
/*****************************************************************************
*
@@ -36,11 +38,11 @@ void Compiler::optCSEstop()
CSEdsc* dsc;
CSEdsc** ptr;
- unsigned cnt;
+ size_t cnt;
optCSEtab = new (this, CMK_CSE) CSEdsc*[optCSECandidateCount]();
- for (cnt = s_optCSEhashSize, ptr = optCSEhash; cnt; cnt--, ptr++)
+ for (cnt = optCSEhashSize, ptr = optCSEhash; cnt; cnt--, ptr++)
{
for (dsc = *ptr; dsc; dsc = dsc->csdNextInBucket)
{
@@ -373,7 +375,11 @@ void Compiler::optValnumCSE_Init()
cseMaskTraits = nullptr;
// Allocate and clear the hash bucket table
- optCSEhash = new (this, CMK_CSE) CSEdsc*[s_optCSEhashSize]();
+ optCSEhash = new (this, CMK_CSE) CSEdsc*[s_optCSEhashSizeInitial]();
+
+ optCSEhashSize = s_optCSEhashSizeInitial;
+ optCSEhashMaxCountBeforeResize = optCSEhashSize * s_optCSEhashBucketSize;
+ optCSEhashCount = 0;
optCSECandidateCount = 0;
optDoCSE = false; // Stays false until we find duplicate CSE tree
@@ -382,6 +388,20 @@ void Compiler::optValnumCSE_Init()
optCseCheckedBoundMap = nullptr;
}
+unsigned optCSEKeyToHashIndex(size_t key, size_t optCSEhashSize)
+{
+ unsigned hash;
+
+ hash = (unsigned)key;
+#ifdef TARGET_64BIT
+ hash ^= (unsigned)(key >> 32);
+#endif
+ hash *= (unsigned)(optCSEhashSize + 1);
+ hash >>= 7;
+
+ return hash % optCSEhashSize;
+}
+
//---------------------------------------------------------------------------
// optValnumCSE_Index:
// - Returns the CSE index to use for this tree,
@@ -401,10 +421,26 @@ void Compiler::optValnumCSE_Init()
//
unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt)
{
- unsigned key;
- unsigned hash;
+ size_t key;
unsigned hval;
CSEdsc* hashDsc;
+ bool isIntConstHash = false;
+ bool enableSharedConstCSE = false;
+ int configValue = JitConfig.JitConstCSE();
+
+#if defined(TARGET_ARM64)
+ // ARM64 - allow to combine with nearby offsets, when config is not 2 or 4
+ if ((configValue != CONST_CSE_ENABLE_ARM64_NO_SHARING) && (configValue != CONST_CSE_ENABLE_ALL_NO_SHARING))
+ {
+ enableSharedConstCSE = true;
+ }
+#endif // TARGET_ARM64
+
+ // All Platforms - also allow to combine with nearby offsets, when config is 3
+ if (configValue == CONST_CSE_ENABLE_ALL)
+ {
+ enableSharedConstCSE = true;
+ }
// We use the liberal Value numbers when building the set of CSE
ValueNum vnLib = tree->GetVN(VNK_Liberal);
@@ -446,11 +482,11 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt)
//
if (vnOp2Lib != vnLib)
{
- key = (unsigned)vnLib; // include the exc set in the hash key
+ key = vnLib; // include the exc set in the hash key
}
else
{
- key = (unsigned)vnLibNorm;
+ key = vnLibNorm;
}
// If we didn't do the above we would have op1 as the CSE def
@@ -459,18 +495,33 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt)
//
assert(vnLibNorm == vnStore->VNNormalValue(vnOp2Lib));
}
- else // Not a GT_COMMA
+ else if (enableSharedConstCSE && tree->IsIntegralConst())
+ {
+ assert(vnStore->IsVNConstant(vnLibNorm));
+ key = vnStore->CoercedConstantValue(vnLibNorm);
+
+ // We don't shared small offset constants when we require a reloc
+ if (!tree->AsIntConCommon()->ImmedValNeedsReloc(this))
+ {
+ // Make constants that have the same upper bits use the same key
+
+ // Shift the key right by CSE_CONST_SHARED_LOW_BITS bits, this sets the upper bits to zero
+ key >>= CSE_CONST_SHARED_LOW_BITS;
+ }
+ assert((key & TARGET_SIGN_BIT) == 0);
+
+ // We use the sign bit of 'key' as the flag
+ // that we are hashing constants (with a shared offset)
+ key |= TARGET_SIGN_BIT;
+ }
+ else // Not a GT_COMMA or a GT_CNS_INT
{
- key = (unsigned)vnLibNorm;
+ key = vnLibNorm;
}
// Compute the hash value for the expression
- hash = key;
- hash *= (unsigned)(s_optCSEhashSize + 1);
- hash >>= 7;
-
- hval = hash % s_optCSEhashSize;
+ hval = optCSEKeyToHashIndex(key, optCSEhashSize);
/* Look for a matching index in the hash table */
@@ -480,6 +531,12 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt)
{
if (hashDsc->csdHashKey == key)
{
+ // Check for mismatched types on GT_CNS_INT nodes
+ if ((tree->OperGet() == GT_CNS_INT) && (tree->TypeGet() != hashDsc->csdTree->TypeGet()))
+ {
+ continue;
+ }
+
treeStmtLst* newElem;
/* Have we started the list of matching nodes? */
@@ -582,9 +639,42 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt)
if (optCSECandidateCount < MAX_CSE_CNT)
{
+ if (optCSEhashCount == optCSEhashMaxCountBeforeResize)
+ {
+ size_t newOptCSEhashSize = optCSEhashSize * s_optCSEhashGrowthFactor;
+ CSEdsc** newOptCSEhash = new (this, CMK_CSE) CSEdsc*[newOptCSEhashSize]();
+
+ // Iterate through each existing entry, moving to the new table
+ CSEdsc** ptr;
+ CSEdsc* dsc;
+ size_t cnt;
+ for (cnt = optCSEhashSize, ptr = optCSEhash; cnt; cnt--, ptr++)
+ {
+ for (dsc = *ptr; dsc;)
+ {
+ CSEdsc* nextDsc = dsc->csdNextInBucket;
+
+ size_t newHval = optCSEKeyToHashIndex(dsc->csdHashKey, newOptCSEhashSize);
+
+ // Move CSEdsc to bucket in enlarged table
+ dsc->csdNextInBucket = newOptCSEhash[newHval];
+ newOptCSEhash[newHval] = dsc;
+
+ dsc = nextDsc;
+ }
+ }
+
+ optCSEhash = newOptCSEhash;
+ optCSEhashSize = newOptCSEhashSize;
+ optCSEhashMaxCountBeforeResize = optCSEhashMaxCountBeforeResize * s_optCSEhashGrowthFactor;
+ }
+
+ ++optCSEhashCount;
hashDsc = new (this, CMK_CSE) CSEdsc;
hashDsc->csdHashKey = key;
+ hashDsc->csdConstDefValue = 0;
+ hashDsc->csdConstDefVN = vnStore->VNForNull(); // uninit value
hashDsc->csdIndex = 0;
hashDsc->csdLiveAcrossCall = false;
hashDsc->csdDefCount = 0;
@@ -645,8 +735,17 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt)
#ifdef DEBUG
if (verbose)
{
- printf("\nCSE candidate #%02u, vn=", CSEindex);
- vnPrint(key, 0);
+ printf("\nCSE candidate #%02u, key=", CSEindex);
+ if (!Compiler::Is_Shared_Const_CSE(key))
+ {
+ vnPrint((unsigned)key, 0);
+ }
+ else
+ {
+ size_t kVal = Compiler::Decode_Shared_Const_CSE_Value(key);
+ printf("K_%p", dspPtr(kVal));
+ }
+
printf(" in " FMT_BB ", [cost=%2u, size=%2u]: \n", compCurBB->bbNum, tree->GetCostEx(), tree->GetCostSz());
gtDispTree(tree);
}
@@ -666,6 +765,29 @@ unsigned Compiler::optValnumCSE_Locate()
{
// Locate CSE candidates and assign them indices
+ bool enableConstCSE = true;
+
+ int configValue = JitConfig.JitConstCSE();
+
+ // all platforms - disable CSE of constant values when config is 1
+ if (configValue == CONST_CSE_DISABLE_ALL)
+ {
+ enableConstCSE = false;
+ }
+
+#if !defined(TARGET_ARM64)
+ // non-ARM64 platforms - disable by default
+ //
+ enableConstCSE = false;
+
+ // Check for the two enable cases for all platforms
+ //
+ if ((configValue == CONST_CSE_ENABLE_ALL) || (configValue == CONST_CSE_ENABLE_ALL_NO_SHARING))
+ {
+ enableConstCSE = true;
+ }
+#endif
+
for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
/* Make the block publicly available */
@@ -691,6 +813,16 @@ unsigned Compiler::optValnumCSE_Locate()
optCseUpdateCheckedBoundMap(tree);
}
+ // Don't allow CSE of constants if it is disabled
+ //
+ if (tree->IsIntegralConst())
+ {
+ if (!enableConstCSE)
+ {
+ continue;
+ }
+ }
+
if (!optIsCSEcandidate(tree))
{
continue;
@@ -701,15 +833,17 @@ unsigned Compiler::optValnumCSE_Locate()
continue;
}
- // Don't CSE constant values, instead let the Value Number
- // based Assertion Prop phase handle them. Here, unlike
- // the rest of optCSE, we use the conservative value number
+ // We want to CSE simple constant leaf nodes, but we don't want to
+ // CSE non-leaf trees that compute CSE constant values.
+ // Instead we let the Value Number based Assertion Prop phase handle them.
+ //
+ // Here, unlike the rest of optCSE, we use the conservative value number
// rather than the liberal one, since the conservative one
// is what the Value Number based Assertion Prop will use
// and the point is to avoid optimizing cases that it will
// handle.
//
- if (vnStore->IsVNConstant(vnStore->VNConservativeNormalValue(tree->gtVNPair)))
+ if (!tree->OperIsLeaf() && vnStore->IsVNConstant(vnStore->VNConservativeNormalValue(tree->gtVNPair)))
{
continue;
}
@@ -1428,23 +1562,28 @@ void Compiler::optValnumCSE_Availablity()
}
}
- // Record or update the value of desc->defConservNormVN
+ // For shared const CSE we don't set/use the defConservNormVN
//
- ValueNum theConservNormVN = vnStore->VNConservativeNormalValue(tree->gtVNPair);
-
- // Is defConservNormVN still set to the uninit marker value of VNForNull() ?
- if (desc->defConservNormVN == vnStore->VNForNull())
- {
- // This is the first def that we have visited, set defConservNormVN
- desc->defConservNormVN = theConservNormVN;
- }
- else
+ if (!Is_Shared_Const_CSE(desc->csdHashKey))
{
- // Check to see if all defs have the same conservative normal VN
- if (theConservNormVN != desc->defConservNormVN)
+ // Record or update the value of desc->defConservNormVN
+ //
+ ValueNum theConservNormVN = vnStore->VNConservativeNormalValue(tree->gtVNPair);
+
+ // Is defConservNormVN still set to the uninit marker value of VNForNull() ?
+ if (desc->defConservNormVN == vnStore->VNForNull())
+ {
+ // This is the first def that we have visited, set defConservNormVN
+ desc->defConservNormVN = theConservNormVN;
+ }
+ else
{
- // This candidate has defs with differing conservative normal VNs, mark it with NoVN
- desc->defConservNormVN = ValueNumStore::NoVN; // record the marker for differing VNs
+ // Check to see if all defs have the same conservative normal VN
+ if (theConservNormVN != desc->defConservNormVN)
+ {
+ // This candidate has defs with differing conservative normal VNs, mark it with NoVN
+ desc->defConservNormVN = ValueNumStore::NoVN; // record the marker for differing VNs
+ }
}
}
@@ -1894,9 +2033,19 @@ class CSE_Heuristic
cost = dsc->csdTree->GetCostEx();
}
- printf("CSE #%02u, {$%-3x, $%-3x} useCnt=%d: [def=%3u, use=%3u, cost=%3u%s]\n :: ",
- dsc->csdIndex, dsc->csdHashKey, dsc->defExcSetPromise, dsc->csdUseCount, def, use, cost,
- dsc->csdLiveAcrossCall ? ", call" : " ");
+ if (!Compiler::Is_Shared_Const_CSE(dsc->csdHashKey))
+ {
+ printf("CSE #%02u, {$%-3x, $%-3x} useCnt=%d: [def=%3u, use=%3u, cost=%3u%s]\n :: ",
+ dsc->csdIndex, dsc->csdHashKey, dsc->defExcSetPromise, dsc->csdUseCount, def, use, cost,
+ dsc->csdLiveAcrossCall ? ", call" : " ");
+ }
+ else
+ {
+ size_t kVal = Compiler::Decode_Shared_Const_CSE_Value(dsc->csdHashKey);
+ printf("CSE #%02u, {K_%p} useCnt=%d: [def=%3u, use=%3u, cost=%3u%s]\n :: ", dsc->csdIndex,
+ dspPtr(kVal), dsc->csdUseCount, def, use, cost,
+ dsc->csdLiveAcrossCall ? ", call" : " ");
+ }
m_pCompiler->gtDispTree(expr, nullptr, nullptr, true);
}
@@ -2377,8 +2526,9 @@ class CSE_Heuristic
#ifdef DEBUG
if (m_pCompiler->verbose)
{
- printf("Moderate CSE Promotion (CSE is live across a call) (%u >= %u)\n", cseRefCnt,
- moderateRefCnt);
+ printf("Moderate CSE Promotion (%s) (%u >= %u)\n",
+ candidate->LiveAcrossCall() ? "CSE is live across a call" : "not enregisterable",
+ cseRefCnt, moderateRefCnt);
}
#endif
cse_def_cost = 2;
@@ -2409,8 +2559,9 @@ class CSE_Heuristic
#ifdef DEBUG
if (m_pCompiler->verbose)
{
- printf("Conservative CSE Promotion (CSE never live at call) (%u < %u)\n", cseRefCnt,
- moderateRefCnt);
+ printf("Conservative CSE Promotion (%s) (%u < %u)\n",
+ candidate->LiveAcrossCall() ? "CSE is live across a call" : "not enregisterable",
+ cseRefCnt, moderateRefCnt);
}
#endif
cse_def_cost = 2;
@@ -2660,8 +2811,7 @@ class CSE_Heuristic
//
// Later we will unmark any nested CSE's for the CSE uses.
//
- Compiler::CSEdsc* dsc = successfulCandidate->CseDsc();
- Compiler::treeStmtLst* lst;
+ Compiler::CSEdsc* dsc = successfulCandidate->CseDsc();
// If there's just a single def for the CSE, we'll put this
// CSE into SSA form on the fly. We won't need any PHIs.
@@ -2678,53 +2828,122 @@ class CSE_Heuristic
cseSsaNum = m_pCompiler->lvaTable[cseLclVarNum].lvPerSsaData.AllocSsaNum(allocator);
}
-#ifdef DEBUG
// Verify that all of the ValueNumbers in this list are correct as
// Morph will change them when it performs a mutating operation.
//
- ValueNum firstVN = ValueNumStore::NoVN;
- ValueNum currVN;
- bool allSame = true;
+ bool setRefCnt = true;
+ bool allSame = true;
+ bool isSharedConst = Compiler::Is_Shared_Const_CSE(dsc->csdHashKey);
+ ValueNum bestVN = ValueNumStore::NoVN;
+ bool bestIsDef = false;
+ ssize_t bestConstValue = 0;
+ Compiler::treeStmtLst* lst = dsc->csdTreeList;
- lst = dsc->csdTreeList;
while (lst != nullptr)
{
// Ignore this node if the gtCSEnum value has been cleared
if (IS_CSE_INDEX(lst->tslTree->gtCSEnum))
{
// We used the liberal Value numbers when building the set of CSE
- currVN = m_pCompiler->vnStore->VNLiberalNormalValue(lst->tslTree->gtVNPair);
+ ValueNum currVN = m_pCompiler->vnStore->VNLiberalNormalValue(lst->tslTree->gtVNPair);
assert(currVN != ValueNumStore::NoVN);
+ ssize_t curConstValue = isSharedConst ? m_pCompiler->vnStore->CoercedConstantValue(currVN) : 0;
+
+ GenTree* exp = lst->tslTree;
+ bool isDef = IS_CSE_DEF(exp->gtCSEnum);
- if (firstVN == ValueNumStore::NoVN)
+ if (bestVN == ValueNumStore::NoVN)
{
- firstVN = currVN;
+ // first entry
+ // set bestVN
+ bestVN = currVN;
+
+ if (isSharedConst)
+ {
+ // set bestConstValue and bestIsDef
+ bestConstValue = curConstValue;
+ bestIsDef = isDef;
+ }
}
- else if (currVN != firstVN)
+ else if (currVN != bestVN)
{
+ assert(isSharedConst); // Must be true when we have differing VNs
+
+ // subsequent entry
+ // clear allSame and check for a lower constant
allSame = false;
- break;
+
+ ssize_t diff = curConstValue - bestConstValue;
+
+ // The ARM64 ldr addressing modes allow for a subtraction of up to 255
+ // so we will allow the diff to be up to -255 before replacing a CSE def
+ // This will minimize the number of extra subtract instructions.
+ //
+ if ((bestIsDef && (diff < -255)) || (!bestIsDef && (diff < 0)))
+ {
+ // set new bestVN, bestConstValue and bestIsDef
+ bestVN = currVN;
+ bestConstValue = curConstValue;
+ bestIsDef = isDef;
+ }
+ }
+
+ BasicBlock* blk = lst->tslBlock;
+ BasicBlock::weight_t curWeight = blk->getBBWeight(m_pCompiler);
+
+ if (setRefCnt)
+ {
+ m_pCompiler->lvaTable[cseLclVarNum].setLvRefCnt(1);
+ m_pCompiler->lvaTable[cseLclVarNum].setLvRefCntWtd(curWeight);
+ setRefCnt = false;
+ }
+ else
+ {
+ m_pCompiler->lvaTable[cseLclVarNum].incRefCnts(curWeight, m_pCompiler);
+ }
+
+ // A CSE Def references the LclVar twice
+ //
+ if (isDef)
+ {
+ m_pCompiler->lvaTable[cseLclVarNum].incRefCnts(curWeight, m_pCompiler);
}
}
lst = lst->tslNext;
}
- if (!allSame)
+
+ dsc->csdConstDefValue = bestConstValue;
+ dsc->csdConstDefVN = bestVN;
+
+#ifdef DEBUG
+ if (m_pCompiler->verbose)
{
- lst = dsc->csdTreeList;
- GenTree* firstTree = lst->tslTree;
- printf("In %s, CSE (oper = %s, type = %s) has differing VNs: ", m_pCompiler->info.compFullName,
- GenTree::OpName(firstTree->OperGet()), varTypeName(firstTree->TypeGet()));
- while (lst != nullptr)
+ if (!allSame)
{
- if (IS_CSE_INDEX(lst->tslTree->gtCSEnum))
+ if (isSharedConst)
{
- currVN = m_pCompiler->vnStore->VNLiberalNormalValue(lst->tslTree->gtVNPair);
- printf("0x%x(%s " FMT_VN ") ", lst->tslTree, IS_CSE_USE(lst->tslTree->gtCSEnum) ? "use" : "def",
- currVN);
+ printf("\nWe have shared Const CSE's and selected " FMT_VN " with a value of 0x%p as the base.\n",
+ dsc->csdConstDefVN, dspPtr(dsc->csdConstDefValue));
+ }
+ else // !isSharedConst
+ {
+ lst = dsc->csdTreeList;
+ GenTree* firstTree = lst->tslTree;
+ printf("In %s, CSE (oper = %s, type = %s) has differing VNs: ", m_pCompiler->info.compFullName,
+ GenTree::OpName(firstTree->OperGet()), varTypeName(firstTree->TypeGet()));
+ while (lst != nullptr)
+ {
+ if (IS_CSE_INDEX(lst->tslTree->gtCSEnum))
+ {
+ ValueNum currVN = m_pCompiler->vnStore->VNLiberalNormalValue(lst->tslTree->gtVNPair);
+ printf("0x%x(%s " FMT_VN ") ", lst->tslTree,
+ IS_CSE_USE(lst->tslTree->gtCSEnum) ? "use" : "def", currVN);
+ }
+ lst = lst->tslNext;
+ }
+ printf("\n");
}
- lst = lst->tslNext;
}
- printf("\n");
}
#endif // DEBUG
@@ -2762,7 +2981,8 @@ class CSE_Heuristic
// The cseLclVarType must be a compatible with expTyp
//
- noway_assert(IsCompatibleType(cseLclVarTyp, expTyp));
+ ValueNumStore* vnStore = m_pCompiler->vnStore;
+ noway_assert(IsCompatibleType(cseLclVarTyp, expTyp) || (dsc->csdConstDefVN != vnStore->VNForNull()));
// This will contain the replacement tree for exp
// It will either be the CSE def or CSE ref
@@ -2790,63 +3010,86 @@ class CSE_Heuristic
// We will replace the CSE ref with a new tree
// this is typically just a simple use of the new CSE LclVar
//
- ValueNumStore* vnStore = m_pCompiler->vnStore;
- cse = m_pCompiler->gtNewLclvNode(cseLclVarNum, cseLclVarTyp);
- // Assign the ssa num for the use. Note it may be the reserved num.
- cse->AsLclVarCommon()->SetSsaNum(cseSsaNum);
+ // Create a reference to the CSE temp
+ GenTree* cseLclVar = m_pCompiler->gtNewLclvNode(cseLclVarNum, cseLclVarTyp);
+ cseLclVar->gtVNPair.SetBoth(dsc->csdConstDefVN);
- // assign the proper ValueNumber, A CSE use discards any exceptions
- cse->gtVNPair = vnStore->VNPNormalPair(exp->gtVNPair);
-
- ValueNum theConservativeVN = successfulCandidate->CseDsc()->defConservNormVN;
+ // Assign the ssa num for the lclvar use. Note it may be the reserved num.
+ cseLclVar->AsLclVarCommon()->SetSsaNum(cseSsaNum);
- if (theConservativeVN != ValueNumStore::NoVN)
+ cse = cseLclVar;
+ if (isSharedConst)
{
- // All defs of this CSE share the same normal conservative VN, and we are rewriting this
- // use to fetch the same value with no reload, so we can safely propagate that
- // conservative VN to this use. This can help range check elimination later on.
- cse->gtVNPair.SetConservative(theConservativeVN);
-
- // If the old VN was flagged as a checked bound, propagate that to the new VN
- // to make sure assertion prop will pay attention to this VN.
- ValueNum oldVN = exp->gtVNPair.GetConservative();
- if (!vnStore->IsVNConstant(theConservativeVN) && vnStore->IsVNCheckedBound(oldVN))
+ ValueNum currVN = m_pCompiler->vnStore->VNLiberalNormalValue(exp->gtVNPair);
+ ssize_t curValue = m_pCompiler->vnStore->CoercedConstantValue(currVN);
+ ssize_t delta = curValue - dsc->csdConstDefValue;
+ if (delta != 0)
{
- vnStore->SetVNIsCheckedBound(theConservativeVN);
+ GenTree* deltaNode = m_pCompiler->gtNewIconNode(delta, cseLclVarTyp);
+ cse = m_pCompiler->gtNewOperNode(GT_ADD, cseLclVarTyp, cseLclVar, deltaNode);
+ cse->SetDoNotCSE();
}
+ }
- GenTree* cmp;
- if ((m_pCompiler->optCseCheckedBoundMap != nullptr) &&
- (m_pCompiler->optCseCheckedBoundMap->Lookup(exp, &cmp)))
- {
- // Propagate the new value number to this compare node as well, since
- // subsequent range check elimination will try to correlate it with
- // the other appearances that are getting CSEd.
+ // assign the proper ValueNumber, A CSE use discards any exceptions
+ cse->gtVNPair = vnStore->VNPNormalPair(exp->gtVNPair);
- ValueNum oldCmpVN = cmp->gtVNPair.GetConservative();
- ValueNum newCmpArgVN;
+ // shared const CSE has the correct value number assigned
+ // and both liberal and conservative are identical
+ // and they do not use theConservativeVN
+ //
+ if (!isSharedConst)
+ {
+ ValueNum theConservativeVN = successfulCandidate->CseDsc()->defConservNormVN;
- ValueNumStore::CompareCheckedBoundArithInfo info;
- if (vnStore->IsVNCompareCheckedBound(oldCmpVN))
+ if (theConservativeVN != ValueNumStore::NoVN)
+ {
+ // All defs of this CSE share the same normal conservative VN, and we are rewriting this
+ // use to fetch the same value with no reload, so we can safely propagate that
+ // conservative VN to this use. This can help range check elimination later on.
+ cse->gtVNPair.SetConservative(theConservativeVN);
+
+ // If the old VN was flagged as a checked bound, propagate that to the new VN
+ // to make sure assertion prop will pay attention to this VN.
+ ValueNum oldVN = exp->gtVNPair.GetConservative();
+ if (!vnStore->IsVNConstant(theConservativeVN) && vnStore->IsVNCheckedBound(oldVN))
{
- // Comparison is against the bound directly.
-
- newCmpArgVN = theConservativeVN;
- vnStore->GetCompareCheckedBound(oldCmpVN, &info);
+ vnStore->SetVNIsCheckedBound(theConservativeVN);
}
- else
+
+ GenTree* cmp;
+ if ((m_pCompiler->optCseCheckedBoundMap != nullptr) &&
+ (m_pCompiler->optCseCheckedBoundMap->Lookup(exp, &cmp)))
{
- // Comparison is against the bound +/- some offset.
+ // Propagate the new value number to this compare node as well, since
+ // subsequent range check elimination will try to correlate it with
+ // the other appearances that are getting CSEd.
+
+ ValueNum oldCmpVN = cmp->gtVNPair.GetConservative();
+ ValueNum newCmpArgVN;
+
+ ValueNumStore::CompareCheckedBoundArithInfo info;
+ if (vnStore->IsVNCompareCheckedBound(oldCmpVN))
+ {
+ // Comparison is against the bound directly.
- assert(vnStore->IsVNCompareCheckedBoundArith(oldCmpVN));
- vnStore->GetCompareCheckedBoundArithInfo(oldCmpVN, &info);
- newCmpArgVN = vnStore->VNForFunc(vnStore->TypeOfVN(info.arrOp), (VNFunc)info.arrOper,
- info.arrOp, theConservativeVN);
+ newCmpArgVN = theConservativeVN;
+ vnStore->GetCompareCheckedBound(oldCmpVN, &info);
+ }
+ else
+ {
+ // Comparison is against the bound +/- some offset.
+
+ assert(vnStore->IsVNCompareCheckedBoundArith(oldCmpVN));
+ vnStore->GetCompareCheckedBoundArithInfo(oldCmpVN, &info);
+ newCmpArgVN = vnStore->VNForFunc(vnStore->TypeOfVN(info.arrOp), (VNFunc)info.arrOper,
+ info.arrOp, theConservativeVN);
+ }
+ ValueNum newCmpVN = vnStore->VNForFunc(vnStore->TypeOfVN(oldCmpVN), (VNFunc)info.cmpOper,
+ info.cmpOp, newCmpArgVN);
+ cmp->gtVNPair.SetConservative(newCmpVN);
}
- ValueNum newCmpVN = vnStore->VNForFunc(vnStore->TypeOfVN(oldCmpVN), (VNFunc)info.cmpOper,
- info.cmpOp, newCmpArgVN);
- cmp->gtVNPair.SetConservative(newCmpVN);
}
}
#ifdef DEBUG
@@ -2878,10 +3121,9 @@ class CSE_Heuristic
}
#endif
- GenTree* cseVal = cse;
- GenTree* curSideEff = sideEffList;
- ValueNumStore* vnStore = m_pCompiler->vnStore;
- ValueNumPair exceptions_vnp = ValueNumStore::VNPForEmptyExcSet();
+ GenTree* cseVal = cse;
+ GenTree* curSideEff = sideEffList;
+ ValueNumPair exceptions_vnp = ValueNumStore::VNPForEmptyExcSet();
while ((curSideEff->OperGet() == GT_COMMA) || (curSideEff->OperGet() == GT_ASG))
{
@@ -2936,6 +3178,17 @@ class CSE_Heuristic
exp->gtCSEnum = NO_CSE; // clear the gtCSEnum field
GenTree* val = exp;
+ if (isSharedConst)
+ {
+ ValueNum currVN = m_pCompiler->vnStore->VNLiberalNormalValue(exp->gtVNPair);
+ ssize_t curValue = m_pCompiler->vnStore->CoercedConstantValue(currVN);
+ ssize_t delta = curValue - dsc->csdConstDefValue;
+ if (delta != 0)
+ {
+ val = m_pCompiler->gtNewIconNode(dsc->csdConstDefValue, cseLclVarTyp);
+ val->gtVNPair.SetBoth(dsc->csdConstDefVN);
+ }
+ }
/* Create an assignment of the value to the temp */
GenTree* asg = m_pCompiler->gtNewTempAssign(cseLclVarNum, val);
@@ -2977,19 +3230,37 @@ class CSE_Heuristic
}
/* Create a reference to the CSE temp */
- GenTree* ref = m_pCompiler->gtNewLclvNode(cseLclVarNum, cseLclVarTyp);
- ref->gtVNPair = val->gtVNPair; // The new 'ref' is the same as 'val'
+ GenTree* cseLclVar = m_pCompiler->gtNewLclvNode(cseLclVarNum, cseLclVarTyp);
+ cseLclVar->gtVNPair.SetBoth(dsc->csdConstDefVN);
+
+ // Assign the ssa num for the lclvar use. Note it may be the reserved num.
+ cseLclVar->AsLclVarCommon()->SetSsaNum(cseSsaNum);
- // Assign the ssa num for the ref use. Note it may be the reserved num.
- ref->AsLclVarCommon()->SetSsaNum(cseSsaNum);
+ GenTree* cseUse = cseLclVar;
+ if (isSharedConst)
+ {
+ ValueNum currVN = m_pCompiler->vnStore->VNLiberalNormalValue(exp->gtVNPair);
+ ssize_t curValue = m_pCompiler->vnStore->CoercedConstantValue(currVN);
+ ssize_t delta = curValue - dsc->csdConstDefValue;
+ if (delta != 0)
+ {
+ GenTree* deltaNode = m_pCompiler->gtNewIconNode(delta, cseLclVarTyp);
+ cseUse = m_pCompiler->gtNewOperNode(GT_ADD, cseLclVarTyp, cseLclVar, deltaNode);
+ cseUse->SetDoNotCSE();
+ }
+ }
+ cseUse->gtVNPair = val->gtVNPair; // The 'cseUse' is equal to 'val'
/* Create a comma node for the CSE assignment */
- cse = m_pCompiler->gtNewOperNode(GT_COMMA, expTyp, origAsg, ref);
- cse->gtVNPair = ref->gtVNPair; // The comma's value is the same as 'val'
- // as the assignment to the CSE LclVar
- // cannot add any new exceptions
+ cse = m_pCompiler->gtNewOperNode(GT_COMMA, expTyp, origAsg, cseUse);
+ cse->gtVNPair = cseUse->gtVNPair; // The comma's value is the same as 'val'
+ // as the assignment to the CSE LclVar
+ // cannot add any new exceptions
}
+ cse->CopyReg(exp); // The cse inheirits any reg num property from the orginal exp node
+ exp->ClearRegNum(); // The exp node (for a CSE def) no longer has a register requirement
+
// Walk the statement 'stmt' and find the pointer
// in the tree is pointing to 'exp'
//
@@ -3069,9 +3340,19 @@ class CSE_Heuristic
#ifdef DEBUG
if (m_pCompiler->verbose)
{
- printf("\nConsidering CSE #%02u {$%-3x, $%-3x} [def=%3u, use=%3u, cost=%3u%s]\n", candidate.CseIndex(),
- dsc->csdHashKey, dsc->defExcSetPromise, candidate.DefCount(), candidate.UseCount(),
- candidate.Cost(), dsc->csdLiveAcrossCall ? ", call" : " ");
+ if (!Compiler::Is_Shared_Const_CSE(dsc->csdHashKey))
+ {
+ printf("\nConsidering CSE #%02u {$%-3x, $%-3x} [def=%3u, use=%3u, cost=%3u%s]\n",
+ candidate.CseIndex(), dsc->csdHashKey, dsc->defExcSetPromise, candidate.DefCount(),
+ candidate.UseCount(), candidate.Cost(), dsc->csdLiveAcrossCall ? ", call" : " ");
+ }
+ else
+ {
+ size_t kVal = Compiler::Decode_Shared_Const_CSE_Value(dsc->csdHashKey);
+ printf("\nConsidering CSE #%02u {K_%p} [def=%3u, use=%3u, cost=%3u%s]\n", candidate.CseIndex(),
+ dspPtr(kVal), candidate.DefCount(), candidate.UseCount(), candidate.Cost(),
+ dsc->csdLiveAcrossCall ? ", call" : " ");
+ }
printf("CSE Expression : \n");
m_pCompiler->gtDispTree(candidate.Expr());
printf("\n");
@@ -3306,8 +3587,11 @@ bool Compiler::optIsCSEcandidate(GenTree* tree)
return (tree->AsOp()->gtOp1->gtOper != GT_ARR_ELEM);
- case GT_CNS_INT:
case GT_CNS_LNG:
+#ifndef TARGET_64BIT
+ return false; // Don't CSE 64-bit constants on 32-bit platforms
+#endif
+ case GT_CNS_INT:
case GT_CNS_DBL:
case GT_CNS_STR:
return true; // We reach here only when CSE_CONSTS is enabled
diff --git a/src/coreclr/src/jit/rationalize.cpp b/src/coreclr/src/jit/rationalize.cpp
index b878a30beeae03..8054fda6e8ef46 100644
--- a/src/coreclr/src/jit/rationalize.cpp
+++ b/src/coreclr/src/jit/rationalize.cpp
@@ -726,7 +726,7 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, Compiler::Ge
case GT_INTRINSIC:
// Non-target intrinsics should have already been rewritten back into user calls.
- assert(comp->IsTargetIntrinsic(node->AsIntrinsic()->gtIntrinsicId));
+ assert(comp->IsTargetIntrinsic(node->AsIntrinsic()->gtIntrinsicName));
break;
#ifdef FEATURE_SIMD
@@ -903,7 +903,7 @@ PhaseStatus Rationalizer::DoPhase()
{
GenTree* const node = *use;
if (node->OperGet() == GT_INTRINSIC &&
- m_rationalizer.comp->IsIntrinsicImplementedByUserCall(node->AsIntrinsic()->gtIntrinsicId))
+ m_rationalizer.comp->IsIntrinsicImplementedByUserCall(node->AsIntrinsic()->gtIntrinsicName))
{
m_rationalizer.RewriteIntrinsicAsUserCall(use, this->m_ancestors);
}
diff --git a/src/coreclr/src/jit/scopeinfo.cpp b/src/coreclr/src/jit/scopeinfo.cpp
index 5fc7bca119f4c2..77d8233cac6328 100644
--- a/src/coreclr/src/jit/scopeinfo.cpp
+++ b/src/coreclr/src/jit/scopeinfo.cpp
@@ -1673,7 +1673,7 @@ void CodeGen::psiEndProlog()
We still report all the arguments at the very start of the method so that
the user can see the arguments at the very start of the method (offset=0).
- Disabling this decreased the debug maps in mscorlib by 10% (01/2003)
+ Disabling this decreased the debug maps in CoreLib by 10% (01/2003)
*/
#if 0
diff --git a/src/coreclr/src/jit/simdcodegenxarch.cpp b/src/coreclr/src/jit/simdcodegenxarch.cpp
index a1acdfd2f1a729..4045c9b97f6280 100644
--- a/src/coreclr/src/jit/simdcodegenxarch.cpp
+++ b/src/coreclr/src/jit/simdcodegenxarch.cpp
@@ -585,9 +585,9 @@ void CodeGen::genSIMDIntrinsicInit(GenTreeSIMD* simdNode)
}
else if (op1->OperIsLocalAddr())
{
- unsigned offset = op1->OperIs(GT_LCL_FLD_ADDR) ? op1->AsLclFld()->GetLclOffs() : 0;
- GetEmitter()->emitIns_R_S(ins, emitTypeSize(targetType), targetReg, op1->AsLclVarCommon()->GetLclNum(),
- offset);
+ const GenTreeLclVarCommon* lclVar = op1->AsLclVarCommon();
+ unsigned offset = lclVar->GetLclOffs();
+ GetEmitter()->emitIns_R_S(ins, emitTypeSize(targetType), targetReg, lclVar->GetLclNum(), offset);
}
else
{
@@ -2143,17 +2143,14 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode)
{
assert((treeNode->OperGet() == GT_STORE_LCL_FLD) || (treeNode->OperGet() == GT_STORE_LCL_VAR));
- unsigned offs = 0;
- unsigned varNum = treeNode->AsLclVarCommon()->GetLclNum();
- assert(varNum < compiler->lvaCount);
+ const GenTreeLclVarCommon* lclVar = treeNode->AsLclVarCommon();
- if (treeNode->OperGet() == GT_STORE_LCL_FLD)
- {
- offs = treeNode->AsLclFld()->GetLclOffs();
- }
+ unsigned offs = lclVar->GetLclOffs();
+ unsigned varNum = lclVar->GetLclNum();
+ assert(varNum < compiler->lvaCount);
regNumber tmpReg = treeNode->GetSingleTempReg();
- GenTree* op1 = treeNode->AsOp()->gtOp1;
+ GenTree* op1 = lclVar->gtOp1;
if (op1->isContained())
{
// This is only possible for a zero-init.
@@ -2197,16 +2194,12 @@ void CodeGen::genLoadLclTypeSIMD12(GenTree* treeNode)
{
assert((treeNode->OperGet() == GT_LCL_FLD) || (treeNode->OperGet() == GT_LCL_VAR));
- regNumber targetReg = treeNode->GetRegNum();
- unsigned offs = 0;
- unsigned varNum = treeNode->AsLclVarCommon()->GetLclNum();
+ const GenTreeLclVarCommon* lclVar = treeNode->AsLclVarCommon();
+ regNumber targetReg = lclVar->GetRegNum();
+ unsigned offs = lclVar->GetLclOffs();
+ unsigned varNum = lclVar->GetLclNum();
assert(varNum < compiler->lvaCount);
- if (treeNode->OperGet() == GT_LCL_FLD)
- {
- offs = treeNode->AsLclFld()->GetLclOffs();
- }
-
// Need an additional Xmm register that is different from targetReg to read upper 4 bytes.
regNumber tmpReg = treeNode->GetSingleTempReg();
assert(tmpReg != targetReg);
diff --git a/src/coreclr/src/jit/ssabuilder.cpp b/src/coreclr/src/jit/ssabuilder.cpp
index d562065bf21655..62efd8696dac86 100644
--- a/src/coreclr/src/jit/ssabuilder.cpp
+++ b/src/coreclr/src/jit/ssabuilder.cpp
@@ -1656,8 +1656,6 @@ bool SsaBuilder::IncludeInSsa(unsigned lclNum)
// - SSA doesn't allow a single node to contain multiple SSA definitions.
// - and PROMOTION_TYPE_DEPENDEDNT fields are never candidates for a register.
//
- // Example mscorlib method: CompatibilitySwitches:IsCompatibilitySwitchSet
- //
return false;
}
else if (varDsc->lvIsStructField && m_pCompiler->lvaGetDesc(varDsc->lvParentLcl)->lvIsMultiRegRet)
diff --git a/src/coreclr/src/jit/static/CMakeLists.txt b/src/coreclr/src/jit/static/CMakeLists.txt
index b4e62c041cd449..01bdbf5a731f5c 100644
--- a/src/coreclr/src/jit/static/CMakeLists.txt
+++ b/src/coreclr/src/jit/static/CMakeLists.txt
@@ -2,14 +2,17 @@ project(ClrJit)
set_source_files_properties(${JIT_EXPORTS_FILE} PROPERTIES GENERATED TRUE)
-add_library_clr(clrjit_static
+add_library_clr(clrjit_obj
OBJECT
${JIT_CORE_SOURCES}
${JIT_ARCH_SOURCES}
)
if(CLR_CMAKE_HOST_UNIX)
- add_dependencies(clrjit_static coreclrpal gcinfo)
+ add_dependencies(clrjit_obj coreclrpal gcinfo)
endif(CLR_CMAKE_HOST_UNIX)
-target_precompile_header(TARGET clrjit_static HEADER jitpch.h ADDITIONAL_INCLUDE_DIRECTORIES ${JIT_SOURCE_DIR})
+target_precompile_header(TARGET clrjit_obj HEADER jitpch.h ADDITIONAL_INCLUDE_DIRECTORIES ${JIT_SOURCE_DIR})
+
+add_library(clrjit_static INTERFACE)
+target_sources(clrjit_static INTERFACE $)
diff --git a/src/coreclr/src/jit/target.h b/src/coreclr/src/jit/target.h
index c9fc28df7bb1c8..5b1f6cff48bca2 100644
--- a/src/coreclr/src/jit/target.h
+++ b/src/coreclr/src/jit/target.h
@@ -31,12 +31,15 @@
// with static const members of Target
#if defined(TARGET_XARCH)
#define REGMASK_BITS 32
+#define CSE_CONST_SHARED_LOW_BITS 16
#elif defined(TARGET_ARM)
#define REGMASK_BITS 64
+#define CSE_CONST_SHARED_LOW_BITS 12
#elif defined(TARGET_ARM64)
#define REGMASK_BITS 64
+#define CSE_CONST_SHARED_LOW_BITS 12
#else
#error Unsupported or unset target architecture
@@ -433,6 +436,7 @@ typedef unsigned char regNumberSmall;
#define FIRST_ARG_STACK_OFFS (2*REGSIZE_BYTES) // Caller's saved EBP and return address
#define MAX_REG_ARG 2
+
#define MAX_FLOAT_REG_ARG 0
#define REG_ARG_FIRST REG_ECX
#define REG_ARG_LAST REG_EDX
@@ -441,10 +445,8 @@ typedef unsigned char regNumberSmall;
#define REG_ARG_0 REG_ECX
#define REG_ARG_1 REG_EDX
- SELECTANY const regNumber intArgRegs [] = {REG_ECX, REG_EDX};
- SELECTANY const regMaskTP intArgMasks[] = {RBM_ECX, RBM_EDX};
- SELECTANY const regNumber fltArgRegs [] = {REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3};
- SELECTANY const regMaskTP fltArgMasks[] = {RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3};
+ extern const regNumber intArgRegs [MAX_REG_ARG];
+ extern const regMaskTP intArgMasks[MAX_REG_ARG];
#define RBM_ARG_0 RBM_ECX
#define RBM_ARG_1 RBM_EDX
@@ -779,10 +781,10 @@ typedef unsigned char regNumberSmall;
#define REG_ARG_4 REG_R8
#define REG_ARG_5 REG_R9
- SELECTANY const regNumber intArgRegs [] = { REG_EDI, REG_ESI, REG_EDX, REG_ECX, REG_R8, REG_R9 };
- SELECTANY const regMaskTP intArgMasks[] = { RBM_EDI, RBM_ESI, RBM_EDX, RBM_ECX, RBM_R8, RBM_R9 };
- SELECTANY const regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3, REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7 };
- SELECTANY const regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3, RBM_XMM4, RBM_XMM5, RBM_XMM6, RBM_XMM7 };
+ extern const regNumber intArgRegs [MAX_REG_ARG];
+ extern const regMaskTP intArgMasks[MAX_REG_ARG];
+ extern const regNumber fltArgRegs [MAX_FLOAT_REG_ARG];
+ extern const regMaskTP fltArgMasks[MAX_FLOAT_REG_ARG];
#define RBM_ARG_0 RBM_RDI
#define RBM_ARG_1 RBM_RSI
@@ -802,10 +804,10 @@ typedef unsigned char regNumberSmall;
#define REG_ARG_2 REG_R8
#define REG_ARG_3 REG_R9
- SELECTANY const regNumber intArgRegs [] = { REG_ECX, REG_EDX, REG_R8, REG_R9 };
- SELECTANY const regMaskTP intArgMasks[] = { RBM_ECX, RBM_EDX, RBM_R8, RBM_R9 };
- SELECTANY const regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3 };
- SELECTANY const regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3 };
+ extern const regNumber intArgRegs [MAX_REG_ARG];
+ extern const regMaskTP intArgMasks[MAX_REG_ARG];
+ extern const regNumber fltArgRegs [MAX_FLOAT_REG_ARG];
+ extern const regMaskTP fltArgMasks[MAX_FLOAT_REG_ARG];
#define RBM_ARG_0 RBM_ECX
#define RBM_ARG_1 RBM_EDX
@@ -1103,7 +1105,9 @@ typedef unsigned char regNumberSmall;
// The registers trashed by profiler enter/leave/tailcall hook
// See vm\arm\asmhelpers.asm for more details.
#define RBM_PROFILER_ENTER_TRASH RBM_NONE
- #define RBM_PROFILER_LEAVE_TRASH RBM_NONE
+ // While REG_PROFILER_RET_SCRATCH is not trashed by the method, the register allocator must
+ // consider it killed by the return.
+ #define RBM_PROFILER_LEAVE_TRASH RBM_PROFILER_RET_SCRATCH
#define RBM_PROFILER_TAILCALL_TRASH RBM_NONE
// Which register are int and long values returned in ?
@@ -1150,8 +1154,8 @@ typedef unsigned char regNumberSmall;
#define REG_ARG_2 REG_R2
#define REG_ARG_3 REG_R3
- SELECTANY const regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3};
- SELECTANY const regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3};
+ extern const regNumber intArgRegs [MAX_REG_ARG];
+ extern const regMaskTP intArgMasks[MAX_REG_ARG];
#define RBM_ARG_0 RBM_R0
#define RBM_ARG_1 RBM_R1
@@ -1162,8 +1166,8 @@ typedef unsigned char regNumberSmall;
#define RBM_FLTARG_REGS (RBM_F0|RBM_F1|RBM_F2|RBM_F3|RBM_F4|RBM_F5|RBM_F6|RBM_F7|RBM_F8|RBM_F9|RBM_F10|RBM_F11|RBM_F12|RBM_F13|RBM_F14|RBM_F15)
#define RBM_DBL_REGS RBM_ALLDOUBLE
- SELECTANY const regNumber fltArgRegs [] = {REG_F0, REG_F1, REG_F2, REG_F3, REG_F4, REG_F5, REG_F6, REG_F7, REG_F8, REG_F9, REG_F10, REG_F11, REG_F12, REG_F13, REG_F14, REG_F15 };
- SELECTANY const regMaskTP fltArgMasks[] = {RBM_F0, RBM_F1, RBM_F2, RBM_F3, RBM_F4, RBM_F5, RBM_F6, RBM_F7, RBM_F8, RBM_F9, RBM_F10, RBM_F11, RBM_F12, RBM_F13, RBM_F14, RBM_F15 };
+ extern const regNumber fltArgRegs [MAX_FLOAT_REG_ARG];
+ extern const regMaskTP fltArgMasks[MAX_FLOAT_REG_ARG];
#define LBL_DIST_SMALL_MAX_NEG (0)
#define LBL_DIST_SMALL_MAX_POS (+1020)
@@ -1484,8 +1488,8 @@ typedef unsigned char regNumberSmall;
#define REG_ARG_6 REG_R6
#define REG_ARG_7 REG_R7
- SELECTANY const regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7};
- SELECTANY const regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3, RBM_R4, RBM_R5, RBM_R6, RBM_R7};
+ extern const regNumber intArgRegs [MAX_REG_ARG];
+ extern const regMaskTP intArgMasks[MAX_REG_ARG];
#define RBM_ARG_0 RBM_R0
#define RBM_ARG_1 RBM_R1
@@ -1517,8 +1521,8 @@ typedef unsigned char regNumberSmall;
#define RBM_ARG_REGS (RBM_ARG_0|RBM_ARG_1|RBM_ARG_2|RBM_ARG_3|RBM_ARG_4|RBM_ARG_5|RBM_ARG_6|RBM_ARG_7)
#define RBM_FLTARG_REGS (RBM_FLTARG_0|RBM_FLTARG_1|RBM_FLTARG_2|RBM_FLTARG_3|RBM_FLTARG_4|RBM_FLTARG_5|RBM_FLTARG_6|RBM_FLTARG_7)
- SELECTANY const regNumber fltArgRegs [] = {REG_V0, REG_V1, REG_V2, REG_V3, REG_V4, REG_V5, REG_V6, REG_V7 };
- SELECTANY const regMaskTP fltArgMasks[] = {RBM_V0, RBM_V1, RBM_V2, RBM_V3, RBM_V4, RBM_V5, RBM_V6, RBM_V7 };
+ extern const regNumber fltArgRegs [MAX_FLOAT_REG_ARG];
+ extern const regMaskTP fltArgMasks[MAX_FLOAT_REG_ARG];
#define LBL_DIST_SMALL_MAX_NEG (-1048576)
#define LBL_DIST_SMALL_MAX_POS (+1048575)
@@ -1616,11 +1620,11 @@ class Target
static const enum ArgOrder g_tgtArgOrder;
};
-#if defined(DEBUG) || defined(LATE_DISASM)
+#if defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES
const char* getRegName(unsigned reg, bool isFloat = false); // this is for gcencode.cpp and disasm.cpp that don't use
// the regNumber type
const char* getRegName(regNumber reg, bool isFloat = false);
-#endif // defined(DEBUG) || defined(LATE_DISASM)
+#endif // defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES
#ifdef DEBUG
const char* getRegNameFloat(regNumber reg, var_types type);
@@ -1997,9 +2001,13 @@ C_ASSERT((RBM_INT_CALLEE_SAVED & RBM_FPBASE) == RBM_NONE);
#ifdef TARGET_64BIT
typedef unsigned __int64 target_size_t;
typedef __int64 target_ssize_t;
-#else // !TARGET_64BIT
+#define TARGET_SIGN_BIT (1ULL << 63)
+
+#else // !TARGET_64BIT
typedef unsigned int target_size_t;
typedef int target_ssize_t;
+#define TARGET_SIGN_BIT (1ULL << 31)
+
#endif // !TARGET_64BIT
C_ASSERT(sizeof(target_size_t) == TARGET_POINTER_SIZE);
diff --git a/src/coreclr/src/jit/targetamd64.cpp b/src/coreclr/src/jit/targetamd64.cpp
index 143e6e4641803a..372c4dffc27b2b 100644
--- a/src/coreclr/src/jit/targetamd64.cpp
+++ b/src/coreclr/src/jit/targetamd64.cpp
@@ -15,4 +15,18 @@
const char* Target::g_tgtCPUName = "x64";
const Target::ArgOrder Target::g_tgtArgOrder = ARG_ORDER_R2L;
+// clang-format off
+#ifdef UNIX_AMD64_ABI
+const regNumber intArgRegs [] = { REG_EDI, REG_ESI, REG_EDX, REG_ECX, REG_R8, REG_R9 };
+const regMaskTP intArgMasks[] = { RBM_EDI, RBM_ESI, RBM_EDX, RBM_ECX, RBM_R8, RBM_R9 };
+const regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3, REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7 };
+const regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3, RBM_XMM4, RBM_XMM5, RBM_XMM6, RBM_XMM7 };
+#else // !UNIX_AMD64_ABI
+const regNumber intArgRegs [] = { REG_ECX, REG_EDX, REG_R8, REG_R9 };
+const regMaskTP intArgMasks[] = { RBM_ECX, RBM_EDX, RBM_R8, RBM_R9 };
+const regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3 };
+const regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3 };
+#endif // !UNIX_AMD64_ABI
+// clang-format on
+
#endif // TARGET_AMD64
diff --git a/src/coreclr/src/jit/targetarm.cpp b/src/coreclr/src/jit/targetarm.cpp
index ca974a76af390f..da125cbb436a0e 100644
--- a/src/coreclr/src/jit/targetarm.cpp
+++ b/src/coreclr/src/jit/targetarm.cpp
@@ -15,4 +15,12 @@
const char* Target::g_tgtCPUName = "arm";
const Target::ArgOrder Target::g_tgtArgOrder = ARG_ORDER_R2L;
+// clang-format off
+const regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3};
+const regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3};
+
+const regNumber fltArgRegs [] = {REG_F0, REG_F1, REG_F2, REG_F3, REG_F4, REG_F5, REG_F6, REG_F7, REG_F8, REG_F9, REG_F10, REG_F11, REG_F12, REG_F13, REG_F14, REG_F15 };
+const regMaskTP fltArgMasks[] = {RBM_F0, RBM_F1, RBM_F2, RBM_F3, RBM_F4, RBM_F5, RBM_F6, RBM_F7, RBM_F8, RBM_F9, RBM_F10, RBM_F11, RBM_F12, RBM_F13, RBM_F14, RBM_F15 };
+// clang-format on
+
#endif // TARGET_ARM
diff --git a/src/coreclr/src/jit/targetarm64.cpp b/src/coreclr/src/jit/targetarm64.cpp
index 7b035f145b01e3..8f5481a83e02d0 100644
--- a/src/coreclr/src/jit/targetarm64.cpp
+++ b/src/coreclr/src/jit/targetarm64.cpp
@@ -15,4 +15,12 @@
const char* Target::g_tgtCPUName = "arm64";
const Target::ArgOrder Target::g_tgtArgOrder = ARG_ORDER_R2L;
+// clang-format off
+const regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7};
+const regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3, RBM_R4, RBM_R5, RBM_R6, RBM_R7};
+
+const regNumber fltArgRegs [] = {REG_V0, REG_V1, REG_V2, REG_V3, REG_V4, REG_V5, REG_V6, REG_V7 };
+const regMaskTP fltArgMasks[] = {RBM_V0, RBM_V1, RBM_V2, RBM_V3, RBM_V4, RBM_V5, RBM_V6, RBM_V7 };
+// clang-format on
+
#endif // TARGET_ARM64
diff --git a/src/coreclr/src/jit/targetx86.cpp b/src/coreclr/src/jit/targetx86.cpp
index 391a934e5b9e78..fab7286782a2d9 100644
--- a/src/coreclr/src/jit/targetx86.cpp
+++ b/src/coreclr/src/jit/targetx86.cpp
@@ -15,4 +15,9 @@
const char* Target::g_tgtCPUName = "x86";
const Target::ArgOrder Target::g_tgtArgOrder = ARG_ORDER_L2R;
+// clang-format off
+const regNumber intArgRegs [] = {REG_ECX, REG_EDX};
+const regMaskTP intArgMasks[] = {RBM_ECX, RBM_EDX};
+// clang-format on
+
#endif // TARGET_X86
diff --git a/src/coreclr/src/jit/unwind.h b/src/coreclr/src/jit/unwind.h
index 5541450e0ef715..f510eb6f1d822a 100644
--- a/src/coreclr/src/jit/unwind.h
+++ b/src/coreclr/src/jit/unwind.h
@@ -150,7 +150,7 @@ class UnwindCodesBase
class UnwindPrologCodes : public UnwindBase, public UnwindCodesBase
{
- // UPC_LOCAL_COUNT is the amount of memory local to this class. For ARM mscorlib.dll, the maximum size is 34.
+ // UPC_LOCAL_COUNT is the amount of memory local to this class. For ARM CoreLib, the maximum size is 34.
// Here is a histogram of other interesting sizes:
// <=16 79%
// <=24 96%
@@ -314,7 +314,7 @@ class UnwindPrologCodes : public UnwindBase, public UnwindCodesBase
class UnwindEpilogCodes : public UnwindBase, public UnwindCodesBase
{
- // UEC_LOCAL_COUNT is the amount of memory local to this class. For ARM mscorlib.dll, the maximum size is 6,
+ // UEC_LOCAL_COUNT is the amount of memory local to this class. For ARM CoreLib, the maximum size is 6,
// while 89% of epilogs fit in 4. So, set it to 4 to maintain array alignment and hit most cases.
static const int UEC_LOCAL_COUNT = 4;
diff --git a/src/coreclr/src/jit/utils.cpp b/src/coreclr/src/jit/utils.cpp
index 4477ceb16295b2..de1fd4a880b2c6 100644
--- a/src/coreclr/src/jit/utils.cpp
+++ b/src/coreclr/src/jit/utils.cpp
@@ -128,7 +128,7 @@ const char* varTypeName(var_types vt)
return varTypeNames[vt];
}
-#if defined(DEBUG) || defined(LATE_DISASM)
+#if defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES
/*****************************************************************************
*
* Return the name of the given register.
@@ -164,7 +164,7 @@ const char* getRegName(unsigned reg,
{
return getRegName((regNumber)reg, isFloat);
}
-#endif // defined(DEBUG) || defined(LATE_DISASM)
+#endif // defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES
#if defined(DEBUG)
@@ -767,11 +767,11 @@ void ConfigMethodRange::InitRanges(const WCHAR* rangeStr, unsigned capacity)
}
else if ((L'A' <= *p) && (*p <= L'F'))
{
- n = (*p++) - L'A';
+ n = (*p++) - L'A' + 10;
}
else if ((L'a' <= *p) && (*p <= L'f'))
{
- n = (*p++) - L'a';
+ n = (*p++) - L'a' + 10;
}
int j = 16 * i + n;
diff --git a/src/coreclr/src/jit/valuenum.cpp b/src/coreclr/src/jit/valuenum.cpp
index 1cc0cab621ca60..51e23701a77df7 100644
--- a/src/coreclr/src/jit/valuenum.cpp
+++ b/src/coreclr/src/jit/valuenum.cpp
@@ -4137,14 +4137,23 @@ ValueNum Compiler::fgValueNumberArrIndexVal(GenTree* tree,
ValueNum Compiler::fgValueNumberByrefExposedLoad(var_types type, ValueNum pointerVN)
{
- ValueNum memoryVN = fgCurMemoryVN[ByrefExposed];
- // The memoization for VNFunc applications does not factor in the result type, so
- // VNF_ByrefExposedLoad takes the loaded type as an explicit parameter.
- ValueNum typeVN = vnStore->VNForIntCon(type);
- ValueNum loadVN =
- vnStore->VNForFunc(type, VNF_ByrefExposedLoad, typeVN, vnStore->VNNormalValue(pointerVN), memoryVN);
-
- return loadVN;
+ if (type == TYP_STRUCT)
+ {
+ // We can't assign a value number for a read of a struct as we can't determine
+ // how many bytes will be read by this load, so return a new unique value number
+ //
+ return vnStore->VNForExpr(compCurBB, TYP_STRUCT);
+ }
+ else
+ {
+ ValueNum memoryVN = fgCurMemoryVN[ByrefExposed];
+ // The memoization for VNFunc applications does not factor in the result type, so
+ // VNF_ByrefExposedLoad takes the loaded type as an explicit parameter.
+ ValueNum typeVN = vnStore->VNForIntCon(type);
+ ValueNum loadVN =
+ vnStore->VNForFunc(type, VNF_ByrefExposedLoad, typeVN, vnStore->VNNormalValue(pointerVN), memoryVN);
+ return loadVN;
+ }
}
var_types ValueNumStore::TypeOfVN(ValueNum vn)
@@ -4548,7 +4557,7 @@ void ValueNumStore::SetVNIsCheckedBound(ValueNum vn)
m_checkedBoundVNs.AddOrUpdate(vn, true);
}
-ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMathFN, ValueNum arg0VN)
+ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, NamedIntrinsic gtMathFN, ValueNum arg0VN)
{
assert(arg0VN == VNNormalValue(arg0VN));
@@ -4568,25 +4577,25 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat
double res = 0.0;
switch (gtMathFN)
{
- case CORINFO_INTRINSIC_Sin:
+ case NI_System_Math_Sin:
res = sin(arg0Val);
break;
- case CORINFO_INTRINSIC_Cos:
+ case NI_System_Math_Cos:
res = cos(arg0Val);
break;
- case CORINFO_INTRINSIC_Sqrt:
+ case NI_System_Math_Sqrt:
res = sqrt(arg0Val);
break;
- case CORINFO_INTRINSIC_Abs:
+ case NI_System_Math_Abs:
res = fabs(arg0Val);
break;
- case CORINFO_INTRINSIC_Ceiling:
+ case NI_System_Math_Ceiling:
res = ceil(arg0Val);
break;
- case CORINFO_INTRINSIC_Floor:
+ case NI_System_Math_Floor:
res = floor(arg0Val);
break;
- case CORINFO_INTRINSIC_Round:
+ case NI_System_Math_Round:
res = FloatingPointUtils::round(arg0Val);
break;
default:
@@ -4604,25 +4613,25 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat
float res = 0.0f;
switch (gtMathFN)
{
- case CORINFO_INTRINSIC_Sin:
+ case NI_System_Math_Sin:
res = sinf(arg0Val);
break;
- case CORINFO_INTRINSIC_Cos:
+ case NI_System_Math_Cos:
res = cosf(arg0Val);
break;
- case CORINFO_INTRINSIC_Sqrt:
+ case NI_System_Math_Sqrt:
res = sqrtf(arg0Val);
break;
- case CORINFO_INTRINSIC_Abs:
+ case NI_System_Math_Abs:
res = fabsf(arg0Val);
break;
- case CORINFO_INTRINSIC_Ceiling:
+ case NI_System_Math_Ceiling:
res = ceilf(arg0Val);
break;
- case CORINFO_INTRINSIC_Floor:
+ case NI_System_Math_Floor:
res = floorf(arg0Val);
break;
- case CORINFO_INTRINSIC_Round:
+ case NI_System_Math_Round:
res = FloatingPointUtils::round(arg0Val);
break;
default:
@@ -4633,11 +4642,11 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat
}
else
{
- // CORINFO_INTRINSIC_Round is currently the only intrinsic that takes floating-point arguments
- // and that returns a non floating-point result.
+ // NI_System_Math{F}_Round are currently the only intrinsic that take floating-point arguments
+ // and return a non floating-point result.
assert(typ == TYP_INT);
- assert(gtMathFN == CORINFO_INTRINSIC_Round);
+ assert(gtMathFN == NI_System_Math_Round);
int res = 0;
@@ -4664,27 +4673,27 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat
}
else
{
- assert(typ == TYP_DOUBLE || typ == TYP_FLOAT || (typ == TYP_INT && gtMathFN == CORINFO_INTRINSIC_Round));
+ assert(typ == TYP_DOUBLE || typ == TYP_FLOAT || typ == TYP_INT && gtMathFN == NI_System_Math_Round);
VNFunc vnf = VNF_Boundary;
switch (gtMathFN)
{
- case CORINFO_INTRINSIC_Sin:
+ case NI_System_Math_Sin:
vnf = VNF_Sin;
break;
- case CORINFO_INTRINSIC_Cos:
+ case NI_System_Math_Cos:
vnf = VNF_Cos;
break;
- case CORINFO_INTRINSIC_Cbrt:
+ case NI_System_Math_Cbrt:
vnf = VNF_Cbrt;
break;
- case CORINFO_INTRINSIC_Sqrt:
+ case NI_System_Math_Sqrt:
vnf = VNF_Sqrt;
break;
- case CORINFO_INTRINSIC_Abs:
+ case NI_System_Math_Abs:
vnf = VNF_Abs;
break;
- case CORINFO_INTRINSIC_Round:
+ case NI_System_Math_Round:
if (typ == TYP_DOUBLE)
{
vnf = VNF_RoundDouble;
@@ -4702,46 +4711,46 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat
noway_assert(!"Invalid INTRINSIC_Round");
}
break;
- case CORINFO_INTRINSIC_Cosh:
+ case NI_System_Math_Cosh:
vnf = VNF_Cosh;
break;
- case CORINFO_INTRINSIC_Sinh:
+ case NI_System_Math_Sinh:
vnf = VNF_Sinh;
break;
- case CORINFO_INTRINSIC_Tan:
+ case NI_System_Math_Tan:
vnf = VNF_Tan;
break;
- case CORINFO_INTRINSIC_Tanh:
+ case NI_System_Math_Tanh:
vnf = VNF_Tanh;
break;
- case CORINFO_INTRINSIC_Asin:
+ case NI_System_Math_Asin:
vnf = VNF_Asin;
break;
- case CORINFO_INTRINSIC_Asinh:
+ case NI_System_Math_Asinh:
vnf = VNF_Asinh;
break;
- case CORINFO_INTRINSIC_Acos:
+ case NI_System_Math_Acos:
vnf = VNF_Acos;
break;
- case CORINFO_INTRINSIC_Acosh:
+ case NI_System_Math_Acosh:
vnf = VNF_Acosh;
break;
- case CORINFO_INTRINSIC_Atan:
+ case NI_System_Math_Atan:
vnf = VNF_Atan;
break;
- case CORINFO_INTRINSIC_Atanh:
+ case NI_System_Math_Atanh:
vnf = VNF_Atanh;
break;
- case CORINFO_INTRINSIC_Log10:
+ case NI_System_Math_Log10:
vnf = VNF_Log10;
break;
- case CORINFO_INTRINSIC_Exp:
+ case NI_System_Math_Exp:
vnf = VNF_Exp;
break;
- case CORINFO_INTRINSIC_Ceiling:
+ case NI_System_Math_Ceiling:
vnf = VNF_Ceiling;
break;
- case CORINFO_INTRINSIC_Floor:
+ case NI_System_Math_Floor:
vnf = VNF_Floor;
break;
default:
@@ -4752,7 +4761,7 @@ ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMat
}
}
-ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, CorInfoIntrinsics gtMathFN, ValueNum arg0VN, ValueNum arg1VN)
+ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, NamedIntrinsic gtMathFN, ValueNum arg0VN, ValueNum arg1VN)
{
assert(varTypeIsFloating(typ));
assert(arg0VN == VNNormalValue(arg0VN));
@@ -4765,11 +4774,11 @@ ValueNum ValueNumStore::EvalMathFuncBinary(var_types typ, CorInfoIntrinsics gtMa
switch (gtMathFN)
{
- case CORINFO_INTRINSIC_Atan2:
+ case NI_System_Math_Atan2:
vnf = VNF_Atan2;
break;
- case CORINFO_INTRINSIC_Pow:
+ case NI_System_Math_Pow:
vnf = VNF_Pow;
break;
@@ -8389,7 +8398,7 @@ void Compiler::fgValueNumberIntrinsic(GenTree* tree)
vnStore->VNPUnpackExc(intrinsic->AsOp()->gtOp2->gtVNPair, &arg1VNP, &arg1VNPx);
}
- if (IsMathIntrinsic(intrinsic->gtIntrinsicId))
+ if (IsMathIntrinsic(intrinsic->gtIntrinsicName))
{
// GT_INTRINSIC is a currently a subtype of binary operators. But most of
// the math intrinsics are actually unary operations.
@@ -8397,13 +8406,13 @@ void Compiler::fgValueNumberIntrinsic(GenTree* tree)
if (intrinsic->AsOp()->gtOp2 == nullptr)
{
intrinsic->gtVNPair =
- vnStore->VNPWithExc(vnStore->EvalMathFuncUnary(tree->TypeGet(), intrinsic->gtIntrinsicId, arg0VNP),
+ vnStore->VNPWithExc(vnStore->EvalMathFuncUnary(tree->TypeGet(), intrinsic->gtIntrinsicName, arg0VNP),
arg0VNPx);
}
else
{
ValueNumPair newVNP =
- vnStore->EvalMathFuncBinary(tree->TypeGet(), intrinsic->gtIntrinsicId, arg0VNP, arg1VNP);
+ vnStore->EvalMathFuncBinary(tree->TypeGet(), intrinsic->gtIntrinsicName, arg0VNP, arg1VNP);
ValueNumPair excSet = vnStore->VNPExcSetUnion(arg0VNPx, arg1VNPx);
intrinsic->gtVNPair = vnStore->VNPWithExc(newVNP, excSet);
}
@@ -8615,7 +8624,7 @@ void Compiler::fgValueNumberHWIntrinsic(GenTree* tree)
else if (tree->AsOp()->gtOp1->OperIs(GT_LIST) || (lookupNumArgs == -1))
{
// We have a HWINTRINSIC node in the GT_LIST form with 3 or more args
- // Or the numArgs was specified as -1 in the numArgs column in "hwinstrinsiclistxarch.h"
+ // Or the numArgs was specified as -1 in the numArgs column in "hwintrinsiclistxarch.h"
// For now we will generate a unique value number for this case.
// Generate unique VN
diff --git a/src/coreclr/src/jit/valuenum.h b/src/coreclr/src/jit/valuenum.h
index 9f3cc2025be203..2f57b6323e6748 100644
--- a/src/coreclr/src/jit/valuenum.h
+++ b/src/coreclr/src/jit/valuenum.h
@@ -818,20 +818,17 @@ class ValueNumStore
// "arg0VN". For binary ops, return the value number for the application of this function to "arg0VN" and
// "arg1VN".
- ValueNum EvalMathFuncUnary(var_types typ, CorInfoIntrinsics mthFunc, ValueNum arg0VN);
+ ValueNum EvalMathFuncUnary(var_types typ, NamedIntrinsic mthFunc, ValueNum arg0VN);
- ValueNum EvalMathFuncBinary(var_types typ, CorInfoIntrinsics mthFunc, ValueNum arg0VN, ValueNum arg1VN);
+ ValueNum EvalMathFuncBinary(var_types typ, NamedIntrinsic mthFunc, ValueNum arg0VN, ValueNum arg1VN);
- ValueNumPair EvalMathFuncUnary(var_types typ, CorInfoIntrinsics mthFunc, ValueNumPair arg0VNP)
+ ValueNumPair EvalMathFuncUnary(var_types typ, NamedIntrinsic mthFunc, ValueNumPair arg0VNP)
{
return ValueNumPair(EvalMathFuncUnary(typ, mthFunc, arg0VNP.GetLiberal()),
EvalMathFuncUnary(typ, mthFunc, arg0VNP.GetConservative()));
}
- ValueNumPair EvalMathFuncBinary(var_types typ,
- CorInfoIntrinsics mthFunc,
- ValueNumPair arg0VNP,
- ValueNumPair arg1VNP)
+ ValueNumPair EvalMathFuncBinary(var_types typ, NamedIntrinsic mthFunc, ValueNumPair arg0VNP, ValueNumPair arg1VNP)
{
return ValueNumPair(EvalMathFuncBinary(typ, mthFunc, arg0VNP.GetLiberal(), arg1VNP.GetLiberal()),
EvalMathFuncBinary(typ, mthFunc, arg0VNP.GetConservative(), arg1VNP.GetConservative()));
diff --git a/src/coreclr/src/md/ceefilegen/CMakeLists.txt b/src/coreclr/src/md/ceefilegen/CMakeLists.txt
index 39864c71817f55..fd0f8424d97f12 100644
--- a/src/coreclr/src/md/ceefilegen/CMakeLists.txt
+++ b/src/coreclr/src/md/ceefilegen/CMakeLists.txt
@@ -25,8 +25,11 @@ if (CLR_CMAKE_TARGET_WIN32)
list(APPEND CEEFILEGEN_SOURCES ${CEEFILEGEN_HEADERS})
endif (CLR_CMAKE_TARGET_WIN32)
-add_library_clr(ceefgen
+add_library_clr(ceefgen_obj
OBJECT
${CEEFILEGEN_SOURCES}
)
-target_precompile_header(TARGET ceefgen HEADER stdafx.h)
+target_precompile_header(TARGET ceefgen_obj HEADER stdafx.h)
+
+add_library(ceefgen INTERFACE)
+target_sources(ceefgen INTERFACE $)
diff --git a/src/coreclr/src/md/compiler/CMakeLists.txt b/src/coreclr/src/md/compiler/CMakeLists.txt
index 495fa4d70ca262..f32c80407c6a59 100644
--- a/src/coreclr/src/md/compiler/CMakeLists.txt
+++ b/src/coreclr/src/md/compiler/CMakeLists.txt
@@ -68,9 +68,11 @@ add_library_clr(mdcompiler_dac ${MDCOMPILER_SOURCES})
set_target_properties(mdcompiler_dac PROPERTIES DAC_COMPONENT TRUE)
target_precompile_header(TARGET mdcompiler_dac HEADER stdafx.h)
-add_library_clr(mdcompiler_wks OBJECT ${MDCOMPILER_WKS_SOURCES})
-target_compile_definitions(mdcompiler_wks PRIVATE FEATURE_METADATA_EMIT_ALL)
-target_precompile_header(TARGET mdcompiler_wks HEADER stdafx.h)
+add_library_clr(mdcompiler_wks_obj OBJECT ${MDCOMPILER_WKS_SOURCES})
+target_compile_definitions(mdcompiler_wks_obj PRIVATE FEATURE_METADATA_EMIT_ALL)
+target_precompile_header(TARGET mdcompiler_wks_obj HEADER stdafx.h)
+add_library(mdcompiler_wks INTERFACE)
+target_sources(mdcompiler_wks INTERFACE $)
add_library_clr(mdcompiler-dbi ${MDCOMPILER_SOURCES})
set_target_properties(mdcompiler-dbi PROPERTIES DBI_COMPONENT TRUE)
diff --git a/src/coreclr/src/md/enc/CMakeLists.txt b/src/coreclr/src/md/enc/CMakeLists.txt
index 14ed0a267fae67..e30c51b1e37c4e 100644
--- a/src/coreclr/src/md/enc/CMakeLists.txt
+++ b/src/coreclr/src/md/enc/CMakeLists.txt
@@ -52,9 +52,11 @@ add_library_clr(mdruntimerw_dac ${MDRUNTIMERW_SOURCES})
set_target_properties(mdruntimerw_dac PROPERTIES DAC_COMPONENT TRUE)
target_precompile_header(TARGET mdruntimerw_dac HEADER stdafx.h)
-add_library_clr(mdruntimerw_wks OBJECT ${MDRUNTIMERW_SOURCES})
-target_compile_definitions(mdruntimerw_wks PRIVATE FEATURE_METADATA_EMIT_ALL)
-target_precompile_header(TARGET mdruntimerw_wks HEADER stdafx.h)
+add_library_clr(mdruntimerw_wks_obj OBJECT ${MDRUNTIMERW_SOURCES})
+target_compile_definitions(mdruntimerw_wks_obj PRIVATE FEATURE_METADATA_EMIT_ALL)
+target_precompile_header(TARGET mdruntimerw_wks_obj HEADER stdafx.h)
+add_library(mdruntimerw_wks INTERFACE)
+target_sources(mdruntimerw_wks INTERFACE $)
add_library_clr(mdruntimerw-dbi ${MDRUNTIMERW_SOURCES})
set_target_properties(mdruntimerw-dbi PROPERTIES DBI_COMPONENT TRUE)
diff --git a/src/coreclr/src/md/hotdata/CMakeLists.txt b/src/coreclr/src/md/hotdata/CMakeLists.txt
index 03430e292c75df..46381cf7dddd11 100644
--- a/src/coreclr/src/md/hotdata/CMakeLists.txt
+++ b/src/coreclr/src/md/hotdata/CMakeLists.txt
@@ -33,8 +33,10 @@ add_library_clr(mdhotdata_dac ${MDHOTDATA_SOURCES})
set_target_properties(mdhotdata_dac PROPERTIES DAC_COMPONENT TRUE)
target_precompile_header(TARGET mdhotdata_dac HEADER external.h)
-add_library_clr(mdhotdata_full OBJECT ${MDHOTDATA_SOURCES})
-target_precompile_header(TARGET mdhotdata_full HEADER external.h)
+add_library_clr(mdhotdata_full_obj OBJECT ${MDHOTDATA_SOURCES})
+target_precompile_header(TARGET mdhotdata_full_obj HEADER external.h)
+add_library(mdhotdata_full INTERFACE)
+target_sources(mdhotdata_full INTERFACE $)
add_library_clr(mdhotdata_crossgen ${MDHOTDATA_SOURCES})
set_target_properties(mdhotdata_crossgen PROPERTIES CROSSGEN_COMPONENT TRUE)
diff --git a/src/coreclr/src/md/runtime/CMakeLists.txt b/src/coreclr/src/md/runtime/CMakeLists.txt
index 5753e655abf990..06e9e830001957 100644
--- a/src/coreclr/src/md/runtime/CMakeLists.txt
+++ b/src/coreclr/src/md/runtime/CMakeLists.txt
@@ -49,9 +49,11 @@ add_library_clr(mdruntime_dac ${MDRUNTIME_SOURCES})
set_target_properties(mdruntime_dac PROPERTIES DAC_COMPONENT TRUE)
target_precompile_header(TARGET mdruntime_dac HEADER stdafx.h)
-add_library_clr(mdruntime_wks OBJECT ${MDRUNTIME_SOURCES})
-target_compile_definitions(mdruntime_wks PRIVATE FEATURE_METADATA_EMIT_ALL)
-target_precompile_header(TARGET mdruntime_wks HEADER stdafx.h)
+add_library_clr(mdruntime_wks_obj OBJECT ${MDRUNTIME_SOURCES})
+target_compile_definitions(mdruntime_wks_obj PRIVATE FEATURE_METADATA_EMIT_ALL)
+target_precompile_header(TARGET mdruntime_wks_obj HEADER stdafx.h)
+add_library(mdruntime_wks INTERFACE)
+target_sources(mdruntime_wks INTERFACE $)
add_library_clr(mdruntime-dbi ${MDRUNTIME_SOURCES})
set_target_properties(mdruntime-dbi PROPERTIES DBI_COMPONENT TRUE)
diff --git a/src/coreclr/src/pal/inc/pal.h b/src/coreclr/src/pal/inc/pal.h
index df658c54690561..fd56fc90c35357 100644
--- a/src/coreclr/src/pal/inc/pal.h
+++ b/src/coreclr/src/pal/inc/pal.h
@@ -511,6 +511,32 @@ PAL_Random(
IN OUT LPVOID lpBuffer,
IN DWORD dwLength);
+PALIMPORT
+BOOL
+PALAPI
+PAL_OpenProcessMemory(
+ IN DWORD processId,
+ OUT DWORD* pHandle
+);
+
+PALIMPORT
+VOID
+PALAPI
+PAL_CloseProcessMemory(
+ IN DWORD handle
+);
+
+PALIMPORT
+BOOL
+PALAPI
+PAL_ReadProcessMemory(
+ IN DWORD handle,
+ IN ULONG64 address,
+ IN LPVOID buffer,
+ IN SIZE_T size,
+ OUT SIZE_T* numberOfBytesRead
+);
+
PALIMPORT
BOOL
PALAPI
diff --git a/src/coreclr/src/pal/inc/rt/guiddef.h b/src/coreclr/src/pal/inc/rt/guiddef.h
index 1a2ed05e16fefa..6650f11092fa24 100644
--- a/src/coreclr/src/pal/inc/rt/guiddef.h
+++ b/src/coreclr/src/pal/inc/rt/guiddef.h
@@ -17,7 +17,7 @@
#ifdef INITGUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
- EXTERN_C DLLEXPORT const GUID DECLSPEC_SELECTANY name \
+ EXTERN_C DLLEXPORT constexpr GUID name \
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#else
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
diff --git a/src/coreclr/src/pal/inc/rt/palrt.h b/src/coreclr/src/pal/inc/rt/palrt.h
index 23f627e1b8e5c6..b021277e437581 100644
--- a/src/coreclr/src/pal/inc/rt/palrt.h
+++ b/src/coreclr/src/pal/inc/rt/palrt.h
@@ -223,7 +223,6 @@ inline void *__cdecl operator new(size_t, void *_P)
#define THIS void
#define DECLSPEC_NOVTABLE
-#define DECLSPEC_SELECTANY __attribute__((weak))
#define DECLARE_INTERFACE(iface) interface DECLSPEC_NOVTABLE iface
#define DECLARE_INTERFACE_(iface, baseiface) interface DECLSPEC_NOVTABLE iface : public baseiface
diff --git a/src/coreclr/src/pal/inc/rt/rpc.h b/src/coreclr/src/pal/inc/rt/rpc.h
index 9b9f425f69fe52..9fd3c096882d61 100644
--- a/src/coreclr/src/pal/inc/rt/rpc.h
+++ b/src/coreclr/src/pal/inc/rt/rpc.h
@@ -25,7 +25,7 @@
#define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x) DECLSPEC_NOVTABLE
#define EXTERN_GUID(itf,l1,s1,s2,c1,c2,c3,c4,c5,c6,c7,c8) \
- EXTERN_C const IID DECLSPEC_SELECTANY itf = {l1,s1,s2,{c1,c2,c3,c4,c5,c6,c7,c8}}
+ constexpr IID itf = {l1,s1,s2,{c1,c2,c3,c4,c5,c6,c7,c8}}
interface IRpcStubBuffer;
interface IRpcChannelBuffer;
diff --git a/src/coreclr/src/pal/prebuilt/corerror/mscorurt.rc b/src/coreclr/src/pal/prebuilt/corerror/mscorurt.rc
index f51e77ae1245c0..783d1adafb10a7 100644
--- a/src/coreclr/src/pal/prebuilt/corerror/mscorurt.rc
+++ b/src/coreclr/src/pal/prebuilt/corerror/mscorurt.rc
@@ -314,14 +314,13 @@ BEGIN
MSG_FOR_URT_HR(CORDBG_E_UNSUPPORTED_DELEGATE) "The delegate contains a delegate currently not supported by the API."
MSG_FOR_URT_HR(PEFMT_E_64BIT) "File is PE32+."
MSG_FOR_URT_HR(PEFMT_E_32BIT) "File is PE32"
- MSG_FOR_URT_HR(NGEN_E_SYS_ASM_NI_MISSING) "NGen cannot proceed because Mscorlib.dll does not have a native image"
MSG_FOR_URT_HR(CLR_E_BIND_ASSEMBLY_VERSION_TOO_LOW) "The bound assembly has a version that is lower than that of the request."
MSG_FOR_URT_HR(CLR_E_BIND_ASSEMBLY_PUBLIC_KEY_MISMATCH) "The assembly version has a public key token that does not match that of the request."
MSG_FOR_URT_HR(CLR_E_BIND_IMAGE_UNAVAILABLE) "The requested image was not found or is unavailable."
MSG_FOR_URT_HR(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT) "The provided identity format is not recognized."
MSG_FOR_URT_HR(CLR_E_BIND_ASSEMBLY_NOT_FOUND) "A binding for the specified assembly name was not found."
MSG_FOR_URT_HR(CLR_E_BIND_TYPE_NOT_FOUND) "A binding for the specified type name was not found."
- MSG_FOR_URT_HR(CLR_E_BIND_SYS_ASM_NI_MISSING) "Could not use native image because Mscorlib.dll is missing a native image"
+ MSG_FOR_URT_HR(CLR_E_BIND_SYS_ASM_NI_MISSING) "Could not use native image because System.Private.CoreLib.dll is missing a native image"
MSG_FOR_URT_HR(CLR_E_BIND_NI_SECURITY_FAILURE) "Native image was generated in a different trust level than present at runtime"
MSG_FOR_URT_HR(CLR_E_BIND_NI_DEP_IDENTITY_MISMATCH) "Native image identity mismatch with respect to its dependencies"
MSG_FOR_URT_HR(CLR_E_GC_OOM) "Failfast due to an OOM during a GC"
diff --git a/src/coreclr/src/pal/prebuilt/idl/cordebug_i.cpp b/src/coreclr/src/pal/prebuilt/idl/cordebug_i.cpp
index 85d7ab575a51ff..5208843c10eb42 100644
--- a/src/coreclr/src/pal/prebuilt/idl/cordebug_i.cpp
+++ b/src/coreclr/src/pal/prebuilt/idl/cordebug_i.cpp
@@ -8,7 +8,7 @@
/* File created by MIDL compiler version 8.01.0622 */
/* at Mon Jan 18 19:14:07 2038
*/
-/* Compiler settings for E:/repos/runtime2/src/coreclr/src/inc/cordebug.idl:
+/* Compiler settings for runtime/src/coreclr/src/inc/cordebug.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
@@ -289,6 +289,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorDebugNativeFrame2,0x35389FF1,0x3684,0x4c55,0xA2,0x
MIDL_DEFINE_GUID(IID, IID_ICorDebugModule3,0x86F012BF,0xFF15,0x4372,0xBD,0x30,0xB6,0xF1,0x1C,0xAA,0xE1,0xDD);
+MIDL_DEFINE_GUID(IID, IID_ICorDebugModule4,0xFF8B8EAF,0x25CD,0x4316,0x88,0x59,0x84,0x41,0x6D,0xE4,0x40,0x2E);
+
+
MIDL_DEFINE_GUID(IID, IID_ICorDebugRuntimeUnwindableFrame,0x879CAC0A,0x4A53,0x4668,0xB8,0xE3,0xCB,0x84,0x73,0xCB,0x18,0x7F);
diff --git a/src/coreclr/src/pal/prebuilt/idl/sospriv_i.cpp b/src/coreclr/src/pal/prebuilt/idl/sospriv_i.cpp
index 993737f7a0b358..ee2cd1d82010b3 100644
--- a/src/coreclr/src/pal/prebuilt/idl/sospriv_i.cpp
+++ b/src/coreclr/src/pal/prebuilt/idl/sospriv_i.cpp
@@ -1,6 +1,3 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
@@ -8,7 +5,17 @@
/* link this file in with the server and any clients */
- /* File created by MIDL compiler version 8.00.0613 */
+ /* File created by MIDL compiler version 8.01.0622 */
+/* at Mon Jan 18 19:14:07 2038
+ */
+/* Compiler settings for C:/ssd/runtime/src/coreclr/src/inc/sospriv.idl:
+ Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
+ protocol : dce , ms_ext, c_ext, robust
+ error checks: allocation ref bounds_check enum stub_data
+ VC __declspec() decoration level:
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)
+ DECLSPEC_UUID(), MIDL_INTERFACE()
+*/
/* @@MIDL_FILE_HEADING( ) */
#pragma warning( disable: 4049 ) /* more than 64k source lines */
@@ -95,6 +102,9 @@ MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface7,0xc1020dde,0xfe98,0x4536,0xa5,0x3b,0
MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface8,0xc12f35a9,0xe55c,0x4520,0xa8,0x94,0xb3,0xdc,0x51,0x65,0xdf,0xce);
+
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface9,0x4eca42d8,0x7e7b,0x4c8a,0xa1,0x16,0x7b,0xfb,0xf6,0x92,0x92,0x67);
+
#undef MIDL_DEFINE_GUID
#ifdef __cplusplus
diff --git a/src/coreclr/src/pal/prebuilt/inc/cordebug.h b/src/coreclr/src/pal/prebuilt/inc/cordebug.h
index 3418b8cf9b30c9..b497d141c48086 100644
--- a/src/coreclr/src/pal/prebuilt/inc/cordebug.h
+++ b/src/coreclr/src/pal/prebuilt/inc/cordebug.h
@@ -6,7 +6,7 @@
/* File created by MIDL compiler version 8.01.0622 */
/* at Mon Jan 18 19:14:07 2038
*/
-/* Compiler settings for E:/repos/runtime2/src/coreclr/src/inc/cordebug.idl:
+/* Compiler settings for runtime/src/coreclr/src/inc/cordebug.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
@@ -563,6 +563,13 @@ typedef interface ICorDebugModule3 ICorDebugModule3;
#endif /* __ICorDebugModule3_FWD_DEFINED__ */
+#ifndef __ICorDebugModule4_FWD_DEFINED__
+#define __ICorDebugModule4_FWD_DEFINED__
+typedef interface ICorDebugModule4 ICorDebugModule4;
+
+#endif /* __ICorDebugModule4_FWD_DEFINED__ */
+
+
#ifndef __ICorDebugRuntimeUnwindableFrame_FWD_DEFINED__
#define __ICorDebugRuntimeUnwindableFrame_FWD_DEFINED__
typedef interface ICorDebugRuntimeUnwindableFrame ICorDebugRuntimeUnwindableFrame;
@@ -11691,6 +11698,86 @@ EXTERN_C const IID IID_ICorDebugModule3;
#endif /* __ICorDebugModule3_INTERFACE_DEFINED__ */
+#ifndef __ICorDebugModule4_INTERFACE_DEFINED__
+#define __ICorDebugModule4_INTERFACE_DEFINED__
+
+/* interface ICorDebugModule4 */
+/* [unique][uuid][local][object] */
+
+
+EXTERN_C const IID IID_ICorDebugModule4;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("FF8B8EAF-25CD-4316-8859-84416DE4402E")
+ ICorDebugModule4 : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE IsMappedLayout(
+ /* [out] */ BOOL *pIsMapped) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICorDebugModule4Vtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICorDebugModule4 * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICorDebugModule4 * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICorDebugModule4 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *IsMappedLayout )(
+ ICorDebugModule4 * This,
+ /* [out] */ BOOL *pIsMapped);
+
+ END_INTERFACE
+ } ICorDebugModule4Vtbl;
+
+ interface ICorDebugModule4
+ {
+ CONST_VTBL struct ICorDebugModule4Vtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugModule4_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICorDebugModule4_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICorDebugModule4_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICorDebugModule4_IsMappedLayout(This,pIsMapped) \
+ ( (This)->lpVtbl -> IsMappedLayout(This,pIsMapped) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICorDebugModule4_INTERFACE_DEFINED__ */
+
+
#ifndef __ICorDebugRuntimeUnwindableFrame_INTERFACE_DEFINED__
#define __ICorDebugRuntimeUnwindableFrame_INTERFACE_DEFINED__
@@ -12075,14 +12162,14 @@ EXTERN_C const IID IID_ICorDebugModule;
#endif /* __ICorDebugModule_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0075 */
+/* interface __MIDL_itf_cordebug_0000_0076 */
/* [local] */
#pragma warning(pop)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0075_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0075_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0076_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0076_v0_0_s_ifspec;
#ifndef __ICorDebugModule2_INTERFACE_DEFINED__
#define __ICorDebugModule2_INTERFACE_DEFINED__
@@ -15129,15 +15216,15 @@ EXTERN_C const IID IID_ICorDebugBoxValue;
#endif /* __ICorDebugBoxValue_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0102 */
+/* interface __MIDL_itf_cordebug_0000_0103 */
/* [local] */
#pragma warning(push)
#pragma warning(disable:28718)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0102_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0102_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0103_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0103_v0_0_s_ifspec;
#ifndef __ICorDebugStringValue_INTERFACE_DEFINED__
#define __ICorDebugStringValue_INTERFACE_DEFINED__
@@ -15277,14 +15364,14 @@ EXTERN_C const IID IID_ICorDebugStringValue;
#endif /* __ICorDebugStringValue_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0103 */
+/* interface __MIDL_itf_cordebug_0000_0104 */
/* [local] */
#pragma warning(pop)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0103_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0103_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0104_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0104_v0_0_s_ifspec;
#ifndef __ICorDebugArrayValue_INTERFACE_DEFINED__
#define __ICorDebugArrayValue_INTERFACE_DEFINED__
@@ -18059,15 +18146,15 @@ EXTERN_C const IID IID_ICorDebugBlockingObjectEnum;
#endif /* __ICorDebugBlockingObjectEnum_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0127 */
+/* interface __MIDL_itf_cordebug_0000_0128 */
/* [local] */
#pragma warning(push)
#pragma warning(disable:28718)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0127_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0127_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0128_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0128_v0_0_s_ifspec;
#ifndef __ICorDebugMDA_INTERFACE_DEFINED__
#define __ICorDebugMDA_INTERFACE_DEFINED__
@@ -18207,7 +18294,7 @@ EXTERN_C const IID IID_ICorDebugMDA;
#endif /* __ICorDebugMDA_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0128 */
+/* interface __MIDL_itf_cordebug_0000_0129 */
/* [local] */
#pragma warning(pop)
@@ -18215,8 +18302,8 @@ EXTERN_C const IID IID_ICorDebugMDA;
#pragma warning(disable:28718)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0128_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0128_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0129_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0129_v0_0_s_ifspec;
#ifndef __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__
#define __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__
@@ -18332,14 +18419,14 @@ EXTERN_C const IID IID_ICorDebugEditAndContinueErrorInfo;
#endif /* __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0129 */
+/* interface __MIDL_itf_cordebug_0000_0130 */
/* [local] */
#pragma warning(pop)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0129_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0129_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0130_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0130_v0_0_s_ifspec;
#ifndef __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__
#define __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__
diff --git a/src/coreclr/src/pal/prebuilt/inc/corerror.h b/src/coreclr/src/pal/prebuilt/inc/corerror.h
index 31ba2d9c455458..0fe7c75d2d249d 100644
--- a/src/coreclr/src/pal/prebuilt/inc/corerror.h
+++ b/src/coreclr/src/pal/prebuilt/inc/corerror.h
@@ -385,7 +385,6 @@
#define CORDBG_E_UNSUPPORTED_DELEGATE EMAKEHR(0x1c68)
#define PEFMT_E_64BIT EMAKEHR(0x1d02)
#define PEFMT_E_32BIT EMAKEHR(0x1d0b)
-#define NGEN_E_SYS_ASM_NI_MISSING EMAKEHR(0x1f06)
#define CLDB_E_INTERNALERROR EMAKEHR(0x1fff)
#define CLR_E_BIND_ASSEMBLY_VERSION_TOO_LOW EMAKEHR(0x2000)
#define CLR_E_BIND_ASSEMBLY_PUBLIC_KEY_MISMATCH EMAKEHR(0x2001)
diff --git a/src/coreclr/src/pal/prebuilt/inc/sospriv.h b/src/coreclr/src/pal/prebuilt/inc/sospriv.h
index d76eac0ead666f..6fe59addcfe218 100644
--- a/src/coreclr/src/pal/prebuilt/inc/sospriv.h
+++ b/src/coreclr/src/pal/prebuilt/inc/sospriv.h
@@ -2644,7 +2644,7 @@ EXTERN_C const IID IID_ISOSDacInterface8;
#define ISOSDacInterface8_GetFinalizationFillPointersSvr(This,heapAddr,cFillPointers,pFinalizationFillPointers,pNeeded) \
( (This)->lpVtbl -> GetFinalizationFillPointersSvr(This,heapAddr,cFillPointers,pFinalizationFillPointers,pNeeded) )
-#define ISOSDacInterface8_GetAssemblyLoadContext(This,methodTable,assemblyLoadContext) \
+#define ISOSDacInterface8_GetAssemblyLoadContext(This,methodTable,assemblyLoadContext) \
( (This)->lpVtbl -> GetAssemblyLoadContext(This,methodTable,assemblyLoadContext) )
#endif /* COBJMACROS */
@@ -2658,6 +2658,93 @@ EXTERN_C const IID IID_ISOSDacInterface8;
#endif /* __ISOSDacInterface8_INTERFACE_DEFINED__ */
+/* interface __MIDL_itf_sospriv_0000_0012 */
+/* [local] */
+
+#define SOS_BREAKING_CHANGE_VERSION 1
+
+
+extern RPC_IF_HANDLE __MIDL_itf_sospriv_0000_0012_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_sospriv_0000_0012_v0_0_s_ifspec;
+
+#ifndef __ISOSDacInterface9_INTERFACE_DEFINED__
+#define __ISOSDacInterface9_INTERFACE_DEFINED__
+
+/* interface ISOSDacInterface9 */
+/* [uuid][local][object] */
+
+
+EXTERN_C const IID IID_ISOSDacInterface9;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("4eca42d8-7e7b-4c8a-a116-7bfbf6929267")
+ ISOSDacInterface9 : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE GetBreakingChangeVersion(
+ int *pVersion) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ISOSDacInterface9Vtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ISOSDacInterface9 * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ISOSDacInterface9 * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ISOSDacInterface9 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetBreakingChangeVersion )(
+ ISOSDacInterface9 * This,
+ int *pVersion);
+
+ END_INTERFACE
+ } ISOSDacInterface9Vtbl;
+
+ interface ISOSDacInterface9
+ {
+ CONST_VTBL struct ISOSDacInterface9Vtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ISOSDacInterface9_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ISOSDacInterface9_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ISOSDacInterface9_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ISOSDacInterface9_GetBreakingChangeVersion(This,pVersion) \
+ ( (This)->lpVtbl -> GetBreakingChangeVersion(This,pVersion) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+#endif /* __ISOSDacInterface9_INTERFACE_DEFINED__ */
+
+
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
@@ -2668,4 +2755,3 @@ EXTERN_C const IID IID_ISOSDacInterface8;
#endif
-
diff --git a/src/coreclr/src/pal/src/CMakeLists.txt b/src/coreclr/src/pal/src/CMakeLists.txt
index 094f14cabf821a..712dabf46a3e68 100644
--- a/src/coreclr/src/pal/src/CMakeLists.txt
+++ b/src/coreclr/src/pal/src/CMakeLists.txt
@@ -267,10 +267,12 @@ endif(CLR_CMAKE_TARGET_OSX)
# > warning for library: libtracepointprovider.a the table of contents is empty (no object file members in the library define global symbols)
#
if(CLR_CMAKE_TARGET_LINUX)
- add_library(tracepointprovider
+ add_library(tracepointprovider_obj
OBJECT
misc/tracepointprovider.cpp
)
+ add_library(tracepointprovider INTERFACE)
+ target_sources(tracepointprovider INTERFACE $)
endif(CLR_CMAKE_TARGET_LINUX)
if(CLR_CMAKE_TARGET_OSX)
diff --git a/src/coreclr/src/pal/src/config.h.in b/src/coreclr/src/pal/src/config.h.in
index 8e7e69288bc9e3..39a05ee0ff2232 100644
--- a/src/coreclr/src/pal/src/config.h.in
+++ b/src/coreclr/src/pal/src/config.h.in
@@ -36,7 +36,6 @@
#cmakedefine01 HAVE_PTHREAD_GETCPUCLOCKID
#cmakedefine01 HAVE_PTHREAD_SIGQUEUE
#cmakedefine01 HAVE_PTHREAD_GETAFFINITY_NP
-#cmakedefine01 HAVE_PTHREAD_ATTR_SETAFFINITY_NP
#cmakedefine01 HAVE_CPUSET_T
#cmakedefine01 HAVE_SIGRETURN
#cmakedefine01 HAVE__THREAD_SYS_SIGRETURN
@@ -66,6 +65,7 @@
#cmakedefine01 HAVE_TTRACE
#cmakedefine01 HAVE_PIPE2
#cmakedefine01 HAVE_SCHED_GETAFFINITY
+#cmakedefine01 HAVE_SCHED_SETAFFINITY
#cmakedefine HAVE_UNW_GET_SAVE_LOC
#cmakedefine HAVE_UNW_GET_ACCESSORS
#cmakedefine01 HAVE_XSWDEV
diff --git a/src/coreclr/src/pal/src/configure.cmake b/src/coreclr/src/pal/src/configure.cmake
index b67637b584ba69..5fb606a2983dca 100644
--- a/src/coreclr/src/pal/src/configure.cmake
+++ b/src/coreclr/src/pal/src/configure.cmake
@@ -81,6 +81,7 @@ check_include_files(gnu/lib-names.h HAVE_GNU_LIBNAMES_H)
check_function_exists(kqueue HAVE_KQUEUE)
check_library_exists(c sched_getaffinity "" HAVE_SCHED_GETAFFINITY)
+check_library_exists(c sched_setaffinity "" HAVE_SCHED_SETAFFINITY)
check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD)
check_library_exists(c pthread_create "" HAVE_PTHREAD_IN_LIBC)
@@ -100,7 +101,6 @@ check_library_exists(${PTHREAD_LIBRARY} pthread_getattr_np "" HAVE_PTHREAD_GETAT
check_library_exists(${PTHREAD_LIBRARY} pthread_getcpuclockid "" HAVE_PTHREAD_GETCPUCLOCKID)
check_library_exists(${PTHREAD_LIBRARY} pthread_sigqueue "" HAVE_PTHREAD_SIGQUEUE)
check_library_exists(${PTHREAD_LIBRARY} pthread_getaffinity_np "" HAVE_PTHREAD_GETAFFINITY_NP)
-check_library_exists(${PTHREAD_LIBRARY} pthread_attr_setaffinity_np "" HAVE_PTHREAD_ATTR_SETAFFINITY_NP)
check_function_exists(sigreturn HAVE_SIGRETURN)
check_function_exists(_thread_sys_sigreturn HAVE__THREAD_SYS_SIGRETURN)
diff --git a/src/coreclr/src/pal/src/debug/debug.cpp b/src/coreclr/src/pal/src/debug/debug.cpp
index b58b2fe587e19d..7e7e368200587b 100644
--- a/src/coreclr/src/pal/src/debug/debug.cpp
+++ b/src/coreclr/src/pal/src/debug/debug.cpp
@@ -62,6 +62,11 @@ SET_DEFAULT_DEBUG_CHANNEL(DEBUG); // some headers have code with asserts, so do
#include
#endif // HAVE_PROCFS_H
+#ifdef __APPLE__
+#include
+#include
+#endif // __APPLE__
+
#if HAVE_MACH_EXCEPTIONS
#include "../exception/machexception.h"
#endif // HAVE_MACH_EXCEPTIONS
@@ -69,6 +74,7 @@ SET_DEFAULT_DEBUG_CHANNEL(DEBUG); // some headers have code with asserts, so do
using namespace CorUnix;
extern "C" void DBG_DebugBreak_End();
+extern size_t OffsetWithinPage(off_t addr);
#if HAVE_PROCFS_CTL
#define CTL_ATTACH "attach"
@@ -541,6 +547,184 @@ SetThreadContext(
return ret;
}
+/*++
+Function:
+ PAL_OpenProcessMemory
+
+Abstract
+ Creates the handle for PAL_ReadProcessMemory.
+
+Parameter
+ processId : process id to read memory
+ pHandle : returns a platform specific handle or UINT32_MAX if failed
+
+Return
+ true successful, false invalid process id or not supported.
+--*/
+BOOL
+PALAPI
+PAL_OpenProcessMemory(
+ IN DWORD processId,
+ OUT DWORD* pHandle
+)
+{
+ ENTRY("PAL_OpenProcessMemory(pid=%d)\n", processId);
+ _ASSERTE(pHandle != nullptr);
+ *pHandle = UINT32_MAX;
+#ifdef __APPLE__
+ mach_port_name_t port;
+ kern_return_t result = ::task_for_pid(mach_task_self(), (int)processId, &port);
+ if (result != KERN_SUCCESS)
+ {
+ ERROR("task_for_pid(%d) FAILED %x %s\n", processId, result, mach_error_string(result));
+ LOGEXIT("PAL_OpenProcessMemory FALSE\n");
+ return FALSE;
+ }
+ *pHandle = port;
+#else
+ char memPath[128];
+ _snprintf_s(memPath, sizeof(memPath), sizeof(memPath), "/proc/%lu/mem", processId);
+
+ int fd = open(memPath, O_RDONLY);
+ if (fd == -1)
+ {
+ ERROR("open(%s) FAILED %d (%s)\n", memPath, errno, strerror(errno));
+ LOGEXIT("PAL_OpenProcessMemory FALSE\n");
+ return FALSE;
+ }
+ *pHandle = fd;
+#endif
+ LOGEXIT("PAL_OpenProcessMemory TRUE\n");
+ return TRUE;
+}
+
+/*++
+Function:
+ PAL_CloseProcessMemory
+
+Abstract
+ Closes the PAL_OpenProcessMemory handle.
+
+Parameter
+ handle : from PAL_OpenProcessMemory
+
+Return
+ none
+--*/
+VOID
+PALAPI
+PAL_CloseProcessMemory(
+ IN DWORD handle
+)
+{
+ ENTRY("PAL_CloseProcessMemory(handle=%x)\n", handle);
+ if (handle != UINT32_MAX)
+ {
+#ifdef __APPLE__
+ kern_return_t result = ::mach_port_deallocate(mach_task_self(), (mach_port_name_t)handle);
+ if (result != KERN_SUCCESS)
+ {
+ ERROR("mach_port_deallocate FAILED %x %s\n", result, mach_error_string(result));
+ }
+#else
+ close(handle);
+#endif
+ }
+ LOGEXIT("PAL_CloseProcessMemory\n");
+}
+
+/*++
+Function:
+ PAL_ReadProcessMemory
+
+Abstract
+ Reads process memory.
+
+Parameter
+ handle : from PAL_OpenProcessMemory
+ address : address of memory to read
+ buffer : buffer to read memory to
+ size : number of bytes to read
+ numberOfBytesRead: number of bytes read (optional)
+
+Return
+ true read memory is successful, false if not.
+--*/
+BOOL
+PALAPI
+PAL_ReadProcessMemory(
+ IN DWORD handle,
+ IN ULONG64 address,
+ IN LPVOID buffer,
+ IN SIZE_T size,
+ OUT SIZE_T* numberOfBytesRead)
+{
+ ENTRY("PAL_ReadProcessMemory(handle=%x, address=%p buffer=%p size=%d)\n", handle, (void*)address, buffer, size);
+ _ASSERTE(handle != 0);
+ _ASSERTE(numberOfBytesRead != nullptr);
+ BOOL result = TRUE;
+ size_t read = 0;
+#ifdef __APPLE__
+ vm_map_t task = (vm_map_t)handle;
+
+ // vm_read_overwrite usually requires that the address be page-aligned
+ // and the size be a multiple of the page size. We can't differentiate
+ // between the cases in which that's required and those in which it
+ // isn't, so we do it all the time.
+ const size_t pageSize = GetVirtualPageSize();
+ vm_address_t addressAligned = ALIGN_DOWN(address, pageSize);
+ size_t offset = OffsetWithinPage(address);
+ size_t bytesToRead;
+
+ char *data = (char*)malloc(pageSize);
+ if (data == nullptr)
+ {
+ ERROR("malloc(%d) FAILED\n", pageSize);
+ result = FALSE;
+ goto exit;
+ }
+
+ while (size > 0)
+ {
+ vm_size_t bytesRead;
+
+ bytesToRead = pageSize - offset;
+ if (bytesToRead > size)
+ {
+ bytesToRead = size;
+ }
+ bytesRead = pageSize;
+ kern_return_t result = ::vm_read_overwrite(task, addressAligned, pageSize, (vm_address_t)data, &bytesRead);
+ if (result != KERN_SUCCESS || bytesRead != pageSize)
+ {
+ ERROR("vm_read_overwrite failed for %d bytes from %p: %x %s\n", pageSize, (void*)addressAligned, result, mach_error_string(result));
+ result = FALSE;
+ goto exit;
+ }
+ memcpy((LPSTR)buffer + read , data + offset, bytesToRead);
+ addressAligned = addressAligned + pageSize;
+ read += bytesToRead;
+ size -= bytesToRead;
+ offset = 0;
+ }
+
+exit:
+ if (data != nullptr)
+ {
+ free(data);
+ }
+#else
+ read = pread(handle, buffer, size, address);
+ if (read == (size_t)-1)
+ {
+ result = FALSE;
+ }
+#endif
+ *numberOfBytesRead = read;
+ LOGEXIT("PAL_ReadProcessMemory result=%d bytes read=%d\n", result, read);
+ return result;
+}
+
/*++
Function:
PAL_ProbeMemory
diff --git a/src/coreclr/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt b/src/coreclr/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt
index 39b9826d1ab5a0..8e6968cf783d4d 100644
--- a/src/coreclr/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt
+++ b/src/coreclr/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt
@@ -1,8 +1,8 @@
-include(FindPython)
+include(FindPythonInterp)
set (GENERATE_SCRIPT ${CLR_DIR}/src/scripts/genDummyProvider.py)
-set(GENERATE_COMMAND ${Python_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --intermediate ${CMAKE_CURRENT_BINARY_DIR})
+set(GENERATE_COMMAND ${PYTHON_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --intermediate ${CMAKE_CURRENT_BINARY_DIR})
execute_process(
COMMAND ${GENERATE_COMMAND} --dry-run
diff --git a/src/coreclr/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt b/src/coreclr/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt
index 234dea19b753db..d55dab3557f35b 100644
--- a/src/coreclr/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt
+++ b/src/coreclr/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt
@@ -1,7 +1,7 @@
-include(FindPython)
+include(FindPythonInterp)
set (GENERATE_SCRIPT ${CLR_DIR}/src/scripts/genLttngProvider.py)
-set(GENERATE_COMMAND ${Python_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --intermediate ${CMAKE_CURRENT_BINARY_DIR})
+set(GENERATE_COMMAND ${PYTHON_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --intermediate ${CMAKE_CURRENT_BINARY_DIR})
execute_process(
COMMAND ${GENERATE_COMMAND} --dry-run
diff --git a/src/coreclr/src/pal/src/locale/utf8.cpp b/src/coreclr/src/pal/src/locale/utf8.cpp
index b8a6f7ad5d6fdb..63bfc8661715d5 100644
--- a/src/coreclr/src/pal/src/locale/utf8.cpp
+++ b/src/coreclr/src/pal/src/locale/utf8.cpp
@@ -10,7 +10,7 @@ Module Name:
unicode/utf8.c
Abstract:
- Functions to encode and decode UTF-8 strings. This is a port of the C# version from mscorlib.
+ Functions to encode and decode UTF-8 strings. This is a port of the C# version from Utf8Encoding.cs.
Revision History:
diff --git a/src/coreclr/src/pal/src/map/map.cpp b/src/coreclr/src/pal/src/map/map.cpp
index 75405c7407c8bf..0cbaef5521d0fe 100644
--- a/src/coreclr/src/pal/src/map/map.cpp
+++ b/src/coreclr/src/pal/src/map/map.cpp
@@ -2137,7 +2137,7 @@ MAPRecordMapping(
return palError;
}
-static size_t OffsetWithinPage(off_t addr)
+size_t OffsetWithinPage(off_t addr)
{
return addr & (GetVirtualPageSize() - 1);
}
diff --git a/src/coreclr/src/pal/src/thread/thread.cpp b/src/coreclr/src/pal/src/thread/thread.cpp
index 6efe93492bc3aa..89d805c3540410 100644
--- a/src/coreclr/src/pal/src/thread/thread.cpp
+++ b/src/coreclr/src/pal/src/thread/thread.cpp
@@ -740,41 +740,6 @@ CorUnix::InternalCreateThread(
storedErrno = errno;
#endif // PTHREAD_CREATE_MODIFIES_ERRNO
-#if HAVE_PTHREAD_ATTR_SETAFFINITY_NP && HAVE_SCHED_GETAFFINITY
- {
- // Threads inherit their parent's affinity mask on Linux. This is not desired, so we reset
- // the current thread's affinity mask to the mask of the current process.
- cpu_set_t cpuSet;
- CPU_ZERO(&cpuSet);
-
- int st = sched_getaffinity(gPID, sizeof(cpu_set_t), &cpuSet);
- if (st != 0)
- {
- ASSERT("sched_getaffinity failed!\n");
- // the sched_getaffinity should never fail for getting affinity of the current process
- palError = ERROR_INTERNAL_ERROR;
- goto EXIT;
- }
-
- st = pthread_attr_setaffinity_np(&pthreadAttr, sizeof(cpu_set_t), &cpuSet);
- if (st != 0)
- {
- if (st == ENOMEM)
- {
- palError = ERROR_NOT_ENOUGH_MEMORY;
- }
- else
- {
- ASSERT("pthread_attr_setaffinity_np failed!\n");
- // The pthread_attr_setaffinity_np should never fail except of OOM when
- // passed the mask extracted using sched_getaffinity.
- palError = ERROR_INTERNAL_ERROR;
- }
- goto EXIT;
- }
- }
-#endif // HAVE_PTHREAD_GETAFFINITY_NP && HAVE_SCHED_GETAFFINITY
-
iError = pthread_create(&pthread, &pthreadAttr, CPalThread::ThreadEntry, pNewThread);
#if PTHREAD_CREATE_MODIFIES_ERRNO
@@ -1754,6 +1719,10 @@ CPalThread::ThreadEntry(
PTHREAD_START_ROUTINE pfnStartRoutine;
LPVOID pvPar;
DWORD retValue;
+#if HAVE_SCHED_GETAFFINITY && HAVE_SCHED_SETAFFINITY
+ cpu_set_t cpuSet;
+ int st;
+#endif
pThread = reinterpret_cast(pvParam);
@@ -1763,6 +1732,42 @@ CPalThread::ThreadEntry(
goto fail;
}
+#if HAVE_SCHED_GETAFFINITY && HAVE_SCHED_SETAFFINITY
+ // Threads inherit their parent's affinity mask on Linux. This is not desired, so we reset
+ // the current thread's affinity mask to the mask of the current process.
+ //
+ // Typically, we would use pthread_attr_setaffinity_np() and have pthread_create() create the thread with the specified
+ // affinity. At least one implementation of pthread_create() following a pthread_attr_setaffinity_np() calls
+ // sched_setaffinity(, ...), which is not allowed under Snap's default strict confinement without manually
+ // connecting the process-control plug. To work around that, have the thread set the affinity after it starts.
+ // sched_setaffinity(, ...) is also currently not allowed, only sched_setaffinity(0, ...).
+ // pthread_setaffinity_np(pthread_self(), ...) seems to call sched_setaffinity(, ...) in at least one
+ // implementation, and does not work. Use sched_setaffinity(0, ...) instead. See the following for more information:
+ // - https://github.com/dotnet/runtime/pull/38795
+ // - https://github.com/dotnet/runtime/issues/1634
+ // - https://forum.snapcraft.io/t/requesting-autoconnect-for-interfaces-in-pigmeat-process-control-home/17987/13
+
+ CPU_ZERO(&cpuSet);
+
+ st = sched_getaffinity(gPID, sizeof(cpu_set_t), &cpuSet);
+ if (st != 0)
+ {
+ ASSERT("sched_getaffinity failed!\n");
+ // The sched_getaffinity should never fail for getting affinity of the current process
+ palError = ERROR_INTERNAL_ERROR;
+ goto fail;
+ }
+
+ st = sched_setaffinity(0, sizeof(cpu_set_t), &cpuSet);
+ if (st != 0)
+ {
+ ASSERT("sched_setaffinity failed!\n");
+ // The sched_setaffinity should never fail when passed the mask extracted using sched_getaffinity
+ palError = ERROR_INTERNAL_ERROR;
+ goto fail;
+ }
+#endif // HAVE_SCHED_GETAFFINITY && HAVE_SCHED_SETAFFINITY
+
#if !HAVE_MACH_EXCEPTIONS
if (!pThread->EnsureSignalAlternateStack())
{
@@ -2946,18 +2951,31 @@ BOOL
PALAPI
PAL_SetCurrentThreadAffinity(WORD procNo)
{
-#if HAVE_PTHREAD_GETAFFINITY_NP
+#if HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP
cpu_set_t cpuSet;
CPU_ZERO(&cpuSet);
-
CPU_SET(procNo, &cpuSet);
+
+ // Snap's default strict confinement does not allow sched_setaffinity(, ...) without manually connecting the
+ // process-control plug. sched_setaffinity(, ...) is also currently not allowed, only
+ // sched_setaffinity(0, ...). pthread_setaffinity_np(pthread_self(), ...) seems to call
+ // sched_setaffinity(, ...) in at least one implementation, and does not work. To work around those
+ // issues, use sched_setaffinity(0, ...) if available and only otherwise fall back to pthread_setaffinity_np(). See the
+ // following for more information:
+ // - https://github.com/dotnet/runtime/pull/38795
+ // - https://github.com/dotnet/runtime/issues/1634
+ // - https://forum.snapcraft.io/t/requesting-autoconnect-for-interfaces-in-pigmeat-process-control-home/17987/13
+#if HAVE_SCHED_SETAFFINITY
+ int st = sched_setaffinity(0, sizeof(cpu_set_t), &cpuSet);
+#else
int st = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuSet);
+#endif
return st == 0;
-#else // HAVE_PTHREAD_GETAFFINITY_NP
+#else // !(HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP)
// There is no API to manage thread affinity, so let's ignore the request
return FALSE;
-#endif // HAVE_PTHREAD_GETAFFINITY_NP
+#endif // HAVE_SCHED_SETAFFINITY || HAVE_PTHREAD_SETAFFINITY_NP
}
/*++
diff --git a/src/coreclr/src/pal/tests/palsuite/common/ResultBuffer.cpp b/src/coreclr/src/pal/tests/palsuite/common/ResultBuffer.cpp
index 4119399b36181e..36924c3c30a2a0 100644
--- a/src/coreclr/src/pal/tests/palsuite/common/ResultBuffer.cpp
+++ b/src/coreclr/src/pal/tests/palsuite/common/ResultBuffer.cpp
@@ -3,11 +3,6 @@
//#include "stdafx.h"
#include "resultbuffer.h"
-//
-//#using
-//
-//using namespace System;
-
ResultBuffer:: ResultBuffer(int ThreadCount, int ThreadLogSize)
{
diff --git a/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/resultbuffer.cpp b/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/resultbuffer.cpp
index e99e31ff31d36a..32e8f92b3e083d 100644
--- a/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/resultbuffer.cpp
+++ b/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/resultbuffer.cpp
@@ -3,11 +3,6 @@
//#include "stdafx.h"
#include "resultbuffer.h"
-//
-//#using
-//
-//using namespace System;
-
ResultBuffer:: ResultBuffer(int ThreadCount, int ThreadLogSize)
{
diff --git a/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/resultbuffer.cpp b/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/resultbuffer.cpp
index e99e31ff31d36a..32e8f92b3e083d 100644
--- a/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/resultbuffer.cpp
+++ b/src/coreclr/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/resultbuffer.cpp
@@ -3,11 +3,6 @@
//#include "stdafx.h"
#include "resultbuffer.h"
-//
-//#using
-//
-//using namespace System;
-
ResultBuffer:: ResultBuffer(int ThreadCount, int ThreadLogSize)
{
diff --git a/src/coreclr/src/pal/tests/palsuite/eventprovider/CMakeLists.txt b/src/coreclr/src/pal/tests/palsuite/eventprovider/CMakeLists.txt
index 000ee2d2fb0d12..845fae656be41a 100644
--- a/src/coreclr/src/pal/tests/palsuite/eventprovider/CMakeLists.txt
+++ b/src/coreclr/src/pal/tests/palsuite/eventprovider/CMakeLists.txt
@@ -5,10 +5,10 @@ set(SOURCES
set(EVENT_MANIFEST ${VM_DIR}/ClrEtwAll.man)
set(TEST_GENERATOR ${CLR_DIR}/src/scripts/genEventingTests.py)
-include(FindPython)
+include(FindPythonInterp)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clralltestevents.cpp
- COMMAND ${Python_EXECUTABLE} ${TEST_GENERATOR} --testdir "${CMAKE_CURRENT_BINARY_DIR}" --man "${EVENT_MANIFEST}"
+ COMMAND ${PYTHON_EXECUTABLE} ${TEST_GENERATOR} --testdir "${CMAKE_CURRENT_BINARY_DIR}" --man "${EVENT_MANIFEST}"
DEPENDS ${EVENT_MANIFEST} ${TEST_GENERATOR}
COMMENT "Updating clralltestevents.cpp"
)
diff --git a/src/coreclr/src/scripts/genEtwProvider.py b/src/coreclr/src/scripts/genEtwProvider.py
index 1a146b5fda36ff..e7df63bb5b38ff 100644
--- a/src/coreclr/src/scripts/genEtwProvider.py
+++ b/src/coreclr/src/scripts/genEtwProvider.py
@@ -164,7 +164,7 @@ def genEtwMacroHeader(manifest, exclusion_filename, intermediate):
header_file.write("#define NO_OF_ETW_PROVIDERS " + str(numOfProviders) + "\n")
header_file.write("#define MAX_BYTES_PER_ETW_PROVIDER " + str(nMaxEventBytesPerProvider) + "\n")
- header_file.write("EXTERN_C SELECTANY const BYTE etwStackSupportedEvents[NO_OF_ETW_PROVIDERS][MAX_BYTES_PER_ETW_PROVIDER] = \n{\n")
+ header_file.write("EXTERN_C constexpr BYTE etwStackSupportedEvents[NO_OF_ETW_PROVIDERS][MAX_BYTES_PER_ETW_PROVIDER] = \n{\n")
for providerNode in tree.getElementsByTagName('provider'):
stackSupportedEvents = [0]*nMaxEventBytesPerProvider
diff --git a/src/coreclr/src/scripts/genEventing.py b/src/coreclr/src/scripts/genEventing.py
index c591be8dc0640a..a7919768c3abc1 100644
--- a/src/coreclr/src/scripts/genEventing.py
+++ b/src/coreclr/src/scripts/genEventing.py
@@ -627,7 +627,7 @@ def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern
if is_windows:
eventpipeProviderCtxName = providerSymbol + "_EVENTPIPE_Context"
- Clrallevents.write('SELECTANY EVENTPIPE_TRACE_CONTEXT const ' + eventpipeProviderCtxName + ' = { W("' + providerName + '"), 0, false, 0 };\n')
+ Clrallevents.write('constexpr EVENTPIPE_TRACE_CONTEXT ' + eventpipeProviderCtxName + ' = { W("' + providerName + '"), 0, false, 0 };\n')
if write_xplatheader:
clrproviders = os.path.join(incDir, "clrproviders.h")
@@ -676,14 +676,14 @@ def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern
symbolName = eventNode.getAttribute('symbol')
keywords = eventNode.getAttribute('keywords')
level = convertToLevelId(levelName)
- Clrproviders.write("SELECTANY EVENT_DESCRIPTOR const " + symbolName + " = { " + str(level) + ", " + hex(getKeywordsMaskCombined(keywords, keywordsToMask)) + " };\n")
+ Clrproviders.write("constexpr EVENT_DESCRIPTOR " + symbolName + " = { " + str(level) + ", " + hex(getKeywordsMaskCombined(keywords, keywordsToMask)) + " };\n")
allProviders.append("&" + providerSymbol + "_LTTNG_Context")
# define and initialize runtime providers' DOTNET_TRACE_CONTEXT depending on the platform
if not is_windows:
Clrproviders.write('#define NB_PROVIDERS ' + str(nbProviders) + '\n')
- Clrproviders.write('SELECTANY LTTNG_TRACE_CONTEXT * const ALL_LTTNG_PROVIDERS_CONTEXT[NB_PROVIDERS] = { ')
+ Clrproviders.write('constexpr LTTNG_TRACE_CONTEXT * ALL_LTTNG_PROVIDERS_CONTEXT[NB_PROVIDERS] = { ')
Clrproviders.write(', '.join(allProviders))
Clrproviders.write(' };\n')
diff --git a/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs b/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs
index 89fd08f3dbab42..dd54a1387bdf9e 100644
--- a/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs
+++ b/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs
@@ -97,6 +97,19 @@ public static bool IsArrayAddressMethod(this MethodDesc method)
return arrayMethod != null && arrayMethod.Kind == ArrayMethodKind.Address;
}
+
+ ///
+ /// Returns true if '' is one of the special methods on multidimensional array types (set, get, address).
+ ///
+ public static bool IsArrayMethod(this MethodDesc method)
+ {
+ var arrayMethod = method as ArrayMethod;
+ return arrayMethod != null && (arrayMethod.Kind == ArrayMethodKind.Address ||
+ arrayMethod.Kind == ArrayMethodKind.Get ||
+ arrayMethod.Kind == ArrayMethodKind.Set ||
+ arrayMethod.Kind == ArrayMethodKind.Ctor);
+ }
+
///
/// Gets a value indicating whether this type has any generic virtual methods.
///
diff --git a/src/coreclr/src/tools/Common/Internal/NativeFormat/NativeFormat.cs b/src/coreclr/src/tools/Common/Internal/NativeFormat/NativeFormat.cs
index e92c689d658b22..1ebbdac34811e8 100644
--- a/src/coreclr/src/tools/Common/Internal/NativeFormat/NativeFormat.cs
+++ b/src/coreclr/src/tools/Common/Internal/NativeFormat/NativeFormat.cs
@@ -84,8 +84,8 @@ enum FixupSignatureKind : uint
MethodLdToken = 0x08,
AllocateObject = 0x09,
DefaultConstructor = 0x0a,
- TlsIndex = 0x0b,
- TlsOffset = 0x0c,
+ ThreadStaticIndex = 0x0b,
+ // unused = 0x0c,
Method = 0x0d,
IsInst = 0x0e,
CastClass = 0x0f,
diff --git a/src/coreclr/src/tools/Common/Internal/Runtime/CorConstants.cs b/src/coreclr/src/tools/Common/Internal/Runtime/CorConstants.cs
index 0b9f35726a1364..57a3353a805d41 100644
--- a/src/coreclr/src/tools/Common/Internal/Runtime/CorConstants.cs
+++ b/src/coreclr/src/tools/Common/Internal/Runtime/CorConstants.cs
@@ -81,7 +81,7 @@ public enum CorElementType : byte
// where the encoding/decoding takes place.
ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG = 0x3d,
- ELEMENT_TYPE_CANON_ZAPSIG = 0x3e, // zapsig encoding for [mscorlib]System.__Canon
+ ELEMENT_TYPE_CANON_ZAPSIG = 0x3e, // zapsig encoding for System.__Canon
ELEMENT_TYPE_MODULE_ZAPSIG = 0x3f, // zapsig encoding for external module id#
ELEMENT_TYPE_HANDLE = 64,
diff --git a/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunConstants.cs
index ce6de5de37cac4..6d92e7b5d1227c 100644
--- a/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunConstants.cs
+++ b/src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunConstants.cs
@@ -314,6 +314,17 @@ public enum ReadyToRunHelper
TypeHandleToRuntimeTypeHandle,
}
+ // Enum used for HFA type recognition.
+ // Supported across architectures, so that it can be used in altjits and cross-compilation.
+ public enum ReadyToRunHFAElemType
+ {
+ None = 0,
+ Float32 = 1,
+ Float64 = 2,
+ Vector64 = 3,
+ Vector128 = 4,
+ }
+
public static class ReadyToRunRuntimeConstants
{
public const int READYTORUN_PInvokeTransitionFrameSizeInPointerUnits = 11;
diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs
index 3f6c089744b217..46cac9f2e8d4e3 100644
--- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs
+++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs
@@ -76,55 +76,6 @@ static IntrinsicHashtable InitializeIntrinsicHashtable()
{
IntrinsicHashtable table = new IntrinsicHashtable();
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sin, "Sin", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sin, "Sin", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cos, "Cos", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cos, "Cos", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cbrt, "Cbrt", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cbrt, "Cbrt", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sqrt, "Sqrt", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sqrt, "Sqrt", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Abs, "Abs", "System", "Math");
- // No System.MathF entry for CORINFO_INTRTINSIC_Abs as System.Math exposes and handles both float and double
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Round, "Round", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Round, "Round", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cosh, "Cosh", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Cosh, "Cosh", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sinh, "Sinh", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Sinh, "Sinh", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tan, "Tan", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tan, "Tan", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tanh, "Tanh", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Tanh, "Tanh", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asin, "Asin", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asin, "Asin", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asinh, "Asinh", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Asinh, "Asinh", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acos, "Acos", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acos, "Acos", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acosh, "Acosh", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Acosh, "Acosh", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan, "Atan", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan, "Atan", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan2, "Atan2", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atan2, "Atan2", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atanh, "Atanh", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Atanh, "Atanh", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Log10, "Log10", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Log10, "Log10", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Pow, "Pow", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Pow, "Pow", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Exp, "Exp", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Exp, "Exp", "System", "MathF");
-#if !READYTORUN
- // These are normally handled via the SSE4.1 instructions ROUNDSS/ROUNDSD.
- // However, we don't know the ISAs the target machine supports so we should
- // fallback to the method call implementation instead.
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Ceiling, "Ceiling", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Ceiling, "Ceiling", "System", "MathF");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Floor, "Floor", "System", "Math");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Floor, "Floor", "System", "MathF");
-#endif
// table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_GetChar, null, null, null); // unused
// table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Array_GetDimLength, "GetLength", "System", "Array"); // not handled
table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Get, "Get", null, null);
@@ -163,7 +114,7 @@ static IntrinsicHashtable InitializeIntrinsicHashtable()
table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_GetRawHandle, "AllocatorOf", "System", "Activator");
// If this assert fails, make sure to add the new intrinsics to the table above and update the expected count below.
- Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_Count == 56, "Please update intrinsic hash table");
+ Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_Count == 34, "Please update intrinsic hash table");
return table;
}
@@ -201,14 +152,6 @@ private CorInfoIntrinsics getIntrinsicID(MethodDesc method, byte* pMustExpand)
CorInfoIntrinsics id = entry.Id;
switch (id)
{
- case CorInfoIntrinsics.CORINFO_INTRINSIC_Abs:
- {
- // RyuJIT handles floating point overloads only
- var returnTypeCategory = method.Signature.ReturnType.Category;
- if (returnTypeCategory != TypeFlags.Double && returnTypeCategory != TypeFlags.Single)
- return CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal;
- }
- break;
case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Get:
case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Address:
case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Set:
diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
index da5d691a39cf6d..3d7dd28329b9bb 100644
--- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
+++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
@@ -508,6 +508,7 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur
if (!signature.HasEmbeddedSignatureData || signature.GetEmbeddedSignatureData() == null)
return false;
+ bool found = false;
foreach (EmbeddedSignatureData data in signature.GetEmbeddedSignatureData())
{
if (data.kind != EmbeddedSignatureDataKind.OptionalCustomModifier)
@@ -524,25 +525,28 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur
if (defType.Namespace != "System.Runtime.CompilerServices")
continue;
- // Take the first recognized calling convention in metadata.
- switch (defType.Name)
+ // Look for a recognized calling convention in metadata.
+ CorInfoCallConv? callConvLocal = defType.Name switch
{
- case "CallConvCdecl":
- callConv = CorInfoCallConv.CORINFO_CALLCONV_C;
- return true;
- case "CallConvStdcall":
- callConv = CorInfoCallConv.CORINFO_CALLCONV_STDCALL;
- return true;
- case "CallConvFastcall":
- callConv = CorInfoCallConv.CORINFO_CALLCONV_FASTCALL;
- return true;
- case "CallConvThiscall":
- callConv = CorInfoCallConv.CORINFO_CALLCONV_THISCALL;
- return true;
+ "CallConvCdecl" => CorInfoCallConv.CORINFO_CALLCONV_C,
+ "CallConvStdcall" => CorInfoCallConv.CORINFO_CALLCONV_STDCALL,
+ "CallConvFastcall" => CorInfoCallConv.CORINFO_CALLCONV_FASTCALL,
+ "CallConvThiscall" => CorInfoCallConv.CORINFO_CALLCONV_THISCALL,
+ _ => null
+ };
+
+ if (callConvLocal.HasValue)
+ {
+ // Error if there are multiple recognized calling conventions
+ if (found)
+ ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramMultipleCallConv, MethodBeingCompiled);
+
+ callConv = callConvLocal.Value;
+ found = true;
}
}
- return false;
+ return found;
}
private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* sig)
@@ -811,7 +815,7 @@ private uint getMethodAttribsInternal(MethodDesc method)
// do a dynamic check instead.
if (
!HardwareIntrinsicHelpers.IsIsSupportedMethod(method)
- || !_compilation.IsHardwareInstrinsicWithRuntimeDeterminedSupport(method))
+ || !_compilation.IsHardwareIntrinsicWithRuntimeDeterminedSupport(method))
#endif
{
result |= CorInfoFlag.CORINFO_FLG_JIT_INTRINSIC;
diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs
index c1a9f87533ad05..8f4b1f60b92a11 100644
--- a/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs
+++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs
@@ -416,28 +416,6 @@ public enum CorInfoOptions
public enum CorInfoIntrinsics
{
- CORINFO_INTRINSIC_Sin,
- CORINFO_INTRINSIC_Cos,
- CORINFO_INTRINSIC_Cbrt,
- CORINFO_INTRINSIC_Sqrt,
- CORINFO_INTRINSIC_Abs,
- CORINFO_INTRINSIC_Round,
- CORINFO_INTRINSIC_Cosh,
- CORINFO_INTRINSIC_Sinh,
- CORINFO_INTRINSIC_Tan,
- CORINFO_INTRINSIC_Tanh,
- CORINFO_INTRINSIC_Asin,
- CORINFO_INTRINSIC_Asinh,
- CORINFO_INTRINSIC_Acos,
- CORINFO_INTRINSIC_Acosh,
- CORINFO_INTRINSIC_Atan,
- CORINFO_INTRINSIC_Atan2,
- CORINFO_INTRINSIC_Atanh,
- CORINFO_INTRINSIC_Log10,
- CORINFO_INTRINSIC_Pow,
- CORINFO_INTRINSIC_Exp,
- CORINFO_INTRINSIC_Ceiling,
- CORINFO_INTRINSIC_Floor,
CORINFO_INTRINSIC_GetChar, // fetch character out of string
CORINFO_INTRINSIC_Array_GetDimLength, // Get number of elements in a given dimension of an array
CORINFO_INTRINSIC_Array_Get, // Get the value of an element in an array
diff --git a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt
index 615fc9648ed58a..d8fe3984a92515 100644
--- a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt
+++ b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt
@@ -15,6 +15,10 @@
; Copy instruction sets defined for other architecture at this point in the file.
; copyinstructionsets,,
+; UPDATE JIT/EE INTERFACE GUID WHEN CHANGING THESE DEFINITIONS. The instruction set definitions are part of JIT/EE interface contract.
+
+; DO NOT CHANGE R2R NUMERIC VALUES OF THE EXISTING SETS. Changing R2R numberic values definitions would be R2R format breaking change.
+
; Definition of X86 instruction sets
definearch ,X86 ,32Bit ,X64
diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs
index d10a2dc0fec277..e10782ef0ad978 100644
--- a/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs
+++ b/src/coreclr/src/tools/Common/TypeSystem/Common/CastingHelper.cs
@@ -166,6 +166,17 @@ private static bool CanCastToInternal(this TypeDesc thisType, TypeDesc otherType
case TypeFlags.SzArray:
return ((ArrayType)thisType).CanCastArrayTo(otherType, protect);
+ case TypeFlags.ByRef:
+ case TypeFlags.Pointer:
+ if (otherType.Category == thisType.Category)
+ {
+ return ((ParameterizedType)thisType).CanCastParamTo(((ParameterizedType)otherType).ParameterType, protect);
+ }
+ return false;
+
+ case TypeFlags.FunctionPointer:
+ return false;
+
default:
Debug.Assert(thisType.IsDefType);
return thisType.CanCastToClassOrInterface(otherType, protect);
diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/ExceptionStringID.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/ExceptionStringID.cs
index 00286eabe3a97b..d9d3de41634de8 100644
--- a/src/coreclr/src/tools/Common/TypeSystem/Common/ExceptionStringID.cs
+++ b/src/coreclr/src/tools/Common/TypeSystem/Common/ExceptionStringID.cs
@@ -36,6 +36,7 @@ public enum ExceptionStringID
InvalidProgramNonStaticMethod,
InvalidProgramGenericMethod,
InvalidProgramNonBlittableTypes,
+ InvalidProgramMultipleCallConv,
// BadImageFormatException
BadImageFormatGeneric,
diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs
index 0545857397ba1e..1da52dccd3bd0a 100644
--- a/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs
+++ b/src/coreclr/src/tools/Common/TypeSystem/Common/MethodDesc.cs
@@ -51,6 +51,14 @@ public sealed partial class MethodSignature : TypeSystemEntity
// Value of for any custom modifiers on the return type
public const string IndexOfCustomModifiersOnReturnType = "0.1.1.1";
+ // Value of for any custom modifiers on
+ // SomeStruct when SomeStruct *, or SomeStruct & is the type of a parameter or return type
+ // Parameter index 0 represents the return type, and indices 1-n represent the parameters to the signature
+ public static string GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(int parameterIndex)
+ {
+ return $"0.1.1.2.{(parameterIndex + 1).ToStringInvariant()}.1";
+ }
+
public MethodSignature(MethodSignatureFlags flags, int genericParameterCount, TypeDesc returnType, TypeDesc[] parameters, EmbeddedSignatureData[] embeddedSignatureData = null)
{
_flags = flags;
diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/Properties/Resources.resx b/src/coreclr/src/tools/Common/TypeSystem/Common/Properties/Resources.resx
index 368145929e05a2..b0efd67b4adc55 100644
--- a/src/coreclr/src/tools/Common/TypeSystem/Common/Properties/Resources.resx
+++ b/src/coreclr/src/tools/Common/TypeSystem/Common/Properties/Resources.resx
@@ -174,7 +174,10 @@
UnmanagedCallersOnly attribute specified on method with non-blittable parameters '{0}'
+
+ Multiple unmanaged calling conventions are specified. Only a single calling convention is supported.
+
The format of a DLL or executable being loaded is invalid
-
\ No newline at end of file
+
diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/ThrowHelper.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/ThrowHelper.cs
index 9ab806e77ffe0e..094ade10facaa8 100644
--- a/src/coreclr/src/tools/Common/TypeSystem/Common/ThrowHelper.cs
+++ b/src/coreclr/src/tools/Common/TypeSystem/Common/ThrowHelper.cs
@@ -41,6 +41,12 @@ public static void ThrowInvalidProgramException()
throw new TypeSystemException.InvalidProgramException();
}
+ [System.Diagnostics.DebuggerHidden]
+ public static void ThrowInvalidProgramException(ExceptionStringID id)
+ {
+ throw new TypeSystemException.InvalidProgramException(id);
+ }
+
[System.Diagnostics.DebuggerHidden]
public static void ThrowInvalidProgramException(ExceptionStringID id, MethodDesc method)
{
diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.Resources.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.Resources.cs
new file mode 100644
index 00000000000000..bf5a3b97b292f4
--- /dev/null
+++ b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.Resources.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Resources;
+using System.Reflection;
+
+// This partial file is designed to allow the runtime variant of the type system to not
+// need to support accessing these strings via the ResourceManager
+namespace Internal.TypeSystem
+{
+ partial class TypeSystemException : Exception
+ {
+ private static Lazy s_stringResourceManager =
+ new Lazy(() => new ResourceManager("Internal.TypeSystem.Strings", typeof(TypeSystemException).GetTypeInfo().Assembly));
+
+ public static string GetFormatString(ExceptionStringID id)
+ {
+ return s_stringResourceManager.Value.GetString(id.ToString(), CultureInfo.InvariantCulture);
+ }
+ }
+}
diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs
index c9a71236c4daf0..17836ca309bd0a 100644
--- a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs
+++ b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs
@@ -9,7 +9,7 @@ namespace Internal.TypeSystem
///
/// Base type for all type system exceptions.
///
- public abstract class TypeSystemException : Exception
+ public abstract partial class TypeSystemException : Exception
{
private string[] _arguments;
@@ -43,53 +43,19 @@ internal TypeSystemException(ExceptionStringID id, params string[] args)
_arguments = args;
}
- private static string GetFormatString(ExceptionStringID id)
- {
- switch (id)
- {
- case ExceptionStringID.ClassLoadGeneral: return SR.ClassLoadGeneral;
- case ExceptionStringID.ClassLoadBadFormat: return SR.ClassLoadBadFormat;
- case ExceptionStringID.ClassLoadExplicitGeneric: return SR.ClassLoadExplicitGeneric;
- case ExceptionStringID.ClassLoadExplicitLayout: return SR.ClassLoadExplicitLayout;
- case ExceptionStringID.ClassLoadValueClassTooLarge: return SR.ClassLoadValueClassTooLarge;
- case ExceptionStringID.ClassLoadRankTooLarge: return SR.ClassLoadRankTooLarge;
- case ExceptionStringID.MissingMethod: return SR.MissingMethod;
- case ExceptionStringID.MissingField: return SR.MissingField;
- case ExceptionStringID.InvalidProgramDefault: return SR.InvalidProgramDefault;
- case ExceptionStringID.InvalidProgramSpecific: return SR.InvalidProgramSpecific;
- case ExceptionStringID.InvalidProgramVararg: return SR.InvalidProgramVararg;
- case ExceptionStringID.InvalidProgramCallVirtFinalize: return SR.InvalidProgramCallVirtFinalize;
- case ExceptionStringID.InvalidProgramUnmanagedCallersOnly: return SR.InvalidProgramUnmanagedCallersOnly;
- case ExceptionStringID.InvalidProgramCallAbstractMethod: return SR.InvalidProgramCallAbstractMethod;
- case ExceptionStringID.InvalidProgramCallVirtStatic: return SR.InvalidProgramCallVirtStatic;
- case ExceptionStringID.InvalidProgramNonStaticMethod: return SR.InvalidProgramNonStaticMethod;
- case ExceptionStringID.InvalidProgramGenericMethod: return SR.InvalidProgramGenericMethod;
- case ExceptionStringID.InvalidProgramNonBlittableTypes: return SR.InvalidProgramNonBlittableTypes;
- case ExceptionStringID.BadImageFormatGeneric: return SR.BadImageFormatGeneric;
- case ExceptionStringID.FileLoadErrorGeneric: return SR.FileLoadErrorGeneric;
- }
-#if !DEBUG
- throw new Exception($"Unknown Exception string id {id}");
-#else
- return null;
-#endif
- }
-
private static string GetExceptionString(ExceptionStringID id, string[] args)
{
string formatString = GetFormatString(id);
-#if !DEBUG
try
{
-#endif
- return String.Format(formatString, (object[])args);
-#if !DEBUG
+ if (formatString != null)
+ {
+ return String.Format(formatString, (object[])args);
+ }
}
- catch
- {
- return "[TEMPORARY EXCEPTION MESSAGE] " + id.ToString() + ": " + String.Join(", ", args);
- }
-#endif
+ catch {}
+
+ return "[TEMPORARY EXCEPTION MESSAGE] " + id.ToString() + ": " + String.Join(", ", args);
}
///
@@ -172,6 +138,11 @@ internal InvalidProgramException(ExceptionStringID id, string method)
{
}
+ internal InvalidProgramException(ExceptionStringID id)
+ : base(id)
+ {
+ }
+
internal InvalidProgramException()
: base(ExceptionStringID.InvalidProgramDefault)
{
diff --git a/src/coreclr/src/tools/Common/TypeSystem/IL/Stubs/VolatileIntrinsics.cs b/src/coreclr/src/tools/Common/TypeSystem/IL/Stubs/VolatileIntrinsics.cs
index f9ab4c10605591..35dca8644ac9e7 100644
--- a/src/coreclr/src/tools/Common/TypeSystem/IL/Stubs/VolatileIntrinsics.cs
+++ b/src/coreclr/src/tools/Common/TypeSystem/IL/Stubs/VolatileIntrinsics.cs
@@ -63,7 +63,7 @@ public static MethodIL EmitIL(MethodDesc method)
//
// Ordinary volatile loads and stores only guarantee atomicity for pointer-sized (or smaller) data.
// So, on 32-bit platforms we must use Interlocked operations instead for the 64-bit types.
- // The implementation in mscorlib already does this, so we will only substitute a new
+ // The implementation in CoreLib already does this, so we will only substitute a new
// IL body if we're running on a 64-bit platform.
//
case TypeFlags.Int64 when method.Context.Target.PointerSize == 8:
diff --git a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs
index 956e4fc8e274df..7b05a9b4ed90bb 100644
--- a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs
+++ b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs
@@ -166,13 +166,44 @@ internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type,
}
}
+ private static bool HasCopyConstructorCustomModifier(int? parameterIndex,
+ EmbeddedSignatureData[] customModifierData)
+ {
+ if (!parameterIndex.HasValue || customModifierData == null)
+ return false;
+
+ string customModifierIndex = MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(parameterIndex.Value);
+ foreach (var customModifier in customModifierData)
+ {
+ if (customModifier.kind != EmbeddedSignatureDataKind.RequiredCustomModifier)
+ continue;
+
+ if (customModifier.index != customModifierIndex)
+ continue;
+
+ var customModifierType = customModifier.type as DefType;
+ if (customModifierType == null)
+ continue;
+
+ if ((customModifierType.Namespace == "System.Runtime.CompilerServices" && customModifierType.Name == "IsCopyConstructed") ||
+ (customModifierType.Namespace == "Microsoft.VisualC" && customModifierType.Name == "NeedsCopyConstructorModifier"))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
internal static MarshallerKind GetMarshallerKind(
- TypeDesc type,
- MarshalAsDescriptor marshalAs,
- bool isReturn,
- bool isAnsi,
- MarshallerType marshallerType,
- out MarshallerKind elementMarshallerKind)
+ TypeDesc type,
+ int? parameterIndex,
+ EmbeddedSignatureData[] customModifierData,
+ MarshalAsDescriptor marshalAs,
+ bool isReturn,
+ bool isAnsi,
+ MarshallerType marshallerType,
+ out MarshallerKind elementMarshallerKind)
{
elementMarshallerKind = MarshallerKind.Invalid;
@@ -183,6 +214,12 @@ internal static MarshallerKind GetMarshallerKind(
type = type.GetParameterType();
+ if (!type.IsPrimitive && type.IsValueType && marshallerType != MarshallerType.Field
+ && HasCopyConstructorCustomModifier(parameterIndex, customModifierData))
+ {
+ return MarshallerKind.BlittableValueClassWithCopyCtor;
+ }
+
// Compat note: CLR allows ref returning blittable structs for IJW
if (isReturn)
return MarshallerKind.Invalid;
@@ -444,7 +481,15 @@ internal static MarshallerKind GetMarshallerKind(
else if (type.IsPointer)
{
if (nativeType == NativeTypeKind.Default)
+ {
+ var pointedAtType = type.GetParameterType();
+ if (!pointedAtType.IsPrimitive && !type.IsEnum && marshallerType != MarshallerType.Field
+ && HasCopyConstructorCustomModifier(parameterIndex, customModifierData))
+ {
+ return MarshallerKind.BlittableValueClassWithCopyCtor;
+ }
return MarshallerKind.BlittableValue;
+ }
else
return MarshallerKind.Invalid;
}
diff --git a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalUtils.cs b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalUtils.cs
index 65f0956943fbbf..f713f9cb0c29f6 100644
--- a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalUtils.cs
+++ b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalUtils.cs
@@ -44,6 +44,8 @@ public static bool IsBlittableType(TypeDesc type)
MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(
field.FieldType,
+ parameterIndex : null,
+ customModifierData: null,
field.GetMarshalAsDescriptor(),
isReturn: false,
isAnsi: mdType.PInvokeStringFormat == PInvokeStringFormat.AnsiClass,
diff --git a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs
index 31c86946302508..ecd7b0df468085 100644
--- a/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs
+++ b/src/coreclr/src/tools/Common/TypeSystem/Interop/IL/Marshaller.cs
@@ -50,6 +50,7 @@ enum MarshallerKind
AsAnyA,
AsAnyW,
ComInterface,
+ BlittableValueClassWithCopyCtor,
Invalid
}
public enum MarshalDirection
@@ -271,6 +272,8 @@ protected Marshaller()
/// type of the parameter to marshal
/// The created Marshaller
public static Marshaller CreateMarshaller(TypeDesc parameterType,
+ int? parameterIndex,
+ EmbeddedSignatureData[] customModifierData,
MarshallerType marshallerType,
MarshalAsDescriptor marshalAs,
MarshalDirection direction,
@@ -286,6 +289,8 @@ public static Marshaller CreateMarshaller(TypeDesc parameterType,
{
MarshallerKind elementMarshallerKind;
MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(parameterType,
+ parameterIndex,
+ customModifierData,
marshalAs,
isReturn,
flags.CharSet == CharSet.Ansi,
diff --git a/src/coreclr/src/tools/ILVerification/ILVerification.projitems b/src/coreclr/src/tools/ILVerification/ILVerification.projitems
index bc5bda42bc03cf..42f60611ee1813 100644
--- a/src/coreclr/src/tools/ILVerification/ILVerification.projitems
+++ b/src/coreclr/src/tools/ILVerification/ILVerification.projitems
@@ -13,18 +13,17 @@
+
+ $(MSBuildThisFileDirectory)..\Common\
+
ILVerification.Strings.resources
-
- true
- Internal.TypeSystem.SR
+
+ Internal.TypeSystem.Strings.resources
-
- $(MSBuildThisFileDirectory)..\Common\
-
TypeSystem\CodeGen\MethodDesc.CodeGen.cs
@@ -53,6 +52,9 @@
TypeSystem\Common\TypeSystemException.cs
+
+ TypeSystem\Common\TypeSystemException.Resources.cs
+
Utilities\CustomAttributeTypeNameParser.cs
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs
index 20d6dac16b8a93..68239af41359d7 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs
@@ -6,6 +6,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
+using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using ILCompiler.DependencyAnalysis.ReadyToRun;
@@ -102,8 +103,9 @@ public void EmitPortableExecutable()
stopwatch.Start();
PEHeaderBuilder headerBuilder;
- int timeDateStamp;
+ int? timeDateStamp;
ISymbolNode r2rHeaderExportSymbol;
+ Func, BlobContentId> peIdProvider = null;
if (_nodeFactory.CompilationModuleGroup.IsCompositeBuildMode && _componentModule == null)
{
@@ -112,8 +114,8 @@ public void EmitPortableExecutable()
dllCharacteristics: default(DllCharacteristics),
Subsystem.Unknown,
_nodeFactory.Target);
- // TODO: generate a non-zero timestamp: https://github.com/dotnet/runtime/issues/32507
- timeDateStamp = 0;
+ peIdProvider = new Func, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSourceHash(content)));
+ timeDateStamp = null;
r2rHeaderExportSymbol = _nodeFactory.Header;
}
else
@@ -135,7 +137,8 @@ public void EmitPortableExecutable()
r2rHeaderExportSymbol,
Path.GetFileName(_objectFilePath),
getRuntimeFunctionsTable,
- _customPESectionAlignment);
+ _customPESectionAlignment,
+ peIdProvider);
NativeDebugDirectoryEntryNode nativeDebugDirectoryEntryNode = null;
ISymbolDefinitionNode firstImportThunk = null;
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/CryptographicHashProvider.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/CryptographicHashProvider.cs
new file mode 100644
index 00000000000000..dafd0c1ae7bbdf
--- /dev/null
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/CryptographicHashProvider.cs
@@ -0,0 +1,252 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Metadata;
+using System.Security.Cryptography;
+
+namespace ILCompiler
+{
+ ///
+ /// Specifies a hash algorithms used for hashing source files.
+ ///
+ public enum SourceHashAlgorithm
+ {
+ ///
+ /// No algorithm specified.
+ ///
+ None = 0,
+
+ ///
+ /// Secure Hash Algorithm 1.
+ ///
+ Sha1 = 1,
+
+ ///
+ /// Secure Hash Algorithm 2 with a hash size of 256 bits.
+ ///
+ Sha256 = 2,
+ }
+
+ internal static class SourceHashAlgorithmUtils
+ {
+ public const SourceHashAlgorithm DefaultContentHashAlgorithm = SourceHashAlgorithm.Sha256;
+ }
+
+ internal abstract class CryptographicHashProvider
+ {
+ private ImmutableArray _lazySHA1Hash;
+ private ImmutableArray _lazySHA256Hash;
+ private ImmutableArray _lazySHA384Hash;
+ private ImmutableArray _lazySHA512Hash;
+ private ImmutableArray _lazyMD5Hash;
+
+ internal abstract ImmutableArray ComputeHash(HashAlgorithm algorithm);
+
+ internal ImmutableArray GetHash(AssemblyHashAlgorithm algorithmId)
+ {
+ using (HashAlgorithm? algorithm = TryGetAlgorithm(algorithmId))
+ {
+ // ERR_CryptoHashFailed has already been reported:
+ if (algorithm == null)
+ {
+ return ImmutableArray.Create();
+ }
+
+ switch (algorithmId)
+ {
+ case AssemblyHashAlgorithm.None:
+ case AssemblyHashAlgorithm.Sha1:
+ return GetHash(ref _lazySHA1Hash, algorithm);
+
+ case AssemblyHashAlgorithm.Sha256:
+ return GetHash(ref _lazySHA256Hash, algorithm);
+
+ case AssemblyHashAlgorithm.Sha384:
+ return GetHash(ref _lazySHA384Hash, algorithm);
+
+ case AssemblyHashAlgorithm.Sha512:
+ return GetHash(ref _lazySHA512Hash, algorithm);
+
+ case AssemblyHashAlgorithm.MD5:
+ return GetHash(ref _lazyMD5Hash, algorithm);
+
+ default:
+ throw new ArgumentException("algorithmId");
+ }
+ }
+ }
+
+ internal static int GetHashSize(SourceHashAlgorithm algorithmId)
+ {
+ switch (algorithmId)
+ {
+ case SourceHashAlgorithm.Sha1:
+ return 160 / 8;
+
+ case SourceHashAlgorithm.Sha256:
+ return 256 / 8;
+
+ default:
+ throw new ArgumentException("algorithmId");
+ }
+ }
+
+ internal static HashAlgorithm? TryGetAlgorithm(SourceHashAlgorithm algorithmId)
+ {
+ switch (algorithmId)
+ {
+ case SourceHashAlgorithm.Sha1:
+ return SHA1.Create();
+
+ case SourceHashAlgorithm.Sha256:
+ return SHA256.Create();
+
+ default:
+ return null;
+ }
+ }
+
+ internal static HashAlgorithmName GetAlgorithmName(SourceHashAlgorithm algorithmId)
+ {
+ switch (algorithmId)
+ {
+ case SourceHashAlgorithm.Sha1:
+ return HashAlgorithmName.SHA1;
+
+ case SourceHashAlgorithm.Sha256:
+ return HashAlgorithmName.SHA256;
+
+ default:
+ throw new ArgumentException("algorithmId");
+ }
+ }
+
+ internal static HashAlgorithm? TryGetAlgorithm(AssemblyHashAlgorithm algorithmId)
+ {
+ switch (algorithmId)
+ {
+ case AssemblyHashAlgorithm.None:
+ case AssemblyHashAlgorithm.Sha1:
+ return SHA1.Create();
+
+ case AssemblyHashAlgorithm.Sha256:
+ return SHA256.Create();
+
+ case AssemblyHashAlgorithm.Sha384:
+ return SHA384.Create();
+
+ case AssemblyHashAlgorithm.Sha512:
+ return SHA512.Create();
+
+ case AssemblyHashAlgorithm.MD5:
+ return MD5.Create();
+
+ default:
+ return null;
+ }
+ }
+
+ internal static bool IsSupportedAlgorithm(AssemblyHashAlgorithm algorithmId)
+ {
+ switch (algorithmId)
+ {
+ case AssemblyHashAlgorithm.None:
+ case AssemblyHashAlgorithm.Sha1:
+ case AssemblyHashAlgorithm.Sha256:
+ case AssemblyHashAlgorithm.Sha384:
+ case AssemblyHashAlgorithm.Sha512:
+ case AssemblyHashAlgorithm.MD5:
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ private ImmutableArray GetHash(ref ImmutableArray lazyHash, HashAlgorithm algorithm)
+ {
+ if (lazyHash.IsDefault)
+ {
+ ImmutableInterlocked.InterlockedCompareExchange(ref lazyHash, ComputeHash(algorithm), default(ImmutableArray));
+ }
+
+ return lazyHash;
+ }
+
+ internal const int Sha1HashSize = 20;
+
+ internal static ImmutableArray ComputeSha1(Stream stream)
+ {
+ if (stream != null)
+ {
+ stream.Seek(0, SeekOrigin.Begin);
+ using (var hashProvider = SHA1.Create())
+ {
+ return ImmutableArray.Create(hashProvider.ComputeHash(stream));
+ }
+ }
+
+ return ImmutableArray.Empty;
+ }
+
+ internal static ImmutableArray ComputeSha1(ImmutableArray bytes)
+ {
+ return ComputeSha1(bytes.ToArray());
+ }
+
+ internal static ImmutableArray ComputeSha1(byte[] bytes)
+ {
+ using (var hashProvider = SHA1.Create())
+ {
+ return ImmutableArray.Create(hashProvider.ComputeHash(bytes));
+ }
+ }
+
+ internal static ImmutableArray ComputeHash(HashAlgorithmName algorithmName, IEnumerable bytes)
+ {
+ using (var incrementalHash = IncrementalHash.CreateHash(algorithmName))
+ {
+ foreach (var blob in bytes)
+ {
+ incrementalHash.AppendData(blob.GetBytes());
+ }
+ return ImmutableArray.Create(incrementalHash.GetHashAndReset());
+ }
+ }
+
+ internal static ImmutableArray ComputeHash(HashAlgorithmName algorithmName, IEnumerable> bytes)
+ {
+ using (var incrementalHash = IncrementalHash.CreateHash(algorithmName))
+ {
+ foreach (var segment in bytes)
+ {
+ incrementalHash.AppendData(segment);
+ }
+ return ImmutableArray.Create(incrementalHash.GetHashAndReset());
+ }
+ }
+
+ internal static ImmutableArray ComputeSourceHash(ImmutableArray bytes, SourceHashAlgorithm hashAlgorithm = SourceHashAlgorithmUtils.DefaultContentHashAlgorithm)
+ {
+ var algorithmName = GetAlgorithmName(hashAlgorithm);
+ using (var incrementalHash = IncrementalHash.CreateHash(algorithmName))
+ {
+ incrementalHash.AppendData(bytes.ToArray());
+ return ImmutableArray.Create(incrementalHash.GetHashAndReset());
+ }
+ }
+
+ internal static ImmutableArray ComputeSourceHash(IEnumerable bytes, SourceHashAlgorithm hashAlgorithm = SourceHashAlgorithmUtils.DefaultContentHashAlgorithm)
+ {
+ return ComputeHash(GetAlgorithmName(hashAlgorithm), bytes);
+ }
+ }
+}
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs
index 8adc7341210bd5..e8596cf24c894a 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs
@@ -67,7 +67,7 @@ private unsafe byte[] GetRvaData(int targetPointerSize)
int currentFieldRid;
if (compressedFieldRef)
{
- currentFieldRid = metadataBlob.ReadInt16();
+ currentFieldRid = metadataBlob.ReadUInt16();
}
else
{
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMetadataBlobNode.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMetadataBlobNode.cs
index 8f0ae4281c31d7..b38dbfba67b59e 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMetadataBlobNode.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMetadataBlobNode.cs
@@ -84,7 +84,7 @@ private void WriteFieldRvas(NodeFactory factory, ref ObjectDataBuilder builder,
int fieldToken;
if (compressedFieldRef)
{
- fieldToken = reader.ReadInt16();
+ fieldToken = reader.ReadUInt16();
}
else
{
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs
index 08093ecd367114..175025449039bd 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugDirectoryNode.cs
@@ -26,10 +26,12 @@ public class DebugDirectoryNode : ObjectNode, ISymbolDefinitionNode
private EcmaModule _module;
private NativeDebugDirectoryEntryNode _nativeEntry;
+ private bool _insertDeterministicEntry;
public DebugDirectoryNode(EcmaModule sourceModule, string outputFileName)
{
_module = sourceModule;
+ _insertDeterministicEntry = sourceModule == null; // Mark module as deterministic if generating composite image
string pdbNameRoot = Path.GetFileNameWithoutExtension(outputFileName);
if (sourceModule != null)
{
@@ -50,7 +52,7 @@ public DebugDirectoryNode(EcmaModule sourceModule, string outputFileName)
public int Offset => 0;
- public int Size => (GetNumDebugDirectoryEntriesInModule() + 1) * ImageDebugDirectorySize;
+ public int Size => (GetNumDebugDirectoryEntriesInModule() + 1 + (_insertDeterministicEntry ? 1 : 0)) * ImageDebugDirectorySize;
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
@@ -112,8 +114,21 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
builder.EmitReloc(entry, RelocType.IMAGE_REL_FILE_ABSOLUTE);
}
+ // If generating a composite image, emit the deterministic marker
+ if (_insertDeterministicEntry)
+ {
+ builder.EmitUInt(0 /* Characteristics */);
+ builder.EmitUInt(0);
+ builder.EmitUShort(0);
+ builder.EmitUShort(0);
+ builder.EmitInt((int)DebugDirectoryEntryType.Reproducible);
+ builder.EmitInt(0);
+ builder.EmitUInt(0);
+ builder.EmitUInt(0);
+ }
+
// Second, copy existing entries from input module
- for(int i = 0; i < numEntries; i++)
+ for (int i = 0; i < numEntries; i++)
{
builder.EmitUInt(0 /* Characteristics */);
builder.EmitUInt(entries[i].Stamp);
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs
index ebeb537f5f152f..eb5431f29e529a 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FieldFixupSignature.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Diagnostics;
using Internal.JitInterface;
using Internal.Text;
@@ -13,17 +14,19 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
public class FieldFixupSignature : Signature
{
+ public const int MaxCheckableOffset = 0x1FFFFFFF;
private readonly ReadyToRunFixupKind _fixupKind;
private readonly FieldDesc _fieldDesc;
- public FieldFixupSignature(ReadyToRunFixupKind fixupKind, FieldDesc fieldDesc)
+ public FieldFixupSignature(ReadyToRunFixupKind fixupKind, FieldDesc fieldDesc, NodeFactory factory)
{
_fixupKind = fixupKind;
_fieldDesc = fieldDesc;
// Ensure types in signature are loadable and resolvable, otherwise we'll fail later while emitting the signature
((CompilerTypeSystemContext)fieldDesc.Context).EnsureLoadableType(fieldDesc.OwningType);
+ Debug.Assert(factory.SignatureContext.GetTargetModule(_fieldDesc) != null);
}
public override int ClassCode => 271828182;
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs
index 54b9849aed8cef..fd80e7e74a582a 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
+using System.Reflection.Metadata.Ecma335;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
@@ -441,11 +442,18 @@ public void EmitMethodSignature(
// Owner type is needed for type specs to instantiating stubs or generics with signature variables still present
if (!method.Method.OwningType.IsDefType &&
- ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0 || method.Method.OwningType.ContainsSignatureVariables())
- || method.Method.IsArrayAddressMethod())
+ ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0 || method.Method.OwningType.ContainsSignatureVariables()))
{
flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
}
+ else if (method.Method.IsArrayMethod())
+ {
+ var memberRefMethod = method.Token.Module.GetMethod(MetadataTokens.EntityHandle((int)method.Token.Token));
+ if (memberRefMethod.OwningType != method.Method.OwningType)
+ {
+ flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
+ }
+ }
EmitUInt(flags);
if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.cs
index 0bc86c7794cbf9..ea21b730330b9e 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TypeFixupSignature.cs
@@ -81,16 +81,16 @@ private static void EncodeTypeLayout(ObjectDataSignatureBuilder dataBuilder, Typ
if (defType.IsHomogeneousAggregate)
{
- CorElementType elementType = (defType.ValueTypeShapeCharacteristics & ValueTypeShapeCharacteristics.AggregateMask) switch
+ ReadyToRunHFAElemType hfaElementType = (defType.ValueTypeShapeCharacteristics & ValueTypeShapeCharacteristics.AggregateMask) switch
{
- ValueTypeShapeCharacteristics.Float32Aggregate => CorElementType.ELEMENT_TYPE_R4,
- ValueTypeShapeCharacteristics.Float64Aggregate => CorElementType.ELEMENT_TYPE_R8,
- ValueTypeShapeCharacteristics.Vector64Aggregate => CorElementType.ELEMENT_TYPE_R8,
+ ValueTypeShapeCharacteristics.Float32Aggregate => ReadyToRunHFAElemType.Float32,
+ ValueTypeShapeCharacteristics.Float64Aggregate => ReadyToRunHFAElemType.Float64,
+ ValueTypeShapeCharacteristics.Vector64Aggregate => ReadyToRunHFAElemType.Vector64,
// See MethodTable::GetHFAType
- ValueTypeShapeCharacteristics.Vector128Aggregate => CorElementType.ELEMENT_TYPE_VALUETYPE,
- _ => CorElementType.Invalid
+ ValueTypeShapeCharacteristics.Vector128Aggregate => ReadyToRunHFAElemType.Vector128,
+ _ => throw new NotSupportedException()
};
- dataBuilder.EmitUInt((uint)elementType);
+ dataBuilder.EmitUInt((uint)hfaElementType);
}
if (alignment != pointerSize)
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs
index 7ae68230d8a692..1178d4372c33a0 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs
@@ -70,7 +70,7 @@ private void CreateNodeCaches()
_codegenNodeFactory,
_codegenNodeFactory.HelperImports,
ReadyToRunHelper.DelayLoad_Helper,
- new FieldFixupSignature(ReadyToRunFixupKind.FieldAddress, key)
+ new FieldFixupSignature(ReadyToRunFixupKind.FieldAddress, key, _codegenNodeFactory)
);
});
@@ -78,7 +78,7 @@ private void CreateNodeCaches()
{
return new PrecodeHelperImport(
_codegenNodeFactory,
- new FieldFixupSignature(ReadyToRunFixupKind.FieldOffset, key)
+ new FieldFixupSignature(ReadyToRunFixupKind.FieldOffset, key, _codegenNodeFactory)
);
});
@@ -94,7 +94,7 @@ private void CreateNodeCaches()
{
return new PrecodeHelperImport(
_codegenNodeFactory,
- new FieldFixupSignature(_verifyTypeAndFieldLayout ? ReadyToRunFixupKind.Verify_FieldOffset : ReadyToRunFixupKind.Check_FieldOffset, key)
+ new FieldFixupSignature(_verifyTypeAndFieldLayout ? ReadyToRunFixupKind.Verify_FieldOffset : ReadyToRunFixupKind.Check_FieldOffset, key, _codegenNodeFactory)
);
});
@@ -356,7 +356,7 @@ private ISymbolNode CreateFieldHandleHelper(FieldDesc field)
{
return new PrecodeHelperImport(
_codegenNodeFactory,
- new FieldFixupSignature(ReadyToRunFixupKind.FieldHandle, field));
+ new FieldFixupSignature(ReadyToRunFixupKind.FieldHandle, field, _codegenNodeFactory));
}
private ISymbolNode CreateCctorTrigger(TypeDesc type)
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs
index c42ecaa13c1ceb..718d4e650fa687 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/IBC/IBCProfileParser.cs
@@ -113,7 +113,8 @@ public ProfileData ParseIBCDataFromModule(EcmaModule ecmaModule)
}
else
{
- _logger.Writer.WriteLine($"Token {0:x} does not refer to a method");
+ if (_logger.IsVerbose)
+ _logger.Writer.WriteLine($"Token {(int)entry.Token:x} does not refer to a method");
}
break;
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
index 483973871a90b5..b8d01189009d15 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
@@ -98,6 +98,7 @@
+
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs
index 4ca7a6f9596505..04b939334a21e1 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs
@@ -70,6 +70,8 @@ public static Marshaller[] GetMarshallersForMethod(MethodDesc targetMethod)
TypeDesc parameterType = (i == 0) ? methodSig.ReturnType : methodSig[i - 1]; //first item is the return type
marshallers[i] = CreateMarshaller(parameterType,
+ parameterIndex,
+ methodSig.GetEmbeddedSignatureData(),
MarshallerType.Argument,
parameterMetadata.MarshalAsDescriptor,
direction,
@@ -121,6 +123,8 @@ public static bool IsMarshallingRequired(MethodSignature methodSig, ParameterMet
MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(
parameterType,
+ parameterIndex: i,
+ customModifierData: methodSig.GetEmbeddedSignatureData(),
parameterMetadata.MarshalAsDescriptor,
parameterMetadata.Return,
isAnsi: true,
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
index 2c2085635f3482..57c4b738d690c1 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
@@ -1012,7 +1012,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET
CorInfoHelpFunc.CORINFO_HELP_GETGENERICS_NONGCSTATIC_BASE);
}
- if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout)
+ if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && (fieldOffset <= FieldFixupSignature.MaxCheckableOffset))
{
// ENCODE_CHECK_FIELD_OFFSET
_methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field));
@@ -1066,7 +1066,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET
else
if (helperId != ReadyToRunHelperId.Invalid)
{
- if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout)
+ if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && (fieldOffset <= FieldFixupSignature.MaxCheckableOffset))
{
// ENCODE_CHECK_FIELD_OFFSET
_methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field));
@@ -1922,7 +1922,7 @@ private bool NeedsTypeLayoutCheck(TypeDesc type)
if (!type.IsValueType)
return false;
- return !_compilation.IsLayoutFixedInCurrentVersionBubble(type) || _compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout;
+ return !_compilation.IsLayoutFixedInCurrentVersionBubble(type) || (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !((MetadataType)type).IsNonVersionable());
}
private bool HasLayoutMetadata(TypeDesc type)
@@ -1963,6 +1963,9 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult,
if (pMT.IsValueType)
{
// ENCODE_CHECK_FIELD_OFFSET
+ if (pResult->offset > FieldFixupSignature.MaxCheckableOffset)
+ throw new RequiresRuntimeJitException(callerMethod.ToString() + " -> " + field.ToString());
+
_methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field));
// No-op other than generating the check field offset fixup
}
@@ -1978,7 +1981,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult,
}
else if (pMT.IsValueType)
{
- if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout)
+ if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !callerMethod.IsNonVersionable() && (pResult->offset <= FieldFixupSignature.MaxCheckableOffset))
{
// ENCODE_CHECK_FIELD_OFFSET
_methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field));
@@ -1987,7 +1990,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult,
}
else if (_compilation.IsInheritanceChainLayoutFixedInCurrentVersionBubble(pMT.BaseType))
{
- if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout)
+ if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !callerMethod.IsNonVersionable() && (pResult->offset <= FieldFixupSignature.MaxCheckableOffset))
{
// ENCODE_CHECK_FIELD_OFFSET
_methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field));
@@ -2009,7 +2012,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult,
{
PreventRecursiveFieldInlinesOutsideVersionBubble(field, callerMethod);
- if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout)
+ if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !callerMethod.IsNonVersionable() && (pResult->offset <= FieldFixupSignature.MaxCheckableOffset))
{
// ENCODE_CHECK_FIELD_OFFSET
_methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field));
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs
index 839b1f21d11067..e1731e4c95f870 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs
@@ -173,8 +173,9 @@ public R2RPEBuilder(
ISymbolNode r2rHeaderExportSymbol,
string outputFileSimpleName,
Func getRuntimeFunctionsTable,
- int? customPESectionAlignment)
- : base(peHeaderBuilder, deterministicIdProvider: null)
+ int? customPESectionAlignment,
+ Func, BlobContentId> deterministicIdProvider)
+ : base(peHeaderBuilder, deterministicIdProvider: deterministicIdProvider)
{
_target = target;
_getRuntimeFunctionsTable = getRuntimeFunctionsTable;
@@ -288,7 +289,7 @@ public int GetSymbolFilePosition(ISymbolNode symbol)
///
/// Output stream for the final R2R PE file
/// Timestamp to set in the PE header of the output R2R executable
- public void Write(Stream outputStream, int timeDateStamp)
+ public void Write(Stream outputStream, int? timeDateStamp)
{
BlobBuilder outputPeFile = new BlobBuilder();
Serialize(outputPeFile);
@@ -302,7 +303,8 @@ public void Write(Stream outputStream, int timeDateStamp)
ApplyMachineOSOverride(outputStream);
- SetPEHeaderTimeStamp(outputStream, timeDateStamp);
+ if (timeDateStamp.HasValue)
+ SetPEHeaderTimeStamp(outputStream, timeDateStamp.Value);
_written = true;
}
diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs
index 1c5150bcedaf6d..08241e0a433d11 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/Amd64/UnwindInfo.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Text;
namespace ILCompiler.Reflection.ReadyToRun.Amd64
@@ -76,6 +77,19 @@ public UnwindCode(byte[] image, int index, ref int offset)
FrameOffset = NativeReader.ReadUInt16(image, ref offset);
NextFrameOffset = -1;
+ if (UnwindOp == UnwindOpCodes.UWOP_ALLOC_LARGE)
+ {
+ uint codedSize;
+ if (OpInfo == 0)
+ {
+ codedSize = NativeReader.ReadUInt16(image, ref offset);
+ }
+ else if (OpInfo == 1)
+ {
+ codedSize = NativeReader.ReadUInt32(image, ref offset);
+ }
+ }
+
IsOpInfo = false;
}
}
@@ -95,7 +109,7 @@ public class UnwindInfo : BaseUnwindInfo
public Registers FrameRegister { get; set; } //4 bits
public byte FrameOffset { get; set; } //4 bits
public UnwindCode[] UnwindCodeArray { get; set; }
- public Dictionary> UnwindCodes { get; set; }
+ public Dictionary UnwindCodes { get; set; }
public uint PersonalityRoutineRVA { get; set; }
public UnwindInfo() { }
@@ -115,7 +129,7 @@ public UnwindInfo(byte[] image, int offset)
FrameOffset = (byte)(frameRegisterAndOffset >> 4);
UnwindCodeArray = new UnwindCode[CountOfUnwindCodes];
- UnwindCodes = new Dictionary>();
+ UnwindCodes = new Dictionary();
for (int i = 0; i < CountOfUnwindCodes; i++)
{
UnwindCodeArray[i] = new UnwindCode(image, i, ref offset);
@@ -123,11 +137,8 @@ public UnwindInfo(byte[] image, int offset)
for (int i = 0; i < CountOfUnwindCodes; i++)
{
ParseUnwindCode(ref i);
- if (!UnwindCodes.ContainsKey(UnwindCodeArray[i].CodeOffset))
- {
- UnwindCodes[UnwindCodeArray[i].CodeOffset] = new List();
- }
- UnwindCodes[UnwindCodeArray[i].CodeOffset].Add(UnwindCodeArray[i]);
+ Debug.Assert(!UnwindCodes.ContainsKey(UnwindCodeArray[i].CodeOffset));
+ UnwindCodes.Add(UnwindCodeArray[i].CodeOffset, UnwindCodeArray[i]);
}
Size = _offsetofUnwindCode + CountOfUnwindCodes * _sizeofUnwindCode;
diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs
index 706e98780acbf7..8a6766d42945aa 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs
@@ -17,15 +17,15 @@ namespace ILCompiler.Reflection.ReadyToRun
///
public class DebugInfo
{
- private readonly ReadyToRunReader _readyToRunReader;
+ private readonly RuntimeFunction _runtimeFunction;
private readonly int _offset;
private List _boundsList;
private List _variablesList;
private Machine _machine;
- public DebugInfo(ReadyToRunReader readyToRunReader, int offset)
+ public DebugInfo(RuntimeFunction runtimeFunction, int offset)
{
- this._readyToRunReader = readyToRunReader;
+ this._runtimeFunction = runtimeFunction;
this._offset = offset;
}
@@ -83,6 +83,7 @@ private void EnsureInitialized()
{
return;
}
+ ReadyToRunReader _readyToRunReader = _runtimeFunction.ReadyToRunReader;
int offset = _offset;
_boundsList = new List();
_variablesList = new List();
@@ -156,6 +157,19 @@ private void ParseNativeVarInfo(byte[] image, int offset)
entry.StartOffset = reader.ReadUInt();
entry.EndOffset = entry.StartOffset + reader.ReadUInt();
entry.VariableNumber = (uint)(reader.ReadUInt() + (int)ImplicitILArguments.Max);
+ entry.Variable = new Variable();
+ // TODO: This is probably incomplete
+ // This does not handle any implicit arguments or var args
+ if (entry.VariableNumber < this._runtimeFunction.Method.Signature.ParameterTypes.Length)
+ {
+ entry.Variable.Type = VariableType.Parameter;
+ entry.Variable.Index = (int)entry.VariableNumber;
+ }
+ else
+ {
+ entry.Variable.Type = VariableType.Local;
+ entry.Variable.Index = (int)entry.VariableNumber - this._runtimeFunction.Method.Signature.ParameterTypes.Length;
+ }
var varLoc = new VarLoc();
varLoc.VarLocType = (VarLocType)reader.ReadUInt();
diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs
index 73782f2344c38f..eef0ab4673cbe1 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/DebugInfoTypes.cs
@@ -17,10 +17,25 @@ public struct NativeVarInfo
{
public uint StartOffset;
public uint EndOffset;
+ // TODO: Eliminate this
public uint VariableNumber;
+ public Variable Variable { get; internal set; }
public VarLoc VariableLocation;
}
+ public enum VariableType
+ {
+ Parameter,
+ Local,
+ // TODO: Special
+ }
+
+ public class Variable
+ {
+ public VariableType Type { get; internal set; }
+ public int Index { get; internal set; }
+ }
+
[Flags]
public enum SourceTypes
{
diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs
index a00419f212c4ce..266a75bbddc134 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs
@@ -144,12 +144,24 @@ public DebugInfo DebugInfo
{
if (_debugInfo == null)
{
- _readyToRunReader.RuntimeFunctionToDebugInfo.TryGetValue(Id, out _debugInfo);
+ int offset;
+ if (_readyToRunReader.RuntimeFunctionToDebugInfo.TryGetValue(Id, out offset))
+ {
+ this._debugInfo = new DebugInfo(this, offset);
+ }
}
return _debugInfo;
}
}
+ internal ReadyToRunReader ReadyToRunReader
+ {
+ get
+ {
+ return _readyToRunReader;
+ }
+ }
+
public RuntimeFunction(
ReadyToRunReader readyToRunReader,
int id,
@@ -218,6 +230,8 @@ public class ReadyToRunMethod
public MethodSignature Signature { get; }
+ public ImmutableArray LocalSignature { get; }
+
///
/// The type that the method belongs to
///
@@ -282,6 +296,7 @@ public IReadOnlyList Fixups
///
public ReadyToRunMethod(
ReadyToRunReader readyToRunReader,
+ PEReader peReader,
MetadataReader metadataReader,
EntityHandle methodHandle,
int entryPointId,
@@ -309,6 +324,15 @@ public ReadyToRunMethod(
case HandleKind.MethodDefinition:
{
MethodDefinition methodDef = MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle);
+ if (methodDef.RelativeVirtualAddress != 0)
+ {
+ MethodBodyBlock mbb = peReader.GetMethodBody(methodDef.RelativeVirtualAddress);
+ if (!mbb.LocalSignature.IsNil)
+ {
+ StandaloneSignature ss = MetadataReader.GetStandaloneSignature(mbb.LocalSignature);
+ LocalSignature = ss.DecodeLocalSignature(typeProvider, genericContext);
+ }
+ }
Name = MetadataReader.GetString(methodDef.Name);
Signature = methodDef.DecodeSignature(typeProvider, genericContext);
owningTypeHandle = methodDef.GetDeclaringType();
diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs
index a829b58599e531..3fdb03f6724bc2 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs
@@ -80,7 +80,7 @@ public sealed class ReadyToRunReader
private List _readyToRunAssemblyHeaders;
// DebugInfo
- private Dictionary _runtimeFunctionToDebugInfo;
+ private Dictionary _runtimeFunctionIdToDebugOffset;
// ManifestReferences
private MetadataReader _manifestReader;
@@ -322,12 +322,12 @@ public IReadOnlyDictionary ImportSignatures
}
- internal Dictionary RuntimeFunctionToDebugInfo
+ internal Dictionary RuntimeFunctionToDebugInfo
{
get
{
EnsureDebugInfo();
- return _runtimeFunctionToDebugInfo;
+ return _runtimeFunctionIdToDebugOffset;
}
}
@@ -583,11 +583,11 @@ private unsafe void EnsureHeader()
private void EnsureDebugInfo()
{
- if (_runtimeFunctionToDebugInfo != null)
+ if (_runtimeFunctionIdToDebugOffset != null)
{
return;
}
- _runtimeFunctionToDebugInfo = new Dictionary();
+ _runtimeFunctionIdToDebugOffset = new Dictionary();
if (!ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.DebugInfo, out ReadyToRunSection debugInfoSection))
{
return;
@@ -604,8 +604,7 @@ private void EnsureDebugInfo()
continue;
}
- var debugInfo = new DebugInfo(this, offset);
- _runtimeFunctionToDebugInfo.Add((int)i, debugInfo);
+ _runtimeFunctionIdToDebugOffset.Add((int)i, offset);
}
}
@@ -741,7 +740,7 @@ private void ParseMethodDefEntrypointsSection(ReadyToRunSection section, Metadat
int runtimeFunctionId;
int? fixupOffset;
GetRuntimeFunctionIndexFromOffset(offset, out runtimeFunctionId, out fixupOffset);
- ReadyToRunMethod method = new ReadyToRunMethod(this, metadataReader, methodHandle, runtimeFunctionId, owningType: null, constrainedType: null, instanceArgs: null, fixupOffset: fixupOffset);
+ ReadyToRunMethod method = new ReadyToRunMethod(this, this.PEReader, metadataReader, methodHandle, runtimeFunctionId, owningType: null, constrainedType: null, instanceArgs: null, fixupOffset: fixupOffset);
if (method.EntryPointRuntimeFunctionId < 0 || method.EntryPointRuntimeFunctionId >= isEntryPoint.Length)
{
@@ -889,6 +888,7 @@ private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint)
GetRuntimeFunctionIndexFromOffset((int)decoder.Offset, out runtimeFunctionId, out fixupOffset);
ReadyToRunMethod method = new ReadyToRunMethod(
this,
+ this.PEReader,
mdReader,
methodHandle,
runtimeFunctionId,
diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ExceptionStringTests.cs b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ExceptionStringTests.cs
new file mode 100644
index 00000000000000..d40bdf774126d8
--- /dev/null
+++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ExceptionStringTests.cs
@@ -0,0 +1,26 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using Internal.TypeSystem;
+
+using Xunit;
+
+namespace TypeSystemTests
+{
+ public class ExceptionStringTests
+ {
+ public ExceptionStringTests()
+ {
+ }
+
+ [Fact]
+ public void TestAllExceptionIdsHaveMessages()
+ {
+ foreach(var exceptionId in (ExceptionStringID[])Enum.GetValues(typeof(ExceptionStringID)))
+ {
+ Assert.NotNull(TypeSystemException.GetFormatString(exceptionId));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj
index 38e1dda8abaaf4..7567ab173f5db3 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj
+++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj
@@ -47,6 +47,7 @@
+
@@ -56,5 +57,6 @@
+
diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il
index b28c850616f7cd..02f33b81f04731 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il
+++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il
@@ -1,6 +1,36 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+.class public auto ansi beforefieldinit ModOptTester
+ extends [CoreTestAssembly]System.Object
+{
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [CoreTestAssembly]System.Object::.ctor()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method I::.ctor
+
+ .method public hidebysig instance int32 modopt([CoreTestAssembly]System.Void) modopt([CoreTestAssembly]System.Char) Method(int32 modopt(FooModifier)) cil managed
+ {
+ ret
+ }
+
+ .method public hidebysig instance int32 modopt([CoreTestAssembly]System.Void) & modopt([CoreTestAssembly]System.Char) Method2(int32 modopt(FooModifier)) cil managed
+ {
+ ret
+ }
+
+ .method public hidebysig instance int32 modopt([CoreTestAssembly]System.Void) & Method3(int32 modopt(FooModifier)*, int32 modopt(FooModifier)*) cil managed
+ {
+ ret
+ }
+}
+
.class private auto ansi beforefieldinit Atom
extends [CoreTestAssembly]System.Object
{
diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs
index cfaeef6ea437e3..60d717291196a0 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs
@@ -27,6 +27,58 @@ public SignatureTests()
_testModule = _context.GetModuleForSimpleName("ILTestAssembly");
}
+ private static string GetModOptMethodSignatureInfo(MethodSignature signature)
+ {
+ if (!signature.HasEmbeddedSignatureData || signature.GetEmbeddedSignatureData() == null)
+ return "";
+
+ StringBuilder sb = new StringBuilder();
+ foreach (EmbeddedSignatureData data in signature.GetEmbeddedSignatureData())
+ {
+ sb.Append(data.kind.ToString());
+ sb.Append(data.index);
+ sb.Append(((MetadataType)data.type).Name);
+ }
+ return sb.ToString();
+ }
+
+ [Fact]
+ public void TestSignatureMatches2ModOptsAtStartOfSig()
+ {
+ MetadataType modOptTester = _testModule.GetType("", "ModOptTester");
+ MethodSignature methodWith2ModOptsAtStartOfSig = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method")).Signature;
+
+ // All modopts that are at the very beginning of the signature are given index 0.1.1.1
+ // Both the index and the order in the modopt array are significant for signature comparison
+ Assert.Equal(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWith2ModOptsAtStartOfSig.GetEmbeddedSignatureData()[0].index);
+ Assert.Equal(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWith2ModOptsAtStartOfSig.GetEmbeddedSignatureData()[1].index);
+ Assert.NotEqual(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWith2ModOptsAtStartOfSig.GetEmbeddedSignatureData()[2].index);
+ Assert.Equal("OptionalCustomModifier0.1.1.1CharOptionalCustomModifier0.1.1.1VoidOptionalCustomModifier0.1.2.1FooModifier", GetModOptMethodSignatureInfo(methodWith2ModOptsAtStartOfSig));
+ }
+
+ [Fact]
+ public void TestSignatureMatchesModOptAtStartOfSigAndAfterByRef()
+ {
+ MetadataType modOptTester = _testModule.GetType("", "ModOptTester");
+ MethodSignature methodWithModOptAtStartOfSigAndAfterByRef = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method2")).Signature;
+
+ // A modopts after an E_T_BYREF will look like 0.1.1.2.1.1
+ Assert.Equal(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWithModOptAtStartOfSigAndAfterByRef.GetEmbeddedSignatureData()[0].index);
+ Assert.NotEqual(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWithModOptAtStartOfSigAndAfterByRef.GetEmbeddedSignatureData()[1].index);
+ Assert.NotEqual(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWithModOptAtStartOfSigAndAfterByRef.GetEmbeddedSignatureData()[2].index);
+ Assert.Equal("OptionalCustomModifier0.1.1.1CharOptionalCustomModifier0.1.1.2.1.1VoidOptionalCustomModifier0.1.2.1FooModifier", GetModOptMethodSignatureInfo(methodWithModOptAtStartOfSigAndAfterByRef));
+ }
+
+ [Fact]
+ public void TestSignatureMatchesModoptOnPointerOrRefModifiedType()
+ {
+ MetadataType modOptTester = _testModule.GetType("", "ModOptTester");
+ MethodSignature methodWithModOpt = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method3")).Signature;
+ Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(0), methodWithModOpt.GetEmbeddedSignatureData()[0].index);
+ Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(1), methodWithModOpt.GetEmbeddedSignatureData()[1].index);
+ Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(2), methodWithModOpt.GetEmbeddedSignatureData()[2].index);
+ }
+
[Fact]
public void TestSignatureMatches()
{
diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.DiagnosticName.cs b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.DiagnosticName.cs
new file mode 100644
index 00000000000000..0ffbdd8a4c0a09
--- /dev/null
+++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.DiagnosticName.cs
@@ -0,0 +1,28 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Internal.TypeSystem;
+
+using Xunit;
+
+
+namespace TypeSystemTests
+{
+ public partial class SyntheticVirtualOverrideTests
+ {
+ private partial class SyntheticMethod : MethodDesc
+ {
+ public override string DiagnosticName
+ {
+ get
+ {
+ return _name;
+ }
+ }
+ }
+ }
+}
diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.cs b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.cs
index 11e0741684899d..9fc3b9bf7d0d0b 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.cs
@@ -12,7 +12,7 @@
namespace TypeSystemTests
{
- public class SyntheticVirtualOverrideTests
+ public partial class SyntheticVirtualOverrideTests
{
TestTypeSystemContext _context;
ModuleDesc _testModule;
@@ -155,7 +155,7 @@ protected override IEnumerable GetAllMethods(TypeDesc type)
}
}
- private class SyntheticMethod : MethodDesc
+ private partial class SyntheticMethod : MethodDesc
{
private TypeDesc _owningType;
private MethodSignature _signature;
@@ -205,14 +205,6 @@ public override string Name
}
}
- public override string DiagnosticName
- {
- get
- {
- return _name;
- }
- }
-
public override TypeDesc OwningType
{
get
diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj
index 733bd833c140a7..cea2c969468d42 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj
+++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj
@@ -19,8 +19,7 @@
- true
- Internal.TypeSystem.SR
+ Internal.TypeSystem.Strings.resources
@@ -153,6 +152,9 @@
TypeSystem\Common\TypeSystemException.cs
+
+ TypeSystem\Common\TypeSystemException.Resources.cs
+
TypeSystem\Common\ThrowHelper.cs
diff --git a/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj b/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj
index b1e2d5a25130e8..2de5f56821453f 100644
--- a/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj
+++ b/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj
@@ -42,7 +42,7 @@
- x64
+ x64
unix
win
diff --git a/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp b/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp
index b4b51185a1f400..1a1ef6ff17bbf8 100644
--- a/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp
+++ b/src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp
@@ -26,11 +26,11 @@ class CORJIT_FLAGS
uint64_t corJitFlags;
};
-static const GUID JITEEVersionIdentifier = { /* 7af97117-55be-4c76-afb2-e26261cb140e */
- 0x7af97117,
- 0x55be,
- 0x4c76,
- { 0xaf, 0xb2, 0xe2, 0x62, 0x61, 0xcb, 0x14, 0x0e }
+static const GUID JITEEVersionIdentifier = { /* a5eec3a4-4176-43a7-8c2b-a05b551d4f49 */
+ 0xa5eec3a4,
+ 0x4176,
+ 0x43a7,
+ {0x8c, 0x2b, 0xa0, 0x5b, 0x55, 0x1d, 0x4f, 0x49}
};
class Jit
diff --git a/src/coreclr/src/tools/crossgen/CMakeLists.txt b/src/coreclr/src/tools/crossgen/CMakeLists.txt
index bf37a9cc75e573..8d861b68df52c7 100644
--- a/src/coreclr/src/tools/crossgen/CMakeLists.txt
+++ b/src/coreclr/src/tools/crossgen/CMakeLists.txt
@@ -50,7 +50,7 @@ target_link_libraries(crossgen
${CLRJIT_CROSSGEN}
gcinfo_crossgen
corzap_crossgen
- mscorlib_crossgen
+ corelib_crossgen
utilcode_crossgen
)
diff --git a/src/coreclr/src/tools/crossgen/crossgen.cpp b/src/coreclr/src/tools/crossgen/crossgen.cpp
index 41da650119d8d9..803ea5aff6e7f5 100644
--- a/src/coreclr/src/tools/crossgen/crossgen.cpp
+++ b/src/coreclr/src/tools/crossgen/crossgen.cpp
@@ -35,7 +35,7 @@ enum ReturnValues
STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzAppNiPaths, LPCWSTR pwzPdbPath, BOOL fGeneratePDBLinesInfo, LPCWSTR pwzManagedPdbSearchPath, LPCWSTR pwzDiasymreaderPath);
STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, SIZE_T customBaseAddress=0, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr);
void SetSvcLogger(ICorSvcLogger *pCorSvcLogger);
-void SetMscorlibPath(LPCWSTR wzSystemDirectory);
+void SetCoreLibPath(LPCWSTR wzSystemDirectory);
/* --------------------------------------------------------------------------- *
* Console stuff
@@ -257,7 +257,7 @@ bool StringEndsWith(LPCWSTR pwzString, LPCWSTR pwzCandidate)
// When using the Phone binding model (TrustedPlatformAssemblies), automatically
// detect which path CoreLib.[ni.]dll lies in.
//
-bool ComputeMscorlibPathFromTrustedPlatformAssemblies(SString& pwzMscorlibPath, LPCWSTR pwzTrustedPlatformAssemblies)
+bool ComputeCoreLibPathFromTrustedPlatformAssemblies(SString& pwzCoreLibPath, LPCWSTR pwzTrustedPlatformAssemblies)
{
LPWSTR wszTrustedPathCopy = new WCHAR[wcslen(pwzTrustedPlatformAssemblies) + 1];
wcscpy_s(wszTrustedPathCopy, wcslen(pwzTrustedPlatformAssemblies) + 1, pwzTrustedPlatformAssemblies);
@@ -277,11 +277,11 @@ bool ComputeMscorlibPathFromTrustedPlatformAssemblies(SString& pwzMscorlibPath,
if (StringEndsWith(wszSingleTrustedPath, DIRECTORY_SEPARATOR_STR_W CoreLibName_IL_W) ||
StringEndsWith(wszSingleTrustedPath, DIRECTORY_SEPARATOR_STR_W CoreLibName_NI_W))
{
- pwzMscorlibPath.Set(wszSingleTrustedPath);
- SString::Iterator pwzSeparator = pwzMscorlibPath.End();
+ pwzCoreLibPath.Set(wszSingleTrustedPath);
+ SString::Iterator pwzSeparator = pwzCoreLibPath.End();
bool retval = true;
- if (!SUCCEEDED(CopySystemDirectory(pwzMscorlibPath, pwzMscorlibPath)))
+ if (!SUCCEEDED(CopySystemDirectory(pwzCoreLibPath, pwzCoreLibPath)))
{
retval = false;
}
@@ -318,7 +318,7 @@ void PopulateTPAList(SString path, LPCWSTR pwszMask, SString &refTPAList, bool f
// No NIs are supported when creating NI images (other than NI of System.Private.CoreLib.dll).
if (!fCreatePDB)
{
- // Only CoreLib's ni.dll should be in the TPAList for the compilation of non-mscorlib assemblies.
+ // Only CoreLib's ni.dll should be in the TPAList for the compilation of non-CoreLib assemblies.
if (StringEndsWith((LPWSTR)pwszFilename, W(".ni.dll")))
{
fAddFileToTPAList = false;
@@ -837,10 +837,10 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
if (pwzTrustedPlatformAssemblies != nullptr)
{
- if (ComputeMscorlibPathFromTrustedPlatformAssemblies(wzTrustedPathRoot, pwzTrustedPlatformAssemblies))
+ if (ComputeCoreLibPathFromTrustedPlatformAssemblies(wzTrustedPathRoot, pwzTrustedPlatformAssemblies))
{
pwzPlatformAssembliesPaths = wzTrustedPathRoot.GetUnicode();
- SetMscorlibPath(pwzPlatformAssembliesPaths);
+ SetCoreLibPath(pwzPlatformAssembliesPaths);
}
}
diff --git a/src/coreclr/src/tools/r2rdump/TextDumper.cs b/src/coreclr/src/tools/r2rdump/TextDumper.cs
index b3bf91845f380d..19aa23f791eae5 100644
--- a/src/coreclr/src/tools/r2rdump/TextDumper.cs
+++ b/src/coreclr/src/tools/r2rdump/TextDumper.cs
@@ -217,16 +217,13 @@ internal override void DumpDisasm(RuntimeFunction rtf, int imageOffset)
if (_r2r.Machine == Machine.Amd64 && ((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes.ContainsKey(codeOffset))
{
- List codes = ((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes[codeOffset];
- foreach (ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode code in codes)
+ ILCompiler.Reflection.ReadyToRun.Amd64.UnwindCode code = ((ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo)rtf.UnwindInfo).UnwindCodes[codeOffset];
+ _writer.Write($"{indentString}{code.UnwindOp} {code.OpInfoStr}");
+ if (code.NextFrameOffset != -1)
{
- _writer.Write($"{indentString}{code.UnwindOp} {code.OpInfoStr}");
- if (code.NextFrameOffset != -1)
- {
- _writer.WriteLine($"{indentString}{code.NextFrameOffset}");
- }
- _writer.WriteLine();
+ _writer.WriteLine($"{indentString}{code.NextFrameOffset}");
}
+ _writer.WriteLine();
}
if (!_options.HideTransitions && rtf.Method.GcInfo?.Transitions != null && rtf.Method.GcInfo.Transitions.TryGetValue(codeOffset, out List transitionsForOffset))
diff --git a/src/coreclr/src/unwinder/CMakeLists.txt b/src/coreclr/src/unwinder/CMakeLists.txt
index 98cdb0c0b7a891..e9af2458140d17 100644
--- a/src/coreclr/src/unwinder/CMakeLists.txt
+++ b/src/coreclr/src/unwinder/CMakeLists.txt
@@ -20,8 +20,10 @@ list(APPEND UNWINDER_SOURCES
convert_to_absolute_path(UNWINDER_SOURCES ${UNWINDER_SOURCES})
if(CLR_CMAKE_HOST_UNIX)
- add_library_clr(unwinder_wks OBJECT ${UNWINDER_SOURCES})
- add_dependencies(unwinder_wks eventing_headers)
+ add_library_clr(unwinder_wks_obj OBJECT ${UNWINDER_SOURCES})
+ add_dependencies(unwinder_wks_obj eventing_headers)
+ add_library(unwinder_wks INTERFACE)
+ target_sources(unwinder_wks INTERFACE $)
endif(CLR_CMAKE_HOST_UNIX)
add_library_clr(unwinder_dac ${UNWINDER_SOURCES})
diff --git a/src/coreclr/src/utilcode/CMakeLists.txt b/src/coreclr/src/utilcode/CMakeLists.txt
index 4c1ce806b65101..9eeac28ae4fb71 100644
--- a/src/coreclr/src/utilcode/CMakeLists.txt
+++ b/src/coreclr/src/utilcode/CMakeLists.txt
@@ -26,7 +26,6 @@ set(UTILCODE_COMMON_SOURCES
arraylist.cpp
bitvector.cpp
comex.cpp
- delayloadhelpers.cpp
guidfromname.cpp
memorypool.cpp
iallocator.cpp
@@ -97,7 +96,9 @@ convert_to_absolute_path(UTILCODE_CROSSGEN_SOURCES ${UTILCODE_CROSSGEN_SOURCES})
convert_to_absolute_path(UTILCODE_STATICNOHOST_SOURCES ${UTILCODE_STATICNOHOST_SOURCES})
add_library_clr(utilcode_dac STATIC ${UTILCODE_DAC_SOURCES})
-add_library_clr(utilcode OBJECT ${UTILCODE_SOURCES})
+add_library_clr(utilcode_obj OBJECT ${UTILCODE_SOURCES})
+add_library(utilcode INTERFACE)
+target_sources(utilcode INTERFACE $)
add_library_clr(utilcodestaticnohost STATIC ${UTILCODE_STATICNOHOST_SOURCES})
add_library_clr(utilcode_crossgen STATIC ${UTILCODE_CROSSGEN_SOURCES})
@@ -105,9 +106,9 @@ if(CLR_CMAKE_HOST_UNIX)
target_link_libraries(utilcodestaticnohost nativeresourcestring)
target_link_libraries(utilcode_crossgen nativeresourcestring)
target_link_libraries(utilcode_dac nativeresourcestring)
- target_link_libraries(utilcode nativeresourcestring)
+ target_link_libraries(utilcode INTERFACE nativeresourcestring)
add_dependencies(utilcode_dac coreclrpal)
- add_dependencies(utilcode coreclrpal)
+ add_dependencies(utilcode_obj coreclrpal)
endif(CLR_CMAKE_HOST_UNIX)
@@ -120,10 +121,10 @@ set_target_properties(utilcode_crossgen PROPERTIES CROSSGEN_COMPONENT TRUE)
target_compile_definitions(utilcode_dac PRIVATE SELF_NO_HOST)
target_compile_definitions(utilcodestaticnohost PRIVATE SELF_NO_HOST)
add_dependencies(utilcode_dac ${UTILCODE_DEPENDENCIES})
-add_dependencies(utilcode ${UTILCODE_DEPENDENCIES})
+add_dependencies(utilcode_obj ${UTILCODE_DEPENDENCIES})
add_dependencies(utilcode_crossgen ${UTILCODE_DEPENDENCIES})
add_dependencies(utilcodestaticnohost ${UTILCODE_DEPENDENCIES})
target_precompile_header(TARGET utilcode_dac HEADER stdafx.h)
-target_precompile_header(TARGET utilcode HEADER stdafx.h)
+target_precompile_header(TARGET utilcode_obj HEADER stdafx.h)
target_precompile_header(TARGET utilcode_crossgen HEADER stdafx.h)
target_precompile_header(TARGET utilcodestaticnohost HEADER stdafx.h)
diff --git a/src/coreclr/src/utilcode/delayloadhelpers.cpp b/src/coreclr/src/utilcode/delayloadhelpers.cpp
deleted file mode 100644
index 90936ccbcfc00c..00000000000000
--- a/src/coreclr/src/utilcode/delayloadhelpers.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-//
-
-//
-// Contains convenience functionality for lazily loading modules
-// and getting entrypoints within them.
-//
-
-#include "stdafx.h"
-
-#include "crtwrap.h"
-#include "winwrap.h"
-#include "utilcode.h"
-#include "clrhost.h"
-#include "holder.h"
-#include "delayloadhelpers.h"
-
-namespace DelayLoad
-{
- //=================================================================================================================
- // Used to synchronize initialization. Is not used when initialization has already taken place.
-
- static CRITSEC_COOKIE g_pLock = nullptr;
-
- //=================================================================================================================
- // Creates and initializes g_pLock when first used.
-
- static HRESULT InitializeLock()
- {
- STATIC_CONTRACT_LIMITED_METHOD;
- HRESULT hr = S_OK;
-
- CRITSEC_COOKIE pLock = ClrCreateCriticalSection(CrstLeafLock, CRST_REENTRANCY);
- IfNullRet(pLock);
- if (InterlockedCompareExchangeT(&g_pLock, pLock, nullptr) != nullptr)
- {
- ClrDeleteCriticalSection(pLock);
- }
-
- return S_OK;
- }
-
- //=================================================================================================================
- HRESULT Module::GetValue(HMODULE *pHMODULE)
- {
- STATIC_CONTRACT_LIMITED_METHOD;
- HRESULT hr = S_OK;
-
- if (pHMODULE == nullptr)
- {
- return E_INVALIDARG;
- }
-
- if (!m_fInitialized)
- {
- IfFailRet(InitializeLock());
-
- HModuleHolder hMod = ::LoadLibraryW(m_wzDllName);
- hr = (hMod == nullptr) ? HRESULT_FROM_GetLastError() : S_OK;
- _ASSERTE(FAILED(hr) == (hMod == nullptr));
-
- { // Lock scope
- CRITSEC_Holder lock(g_pLock);
- if (!m_fInitialized)
- {
- m_hr = hr;
- m_hMod = hMod.Extract();
- m_fInitialized = true;
- }
- }
- }
-
- _ASSERTE(m_fInitialized);
- *pHMODULE = m_hMod;
- return m_hr;
- }
-
- //=================================================================================================================
- HRESULT Function::GetValue(LPVOID * ppvFunc)
- {
- STATIC_CONTRACT_LIMITED_METHOD;
- HRESULT hr = S_OK;
-
- if (ppvFunc == nullptr)
- {
- return E_INVALIDARG;
- }
-
- if (!m_fInitialized)
- {
- HMODULE hMod = nullptr;
- IfFailRet(m_pModule->GetValue(&hMod));
-
- LPVOID pvFunc = reinterpret_cast(::GetProcAddress(hMod, m_szFunctionName));
- hr = (pvFunc == nullptr) ? HRESULT_FROM_GetLastError() : S_OK;
-
- { // Lock scope
- CRITSEC_Holder lock(g_pLock);
- if (!m_fInitialized)
- {
- m_hr = hr;
- m_pvFunction = pvFunc;
- m_fInitialized = true;
- }
- }
- }
-
- _ASSERTE(m_fInitialized);
- *ppvFunc = m_pvFunction;
- return m_hr;
- }
-}
diff --git a/src/coreclr/src/utilcode/pedecoder.cpp b/src/coreclr/src/utilcode/pedecoder.cpp
index d0854bbc043fdf..91fde64d297c7b 100644
--- a/src/coreclr/src/utilcode/pedecoder.cpp
+++ b/src/coreclr/src/utilcode/pedecoder.cpp
@@ -1770,20 +1770,29 @@ void PEDecoder::LayoutILOnly(void *base, BOOL allowFullPE) const
PAGE_READONLY, &oldProtection))
ThrowLastError();
- // Finally, apply proper protection to copied sections
- section = sectionStart;
- while (section < sectionEnd)
+ // Finally, apply proper protection to copied sections
+ for (section = sectionStart; section < sectionEnd; section++)
{
// Add appropriate page protection.
- if ((section->Characteristics & VAL32(IMAGE_SCN_MEM_WRITE)) == 0)
+#if defined(CROSSGEN_COMPILE) || defined(TARGET_UNIX)
+ if (section->Characteristics & IMAGE_SCN_MEM_WRITE)
+ continue;
+
+ DWORD newProtection = PAGE_READONLY;
+#else
+ DWORD newProtection = section->Characteristics & IMAGE_SCN_MEM_EXECUTE ?
+ PAGE_EXECUTE_READ :
+ section->Characteristics & IMAGE_SCN_MEM_WRITE ?
+ PAGE_READWRITE :
+ PAGE_READONLY;
+#endif
+
+ if (!ClrVirtualProtect((void*)((BYTE*)base + VAL32(section->VirtualAddress)),
+ VAL32(section->Misc.VirtualSize),
+ newProtection, &oldProtection))
{
- if (!ClrVirtualProtect((void *) ((BYTE *)base + VAL32(section->VirtualAddress)),
- VAL32(section->Misc.VirtualSize),
- PAGE_READONLY, &oldProtection))
- ThrowLastError();
+ ThrowLastError();
}
-
- section++;
}
RETURN;
diff --git a/src/coreclr/src/utilcode/sigbuilder.cpp b/src/coreclr/src/utilcode/sigbuilder.cpp
index 111164149e7ec4..4a8f8fe6c18357 100644
--- a/src/coreclr/src/utilcode/sigbuilder.cpp
+++ b/src/coreclr/src/utilcode/sigbuilder.cpp
@@ -6,6 +6,8 @@
#include "sigbuilder.h"
#include "ex.h"
+const mdToken g_tkCorEncodeToken[4] ={mdtTypeDef, mdtTypeRef, mdtTypeSpec, mdtBaseType};
+
void SigBuilder::AppendByte(BYTE b)
{
STANDARD_VM_CONTRACT;
diff --git a/src/coreclr/src/utilcode/util.cpp b/src/coreclr/src/utilcode/util.cpp
index d697946beb8fef..ef35f09b17722e 100644
--- a/src/coreclr/src/utilcode/util.cpp
+++ b/src/coreclr/src/utilcode/util.cpp
@@ -850,6 +850,7 @@ BYTE * ClrVirtualAllocWithinRange(const BYTE *pMinAddr,
/*static*/ BOOL CPUGroupInfo::m_enableGCCPUGroups = FALSE;
/*static*/ BOOL CPUGroupInfo::m_threadUseAllCpuGroups = FALSE;
+/*static*/ BOOL CPUGroupInfo::m_threadAssignCpuGroups = FALSE;
/*static*/ WORD CPUGroupInfo::m_nGroups = 0;
/*static*/ WORD CPUGroupInfo::m_nProcessors = 0;
/*static*/ WORD CPUGroupInfo::m_initialGroup = 0;
@@ -991,6 +992,7 @@ DWORD LCM(DWORD u, DWORD v)
#if !defined(FEATURE_REDHAWK) && (defined(TARGET_AMD64) || defined(TARGET_ARM64))
BOOL enableGCCPUGroups = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_GCCpuGroup) != 0;
BOOL threadUseAllCpuGroups = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Thread_UseAllCpuGroups) != 0;
+ BOOL threadAssignCpuGroups = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Thread_AssignCpuGroups) != 0;
if (!enableGCCPUGroups)
return;
@@ -1006,10 +1008,11 @@ DWORD LCM(DWORD u, DWORD v)
CPUGroupInfo::GetThreadGroupAffinity(GetCurrentThread(), &groupAffinity);
m_initialGroup = groupAffinity.Group;
- // only enable CPU groups if more than one group exists
- BOOL hasMultipleGroups = m_nGroups > 1;
- m_enableGCCPUGroups = enableGCCPUGroups && hasMultipleGroups;
- m_threadUseAllCpuGroups = threadUseAllCpuGroups && hasMultipleGroups;
+ // only enable CPU groups if more than one group exists
+ BOOL hasMultipleGroups = m_nGroups > 1;
+ m_enableGCCPUGroups = enableGCCPUGroups && hasMultipleGroups;
+ m_threadUseAllCpuGroups = threadUseAllCpuGroups && hasMultipleGroups;
+ m_threadAssignCpuGroups = threadAssignCpuGroups && hasMultipleGroups;
#endif // TARGET_AMD64 || TARGET_ARM64
// Determine if the process is affinitized to a single processor (or if the system has a single processor)
@@ -1164,8 +1167,8 @@ DWORD LCM(DWORD u, DWORD v)
WORD i, minGroup = 0;
DWORD minWeight = 0;
- // m_enableGCCPUGroups and m_threadUseAllCpuGroups must be TRUE
- _ASSERTE(m_enableGCCPUGroups && m_threadUseAllCpuGroups);
+ // m_enableGCCPUGroups, m_threadUseAllCpuGroups, and m_threadAssignCpuGroups must be TRUE
+ _ASSERTE(m_enableGCCPUGroups && m_threadUseAllCpuGroups && m_threadAssignCpuGroups);
for (i = 0; i < m_nGroups; i++)
{
@@ -1204,8 +1207,8 @@ DWORD LCM(DWORD u, DWORD v)
{
LIMITED_METHOD_CONTRACT;
#if (defined(TARGET_AMD64) || defined(TARGET_ARM64))
- // m_enableGCCPUGroups and m_threadUseAllCpuGroups must be TRUE
- _ASSERTE(m_enableGCCPUGroups && m_threadUseAllCpuGroups);
+ // m_enableGCCPUGroups, m_threadUseAllCpuGroups, and m_threadAssignCpuGroups must be TRUE
+ _ASSERTE(m_enableGCCPUGroups && m_threadUseAllCpuGroups && m_threadAssignCpuGroups);
WORD group = gf->Group;
m_CPUGroupInfoArray[group].activeThreadWeight -= m_CPUGroupInfoArray[group].groupWeight;
@@ -1238,6 +1241,12 @@ BOOL CPUGroupInfo::GetCPUGroupRange(WORD group_number, WORD* group_begin, WORD*
LIMITED_METHOD_CONTRACT;
return m_threadUseAllCpuGroups;
}
+
+/*static*/ BOOL CPUGroupInfo::CanAssignCpuGroupsToThreads()
+{
+ LIMITED_METHOD_CONTRACT;
+ return m_threadAssignCpuGroups;
+}
#endif // HOST_WINDOWS
//******************************************************************************
diff --git a/src/coreclr/src/vm/CMakeLists.txt b/src/coreclr/src/vm/CMakeLists.txt
index 81d0e8c21b108d..83ebd3c3576e21 100644
--- a/src/coreclr/src/vm/CMakeLists.txt
+++ b/src/coreclr/src/vm/CMakeLists.txt
@@ -316,6 +316,7 @@ set(VM_SOURCES_WKS
comthreadpool.cpp
comutilnative.cpp
comwaithandle.cpp
+ corelib.cpp # true
customattribute.cpp
custommarshalerinfo.cpp
autotrace.cpp
@@ -370,7 +371,6 @@ set(VM_SOURCES_WKS
marshalnative.cpp
methodtablebuilder.cpp
mlinfo.cpp
- mscorlib.cpp # true
multicorejit.cpp # Condition="'$(FeatureMulticoreJIT)' == 'true'
multicorejitplayer.cpp # Condition="'$(FeatureMulticoreJIT)' == 'true'
nativeeventsource.cpp
@@ -379,6 +379,7 @@ set(VM_SOURCES_WKS
objectlist.cpp
olevariant.cpp
pendingload.cpp
+ processdiagnosticsprotocolhelper.cpp
profdetach.cpp
profilermetadataemitvalidator.cpp
profilingenumerators.cpp
@@ -490,7 +491,7 @@ set(VM_HEADERS_WKS
marshalnative.h
methodtablebuilder.h
mlinfo.h
- mscorlib.h
+ corelib.h
multicorejit.h
multicorejitimpl.h
nativeeventsource.h
@@ -499,6 +500,7 @@ set(VM_HEADERS_WKS
objectlist.h
olevariant.h
pendingload.h
+ processdiagnosticsprotocolhelper.h
profdetach.h
profilermetadataemitvalidator.h
profilingenumerators.h
@@ -921,7 +923,7 @@ list(APPEND VM_HEADERS_DAC
if (CLR_CMAKE_TARGET_WIN32)
list(APPEND VM_SOURCES_WKS ${VM_HEADERS_WKS})
- list(APPEND VM_SOURCES_WKS_ARCH_ASM ${VM_HEADERS_WKS_ARCH_ASM})
+ list(APPEND VM_SOURCES_WKS ${VM_HEADERS_WKS_ARCH_ASM})
list(APPEND VM_SOURCES_DAC ${VM_HEADERS_DAC})
endif(CLR_CMAKE_TARGET_WIN32)
diff --git a/src/coreclr/src/vm/ClrEtwAll.man b/src/coreclr/src/vm/ClrEtwAll.man
index c68eac52ac28ea..cf2108b4e56ac3 100644
--- a/src/coreclr/src/vm/ClrEtwAll.man
+++ b/src/coreclr/src/vm/ClrEtwAll.man
@@ -83,6 +83,8 @@
message="$(string.RuntimePublisher.CompilationDiagnosticKeywordMessage)" symbol="CLR_COMPILATIONDIAGNOSTIC_KEYWORD" />
+
@@ -401,7 +403,14 @@
-
+
+
+
+
+
+
@@ -1895,6 +1904,34 @@
+
+
+
+
+
+ %1
+ %2
+
+
+
+
+
+
+
+
+
+
+
+
+ %1
+ %2
+ %3
+ %4
+ %5
+
+
+
+
@@ -1980,6 +2017,17 @@
+
+
+
+
+
+ %1
+ %2
+
+
+
+
@@ -3200,6 +3248,7 @@
opcode="Running"
symbol="ThreadRunning"
message="$(string.RuntimePublisher.ThreadRunningEventMessage)"/>
+
+
+
+
+
-
+
+
+
+
@@ -6917,6 +6987,7 @@
+
@@ -7149,6 +7220,7 @@
+
@@ -7475,6 +7547,7 @@
+
diff --git a/src/coreclr/src/vm/amd64/AsmHelpers.asm b/src/coreclr/src/vm/amd64/AsmHelpers.asm
index cb5d1fad499d07..172b800f3feac2 100644
--- a/src/coreclr/src/vm/amd64/AsmHelpers.asm
+++ b/src/coreclr/src/vm/amd64/AsmHelpers.asm
@@ -667,27 +667,6 @@ NESTED_ENTRY ProfileTailcallNaked, _TEXT
NESTED_END ProfileTailcallNaked, _TEXT
-;; extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]);
-NESTED_ENTRY getcpuid, _TEXT
-
- push_nonvol_reg rbx
- push_nonvol_reg rsi
- END_PROLOGUE
-
- mov eax, ecx ; first arg
- mov rsi, rdx ; second arg (result)
- xor ecx, ecx ; clear ecx - needed for "Structured Extended Feature Flags"
- cpuid
- mov [rsi+ 0], eax
- mov [rsi+ 4], ebx
- mov [rsi+ 8], ecx
- mov [rsi+12], edx
- pop rsi
- pop rbx
- ret
-NESTED_END getcpuid, _TEXT
-
-
;; extern "C" DWORD __stdcall xmmYmmStateSupport();
LEAF_ENTRY xmmYmmStateSupport, _TEXT
mov ecx, 0 ; Specify xcr0
@@ -703,30 +682,6 @@ LEAF_ENTRY xmmYmmStateSupport, _TEXT
ret
LEAF_END xmmYmmStateSupport, _TEXT
-;The following function uses Deterministic Cache Parameter leafs to determine the cache hierarchy information on Prescott & Above platforms.
-; This function takes 3 arguments:
-; Arg1 is an input to ECX. Used as index to specify which cache level to return information on by CPUID.
-; Arg1 is already passed in ECX on call to getextcpuid, so no explicit assignment is required;
-; Arg2 is an input to EAX. For deterministic code enumeration, we pass in 4H in arg2.
-; Arg3 is a pointer to the return dwbuffer
-NESTED_ENTRY getextcpuid, _TEXT
- push_nonvol_reg rbx
- push_nonvol_reg rsi
- END_PROLOGUE
-
- mov eax, edx ; second arg (input to EAX)
- mov rsi, r8 ; third arg (pointer to return dwbuffer)
- cpuid
- mov [rsi+ 0], eax
- mov [rsi+ 4], ebx
- mov [rsi+ 8], ecx
- mov [rsi+12], edx
- pop rsi
- pop rbx
-
- ret
-NESTED_END getextcpuid, _TEXT
-
; EXTERN_C void moveOWord(LPVOID* src, LPVOID* target);
;
diff --git a/src/coreclr/src/vm/amd64/asmconstants.h b/src/coreclr/src/vm/amd64/asmconstants.h
index a073179f812172..8ef508e429885c 100644
--- a/src/coreclr/src/vm/amd64/asmconstants.h
+++ b/src/coreclr/src/vm/amd64/asmconstants.h
@@ -486,7 +486,7 @@ ASMCONSTANTS_C_ASSERT(OFFSET__TEB__ThreadLocalStoragePointer == offsetof(TEB, Th
#define DELEGATE_FIELD_OFFSET__METHOD_AUX 0x20
ASMCONSTANTS_RUNTIME_ASSERT(DELEGATE_FIELD_OFFSET__METHOD_AUX == Object::GetOffsetOfFirstField() +
- MscorlibBinder::GetFieldOffset(FIELD__DELEGATE__METHOD_PTR_AUX));
+ CoreLibBinder::GetFieldOffset(FIELD__DELEGATE__METHOD_PTR_AUX));
#define ASM_LARGE_OBJECT_SIZE 85000
diff --git a/src/coreclr/src/vm/amd64/asmhelpers.S b/src/coreclr/src/vm/amd64/asmhelpers.S
index 82d6984ab545df..7a70334d6383b3 100644
--- a/src/coreclr/src/vm/amd64/asmhelpers.S
+++ b/src/coreclr/src/vm/amd64/asmhelpers.S
@@ -52,17 +52,12 @@
# we can align to 16 and be guaranteed to not exceed the frame size
.equ STACK_FUDGE_FACTOR, 0x8
-# Space to keep xmm0 and xmm1
-.equ SIZEOF_FP_ARG_SPILL, 0x10*2
-
-.equ OFFSETOF_FP_ARG_SPILL, SIZEOF_PROFILE_PLATFORM_SPECIFIC_DATA + STACK_FUDGE_FACTOR
-
# SIZEOF_STACK_FRAME is how many bytes we reserve in our ELT helpers below
# There are three components, the first is space for profiler platform specific
# data struct that we spill the general purpose registers to, then space to
# spill xmm0 and xmm1, then finally 8 bytes of padding to ensure that the xmm
# register reads/writes are aligned on 16 bytes.
-.equ SIZEOF_STACK_FRAME, SIZEOF_PROFILE_PLATFORM_SPECIFIC_DATA + SIZEOF_FP_ARG_SPILL + STACK_FUDGE_FACTOR
+.equ SIZEOF_STACK_FRAME, SIZEOF_PROFILE_PLATFORM_SPECIFIC_DATA + STACK_FUDGE_FACTOR
.equ PROFILE_ENTER, 0x1
.equ PROFILE_LEAVE, 0x2
@@ -131,15 +126,6 @@ NESTED_ENTRY ProfileEnterNaked, _TEXT, NoHandler
mov r10, 0x1 # PROFILE_ENTER
mov [rsp + 0xa8], r10d # -- struct flags field
- # get aligned stack ptr (rsp + OFFSETOF_FP_ARG_SPILL) & (-16)
- lea rax, [rsp + OFFSETOF_FP_ARG_SPILL]
- and rax, -16
-
- # we need to be able to restore the fp return register
- # save fp return registers
- movdqa [rax + 0x00], xmm0
- movdqa [rax + 0x10], xmm1
-
END_PROLOGUE
# rdi already contains the clientInfo
@@ -148,10 +134,14 @@ NESTED_ENTRY ProfileEnterNaked, _TEXT, NoHandler
call C_FUNC(ProfileEnter)
# restore fp return registers
- lea rax, [rsp + OFFSETOF_FP_ARG_SPILL]
- and rax, -16
- movdqa xmm0, [rax + 0x00]
- movdqa xmm1, [rax + 0x10]
+ movsd xmm0, real8 ptr [rsp + 0x38] # -- struct flt0 field
+ movsd xmm1, real8 ptr [rsp + 0x40] # -- struct flt1 field
+ movsd xmm2, real8 ptr [rsp + 0x48] # -- struct flt2 field
+ movsd xmm3, real8 ptr [rsp + 0x50] # -- struct flt3 field
+ movsd xmm4, real8 ptr [rsp + 0x58] # -- struct flt4 field
+ movsd xmm5, real8 ptr [rsp + 0x60] # -- struct flt5 field
+ movsd xmm6, real8 ptr [rsp + 0x68] # -- struct flt6 field
+ movsd xmm7, real8 ptr [rsp + 0x70] # -- struct flt7 field
# restore arg registers
mov rdi, [rsp + 0x78]
@@ -216,15 +206,6 @@ NESTED_ENTRY ProfileLeaveNaked, _TEXT, NoHandler
mov r10, 0x2 # PROFILE_LEAVE
mov [rsp + 0xa8], r10d # flags -- struct flags field
- # get aligned stack ptr (rsp + OFFSETOF_FP_ARG_SPILL) & (-16)
- lea rax, [rsp + OFFSETOF_FP_ARG_SPILL]
- and rax, -16
-
- # we need to be able to restore the fp return register
- # save fp return registers
- movdqa [rax + 0x00], xmm0
- movdqa [rax + 0x10], xmm1
-
END_PROLOGUE
# rdi already contains the clientInfo
@@ -232,10 +213,14 @@ NESTED_ENTRY ProfileLeaveNaked, _TEXT, NoHandler
call C_FUNC(ProfileLeave)
# restore fp return registers
- lea rax, [rsp + OFFSETOF_FP_ARG_SPILL]
- and rax, -16
- movdqa xmm0, [rax + 0x00]
- movdqa xmm1, [rax + 0x10]
+ movsd xmm0, real8 ptr [rsp + 0x38] # -- struct flt0 field
+ movsd xmm1, real8 ptr [rsp + 0x40] # -- struct flt1 field
+ movsd xmm2, real8 ptr [rsp + 0x48] # -- struct flt2 field
+ movsd xmm3, real8 ptr [rsp + 0x50] # -- struct flt3 field
+ movsd xmm4, real8 ptr [rsp + 0x58] # -- struct flt4 field
+ movsd xmm5, real8 ptr [rsp + 0x60] # -- struct flt5 field
+ movsd xmm6, real8 ptr [rsp + 0x68] # -- struct flt6 field
+ movsd xmm7, real8 ptr [rsp + 0x70] # -- struct flt7 field
# restore int return register
mov rax, [rsp + 0x28]
@@ -295,15 +280,6 @@ NESTED_ENTRY ProfileTailcallNaked, _TEXT, NoHandler
mov r10, 0x2 # PROFILE_LEAVE
mov [rsp + 0xa8], r10d # flags -- struct flags field
- # get aligned stack ptr (rsp + OFFSETOF_FP_ARG_SPILL) & (-16)
- lea rax, [rsp + OFFSETOF_FP_ARG_SPILL]
- and rax, -16
-
- # we need to be able to restore the fp return register
- # save fp return registers
- movdqa [rax + 0x00], xmm0
- movdqa [rax + 0x10], xmm1
-
END_PROLOGUE
# rdi already contains the clientInfo
@@ -311,10 +287,14 @@ NESTED_ENTRY ProfileTailcallNaked, _TEXT, NoHandler
call C_FUNC(ProfileTailcall)
# restore fp return registers
- lea rax, [rsp + OFFSETOF_FP_ARG_SPILL]
- and rax, -16
- movdqa xmm0, [rax + 0x00]
- movdqa xmm1, [rax + 0x10]
+ movsd xmm0, real8 ptr [rsp + 0x38] # -- struct flt0 field
+ movsd xmm1, real8 ptr [rsp + 0x40] # -- struct flt1 field
+ movsd xmm2, real8 ptr [rsp + 0x48] # -- struct flt2 field
+ movsd xmm3, real8 ptr [rsp + 0x50] # -- struct flt3 field
+ movsd xmm4, real8 ptr [rsp + 0x58] # -- struct flt4 field
+ movsd xmm5, real8 ptr [rsp + 0x60] # -- struct flt5 field
+ movsd xmm6, real8 ptr [rsp + 0x68] # -- struct flt6 field
+ movsd xmm7, real8 ptr [rsp + 0x70] # -- struct flt7 field
# restore int return register
mov rax, [rsp + 0x28]
diff --git a/src/coreclr/src/vm/amd64/profiler.cpp b/src/coreclr/src/vm/amd64/profiler.cpp
index afe9685cda845b..025bfab6f56408 100644
--- a/src/coreclr/src/vm/amd64/profiler.cpp
+++ b/src/coreclr/src/vm/amd64/profiler.cpp
@@ -126,6 +126,7 @@ ProfileArgIterator::ProfileArgIterator(MetaSig * pSig, void * platformSpecificHa
PROFILE_PLATFORM_SPECIFIC_DATA* pData = (PROFILE_PLATFORM_SPECIFIC_DATA*)m_handle;
#ifdef UNIX_AMD64_ABI
m_bufferPos = 0;
+ ZeroMemory(pData->buffer, PROFILE_PLATFORM_SPECIFIC_DATA_BUFFER_SIZE * sizeof(UINT64));
#endif // UNIX_AMD64_ABI
// unwind a frame and get the Rsp for the profiled method to make sure it matches
@@ -483,17 +484,46 @@ LPVOID ProfileArgIterator::GetReturnBufferAddr(void)
// by our calling convention, but is required by our profiler spec.
return (LPVOID)pData->rax;
}
-
+
CorElementType t = m_argIterator.GetSig()->GetReturnType();
- if (ELEMENT_TYPE_VOID != t)
+ if (ELEMENT_TYPE_VOID == t)
+ {
+ return NULL;
+ }
+
+#ifdef UNIX_AMD64_ABI
+ if (m_argIterator.GetSig()->GetReturnTypeSize() == 16)
{
- if (ELEMENT_TYPE_R4 == t || ELEMENT_TYPE_R8 == t)
- pData->rax = pData->flt0;
+ _ASSERTE(m_bufferPos == 0 && "Nothing else should be using the scratch space during a return");
+
+ // The unix x64 ABI has a special case where a 16 byte struct will be passed in registers
+ // and if there are integer and float args it will be passed in rax/etc and xmm/etc, respectively
+ // which means the values are noncontiguous. Just like the argument passing above
+ // we copy it in to the buffer to fake it being contiguous.
+ UINT flags = m_argIterator.GetFPReturnSize();
- return &(pData->rax);
+ // The lower two bits are used to indicate whether struct args are floating point or integer
+ if (flags & 1)
+ {
+ pData->buffer[0] = pData->flt0;
+ pData->buffer[1] = (flags & 2) ? pData->flt1 : pData->rax;
+ }
+ else
+ {
+ pData->buffer[0] = pData->rax;
+ pData->buffer[1] = (flags & 2) ? pData->flt0 : pData->rdx;
+ }
+
+ return pData->buffer;
}
- else
- return NULL;
+#endif // UNIX_AMD64_ABI
+
+ if (ELEMENT_TYPE_R4 == t || ELEMENT_TYPE_R8 == t)
+ {
+ pData->rax = pData->flt0;
+ }
+
+ return &(pData->rax);
}
#undef PROFILE_ENTER
diff --git a/src/coreclr/src/vm/amd64/unixstubs.cpp b/src/coreclr/src/vm/amd64/unixstubs.cpp
index 1de9b9a5b9d112..517eea98f6b6a2 100644
--- a/src/coreclr/src/vm/amd64/unixstubs.cpp
+++ b/src/coreclr/src/vm/amd64/unixstubs.cpp
@@ -10,35 +10,26 @@ extern "C"
PORTABILITY_ASSERT("Implement for PAL");
}
- DWORD getcpuid(DWORD arg, unsigned char result[16])
+ void __cpuid(int cpuInfo[4], int function_id)
{
- DWORD eax;
- __asm(" xor %%ecx, %%ecx\n" \
- " cpuid\n" \
- " mov %%eax, 0(%[result])\n" \
- " mov %%ebx, 4(%[result])\n" \
- " mov %%ecx, 8(%[result])\n" \
- " mov %%edx, 12(%[result])\n" \
- : "=a"(eax) /*output in eax*/\
- : "a"(arg), [result]"r"(result) /*inputs - arg in eax, result in any register*/\
- : "rbx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */
- );
- return eax;
+ // Based on the Clang implementation provided in cpuid.h:
+ // https://github.com/llvm/llvm-project/blob/master/clang/lib/Headers/cpuid.h
+
+ __asm(" cpuid\n" \
+ : "=a"(cpuInfo[0]), "=b"(cpuInfo[1]), "=c"(cpuInfo[2]), "=d"(cpuInfo[3]) \
+ : "0"(function_id)
+ );
}
- DWORD getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16])
+ void __cpuidex(int cpuInfo[4], int function_id, int subFunction_id)
{
- DWORD eax;
+ // Based on the Clang implementation provided in cpuid.h:
+ // https://github.com/llvm/llvm-project/blob/master/clang/lib/Headers/cpuid.h
+
__asm(" cpuid\n" \
- " mov %%eax, 0(%[result])\n" \
- " mov %%ebx, 4(%[result])\n" \
- " mov %%ecx, 8(%[result])\n" \
- " mov %%edx, 12(%[result])\n" \
- : "=a"(eax) /*output in eax*/\
- : "c"(arg1), "a"(arg2), [result]"r"(result) /*inputs - arg1 in ecx, arg2 in eax, result in any register*/\
- : "rbx", "edx", "memory" /* registers that are clobbered, *result is clobbered */
- );
- return eax;
+ : "=a"(cpuInfo[0]), "=b"(cpuInfo[1]), "=c"(cpuInfo[2]), "=d"(cpuInfo[3]) \
+ : "0"(function_id), "2"(subFunction_id)
+ );
}
DWORD xmmYmmStateSupport()
diff --git a/src/coreclr/src/vm/appdomain.cpp b/src/coreclr/src/vm/appdomain.cpp
index 8f5b4153d8e5a0..1ba7c47cd50a15 100644
--- a/src/coreclr/src/vm/appdomain.cpp
+++ b/src/coreclr/src/vm/appdomain.cpp
@@ -928,7 +928,7 @@ OBJECTREF AppDomain::GetMissingObject()
if (!m_hndMissing)
{
// Get the field
- FieldDesc *pValueFD = MscorlibBinder::GetField(FIELD__MISSING__VALUE);
+ FieldDesc *pValueFD = CoreLibBinder::GetField(FIELD__MISSING__VALUE);
pValueFD->CheckRunClassInitThrowing();
@@ -1268,7 +1268,7 @@ void SystemDomain::Init()
DWORD size = 0;
- // Get the install directory so we can find mscorlib
+ // Get the install directory so we can find CoreLib
hr = GetInternalSystemDirectory(NULL, &size);
if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
ThrowHR(hr);
@@ -1307,7 +1307,7 @@ void SystemDomain::Init()
}
#endif
- // Finish loading mscorlib now.
+ // Finish loading CoreLib now.
m_pSystemAssembly->GetDomainAssembly()->EnsureActive();
}
@@ -1424,36 +1424,36 @@ void SystemDomain::LoadBaseSystemClasses()
// the globals in this function before finishing the load.
m_pSystemAssembly = DefaultDomain()->LoadDomainAssembly(NULL, m_pSystemFile, FILE_LOAD_POST_LOADLIBRARY)->GetCurrentAssembly();
- // Set up binder for mscorlib
- MscorlibBinder::AttachModule(m_pSystemAssembly->GetManifestModule());
+ // Set up binder for CoreLib
+ CoreLibBinder::AttachModule(m_pSystemAssembly->GetManifestModule());
// Load Object
- g_pObjectClass = MscorlibBinder::GetClass(CLASS__OBJECT);
+ g_pObjectClass = CoreLibBinder::GetClass(CLASS__OBJECT);
// Now that ObjectClass is loaded, we can set up
// the system for finalizers. There is no point in deferring this, since we need
// to know this before we allocate our first object.
- g_pObjectFinalizerMD = MscorlibBinder::GetMethod(METHOD__OBJECT__FINALIZE);
+ g_pObjectFinalizerMD = CoreLibBinder::GetMethod(METHOD__OBJECT__FINALIZE);
- g_pCanonMethodTableClass = MscorlibBinder::GetClass(CLASS____CANON);
+ g_pCanonMethodTableClass = CoreLibBinder::GetClass(CLASS____CANON);
// NOTE: !!!IMPORTANT!!! ValueType and Enum MUST be loaded one immediately after
// the other, because we have coded MethodTable::IsChildValueType
// in such a way that it depends on this behaviour.
// Load the ValueType class
- g_pValueTypeClass = MscorlibBinder::GetClass(CLASS__VALUE_TYPE);
+ g_pValueTypeClass = CoreLibBinder::GetClass(CLASS__VALUE_TYPE);
// Load the enum class
- g_pEnumClass = MscorlibBinder::GetClass(CLASS__ENUM);
+ g_pEnumClass = CoreLibBinder::GetClass(CLASS__ENUM);
_ASSERTE(!g_pEnumClass->IsValueType());
// Load System.RuntimeType
- g_pRuntimeTypeClass = MscorlibBinder::GetClass(CLASS__CLASS);
+ g_pRuntimeTypeClass = CoreLibBinder::GetClass(CLASS__CLASS);
_ASSERTE(g_pRuntimeTypeClass->IsFullyLoaded());
// Load Array class
- g_pArrayClass = MscorlibBinder::GetClass(CLASS__ARRAY);
+ g_pArrayClass = CoreLibBinder::GetClass(CLASS__ARRAY);
// Calling a method on IList for an array requires redirection to a method on
// the SZArrayHelper class. Retrieving such methods means calling
@@ -1461,31 +1461,31 @@ void SystemDomain::LoadBaseSystemClasses()
// the corresponding method on SZArrayHelper. This basically results in a class
// load due to a method call, which the debugger cannot handle, so we pre-load
// the SZArrayHelper class here.
- g_pSZArrayHelperClass = MscorlibBinder::GetClass(CLASS__SZARRAYHELPER);
+ g_pSZArrayHelperClass = CoreLibBinder::GetClass(CLASS__SZARRAYHELPER);
// Load ByReference class
//
// NOTE: ByReference must be the first by-ref-like system type to be loaded,
// because MethodTable::ClassifyEightBytesWithManagedLayout depends on it.
- g_pByReferenceClass = MscorlibBinder::GetClass(CLASS__BYREFERENCE);
+ g_pByReferenceClass = CoreLibBinder::GetClass(CLASS__BYREFERENCE);
// Load Nullable class
- g_pNullableClass = MscorlibBinder::GetClass(CLASS__NULLABLE);
+ g_pNullableClass = CoreLibBinder::GetClass(CLASS__NULLABLE);
// Load the Object array class.
g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT] = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pObjectClass));
- // We have delayed allocation of mscorlib's static handles until we load the object class
- MscorlibBinder::GetModule()->AllocateRegularStaticHandles(DefaultDomain());
+ // We have delayed allocation of CoreLib's static handles until we load the object class
+ CoreLibBinder::GetModule()->AllocateRegularStaticHandles(DefaultDomain());
// Make sure all primitive types are loaded
for (int et = ELEMENT_TYPE_VOID; et <= ELEMENT_TYPE_R8; et++)
- MscorlibBinder::LoadPrimitiveType((CorElementType)et);
+ CoreLibBinder::LoadPrimitiveType((CorElementType)et);
- MscorlibBinder::LoadPrimitiveType(ELEMENT_TYPE_I);
- MscorlibBinder::LoadPrimitiveType(ELEMENT_TYPE_U);
+ CoreLibBinder::LoadPrimitiveType(ELEMENT_TYPE_I);
+ CoreLibBinder::LoadPrimitiveType(ELEMENT_TYPE_U);
- g_TypedReferenceMT = MscorlibBinder::GetClass(CLASS__TYPED_REFERENCE);
+ g_TypedReferenceMT = CoreLibBinder::GetClass(CLASS__TYPED_REFERENCE);
// unfortunately, the following cannot be delay loaded since the jit
// uses it to compute method attributes within a function that cannot
@@ -1493,8 +1493,8 @@ void SystemDomain::LoadBaseSystemClasses()
// where a complus exception can be thrown. It is unfortunate, because
// we know that the delegate class and multidelegate class are always
// guaranteed to be found.
- g_pDelegateClass = MscorlibBinder::GetClass(CLASS__DELEGATE);
- g_pMulticastDelegateClass = MscorlibBinder::GetClass(CLASS__MULTICAST_DELEGATE);
+ g_pDelegateClass = CoreLibBinder::GetClass(CLASS__DELEGATE);
+ g_pMulticastDelegateClass = CoreLibBinder::GetClass(CLASS__MULTICAST_DELEGATE);
#ifndef CROSSGEN_COMPILE
CrossLoaderAllocatorHashSetup::EnsureTypesLoaded();
@@ -1508,45 +1508,45 @@ void SystemDomain::LoadBaseSystemClasses()
#endif // CROSSGEN_COMPILE
// used by IsImplicitInterfaceOfSZArray
- MscorlibBinder::GetClass(CLASS__IENUMERABLEGENERIC);
- MscorlibBinder::GetClass(CLASS__ICOLLECTIONGENERIC);
- MscorlibBinder::GetClass(CLASS__ILISTGENERIC);
- MscorlibBinder::GetClass(CLASS__IREADONLYCOLLECTIONGENERIC);
- MscorlibBinder::GetClass(CLASS__IREADONLYLISTGENERIC);
+ CoreLibBinder::GetClass(CLASS__IENUMERABLEGENERIC);
+ CoreLibBinder::GetClass(CLASS__ICOLLECTIONGENERIC);
+ CoreLibBinder::GetClass(CLASS__ILISTGENERIC);
+ CoreLibBinder::GetClass(CLASS__IREADONLYCOLLECTIONGENERIC);
+ CoreLibBinder::GetClass(CLASS__IREADONLYLISTGENERIC);
// Load String
- g_pStringClass = MscorlibBinder::LoadPrimitiveType(ELEMENT_TYPE_STRING);
+ g_pStringClass = CoreLibBinder::LoadPrimitiveType(ELEMENT_TYPE_STRING);
#ifdef FEATURE_UTF8STRING
// Load Utf8String
- g_pUtf8StringClass = MscorlibBinder::GetClass(CLASS__UTF8_STRING);
+ g_pUtf8StringClass = CoreLibBinder::GetClass(CLASS__UTF8_STRING);
#endif // FEATURE_UTF8STRING
#ifndef CROSSGEN_COMPILE
ECall::PopulateManagedStringConstructors();
#endif // CROSSGEN_COMPILE
- g_pExceptionClass = MscorlibBinder::GetClass(CLASS__EXCEPTION);
- g_pOutOfMemoryExceptionClass = MscorlibBinder::GetException(kOutOfMemoryException);
- g_pStackOverflowExceptionClass = MscorlibBinder::GetException(kStackOverflowException);
- g_pExecutionEngineExceptionClass = MscorlibBinder::GetException(kExecutionEngineException);
- g_pThreadAbortExceptionClass = MscorlibBinder::GetException(kThreadAbortException);
+ g_pExceptionClass = CoreLibBinder::GetClass(CLASS__EXCEPTION);
+ g_pOutOfMemoryExceptionClass = CoreLibBinder::GetException(kOutOfMemoryException);
+ g_pStackOverflowExceptionClass = CoreLibBinder::GetException(kStackOverflowException);
+ g_pExecutionEngineExceptionClass = CoreLibBinder::GetException(kExecutionEngineException);
+ g_pThreadAbortExceptionClass = CoreLibBinder::GetException(kThreadAbortException);
- g_pThreadClass = MscorlibBinder::GetClass(CLASS__THREAD);
+ g_pThreadClass = CoreLibBinder::GetClass(CLASS__THREAD);
#ifdef FEATURE_COMINTEROP
- g_pBaseCOMObject = MscorlibBinder::GetClass(CLASS__COM_OBJECT);
+ g_pBaseCOMObject = CoreLibBinder::GetClass(CLASS__COM_OBJECT);
#endif
- g_pIDynamicInterfaceCastableInterface = MscorlibBinder::GetClass(CLASS__IDYNAMICINTERFACECASTABLE);
+ g_pIDynamicInterfaceCastableInterface = CoreLibBinder::GetClass(CLASS__IDYNAMICINTERFACECASTABLE);
#ifdef FEATURE_ICASTABLE
- g_pICastableInterface = MscorlibBinder::GetClass(CLASS__ICASTABLE);
+ g_pICastableInterface = CoreLibBinder::GetClass(CLASS__ICASTABLE);
#endif // FEATURE_ICASTABLE
// Make sure that FCall mapping for Monitor.Enter is initialized. We need it in case Monitor.Enter is used only as JIT helper.
// For more details, see comment in code:JITutil_MonEnterWorker around "__me = GetEEFuncEntryPointMacro(JIT_MonEnter)".
- ECall::GetFCallImpl(MscorlibBinder::GetMethod(METHOD__MONITOR__ENTER));
+ ECall::GetFCallImpl(CoreLibBinder::GetMethod(METHOD__MONITOR__ENTER));
#ifdef PROFILING_SUPPORTED
// Note that g_profControlBlock.fBaseSystemClassesLoaded must be set to TRUE only after
@@ -1559,7 +1559,7 @@ void SystemDomain::LoadBaseSystemClasses()
#if defined(_DEBUG) && !defined(CROSSGEN_COMPILE)
if (!NingenEnabled())
{
- g_Mscorlib.Check();
+ g_CoreLib.Check();
}
#endif
@@ -1567,8 +1567,8 @@ void SystemDomain::LoadBaseSystemClasses()
if (GCStress::IsEnabled())
{
// Setting up gc coverage requires the base system classes
- // to be initialized. So we have deferred it until now for mscorlib.
- Module *pModule = MscorlibBinder::GetModule();
+ // to be initialized. So we have deferred it until now for CoreLib.
+ Module *pModule = CoreLibBinder::GetModule();
_ASSERTE(pModule->IsSystem());
if(pModule->HasNativeImage())
{
@@ -1666,7 +1666,7 @@ bool SystemDomain::IsReflectionInvocationMethod(MethodDesc* pMeth)
MethodTable* pCaller = pMeth->GetMethodTable();
- // All Reflection Invocation methods are defined in mscorlib.dll
+ // All Reflection Invocation methods are defined in CoreLib
if (!pCaller->GetModule()->IsSystem())
return false;
@@ -1707,7 +1707,7 @@ bool SystemDomain::IsReflectionInvocationMethod(MethodDesc* pMeth)
// Make sure all types are loaded so that we can use faster GetExistingClass()
for (unsigned i = 0; i < NumItems(reflectionInvocationTypes); i++)
{
- MscorlibBinder::GetClass(reflectionInvocationTypes[i]);
+ CoreLibBinder::GetClass(reflectionInvocationTypes[i]);
}
VolatileStore(&fInited, true);
@@ -1717,7 +1717,7 @@ bool SystemDomain::IsReflectionInvocationMethod(MethodDesc* pMeth)
{
for (unsigned i = 0; i < NumItems(reflectionInvocationTypes); i++)
{
- if (MscorlibBinder::GetExistingClass(reflectionInvocationTypes[i]) == pCaller)
+ if (CoreLibBinder::GetExistingClass(reflectionInvocationTypes[i]) == pCaller)
return true;
}
}
@@ -1889,7 +1889,7 @@ StackWalkAction SystemDomain::CallersMethodCallbackWithStackMark(CrawlFrame* pCf
// Skipping reflection frames. We don't need to be quite as exhaustive here
// as the security or reflection stack walking code since we know this logic
- // is only invoked for selected methods in mscorlib itself. So we're
+ // is only invoked for selected methods in CoreLib itself. So we're
// reasonably sure we won't have any sensitive methods late bound invoked on
// constructors, properties or events. This leaves being invoked via
// MethodInfo, Type or Delegate (and depending on which invoke overload is
@@ -3162,8 +3162,8 @@ DomainFile *AppDomain::LoadDomainFile(FileLoadLock *pLock, FileLoadLevel targetL
// Make sure we release the lock on exit
FileLoadLockRefHolder lockRef(pLock);
- // We need to perform the early steps of loading mscorlib without a domain transition. This is
- // important for bootstrapping purposes - we need to get mscorlib at least partially loaded
+ // We need to perform the early steps of loading CoreLib without a domain transition. This is
+ // important for bootstrapping purposes - we need to get CoreLib at least partially loaded
// into a domain before we can run serialization code to do the transition.
//
// Note that we cannot do this in general for all assemblies, because some of the security computations
@@ -3499,7 +3499,7 @@ void AppDomain::SetupSharedStatics()
// Because we are allocating/referencing objects, need to be in cooperative mode
GCX_COOP();
- DomainLocalModule *pLocalModule = MscorlibBinder::GetModule()->GetDomainLocalModule();
+ DomainLocalModule *pLocalModule = CoreLibBinder::GetModule()->GetDomainLocalModule();
// This is a convenient place to initialize String.Empty.
// It is treated as intrinsic by the JIT as so the static constructor would never run.
@@ -3508,7 +3508,7 @@ void AppDomain::SetupSharedStatics()
// String should not have any static constructors.
_ASSERTE(g_pStringClass->IsClassPreInited());
- FieldDesc * pEmptyStringFD = MscorlibBinder::GetField(FIELD__STRING__EMPTY);
+ FieldDesc * pEmptyStringFD = CoreLibBinder::GetField(FIELD__STRING__EMPTY);
OBJECTREF* pEmptyStringHandle = (OBJECTREF*)
((TADDR)pLocalModule->GetPrecomputedGCStaticsBasePointer()+pEmptyStringFD->GetOffset());
SetObjectReference( pEmptyStringHandle, StringObject::GetEmptyString());
@@ -3876,9 +3876,9 @@ BOOL AppDomain::IsCached(AssemblySpec *pSpec)
{
WRAPPER_NO_CONTRACT;
- // Check to see if this fits our rather loose idea of a reference to mscorlib.
+ // Check to see if this fits our rather loose idea of a reference to CoreLib.
// If so, don't use fusion to bind it - do it ourselves.
- if (pSpec->IsMscorlib())
+ if (pSpec->IsCoreLib())
return TRUE;
return m_AssemblyCache.Contains(pSpec);
@@ -3906,9 +3906,9 @@ PEAssembly* AppDomain::FindCachedFile(AssemblySpec* pSpec, BOOL fThrow /*=TRUE*/
}
CONTRACTL_END;
- // Check to see if this fits our rather loose idea of a reference to mscorlib.
+ // Check to see if this fits our rather loose idea of a reference to CoreLib.
// If so, don't use fusion to bind it - do it ourselves.
- if (fThrow && pSpec->IsMscorlib())
+ if (fThrow && pSpec->IsCoreLib())
{
CONSISTENCY_CHECK(SystemDomain::System()->SystemAssembly() != NULL);
PEAssembly *pFile = SystemDomain::System()->SystemFile();
@@ -4002,15 +4002,15 @@ PEAssembly * AppDomain::BindAssemblySpec(
if (bindResult.Found())
{
- if (SystemDomain::SystemFile() && bindResult.IsMscorlib())
+ if (SystemDomain::SystemFile() && bindResult.IsCoreLib())
{
- // Avoid rebinding to another copy of mscorlib
+ // Avoid rebinding to another copy of CoreLib
result = SystemDomain::SystemFile();
result.SuppressRelease(); // Didn't get a refcount
}
else
{
- // IsSystem on the PEFile should be false, even for mscorlib satellites
+ // IsSystem on the PEFile should be false, even for CoreLib satellites
result = PEAssembly::Open(&bindResult,
FALSE);
}
@@ -4034,7 +4034,7 @@ PEAssembly * AppDomain::BindAssemblySpec(
// return an assembly that does not match, and this can cause recursive resource lookups during error
// reporting. The CoreLib satellite assembly is loaded from relative locations based on the culture, see
// AssemblySpec::Bind().
- if (!pSpec->IsMscorlibSatellite())
+ if (!pSpec->IsCoreLibSatellite())
{
// Trigger the resolve event also for non-throw situation.
AssemblySpec NewSpec(this);
@@ -4258,7 +4258,7 @@ void AppDomain::RaiseLoadingAssemblyEvent(DomainAssembly *pAssembly)
EX_TRY
{
- if (MscorlibBinder::GetField(FIELD__ASSEMBLYLOADCONTEXT__ASSEMBLY_LOAD)->GetStaticOBJECTREF() != NULL)
+ if (CoreLibBinder::GetField(FIELD__ASSEMBLYLOADCONTEXT__ASSEMBLY_LOAD)->GetStaticOBJECTREF() != NULL)
{
struct _gc {
OBJECTREF orThis;
@@ -4342,7 +4342,7 @@ AppDomain::RaiseUnhandledExceptionEvent(OBJECTREF *pThrowable, BOOL isTerminatin
_ASSERTE(this == GetThread()->GetDomain());
- OBJECTREF orDelegate = MscorlibBinder::GetField(FIELD__APPCONTEXT__UNHANDLED_EXCEPTION)->GetStaticOBJECTREF();
+ OBJECTREF orDelegate = CoreLibBinder::GetField(FIELD__APPCONTEXT__UNHANDLED_EXCEPTION)->GetStaticOBJECTREF();
if (orDelegate == NULL)
return FALSE;
@@ -5346,7 +5346,7 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB
BinderTracing::ResolutionAttemptedOperation tracer{pAssemblyName, 0 /*binderID*/, pManagedAssemblyLoadContextToBindWithin, hr};
// Allocate an AssemblyName managed object
- _gcRefs.oRefAssemblyName = (ASSEMBLYNAMEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__ASSEMBLY_NAME));
+ _gcRefs.oRefAssemblyName = (ASSEMBLYNAMEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__ASSEMBLY_NAME));
// Initialize the AssemblyName object from the AssemblySpec
spec.AssemblyNameInit(&_gcRefs.oRefAssemblyName, NULL);
diff --git a/src/coreclr/src/vm/appdomain.hpp b/src/coreclr/src/vm/appdomain.hpp
index 8a73d95c8fcfc7..a84bd6a6d31b5f 100644
--- a/src/coreclr/src/vm/appdomain.hpp
+++ b/src/coreclr/src/vm/appdomain.hpp
@@ -2737,7 +2737,6 @@ class SystemDomain : public BaseDomain
#endif // DACCESS_COMPILE
//****************************************************************************************
- // Routines to deal with the base library (currently mscorlib.dll)
LPCWSTR BaseLibrary()
{
WRAPPER_NO_CONTRACT;
@@ -2750,11 +2749,11 @@ class SystemDomain : public BaseDomain
{
WRAPPER_NO_CONTRACT;
- // See if it is the installation path to mscorlib
+ // See if it is the installation path to CoreLib
if (path.EqualsCaseInsensitive(m_BaseLibrary))
return TRUE;
- // Or, it might be the GAC location of mscorlib
+ // Or, it might be the GAC location of CoreLib
if (System()->SystemAssembly() != NULL
&& path.EqualsCaseInsensitive(System()->SystemAssembly()->GetManifestFile()->GetPath()))
return TRUE;
@@ -2766,7 +2765,7 @@ class SystemDomain : public BaseDomain
{
WRAPPER_NO_CONTRACT;
- // See if it is the installation path to mscorlib.resources
+ // See if it is the installation path to corelib.resources
SString s(SString::Ascii,g_psBaseLibrarySatelliteAssemblyName);
if (path.EqualsCaseInsensitive(s))
return TRUE;
@@ -2842,7 +2841,7 @@ class SystemDomain : public BaseDomain
#ifdef FEATURE_PREJIT
protected:
- // These flags let the correct native image of mscorlib to be loaded.
+ // These flags let the correct native image of CoreLib to be loaded.
// This is important for hardbinding to it
SVAL_DECL(BOOL, s_fForceDebug);
diff --git a/src/coreclr/src/vm/appdomainnative.cpp b/src/coreclr/src/vm/appdomainnative.cpp
index 9df486ba46ff87..2a2a8c561aca3d 100644
--- a/src/coreclr/src/vm/appdomainnative.cpp
+++ b/src/coreclr/src/vm/appdomainnative.cpp
@@ -60,7 +60,7 @@ FCIMPL0(Object*, AppDomainNative::GetLoadedAssemblies)
HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
- MethodTable * pAssemblyClass = MscorlibBinder::GetClass(CLASS__ASSEMBLY);
+ MethodTable * pAssemblyClass = CoreLibBinder::GetClass(CLASS__ASSEMBLY);
AppDomain * pApp = GetAppDomain();
diff --git a/src/coreclr/src/vm/arm/asmhelpers.S b/src/coreclr/src/vm/arm/asmhelpers.S
index dbc7baa9a175c7..dcdfda4df350d6 100644
--- a/src/coreclr/src/vm/arm/asmhelpers.S
+++ b/src/coreclr/src/vm/arm/asmhelpers.S
@@ -366,134 +366,87 @@ LEAF_ENTRY JIT_ProfilerEnterLeaveTailcallStub, _TEXT
bx lr
LEAF_END JIT_ProfilerEnterLeaveTailcallStub, _TEXT
-//
-// EXTERN_C void ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID);
-//
-NESTED_ENTRY ProfileEnterNaked, _TEXT, NoHandler
- PROLOG_PUSH "{r4, r5, r7, r11, lr}"
- PROLOG_STACK_SAVE_OFFSET r7, #8
-
- // fields of PROFILE_PLATFORM_SPECIFIC_DATA, in reverse order
-
- // UINT32 r0; // Keep r0 & r1 contiguous to make returning 64-bit results easier
- // UINT32 r1;
- // void *r11;
- // void *Pc;
- // union // Float arg registers as 32-bit (s0-s15) and 64-bit (d0-d7)
- // {
- // UINT32 s[16];
- // UINT64 d[8];
- // };
- // FunctionID functionId;
- // void *probeSp; // stack pointer of managed function
- // void *profiledSp; // location of arguments on stack
- // LPVOID hiddenArg;
- // UINT32 flags;
- movw r4, #1
- push { /* flags */ r4 }
- movw r4, #0
- push { /* hiddenArg */ r4 }
- add r5, r11, #8
- push { /* profiledSp */ r5 }
- add r5, sp, #32
- push { /* probeSp */ r5 }
- push { /* functionId */ r0 }
+#define PROFILE_ENTER 1
+#define PROFILE_LEAVE 2
+#define PROFILE_TAILCALL 4
+// size of profiler data structure plus alignment padding
+#define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 104+4
+
+// typedef struct _PROFILE_PLATFORM_SPECIFIC_DATA
+// {
+// UINT32 r0; // Keep r0 & r1 contiguous to make returning 64-bit results easier
+// UINT32 r1;
+// void *R11;
+// void *Pc;
+// union // Float arg registers as 32-bit (s0-s15) and 64-bit (d0-d7)
+// {
+// UINT32 s[16];
+// UINT64 d[8];
+// };
+// FunctionID functionId;
+// void *probeSp; // stack pointer of managed function
+// void *profiledSp; // location of arguments on stack
+// LPVOID hiddenArg;
+// UINT32 flags;
+// } PROFILE_PLATFORM_SPECIFIC_DATA, *PPROFILE_PLATFORM_SPECIFIC_DATA;
+
+.macro GenerateProfileHelper helper, flags
+NESTED_ENTRY \helper\()Naked, _TEXT, NoHandler
+ PROLOG_PUSH "{r0,r3,r9,r12}"
+
+ // for the 5 arguments that do not need popped plus 4 bytes of alignment
+ alloc_stack 6*4
+
+ // push fp regs
vpush.64 { d0 - d7 }
- push { lr }
- push { r11 }
- push { /* return value, r4 is NULL */ r4 }
- push { /* return value, r4 is NULL */ r4 }
- mov r1, sp
- bl C_FUNC(ProfileEnter)
- EPILOG_STACK_RESTORE_OFFSET r7, #8
- EPILOG_POP "{r4, r5, r7, r11, pc}"
-NESTED_END ProfileEnterNaked, _TEXT
-//
-// EXTERN_C void ProfileLeaveNaked(FunctionIDOrClientID functionIDOrClientID);
-//
-NESTED_ENTRY ProfileLeaveNaked, _TEXT, NoHandler
- PROLOG_PUSH "{r1, r2, r4, r5, r7, r11, lr}"
- PROLOG_STACK_SAVE_OFFSET r7, #16
-
- // fields of PROFILE_PLATFORM_SPECIFIC_DATA, in reverse order
-
- // UINT32 r0; // Keep r0 & r1 contiguous to make returning 64-bit results easier
- // UINT32 r1;
- // void *r11;
- // void *Pc;
- // union // Float arg registers as 32-bit (s0-s15) and 64-bit (d0-d7)
- // {
- // UINT32 s[16];
- // UINT64 d[8];
- // };
- // FunctionID functionId;
- // void *probeSp; // stack pointer of managed function
- // void *profiledSp; // location of arguments on stack
- // LPVOID hiddenArg;
- // UINT32 flags;
- movw r4, #2
- push { /* flags */ r4 }
- movw r4, #0
- push { /* hiddenArg */ r4 }
- add r5, r11, #8
- push { /* profiledSp */ r5 }
- add r5, sp, #40
- push { /* probeSp */ r5 }
- push { /* functionId */ r0 }
- vpush.64 { d0 - d7 }
- push { lr }
- push { r11 }
- push { r1 }
- push { r0 }
- mov r1, sp
- bl C_FUNC(ProfileLeave)
- EPILOG_STACK_RESTORE_OFFSET r7, #16
- EPILOG_POP "{r1, r2, r4, r5, r7, r11, pc}"
-NESTED_END ProfileLeaveNaked, _TEXT
+ // next three fields pc, r11, r1
+ push { r1, r11, lr}
-//
-// EXTERN_C void ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID);
-//
-NESTED_ENTRY ProfileTailcallNaked, _TEXT, NoHandler
- PROLOG_PUSH "{r1, r2, r4, r5, r7, r11, lr}"
- PROLOG_STACK_SAVE_OFFSET r7, #16
-
- // fields of PROFILE_PLATFORM_SPECIFIC_DATA, in reverse order
-
- // UINT32 r0; // Keep r0 & r1 contiguous to make returning 64-bit results easier
- // UINT32 r1;
- // void *r11;
- // void *Pc;
- // union // Float arg registers as 32-bit (s0-s15) and 64-bit (d0-d7)
- // {
- // UINT32 s[16];
- // UINT64 d[8];
- // };
- // FunctionID functionId;
- // void *probeSp; // stack pointer of managed function
- // void *profiledSp; // location of arguments on stack
- // LPVOID hiddenArg;
- // UINT32 flags;
- movw r4, #2
- push { /* flags */ r4 }
- movw r4, #0
- push { /* hiddenArg */ r4 }
- add r5, r11, #8
- push { /* profiledSp */ r5 }
- add r5, sp, #40
- push { /* probeSp */ r5 }
- push { /* functionId */ r0 }
- vpush.64 { d0 - d7 }
- push { lr }
- push { r11 }
- push { r1 }
- push { r0 }
+ // return value is in r2 instead of r0 because functionID is passed in r0
+ push { r2 }
+
+ CHECK_STACK_ALIGNMENT
+
+ // set the other args, starting with functionID
+ str r0, [sp, #80]
+
+ // probeSp is the original sp when this stub was called
+ add r2, sp, SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA+20
+ str r2, [sp, #84]
+
+ // get the address of the arguments from the frame pointer, store in profiledSp
+ add r2, r11, #8
+ str r2, [sp, #88]
+
+ // clear hiddenArg
+ movw r2, #0
+ str r2, [sp, #92]
+
+ // set the flag to indicate what hook this is
+ movw r2, \flags
+ str r2, [sp, #96]
+
+ // sp is the address of PROFILE_PLATFORM_SPECIFIC_DATA, then call to C++
mov r1, sp
- bl C_FUNC(ProfileTailcall)
- EPILOG_STACK_RESTORE_OFFSET r7, #16
- EPILOG_POP "{r1, r2, r4, r5, r7, r11, pc}"
-NESTED_END ProfileTailcallNaked, _TEXT
+ bl C_FUNC(\helper)
+
+ // restore all our regs
+ pop { r2 }
+ pop { r1, r11, lr}
+ vpop.64 { d0 - d7 }
+
+ free_stack 6*4
+
+ EPILOG_POP "{r0,r3,r9,r12}"
+
+ bx lr
+NESTED_END \helper\()Naked, _TEXT
+.endm
+
+GenerateProfileHelper ProfileEnter, PROFILE_ENTER
+GenerateProfileHelper ProfileLeave, PROFILE_LEAVE
+GenerateProfileHelper ProfileTailcall, PROFILE_TAILCALL
#endif
diff --git a/src/coreclr/src/vm/arm/profiler.cpp b/src/coreclr/src/vm/arm/profiler.cpp
index 8bcd075fe986c4..670dedb8ca8ca1 100644
--- a/src/coreclr/src/vm/arm/profiler.cpp
+++ b/src/coreclr/src/vm/arm/profiler.cpp
@@ -144,7 +144,7 @@ Stack for the above call will look as follows (stack growing downwards):
Thread::VirtualUnwindCallFrame(&ctx);
// add the prespill register(r0-r3) size to get the stack pointer of previous function
- _ASSERTE(pData->profiledSp == (void*)(ctx.Sp - 4*4));
+ _ASSERTE(pData->profiledSp == (void*)(ctx.Sp - 4*4) || pData->profiledSp == (void*)(ctx.Sp - 6*4));
}
#endif // _DEBUG
diff --git a/src/coreclr/src/vm/arm64/asmhelpers.S b/src/coreclr/src/vm/arm64/asmhelpers.S
index 9ff8203f22f4bf..a8b0a7c07873a4 100644
--- a/src/coreclr/src/vm/arm64/asmhelpers.S
+++ b/src/coreclr/src/vm/arm64/asmhelpers.S
@@ -1200,7 +1200,7 @@ LEAF_END JIT_ProfilerEnterLeaveTailcallStub, _TEXT
#define PROFILE_ENTER 1
#define PROFILE_LEAVE 2
#define PROFILE_TAILCALL 4
-#define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 256
+#define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 272
// ------------------------------------------------------------------
.macro GenerateProfileHelper helper, flags
diff --git a/src/coreclr/src/vm/arm64/asmhelpers.asm b/src/coreclr/src/vm/arm64/asmhelpers.asm
index 1250bd32652004..2f9227b1d80df6 100644
--- a/src/coreclr/src/vm/arm64/asmhelpers.asm
+++ b/src/coreclr/src/vm/arm64/asmhelpers.asm
@@ -1427,7 +1427,7 @@ CallHelper2
#define PROFILE_ENTER 1
#define PROFILE_LEAVE 2
#define PROFILE_TAILCALL 4
- #define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 256
+ #define SIZEOF__PROFILE_PLATFORM_SPECIFIC_DATA 272
; ------------------------------------------------------------------
MACRO
diff --git a/src/coreclr/src/vm/arm64/profiler.cpp b/src/coreclr/src/vm/arm64/profiler.cpp
index 64bd9603c877b3..2b6a2e69ea51db 100644
--- a/src/coreclr/src/vm/arm64/profiler.cpp
+++ b/src/coreclr/src/vm/arm64/profiler.cpp
@@ -10,6 +10,9 @@
#define PROFILE_LEAVE 2
#define PROFILE_TAILCALL 4
+// Scratch space to store HFA return values (max 16 bytes)
+#define PROFILE_PLATFORM_SPECIFIC_DATA_BUFFER_SIZE 16
+
typedef struct _PROFILE_PLATFORM_SPECIFIC_DATA
{
void* Fp;
@@ -23,6 +26,7 @@ typedef struct _PROFILE_PLATFORM_SPECIFIC_DATA
void* hiddenArg;
UINT32 flags;
UINT32 unused;
+ BYTE buffer[PROFILE_PLATFORM_SPECIFIC_DATA_BUFFER_SIZE];
} PROFILE_PLATFORM_SPECIFIC_DATA, *PPROFILE_PLATFORM_SPECIFIC_DATA;
UINT_PTR ProfileGetIPFromPlatformSpecificHandle(void* pPlatformSpecificHandle)
@@ -45,7 +49,8 @@ void ProfileSetFunctionIDInPlatformSpecificHandle(void* pPlatformSpecificHandle,
}
ProfileArgIterator::ProfileArgIterator(MetaSig* pSig, void* pPlatformSpecificHandle)
- : m_argIterator(pSig)
+ : m_argIterator(pSig),
+ m_bufferPos(0)
{
WRAPPER_NO_CONTRACT;
@@ -235,8 +240,49 @@ LPVOID ProfileArgIterator::GetReturnBufferAddr(void)
}
}
- if (m_argIterator.GetFPReturnSize() != 0)
- {
+ UINT fpReturnSize = m_argIterator.GetFPReturnSize();
+ if (fpReturnSize != 0)
+ {
+ TypeHandle thReturnValueType;
+ m_argIterator.GetSig()->GetReturnTypeNormalized(&thReturnValueType);
+ if (!thReturnValueType.IsNull() && thReturnValueType.IsHFA())
+ {
+ UINT hfaFieldSize = fpReturnSize / 4;
+ UINT totalSize = m_argIterator.GetSig()->GetReturnTypeSize();
+ _ASSERTE(totalSize % hfaFieldSize == 0);
+ _ASSERTE(totalSize <= 16);
+
+ BYTE *dest = pData->buffer;
+ for (UINT floatRegIdx = 0; floatRegIdx < totalSize / hfaFieldSize; ++floatRegIdx)
+ {
+ if (hfaFieldSize == 4)
+ {
+ *(UINT32*)dest = *(UINT32*)&pData->floatArgumentRegisters.q[floatRegIdx];
+ dest += 4;
+ }
+ else if (hfaFieldSize == 8)
+ {
+ *(UINT64*)dest = *(UINT64*)&pData->floatArgumentRegisters.q[floatRegIdx];
+ dest += 8;
+ }
+ else
+ {
+ _ASSERTE(hfaFieldSize == 16);
+ *(NEON128*)dest = pData->floatArgumentRegisters.q[floatRegIdx];
+ dest += 16;
+ }
+
+ if (floatRegIdx > 8)
+ {
+ // There's only space for 8 arguments in buffer
+ _ASSERTE(FALSE);
+ break;
+ }
+ }
+
+ return pData->buffer;
+ }
+
return &pData->floatArgumentRegisters.q[0];
}
diff --git a/src/coreclr/src/vm/array.cpp b/src/coreclr/src/vm/array.cpp
index dd35b491e9d70f..767c2ccb0b02a4 100644
--- a/src/coreclr/src/vm/array.cpp
+++ b/src/coreclr/src/vm/array.cpp
@@ -765,7 +765,7 @@ class ArrayOpLinker : public ILStubLinker
DWORD dwTotalLocalNum = NewLocal(ELEMENT_TYPE_I4);
DWORD dwLengthLocalNum = NewLocal(ELEMENT_TYPE_I4);
- mdToken tokRawData = GetToken(MscorlibBinder::GetField(FIELD__RAW_DATA__DATA));
+ mdToken tokRawData = GetToken(CoreLibBinder::GetField(FIELD__RAW_DATA__DATA));
ILCodeLabel * pRangeExceptionLabel = NewCodeLabel();
ILCodeLabel * pRangeExceptionLabel1 = NewCodeLabel();
@@ -979,14 +979,14 @@ class ArrayOpLinker : public ILStubLinker
m_pCode->EmitLabel(pRangeExceptionLabel1); // Assumes that there is one "int" pushed on the stack
m_pCode->EmitPOP();
- mdToken tokIndexOutOfRangeCtorExcep = GetToken((MscorlibBinder::GetException(kIndexOutOfRangeException))->GetDefaultConstructor());
+ mdToken tokIndexOutOfRangeCtorExcep = GetToken((CoreLibBinder::GetException(kIndexOutOfRangeException))->GetDefaultConstructor());
m_pCode->EmitLabel(pRangeExceptionLabel);
m_pCode->EmitNEWOBJ(tokIndexOutOfRangeCtorExcep, 0);
m_pCode->EmitTHROW();
if(pTypeMismatchExceptionLabel != NULL)
{
- mdToken tokTypeMismatchExcepCtor = GetToken((MscorlibBinder::GetException(kArrayTypeMismatchException))->GetDefaultConstructor());
+ mdToken tokTypeMismatchExcepCtor = GetToken((CoreLibBinder::GetException(kArrayTypeMismatchException))->GetDefaultConstructor());
m_pCode->EmitLabel(pTypeMismatchExceptionLabel);
m_pCode->EmitNEWOBJ(tokTypeMismatchExcepCtor, 0);
@@ -1273,18 +1273,18 @@ BOOL IsImplicitInterfaceOfSZArray(MethodTable *pInterfaceMT)
PRECONDITION(pInterfaceMT->IsInterface());
PRECONDITION(pInterfaceMT->HasInstantiation());
- // Is target interface Anything in mscorlib?
+ // Is target interface Anything in CoreLib?
if (!pInterfaceMT->HasInstantiation() || !pInterfaceMT->GetModule()->IsSystem())
return FALSE;
unsigned rid = pInterfaceMT->GetTypeDefRid();
// Is target interface IList or one of its ancestors, or IReadOnlyList?
- return (rid == MscorlibBinder::GetExistingClass(CLASS__ILISTGENERIC)->GetTypeDefRid() ||
- rid == MscorlibBinder::GetExistingClass(CLASS__ICOLLECTIONGENERIC)->GetTypeDefRid() ||
- rid == MscorlibBinder::GetExistingClass(CLASS__IENUMERABLEGENERIC)->GetTypeDefRid() ||
- rid == MscorlibBinder::GetExistingClass(CLASS__IREADONLYCOLLECTIONGENERIC)->GetTypeDefRid() ||
- rid == MscorlibBinder::GetExistingClass(CLASS__IREADONLYLISTGENERIC)->GetTypeDefRid());
+ return (rid == CoreLibBinder::GetExistingClass(CLASS__ILISTGENERIC)->GetTypeDefRid() ||
+ rid == CoreLibBinder::GetExistingClass(CLASS__ICOLLECTIONGENERIC)->GetTypeDefRid() ||
+ rid == CoreLibBinder::GetExistingClass(CLASS__IENUMERABLEGENERIC)->GetTypeDefRid() ||
+ rid == CoreLibBinder::GetExistingClass(CLASS__IREADONLYCOLLECTIONGENERIC)->GetTypeDefRid() ||
+ rid == CoreLibBinder::GetExistingClass(CLASS__IREADONLYLISTGENERIC)->GetTypeDefRid());
}
//----------------------------------------------------------------------------------
@@ -1324,10 +1324,10 @@ MethodDesc* GetActualImplementationForArrayGenericIListOrIReadOnlyListMethod(Met
unsigned int inheritanceDepth = pItfcMeth->GetMethodTable()->GetNumInterfaces() - 1;
PREFIX_ASSUME(0 <= inheritanceDepth && inheritanceDepth < NumItems(startingMethod));
- MethodDesc *pGenericImplementor = MscorlibBinder::GetMethod((BinderMethodID)(startingMethod[inheritanceDepth] + slot));
+ MethodDesc *pGenericImplementor = CoreLibBinder::GetMethod((BinderMethodID)(startingMethod[inheritanceDepth] + slot));
// The most common reason for this assert is that the order of the SZArrayHelper methods in
- // mscorlib.h does not match the order they are implemented on the generic interfaces.
+ // corelib.h does not match the order they are implemented on the generic interfaces.
_ASSERTE(pGenericImplementor == MemberLoader::FindMethodByName(g_pSZArrayHelperClass, pItfcMeth->GetName()));
// OPTIMIZATION: For any method other than GetEnumerator(), we can safely substitute
diff --git a/src/coreclr/src/vm/assembly.cpp b/src/coreclr/src/vm/assembly.cpp
index 8bfb3d283a7cbc..4934ae689708cf 100644
--- a/src/coreclr/src/vm/assembly.cpp
+++ b/src/coreclr/src/vm/assembly.cpp
@@ -190,6 +190,19 @@ void Assembly::Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocat
// loading it entirely.
//CacheFriendAssemblyInfo();
+#ifndef CROSSGEN_COMPILE
+ if (IsCollectible())
+ {
+ COUNT_T size;
+ BYTE *start = (BYTE*)m_pManifest->GetFile()->GetLoadedImageContents(&size);
+ if (start != NULL)
+ {
+ GCX_COOP();
+ LoaderAllocator::AssociateMemoryWithLoaderAllocator(start, start + size, m_pLoaderAllocator);
+ }
+ }
+#endif
+
{
CANNOTTHROWCOMPLUSEXCEPTION();
FAULT_FORBID();
diff --git a/src/coreclr/src/vm/assemblyname.cpp b/src/coreclr/src/vm/assemblyname.cpp
index 60b46cfc6449a2..3ccb15140f2bf4 100644
--- a/src/coreclr/src/vm/assemblyname.cpp
+++ b/src/coreclr/src/vm/assemblyname.cpp
@@ -45,7 +45,7 @@ FCIMPL1(Object*, AssemblyNameNative::GetFileInformation, StringObject* filenameU
if (gc.filename->GetStringLength() == 0)
COMPlusThrow(kArgumentException, W("Argument_EmptyFileName"));
- gc.result = (ASSEMBLYNAMEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__ASSEMBLY_NAME));
+ gc.result = (ASSEMBLYNAMEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__ASSEMBLY_NAME));
///////////////////////////////////////////////
diff --git a/src/coreclr/src/vm/assemblynative.cpp b/src/coreclr/src/vm/assemblynative.cpp
index b5701e8bcbbec8..f73697d5a3ac0c 100644
--- a/src/coreclr/src/vm/assemblynative.cpp
+++ b/src/coreclr/src/vm/assemblynative.cpp
@@ -170,7 +170,7 @@ Assembly* AssemblyNative::LoadFromPEImage(ICLRPrivBinder* pBinderContext, PEImag
DWORD dwMessageID = IDS_EE_FILELOAD_ERROR_GENERIC;
- // Set the caller's assembly to be mscorlib
+ // Set the caller's assembly to be CoreLib
DomainAssembly *pCallersAssembly = SystemDomain::System()->SystemAssembly()->GetDomainAssembly();
PEAssembly *pParentAssembly = pCallersAssembly->GetFile();
@@ -705,7 +705,7 @@ void QCALLTYPE AssemblyNative::GetModules(QCall::AssemblyHandle pAssembly, BOOL
GCPROTECT_BEGIN(orModules);
// Return the modules
- orModules = (PTRARRAYREF)AllocateObjectArray(modules.GetCount(), MscorlibBinder::GetClass(CLASS__MODULE));
+ orModules = (PTRARRAYREF)AllocateObjectArray(modules.GetCount(), CoreLibBinder::GetClass(CLASS__MODULE));
for(COUNT_T i = 0; i < modules.GetCount(); i++)
{
@@ -889,7 +889,7 @@ void QCALLTYPE AssemblyNative::GetExportedTypes(QCall::AssemblyHandle pAssembly,
GCPROTECT_BEGIN(orTypes);
// Return the types
- orTypes = (PTRARRAYREF)AllocateObjectArray(types.GetCount(), MscorlibBinder::GetClass(CLASS__TYPE));
+ orTypes = (PTRARRAYREF)AllocateObjectArray(types.GetCount(), CoreLibBinder::GetClass(CLASS__TYPE));
for(COUNT_T i = 0; i < types.GetCount(); i++)
{
@@ -960,7 +960,7 @@ void QCALLTYPE AssemblyNative::GetForwardedTypes(QCall::AssemblyHandle pAssembly
GCPROTECT_BEGIN(orTypes);
// Return the types
- orTypes = (PTRARRAYREF)AllocateObjectArray(types.GetCount(), MscorlibBinder::GetClass(CLASS__TYPE));
+ orTypes = (PTRARRAYREF)AllocateObjectArray(types.GetCount(), CoreLibBinder::GetClass(CLASS__TYPE));
for(COUNT_T i = 0; i < types.GetCount(); i++)
{
@@ -1051,7 +1051,7 @@ FCIMPL1(Object*, AssemblyNative::GetReferencedAssemblies, AssemblyBaseObject * p
IMDInternalImport *pImport = pAssembly->GetAssembly()->GetManifestImport();
- MethodTable* pAsmNameClass = MscorlibBinder::GetClass(CLASS__ASSEMBLY_NAME);
+ MethodTable* pAsmNameClass = CoreLibBinder::GetClass(CLASS__ASSEMBLY_NAME);
HENUMInternalHolder phEnum(pImport);
DWORD dwCount = 0;
diff --git a/src/coreclr/src/vm/assemblyspec.cpp b/src/coreclr/src/vm/assemblyspec.cpp
index ad035b2daf6256..946f5856f7ca21 100644
--- a/src/coreclr/src/vm/assemblyspec.cpp
+++ b/src/coreclr/src/vm/assemblyspec.cpp
@@ -244,7 +244,7 @@ void AssemblySpec::InitializeSpec(PEAssembly * pFile)
{
// We should aways having the binding context in the PEAssembly. The only exception to this are the following:
//
- // 1) when we are here during EEStartup and loading mscorlib.dll.
+ // 1) when we are here during EEStartup and loading CoreLib.
// 2) We are dealing with dynamic assemblies
_ASSERTE((pExpectedBinder != NULL) || pFile->IsSystem() || pFile->IsDynamic());
SetBindingContext(pExpectedBinder);
@@ -423,7 +423,7 @@ void AssemblySpec::AssemblyNameInit(ASSEMBLYNAMEREF* pAsmName, PEImage* pImageIn
if ((m_context.usMajorVersion != (USHORT) -1) &&
(m_context.usMinorVersion != (USHORT) -1)) {
- MethodTable* pVersion = MscorlibBinder::GetClass(CLASS__VERSION);
+ MethodTable* pVersion = CoreLibBinder::GetClass(CLASS__VERSION);
// version
gc.Version = AllocateObject(pVersion);
@@ -495,7 +495,7 @@ void AssemblySpec::AssemblyNameInit(ASSEMBLYNAMEREF* pAsmName, PEImage* pImageIn
// cultureinfo
if (m_context.szLocale) {
- MethodTable* pCI = MscorlibBinder::GetClass(CLASS__CULTURE_INFO);
+ MethodTable* pCI = CoreLibBinder::GetClass(CLASS__CULTURE_INFO);
gc.CultureInfo = AllocateObject(pCI);
gc.Locale = StringObject::NewString(m_context.szLocale);
@@ -1029,7 +1029,7 @@ AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::LookupInter
// Check if the AssemblySpec already has specified its binding context. This will be set for assemblies that are
// attempted to be explicitly bound using AssemblyLoadContext LoadFrom* methods.
- if(!pSpec->IsAssemblySpecForMscorlib())
+ if(!pSpec->IsAssemblySpecForCoreLib())
pBinderContextForLookup = pSpec->GetBindingContext();
else
{
@@ -1046,9 +1046,9 @@ AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::LookupInter
if (fGetBindingContextFromParent)
{
- // MScorlib does not have a binding context associated with it and its lookup will only be done
+ // CoreLib does not have a binding context associated with it and its lookup will only be done
// using its AssemblySpec hash.
- if (!pSpec->IsAssemblySpecForMscorlib())
+ if (!pSpec->IsAssemblySpecForCoreLib())
{
pBinderContextForLookup = pSpec->GetBindingContextFromParentAssembly(pSpecDomain);
pSpec->SetBindingContext(pBinderContextForLookup);
@@ -1453,7 +1453,7 @@ BOOL AssemblySpecBindingCache::StoreException(AssemblySpec *pSpec, Exception* pE
pBinderToSaveException = pSpec->GetBindingContext();
if (pBinderToSaveException == NULL)
{
- if (!pSpec->IsAssemblySpecForMscorlib())
+ if (!pSpec->IsAssemblySpecForCoreLib())
{
pBinderToSaveException = pSpec->GetBindingContextFromParentAssembly(pSpec->GetAppDomain());
UINT_PTR binderID = 0;
diff --git a/src/coreclr/src/vm/baseassemblyspec.cpp b/src/coreclr/src/vm/baseassemblyspec.cpp
index 864dd2ec44b098..5a57c0ba5d3e7a 100644
--- a/src/coreclr/src/vm/baseassemblyspec.cpp
+++ b/src/coreclr/src/vm/baseassemblyspec.cpp
@@ -73,7 +73,7 @@ VOID BaseAssemblySpec::CloneFieldsToStackingAllocator( StackingAllocator* alloc)
}
#ifndef DACCESS_COMPILE
-BOOL BaseAssemblySpec::IsMscorlib()
+BOOL BaseAssemblySpec::IsCoreLib()
{
CONTRACTL
{
@@ -106,7 +106,7 @@ BOOL BaseAssemblySpec::IsMscorlib()
( (iNameLen == CoreLibNameLen) || (m_pAssemblyName[CoreLibNameLen] == ',') ) ) ) );
}
-BOOL BaseAssemblySpec::IsAssemblySpecForMscorlib()
+BOOL BaseAssemblySpec::IsAssemblySpecForCoreLib()
{
CONTRACTL
{
@@ -118,28 +118,28 @@ BOOL BaseAssemblySpec::IsAssemblySpecForMscorlib()
}
CONTRACTL_END;
- BOOL fIsAssemblySpecForMscorlib = FALSE;
+ BOOL fIsAssemblySpecForCoreLib = FALSE;
if (m_pAssemblyName)
{
size_t iNameLen = strlen(m_pAssemblyName);
- fIsAssemblySpecForMscorlib = ( (iNameLen >= CoreLibNameLen) &&
+ fIsAssemblySpecForCoreLib = ( (iNameLen >= CoreLibNameLen) &&
( (!_stricmp(m_pAssemblyName, g_psBaseLibrary)) ||
( (!_strnicmp(m_pAssemblyName, g_psBaseLibraryName, CoreLibNameLen)) &&
( (iNameLen == CoreLibNameLen) || (m_pAssemblyName[CoreLibNameLen] == ',') ) ) ) );
}
- return fIsAssemblySpecForMscorlib;
+ return fIsAssemblySpecForCoreLib;
}
-#define MSCORLIB_PUBLICKEY g_rbTheSilverlightPlatformKey
+#define CORELIB_PUBLICKEY g_rbTheSilverlightPlatformKey
-// A satellite assembly for mscorlib is named "mscorlib.resources" or
-// mscorlib.debug.resources.dll and uses the same public key as mscorlib.
+// A satellite assembly for CoreLib is named "System.Private.CoreLib.resources" or
+// System.Private.CoreLib.debug.resources.dll and uses the same public key as CoreLib.
// It does not necessarily have the same version, and the Culture will
// always be set to something like "jp-JP".
-BOOL BaseAssemblySpec::IsMscorlibSatellite() const
+BOOL BaseAssemblySpec::IsCoreLibSatellite() const
{
CONTRACTL
{
@@ -168,13 +168,13 @@ BOOL BaseAssemblySpec::IsMscorlibSatellite() const
// More of bug 213471
size_t iNameLen = strlen(m_pAssemblyName);
- // we allow name to be of the form mscorlib.resources.dll only
- BOOL r = ( (m_cbPublicKeyOrToken == sizeof(MSCORLIB_PUBLICKEY)) &&
+ // we allow name to be of the form System.Private.CoreLib.resources.dll only
+ BOOL r = ( (m_cbPublicKeyOrToken == sizeof(CORELIB_PUBLICKEY)) &&
(iNameLen >= CoreLibSatelliteNameLen) &&
(!SString::_strnicmp(m_pAssemblyName, g_psBaseLibrarySatelliteAssemblyName, CoreLibSatelliteNameLen)) &&
( (iNameLen == CoreLibSatelliteNameLen) || (m_pAssemblyName[CoreLibSatelliteNameLen] == ',') ) );
- r = r && ( memcmp(m_pbPublicKeyOrToken,MSCORLIB_PUBLICKEY,sizeof(MSCORLIB_PUBLICKEY)) == 0);
+ r = r && ( memcmp(m_pbPublicKeyOrToken,CORELIB_PUBLICKEY,sizeof(CORELIB_PUBLICKEY)) == 0);
return r;
}
diff --git a/src/coreclr/src/vm/baseassemblyspec.h b/src/coreclr/src/vm/baseassemblyspec.h
index 180ce86e119fd8..150368c1c447c3 100644
--- a/src/coreclr/src/vm/baseassemblyspec.h
+++ b/src/coreclr/src/vm/baseassemblyspec.h
@@ -79,7 +79,7 @@ class BaseAssemblySpec
return m_pBindingContext;
}
- BOOL IsAssemblySpecForMscorlib();
+ BOOL IsAssemblySpecForCoreLib();
HRESULT ParseName();
DWORD Hash();
@@ -106,8 +106,8 @@ class BaseAssemblySpec
BOOL IsStrongNamed() const;
BOOL HasPublicKey() const;
BOOL HasPublicKeyToken() const;
- BOOL IsMscorlibSatellite() const;
- BOOL IsMscorlib();
+ BOOL IsCoreLibSatellite() const;
+ BOOL IsCoreLib();
// Returns true
inline BOOL HasUniqueIdentity() const
diff --git a/src/coreclr/src/vm/baseassemblyspec.inl b/src/coreclr/src/vm/baseassemblyspec.inl
index 5a6759506f5ab5..5e1496b5986e1f 100644
--- a/src/coreclr/src/vm/baseassemblyspec.inl
+++ b/src/coreclr/src/vm/baseassemblyspec.inl
@@ -320,7 +320,7 @@ inline BOOL BaseAssemblySpec::CompareEx(BaseAssemblySpec *pSpec, DWORD dwCompare
// If the assemblySpec contains the binding context, then check if they match.
- if (!(pSpec->IsAssemblySpecForMscorlib() && IsAssemblySpecForMscorlib()))
+ if (!(pSpec->IsAssemblySpecForCoreLib() && IsAssemblySpecForCoreLib()))
{
if (!AreSameBinderInstance(pSpec->m_pBindingContext, m_pBindingContext))
{
diff --git a/src/coreclr/src/vm/binder.cpp b/src/coreclr/src/vm/binder.cpp
index bef7b479bc6031..3dbd8660596726 100644
--- a/src/coreclr/src/vm/binder.cpp
+++ b/src/coreclr/src/vm/binder.cpp
@@ -28,13 +28,13 @@
//
// Retrieve structures from ID.
//
-NOINLINE PTR_MethodTable MscorlibBinder::LookupClass(BinderClassID id)
+NOINLINE PTR_MethodTable CoreLibBinder::LookupClass(BinderClassID id)
{
WRAPPER_NO_CONTRACT;
- return (&g_Mscorlib)->LookupClassLocal(id);
+ return (&g_CoreLib)->LookupClassLocal(id);
}
-PTR_MethodTable MscorlibBinder::GetClassLocal(BinderClassID id)
+PTR_MethodTable CoreLibBinder::GetClassLocal(BinderClassID id)
{
WRAPPER_NO_CONTRACT;
@@ -44,7 +44,7 @@ PTR_MethodTable MscorlibBinder::GetClassLocal(BinderClassID id)
return pMT;
}
-PTR_MethodTable MscorlibBinder::LookupClassLocal(BinderClassID id)
+PTR_MethodTable CoreLibBinder::LookupClassLocal(BinderClassID id)
{
CONTRACTL
{
@@ -59,11 +59,11 @@ PTR_MethodTable MscorlibBinder::LookupClassLocal(BinderClassID id)
PTR_MethodTable pMT = NULL;
- // Binder methods are used for loading "known" types from mscorlib.dll. Thus they are unlikely to be part
+ // Binder methods are used for loading "known" types. Thus they are unlikely to be part
// of a recursive cycle. This is used too broadly to force manual overrides at every callsite.
OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED);
- const MscorlibClassDescription *d = m_classDescriptions + (int)id;
+ const CoreLibClassDescription *d = m_classDescriptions + (int)id;
pMT = ClassLoader::LoadTypeByNameThrowing(GetModule()->GetAssembly(), d->nameSpace, d->name).AsMethodTable();
@@ -76,13 +76,13 @@ PTR_MethodTable MscorlibBinder::LookupClassLocal(BinderClassID id)
return pMT;
}
-NOINLINE MethodDesc * MscorlibBinder::LookupMethod(BinderMethodID id)
+NOINLINE MethodDesc * CoreLibBinder::LookupMethod(BinderMethodID id)
{
WRAPPER_NO_CONTRACT;
- return (&g_Mscorlib)->LookupMethodLocal(id);
+ return (&g_CoreLib)->LookupMethodLocal(id);
}
-MethodDesc * MscorlibBinder::GetMethodLocal(BinderMethodID id)
+MethodDesc * CoreLibBinder::GetMethodLocal(BinderMethodID id)
{
WRAPPER_NO_CONTRACT;
@@ -92,7 +92,7 @@ MethodDesc * MscorlibBinder::GetMethodLocal(BinderMethodID id)
return pMD;
}
-MethodDesc * MscorlibBinder::LookupMethodLocal(BinderMethodID id)
+MethodDesc * CoreLibBinder::LookupMethodLocal(BinderMethodID id)
{
CONTRACTL
{
@@ -108,10 +108,10 @@ MethodDesc * MscorlibBinder::LookupMethodLocal(BinderMethodID id)
#ifndef DACCESS_COMPILE
MethodDesc * pMD = NULL;
- const MscorlibMethodDescription *d = m_methodDescriptions + (id - 1);
+ const CoreLibMethodDescription *d = m_methodDescriptions + (id - 1);
MethodTable * pMT = GetClassLocal(d->classID);
- _ASSERTE(pMT != NULL && "Couldn't find a type in mscorlib!");
+ _ASSERTE(pMT != NULL && "Couldn't find a type in System.Private.CoreLib!");
if (d->sig != NULL)
{
@@ -136,13 +136,13 @@ MethodDesc * MscorlibBinder::LookupMethodLocal(BinderMethodID id)
#endif
}
-NOINLINE FieldDesc * MscorlibBinder::LookupField(BinderFieldID id)
+NOINLINE FieldDesc * CoreLibBinder::LookupField(BinderFieldID id)
{
WRAPPER_NO_CONTRACT;
- return (&g_Mscorlib)->LookupFieldLocal(id);
+ return (&g_CoreLib)->LookupFieldLocal(id);
}
-FieldDesc * MscorlibBinder::GetFieldLocal(BinderFieldID id)
+FieldDesc * CoreLibBinder::GetFieldLocal(BinderFieldID id)
{
WRAPPER_NO_CONTRACT;
@@ -152,7 +152,7 @@ FieldDesc * MscorlibBinder::GetFieldLocal(BinderFieldID id)
return pFD;
}
-FieldDesc * MscorlibBinder::LookupFieldLocal(BinderFieldID id)
+FieldDesc * CoreLibBinder::LookupFieldLocal(BinderFieldID id)
{
CONTRACTL
{
@@ -167,7 +167,7 @@ FieldDesc * MscorlibBinder::LookupFieldLocal(BinderFieldID id)
FieldDesc * pFD = NULL;
- const MscorlibFieldDescription *d = m_fieldDescriptions + (id - 1);
+ const CoreLibFieldDescription *d = m_fieldDescriptions + (id - 1);
MethodTable * pMT = GetClassLocal(d->classID);
@@ -182,7 +182,7 @@ FieldDesc * MscorlibBinder::LookupFieldLocal(BinderFieldID id)
return pFD;
}
-NOINLINE PTR_MethodTable MscorlibBinder::LookupClassIfExist(BinderClassID id)
+NOINLINE PTR_MethodTable CoreLibBinder::LookupClassIfExist(BinderClassID id)
{
CONTRACTL
{
@@ -192,18 +192,18 @@ NOINLINE PTR_MethodTable MscorlibBinder::LookupClassIfExist(BinderClassID id)
MODE_ANY;
PRECONDITION(id != CLASS__NIL);
- PRECONDITION(id <= (&g_Mscorlib)->m_cClasses);
+ PRECONDITION(id <= (&g_CoreLib)->m_cClasses);
}
CONTRACTL_END;
// Run the class loader in non-load mode.
ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE();
- // Binder methods are used for loading "known" types from mscorlib.dll. Thus they are unlikely to be part
+ // Binder methods are used for loading "known" types. Thus they are unlikely to be part
// of a recursive cycle. This is used too broadly to force manual overrides at every callsite.
OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED);
- const MscorlibClassDescription *d = (&g_Mscorlib)->m_classDescriptions + (int)id;
+ const CoreLibClassDescription *d = (&g_CoreLib)->m_classDescriptions + (int)id;
PTR_MethodTable pMT = ClassLoader::LoadTypeByNameThrowing(GetModule()->GetAssembly(), d->nameSpace, d->name,
ClassLoader::ReturnNullIfNotFound, ClassLoader::DontLoadTypes, CLASS_LOAD_UNRESTOREDTYPEKEY).AsMethodTable();
@@ -212,13 +212,13 @@ NOINLINE PTR_MethodTable MscorlibBinder::LookupClassIfExist(BinderClassID id)
#ifndef DACCESS_COMPILE
if ((pMT != NULL) && pMT->IsFullyLoaded())
- VolatileStore(&(g_Mscorlib.m_pClasses[id]), pMT);
+ VolatileStore(&(g_CoreLib.m_pClasses[id]), pMT);
#endif
return pMT;
}
-Signature MscorlibBinder::GetSignature(LPHARDCODEDMETASIG pHardcodedSig)
+Signature CoreLibBinder::GetSignature(LPHARDCODEDMETASIG pHardcodedSig)
{
CONTRACTL
{
@@ -245,10 +245,10 @@ Signature MscorlibBinder::GetSignature(LPHARDCODEDMETASIG pHardcodedSig)
}
#endif
- return (&g_Mscorlib)->GetSignatureLocal(pHardcodedSig);
+ return (&g_CoreLib)->GetSignatureLocal(pHardcodedSig);
}
-Signature MscorlibBinder::GetTargetSignature(LPHARDCODEDMETASIG pHardcodedSig)
+Signature CoreLibBinder::GetTargetSignature(LPHARDCODEDMETASIG pHardcodedSig)
{
CONTRACTL
{
@@ -262,12 +262,12 @@ Signature MscorlibBinder::GetTargetSignature(LPHARDCODEDMETASIG pHardcodedSig)
#ifdef CROSSGEN_COMPILE
return GetModule()->m_pBinder->GetSignatureLocal(pHardcodedSig);
#else
- return (&g_Mscorlib)->GetSignatureLocal(pHardcodedSig);
+ return (&g_CoreLib)->GetSignatureLocal(pHardcodedSig);
#endif
}
// Get the metasig, do a one-time conversion if necessary
-Signature MscorlibBinder::GetSignatureLocal(LPHARDCODEDMETASIG pHardcodedSig)
+Signature CoreLibBinder::GetSignatureLocal(LPHARDCODEDMETASIG pHardcodedSig)
{
CONTRACTL
{
@@ -311,7 +311,7 @@ Signature MscorlibBinder::GetSignatureLocal(LPHARDCODEDMETASIG pHardcodedSig)
#ifndef DACCESS_COMPILE
-bool MscorlibBinder::ConvertType(const BYTE*& pSig, SigBuilder * pSigBuilder)
+bool CoreLibBinder::ConvertType(const BYTE*& pSig, SigBuilder * pSigBuilder)
{
bool bSomethingResolved = false;
@@ -389,7 +389,7 @@ bool MscorlibBinder::ConvertType(const BYTE*& pSig, SigBuilder * pSigBuilder)
// Resolve type references in the hardcoded metasig.
// Returns a new signature with type refences resolved.
//------------------------------------------------------------------
-void MscorlibBinder::BuildConvertedSignature(const BYTE* pSig, SigBuilder * pSigBuilder)
+void CoreLibBinder::BuildConvertedSignature(const BYTE* pSig, SigBuilder * pSigBuilder)
{
CONTRACTL
{
@@ -427,7 +427,7 @@ void MscorlibBinder::BuildConvertedSignature(const BYTE* pSig, SigBuilder * pSig
_ASSERTE(bSomethingResolved);
}
-const BYTE* MscorlibBinder::ConvertSignature(LPHARDCODEDMETASIG pHardcodedSig, const BYTE* pSig)
+const BYTE* CoreLibBinder::ConvertSignature(LPHARDCODEDMETASIG pHardcodedSig, const BYTE* pSig)
{
CONTRACTL
{
@@ -469,7 +469,7 @@ const BYTE* MscorlibBinder::ConvertSignature(LPHARDCODEDMETASIG pHardcodedSig, c
#endif // #ifndef DACCESS_COMPILE
#ifdef _DEBUG
-void MscorlibBinder::TriggerGCUnderStress()
+void CoreLibBinder::TriggerGCUnderStress()
{
CONTRACTL
{
@@ -498,7 +498,7 @@ void MscorlibBinder::TriggerGCUnderStress()
}
#endif // _DEBUG
-DWORD MscorlibBinder::GetFieldOffset(BinderFieldID id)
+DWORD CoreLibBinder::GetFieldOffset(BinderFieldID id)
{
WRAPPER_NO_CONTRACT;
@@ -507,10 +507,10 @@ DWORD MscorlibBinder::GetFieldOffset(BinderFieldID id)
#ifndef DACCESS_COMPILE
-CrstStatic MscorlibBinder::s_SigConvertCrst;
+CrstStatic CoreLibBinder::s_SigConvertCrst;
/*static*/
-void MscorlibBinder::Startup()
+void CoreLibBinder::Startup()
{
WRAPPER_NO_CONTRACT
s_SigConvertCrst.Init(CrstSigConvert);
@@ -521,20 +521,20 @@ void MscorlibBinder::Startup()
// NoClass is used to suppress check for unmanaged and managed size match
#define NoClass char[USHRT_MAX]
-const MscorlibBinder::OffsetAndSizeCheck MscorlibBinder::OffsetsAndSizes[] =
+const CoreLibBinder::OffsetAndSizeCheck CoreLibBinder::OffsetsAndSizes[] =
{
#define DEFINE_CLASS_U(nameSpace, stringName, unmanagedType) \
{ PTR_CSTR((TADDR) g_ ## nameSpace ## NS ), PTR_CUTF8((TADDR) # stringName), sizeof(unmanagedType), 0, 0, 0 },
#define DEFINE_FIELD_U(stringName, unmanagedContainingType, unmanagedOffset) \
{ 0, 0, 0, PTR_CUTF8((TADDR) # stringName), offsetof(unmanagedContainingType, unmanagedOffset), sizeof(((unmanagedContainingType*)1)->unmanagedOffset) },
- #include "mscorlib.h"
+ #include "corelib.h"
};
//
-// check the basic consistency between mscorlib and mscorwks
+// check the basic consistency between CoreLib and VM
//
-void MscorlibBinder::Check()
+void CoreLibBinder::Check()
{
STANDARD_VM_CONTRACT;
@@ -566,7 +566,7 @@ void MscorlibBinder::Check()
else
if (p->fieldName != NULL)
{
- // This assert will fire if there is DEFINE_FIELD_U macro without preceeding DEFINE_CLASS_U macro in mscorlib.h
+ // This assert will fire if there is DEFINE_FIELD_U macro without preceeding DEFINE_CLASS_U macro in corelib.h
_ASSERTE(pMT != NULL);
FieldDesc * pFD = MemberLoader::FindField(pMT, p->fieldName, NULL, 0, NULL);
@@ -876,32 +876,32 @@ static void FCallCheckSignature(MethodDesc* pMD, PCODE pImpl)
#endif // CHECK_FCALL_SIGNATURE
//
-// extended check of consistency between mscorlib and mscorwks:
-// - verifies that all references from mscorlib to mscorwks are present
-// - verifies that all references from mscorwks to mscorlib are present
+// extended check of consistency between CoreLib and VM:
+// - verifies that all references from CoreLib to VM are present
+// - verifies that all references from VM to CoreLib are present
// - limited detection of mismatches between managed and unmanaged fcall signatures
//
-void MscorlibBinder::CheckExtended()
+void CoreLibBinder::CheckExtended()
{
STANDARD_VM_CONTRACT;
- // check the consistency of BCL and VM
+ // check the consistency of CoreLib and VM
// note: it is not enabled by default because of it is time consuming and
// changes the bootstrap sequence of the EE
if (!CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ConsistencyCheck))
return;
//
- // VM referencing BCL (mscorlib.h)
+ // VM referencing CoreLib (corelib.h)
//
for (BinderClassID cID = (BinderClassID) 1; (int)cID < m_cClasses; cID = (BinderClassID) (cID + 1))
{
bool fError = false;
EX_TRY
{
- if (MscorlibBinder::GetClassName(cID) != NULL) // Allow for CorSigElement entries with no classes
+ if (CoreLibBinder::GetClassName(cID) != NULL) // Allow for CorSigElement entries with no classes
{
- if (NULL == MscorlibBinder::GetClass(cID))
+ if (NULL == CoreLibBinder::GetClass(cID))
{
fError = true;
}
@@ -915,17 +915,17 @@ void MscorlibBinder::CheckExtended()
if (fError)
{
- printf("CheckExtended: VM expects type to exist: %s.%s\n", MscorlibBinder::GetClassNameSpace(cID), MscorlibBinder::GetClassName(cID));
+ printf("CheckExtended: VM expects type to exist: %s.%s\n", CoreLibBinder::GetClassNameSpace(cID), CoreLibBinder::GetClassName(cID));
}
}
- for (BinderMethodID mID = (BinderMethodID) 1; mID < (BinderMethodID) MscorlibBinder::m_cMethods; mID = (BinderMethodID) (mID + 1))
+ for (BinderMethodID mID = (BinderMethodID) 1; mID < (BinderMethodID) CoreLibBinder::m_cMethods; mID = (BinderMethodID) (mID + 1))
{
bool fError = false;
BinderClassID cID = m_methodDescriptions[mID-1].classID;
EX_TRY
{
- if (NULL == MscorlibBinder::GetMethod(mID))
+ if (NULL == CoreLibBinder::GetMethod(mID))
{
fError = true;
}
@@ -938,17 +938,17 @@ void MscorlibBinder::CheckExtended()
if (fError)
{
- printf("CheckExtended: VM expects method to exist: %s.%s::%s\n", MscorlibBinder::GetClassNameSpace(cID), MscorlibBinder::GetClassName(cID), MscorlibBinder::GetMethodName(mID));
+ printf("CheckExtended: VM expects method to exist: %s.%s::%s\n", CoreLibBinder::GetClassNameSpace(cID), CoreLibBinder::GetClassName(cID), CoreLibBinder::GetMethodName(mID));
}
}
- for (BinderFieldID fID = (BinderFieldID) 1; fID < (BinderFieldID) MscorlibBinder::m_cFields; fID = (BinderFieldID) (fID + 1))
+ for (BinderFieldID fID = (BinderFieldID) 1; fID < (BinderFieldID) CoreLibBinder::m_cFields; fID = (BinderFieldID) (fID + 1))
{
bool fError = false;
BinderClassID cID = m_fieldDescriptions[fID-1].classID;
EX_TRY
{
- if (NULL == MscorlibBinder::GetField(fID))
+ if (NULL == CoreLibBinder::GetField(fID))
{
fError = true;
}
@@ -961,17 +961,17 @@ void MscorlibBinder::CheckExtended()
if (fError)
{
- printf("CheckExtended: VM expects field to exist: %s.%s::%s\n", MscorlibBinder::GetClassNameSpace(cID), MscorlibBinder::GetClassName(cID), MscorlibBinder::GetFieldName(fID));
+ printf("CheckExtended: VM expects field to exist: %s.%s::%s\n", CoreLibBinder::GetClassNameSpace(cID), CoreLibBinder::GetClassName(cID), CoreLibBinder::GetFieldName(fID));
}
}
//
- // BCL referencing VM (ecall.cpp)
+ // CoreLib referencing VM (ecalllist.h)
//
SetSHash usedECallIds;
HRESULT hr = S_OK;
- Module *pModule = MscorlibBinder::m_pModule;
+ Module *pModule = CoreLibBinder::m_pModule;
IMDInternalImport *pInternalImport = pModule->GetMDImport();
HENUMInternal hEnum;
@@ -1014,7 +1014,7 @@ void MscorlibBinder::CheckExtended()
{
pszClassName = pszNameSpace = "Invalid TypeDef record";
}
- printf("CheckExtended: Unable to load class from mscorlib: %s.%s\n", pszNameSpace, pszClassName);
+ printf("CheckExtended: Unable to load class from System.Private.CoreLib: %s.%s\n", pszNameSpace, pszClassName);
}
EX_END_CATCH(SwallowAllExceptions)
@@ -1099,7 +1099,7 @@ void MscorlibBinder::CheckExtended()
#define ASMCONSTANTS_RUNTIME_ASSERT(cond) _ASSERTE(cond)
#include "asmconstants.h"
- _ASSERTE(sizeof(VARIANT) == MscorlibBinder::GetClass(CLASS__NATIVEVARIANT)->GetNativeSize());
+ _ASSERTE(sizeof(VARIANT) == CoreLibBinder::GetClass(CLASS__NATIVEVARIANT)->GetNativeSize());
printf("CheckExtended: completed without exception.\n");
@@ -1109,45 +1109,45 @@ void MscorlibBinder::CheckExtended()
#endif // _DEBUG && !CROSSGEN_COMPILE
-extern const MscorlibClassDescription c_rgMscorlibClassDescriptions[];
-extern const USHORT c_nMscorlibClassDescriptions;
+extern const CoreLibClassDescription c_rgCoreLibClassDescriptions[];
+extern const USHORT c_nCoreLibClassDescriptions;
-extern const MscorlibMethodDescription c_rgMscorlibMethodDescriptions[];
-extern const USHORT c_nMscorlibMethodDescriptions;
+extern const CoreLibMethodDescription c_rgCoreLibMethodDescriptions[];
+extern const USHORT c_nCoreLibMethodDescriptions;
-extern const MscorlibFieldDescription c_rgMscorlibFieldDescriptions[];
-extern const USHORT c_nMscorlibFieldDescriptions;
+extern const CoreLibFieldDescription c_rgCoreLibFieldDescriptions[];
+extern const USHORT c_nCoreLibFieldDescriptions;
#ifdef CROSSGEN_COMPILE
-namespace CrossGenMscorlib
+namespace CrossGenCoreLib
{
- extern const MscorlibClassDescription c_rgMscorlibClassDescriptions[];
- extern const USHORT c_nMscorlibClassDescriptions;
+ extern const CoreLibClassDescription c_rgCoreLibClassDescriptions[];
+ extern const USHORT c_nCoreLibClassDescriptions;
- extern const MscorlibMethodDescription c_rgMscorlibMethodDescriptions[];
- extern const USHORT c_nMscorlibMethodDescriptions;
+ extern const CoreLibMethodDescription c_rgCoreLibMethodDescriptions[];
+ extern const USHORT c_nCoreLibMethodDescriptions;
- extern const MscorlibFieldDescription c_rgMscorlibFieldDescriptions[];
- extern const USHORT c_nMscorlibFieldDescriptions;
+ extern const CoreLibFieldDescription c_rgCoreLibFieldDescriptions[];
+ extern const USHORT c_nCoreLibFieldDescriptions;
};
#endif
-void MscorlibBinder::AttachModule(Module * pModule)
+void CoreLibBinder::AttachModule(Module * pModule)
{
STANDARD_VM_CONTRACT;
- MscorlibBinder * pGlobalBinder = &g_Mscorlib;
+ CoreLibBinder * pGlobalBinder = &g_CoreLib;
pGlobalBinder->SetDescriptions(pModule,
- c_rgMscorlibClassDescriptions, c_nMscorlibClassDescriptions,
- c_rgMscorlibMethodDescriptions, c_nMscorlibMethodDescriptions,
- c_rgMscorlibFieldDescriptions, c_nMscorlibFieldDescriptions);
+ c_rgCoreLibClassDescriptions, c_nCoreLibClassDescriptions,
+ c_rgCoreLibMethodDescriptions, c_nCoreLibMethodDescriptions,
+ c_rgCoreLibFieldDescriptions, c_nCoreLibFieldDescriptions);
#if defined(FEATURE_PREJIT) && !defined(CROSSGEN_COMPILE)
- MscorlibBinder * pPersistedBinder = pModule->m_pBinder;
+ CoreLibBinder * pPersistedBinder = pModule->m_pBinder;
if (pPersistedBinder != NULL
- // Do not use persisted binder for profiling native images. See comment in code:MscorlibBinder::Fixup.
+ // Do not use persisted binder for profiling native images. See comment in code:CoreLibBinder::Fixup.
&& !(pModule->GetNativeImage()->GetNativeVersionInfo()->wConfigFlags & CORCOMPILE_CONFIG_PROFILING))
{
pGlobalBinder->m_pClasses = pPersistedBinder->m_pClasses;
@@ -1162,14 +1162,14 @@ void MscorlibBinder::AttachModule(Module * pModule)
pGlobalBinder->AllocateTables();
#ifdef CROSSGEN_COMPILE
- MscorlibBinder * pTargetBinder = (MscorlibBinder *)(void *)
+ CoreLibBinder * pTargetBinder = (CoreLibBinder *)(void *)
pModule->GetAssembly()->GetLowFrequencyHeap()
- ->AllocMem(S_SIZE_T(sizeof(MscorlibBinder)));
+ ->AllocMem(S_SIZE_T(sizeof(CoreLibBinder)));
pTargetBinder->SetDescriptions(pModule,
- CrossGenMscorlib::c_rgMscorlibClassDescriptions, CrossGenMscorlib::c_nMscorlibClassDescriptions,
- CrossGenMscorlib::c_rgMscorlibMethodDescriptions, CrossGenMscorlib::c_nMscorlibMethodDescriptions,
- CrossGenMscorlib::c_rgMscorlibFieldDescriptions, CrossGenMscorlib::c_nMscorlibFieldDescriptions);
+ CrossGenCoreLib::c_rgCoreLibClassDescriptions, CrossGenCoreLib::c_nCoreLibClassDescriptions,
+ CrossGenCoreLib::c_rgCoreLibMethodDescriptions, CrossGenCoreLib::c_nCoreLibMethodDescriptions,
+ CrossGenCoreLib::c_rgCoreLibFieldDescriptions, CrossGenCoreLib::c_nCoreLibFieldDescriptions);
pTargetBinder->AllocateTables();
@@ -1179,10 +1179,10 @@ void MscorlibBinder::AttachModule(Module * pModule)
#endif
}
-void MscorlibBinder::SetDescriptions(Module * pModule,
- const MscorlibClassDescription * pClassDescriptions, USHORT nClasses,
- const MscorlibMethodDescription * pMethodDescriptions, USHORT nMethods,
- const MscorlibFieldDescription * pFieldDescriptions, USHORT nFields)
+void CoreLibBinder::SetDescriptions(Module * pModule,
+ const CoreLibClassDescription * pClassDescriptions, USHORT nClasses,
+ const CoreLibMethodDescription * pMethodDescriptions, USHORT nMethods,
+ const CoreLibFieldDescription * pFieldDescriptions, USHORT nFields)
{
LIMITED_METHOD_CONTRACT;
@@ -1198,7 +1198,7 @@ void MscorlibBinder::SetDescriptions(Module * pModule,
m_cFields = nFields;
}
-void MscorlibBinder::AllocateTables()
+void CoreLibBinder::AllocateTables()
{
STANDARD_VM_CONTRACT;
@@ -1220,20 +1220,20 @@ void MscorlibBinder::AllocateTables()
// ZeroMemory(m_pFields, m_cFieldRIDs * sizeof(*m_pFields));
}
-PTR_MethodTable MscorlibBinder::LoadPrimitiveType(CorElementType et)
+PTR_MethodTable CoreLibBinder::LoadPrimitiveType(CorElementType et)
{
STANDARD_VM_CONTRACT;
- PTR_MethodTable pMT = g_Mscorlib.m_pClasses[et];
+ PTR_MethodTable pMT = g_CoreLib.m_pClasses[et];
// Primitive types hit cyclic reference on binder during type loading so we have to load them in two steps
if (pMT == NULL)
{
- const MscorlibClassDescription *d = (&g_Mscorlib)->m_classDescriptions + (int)et;
+ const CoreLibClassDescription *d = (&g_CoreLib)->m_classDescriptions + (int)et;
pMT = ClassLoader::LoadTypeByNameThrowing(GetModule()->GetAssembly(), d->nameSpace, d->name,
ClassLoader::ThrowIfNotFound, ClassLoader::LoadTypes, CLASS_LOAD_APPROXPARENTS).AsMethodTable();
- g_Mscorlib.m_pClasses[et] = pMT;
+ g_CoreLib.m_pClasses[et] = pMT;
ClassLoader::EnsureLoaded(pMT);
}
@@ -1242,7 +1242,7 @@ PTR_MethodTable MscorlibBinder::LoadPrimitiveType(CorElementType et)
}
#ifdef FEATURE_NATIVE_IMAGE_GENERATION
-void MscorlibBinder::BindAll()
+void CoreLibBinder::BindAll()
{
STANDARD_VM_CONTRACT;
@@ -1259,11 +1259,11 @@ void MscorlibBinder::BindAll()
GetFieldLocal(fID);
}
-void MscorlibBinder::Save(DataImage *image)
+void CoreLibBinder::Save(DataImage *image)
{
STANDARD_VM_CONTRACT;
- image->StoreStructure(this, sizeof(MscorlibBinder),
+ image->StoreStructure(this, sizeof(CoreLibBinder),
DataImage::ITEM_BINDER);
image->StoreStructure(m_pClasses, m_cClasses * sizeof(*m_pClasses),
@@ -1276,15 +1276,15 @@ void MscorlibBinder::Save(DataImage *image)
DataImage::ITEM_BINDER_ITEMS);
}
-void MscorlibBinder::Fixup(DataImage *image)
+void CoreLibBinder::Fixup(DataImage *image)
{
STANDARD_VM_CONTRACT;
- image->FixupPointerField(this, offsetof(MscorlibBinder, m_pModule));
+ image->FixupPointerField(this, offsetof(CoreLibBinder, m_pModule));
int i;
- image->FixupPointerField(this, offsetof(MscorlibBinder, m_pClasses));
+ image->FixupPointerField(this, offsetof(CoreLibBinder, m_pClasses));
for (i = 1; i < m_cClasses; i++)
{
#if _DEBUG
@@ -1304,7 +1304,7 @@ void MscorlibBinder::Fixup(DataImage *image)
image->FixupPointerField(m_pClasses, i * sizeof(m_pClasses[0]));
}
- image->FixupPointerField(this, offsetof(MscorlibBinder, m_pMethods));
+ image->FixupPointerField(this, offsetof(CoreLibBinder, m_pMethods));
for (i = 1; i < m_cMethods; i++)
{
#if _DEBUG
@@ -1318,15 +1318,15 @@ void MscorlibBinder::Fixup(DataImage *image)
image->FixupPointerField(m_pMethods, i * sizeof(m_pMethods[0]));
}
- image->FixupPointerField(this, offsetof(MscorlibBinder, m_pFields));
+ image->FixupPointerField(this, offsetof(CoreLibBinder, m_pFields));
for (i = 1; i < m_cFields; i++)
{
image->FixupPointerField(m_pFields, i * sizeof(m_pFields[0]));
}
- image->ZeroPointerField(this, offsetof(MscorlibBinder, m_classDescriptions));
- image->ZeroPointerField(this, offsetof(MscorlibBinder, m_methodDescriptions));
- image->ZeroPointerField(this, offsetof(MscorlibBinder, m_fieldDescriptions));
+ image->ZeroPointerField(this, offsetof(CoreLibBinder, m_classDescriptions));
+ image->ZeroPointerField(this, offsetof(CoreLibBinder, m_methodDescriptions));
+ image->ZeroPointerField(this, offsetof(CoreLibBinder, m_fieldDescriptions));
}
#endif // FEATURE_NATIVE_IMAGE_GENERATION
@@ -1335,17 +1335,17 @@ void MscorlibBinder::Fixup(DataImage *image)
#ifdef DACCESS_COMPILE
void
-MscorlibBinder::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
+CoreLibBinder::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
{
SUPPORTS_DAC;
DAC_ENUM_DTHIS();
DacEnumMemoryRegion(dac_cast(m_classDescriptions),
- m_cClasses * sizeof(MscorlibClassDescription));
+ m_cClasses * sizeof(CoreLibClassDescription));
DacEnumMemoryRegion(dac_cast(m_methodDescriptions),
- (m_cMethods - 1) * sizeof(MscorlibMethodDescription));
+ (m_cMethods - 1) * sizeof(CoreLibMethodDescription));
DacEnumMemoryRegion(dac_cast(m_fieldDescriptions),
- (m_cFields - 1) * sizeof(MscorlibFieldDescription));
+ (m_cFields - 1) * sizeof(CoreLibFieldDescription));
if (m_pModule.IsValid())
{
@@ -1362,4 +1362,4 @@ MscorlibBinder::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
#endif // #ifdef DACCESS_COMPILE
-GVAL_IMPL(MscorlibBinder, g_Mscorlib);
+GVAL_IMPL(CoreLibBinder, g_CoreLib);
diff --git a/src/coreclr/src/vm/binder.h b/src/coreclr/src/vm/binder.h
index 24db64e33fd167..4ff115d2b557ea 100644
--- a/src/coreclr/src/vm/binder.h
+++ b/src/coreclr/src/vm/binder.h
@@ -33,7 +33,7 @@ struct HardCodedMetaSig
// Use the Binder objects to avoid doing unnecessary name lookup
// (esp. in the prejit case)
//
-// E.g. MscorlibBinder::GetClass(CLASS__APP_DOMAIN);
+// E.g. CoreLibBinder::GetClass(CLASS__APP_DOMAIN);
//
// BinderClassIDs are of the form CLASS__XXX
@@ -45,9 +45,9 @@ enum BinderClassID
#undef TYPEINFO
#define DEFINE_CLASS(i,n,s) CLASS__ ## i,
-#include "mscorlib.h"
+#include "corelib.h"
- CLASS__MSCORLIB_COUNT,
+ CLASS__CORELIB_COUNT,
// Aliases for element type classids
CLASS__NIL = CLASS__ELEMENT_TYPE_END,
@@ -80,9 +80,9 @@ enum BinderMethodID : int
METHOD__NIL = 0,
#define DEFINE_METHOD(c,i,s,g) METHOD__ ## c ## __ ## i,
-#include "mscorlib.h"
+#include "corelib.h"
- METHOD__MSCORLIB_COUNT,
+ METHOD__CORELIB_COUNT,
};
// BinderFieldIDs are of the form FIELD__XXX__YYY,
@@ -93,31 +93,31 @@ enum BinderFieldID
FIELD__NIL = 0,
#define DEFINE_FIELD(c,i,s) FIELD__ ## c ## __ ## i,
-#include "mscorlib.h"
+#include "corelib.h"
- FIELD__MSCORLIB_COUNT,
+ FIELD__CORELIB_COUNT,
};
-struct MscorlibClassDescription
+struct CoreLibClassDescription
{
PTR_CSTR nameSpace;
PTR_CSTR name;
};
-struct MscorlibMethodDescription
+struct CoreLibMethodDescription
{
BinderClassID classID;
PTR_CSTR name;
PTR_HARDCODEDMETASIG sig;
};
-struct MscorlibFieldDescription
+struct CoreLibFieldDescription
{
BinderClassID classID;
PTR_CSTR name;
};
-class MscorlibBinder
+class CoreLibBinder
{
public:
#ifdef DACCESS_COMPILE
@@ -134,7 +134,7 @@ class MscorlibBinder
//
// Retrieve structures from ID.
//
- // Note that none of the MscorlibBinder methods trigger static
+ // Note that none of the CoreLibBinder methods trigger static
// constructors. The JITed code takes care of triggering them.
//
static PTR_MethodTable GetClass(BinderClassID id);
@@ -189,24 +189,24 @@ class MscorlibBinder
static MethodTable *GetException(RuntimeExceptionKind kind)
{
WRAPPER_NO_CONTRACT;
- _ASSERTE(kind <= kLastExceptionInMscorlib); // Not supported for exceptions defined outside mscorlib.
- BinderClassID id = (BinderClassID) (kind + CLASS__MSCORLIB_COUNT);
+ _ASSERTE(kind < kLastException);
+ BinderClassID id = (BinderClassID) (kind + CLASS__CORELIB_COUNT);
return GetClass(id);
}
static BOOL IsException(MethodTable *pMT, RuntimeExceptionKind kind)
{
WRAPPER_NO_CONTRACT;
- _ASSERTE(kind <= kLastExceptionInMscorlib); // Not supported for exceptions defined outside mscorlib.
- BinderClassID id = (BinderClassID) (kind + CLASS__MSCORLIB_COUNT);
+ _ASSERTE(kind < kLastException);
+ BinderClassID id = (BinderClassID) (kind + CLASS__CORELIB_COUNT);
return dac_cast(GetClassIfExist(id)) == dac_cast(pMT);
}
static LPCUTF8 GetExceptionName(RuntimeExceptionKind kind)
{
WRAPPER_NO_CONTRACT;
- _ASSERTE(kind <= kLastExceptionInMscorlib); // Not supported for exceptions defined outside mscorlib.
- BinderClassID id = (BinderClassID) (kind + CLASS__MSCORLIB_COUNT);
+ _ASSERTE(kind < kLastException);
+ BinderClassID id = (BinderClassID) (kind + CLASS__CORELIB_COUNT);
return GetClassName(id);
}
@@ -281,9 +281,9 @@ class MscorlibBinder
const BYTE* ConvertSignature(LPHARDCODEDMETASIG pHardcodedSig, const BYTE* pSig);
void SetDescriptions(Module * pModule,
- const MscorlibClassDescription * pClassDescriptions, USHORT nClasses,
- const MscorlibMethodDescription * pMethodDescriptions, USHORT nMethods,
- const MscorlibFieldDescription * pFieldDescriptions, USHORT nFields);
+ const CoreLibClassDescription * pClassDescriptions, USHORT nClasses,
+ const CoreLibMethodDescription * pMethodDescriptions, USHORT nMethods,
+ const CoreLibFieldDescription * pFieldDescriptions, USHORT nFields);
void AllocateTables();
@@ -298,9 +298,9 @@ class MscorlibBinder
DPTR(PTR_FieldDesc) m_pFields;
// This is necessary to avoid embeding copy of the descriptions into mscordacwks
- DPTR(const MscorlibClassDescription) m_classDescriptions;
- DPTR(const MscorlibMethodDescription) m_methodDescriptions;
- DPTR(const MscorlibFieldDescription) m_fieldDescriptions;
+ DPTR(const CoreLibClassDescription) m_classDescriptions;
+ DPTR(const CoreLibMethodDescription) m_methodDescriptions;
+ DPTR(const CoreLibFieldDescription) m_fieldDescriptions;
USHORT m_cClasses;
USHORT m_cMethods;
@@ -330,9 +330,9 @@ class MscorlibBinder
// Global bound modules:
//
-GVAL_DECL(MscorlibBinder, g_Mscorlib);
+GVAL_DECL(CoreLibBinder, g_CoreLib);
-FORCEINLINE PTR_MethodTable MscorlibBinder::GetClass(BinderClassID id)
+FORCEINLINE PTR_MethodTable CoreLibBinder::GetClass(BinderClassID id)
{
CONTRACTL
{
@@ -341,21 +341,21 @@ FORCEINLINE PTR_MethodTable MscorlibBinder::GetClass(BinderClassID id)
INJECT_FAULT(ThrowOutOfMemory());
PRECONDITION(id != CLASS__NIL);
- PRECONDITION((&g_Mscorlib)->m_cClasses > 0); // Make sure mscorlib has been loaded.
- PRECONDITION(id <= (&g_Mscorlib)->m_cClasses);
+ PRECONDITION((&g_CoreLib)->m_cClasses > 0); // Make sure CoreLib has been loaded.
+ PRECONDITION(id <= (&g_CoreLib)->m_cClasses);
}
CONTRACTL_END;
// Force a GC here under stress because type loading could trigger GC nondeterminsticly
INDEBUG(TriggerGCUnderStress());
- PTR_MethodTable pMT = VolatileLoad(&((&g_Mscorlib)->m_pClasses[id]));
+ PTR_MethodTable pMT = VolatileLoad(&((&g_CoreLib)->m_pClasses[id]));
if (pMT == NULL)
return LookupClass(id);
return pMT;
}
-FORCEINLINE MethodDesc * MscorlibBinder::GetMethod(BinderMethodID id)
+FORCEINLINE MethodDesc * CoreLibBinder::GetMethod(BinderMethodID id)
{
CONTRACTL
{
@@ -364,20 +364,20 @@ FORCEINLINE MethodDesc * MscorlibBinder::GetMethod(BinderMethodID id)
INJECT_FAULT(ThrowOutOfMemory());
PRECONDITION(id != METHOD__NIL);
- PRECONDITION(id <= (&g_Mscorlib)->m_cMethods);
+ PRECONDITION(id <= (&g_CoreLib)->m_cMethods);
}
CONTRACTL_END;
// Force a GC here under stress because type loading could trigger GC nondeterminsticly
INDEBUG(TriggerGCUnderStress());
- MethodDesc * pMD = VolatileLoad(&((&g_Mscorlib)->m_pMethods[id]));
+ MethodDesc * pMD = VolatileLoad(&((&g_CoreLib)->m_pMethods[id]));
if (pMD == NULL)
return LookupMethod(id);
return pMD;
}
-FORCEINLINE FieldDesc * MscorlibBinder::GetField(BinderFieldID id)
+FORCEINLINE FieldDesc * CoreLibBinder::GetField(BinderFieldID id)
{
CONTRACTL
{
@@ -386,44 +386,44 @@ FORCEINLINE FieldDesc * MscorlibBinder::GetField(BinderFieldID id)
INJECT_FAULT(ThrowOutOfMemory());
PRECONDITION(id != FIELD__NIL);
- PRECONDITION(id <= (&g_Mscorlib)->m_cFields);
+ PRECONDITION(id <= (&g_CoreLib)->m_cFields);
}
CONTRACTL_END;
// Force a GC here under stress because type loading could trigger GC nondeterminsticly
INDEBUG(TriggerGCUnderStress());
- FieldDesc * pFD = VolatileLoad(&((&g_Mscorlib)->m_pFields[id]));
+ FieldDesc * pFD = VolatileLoad(&((&g_CoreLib)->m_pFields[id]));
if (pFD == NULL)
return LookupField(id);
return pFD;
}
-FORCEINLINE PTR_MethodTable MscorlibBinder::GetExistingClass(BinderClassID id)
+FORCEINLINE PTR_MethodTable CoreLibBinder::GetExistingClass(BinderClassID id)
{
LIMITED_METHOD_DAC_CONTRACT;
- PTR_MethodTable pMT = (&g_Mscorlib)->m_pClasses[id];
+ PTR_MethodTable pMT = (&g_CoreLib)->m_pClasses[id];
_ASSERTE(pMT != NULL);
return pMT;
}
-FORCEINLINE MethodDesc * MscorlibBinder::GetExistingMethod(BinderMethodID id)
+FORCEINLINE MethodDesc * CoreLibBinder::GetExistingMethod(BinderMethodID id)
{
LIMITED_METHOD_DAC_CONTRACT;
- MethodDesc * pMD = (&g_Mscorlib)->m_pMethods[id];
+ MethodDesc * pMD = (&g_CoreLib)->m_pMethods[id];
_ASSERTE(pMD != NULL);
return pMD;
}
-FORCEINLINE FieldDesc * MscorlibBinder::GetExistingField(BinderFieldID id)
+FORCEINLINE FieldDesc * CoreLibBinder::GetExistingField(BinderFieldID id)
{
LIMITED_METHOD_DAC_CONTRACT;
- FieldDesc * pFD = (&g_Mscorlib)->m_pFields[id];
+ FieldDesc * pFD = (&g_CoreLib)->m_pFields[id];
_ASSERTE(pFD != NULL);
return pFD;
}
-FORCEINLINE PTR_MethodTable MscorlibBinder::GetClassIfExist(BinderClassID id)
+FORCEINLINE PTR_MethodTable CoreLibBinder::GetClassIfExist(BinderClassID id)
{
CONTRACTL
{
@@ -433,68 +433,68 @@ FORCEINLINE PTR_MethodTable MscorlibBinder::GetClassIfExist(BinderClassID id)
MODE_ANY;
PRECONDITION(id != CLASS__NIL);
- PRECONDITION(id <= (&g_Mscorlib)->m_cClasses);
+ PRECONDITION(id <= (&g_CoreLib)->m_cClasses);
}
CONTRACTL_END;
- PTR_MethodTable pMT = VolatileLoad(&((&g_Mscorlib)->m_pClasses[id]));
+ PTR_MethodTable pMT = VolatileLoad(&((&g_CoreLib)->m_pClasses[id]));
if (pMT == NULL)
return LookupClassIfExist(id);
return pMT;
}
-FORCEINLINE PTR_Module MscorlibBinder::GetModule()
+FORCEINLINE PTR_Module CoreLibBinder::GetModule()
{
LIMITED_METHOD_DAC_CONTRACT;
- PTR_Module pModule = (&g_Mscorlib)->m_pModule;
+ PTR_Module pModule = (&g_CoreLib)->m_pModule;
_ASSERTE(pModule != NULL);
return pModule;
}
-FORCEINLINE LPCUTF8 MscorlibBinder::GetClassNameSpace(BinderClassID id)
+FORCEINLINE LPCUTF8 CoreLibBinder::GetClassNameSpace(BinderClassID id)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(id != CLASS__NIL);
- _ASSERTE(id <= (&g_Mscorlib)->m_cClasses);
- return (&g_Mscorlib)->m_classDescriptions[id].nameSpace;
+ _ASSERTE(id <= (&g_CoreLib)->m_cClasses);
+ return (&g_CoreLib)->m_classDescriptions[id].nameSpace;
}
-FORCEINLINE LPCUTF8 MscorlibBinder::GetClassName(BinderClassID id)
+FORCEINLINE LPCUTF8 CoreLibBinder::GetClassName(BinderClassID id)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(id != CLASS__NIL);
- _ASSERTE(id <= (&g_Mscorlib)->m_cClasses);
- return (&g_Mscorlib)->m_classDescriptions[id].name;
+ _ASSERTE(id <= (&g_CoreLib)->m_cClasses);
+ return (&g_CoreLib)->m_classDescriptions[id].name;
}
-FORCEINLINE LPCUTF8 MscorlibBinder::GetMethodName(BinderMethodID id)
+FORCEINLINE LPCUTF8 CoreLibBinder::GetMethodName(BinderMethodID id)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(id != METHOD__NIL);
- _ASSERTE(id <= (&g_Mscorlib)->m_cMethods);
- return (&g_Mscorlib)->m_methodDescriptions[id-1].name;
+ _ASSERTE(id <= (&g_CoreLib)->m_cMethods);
+ return (&g_CoreLib)->m_methodDescriptions[id-1].name;
}
-FORCEINLINE LPHARDCODEDMETASIG MscorlibBinder::GetMethodSig(BinderMethodID id)
+FORCEINLINE LPHARDCODEDMETASIG CoreLibBinder::GetMethodSig(BinderMethodID id)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(id != METHOD__NIL);
- _ASSERTE(id <= (&g_Mscorlib)->m_cMethods);
- return (&g_Mscorlib)->m_methodDescriptions[id-1].sig;
+ _ASSERTE(id <= (&g_CoreLib)->m_cMethods);
+ return (&g_CoreLib)->m_methodDescriptions[id-1].sig;
}
-FORCEINLINE LPCUTF8 MscorlibBinder::GetFieldName(BinderFieldID id)
+FORCEINLINE LPCUTF8 CoreLibBinder::GetFieldName(BinderFieldID id)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(id != FIELD__NIL);
- _ASSERTE(id <= (&g_Mscorlib)->m_cFields);
- return (&g_Mscorlib)->m_fieldDescriptions[id-1].name;
+ _ASSERTE(id <= (&g_CoreLib)->m_cFields);
+ return (&g_CoreLib)->m_fieldDescriptions[id-1].name;
}
#endif // _BINDERMODULE_H_
diff --git a/src/coreclr/src/vm/callcounting.cpp b/src/coreclr/src/vm/callcounting.cpp
index aadb400295cda8..8c3678bfd8536d 100644
--- a/src/coreclr/src/vm/callcounting.cpp
+++ b/src/coreclr/src/vm/callcounting.cpp
@@ -474,7 +474,16 @@ void CallCountingManager::DisableCallCounting(NativeCodeVersion codeVersion)
CodeVersionManager::LockHolder codeVersioningLockHolder;
- _ASSERTE(m_callCountingInfoByCodeVersionHash.Lookup(codeVersion) == nullptr);
+ CallCountingInfo *callCountingInfo = m_callCountingInfoByCodeVersionHash.Lookup(codeVersion);
+ if (callCountingInfo != nullptr)
+ {
+ // Call counting may already have been disabled due to the possibility of concurrent or reentering JIT of the same
+ // native code version of a method. The call counting info is created with call counting enabled or disabled and it
+ // cannot be changed thereafter for consistency in dependents of the info.
+ _ASSERTE(callCountingInfo->GetStage() == CallCountingInfo::Stage::Disabled);
+ return;
+ }
+
NewHolder callCountingInfoHolder = CallCountingInfo::CreateWithCallCountingDisabled(codeVersion);
m_callCountingInfoByCodeVersionHash.Add(callCountingInfoHolder);
callCountingInfoHolder.SuppressRelease();
@@ -815,8 +824,7 @@ void CallCountingManager::CompleteCallCounting()
{
CodeVersionManager *codeVersionManager = appDomain->GetCodeVersionManager();
- MethodDescBackpatchInfoTracker::PollForDebuggerSuspension();
- MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder;
+ MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCCoop slotBackpatchLockHolder;
// Backpatching entry point slots requires cooperative GC mode, see
// MethodDescBackpatchInfoTracker::Backpatch_Locked(). The code version manager's table lock is an unsafe lock that
@@ -947,8 +955,7 @@ void CallCountingManager::StopAndDeleteAllCallCountingStubs()
TieredCompilationManager *tieredCompilationManager = GetAppDomain()->GetTieredCompilationManager();
bool scheduleTieringBackgroundWork = false;
{
- MethodDescBackpatchInfoTracker::PollForDebuggerSuspension();
- MethodDescBackpatchInfoTracker::ConditionalLockHolder slotBackpatchLockHolder;
+ MethodDescBackpatchInfoTracker::ConditionalLockHolderForGCCoop slotBackpatchLockHolder;
ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_OTHER);
struct AutoRestartEE
diff --git a/src/coreclr/src/vm/callhelpers.cpp b/src/coreclr/src/vm/callhelpers.cpp
index 25e2cc44385e01..910cc060f74ae2 100644
--- a/src/coreclr/src/vm/callhelpers.cpp
+++ b/src/coreclr/src/vm/callhelpers.cpp
@@ -285,11 +285,11 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
_ASSERTE(!NingenEnabled() && "You cannot invoke managed code inside the ngen compilation process.");
- // If we're invoking an mscorlib method, lift the restriction on type load limits. Calls into mscorlib are
+ // If we're invoking an CoreLib method, lift the restriction on type load limits. Calls into CoreLib are
// typically calls into specific and controlled helper methods for security checks and other linktime tasks.
//
// @todo: In an ideal world, we would require each of those sites to do the override rather than disabling
- // the assert broadly here. However, by limiting the override to mscorlib methods, we should still be able
+ // the assert broadly here. However, by limiting the override to CoreLib methods, we should still be able
// to effectively enforce the more general rule about loader recursion.
MAYBE_OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED, m_pMD->GetModule()->IsSystem());
diff --git a/src/coreclr/src/vm/callhelpers.h b/src/coreclr/src/vm/callhelpers.h
index a2503f15bb10a2..4640413d2889ce 100644
--- a/src/coreclr/src/vm/callhelpers.h
+++ b/src/coreclr/src/vm/callhelpers.h
@@ -154,12 +154,12 @@ class MethodDescCallSite
#endif
public:
- // Used to avoid touching metadata for mscorlib methods.
+ // Used to avoid touching metadata for CoreLib methods.
// instance methods must pass in the 'this' object
// static methods must pass null
MethodDescCallSite(BinderMethodID id, OBJECTREF* porProtectedThis = NULL) :
m_pMD(
- MscorlibBinder::GetMethod(id)
+ CoreLibBinder::GetMethod(id)
),
m_methodSig(id),
m_argIt(&m_methodSig)
@@ -174,12 +174,12 @@ class MethodDescCallSite
DefaultInit(porProtectedThis);
}
- // Used to avoid touching metadata for mscorlib methods.
+ // Used to avoid touching metadata for CoreLib methods.
// instance methods must pass in the 'this' object
// static methods must pass null
MethodDescCallSite(BinderMethodID id, OBJECTHANDLE hThis) :
m_pMD(
- MscorlibBinder::GetMethod(id)
+ CoreLibBinder::GetMethod(id)
),
m_methodSig(id),
m_argIt(&m_methodSig)
@@ -558,14 +558,14 @@ enum DispatchCallSimpleFlags
PCODE __pSlot = VolatileLoad(&s_pAddr##id); \
if ( __pSlot == NULL ) \
{ \
- MethodDesc *pMeth = MscorlibBinder::GetMethod(id); \
+ MethodDesc *pMeth = CoreLibBinder::GetMethod(id); \
_ASSERTE(pMeth); \
__pSlot = pMeth->GetMultiCallableAddrOfCode(); \
VolatileStore(&s_pAddr##id, __pSlot); \
}
#define PREPARE_VIRTUAL_CALLSITE(id, objref) \
- MethodDesc *__pMeth = MscorlibBinder::GetMethod(id); \
+ MethodDesc *__pMeth = CoreLibBinder::GetMethod(id); \
PCODE __pSlot = __pMeth->GetCallTarget(&objref);
#define PREPARE_VIRTUAL_CALLSITE_USING_METHODDESC(pMD, objref) \
@@ -590,7 +590,7 @@ enum DispatchCallSimpleFlags
WORD __slot = VolatileLoad(&s_slot##id); \
if (__slot == MethodTable::NO_SLOT) \
{ \
- MethodDesc *pMeth = MscorlibBinder::GetMethod(id); \
+ MethodDesc *pMeth = CoreLibBinder::GetMethod(id); \
_ASSERTE(pMeth); \
__slot = pMeth->GetSlot(); \
VolatileStore(&s_slot##id, __slot); \
diff --git a/src/coreclr/src/vm/callsiteinspect.cpp b/src/coreclr/src/vm/callsiteinspect.cpp
index eeb9678e9655a4..3773580bd0a5c6 100644
--- a/src/coreclr/src/vm/callsiteinspect.cpp
+++ b/src/coreclr/src/vm/callsiteinspect.cpp
@@ -53,7 +53,7 @@ namespace
if (ELEMENT_TYPE_PTR == eType)
COMPlusThrow(kNotSupportedException);
- MethodTable *pMT = MscorlibBinder::GetElementType(eType);
+ MethodTable *pMT = CoreLibBinder::GetElementType(eType);
OBJECTREF pObj = pMT->Allocate();
if (fIsByRef)
@@ -337,7 +337,7 @@ void CallsiteInspect::GetCallsiteArgs(
// Allocate all needed arrays for callsite arg details
gc.Args = (PTRARRAYREF)AllocateObjectArray(numArgs, g_pObjectClass);
- MethodTable *typeMT = MscorlibBinder::GetClass(CLASS__TYPE);
+ MethodTable *typeMT = CoreLibBinder::GetClass(CLASS__TYPE);
gc.ArgsTypes = (PTRARRAYREF)AllocateObjectArray(numArgs, typeMT);
gc.ArgsIsByRef = (BOOLARRAYREF)AllocatePrimitiveArray(ELEMENT_TYPE_BOOLEAN, numArgs);
diff --git a/src/coreclr/src/vm/castcache.cpp b/src/coreclr/src/vm/castcache.cpp
index b4a20162675255..6613c6fe5c9b31 100644
--- a/src/coreclr/src/vm/castcache.cpp
+++ b/src/coreclr/src/vm/castcache.cpp
@@ -124,7 +124,7 @@ void CastCache::Initialize()
}
CONTRACTL_END;
- FieldDesc* pTableField = MscorlibBinder::GetField(FIELD__CASTHELPERS__TABLE);
+ FieldDesc* pTableField = CoreLibBinder::GetField(FIELD__CASTHELPERS__TABLE);
GCX_COOP();
s_pTableRef = (BASEARRAYREF*)pTableField->GetCurrentStaticAddress();
diff --git a/src/coreclr/src/vm/ceeload.cpp b/src/coreclr/src/vm/ceeload.cpp
index 75d1f0bd0c2dff..663c5a46ad2ff7 100644
--- a/src/coreclr/src/vm/ceeload.cpp
+++ b/src/coreclr/src/vm/ceeload.cpp
@@ -481,7 +481,7 @@ void Module::InitializeNativeImage(AllocMemTracker* pamTracker)
if (GCStress::IsEnabled())
{
// Setting up gc coverage requires the base system classes
- // to be initialized. So we must defer this for mscorlib.
+ // to be initialized. So we must defer this for CoreLib.
if(!IsSystem())
{
SetupGcCoverageForNativeImage(this);
@@ -1512,11 +1512,11 @@ static bool IsLikelyDependencyOf(Module * pModule, Module * pOtherModule)
if (!pOtherModule->IsLowLevelSystemAssemblyByName())
return true;
- // Every module depends upon mscorlib
+ // Every module depends upon CoreLib
if (pModule->IsSystem())
return true;
- // mscorlib does not depend upon any other module
+ // CoreLib does not depend upon any other module
if (pOtherModule->IsSystem())
return false;
}
@@ -1526,7 +1526,7 @@ static bool IsLikelyDependencyOf(Module * pModule, Module * pOtherModule)
return false;
}
- // At this point neither pModule or pOtherModule is mscorlib
+ // At this point neither pModule or pOtherModule is CoreLib
#ifndef DACCESS_COMPILE
//
@@ -1591,8 +1591,8 @@ PTR_Module Module::ComputePreferredZapModuleHelper(
RETURN dac_cast(pOpenModule);
}
- // The initial value of pCurrentPZM is the pDefinitionModule or mscorlib
- Module* pCurrentPZM = (pDefinitionModule != NULL) ? pDefinitionModule : MscorlibBinder::GetModule();
+ // The initial value of pCurrentPZM is the pDefinitionModule or CoreLib
+ Module* pCurrentPZM = (pDefinitionModule != NULL) ? pDefinitionModule : CoreLibBinder::GetModule();
bool preferredZapModuleBasedOnValueType = false;
for (DWORD i = 0; i < totalArgs; i++)
@@ -1626,7 +1626,7 @@ PTR_Module Module::ComputePreferredZapModuleHelper(
// pCurrentPZM is a dependency of pParamPZM
// and pParamPZM is not a dependency of pCurrentPZM
//
- // note that the second condition is alway true when pCurrentPZM is mscorlib
+ // note that the second condition is alway true when pCurrentPZM is CoreLib
//
if (!IsLikelyDependencyOf(pParamPZM, pCurrentPZM))
{
@@ -2691,7 +2691,7 @@ ModuleIndex Module::AllocateModuleIndex()
// For various reasons, the IDs issued by the IdDispenser start at 1.
// Domain neutral module IDs have historically started at 0, and we
- // have always assigned ID 0 to mscorlib. Thus, to make it so that
+ // have always assigned ID 0 to CoreLib. Thus, to make it so that
// domain neutral module IDs start at 0, we will subtract 1 from the
// ID that we got back from the ID dispenser.
ModuleIndex index((SIZE_T)(val-1));
@@ -2861,7 +2861,7 @@ void Module::SetDomainFile(DomainFile *pDomainFile)
m_ModuleID->SetDomainFile(pDomainFile);
// Allocate static handles now.
- // NOTE: Bootstrapping issue with mscorlib - we will manually allocate later
+ // NOTE: Bootstrapping issue with CoreLib - we will manually allocate later
// If the assembly is collectible, we don't initialize static handles for them
// as it is currently initialized through the DomainLocalModule::PopulateClass in MethodTable::CheckRunClassInitThrowing
// (If we don't do this, it would allocate here unused regular static handles that will be overridden later)
@@ -4207,10 +4207,10 @@ OBJECTHANDLE Module::ResolveStringRef(DWORD token, BaseDomain *pDomain, bool bNe
}
/* Unfortunately, this assert won't work in some cases of generics, consider the following scenario:
- 1) Generic type in mscorlib.
+ 1) Generic type in CoreLib.
2) Instantiation of generic (1) (via valuetype) in another module
3) other module now holds a copy of the code of the generic for that particular instantiation
- however, it is resolving the string literals against mscorlib, which breaks the invariant
+ however, it is resolving the string literals against CoreLib, which breaks the invariant
this assert was based on (no string fixups against other modules). In fact, with NoStringInterning,
our behavior is not very intuitive.
*/
@@ -4758,7 +4758,7 @@ DomainAssembly * Module::LoadAssembly(mdAssemblyRef kAssemblyRef)
if (pDomainAssembly != NULL)
{
_ASSERTE(
- pDomainAssembly->IsSystem() || // GetAssemblyIfLoaded will not find mscorlib (see AppDomain::FindCachedFile)
+ pDomainAssembly->IsSystem() || // GetAssemblyIfLoaded will not find CoreLib (see AppDomain::FindCachedFile)
!pDomainAssembly->IsLoaded() || // GetAssemblyIfLoaded will not find not-yet-loaded assemblies
GetAssemblyIfLoaded(kAssemblyRef, NULL, FALSE, pDomainAssembly->GetFile()->GetHostAssembly()) != NULL); // GetAssemblyIfLoaded should find all remaining cases
diff --git a/src/coreclr/src/vm/ceeload.h b/src/coreclr/src/vm/ceeload.h
index 27c4c8f485ff78..b963624fb56619 100644
--- a/src/coreclr/src/vm/ceeload.h
+++ b/src/coreclr/src/vm/ceeload.h
@@ -157,7 +157,7 @@ typedef DPTR(struct LookupMapBase) PTR_LookupMapBase;
//
// This still leaves the problem of runtime lookup performance. Touches to the cold section of a LookupMap
// aren't all that critical (after all the data is meant to be cold), but looking up the last entry of a map
-// with 22 thousand entries (roughly what the MethodDefToDesc map in mscorlib is sized at at the time of
+// with 22 thousand entries (roughly what the MethodDefToDesc map in CoreLib is sized at at the time of
// writing) is still likely to so inefficient as to be noticeable. Remember that the issue is that we have to
// decode all predecessor entries in order to compute the value of a given entry in the table.
//
@@ -170,7 +170,7 @@ typedef DPTR(struct LookupMapBase) PTR_LookupMapBase;
//
// The main areas in which this algorithm can be tuned are the number of bits used as an index into the
// encoding lengths table (kLookupMapLengthBits) and the frequency with which entries are bookmarked in the
-// index (kLookupMapIndexStride). The current values have been set based on looking at models of mscorlib,
+// index (kLookupMapIndexStride). The current values have been set based on looking at models of CoreLib,
// PresentationCore and PresentationFramework built from the actual ridmap data in their ngen images and
// methodically trying different values in order to maximize compression or balance size versus likely runtime
// performance. An alternative strategy was considered using direct (non-length prefix) encoding of the
@@ -1597,8 +1597,8 @@ class Module
PTR_EEClassHashTable m_pAvailableClassesCaseIns;
// Pointer to binder, if we have one
- friend class MscorlibBinder;
- PTR_MscorlibBinder m_pBinder;
+ friend class CoreLibBinder;
+ PTR_CoreLibBinder m_pBinder;
public:
BOOL IsCollectible()
diff --git a/src/coreclr/src/vm/ceemain.cpp b/src/coreclr/src/vm/ceemain.cpp
index 5c763f86039db1..962ba0d2298ac4 100644
--- a/src/coreclr/src/vm/ceemain.cpp
+++ b/src/coreclr/src/vm/ceemain.cpp
@@ -240,10 +240,14 @@ extern "C" HRESULT __cdecl CorDBGetInterface(DebugInterface** rcInterface);
#endif // !CROSSGEN_COMPILE
// g_coreclr_embedded indicates that coreclr is linked directly into the program
+// g_hostpolicy_embedded indicates that the hostpolicy library is linked directly into the executable
+// Note: that it can happen that the hostpolicy is embedded but coreclr isn't (on Windows singlefilehost is built that way)
#ifdef CORECLR_EMBEDDED
bool g_coreclr_embedded = true;
+bool g_hostpolicy_embedded = true; // We always embed hostpolicy if coreclr is also embedded
#else
bool g_coreclr_embedded = false;
+bool g_hostpolicy_embedded = false; // In this case the value may come from a runtime property and may change
#endif
// Remember how the last startup of EE went.
@@ -283,8 +287,8 @@ HRESULT EnsureEEStarted()
HRESULT hr = E_FAIL;
- // On non x86 platforms, when we load mscorlib.dll during EEStartup, we will
- // re-enter _CorDllMain with a DLL_PROCESS_ATTACH for mscorlib.dll. We are
+ // On non x86 platforms, when we load CoreLib during EEStartup, we will
+ // re-enter _CorDllMain with a DLL_PROCESS_ATTACH for CoreLib. We are
// far enough in startup that this is allowed, however we don't want to
// re-start the startup code so we need to check to see if startup has
// been initiated or completed before we call EEStartup.
@@ -677,6 +681,17 @@ void EEStartupHelper()
PAL_SetShutdownCallback(EESocketCleanupHelper);
#endif // TARGET_UNIX
+#ifdef STRESS_LOG
+ if (REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, g_pConfig->StressLog ()) != 0) {
+ unsigned facilities = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_LogFacility, LF_ALL);
+ unsigned level = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_LogLevel, LL_INFO1000);
+ unsigned bytesPerThread = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLogSize, STRESSLOG_CHUNK_SIZE * 4);
+ unsigned totalBytes = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_TotalStressLogSize, STRESSLOG_CHUNK_SIZE * 1024);
+ StressLog::Initialize(facilities, level, bytesPerThread, totalBytes, GetModuleInst());
+ g_pStressLog = &StressLog::theLog;
+ }
+#endif
+
#ifdef FEATURE_PERFTRACING
DiagnosticServer::Initialize();
DiagnosticServer::PauseForDiagnosticsMonitor();
@@ -702,16 +717,6 @@ void EEStartupHelper()
#endif // CROSSGEN_COMPILE
-#ifdef STRESS_LOG
- if (REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, g_pConfig->StressLog ()) != 0) {
- unsigned facilities = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_LogFacility, LF_ALL);
- unsigned level = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_LogLevel, LL_INFO1000);
- unsigned bytesPerThread = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLogSize, STRESSLOG_CHUNK_SIZE * 4);
- unsigned totalBytes = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_TotalStressLogSize, STRESSLOG_CHUNK_SIZE * 1024);
- StressLog::Initialize(facilities, level, bytesPerThread, totalBytes, GetModuleInst());
- g_pStressLog = &StressLog::theLog;
- }
-#endif
#ifdef LOGGING
InitializeLogging();
@@ -823,7 +828,7 @@ void EEStartupHelper()
AccessCheckOptions::Startup();
- MscorlibBinder::Startup();
+ CoreLibBinder::Startup();
Stub::Init();
StubLinkerCPU::Init();
@@ -1029,8 +1034,8 @@ void EEStartupHelper()
SystemDomain::SystemModule()->ExpandAll();
}
- // Perform mscorlib consistency check if requested
- g_Mscorlib.CheckExtended();
+ // Perform CoreLib consistency check if requested
+ g_CoreLib.CheckExtended();
#endif // _DEBUG
@@ -1106,7 +1111,7 @@ LONG FilterStartupException(PEXCEPTION_POINTERS p, PVOID pv)
// EEStartup is responsible for all the one time intialization of the runtime. Some of the highlights of
// what it does include
// * Creates the default and shared, appdomains.
-// * Loads mscorlib.dll and loads up the fundamental types (System.Object ...)
+// * Loads System.Private.CoreLib and loads up the fundamental types (System.Object ...)
//
// see code:EEStartup#TableOfContents for more on the runtime in general.
// see code:#EEShutdown for a analagous routine run during shutdown.
diff --git a/src/coreclr/src/vm/cgensys.h b/src/coreclr/src/vm/cgensys.h
index 53e21461304d4b..216729938ae143 100644
--- a/src/coreclr/src/vm/cgensys.h
+++ b/src/coreclr/src/vm/cgensys.h
@@ -95,21 +95,22 @@ inline void GetSpecificCpuInfo(CORINFO_CPU * cpuInfo)
#endif // !TARGET_X86
#if (defined(TARGET_X86) || defined(TARGET_AMD64)) && !defined(CROSSGEN_COMPILE)
-extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]);
-extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]);
+#ifdef TARGET_UNIX
+// MSVC directly defines intrinsics for __cpuid and __cpuidex matching the below signatures
+// We define matching signatures for use on Unix platforms.
+
+extern "C" void __stdcall __cpuid(int cpuInfo[4], int function_id);
+extern "C" void __stdcall __cpuidex(int cpuInfo[4], int function_id, int subFunction_id);
+#endif // TARGET_UNIX
extern "C" DWORD __stdcall xmmYmmStateSupport();
#endif
inline bool TargetHasAVXSupport()
{
#if (defined(TARGET_X86) || defined(TARGET_AMD64)) && !defined(CROSSGEN_COMPILE)
- unsigned char buffer[16];
- // All x86/AMD64 targets support cpuid.
- (void) getcpuid(1, buffer);
- // getcpuid executes cpuid with eax set to its first argument, and ecx cleared.
- // It returns the resulting eax, ebx, ecx and edx (in that order) in buffer[].
- // The AVX feature is ECX bit 28.
- return ((buffer[11] & 0x10) != 0);
+ int cpuInfo[4];
+ __cpuid(cpuInfo, 0x00000001); // All x86/AMD64 targets support cpuid.
+ return ((cpuInfo[3] & (1 << 28)) != 0); // The AVX feature is ECX bit 28.
#endif // (defined(TARGET_X86) || defined(TARGET_AMD64)) && !defined(CROSSGEN_COMPILE)
return false;
}
@@ -143,7 +144,7 @@ BOOL GetAnyThunkTarget (T_CONTEXT *pctx, TADDR *pTarget, TADDR *pTargetMethodDes
//
// ResetProcessorStateHolder saves/restores processor state around calls to
-// mscorlib during exception handling.
+// CoreLib during exception handling.
//
class ResetProcessorStateHolder
{
diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp
index 8e18a47059f9fa..d56cb02b68d265 100644
--- a/src/coreclr/src/vm/class.cpp
+++ b/src/coreclr/src/vm/class.cpp
@@ -1184,107 +1184,129 @@ void ClassLoader::ValidateMethodsWithCovariantReturnTypes(MethodTable* pMT)
return;
// Step 1: Validate compatibility of return types on overriding methods
-
- for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++)
+ if (pMT->GetClass()->HasCovariantOverride() && (!pMT->GetModule()->IsReadyToRun() || !pMT->GetModule()->GetReadyToRunInfo()->SkipTypeValidation()))
{
- MethodDesc* pMD = pMT->GetMethodDescForSlot(i);
- MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i);
-
- if (pMD == pParentMD)
- continue;
+ for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++)
+ {
+ if (pMT->GetRestoredSlot(i) == pParentMT->GetRestoredSlot(i))
+ {
+ // The real check is that the MethodDesc's must not match, but a simple VTable check will
+ // work most of the time, and is far faster than the GetMethodDescForSlot method.
+ _ASSERTE(pMT->GetMethodDescForSlot(i) == pParentMT->GetMethodDescForSlot(i));
+ continue;
+ }
+ MethodDesc* pMD = pMT->GetMethodDescForSlot(i);
+ MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i);
- if (!pMD->RequiresCovariantReturnTypeChecking() && !pParentMD->RequiresCovariantReturnTypeChecking())
- continue;
+ if (pMD == pParentMD)
+ continue;
- // If the bit is not set on this method, but we reach here because it's been set on the method at the same slot on
- // the base type, set the bit for the current method to ensure any future overriding method down the chain gets checked.
- if (!pMD->RequiresCovariantReturnTypeChecking())
- pMD->SetRequiresCovariantReturnTypeChecking();
+ if (!pMD->RequiresCovariantReturnTypeChecking() && !pParentMD->RequiresCovariantReturnTypeChecking())
+ continue;
- // The context used to load the return type of the parent method has to use the generic method arguments
- // of the overriding method, otherwise the type comparison below will not work correctly
- SigTypeContext context1(pParentMD->GetClassInstantiation(), pMD->GetMethodInstantiation());
- MetaSig methodSig1(pParentMD);
- TypeHandle hType1 = methodSig1.GetReturnProps().GetTypeHandleThrowing(pParentMD->GetModule(), &context1, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS);
+ // If the bit is not set on this method, but we reach here because it's been set on the method at the same slot on
+ // the base type, set the bit for the current method to ensure any future overriding method down the chain gets checked.
+ if (!pMD->RequiresCovariantReturnTypeChecking())
+ pMD->SetRequiresCovariantReturnTypeChecking();
- SigTypeContext context2(pMD);
- MetaSig methodSig2(pMD);
- TypeHandle hType2 = methodSig2.GetReturnProps().GetTypeHandleThrowing(pMD->GetModule(), &context2, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS);
+ // The context used to load the return type of the parent method has to use the generic method arguments
+ // of the overriding method, otherwise the type comparison below will not work correctly
+ SigTypeContext context1(pParentMD->GetClassInstantiation(), pMD->GetMethodInstantiation());
+ MetaSig methodSig1(pParentMD);
+ TypeHandle hType1 = methodSig1.GetReturnProps().GetTypeHandleThrowing(pParentMD->GetModule(), &context1, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS);
- if (!IsCompatibleWith(hType1, hType2))
- {
- SString strAssemblyName;
- pMD->GetAssembly()->GetDisplayName(strAssemblyName);
+ SigTypeContext context2(pMD);
+ MetaSig methodSig2(pMD);
+ TypeHandle hType2 = methodSig2.GetReturnProps().GetTypeHandleThrowing(pMD->GetModule(), &context2, ClassLoader::LoadTypesFlag::LoadTypes, CLASS_LOAD_EXACTPARENTS);
- SString strInvalidTypeName;
- TypeString::AppendType(strInvalidTypeName, TypeHandle(pMD->GetMethodTable()));
+ if (!IsCompatibleWith(hType1, hType2))
+ {
+ SString strAssemblyName;
+ pMD->GetAssembly()->GetDisplayName(strAssemblyName);
- SString strInvalidMethodName;
- TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation());
+ SString strInvalidTypeName;
+ TypeString::AppendType(strInvalidTypeName, TypeHandle(pMD->GetMethodTable()));
- SString strParentMethodName;
- TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation());
+ SString strInvalidMethodName;
+ SString strParentMethodName;
+ {
+ CONTRACT_VIOLATION(LoadsTypeViolation);
+ TypeString::AppendMethod(strInvalidMethodName, pMD, pMD->GetMethodInstantiation());
+ TypeString::AppendMethod(strParentMethodName, pParentMD, pParentMD->GetMethodInstantiation());
+ }
- COMPlusThrow(
- kTypeLoadException,
- IDS_CLASSLOAD_MI_BADRETURNTYPE,
- strInvalidMethodName,
- strInvalidTypeName,
- strAssemblyName,
- strParentMethodName);
+ COMPlusThrow(
+ kTypeLoadException,
+ IDS_CLASSLOAD_MI_BADRETURNTYPE,
+ strInvalidMethodName,
+ strInvalidTypeName,
+ strAssemblyName,
+ strParentMethodName);
+ }
}
}
// Step 2: propate overriding MethodImpls to applicable vtable slots if the declaring method has the attribute
- MethodTable::MethodDataWrapper hMTData(MethodTable::GetMethodData(pMT, FALSE));
-
- for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++)
+ if (pMT->GetClass()->HasVTableMethodImpl())
{
- MethodDesc* pMD = pMT->GetMethodDescForSlot(i);
- MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i);
- if (pMD == pParentMD)
- continue;
+ MethodTable::MethodDataWrapper hMTData(MethodTable::GetMethodData(pMT, FALSE));
- // The attribute is only applicable to MethodImpls. For anything else, it will be treated as a no-op
- if (!pMD->IsMethodImpl())
- continue;
-
- // Search if the attribute has been applied on this vtable slot, either by the current MethodImpl, or by a previous
- // MethodImpl somewhere in the base type hierarchy.
- bool foundAttribute = false;
- MethodTable* pCurrentMT = pMT;
- while (!foundAttribute && pCurrentMT != NULL && i < pCurrentMT->GetNumVirtuals())
+ for (WORD i = 0; i < pParentMT->GetNumVirtuals(); i++)
{
- MethodDesc* pCurrentMD = pCurrentMT->GetMethodDescForSlot(i);
+ if (pMT->GetRestoredSlot(i) == pParentMT->GetRestoredSlot(i))
+ {
+ // The real check is that the MethodDesc's must not match, but a simple VTable check will
+ // work most of the time, and is far faster than the GetMethodDescForSlot method.
+ _ASSERTE(pMT->GetMethodDescForSlot(i) == pParentMT->GetMethodDescForSlot(i));
+ continue;
+ }
+
+ MethodDesc* pMD = pMT->GetMethodDescForSlot(i);
+ MethodDesc* pParentMD = pParentMT->GetMethodDescForSlot(i);
+ if (pMD == pParentMD)
+ continue;
// The attribute is only applicable to MethodImpls. For anything else, it will be treated as a no-op
- if (pCurrentMD->IsMethodImpl())
+ if (!pMD->IsMethodImpl())
+ continue;
+
+ // Search if the attribute has been applied on this vtable slot, either by the current MethodImpl, or by a previous
+ // MethodImpl somewhere in the base type hierarchy.
+ bool foundAttribute = false;
+ MethodTable* pCurrentMT = pMT;
+ while (!foundAttribute && pCurrentMT != NULL && i < pCurrentMT->GetNumVirtuals())
{
- BYTE* pVal = NULL;
- ULONG cbVal = 0;
- if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::PreserveBaseOverridesAttribute, (const void**)&pVal, &cbVal) == S_OK)
- foundAttribute = true;
- }
+ MethodDesc* pCurrentMD = pCurrentMT->GetMethodDescForSlot(i);
- pCurrentMT = pCurrentMT->GetParentMethodTable();
- }
+ // The attribute is only applicable to MethodImpls. For anything else, it will be treated as a no-op
+ if (pCurrentMD->IsMethodImpl())
+ {
+ BYTE* pVal = NULL;
+ ULONG cbVal = 0;
+ if (pCurrentMD->GetCustomAttribute(WellKnownAttribute::PreserveBaseOverridesAttribute, (const void**)&pVal, &cbVal) == S_OK)
+ foundAttribute = true;
+ }
- if (!foundAttribute)
- continue;
+ pCurrentMT = pCurrentMT->GetParentMethodTable();
+ }
- // Search for any vtable slot still pointing at the parent method, and update it with the current overriding method
- for (WORD j = i; j < pParentMT->GetNumVirtuals(); j++)
- {
- MethodDesc* pCurrentMD = pMT->GetMethodDescForSlot(j);
- if (pCurrentMD == pParentMD)
+ if (!foundAttribute)
+ continue;
+
+ // Search for any vtable slot still pointing at the parent method, and update it with the current overriding method
+ for (WORD j = i; j < pParentMT->GetNumVirtuals(); j++)
{
- // This is a vtable slot that needs to be updated to the new overriding method because of the
- // presence of the attribute.
- pMT->SetSlot(j, pMT->GetSlot(i));
- _ASSERT(pMT->GetMethodDescForSlot(j) == pMD);
+ MethodDesc* pCurrentMD = pMT->GetMethodDescForSlot(j);
+ if (pCurrentMD == pParentMD)
+ {
+ // This is a vtable slot that needs to be updated to the new overriding method because of the
+ // presence of the attribute.
+ pMT->SetSlot(j, pMT->GetSlot(i));
+ _ASSERT(pMT->GetMethodDescForSlot(j) == pMD);
- hMTData->UpdateImplMethodDesc(pMD, j);
+ hMTData->UpdateImplMethodDesc(pMD, j);
+ }
}
}
}
diff --git a/src/coreclr/src/vm/class.h b/src/coreclr/src/vm/class.h
index 98a59dbba18218..179a082199a31d 100644
--- a/src/coreclr/src/vm/class.h
+++ b/src/coreclr/src/vm/class.h
@@ -1158,6 +1158,30 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW!
}
#endif // FEATURE_COMINTEROP
+ inline void SetHasVTableMethodImpl()
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_VMFlags |= VMFLAG_VTABLEMETHODIMPL;
+ }
+
+ inline BOOL HasVTableMethodImpl()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return (m_VMFlags & VMFLAG_VTABLEMETHODIMPL);
+ }
+
+ inline void SetHasCovariantOverride()
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_VMFlags |= VMFLAG_COVARIANTOVERRIDE;
+ }
+
+ inline BOOL HasCovariantOverride()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return (m_VMFlags & VMFLAG_COVARIANTOVERRIDE);
+ }
+
#ifdef _DEBUG
inline DWORD IsDestroyed()
{
@@ -1691,8 +1715,8 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW!
VMFLAG_HASCOCLASSATTRIB = 0x01000000,
VMFLAG_COMEVENTITFMASK = 0x02000000, // class is a special COM event interface
#endif // FEATURE_COMINTEROP
- // unused = 0x04000000,
- // unused = 0x08000000,
+ VMFLAG_VTABLEMETHODIMPL = 0x04000000, // class uses MethodImpl to override virtual function defined on class
+ VMFLAG_COVARIANTOVERRIDE = 0x08000000, // class has a covariant override
// This one indicates that the fields of the valuetype are
// not tightly packed and is used to check whether we can
diff --git a/src/coreclr/src/vm/classcompat.cpp b/src/coreclr/src/vm/classcompat.cpp
index aab4e63d5ccc13..4f00fbf9448142 100644
--- a/src/coreclr/src/vm/classcompat.cpp
+++ b/src/coreclr/src/vm/classcompat.cpp
@@ -3010,49 +3010,6 @@ VOID MethodTableBuilder::AllocateMethodWorkingMemory()
}
bmtVT->pParentMethodTable = bmtParent->pParentMethodTable;
}
-
-#if 0
- // @todo: Figure out the right way to override Equals for value
- // types only.
- //
- // This is broken because
- // (a) g_pObjectClass->FindMethod("Equals", &gsig_IM_Obj_RetBool); will return
- // the EqualsValue method
- // (b) When mscorlib has been preloaded (and thus the munge already done
- // ahead of time), we cannot easily find both methods
- // to compute EqualsAddr & EqualsSlot
- //
- // For now, the Equals method has a runtime check to see if it's
- // comparing value types.
- //
-
- // If it is a value type, over ride a few of the base class methods.
- if (IsValueClass())
- {
- static WORD EqualsSlot;
-
- // If we haven't been through here yet, get some stuff from the Object class definition.
- if (EqualsSlot == NULL)
- {
- // Get the slot of the Equals method.
- MethodDesc *pEqualsMD = g_pObjectClass->FindMethod("Equals", &gsig_IM_Obj_RetBool);
- THROW_BAD_FORMAT_MAYBE(pEqualsMD != NULL, 0, this);
- EqualsSlot = pEqualsMD->GetSlot();
-
- // Get the address of the EqualsValue method.
- MethodDesc *pEqualsValueMD = g_pObjectClass->FindMethod("EqualsValue", &gsig_IM_Obj_RetBool);
- THROW_BAD_FORMAT_MAYBE(pEqualsValueMD != NULL, 0, this);
-
- // Patch the EqualsValue method desc in a dangerous way to
- // look like the Equals method desc.
- pEqualsValueMD->SetSlot(EqualsSlot);
- pEqualsValueMD->SetMemberDef(pEqualsMD->GetMemberDef());
- }
-
- // Override the valuetype "Equals" with "EqualsValue".
- bmtVT->SetMethodDescForSlot(EqualsSlot, EqualsSlot);
- }
-#endif // 0
}
if (NumDeclaredMethods() > 0)
diff --git a/src/coreclr/src/vm/classlayoutinfo.cpp b/src/coreclr/src/vm/classlayoutinfo.cpp
index a9c932886a8b73..e5f9345c88327a 100644
--- a/src/coreclr/src/vm/classlayoutinfo.cpp
+++ b/src/coreclr/src/vm/classlayoutinfo.cpp
@@ -903,16 +903,16 @@ EEClassNativeLayoutInfo* EEClassNativeLayoutInfo::CollectNativeLayoutFieldMetada
// from the managed size and alignment.
// Crossgen scenarios block Vector from even being loaded, so only do this check when not in crossgen.
#ifndef CROSSGEN_COMPILE
- if (pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTORT)))
+ if (pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTORT)))
{
pNativeLayoutInfo->m_size = pEEClassLayoutInfo->GetManagedSize();
pNativeLayoutInfo->m_alignmentRequirement = pEEClassLayoutInfo->m_ManagedLargestAlignmentRequirementOfAllMembers;
}
else
#endif
- if (pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR64T)) ||
- pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR128T)) ||
- pMT->HasSameTypeDefAs(MscorlibBinder::GetClass(CLASS__VECTOR256T)))
+ if (pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR64T)) ||
+ pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR128T)) ||
+ pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR256T)))
{
pNativeLayoutInfo->m_alignmentRequirement = pEEClassLayoutInfo->m_ManagedLargestAlignmentRequirementOfAllMembers;
}
diff --git a/src/coreclr/src/vm/clrex.cpp b/src/coreclr/src/vm/clrex.cpp
index 0965a32c3dae24..04a8d5b9be7d93 100644
--- a/src/coreclr/src/vm/clrex.cpp
+++ b/src/coreclr/src/vm/clrex.cpp
@@ -189,7 +189,7 @@ OBJECTREF CLRException::GetThrowable()
// CreateThrowable() and is being caught in this EX_TRY/EX_CATCH.)
// If that exception is the same as the one for which this GetThrowable()
// was called, we're in a recursive situation.
- // Since the CreateThrowable() call should return a type from mscorlib,
+ // Since the CreateThrowable() call should return a type from CoreLib,
// there really shouldn't be much opportunity for error. We could be
// out of memory, we could overflow the stack, or the runtime could
// be in a weird state(the thread could be aborted as well).
@@ -1071,7 +1071,7 @@ void EEException::GetMessage(SString &result)
return;
// Otherwise, report the class's generic message
- LPCUTF8 pszExceptionName = MscorlibBinder::GetExceptionName(m_kind);
+ LPCUTF8 pszExceptionName = CoreLibBinder::GetExceptionName(m_kind);
result.SetUTF8(pszExceptionName);
}
@@ -1092,7 +1092,7 @@ OBJECTREF EEException::CreateThrowable()
_ASSERTE(g_pPreallocatedOutOfMemoryException != NULL);
static int allocCount = 0;
- MethodTable *pMT = MscorlibBinder::GetException(m_kind);
+ MethodTable *pMT = CoreLibBinder::GetException(m_kind);
ThreadPreventAsyncHolder preventAsyncHolder(m_kind == kThreadAbortException);
@@ -1218,7 +1218,7 @@ void EEResourceException::GetMessage(SString &result)
//
result.Printf("%s (message resource %s)",
- MscorlibBinder::GetExceptionName(m_kind), m_resourceName.GetUnicode());
+ CoreLibBinder::GetExceptionName(m_kind), m_resourceName.GetUnicode());
}
BOOL EEResourceException::GetThrowableMessage(SString &result)
@@ -1420,7 +1420,7 @@ OBJECTREF EEArgumentException::CreateThrowable()
ResMgrGetString(m_resourceName, &prot.s1);
GCPROTECT_BEGIN(prot);
- MethodTable *pMT = MscorlibBinder::GetException(m_kind);
+ MethodTable *pMT = CoreLibBinder::GetException(m_kind);
prot.pThrowable = AllocateObject(pMT);
MethodDesc* pMD = MemberLoader::FindMethod(prot.pThrowable->GetMethodTable(),
@@ -1547,7 +1547,7 @@ OBJECTREF EETypeLoadException::CreateThrowable()
}
CONTRACTL_END;
- MethodTable *pMT = MscorlibBinder::GetException(kTypeLoadException);
+ MethodTable *pMT = CoreLibBinder::GetException(kTypeLoadException);
struct _gc {
OBJECTREF pNewException;
@@ -1752,7 +1752,7 @@ OBJECTREF EEFileLoadException::CreateThrowable()
GCPROTECT_BEGIN(gc);
gc.pNewFileString = StringObject::NewString(m_name);
- gc.pNewException = AllocateObject(MscorlibBinder::GetException(m_kind));
+ gc.pNewException = AllocateObject(CoreLibBinder::GetException(m_kind));
MethodDesc* pMD = MemberLoader::FindMethod(gc.pNewException->GetMethodTable(),
COR_CTOR_METHOD_NAME, &gsig_IM_Str_Int_RetVoid);
diff --git a/src/coreclr/src/vm/clsload.cpp b/src/coreclr/src/vm/clsload.cpp
index 851266f475765b..01278d32f8f217 100644
--- a/src/coreclr/src/vm/clsload.cpp
+++ b/src/coreclr/src/vm/clsload.cpp
@@ -63,7 +63,7 @@
// Some useful effects of this rule (for ngen purposes) are:
//
// * G