Merge branch 'main' into dotnet-upstream/fix-typedescription-alc-leak

This commit is contained in:
Alexey Zakharov 2025-07-30 13:06:55 +02:00 committed by GitHub
commit edfac0ddcd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1585 changed files with 123218 additions and 30784 deletions

1
.github/CODEOWNERS vendored
View File

@ -1,7 +1,6 @@
# Users referenced in this file will automatically be requested as reviewers for PRs that modify the given paths.
# See https://help.github.com/articles/about-code-owners/
/src/libraries/Common/src/Interop/ @dotnet/platform-deps-team
/src/libraries/Common/src/System/Net/Http/aspnetcore/ @dotnet/http
/src/libraries/Common/tests/Tests/System/Net/aspnetcore/ @dotnet/http

View File

@ -37,10 +37,11 @@ In addition to the rules enforced by `.editorconfig`, you SHOULD:
- [5.1. How To: Identify Affected Libraries](#51-how-to-identify-affected-libraries)
- [5.2. How To: Build and Test Specific Library](#52-how-to-build-and-test-specific-library)
- [6. WebAssembly (WASM) Libraries Workflow](#6-webassembly-wasm-libraries-workflow)
- [7. Additional Notes](#7-additional-notes)
- [7.1. Troubleshooting](#71-troubleshooting)
- [7.2. Windows Command Equivalents](#72-windows-command-equivalents)
- [7.3. References](#73-references)
- [7. Host Workflow](#7-host-workflow)
- [8. Additional Notes](#8-additional-notes)
- [8.1. Troubleshooting](#81-troubleshooting)
- [8.2. Windows Command Equivalents](#82-windows-command-equivalents)
- [8.3. References](#83-references)
## 1. Prerequisites
@ -54,6 +55,7 @@ Identify which components will be impacted by the changes. If in doubt, analyze
- **Mono Runtime:** Changes in `src/mono/`
- **Libraries:** Changes in `src/libraries/`
- **WASM/WASI Libraries:** Changes in `src/libraries/` *and* the affected library targets WASM or WASI *and* the changes are included for the target (see below for details).
- **Host:** Changes in `src/native/corehost/`, `src/installer/managed/`, or `src/installer/tests/`
- If none above apply, it is most possibly an infra-only or a docs-only change. Skip build and test steps.
**WASM/WASI Library Change Detection**
@ -76,6 +78,7 @@ Before applying any changes, ensure you have a full successful build of the need
- **Mono Runtime:** `./build.sh mono+libs`
- **Libraries:** `./build.sh clr+libs -rc release`
- **WASM/WASI Libraries:** `./build.sh mono+libs -os browser`
- **Host:** `./build.sh clr+libs+host -rc release -lc release`
3. Verify the build completed without error.
- _If the baseline build failed, report the failure and don't proceed with the changes._
@ -239,9 +242,24 @@ From the repository root:
---
## 7. Additional Notes
## 7. Host Workflow
### 7.1. Troubleshooting
From the repository root:
- Build:
`./build.sh host -rc release -lc release`
- Run all tests:
`./build.sh host.tests -rc release -lc release -test`
- More info can be found in the dedicated workflow docs:
- [Building and running host tests](/docs/workflow/testing/host/testing.md)
---
## 8. Additional Notes
### 8.1. Troubleshooting
- **Shared Framework Missing**
@ -273,7 +291,7 @@ From the repository root:
---
### 7.2. Windows Command Equivalents
### 8.2. Windows Command Equivalents
- Use `build.cmd` instead of `build.sh` on Windows.
- Set PATH: `set PATH=%CD%\.dotnet;%PATH%`
@ -281,7 +299,7 @@ From the repository root:
---
### 7.3. References
### 8.3. References
- [`.editorconfig`](/.editorconfig)
- [Building CoreCLR Guide](/docs/workflow/building/coreclr/README.md)
@ -292,3 +310,4 @@ From the repository root:
- [Testing Libraries](/docs/workflow/testing/libraries/testing.md)
- [Build libraries for WebAssembly](/docs/workflow/building/libraries/webassembly-instructions.md)
- [Testing Libraries on WebAssembly](/docs/workflow/testing/libraries/testing-wasm.md)
- [Building and running host tests](/docs/workflow/testing/host/testing.md)

View File

@ -19,7 +19,7 @@ configuration:
- adamsitnik
- bartonjs
- jeffhandley
- terrajobst
- JeremyKuhne
replyTemplate: >-
Tagging subscribers to 'binaryformatter-migration': ${mentionees}
assignMentionees: False

View File

@ -1789,7 +1789,6 @@ configuration:
mentionees:
- vitek-karas
- kotlarmilos
- ivanpovazan
- steveisok
- akoeplinger
replyTemplate: >-
@ -1828,7 +1827,6 @@ configuration:
mentionees:
- vitek-karas
- kotlarmilos
- ivanpovazan
- steveisok
- akoeplinger
replyTemplate: >-
@ -1848,7 +1846,6 @@ configuration:
mentionees:
- vitek-karas
- kotlarmilos
- ivanpovazan
- steveisok
- akoeplinger
replyTemplate: >-

View File

@ -178,7 +178,7 @@
<PropertyGroup>
<DotNetHostBinDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', '$(TargetRid).$(HostConfiguration)', 'corehost'))</DotNetHostBinDir>
<DotNetCdacBinDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'mscordaccore_universal', '$(Configuration)', '$(NetCoreAppCurrent)', '$(TargetRid)', 'publish'))</DotNetCdacBinDir>
<DotNetCdacBinDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'mscordaccore_universal', '$(Configuration)', '$(NetCoreAppCurrent)', '$(PortableTargetRid)', 'publish'))</DotNetCdacBinDir>
</PropertyGroup>
<!--Feature switches -->

View File

@ -17,7 +17,7 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi
| area-Build-mono | @lewing | @akoeplinger | |
| area-Codeflow | @dotnet/dnr-codeflow | @dotnet/dnr-codeflow | Used for automated PRs that ingest code from other repos |
| area-Codegen-AOT-mono | @steveisok | @kotlarmilos | |
| area-CodeGen-coreclr | @JulieLeeMSFT | @BruceForstall @dotnet/jit-contrib | |
| area-CodeGen-coreclr | @JulieLeeMSFT | @dotnet/jit-contrib | |
| area-Codegen-Interpreter-coreclr | @vitek-karas | @BrzVlad @janvorli | |
| area-Codegen-Interpreter-mono | @vitek-karas | @BrzVlad @kotlarmilos | |
| area-Codegen-Intrinsics-mono | @steveisok | | |
@ -25,87 +25,87 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi
| area-Codegen-LLVM-mono | @steveisok | | |
| area-Codegen-meta-mono | @steveisok | | |
| area-crossgen2-coreclr | @mangod9 | @dotnet/crossgen-contrib | |
| area-Debugger-mono | @steveisok | @thaystg @dotnet/dotnet-diag | |
| area-DependencyModel | @ericstj | @dotnet/area-dependencymodel | Included:<ul><li>Microsoft.Extensions.DependencyModel</li></ul> |
| area-Diagnostics-coreclr | @steveisok | @tommcdon @dotnet/dotnet-diag | |
| area-Diagnostics-mono | @steveisok | @tommcdon @mdh1418 @thaystg | |
| area-EnC-mono | @steveisok | @dotnet/dotnet-diag @thaystg | Hot Reload on WebAssembly, Android, iOS, etc . @lambdageek to consult |
| area-Debugger-mono | @steveisok | @thaystg @dotnet/dotnet-diag | |
| area-DependencyModel | @jeffhandley | @dotnet/area-dependencymodel | Included:<ul><li>Microsoft.Extensions.DependencyModel</li></ul> |
| area-Diagnostics-coreclr | @steveisok | @tommcdon @dotnet/dotnet-diag | |
| area-Diagnostics-mono | @steveisok | @tommcdon @mdh1418 @thaystg | |
| area-EnC-mono | @steveisok | @dotnet/dotnet-diag @thaystg | Hot Reload on WebAssembly, Android, iOS, etc. |
| area-ExceptionHandling-coreclr | @mangod9 | @janvorli | |
| area-Extensions-Caching | @jeffhandley | @dotnet/area-extensions-caching | Consultants: @mgravell, @sebastienros |
| area-Extensions-Configuration | @ericstj | @dotnet/area-extensions-configuration | Consultants: @eerhardt |
| area-Extensions-DependencyInjection | @ericstj | @dotnet/area-extensions-dependencyinjection | Consultants: @halter73, @benjaminpetit |
| area-Extensions-Configuration | @jeffhandley | @dotnet/area-extensions-configuration | Consultants: @eerhardt |
| area-Extensions-DependencyInjection | @jeffhandley | @dotnet/area-extensions-dependencyinjection | Consultants: @halter73, @benjaminpetit |
| area-Extensions-FileSystem | @jeffhandley | @dotnet/area-extensions-filesystem | |
| area-Extensions-Hosting | @ericstj | @dotnet/area-extensions-hosting | Consultants: @halter73, @tratcher |
| area-Extensions-Hosting | @jeffhandley | @dotnet/area-extensions-hosting | Consultants: @halter73, @tratcher |
| area-Extensions-HttpClientFactory | @karelz | @dotnet/ncl | |
| area-Extensions-Logging | @ericstj | @dotnet/area-extensions-logging | Consultants: @brennanconroy |
| area-Extensions-Options | @ericstj | @dotnet/area-extensions-options | Consultants: @eerhardt, @brennanconroy |
| area-Extensions-Primitives | @ericstj | @dotnet/area-extensions-primitives | |
| area-Extensions-Logging | @jeffhandley | @dotnet/area-extensions-logging | Consultants: @brennanconroy |
| area-Extensions-Options | @jeffhandley | @dotnet/area-extensions-options | Consultants: @eerhardt, @brennanconroy |
| area-Extensions-Primitives | @jeffhandley | @dotnet/area-extensions-primitives | |
| area-GC-coreclr | @mangod9 | @Maoni0 | |
| area-GC-mono | @mangod9 | @mangod9 | @BrzVlad to consult |
| area-Host | @agocke | @jeffschwMSFT @elinor-fung | Issues with dotnet.exe including bootstrapping, framework detection, hostfxr.dll and hostpolicy.dll |
| area-HostModel | @agocke | @elinor-fung | |
| area-ILTools-coreclr | @JulieLeeMSFT | @BruceForstall @dotnet/jit-contrib | |
| area-ILTools-coreclr | @JulieLeeMSFT | @dotnet/jit-contrib | |
| area-Infrastructure | @agocke | @jeffschwMSFT @MichaelSimons | |
| area-Infrastructure-coreclr | @agocke | @jeffschwMSFT | |
| area-Infrastructure-installer | @MichaelSimons | @NikolaMilosavljevic | |
| area-Infrastructure-libraries | @ericstj | @dotnet/area-infrastructure-libraries | Covers:<ul><li>Packaging</li><li>Build and test infra for libraries in dotnet/runtime repo</li><li>VS integration</li></ul><br/> |
| area-Infrastructure-libraries | @jeffhandley | @dotnet/area-infrastructure-libraries | Covers:<ul><li>Packaging</li><li>Build and test infra for libraries in dotnet/runtime repo</li><li>VS integration</li></ul><br/> |
| area-Infrastructure-mono | @steveisok | @agocke | |
| area-Interop-coreclr | @agocke | @AaronRobinsonMSFT @jkoritzinsky | |
| area-Interop-mono | @agocke | @AaronRobinsonMSFT @jkoritzinsky | |
| area-Meta | @jeffhandley | @dotnet/area-meta | Cross-cutting concerns that span many or all areas, including project-wide code/test patterns and documentation. |
| area-Microsoft.CSharp | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) |
| area-Microsoft.VisualBasic | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) |
| area-Microsoft.Win32 | @ericstj | @dotnet/area-microsoft-win32 | Included:<ul><li>System.Windows.Extensions</li></ul> |
| area-Microsoft.Win32 | @jeffhandley | @dotnet/area-microsoft-win32 | Included:<ul><li>System.Windows.Extensions</li></ul> |
| area-NativeAOT-coreclr | @agocke | @dotnet/ilc-contrib | |
| area-PAL-coreclr | @mangod9 | @janvorli | |
| area-R2RDump-coreclr | @mangod9 | | |
| area-ReadyToRun-coreclr | @mangod9 | | |
| area-Serialization | @HongGit | @StephenMolloy @HongGit | Packages:<ul><li>System.Runtime.Serialization.Xml</li><li>System.Runtime.Serialization.Json</li><li>System.Private.DataContractSerialization</li><li>System.Xml.XmlSerializer</li></ul> Excluded:<ul><li>System.Runtime.Serialization.Formatters</li></ul> |
| area-Serialization | @StephenMolloy | @StephenMolloy @dotnet/Tellurium | Packages:<ul><li>System.Runtime.Serialization.Xml</li><li>System.Runtime.Serialization.Json</li><li>System.Private.DataContractSerialization</li><li>System.Xml.XmlSerializer</li></ul> Excluded:<ul><li>System.Runtime.Serialization.Formatters</li></ul> |
| area-Setup | @MichaelSimons | @NikolaMilosavljevic | Distro-specific (Linux, Mac and Windows) setup packages and msi files |
| area-Single-File | @agocke | @elinor-fung @vsadov | |
| area-Snap | @MichaelSimons | @NikolaMilosavljevic @leecow @MichaelSimons | |
| area-System.Buffers | @jeffhandley | @dotnet/area-system-buffers | |
| area-System.ClientModel | @terrajobst | @dotnet/fxdc | Bugs and feature requests should go to https://github.com/Azure/azure-sdk-for-net/issues. We don't own the code, but FXDC reviews changes to determine overlap with other `System` concepts. The Azure SDK team will post API updates in this repo for us to review. |
| area-System.CodeDom | @ericstj | @dotnet/area-system-codedom | |
| area-System.CodeDom | @jeffhandley | @dotnet/area-system-codedom | |
| area-System.Collections | @jeffhandley | @dotnet/area-system-collections | Excluded:<ul><li>System.Array -> System.Runtime</li></ul> |
| area-System.ComponentModel | @ericstj | @dotnet/area-system-componentmodel | Consultants: @dotnet/dotnet-winforms |
| area-System.ComponentModel.Composition | @ericstj | @dotnet/area-system-componentmodel-composition | |
| area-System.ComponentModel | @jeffhandley | @dotnet/area-system-componentmodel | Consultants: @dotnet/dotnet-winforms |
| area-System.ComponentModel.Composition | @jeffhandley | @dotnet/area-system-componentmodel-composition | |
| area-System.ComponentModel.DataAnnotations | @jeffhandley | @dotnet/area-system-componentmodel-dataannotations | Included:<ul><li>System.ComponentModel.Annotations</li></ul> |
| area-System.Composition | @ericstj | @dotnet/area-system-composition | |
| area-System.Configuration | @ericstj | @dotnet/area-system-configuration | |
| area-System.Composition | @jeffhandley | @dotnet/area-system-composition | |
| area-System.Configuration | @jeffhandley | @dotnet/area-system-configuration | |
| area-System.Console | @jeffhandley | @dotnet/area-system-console | |
| area-System.Data | @sammonort | @ajcvickers @roji | <ul><li>Odbc, OleDb - @saurabh500</li></ul> |
| area-System.Data.Odbc | @sammonort | @ajcvickers @roji | |
| area-System.Data.OleDB | @sammonort | @ajcvickers @roji | |
| area-System.Data.SqlClient | @David-Engel | @cheenamalhotra @david-engel | Archived component - limited churn/contributions (see https://devblogs.microsoft.com/dotnet/introducing-the-new-microsoftdatasqlclient/) |
| area-System.DateTime | @ericstj | @dotnet/area-system-datetime | System namespace APIs related to dates and times, including DateOnly, DateTime, DateTimeKind, DateTimeOffset, DayOfWeek, TimeOnly, TimeSpan, TimeZone, and TimeZoneInfo |
| area-System.DateTime | @jeffhandley | @dotnet/area-system-datetime | System namespace APIs related to dates and times, including DateOnly, DateTime, DateTimeKind, DateTimeOffset, DayOfWeek, TimeOnly, TimeSpan, TimeZone, and TimeZoneInfo |
| area-System.Diagnostics | @steveisok | @dotnet/area-system-diagnostics | |
| area-System.Diagnostics-coreclr | @steveisok | @dotnet/area-system-diagnostics-coreclr | |
| area-System.Diagnostics-mono | @steveisok | @dotnet/dotnet-diag | |
| area-System.Diagnostics.Activity | @ericstj | @dotnet/area-system-diagnostics-activity | |
| area-System.Diagnostics.EventLog | @ericstj | @dotnet/area-system-diagnostics-eventlog | |
| area-System.Diagnostics.Metric | @ericstj | @dotnet/area-system-diagnostics-metric | |
| area-System.Diagnostics.PerformanceCounter | @ericstj | @dotnet/area-system-diagnostics-performancecounter | |
| area-System.Diagnostics.Activity | @jeffhandley | @dotnet/area-system-diagnostics-activity | |
| area-System.Diagnostics.EventLog | @jeffhandley | @dotnet/area-system-diagnostics-eventlog | |
| area-System.Diagnostics.Metric | @jeffhandley | @dotnet/area-system-diagnostics-metric | |
| area-System.Diagnostics.PerformanceCounter | @jeffhandley | @dotnet/area-system-diagnostics-performancecounter | |
| area-System.Diagnostics.Process | @jeffhandley | @dotnet/area-system-diagnostics-process | |
| area-System.Diagnostics.Tracing | @steveisok | @dotnet/area-system-diagnostics-tracing | Included:<ul><li>System.Diagnostics.DiagnosticSource</li></ul> |
| area-System.Diagnostics.TraceSource | @ericstj | @dotnet/area-system-diagnostics-tracesource | |
| area-System.DirectoryServices | @ericstj | @dotnet/area-system-directoryservices | Consultants: @BRDPM @grubioe @jay98014 |
| area-System.Drawing | @ericstj | @dotnet/area-system-drawing | Excluded:<ul><li>System.Drawing.Common -> winforms</li></ul> |
| area-System.Diagnostics.TraceSource | @jeffhandley | @dotnet/area-system-diagnostics-tracesource | |
| area-System.DirectoryServices | @jeffhandley | @dotnet/area-system-directoryservices | Consultants: @BRDPM @grubioe @jay98014 |
| area-System.Drawing | @jeffhandley | @dotnet/area-system-drawing | Excluded:<ul><li>System.Drawing.Common -> winforms</li></ul> |
| area-System.Dynamic.Runtime | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) |
| area-System.Formats.Asn1 | @jeffhandley | @dotnet/area-system-formats-asn1 | Consultants: @bartonjs @vcsjones |
| area-System.Formats.Cbor | @jeffhandley | @dotnet/area-system-formats-cbor | Consultants: @bartonjs @vcsjones |
| area-System.Formats.Nrbf | @jeffhandley | @dotnet/area-system-formats-nrbf | Consultants: @bartonjs @grabyourpitchforks |
| area-System.Formats.Tar | @ericstj | @dotnet/area-system-formats-tar | |
| area-System.Globalization | @ericstj | @dotnet/area-system-globalization | |
| area-System.Formats.Tar | @jeffhandley | @dotnet/area-system-formats-tar | |
| area-System.Globalization | @jeffhandley | @dotnet/area-system-globalization | |
| area-System.IO | @jeffhandley | @dotnet/area-system-io | |
| area-System.IO.Compression | @ericstj | @dotnet/area-system-io-compression | Included:<ul><li>System.Formats.Tar</li><li>System.IO.Packaging</li></ul> |
| area-System.IO.Compression | @jeffhandley | @dotnet/area-system-io-compression | Included:<ul><li>System.Formats.Tar</li><li>System.IO.Packaging</li></ul> |
| area-System.IO.Hashing | @jeffhandley | @dotnet/area-system-io-hashing | APIs within the System.IO.Hashing namespace, which align more with cryptography than with I/O |
| area-System.IO.Pipelines | @adityamandaleeka | @davidfowl @halter73 | |
| area-System.IO.Ports | @jeffhandley | @dotnet/area-system-io-ports | |
| area-System.Linq | @jeffhandley | @dotnet/area-system-linq | |
| area-System.Linq.Expressions | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) |
| area-System.Linq.Parallel | @jeffhandley | @dotnet/area-system-linq-parallel | Consultants: @stephentoub @kouvel |
| area-System.Management | @ericstj | @dotnet/area-system-management | WMI |
| area-System.Management | @jeffhandley | @dotnet/area-system-management | WMI |
| area-System.Memory | @jeffhandley | @dotnet/area-system-memory | |
| area-System.Net | @karelz | @dotnet/ncl | Included:<ul><li>System.Uri</li></ul> |
| area-System.Net.Http | @karelz | @dotnet/ncl | |
@ -114,25 +114,25 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi
| area-System.Net.Sockets | @karelz | @dotnet/ncl | |
| area-System.Numerics | @jeffhandley | @dotnet/area-system-numerics | |
| area-System.Numerics.Tensors | @jeffhandley | @dotnet/area-system-numerics-tensors | |
| area-System.Reflection | @ericstj | @dotnet/area-system-reflection | |
| area-System.Reflection.Emit | @ericstj | @dotnet/area-system-reflection-emit | |
| area-System.Reflection.Metadata | @ericstj | @dotnet/area-system-reflection-metadata | Consultants: @tmat |
| area-System.Resources | @ericstj | @dotnet/area-system-resources | |
| area-System.Reflection | @jeffhandley | @dotnet/area-system-reflection | |
| area-System.Reflection.Emit | @jeffhandley | @dotnet/area-system-reflection-emit | |
| area-System.Reflection.Metadata | @jeffhandley | @dotnet/area-system-reflection-metadata | Consultants: @tmat |
| area-System.Resources | @jeffhandley | @dotnet/area-system-resources | |
| area-System.Runtime | @jeffhandley | @dotnet/area-system-runtime | Included:<ul><li>System.Runtime.Serialization.Formatters</li><li>System.Runtime.InteropServices.RuntimeInfo</li><li>System.Array</li></ul>Excluded:<ul><li>Path -> System.IO</li><li>StopWatch -> System.Diagnostics</li><li>Uri -> System.Net</li><li>WebUtility -> System.Net</li></ul> |
| area-System.Runtime.Caching | @HongGit | @StephenMolloy @HongGit | |
| area-System.Runtime.CompilerServices | @ericstj | @dotnet/area-system-runtime-compilerservices | |
| area-System.Runtime.Caching | @StephenMolloy | @StephenMolloy @dotnet/Tellurium | |
| area-System.Runtime.CompilerServices | @jeffhandley | @dotnet/area-system-runtime-compilerservices | |
| area-System.Runtime.InteropServices | @agocke | @AaronRobinsonMSFT @jkoritzinsky | Excluded:<ul><li>System.Runtime.InteropServices.RuntimeInfo</li></ul> |
| area-System.Runtime.InteropServices.JavaScript | @lewing | @pavelsavara | |
| area-System.Runtime.Intrinsics | @jeffhandley | @dotnet/area-system-runtime-intrinsics | Consultants: @echesakovMSFT @kunalspathak |
| area-System.Security | @jeffhandley | @dotnet/area-system-security | Consultants: @bartonjs @GrabYourPitchforks @SteveHarter @vcsjones @wfurt |
| area-System.ServiceModel | @HongGit | @HongGit @mconnew | Repo: https://github.com/dotnet/WCF<br>Packages:<ul><li>System.ServiceModel.Primitives</li><li>System.ServiceModel.Http</li><li>System.ServiceModel.NetTcp</li><li>System.ServiceModel.Duplex</li><li>System.ServiceModel.Security</li></ul> |
| area-System.ServiceModel.Syndication | @HongGit | @StephenMolloy @HongGit | |
| area-System.ServiceProcess | @ericstj | @dotnet/area-system-serviceprocess | |
| area-System.Speech | @ericstj | @dotnet/area-system-speech | |
| area-System.Text.Encoding | @ericstj | @dotnet/area-system-text-encoding | |
| area-System.Text.Encodings.Web | @ericstj | @dotnet/area-system-text-encodings-web | |
| area-System.Security | @jeffhandley | @dotnet/area-system-security | Consultants: @bartonjs @GrabYourPitchforks @vcsjones @wfurt |
| area-System.ServiceModel | @mconnew | @mconnew @dotnet/Tellurium | Repo: https://github.com/dotnet/WCF<br>Packages:<ul><li>System.ServiceModel.Primitives</li><li>System.ServiceModel.Http</li><li>System.ServiceModel.NetTcp</li><li>System.ServiceModel.Duplex</li><li>System.ServiceModel.Security</li></ul> |
| area-System.ServiceModel.Syndication | @StephenMolloy | @StephenMolloy @dotnet/Tellurium | |
| area-System.ServiceProcess | @jeffhandley | @dotnet/area-system-serviceprocess | |
| area-System.Speech | @jeffhandley | @dotnet/area-system-speech | |
| area-System.Text.Encoding | @jeffhandley | @dotnet/area-system-text-encoding | |
| area-System.Text.Encodings.Web | @jeffhandley | @dotnet/area-system-text-encodings-web | |
| area-System.Text.Json | @jeffhandley | @dotnet/area-system-text-json | |
| area-System.Text.RegularExpressions | @ericstj | @dotnet/area-system-text-regularexpressions | Consultants: @stephentoub |
| area-System.Text.RegularExpressions | @jeffhandley | @dotnet/area-system-text-regularexpressions | Consultants: @stephentoub |
| area-System.Threading | @mangod9 | @kouvel @vsadov | |
| area-System.Threading.Channels | @jeffhandley | @dotnet/area-system-threading-channels | Consultants: @stephentoub |
| area-System.Threading.RateLimiting | @rafikiassumani-msft | @BrennanConroy @halter73 | |
@ -141,7 +141,7 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi
| area-System.Xml | @jeffhandley | @dotnet/area-system-xml | |
| area-TieredCompilation-coreclr | @mangod9 | @kouvel | |
| area-Tools-ILLink | @agocke | @dotnet/illink | |
| area-Tools-ILVerification | @JulieLeeMSFT | @BruceForstall @dotnet/jit-contrib | |
| area-Tools-ILVerification | @JulieLeeMSFT | @dotnet/jit-contrib | |
| area-Tracing-coreclr | @steveisok | @dotnet/area-tracing-coreclr | .NET runtime issues for EventPipe and ICorProfiler |
| area-Tracing-mono | @steveisok | @dotnet/dotnet-diag @thaystg | |
| area-TypeSystem-coreclr | @mangod9 | @davidwrighton @MichalStrehovsky @janvorli @mangod9 | |

View File

@ -15,12 +15,6 @@ We have the following goals related to interop code being used in dotnet/runtime
- Ensure maximal managed code reuse across different OS flavors which have the same API but not the same ABI.
- This is the case for UNIX and addressing it is a work-in-progress (see issue #2137 and section on "shims" below.)
## Submitting Changes
Interop code implicitly defines the native platform dependencies that .NET has. These dependencies are tracked and modeled according to the [Tracking Platform Dependencies design](https://github.com/dotnet/designs/blob/main/accepted/2021/platform-dependencies/platform-dependencies.md). Whenever a PR is submitted that changes interop code, it needs to be reviewed to determine whether a change to the platform dependencies model is required.
By default, any change to `src/libraries/Common/src/Interop` folder will add @dotnet/platform-deps-team as a reviewer. If necessary, update the corresponding `https://github.com/dotnet/core/blob/main/release-notes/<product-version>/runtime-deps.json` file to reflect the dependency change. The scope of dependencies is at the file/package level, not individual functions, so interop changes rarely require an update to the model.
## Approach
### Interop type

View File

@ -523,7 +523,7 @@ int ManagedReferencesSum(int[] buffer)
Vector128<int> sum = Vector128<int>.Zero;
while (!Unsafe.IsAddressGreaterThan(ref current, ref oneVectorAwayFromEnd))
while (Unsafe.IsAddressLessThanOrEqualTo(ref current, ref oneVectorAwayFromEnd))
{
sum += Vector128.LoadUnsafe(ref current);
@ -561,7 +561,7 @@ do
return ...;
}
while (!Unsafe.IsAddressLessThan(ref currentSearchSpace, ref searchSpace));
while (Unsafe.IsAddressGreaterThanOrEqualTo(ref currentSearchSpace, ref searchSpace));
```
It was part of `LastIndexOf` implementation, where we were iterating from the end to the beginning of the buffer. In the last iteration of the loop, `currentSearchSpace` could become a pointer to unknown memory that lied before the beginning of the buffer:
@ -573,7 +573,7 @@ currentSearchSpace = ref Unsafe.Subtract(ref currentSearchSpace, Vector128<TValu
And it was fine until GC kicked right after that, moved objects in memory, updated all valid managed references and resumed the execution, which run following condition:
```csharp
while (!Unsafe.IsAddressLessThan(ref currentSearchSpace, ref searchSpace));
while (Unsafe.IsAddressGreaterThanOrEqualTo(ref currentSearchSpace, ref searchSpace));
```
Which could return true because `currentSearchSpace` was invalid and not updated. If you are interested in more details, you can check the [issue](https://github.com/dotnet/runtime/issues/75792#issuecomment-1249973858) and the [fix](https://github.com/dotnet/runtime/pull/75857).

View File

@ -712,22 +712,82 @@ the first byte of the encoding specify the number of following bytes as follows:
## Sparse Array
**TODO**: Document native format sparse array
The NativeArray provides O(1) indexed access while maintaining compact storage through null element compression (empty blocks share storage) and variable-sized offset encoding (adapts to data size).
The array is made up of three parts, the header, block index, and the blocks.
The header is a variable encoded value where:
- Bits 0-1: Entry index size
- 0 = uint8 offsets
- 1 = uint16 offsets
- 2 = uint32 offsets
- Bits 2-31: Number of elements in the array
The block index immediately follows the header in memory and consists of one offset entry per block (dynamic size encoded in the header), where each entry points to the location of a data block relative to the start of the block index section. The array uses a maximum block size of 16 elements, the block index effectively maps every group of 16 consecutive array indices to their corresponding data blocks.
The following the block index are the actual data blocks. These are made up of two types of nodes. Tree nodes and Data nodes.
Tree nodes are made up of a variable length encoded uint where:
- Bit 0: If set, the node has a lower index child
- Bit 1: If set, the node has a higher index child
- Bits 2-31: Shifted relative offset of higher index child
Data nodes contain the user defined data.
Since each block has at most 16 elements, they have a depth of `4`.
### Lookup Algorithm Steps
**Step 1: Read the Header**
- Decode the variable-length encoded header value from the array
- Extract the entry index size from bits 0-1 (0=uint8, 1=uint16, 2=uint32 offsets)
- Extract the total number of elements from bits 2-31 by right-shifting the header value by 2 bits
- Use this information to determine how to interpret the block index entries and validate array bounds
**Step 2: Calculate Block Offset**
- Determine the block index `blockIndex` containing the target element by dividing the index by the block size (16).
- Calculate the memory location containing the block offset `pBlockOffset = baseOffset + entrySize * blockIndex` where `baseOffset` is the address immediately following the header and `entrySize` is determined by the low bits of the header.
- Read the block offset `blockOffset` from the block index table using the calculated `pBlockOffset` and entry size determined by the header.
- Add the `baseOffset` to convert the relative `blockOffset` to an absolute position.
**Step 3: Initialize Tree Navigation**
- Using the `blockOffset` calculated above, begin traversal at the root of the block's binary tree structure
**Step 4: Navigate Binary Tree**
For each level of the tree (iterating through bit positions 8, 4, 2, 1):
**Step 4a: Read Node Descriptor**
- Decode the current node's control value, which contains navigation flags and child offset information
- Extract flags indicating the presence of left and right child nodes
- Extract the relative offset to the right child node (if present)
**Step 4b: Determine Navigation Direction**
- Test the current bit position against the target index
- If the bit is set in the target index, attempt to navigate to the right child
- If the bit is clear in the target index, attempt to navigate to the left child
**Step 4c: Follow Navigation Path**
- If the desired child exists (indicated by the appropriate flag), update the current position
- For right child navigation, add the encoded offset to the current position
- For left child navigation, move to the position immediately following the current node
- Continue to the next bit level if navigation was successful
**Step 5: Return Element Location**
- Upon successful traversal, return the final offset position which points to the stored data.
- If traversal is not successful (child node does not exist), the element can not be found in the array and return a failure status.
## Hashtable
Conceptually, a native hash table is a header that describe the dimensions of the table, a table that maps hash values of the keys to buckets followed with a list of buckets that store the values. These three things are stored consecutively in the format.
To make look up fast, the number of buckets is always a power of 2. The table is simply a sequence of `(1 + number of buckets)` cells, for the first `(number of buckets)` cells, its stores the offset of the bucket list from the beginning of the whole native hash table. The last cell stores the offset to the end of the buckets.
Each bucket is a sequence of entries. An entry has a hash code and an offset to the object stored. The entries are sorted by hash code.
To make look up fast, the number of buckets is always a power of 2. The table is simply a sequence of `(1 + number of buckets)` cells, for the first `(number of buckets)` cells, its stores the offset of the bucket list from the beginning of the whole native hash table. The last cell stores the offset to the end of the buckets. Entries are mapped to buckets using `x` lowest bits of the hash not in the lowest byte where `2^x = (number of buckets)`. For example, if `x=2` the following bits marked with `X` would be used in a 32-bit hash `b00000000_00000000_000000XX_00000000`.
Physically, the header is a single byte. The most significant six bits is used to store the number of buckets in its base-2 logarithm. The remaining two bits are used for storing the entry size, as explained below:
Because the offsets to the bucket lists are often small numbers, the table cells are variable sized.
It could be either 1 byte, 2 bytes or 4 bytes. The three cases are described with two bits. `00` means it is one byte, `01` means it is two bytes and `10` means it is four bytes.
The remaining data are the entries. The entries has only the least significant byte of the hash code, followed by the offset to the actual object stored in the hash table.
The remaining data are the entries. The entries has only the least significant byte of the hash code, followed by the offset to the actual object stored in the hash table. The entries are sorted by hash code.
To perform a lookup, one starts with reading the header, computing the hash code, using the number of buckets to determine the number of bits to mask away from the hash code, look it up in the table using the right pointer size, find the bucket list, find the next bucket list (or the end of the table) so that we know where to stop, search the entries in that list and then we will find the object if we have a hit, or we have a miss.
@ -740,23 +800,23 @@ To see this in action, we can take a look at the following example, with these o
| P | 0x1231 |
| Q | 0x1232 |
| R | 0x1234 |
| S | 0x1238 |
| S | 0x1338 |
Suppose we decided to have only two buckets, then only the least significant digit will be used to index the table, the whole hash table will look like this:
Suppose we decided to have only two buckets, then only the 9th bit will be used to index the table, the whole hash table will look like this:
| Part | Offset | Content | Meaning |
|:--------|:-------|:--------:|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Header | 0 | 0x04 | This is the header, the least significant bit is `00`, therefore the table cell is just one byte. The most significant six bit represents 1, which means the number of buckets is 2^1 = 2. |
| Table | 1 | 0x08 | This is the representation of the unsigned integer 4, which correspond to the offset of the bucket correspond to hash code `0`. |
| Table | 2 | 0x14 | This is the representation of the unsigned integer 10, which correspond to the offset of the bucket correspond to hash code `1`. |
| Table | 3 | 0x18 | This is the representation of the unsigned integer 12, which correspond to the offset of the end of the whole hash table. |
| Bucket1 | 4 | 0x32 | This is the least significant byte of the hash code of P |
| Table | 1 | 0x04 | This is the representation of the unsigned integer 4, which correspond to the offset of the bucket correspond to hash code `0`. |
| Table | 2 | 0x0A | This is the representation of the unsigned integer 10, which correspond to the offset of the bucket correspond to hash code `1`. |
| Table | 3 | 0x0C | This is the representation of the unsigned integer 12, which correspond to the offset of the end of the whole hash table. |
| Bucket1 | 4 | 0x31 | This is the least significant byte of the hash code of P |
| Bucket1 | 5 | P | This should be the offset to the object P |
| Bucket1 | 6 | 0x34 | This is the least significant byte of the hash code of Q |
| Bucket1 | 6 | 0x32 | This is the least significant byte of the hash code of Q |
| Bucket1 | 7 | Q | This should be the offset to the object Q |
| Bucket1 | 8 | 0x38 | This is the least significant byte of the hash code of R |
| Bucket1 | 8 | 0x34 | This is the least significant byte of the hash code of R |
| Bucket1 | 9 | R | This should be the offset to the object R |
| Bucket2 | 10 | 0x31 | This is the least significant byte of the hash code of S |
| Bucket2 | 10 | 0x38 | This is the least significant byte of the hash code of S |
| Bucket2 | 11 | S | This should be the offset to the object S |

View File

@ -132,7 +132,7 @@ IEnumerable<ILCodeVersionHandle> ICodeVersions.GetILCodeVersions(TargetPointer m
// CodeVersionManager::GetILCodeVersions
GetModuleAndMethodDesc(methodDesc, out TargetPointer module, out uint methodDefToken);
ModuleHandle moduleHandle = _target.Contracts.Loader.GetModuleHandle(module);
ModuleHandle moduleHandle = _target.Contracts.Loader.GetModuleHandleFromModulePtr(module);
TargetPointer ilCodeVersionTable = _target.Contracts.Loader.GetLookupTables(moduleHandle).MethodDefToILCodeVersioningState;
TargetPointer ilVersionStateAddress = _target.Contracts.Loader.GetModuleLookupMapElement(ilCodeVersionTable, methodDefToken, out var _);
@ -247,7 +247,7 @@ bool ICodeVersions.CodeVersionManagerSupportsMethod(TargetPointer methodDescAddr
TypeHandle mt = rts.GetTypeHandle(mtAddr);
TargetPointer modAddr = rts.GetModule(mt);
ILoader loader = _target.Contracts.Loader;
ModuleHandle mod = loader.GetModuleHandle(modAddr);
ModuleHandle mod = loader.GetModuleHandleFromModulePtr(modAddr);
ModuleFlags modFlags = loader.GetFlags(mod);
if (modFlags.HasFlag(ModuleFlags.EditAndContinue))
return false;

View File

@ -52,9 +52,12 @@ record struct ModuleLookupTables(
```
``` csharp
ModuleHandle GetModuleHandle(TargetPointer module);
IEnumerable<ModuleHandle> GetModules(TargetPointer appDomain, AssemblyIterationFlags iterationFlags);
ModuleHandle GetModuleHandleFromModulePtr(TargetPointer module);
ModuleHandle GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer);
IEnumerable<ModuleHandle> GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags);
TargetPointer GetRootAssembly();
string GetAppDomainFriendlyName();
TargetPointer GetModule(ModuleHandle handle);
TargetPointer GetAssembly(ModuleHandle handle);
TargetPointer GetPEAssembly(ModuleHandle handle);
bool TryGetLoadedImageContents(ModuleHandle handle, out TargetPointer baseAddress, out uint size, out uint imageFlags);
@ -64,12 +67,16 @@ ModuleFlags GetFlags(ModuleHandle handle);
string GetPath(ModuleHandle handle);
string GetFileName(ModuleHandle handle);
TargetPointer GetLoaderAllocator(ModuleHandle handle);
TargetPointer GetThunkHeap(ModuleHandle handle);
TargetPointer GetILBase(ModuleHandle handle);
TargetPointer GetAssemblyLoadContext(ModuleHandle handle);
ModuleLookupTables GetLookupTables(ModuleHandle handle);
TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags);
bool IsCollectible(ModuleHandle handle);
bool IsAssemblyLoaded(ModuleHandle handle);
TargetPointer GetGlobalLoaderAllocator();
TargetPointer GetHighFrequencyHeap(TargetPointer loaderAllocatorPointer);
TargetPointer GetLowFrequencyHeap(TargetPointer loaderAllocatorPointer);
TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer);
```
## Version 1
@ -82,7 +89,6 @@ bool IsAssemblyLoaded(ModuleHandle handle);
| `Module` | `Base` | Pointer to start of PE file in memory |
| `Module` | `Flags` | Assembly of the Module |
| `Module` | `LoaderAllocator` | LoaderAllocator of the Module |
| `Module` | `ThunkHeap` | Pointer to the thunk heap |
| `Module` | `Path` | Path of the Module (UTF-16, null-terminated) |
| `Module` | `FileName` | File name of the Module (UTF-16, null-terminated) |
| `Module` | `GrowableSymbolStream` | Pointer to the in memory symbol stream |
@ -102,6 +108,8 @@ bool IsAssemblyLoaded(ModuleHandle handle);
| `Assembly` | `NotifyFlags` | Flags relating to the debugger/profiler notification state of the assembly |
| `Assembly` | `Level` | File load level of the assembly |
| `PEAssembly` | `PEImage` | Pointer to the PEAssembly's PEImage |
| `PEAssembly` | `AssemblyBinder` | Pointer to the PEAssembly's binder |
| `AssemblyBinder` | `ManagedAssemblyLoadContext` | Pointer to the AssemblyBinder's ManagedAssemblyLoadContext |
| `PEImage` | `LoadedImageLayout` | Pointer to the PEImage's loaded PEImageLayout |
| `PEImage` | `ProbeExtensionResult` | PEImage's ProbeExtensionResult |
| `ProbeExtensionResult` | `Type` | Type of ProbeExtensionResult |
@ -112,18 +120,24 @@ bool IsAssemblyLoaded(ModuleHandle handle);
| `CGrowableSymbolStream` | `Size` | Size of the raw symbol stream buffer |
| `AppDomain` | `RootAssembly` | Pointer to the root assembly |
| `AppDomain` | `DomainAssemblyList` | ArrayListBase of assemblies in the AppDomain |
| `AppDomain` | `FriendlyName` | Friendly name of the AppDomain |
| `LoaderAllocator` | `ReferenceCount` | Reference count of LoaderAllocator |
| `LoaderAllocator` | `HighFrequencyHeap` | High-frequency heap of LoaderAllocator |
| `LoaderAllocator` | `LowFrequencyHeap` | Low-frequency heap of LoaderAllocator |
| `LoaderAllocator` | `StubHeap` | Stub heap of LoaderAllocator |
| `ArrayListBase` | `Count` | Total number of elements in the ArrayListBase |
| `ArrayListBase` | `FirstBlock` | First ArrayListBlock |
| `ArrayListBlock` | `Next` | Next ArrayListBlock in chain |
| `ArrayListBlock` | `Size` | Size of data section in block |
| `ArrayListBlock` | `ArrayStart` | Start of data section in block |
| `SystemDomain` | `GlobalLoaderAllocator` | global LoaderAllocator |
### Global variables used:
| Global Name | Type | Purpose |
| --- | --- | --- |
| `AppDomain` | TargetPointer | Pointer to the global AppDomain |
| `SystemDomain` | TargetPointer | Pointer to the global SystemDomain |
### Contract Constants:
@ -146,12 +160,18 @@ private enum ModuleFlags_1 : uint
### Method Implementations
``` csharp
ModuleHandle GetModuleHandle(TargetPointer modulePointer)
ModuleHandle GetModuleHandleFromModulePtr(TargetPointer modulePointer)
{
return new ModuleHandle(modulePointer);
}
IEnumerable<ModuleHandle> GetModules(TargetPointer appDomain, AssemblyIterationFlags iterationFlags)
ModuleHandle ILoader.GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer)
{
Data.Assembly assembly = // read Assembly object at assemblyPointer
return new ModuleHandle(assembly.Module);
}
IEnumerable<ModuleHandle> GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags)
{
if (appDomain == TargetPointer.Null) throw new ArgumentException("appDomain must not be null");
@ -255,6 +275,20 @@ TargetPointer GetRootAssembly()
return appDomain.RootAssembly;
}
string ILoader.GetAppDomainFriendlyName()
{
TargetPointer appDomainPointer = target.ReadGlobalPointer(Constants.Globals.AppDomain);
TargetPointer appDomain = target.ReadPointer(appDomainPointer)
TargetPointer pathStart = appDomain + /* AppDomain::FriendlyName offset */;
char[] name = // Read<char> from target starting at pathStart until null terminator
return new string(name);
}
TargetPointer ILoader.GetModule(ModuleHandle handle)
{
return handle.Address;
}
TargetPointer GetAssembly(ModuleHandle handle)
{
return target.ReadPointer(handle.Address + /* Module::Assembly offset */);
@ -348,16 +382,19 @@ TargetPointer GetLoaderAllocator(ModuleHandle handle)
return target.ReadPointer(handle.Address + /* Module::LoaderAllocator offset */);
}
TargetPointer GetThunkHeap(ModuleHandle handle)
{
return target.ReadPointer(handle.Address + /* Module::ThunkHeap offset */);
}
TargetPointer GetILBase(ModuleHandle handle)
{
return target.ReadPointer(handle.Address + /* Module::Base offset */);
}
TargetPointer ILoader.GetAssemblyLoadContext(ModuleHandle handle)
{
PEAssembly peAssembly = target.ReadPointer(handle.Address + /* Module::PEAssembly offset */);
AssemblyBinder binder = target.ReadPointer(peAssembly + /* PEAssembly::AssemblyBinder offset */);
ObjectHandle objectHandle = new ObjectHandle(binder);
return objectHandle.Object;
}
ModuleLookupTables GetLookupTables(ModuleHandle handle)
{
return new ModuleLookupTables(
@ -380,38 +417,59 @@ TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out Tar
uint index = rid;
// have to read lookupMap an extra time upfront because only the first map
// has valid supportedFlagsMask
TargetNUInt supportedFlagsMask = _target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */);
TargetNUInt supportedFlagsMask = target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */);
do
{
if (index < _target.Read<uint>(table + /*ModuleLookupMap::Count*/))
if (index < target.Read<uint>(table + /*ModuleLookupMap::Count*/))
{
TargetPointer entryAddress = _target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * _target.PointerSize);
TargetPointer rawValue = _target.ReadPointer(entryAddress);
TargetPointer entryAddress = target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * target.PointerSize);
TargetPointer rawValue = target.ReadPointer(entryAddress);
flags = rawValue & supportedFlagsMask;
return rawValue & ~(supportedFlagsMask.Value);
}
else
{
table = _target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/);
index -= _target.Read<uint>(lookupMap + /*ModuleLookupMap::Count*/);
table = target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/);
index -= target.Read<uint>(lookupMap + /*ModuleLookupMap::Count*/);
}
} while (table != TargetPointer.Null);
return TargetPointer.Null;
}
```
```csharp
bool ILoader.IsCollectible(ModuleHandle handle)
bool IsCollectible(ModuleHandle handle)
{
TargetPointer assembly = _target.ReadPointer(handle.Address + /*Module::Assembly*/);
byte isCollectible = _target.Read<byte>(assembly + /* Assembly::IsCollectible*/);
TargetPointer assembly = target.ReadPointer(handle.Address + /*Module::Assembly*/);
byte isCollectible = target.Read<byte>(assembly + /* Assembly::IsCollectible*/);
return isCollectible != 0;
}
bool ILoader.IsAssemblyLoaded(ModuleHandle handle)
bool IsAssemblyLoaded(ModuleHandle handle)
{
TargetPointer assembly = _target.ReadPointer(handle.Address + /*Module::Assembly*/);
uint loadLevel = _target.Read<uint>(assembly + /* Assembly::Level*/);
TargetPointer assembly = target.ReadPointer(handle.Address + /*Module::Assembly*/);
uint loadLevel = target.Read<uint>(assembly + /* Assembly::Level*/);
return assembly.Level >= ASSEMBLY_LEVEL_LOADED;
}
TargetPointer GetGlobalLoaderAllocator()
{
TargetPointer systemDomainPointer = target.ReadGlobalPointer(Constants.Globals.SystemDomain);
TargetPointer systemDomain = target.ReadPointer(systemDomainPointer);
return target.ReadPointer(systemDomain + /* SystemDomain::GlobalLoaderAllocator offset */);
}
TargetPointer GetHighFrequencyHeap(TargetPointer loaderAllocatorPointer)
{
return target.ReadPointer(loaderAllocatorPointer + /* LoaderAllocator::HighFrequencyHeap offset */);
}
TargetPointer GetLowFrequencyHeap(TargetPointer loaderAllocatorPointer)
{
return target.ReadPointer(loaderAllocatorPointer + /* LoaderAllocator::LowFrequencyHeap offset */);
}
TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer)
{
return target.ReadPointer(loaderAllocatorPointer + /* LoaderAllocator::StubHeap offset */);
}
```

View File

@ -51,14 +51,18 @@ partial interface IRuntimeTypeSystem : IContract
// True if the MethodTable represents a type that contains managed references
public virtual bool ContainsGCPointers(TypeHandle typeHandle);
public virtual bool IsDynamicStatics(TypeHandle typeHandle);
public virtual ushort GetNumMethods(TypeHandle typeHandle);
public virtual ushort GetNumInterfaces(TypeHandle typeHandle);
// Returns an ECMA-335 TypeDef table token for this type, or for its generic type definition if it is a generic instantiation
public virtual uint GetTypeDefToken(TypeHandle typeHandle);
public virtual ushort GetNumMethods(TypeHandle typeHandle);
// Returns the ECMA 335 TypeDef table Flags value (a bitmask of TypeAttributes) for this type,
// or for its generic type definition if it is a generic instantiation
public virtual uint GetTypeDefTypeAttributes(TypeHandle typeHandle);
public ushort GetNumInstanceFields(TypeHandle typeHandle);
public ushort GetNumStaticFields(TypeHandle typeHandle);
public ushort GetNumThreadStaticFields(TypeHandle typeHandle);
public TargetPointer GetFieldDescList(TypeHandle typeHandle);
public virtual ReadOnlySpan<TypeHandle> GetInstantiation(TypeHandle typeHandle);
public virtual bool IsGenericTypeDefinition(TypeHandle typeHandle);
@ -348,6 +352,10 @@ The contract additionally depends on these data descriptors
| `EEClass` | `NumMethods` | Count of methods attached to the EEClass |
| `EEClass` | `NumNonVirtualSlots` | Count of non-virtual slots for the EEClass |
| `EEClass` | `CorTypeAttr` | Various flags |
| `EEClass` | `NumInstanceFields` | Count of instance fields of the EEClass |
| `EEClass` | `NumStaticFields` | Count of static fields of the EEClass |
| `EEClass` | `NumThreadStaticFields` | Count of threadstatic fields of the EEClass |
| `EEClass` | `FieldDescList` | A list of fields in the type |
| `ArrayClass` | `Rank` | Rank of the associated array MethodTable |
| `TypeDesc` | `TypeAndFlags` | The lower 8 bits are the CorElementType of the `TypeDesc`, the upper 24 bits are reserved for flags |
| `ParamTypeDesc` | `TypeArg` | Associated type argument |
@ -374,32 +382,6 @@ The contract additionally depends on these data descriptors
return TypeHandle { Address = typeHandlePointer }
}
internal static EEClassOrCanonMTBits GetEEClassOrCanonMTBits(TargetPointer eeClassOrCanonMTPtr)
{
return (EEClassOrCanonMTBits)(eeClassOrCanonMTPtr & (ulong)EEClassOrCanonMTBits.Mask);
}
public uint GetBaseSize(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? (uint)0 : _methodTables[TypeHandle.Address].Flags.BaseSize;
public uint GetComponentSize(TypeHandle TypeHandle) =>!typeHandle.IsMethodTable() ? (uint)0 : GetComponentSize(_methodTables[TypeHandle.Address]);
private TargetPointer GetClassPointer(TypeHandle TypeHandle)
{
... // if the MethodTable stores a pointer to the EEClass, return it
// otherwise the MethodTable stores a pointer to the canonical MethodTable
// in that case, return the canonical MethodTable's EEClass.
// Canonical MethodTables always store an EEClass pointer.
}
private Data.EEClass GetClassData(TypeHandle TypeHandle)
{
TargetPointer eeClassPtr = GetClassPointer(TypeHandle);
... // read Data.EEClass data from eeClassPtr
}
public TargetPointer GetCanonicalMethodTable(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(TypeHandle).MethodTable;
public TargetPointer GetModule(TypeHandle TypeHandle)
{
if (typeHandle.IsMethodTable())
@ -420,13 +402,43 @@ The contract additionally depends on these data descriptors
return TargetPointer.Null;
}
internal static EEClassOrCanonMTBits GetEEClassOrCanonMTBits(TargetPointer eeClassOrCanonMTPtr)
{
return (EEClassOrCanonMTBits)(eeClassOrCanonMTPtr & (ulong)EEClassOrCanonMTBits.Mask);
}
public TargetPointer GetCanonicalMethodTable(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(TypeHandle).MethodTable;
public TargetPointer GetParentMethodTable(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : _methodTables[TypeHandle.Address].ParentMethodTable;
public uint GetBaseSize(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? (uint)0 : _methodTables[TypeHandle.Address].Flags.BaseSize;
public uint GetComponentSize(TypeHandle TypeHandle) =>!typeHandle.IsMethodTable() ? (uint)0 : GetComponentSize(_methodTables[TypeHandle.Address]);
private TargetPointer GetClassPointer(TypeHandle TypeHandle)
{
... // if the MethodTable stores a pointer to the EEClass, return it
// otherwise the MethodTable stores a pointer to the canonical MethodTable
// in that case, return the canonical MethodTable's EEClass.
// Canonical MethodTables always store an EEClass pointer.
}
private Data.EEClass GetClassData(TypeHandle TypeHandle)
{
TargetPointer eeClassPtr = GetClassPointer(TypeHandle);
... // read Data.EEClass data from eeClassPtr
}
public bool IsFreeObjectMethodTable(TypeHandle TypeHandle) => FreeObjectMethodTablePointer == TypeHandle.Address;
public bool IsString(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsString;
public bool ContainsGCPointers(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.ContainsGCPointers;
public bool IsDynamicStatics(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsDynamicStatics;
public ushort GetNumInterfaces(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : _methodTables[TypeHandle.Address].NumInterfaces;
public uint GetTypeDefToken(TypeHandle TypeHandle)
{
if (!typeHandle.IsMethodTable())
@ -438,11 +450,15 @@ The contract additionally depends on these data descriptors
public ushort GetNumMethods(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : GetClassData(TypeHandle).NumMethods;
public ushort GetNumInterfaces(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : _methodTables[TypeHandle.Address].NumInterfaces;
public uint GetTypeDefTypeAttributes(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : GetClassData(TypeHandle).CorTypeAttr;
public bool IsDynamicStatics(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsDynamicStatics;
public ushort GetNumInstanceFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumInstanceFields;
public ushort GetNumStaticFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumStaticFields;
public ushort GetNumThreadStaticFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumThreadStaticFields;
public TargetPointer GetFieldDescList(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(typeHandle).FieldDescList;
public ReadOnlySpan<TypeHandle> GetInstantiation(TypeHandle TypeHandle)
{
@ -1004,7 +1020,7 @@ Determining if a method is in a collectible module:
{
MethodDesc md = _methodDescs[methodDesc.Address];
TargetPointer loaderModuleAddr = GetLoaderModule(md);
ModuleHandle mod = _target.Contracts.Loader.GetModuleHandle(loaderModuleAddr);
ModuleHandle mod = _target.Contracts.Loader.GetModuleHandleFromModulePtr(loaderModuleAddr);
return _target.Contracts.Loader.IsCollectible(mod);
}

View File

@ -46,7 +46,6 @@ record struct ThreadData (
ThreadStoreData GetThreadStoreData();
ThreadStoreCounts GetThreadCounts();
ThreadData GetThreadData(TargetPointer threadPointer);
TargetPointer GetManagedThreadObject(TargetPointer threadPointer);
```
## Version 1
@ -128,10 +127,4 @@ ThreadData GetThreadData(TargetPointer address)
NextThread: target.ReadPointer(address + /* Thread::LinkNext offset */) - threadLinkOffset;
);
}
TargetPointer GetManagedThreadObject(TargetPointer threadPointer)
{
var runtimeThread = new Thread(Target, threadPointer);
return Contracts.GCHandle.GetObject(new DacGCHandle(runtimeThread.m_ExposedObject));
}
```

View File

@ -0,0 +1,22 @@
# Debug Interface Globals
The following document lists the global variables that are used directly in the debug interface managed code (SOSDacImpl.cs, etc.)
Global variables used
| Global Name | Type | Purpose |
| --- | --- | --- |
| StringMethodTable | TargetPointer | Identify where the string MethodTable exists |
| ObjectMethodTable | TargetPointer | Identify where the object MethodTable exists |
| SystemDomain | TargetPointer | Identify where the SystemDomain exists |
| DirectorySeparator | TargetPointer | Identify where the directory separator exists |
| FeatureCOMInterop | TargetPointer | Identify where the flag for FeatureCOMInterop exists |
| StressLog | TargetPointer | Identify where the StressLog exists |
| AppDomain | TargetPointer | Identify where the AppDomain exists |
| ObjectArrayMethodTable | TargetPointer | Identify where the ObjectArrayMethodTable exists |
| ExceptionMethodTable | TargetPointer | Identify where the ExceptionMethodTable exists |
| FreeObjectMethodTable | TargetPointer | Identify where the FreeObjectMethodTable exists |
| SOSBreakingChangeVersion | TargetPointer | Identify where the SOSBreakingChangeVersion exists |
| DacNotificationFlags | TargetPointer | Identify where the DacNotificationFlags exists |
| MaxClrNotificationArgs | uint32 | Identify the maximum number of CLR notification arguments |
| ClrNotificationArguments | TargetPointer | Identify where the ClrNotificationArguments exists |
| DefaultADID | uint | Identify the default AppDomain ID |

View File

@ -41,7 +41,7 @@ Each IR instruction is represented by a MonoInst structure. The fields of the st
- ins-\>opcode contains the opcode of the instruction. It is always set.
- ins-\>dreg, ins-\>sreg1, ins-\>sreg2 contain the the destination and source vregs of the instruction. If the instruction doesn't have a destination/and our source, the corresponding field is set to -1.
- ins-\>dreg, ins-\>sreg1, ins-\>sreg2 contain the destination and source vregs of the instruction. If the instruction doesn't have a destination/and our source, the corresponding field is set to -1.
- ins-\>backend is used for various purposes:
- for MonoInst's representing vtype variables, it indicates that the variable is in unmanaged format (used during marshalling)

View File

@ -392,7 +392,7 @@ Each command requires at least one TypeID (of type id) parameter before any addi
| GET_FIELD_CATTRS | 11 | Returns a list of custom attributes of a type's field. Custom attribute definition is given below. | Ask for a FieldID of one the type field and a TypeID of an custom attribute type | INVALID_TYPEID, INVALID_FIELDID |
| GET_PROPERTY_CATTRS | 12 | Returns a list of custom attributes of a type's property. Custom attribute definition is given below. | Ask for a PropertyID of one the type field and a TypeID of an custom attribute type | INVALID_TYPEID, INVALID_PROPERTYID |
| GET_SOURCE_FILES_2 | 13 | Returns a list of source file full paths (string) where the type is defined | None | INVALID_TYPEID |
| GET_VALUES_2 | 14 | Returns a number of variant value equals to the number of FieldID that was passed as parameter. If the field had a ThreadStatic attribute applied to it, value fetched are from the thread parameter point of view. | Ask for an ObjectID representing a System.Thread instance and a list of FieldID representing this type static fields to the the value of. Only static field are supported. | INVALID_OBJECT, INVALID_TYPEID, INVALID_FIELDID |
| GET_VALUES_2 | 14 | Returns a number of variant value equals to the number of FieldID that was passed as parameter. If the field had a ThreadStatic attribute applied to it, value fetched are from the thread parameter point of view. | Ask for an ObjectID representing a System.Thread instance and a list of FieldID representing this type static fields to the value of. Only static field are supported. | INVALID_OBJECT, INVALID_TYPEID, INVALID_FIELDID |
The main functions handling these commands are `type_commands` and `type_commands_internal` and are situated at `debugger-agent.c:6726` and `debugger-agent.c:6403` respectively.

View File

@ -128,7 +128,7 @@ Concretely, in the face of adversarial input:
## Implementation
The `HashCode` type uses the [**xxHash32**](https://github.com/Cyan4973/xxHash) algorithm, which is a non-cryptographic hash algorithm with a 32-bit seed and a 32-bit digest. All instances of the `HashCode` type use the same seed value, generated randomly at app start. This value is chosen independently of other random seed values in the runtime, such as the the global 64-bit seed used in `string.GetHashCode`'s Marvin32 routine.
The `HashCode` type uses the [**xxHash32**](https://github.com/Cyan4973/xxHash) algorithm, which is a non-cryptographic hash algorithm with a 32-bit seed and a 32-bit digest. All instances of the `HashCode` type use the same seed value, generated randomly at app start. This value is chosen independently of other random seed values in the runtime, such as the global 64-bit seed used in `string.GetHashCode`'s Marvin32 routine.
The xxHash32 repo's README file touts good performance and avalanching. This can be validated through a simple C# program.

View File

@ -95,6 +95,24 @@ static IEnumerable<int> TestLocalVariable ()
}
```
## Attribute propagation via CompilerLoweringPreserveAttribute
To address the challenges of propagating user-authored attributes to compiler-generated code, .NET 10 introduced a general mechanism: `[CompilerLoweringPreserveAttribute]`. This attribute can be applied to other attribute types to instruct compilers to propagate those attributes to compiler-generated code.
`DynamicallyAccessedMembersAttribute` is now marked with `[CompilerLoweringPreserve]`, so when the compiler generates new fields or type parameters (such as for local functions, iterator/async state machines, or primary constructor parameters), the relevant `DynamicallyAccessedMembers` annotations are automatically applied to the generated members. This allows trimming tools to directly use the annotations present in the generated code, without needing to reverse-engineer the mapping to user code.
### .NET 10 and later
For .NET 10 and later, trimming tools should rely on the compiler to propagate attributes such as `DynamicallyAccessedMembersAttribute` to all relevant compiler-generated code, as indicated by `[CompilerLoweringPreserve]`. No heuristics are needed for these assemblies. This isn't perfect because it's possible for such assemblies to be compiled with new Roslyn versions that could use different lowering strategies, so it's possible that the existing heuristics will break for new releases of a pre-`net10.0` assembly.
To mitigate this there are a few options:
1. Multitarget the library to `net10.0` (so that it is built with the new `CompilerLoweringPreserve` behavior and will avoid the heuristics)
2. Fix the heuristics to work for code produced by new Roslyn versions
3. The trimming tools could detect the presence of a polyfilled `DynamicallyAccessedMembersAttribute` type with `CompilerLoweringPreserve`. When present this would turn off the heuristics for the containing assembly.
Another issue is that .NET 10 libraries might be built with `<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>`, and the tooling would not be able to detect the TargetFramework. Aside from setting `<GenerateTargetFrameworkAttribute>true</GenerateTargetFrameworkAttribute>`, mitigations 1. and 2. above would also apply to this scenario.
### Compiler dependent behavior
Since the problems are all caused by compiler generated code, the behaviors depend on the specific compiler in use. The main focus of this document is the Roslyn C# compiler right now. Mainly since it's by far the most used compiler for .NET code. That said, we would like to design the solution in such a way that other compilers using similar patterns could also benefit from it.
@ -560,9 +578,9 @@ and fields on the closure types.
### Long term solution
Detecting which compiler generated items are used by any given user method is currently relatively tricky.
There's no definitive marker in the IL which would let the trimmer confidently determine this information.
Good long term solution will need the compilers to produce some kind of marker in the IL so that
static analysis tools can reliably detect all of the compiler generated items.
There's no definitive marker in the IL which would let the trimmer confidently determine this information
for all of the above cases. Good long term solution will need the compilers to produce some kind of marker
in the IL so that static analysis tools can reliably detect all of the compiler generated items.
This ask can be described as:
For a given user method, ability to determine all of the items (methods, fields, types, IL code) which were
@ -573,6 +591,10 @@ helpers and other infrastructure which may be needed but is not directly attribu
This should be enough to implement solutions for both suppression propagation and data flow analysis.
For `DynamicallyAccessedMembersAttribute`, we have a long-term solution that relies on the
`[CompilerLoweringPreserve]` attribute, which tells Roslyn to propagate `DynamicallyAccessedMembers`
annotations to compiler-generated code.
### Possible short term solution
#### Heuristic based solution

View File

@ -116,6 +116,7 @@ The PR that reveals the implementation of the `<IncludeInternalObsoleteAttribute
| __`SYSLIB0059`__ | SystemEvents.EventsThreadShutdown callbacks are not run before the process exits. Use AppDomain.ProcessExit instead. |
| __`SYSLIB0060`__ | The constructors on Rfc2898DeriveBytes are obsolete. Use the static Pbkdf2 method instead. |
| __`SYSLIB0061`__ | The Queryable MinBy and MaxBy taking an IComparer\<TSource\> are obsolete. Use the new ones that take an IComparer\<TKey\>. |
| __`SYSLIB0062`__ | XSLT Script blocks are not supported. |
## Analyzer Warnings
@ -296,7 +297,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
APIs can be marked as `[Experimental]` if their shape or functionality is included in a release but not yet officially supported. Experimental APIs offer the opportunity to collect customer feedback on these APIs in a major release, usually refining the APIs and removing the `[Experimental]` attribute in the next release. The `[Experimental]` attribute differs from `[RequiresPreviewFeatures]`, wherein:
* `[RequiresPreviewFeatures]` APIs require a corresponding preview feature in another product area such as the compiler or SDK
- Using these APIs requires enabling preview features for the the project and all its consumers
- Using these APIs requires enabling preview features for the project and all its consumers
* `[Experimental]` APIs are self-contained within the libraries and do not require preview features in other parts of the product
- These APIs can be used by suppressing specific diagnostics without enabling preview features for the project

View File

@ -18,7 +18,6 @@ To build the runtime repo, you will also need to install the following dependenc
- `CMake` 3.20 or newer
- `icu4c`
- `openssl@1.1` or `openssl@3`
- `pkg-config`
- `python3`
- `ninja` (This one is optional. It is an alternative tool to `make` for building native code)

View File

@ -46,9 +46,9 @@ It is highly recommended to use the *Workloads* approach, as that installs the f
- .NET desktop development
- Desktop development with C++
To build the tests and do ARM32/ARM64 development, you'll need some additional components. You can find them by clicking on the *Individual components* tab in the *Visual Studio Installer*:
To build the tests and do ARM64 development, you'll need some additional components. You can find them by clicking on the *Individual components* tab in the *Visual Studio Installer*:
- For ARM stuff: *MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)* for Arm64, and *MSVC v143 - VS 2022 C++ ARM build tools (Latest)* for Arm32.
- For Arm64: *MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)*
- For building tests: *C++/CLI support for v143 build tools (Latest)*
Alternatively, there is also a `.vsconfig` file included at the root of the runtime repo. It includes all the necessary components required, outlined in a JSON format that Visual Studio can read and parse. You can boot up Visual Studio directly and [import this `.vsconfig` file](https://learn.microsoft.com/visualstudio/install/import-export-installation-configurations?view=vs-2022#import-a-configuration) instead of installing the workloads yourself. It is worth mentioning however, that while we are very careful in maintaining this file up-to-date, sometimes it might get a tad obsolete and miss important components. So, it is always a good idea to double check that the full workloads are installed.

View File

@ -118,11 +118,9 @@ Console.WriteLine($"The location of System.Private.CoreLib.dll is '{typeof(objec
The following command will build and publish your app:
```cmd
dotnet publish -r win-x64
dotnet publish --self-contained
```
Adjust the `win-x64` to match your machine's OS and architecture.
Running this little app should yield an output like the following:
```text

View File

@ -47,7 +47,7 @@
<MonoAOTCrossCompilerSupported Condition="'$(_MonoAotCrossSupportedOS)' == 'true' and '$(_MonoAotCrossSupportedArch)' == 'true'">true</MonoAOTCrossCompilerSupported>
<!-- Determine if the NativeAOT runtime can run on the specified target. -->
<_NativeAotSupportedOS Condition="'$(TargetOS)' == 'windows' or '$(TargetOS)' == 'linux' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'maccatalyst' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvossimulator' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'freebsd'">true</_NativeAotSupportedOS>
<_NativeAotSupportedOS Condition="'$(TargetOS)' != 'browser' and '$(TargetOS)' != 'haiku' and '$(TargetOS)' != 'illumos' and '$(TargetOS)' != 'netbsd' and '$(TargetOS)' != 'solaris'">true</_NativeAotSupportedOS>
<_NativeAotSupportedArch Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'loongarch64' or '$(TargetArchitecture)' == 'riscv64' or ('$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'x86')">true</_NativeAotSupportedArch>
<NativeAotSupported Condition="'$(_NativeAotSupportedOS)' == 'true' and '$(_NativeAotSupportedArch)' == 'true'">true</NativeAotSupported>
@ -71,6 +71,7 @@
<DefaultSubsets>clr+mono+libs+tools+host+packs</DefaultSubsets>
<DefaultSubsets Condition="'$(TargetsMobile)' == 'true'">mono+libs+packs</DefaultSubsets>
<DefaultSubsets Condition="'$(TargetsAndroid)' == 'true' and '$(CoreCLRSupported)' == 'true'">clr+mono+libs+host+packs</DefaultSubsets>
<DefaultSubsets Condition="'$(TargetsAndroid)' == 'true' and '$(CoreCLRSupported)' != 'true' and '$(NativeAotSupported)' == 'true'">clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+packs</DefaultSubsets>
<DefaultSubsets Condition="'$(TargetsAppleMobile)' == 'true'">clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+packs</DefaultSubsets>
<DefaultSubsets Condition="'$(TargetsLinuxBionic)' == 'true' and '$(MonoSupported)' == 'true'">clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+host+packs</DefaultSubsets>
<DefaultSubsets Condition="'$(TargetsLinuxBionic)' == 'true' and '$(MonoSupported)' != 'true'">clr.nativeaotruntime+clr.nativeaotlibs+libs+packs</DefaultSubsets>
@ -153,7 +154,7 @@
<BootstrapSubsets Condition="'$(UseNativeAotForComponents)' == 'true'">$(BootstrapSubsets)+clr.nativeaotlibs+clr.nativeaotruntime+libs.native</BootstrapSubsets>
<SwapNativeForIL Condition="$(_subset.Contains('+bootstrap+')) and '$(RuntimeFlavor)' == 'CoreCLR'">true</SwapNativeForIL>
<!-- Define AllSubsets to include all available subsets including OnDemand ones -->
<AllSubsetsExpansion>clr.nativeprereqs+clr.iltools+clr.runtime+clr.native+clr.aot+clr.nativeaotlibs+clr.nativeaotruntime+clr.crossarchtools</AllSubsetsExpansion>
<AllSubsetsExpansion>$(AllSubsetsExpansion)+clr.paltests+clr.paltestlist+clr.hosts+clr.jit+clr.alljits+clr.alljitscommunity+clr.spmi+clr.corelib+clr.nativecorelib+clr.tools+clr.toolstests+clr.packages</AllSubsetsExpansion>
@ -656,6 +657,8 @@
<_BuildMonoRuntimePack Condition="'$(RuntimeFlavor)' == 'Mono' and '$(MonoSupported)' == 'true'">true</_BuildMonoRuntimePack>
<_BuildHostPack Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'">true</_BuildHostPack>
<_BuildCdacPack Condition="'$(_CDacToolsBuilt)' == 'true' and '$(RuntimeFlavor)' == 'CoreCLR' and '$(TargetsMobile)' != 'true' and ('$(TargetOS)' == 'windows' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'linux')">true</_BuildCdacPack>
<!-- Some source build configurations and musl need to work out packaging errors before they can be enabled -->
<_BuildCdacPack Condition="'$(DotNetBuildSourceOnly)' == 'true' or '$(TargetsLinuxMusl)' == 'true'">false</_BuildCdacPack>
<_BuildBundle Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'">true</_BuildBundle>
</PropertyGroup>

View File

@ -0,0 +1 @@
<!-- will get filled in the next backflow -->

View File

@ -1,5 +1,5 @@
<Dependencies>
<Source Uri="https://github.com/dotnet/dotnet" Mapping="runtime" Sha="f451e5d3036a4f140a989e0a7f3f1ae432420e71" BarId="274568" />
<Source Uri="https://github.com/dotnet/dotnet" Mapping="runtime" Sha="699b0116eb3df66c4dd7698af4f1cd24ac4547a3" BarId="275638" />
<ProductDependencies>
<Dependency Name="Microsoft.NETCore.Runtime.ICU.Transport" Version="10.0.0-preview.6.25302.1">
<Uri>https://github.com/dotnet/icu</Uri>
@ -41,91 +41,91 @@
<Uri>https://github.com/dotnet/llvm-project</Uri>
<Sha>da5dd054a531e6fea65643b7e754285b73eab433</Sha>
</Dependency>
<Dependency Name="System.CommandLine" Version="2.0.0-beta6.25359.101">
<Dependency Name="System.CommandLine" Version="2.0.0-beta7.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Cecil" Version="0.11.5-alpha.25359.101">
<Dependency Name="Microsoft.DotNet.Cecil" Version="0.11.5-alpha.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.NET.Workload.Emscripten.Current.Manifest-10.0.100.Transport" Version="10.0.100-preview.7.25359.101">
<Dependency Name="Microsoft.NET.Workload.Emscripten.Current.Manifest-10.0.100.Transport" Version="10.0.100-preview.7.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
</ProductDependencies>
<ToolsetDependencies>
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.XliffTasks" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.XliffTasks" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.GenAPI" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.GenAPI" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.GenFacades" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.GenFacades" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.XUnitAssert" Version="2.9.2-beta.25359.101">
<Dependency Name="Microsoft.DotNet.XUnitAssert" Version="2.9.3-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.XUnitExtensions" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.XUnitExtensions" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.XUnitConsoleRunner" Version="2.9.2-beta.25359.101">
<Dependency Name="Microsoft.DotNet.XUnitConsoleRunner" Version="2.9.3-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Build.Tasks.Archives" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.Build.Tasks.Archives" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Build.Tasks.Packaging" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.Build.Tasks.Packaging" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Build.Tasks.Workloads" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.Build.Tasks.Workloads" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.CodeAnalysis" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.CodeAnalysis" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Build.Tasks.TargetFramework" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.Build.Tasks.TargetFramework" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.RemoteExecutor" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.RemoteExecutor" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Build.Tasks.Feed" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.Build.Tasks.Feed" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.SharedFramework.Sdk" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.SharedFramework.Sdk" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="System.ComponentModel.TypeConverter.TestData" Version="10.0.0-beta.25310.1">
<Uri>https://github.com/dotnet/runtime-assets</Uri>
@ -263,33 +263,33 @@
<Uri>https://github.com/dotnet/llvm-project</Uri>
<Sha>da5dd054a531e6fea65643b7e754285b73eab433</Sha>
</Dependency>
<Dependency Name="Microsoft.NETCore.App.Ref" Version="10.0.0-preview.7.25359.101">
<Dependency Name="Microsoft.NETCore.App.Ref" Version="10.0.0-preview.7.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="runtime.native.System.IO.Ports" Version="10.0.0-preview.7.25359.101">
<Dependency Name="runtime.native.System.IO.Ports" Version="10.0.0-preview.7.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.NETCore.ILAsm" Version="10.0.0-preview.7.25359.101">
<Dependency Name="Microsoft.NETCore.ILAsm" Version="10.0.0-preview.7.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.NET.Sdk.IL" Version="10.0.0-preview.7.25359.101">
<Dependency Name="Microsoft.NET.Sdk.IL" Version="10.0.0-preview.7.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="System.Text.Json" Version="10.0.0-preview.7.25359.101">
<Dependency Name="System.Text.Json" Version="10.0.0-preview.7.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="System.Reflection.Metadata" Version="10.0.0-preview.7.25359.101">
<Dependency Name="System.Reflection.Metadata" Version="10.0.0-preview.7.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="System.Reflection.MetadataLoadContext" Version="10.0.0-preview.7.25359.101">
<Dependency Name="System.Reflection.MetadataLoadContext" Version="10.0.0-preview.7.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.XHarness.TestRunners.Common" Version="10.0.0-prerelease.25330.2">
<Uri>https://github.com/dotnet/xharness</Uri>
@ -303,25 +303,25 @@
<Uri>https://github.com/dotnet/xharness</Uri>
<Sha>feac80219b22c403d32df9b6bd61cbf78e1b9986</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.PackageTesting" Version="10.0.0-beta.25359.101">
<Dependency Name="Microsoft.DotNet.PackageTesting" Version="10.0.0-beta.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.25324.1">
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.25363.1">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
</Dependency>
<Dependency Name="optimization.windows_nt-x86.MIBC.Runtime" Version="1.0.0-prerelease.25324.1">
<Dependency Name="optimization.windows_nt-x86.MIBC.Runtime" Version="1.0.0-prerelease.25363.1">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
</Dependency>
<Dependency Name="optimization.linux-x64.MIBC.Runtime" Version="1.0.0-prerelease.25324.1">
<Dependency Name="optimization.linux-x64.MIBC.Runtime" Version="1.0.0-prerelease.25363.1">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
</Dependency>
<Dependency Name="optimization.PGO.CoreCLR" Version="1.0.0-prerelease.25324.1">
<Dependency Name="optimization.PGO.CoreCLR" Version="1.0.0-prerelease.25363.1">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.HotReload.Utils.Generator.BuildTool" Version="10.0.0-alpha.0.25302.2">
<Uri>https://github.com/dotnet/hotreload-utils</Uri>
@ -331,37 +331,37 @@
<Uri>https://github.com/dotnet/runtime-assets</Uri>
<Sha>385d085eb055cabeaed3dde958a900e7b31cf6ce</Sha>
</Dependency>
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="5.0.0-1.25359.101">
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="5.0.0-2.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.CodeAnalysis" Version="5.0.0-1.25359.101">
<Dependency Name="Microsoft.CodeAnalysis" Version="5.0.0-2.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="5.0.0-1.25359.101">
<Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="5.0.0-2.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.CodeAnalysis.Analyzers" Version="5.0.0-1.25359.101">
<Dependency Name="Microsoft.CodeAnalysis.Analyzers" Version="5.0.0-2.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.0-preview.25359.101">
<Dependency Name="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.0-preview.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.ApiCompat.Task" Version="10.0.100-preview.7.25359.101">
<Dependency Name="Microsoft.DotNet.ApiCompat.Task" Version="10.0.100-preview.7.25367.101">
<Uri>https://github.com/dotnet/dotnet</Uri>
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
</Dependency>
<Dependency Name="optimization.windows_nt-arm64.MIBC.Runtime" Version="1.0.0-prerelease.25324.1">
<Dependency Name="optimization.windows_nt-arm64.MIBC.Runtime" Version="1.0.0-prerelease.25363.1">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
</Dependency>
<Dependency Name="optimization.linux-arm64.MIBC.Runtime" Version="1.0.0-prerelease.25324.1">
<Dependency Name="optimization.linux-arm64.MIBC.Runtime" Version="1.0.0-prerelease.25363.1">
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
</Dependency>
<!-- Necessary for source-build. This allows the package to be retrieved from previously-source-built artifacts
and flow in as dependencies of the packages produced by runtime. -->

View File

@ -11,8 +11,8 @@
<PackageVersionNet8>8.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet9)').Build),11))</PackageVersionNet8>
<PackageVersionNet7>7.0.20</PackageVersionNet7>
<PackageVersionNet6>6.0.36</PackageVersionNet6>
<PreReleaseVersionLabel>preview</PreReleaseVersionLabel>
<PreReleaseVersionIteration>7</PreReleaseVersionIteration>
<PreReleaseVersionLabel>rc</PreReleaseVersionLabel>
<PreReleaseVersionIteration>1</PreReleaseVersionIteration>
<!-- Enable to remove prerelease label. -->
<StabilizePackageVersion Condition="'$(StabilizePackageVersion)' == ''">false</StabilizePackageVersion>
<DotNetFinalVersionKind Condition="'$(StabilizePackageVersion)' == 'true'">release</DotNetFinalVersionKind>
@ -28,25 +28,24 @@
<FlagNetStandard1XDependencies Condition="'$(FlagNetStandard1XDependencies)' == ''">true</FlagNetStandard1XDependencies>
<!-- Runtime controls its dependency graph via Traversal projects and doesn't want or need Arcade's ExcludeFrom infrastructure. -->
<DisableArcadeExcludeFromBuildSupport>true</DisableArcadeExcludeFromBuildSupport>
<!-- Use SDK compilers in full VMR builds. -->
<UsingToolMicrosoftNetCompilers Condition="'$(DotNetBuildOrchestrator)' != 'true'">true</UsingToolMicrosoftNetCompilers>
<UsingToolMicrosoftNetCompilers>true</UsingToolMicrosoftNetCompilers>
</PropertyGroup>
<ItemGroup>
<WorkloadSdkBandVersions Include="$(SdkBandVersion)" SupportsMachineArch="true" />
</ItemGroup>
<PropertyGroup>
<!-- dotnet/roslyn-analyzers dependencies -->
<MicrosoftCodeAnalysisNetAnalyzersVersion>10.0.0-preview.25359.101</MicrosoftCodeAnalysisNetAnalyzersVersion>
<MicrosoftCodeAnalysisNetAnalyzersVersion>10.0.0-preview.25367.101</MicrosoftCodeAnalysisNetAnalyzersVersion>
<!-- dotnet/roslyn dependencies -->
<MicrosoftCodeAnalysisAnalyzersVersion>5.0.0-1.25359.101</MicrosoftCodeAnalysisAnalyzersVersion>
<MicrosoftCodeAnalysisAnalyzersVersion>5.0.0-2.25367.101</MicrosoftCodeAnalysisAnalyzersVersion>
<!--
These versions should not be used by any project that contributes to the design-time experience in VS, such as an analyzer, code-fix, or generator assembly.
Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure
they do not break the local dev experience.
-->
<MicrosoftCodeAnalysisCSharpVersion>5.0.0-1.25359.101</MicrosoftCodeAnalysisCSharpVersion>
<MicrosoftCodeAnalysisVersion>5.0.0-1.25359.101</MicrosoftCodeAnalysisVersion>
<MicrosoftNetCompilersToolsetVersion>5.0.0-1.25359.101</MicrosoftNetCompilersToolsetVersion>
<MicrosoftCodeAnalysisCSharpVersion>5.0.0-2.25367.101</MicrosoftCodeAnalysisCSharpVersion>
<MicrosoftCodeAnalysisVersion>5.0.0-2.25367.101</MicrosoftCodeAnalysisVersion>
<MicrosoftNetCompilersToolsetVersion>5.0.0-2.25367.101</MicrosoftNetCompilersToolsetVersion>
</PropertyGroup>
<!--
For source generator support we need to target multiple versions of Roslyn in order to be able to run on older versions of Roslyn.
@ -83,34 +82,34 @@
<PropertyGroup>
<StaticCsVersion>0.2.0</StaticCsVersion>
<!-- SDK dependencies (also used in wasm build tests -->
<MicrosoftDotNetApiCompatTaskVersion>10.0.100-preview.7.25359.101</MicrosoftDotNetApiCompatTaskVersion>
<MicrosoftDotNetApiCompatTaskVersion>10.0.100-preview.7.25367.101</MicrosoftDotNetApiCompatTaskVersion>
<!-- Arcade dependencies -->
<MicrosoftDotNetBuildTasksFeedVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksFeedVersion>
<MicrosoftDotNetCodeAnalysisVersion>10.0.0-beta.25359.101</MicrosoftDotNetCodeAnalysisVersion>
<MicrosoftDotNetGenAPIVersion>10.0.0-beta.25359.101</MicrosoftDotNetGenAPIVersion>
<MicrosoftDotNetGenFacadesVersion>10.0.0-beta.25359.101</MicrosoftDotNetGenFacadesVersion>
<MicrosoftDotNetXUnitAssertVersion>2.9.2-beta.25359.101</MicrosoftDotNetXUnitAssertVersion>
<MicrosoftDotNetXUnitExtensionsVersion>10.0.0-beta.25359.101</MicrosoftDotNetXUnitExtensionsVersion>
<MicrosoftDotNetXUnitConsoleRunnerVersion>2.9.2-beta.25359.101</MicrosoftDotNetXUnitConsoleRunnerVersion>
<MicrosoftDotNetBuildTasksArchivesVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksArchivesVersion>
<MicrosoftDotNetBuildTasksInstallersVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksInstallersVersion>
<MicrosoftDotNetBuildTasksPackagingVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksPackagingVersion>
<MicrosoftDotNetBuildTasksTargetFrameworkVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksTargetFrameworkVersion>
<MicrosoftDotNetBuildTasksTemplatingVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksTemplatingVersion>
<MicrosoftDotNetBuildTasksWorkloadsPackageVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksWorkloadsPackageVersion>
<MicrosoftDotNetRemoteExecutorVersion>10.0.0-beta.25359.101</MicrosoftDotNetRemoteExecutorVersion>
<MicrosoftDotNetPackageTestingVersion>10.0.0-beta.25359.101</MicrosoftDotNetPackageTestingVersion>
<MicrosoftDotNetXliffTasksVersion>10.0.0-beta.25359.101</MicrosoftDotNetXliffTasksVersion>
<MicrosoftDotNetBuildTasksFeedVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksFeedVersion>
<MicrosoftDotNetCodeAnalysisVersion>10.0.0-beta.25367.101</MicrosoftDotNetCodeAnalysisVersion>
<MicrosoftDotNetGenAPIVersion>10.0.0-beta.25367.101</MicrosoftDotNetGenAPIVersion>
<MicrosoftDotNetGenFacadesVersion>10.0.0-beta.25367.101</MicrosoftDotNetGenFacadesVersion>
<MicrosoftDotNetXUnitAssertVersion>2.9.3-beta.25367.101</MicrosoftDotNetXUnitAssertVersion>
<MicrosoftDotNetXUnitExtensionsVersion>10.0.0-beta.25367.101</MicrosoftDotNetXUnitExtensionsVersion>
<MicrosoftDotNetXUnitConsoleRunnerVersion>2.9.3-beta.25367.101</MicrosoftDotNetXUnitConsoleRunnerVersion>
<MicrosoftDotNetBuildTasksArchivesVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksArchivesVersion>
<MicrosoftDotNetBuildTasksInstallersVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksInstallersVersion>
<MicrosoftDotNetBuildTasksPackagingVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksPackagingVersion>
<MicrosoftDotNetBuildTasksTargetFrameworkVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksTargetFrameworkVersion>
<MicrosoftDotNetBuildTasksTemplatingVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksTemplatingVersion>
<MicrosoftDotNetBuildTasksWorkloadsPackageVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksWorkloadsPackageVersion>
<MicrosoftDotNetRemoteExecutorVersion>10.0.0-beta.25367.101</MicrosoftDotNetRemoteExecutorVersion>
<MicrosoftDotNetPackageTestingVersion>10.0.0-beta.25367.101</MicrosoftDotNetPackageTestingVersion>
<MicrosoftDotNetXliffTasksVersion>10.0.0-beta.25367.101</MicrosoftDotNetXliffTasksVersion>
<!-- TODO: Remove pinned xunit.analyzers version: https://github.com/dotnet/runtime/issues/97088 -->
<XUnitAnalyzersVersion>1.4.0</XUnitAnalyzersVersion>
<!-- NuGet dependencies -->
<NuGetBuildTasksPackVersion>6.0.0-preview.1.102</NuGetBuildTasksPackVersion>
<!-- Installer dependencies -->
<MicrosoftNETCoreAppRefVersion>10.0.0-preview.7.25359.101</MicrosoftNETCoreAppRefVersion>
<MicrosoftNETCoreAppRefVersion>10.0.0-preview.7.25367.101</MicrosoftNETCoreAppRefVersion>
<MicrosoftExtensionsDependencyModelVersion>6.0.0</MicrosoftExtensionsDependencyModelVersion>
<!-- ILAsm dependencies -->
<MicrosoftNETCoreILAsmVersion>10.0.0-preview.7.25359.101</MicrosoftNETCoreILAsmVersion>
<MicrosoftNETSdkILVersion>10.0.0-preview.7.25359.101</MicrosoftNETSdkILVersion>
<MicrosoftNETCoreILAsmVersion>10.0.0-preview.7.25367.101</MicrosoftNETCoreILAsmVersion>
<MicrosoftNETSdkILVersion>10.0.0-preview.7.25367.101</MicrosoftNETSdkILVersion>
<!-- Maintenance-Packages dependencies -->
<MicrosoftBclHashCodeVersion>6.0.0</MicrosoftBclHashCodeVersion>
<SystemBuffersVersion>4.6.1</SystemBuffersVersion>
@ -128,16 +127,16 @@
<SystemDrawingCommonVersion>8.0.0</SystemDrawingCommonVersion>
<SystemFormatsAsn1Version>8.0.1</SystemFormatsAsn1Version>
<SystemIOFileSystemAccessControlVersion>5.0.0</SystemIOFileSystemAccessControlVersion>
<SystemReflectionMetadataVersion>10.0.0-preview.7.25359.101</SystemReflectionMetadataVersion>
<SystemReflectionMetadataLoadContextVersion>10.0.0-preview.7.25359.101</SystemReflectionMetadataLoadContextVersion>
<SystemReflectionMetadataVersion>10.0.0-preview.7.25367.101</SystemReflectionMetadataVersion>
<SystemReflectionMetadataLoadContextVersion>10.0.0-preview.7.25367.101</SystemReflectionMetadataLoadContextVersion>
<SystemSecurityAccessControlVersion>6.0.0</SystemSecurityAccessControlVersion>
<SystemSecurityCryptographyCngVersion>5.0.0</SystemSecurityCryptographyCngVersion>
<SystemSecurityCryptographyOpenSslVersion>5.0.0</SystemSecurityCryptographyOpenSslVersion>
<SystemSecurityPrincipalWindowsVersion>5.0.0</SystemSecurityPrincipalWindowsVersion>
<SystemSecurityPermissionsVersion>7.0.0</SystemSecurityPermissionsVersion>
<SystemTextJsonVersion>10.0.0-preview.7.25359.101</SystemTextJsonVersion>
<SystemTextJsonVersion>10.0.0-preview.7.25367.101</SystemTextJsonVersion>
<SystemThreadingAccessControlVersion>7.0.0</SystemThreadingAccessControlVersion>
<runtimenativeSystemIOPortsVersion>10.0.0-preview.7.25359.101</runtimenativeSystemIOPortsVersion>
<runtimenativeSystemIOPortsVersion>10.0.0-preview.7.25367.101</runtimenativeSystemIOPortsVersion>
<!-- Keep toolset versions in sync with dotnet/msbuild and dotnet/sdk -->
<MicrosoftBclAsyncInterfacesToolsetVersion>8.0.0</MicrosoftBclAsyncInterfacesToolsetVersion>
<SystemBuffersToolsetVersion>4.5.1</SystemBuffersToolsetVersion>
@ -171,16 +170,16 @@
<!-- hotreload-utils dependencies -->
<MicrosoftDotNetHotReloadUtilsGeneratorBuildToolVersion>10.0.0-alpha.0.25302.2</MicrosoftDotNetHotReloadUtilsGeneratorBuildToolVersion>
<!-- dotnet-optimization dependencies -->
<optimizationwindows_ntx64MIBCRuntimeVersion>1.0.0-prerelease.25324.1</optimizationwindows_ntx64MIBCRuntimeVersion>
<optimizationwindows_ntx86MIBCRuntimeVersion>1.0.0-prerelease.25324.1</optimizationwindows_ntx86MIBCRuntimeVersion>
<optimizationwindows_ntarm64MIBCRuntimeVersion>1.0.0-prerelease.25324.1</optimizationwindows_ntarm64MIBCRuntimeVersion>
<optimizationlinuxx64MIBCRuntimeVersion>1.0.0-prerelease.25324.1</optimizationlinuxx64MIBCRuntimeVersion>
<optimizationlinuxarm64MIBCRuntimeVersion>1.0.0-prerelease.25324.1</optimizationlinuxarm64MIBCRuntimeVersion>
<optimizationPGOCoreCLRVersion>1.0.0-prerelease.25324.1</optimizationPGOCoreCLRVersion>
<optimizationwindows_ntx64MIBCRuntimeVersion>1.0.0-prerelease.25363.1</optimizationwindows_ntx64MIBCRuntimeVersion>
<optimizationwindows_ntx86MIBCRuntimeVersion>1.0.0-prerelease.25363.1</optimizationwindows_ntx86MIBCRuntimeVersion>
<optimizationwindows_ntarm64MIBCRuntimeVersion>1.0.0-prerelease.25363.1</optimizationwindows_ntarm64MIBCRuntimeVersion>
<optimizationlinuxx64MIBCRuntimeVersion>1.0.0-prerelease.25363.1</optimizationlinuxx64MIBCRuntimeVersion>
<optimizationlinuxarm64MIBCRuntimeVersion>1.0.0-prerelease.25363.1</optimizationlinuxarm64MIBCRuntimeVersion>
<optimizationPGOCoreCLRVersion>1.0.0-prerelease.25363.1</optimizationPGOCoreCLRVersion>
<!-- Not auto-updated. -->
<MicrosoftDiaSymReaderVersion>2.0.0</MicrosoftDiaSymReaderVersion>
<MicrosoftDiaSymReaderNativeVersion>17.10.0-beta1.24272.1</MicrosoftDiaSymReaderNativeVersion>
<SystemCommandLineVersion>2.0.0-beta6.25359.101</SystemCommandLineVersion>
<SystemCommandLineVersion>2.0.0-beta7.25367.101</SystemCommandLineVersion>
<TraceEventVersion>3.1.16</TraceEventVersion>
<NETStandardLibraryRefVersion>2.1.0</NETStandardLibraryRefVersion>
<NetStandardLibraryVersion>2.0.3</NetStandardLibraryVersion>
@ -226,7 +225,7 @@
<!-- Docs -->
<MicrosoftPrivateIntellisenseVersion>9.0.0-preview-20241010.1</MicrosoftPrivateIntellisenseVersion>
<!-- Mono Cecil -->
<MicrosoftDotNetCecilVersion>0.11.5-alpha.25359.101</MicrosoftDotNetCecilVersion>
<MicrosoftDotNetCecilVersion>0.11.5-alpha.25367.101</MicrosoftDotNetCecilVersion>
<!-- ICU -->
<MicrosoftNETCoreRuntimeICUTransportVersion>10.0.0-preview.6.25302.1</MicrosoftNETCoreRuntimeICUTransportVersion>
<!-- MsQuic -->
@ -258,7 +257,7 @@
Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml
like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-10_0_100_Transport
-->
<MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion>10.0.100-preview.7.25359.101</MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion>
<MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion>10.0.100-preview.7.25367.101</MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion>
<MicrosoftNETRuntimeEmscriptenVersion>$(MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion)</MicrosoftNETRuntimeEmscriptenVersion>
<!-- workloads -->
<SwixPackageVersion>1.1.87-gba258badda</SwixPackageVersion>

View File

@ -150,7 +150,7 @@ initDistroRid()
showSubsetHelp()
{
"$scriptroot/common/build.sh" "-restore" "-build" "/p:Subset=help" "/clp:nosummary /tl:false"
"$scriptroot/common/build.sh" "-restore" "-build" "/p:Subset=help" "/clp:nosummary" "/tl:false"
}
arguments=()

View File

@ -70,7 +70,7 @@ build_native()
# Let users provide additional compiler/linker flags via EXTRA_CFLAGS/EXTRA_CXXFLAGS/EXTRA_LDFLAGS.
# If users directly override CFLAG/CXXFLAGS/LDFLAGS, that may lead to some configure tests working incorrectly.
# See https://github.com/dotnet/runtime/issues/35727 for more information.
#
#
# These flags MUST be exported before gen-buildsys.sh runs or cmake will ignore them
#
export CFLAGS="${CFLAGS} ${EXTRA_CFLAGS}"
@ -547,6 +547,9 @@ elif [[ "$__TargetOS" == ios || "$__TargetOS" == iossimulator ]]; then
elif [[ "$__TargetOS" == tvos || "$__TargetOS" == tvossimulator ]]; then
# nothing to do here
true
elif [[ "$__TargetOS" == osx || "$__TargetOS" == maccatalyst ]]; then
# nothing to do here
true
elif [[ "$__TargetOS" == android ]]; then
# nothing to do here
true

View File

@ -308,6 +308,8 @@ elseif(CLR_CMAKE_HOST_APPLE)
add_definitions(-D_XOPEN_SOURCE)
# enable support for Darwin extension APIs, like pthread_getthreadid_np
add_definitions(-D_DARWIN_C_SOURCE)
# enable the non-cancellable versions of APIs with $NOCANCEL variants, like close(2)
add_definitions(-D__DARWIN_NON_CANCELABLE=1)
if(CLR_CMAKE_HOST_OSX)
# the new linker in Xcode 15 (ld_new/ld_prime) deprecated the -bind_at_load flag for macOS which causes a warning

View File

@ -548,11 +548,11 @@ function(install_static_library targetName destination component)
endif()
endfunction()
# install_clr(TARGETS targetName [targetName2 ...] [DESTINATIONS destination [destination2 ...]] [COMPONENT componentName])
# install_clr(TARGETS targetName [targetName2 ...] [DESTINATIONS destination [destination2 ...]] [COMPONENT componentName] [OPTIONAL])
function(install_clr)
set(multiValueArgs TARGETS DESTINATIONS)
set(singleValueArgs COMPONENT)
set(options "")
set(options OPTIONAL)
cmake_parse_arguments(INSTALL_CLR "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGV})
if ("${INSTALL_CLR_TARGETS}" STREQUAL "")
@ -587,12 +587,18 @@ function(install_clr)
get_symbol_file_name(${targetName} symbolFile)
endif()
if (${INSTALL_CLR_OPTIONAL})
set(INSTALL_CLR_OPTIONAL "OPTIONAL")
else()
set(INSTALL_CLR_OPTIONAL "")
endif()
foreach(destination ${destinations})
# We don't need to install the export libraries for our DLLs
# since they won't be directly linked against.
install(PROGRAMS $<TARGET_FILE:${targetName}> DESTINATION ${destination} COMPONENT ${INSTALL_CLR_COMPONENT})
install(PROGRAMS $<TARGET_FILE:${targetName}> DESTINATION ${destination} COMPONENT ${INSTALL_CLR_COMPONENT} ${INSTALL_CLR_OPTIONAL})
if (NOT "${symbolFile}" STREQUAL "")
install_symbol_file(${symbolFile} ${destination} COMPONENT ${INSTALL_CLR_COMPONENT})
install_symbol_file(${symbolFile} ${destination} COMPONENT ${INSTALL_CLR_COMPONENT} ${INSTALL_CLR_OPTIONAL})
endif()
if(CLR_CMAKE_PGO_INSTRUMENT)

View File

@ -76,7 +76,7 @@ jobs:
nameSuffix: AllSubsets_Mono
isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAdditionalTimezoneChecks=true
timeoutInMinutes: 480
timeoutInMinutes: 240
# extra steps, run tests
postBuildSteps:
- template: /eng/pipelines/libraries/helix.yml
@ -107,7 +107,7 @@ jobs:
nameSuffix: AllSubsets_CoreCLR
isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
buildArgs: -s clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg)
timeoutInMinutes: 480
timeoutInMinutes: 240
# extra steps, run tests
postBuildSteps:
- template: /eng/pipelines/libraries/helix.yml

View File

@ -111,7 +111,7 @@ jobs:
nameSuffix: AllSubsets_Mono
isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg)
timeoutInMinutes: 180
timeoutInMinutes: 240
# extra steps, run tests
postBuildSteps:
- template: /eng/pipelines/libraries/helix.yml

View File

@ -42,7 +42,7 @@ jobs:
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:IsManualOrRollingBuild=true /p:EnableAggressiveTrimming=false
${{ else }}:
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:IsManualOrRollingBuild=true /p:EnableAggressiveTrimming=true
timeoutInMinutes: 480
timeoutInMinutes: 240
# extra steps, run tests
postBuildSteps:
- template: /eng/pipelines/libraries/helix.yml
@ -81,7 +81,7 @@ jobs:
testGroup: innerloop
nameSuffix: AllSubsets_Mono_RuntimeTests
buildArgs: -s mono+libs -c $(_BuildConfig)
timeoutInMinutes: 480
timeoutInMinutes: 240
# extra steps, run tests
extraVariablesTemplates:
- template: /eng/pipelines/common/templates/runtimes/test-variables.yml
@ -152,7 +152,7 @@ jobs:
jobParameters:
testGroup: innerloop
nameSuffix: AllSubsets_NativeAOT_RuntimeTests
timeoutInMinutes: 480
timeoutInMinutes: 240
buildArgs: --cross -s clr.alljits+clr.tools+clr.nativeaotruntime+clr.nativeaotlibs+libs -c $(_BuildConfig)
# extra steps, run tests
extraVariablesTemplates:

View File

@ -36,7 +36,7 @@ jobs:
testGroup: innerloop
nameSuffix: AllSubsets_Mono
buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:RunAOTCompilation=true /p:MonoForceInterpreter=true
timeoutInMinutes: 180
timeoutInMinutes: 240
# extra steps, run tests
postBuildSteps:
- template: /eng/pipelines/libraries/helix.yml
@ -119,7 +119,7 @@ jobs:
jobParameters:
testGroup: innerloop
nameSuffix: AllSubsets_NativeAOT_RuntimeTests
timeoutInMinutes: 240
timeoutInMinutes: 180
buildArgs: --cross -s clr.alljits+clr.tools+clr.nativeaotruntime+clr.nativeaotlibs+libs -c $(_BuildConfig)
# extra steps, run tests
extraVariablesTemplates:
@ -133,3 +133,37 @@ jobs:
testBuildArgs: tree nativeaot/SmokeTests /p:BuildNativeAOTRuntimePack=true
testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
buildAllTestsAsStandalone: true
#
# iOS simulator
# Build the whole product using CoreCLR and run functional tests
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: checked
runtimeFlavor: coreclr
isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
isiOSLikeSimulatorOnlyBuild: ${{ parameters.isiOSLikeSimulatorOnlyBuild }}
platforms:
- iossimulator_arm64
variables:
# map dependencies variables to local variables
- name: librariesContainsChange
value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
- name: coreclrContainsChange
value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ]
- name: illinkContainsChange
value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'] ]
jobParameters:
testGroup: innerloop
nameSuffix: AllSubsets_CoreCLR
buildArgs: -s clr+clr.runtime+libs+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=false /p:UseMonoRuntime=false /p:MonoForceInterpreter=false /p:RunSmokeTestsOnly=true
timeoutInMinutes: 120
# extra steps, run tests
postBuildSteps:
- template: /eng/pipelines/libraries/helix.yml
parameters:
creator: dotnet-bot
testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig)

View File

@ -42,7 +42,6 @@ jobs:
# Linux x64
- ${{ if eq(parameters.platform, 'linux_x64') }}:
- AzureLinux.3.Amd64.Open
- Ubuntu.2204.Amd64.Open
# OSX arm64
- ${{ if eq(parameters.platform, 'osx_arm64') }}:

View File

@ -14,10 +14,6 @@ parameters:
displayName: Build Coreclr Arm64 Windows
type: boolean
default: true
- name: coreclr_muslx64_linux
displayName: Build Coreclr Musl x64 Linux
type: boolean
default: true
- name: coreclr_x64_linux
displayName: Build Coreclr x64 Linux
type: boolean
@ -110,8 +106,6 @@ extends:
- coreclr_arm64_linux
- ${{ if eq(parameters.coreclr_arm64_windows, true) }}:
- coreclr_arm64_windows
- ${{ if eq(parameters.coreclr_muslx64_linux, true) }}:
- coreclr_muslx64_linux
- ${{ if eq(parameters.coreclr_x64_linux, true) }}:
- coreclr_x64_linux
- ${{ if eq(parameters.coreclr_x64_windows, true) }}:
@ -152,8 +146,6 @@ extends:
- coreclr_arm64_linux
- ${{ if eq(parameters.coreclr_arm64_windows, true) }}:
- coreclr_arm64_windows
- ${{ if eq(parameters.coreclr_muslx64_linux, true) }}:
- coreclr_muslx64_linux
- ${{ if eq(parameters.coreclr_x64_linux, true) }}:
- coreclr_x64_linux
- ${{ if eq(parameters.coreclr_x64_windows, true) }}:
@ -182,7 +174,7 @@ extends:
- nativeAot_arm64_ios
${{ if parameters.mauiFramework }}:
mauiFramework: ${{ parameters.mauiFramework }}
- ${{ if and(ne(variables['System.TeamProject'], 'public'), or(eq(variables['Build.Reason'], 'IndividualCI'), parameters.runPrivateJobs)) }}:
- stage: UploadArtifacts
displayName: 'Upload Artifacts'
@ -200,8 +192,6 @@ extends:
- coreclr_arm64_linux
- ${{ if eq(parameters.coreclr_arm64_windows, true) }}:
- coreclr_arm64_windows
- ${{ if eq(parameters.coreclr_muslx64_linux, true) }}:
- coreclr_muslx64_linux
- ${{ if eq(parameters.coreclr_x64_linux, true) }}:
- coreclr_x64_linux
- ${{ if eq(parameters.coreclr_x64_windows, true) }}:

View File

@ -8,6 +8,7 @@ trigger:
branches:
include:
- main
- release/10.0
- release/9.0
- release/8.0
paths:

View File

@ -8,7 +8,6 @@ jobs:
linux_x64: true
windows_x64: true
windows_x86: true
linux_musl_x64: true
android_arm64: true
# build mono for AOT

View File

@ -1,6 +1,5 @@
parameters:
linux_x64: false
linux_musl_x64: false
linux_arm64: false
windows_x64: false
windows_x86: false
@ -8,7 +7,7 @@ parameters:
android_arm64: false
jobs:
- ${{ if or(eq(parameters.linux_x64, true), eq(parameters.windows_x64, true), eq(parameters.windows_x86, true), eq(parameters.linux_musl_x64, true), eq(parameters.linux_arm64, true), eq(parameters.windows_arm64, true)) }}:
- ${{ if or(eq(parameters.linux_x64, true), eq(parameters.windows_x64, true), eq(parameters.windows_x86, true), eq(parameters.linux_arm64, true), eq(parameters.windows_arm64, true)) }}:
# build coreclr and libraries
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@ -21,8 +20,6 @@ jobs:
- windows_x64
- ${{ if eq(parameters.windows_x86, true) }}:
- windows_x86
- ${{ if eq(parameters.linux_musl_x64, true) }}:
- linux_musl_x64
- ${{ if eq(parameters.linux_arm64, true) }}:
- linux_arm64
- ${{ if eq(parameters.windows_arm64, true) }}:

View File

@ -900,13 +900,13 @@ extends:
# WASI/WASM
- template: /eng/pipelines/common/templates/simple-wasm-build-tests.yml
parameters:
platforms:
- wasi_wasm
- wasi_wasm_win
extraBuildArgs: /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS)
alwaysRun: ${{ variables.isRollingBuild }}
# - template: /eng/pipelines/common/templates/simple-wasm-build-tests.yml
# parameters:
# platforms:
# - wasi_wasm
# - wasi_wasm_win
# extraBuildArgs: /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS)
# alwaysRun: ${{ variables.isRollingBuild }}
#
# Android devices
@ -931,7 +931,7 @@ extends:
testGroup: innerloop
nameSuffix: AllSubsets_Mono
buildArgs: -s mono+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:EnableAdditionalTimezoneChecks=true
timeoutInMinutes: 480
timeoutInMinutes: 120
condition: >-
or(
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
@ -961,7 +961,8 @@ extends:
buildConfig: Release
runtimeFlavor: coreclr
platforms:
- android_x64
# Tracking issue: https://github.com/dotnet/dnceng/issues/5909
# - android_x64
- android_arm64
variables:
# map dependencies variables to local variables
@ -973,7 +974,7 @@ extends:
testGroup: innerloop
nameSuffix: AllSubsets_CoreCLR
buildArgs: -s clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true
timeoutInMinutes: 480
timeoutInMinutes: 120
condition: >-
or(
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
@ -1017,7 +1018,7 @@ extends:
testGroup: innerloop
nameSuffix: AllSubsets_Mono
buildArgs: -s mono+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:RunSmokeTestsOnly=true /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:EnableAggressiveTrimming=true
timeoutInMinutes: 480
timeoutInMinutes: 120
condition: >-
or(
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),

View File

@ -4,7 +4,7 @@
<SlnGenSolutionFolder Condition="'$(IsGeneratorProject)' == 'true'">$(SlnGenSolutionFolder)gen$(SlnGenSolutionInnerFolder)</SlnGenSolutionFolder>
<SlnGenSolutionFolder Condition="'$(IsReferenceAssemblyProject)' == 'true'">$(SlnGenSolutionFolder)ref$(SlnGenSolutionInnerFolder)</SlnGenSolutionFolder>
<SlnGenSolutionFolder Condition="'$(IsTestProject)' == 'true' or '$(IsTrimmingTestProject)' == 'true' or '$(IsTestSupportProject)' == 'true'">$(SlnGenSolutionFolder)tests$(SlnGenSolutionInnerFolder)</SlnGenSolutionFolder>
<SlnGenSolutionFolder Condition="'$(IsSourceProject)' == 'true' or '$(SlnGenSolutionFolder)' == ''">$(SlnGenSolutionFolder)src$(SlnGenSolutionInnerFolder)</SlnGenSolutionFolder>
<SlnGenSolutionFolder Condition="'$(IsSourceProject)' == 'true' or ('$(SlnGenSolutionFolder)' == '' and '$(NoDefaultSlnGenSolutionFolder)' != 'true')">$(SlnGenSolutionFolder)src$(SlnGenSolutionInnerFolder)</SlnGenSolutionFolder>
</PropertyGroup>
</Project>

View File

@ -1,7 +1 @@
Wasi.Build.Tests.InvariantTests
Wasi.Build.Tests.ILStripTests
Wasi.Build.Tests.SdkMissingTests
Wasi.Build.Tests.RuntimeConfigTests
Wasi.Build.Tests.WasiTemplateTests
Wasi.Build.Tests.PInvokeTableGeneratorTests
Wasi.Build.Tests.WasiLibraryModeTests

View File

@ -8,11 +8,11 @@
"dotnet": "10.0.100-preview.7.25322.101"
},
"msbuild-sdks": {
"Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25359.101",
"Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25359.101",
"Microsoft.DotNet.SharedFramework.Sdk": "10.0.0-beta.25359.101",
"Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25367.101",
"Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25367.101",
"Microsoft.DotNet.SharedFramework.Sdk": "10.0.0-beta.25367.101",
"Microsoft.Build.NoTargets": "3.7.0",
"Microsoft.Build.Traversal": "3.4.0",
"Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25359.101"
"Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25367.101"
}
}

View File

@ -39,6 +39,10 @@ if (DEFINED CLR_CMAKE_ICU_DIR)
include_directories(${CLR_CMAKE_ICU_DIR}/include)
endif(DEFINED CLR_CMAKE_ICU_DIR)
if (CLR_CMAKE_TARGET_ARCH_WASM)
add_compile_options(-fwasm-exceptions)
endif()
#----------------------------------------------------
# Cross target Component build specific configuration
#----------------------------------------------------

View File

@ -223,6 +223,7 @@
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Marshal.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\MemoryMarshal.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeLibrary.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Java\JavaMarshal.CoreCLR.cs" Condition="'$(FeatureJavaMarshal)' == 'true'" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\Intrinsics\X86\X86Base.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\Loader\AssemblyLoadContext.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\RuntimeArgumentHandle.cs" />

View File

@ -9,6 +9,7 @@ using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Threading;
namespace System
{
@ -144,7 +145,7 @@ namespace System
private static bool TrySetSlot(object?[] a, int index, object o)
{
if (a[index] == null && Threading.Interlocked.CompareExchange<object?>(ref a[index], o, null) == null)
if (a[index] == null && Interlocked.CompareExchange(ref a[index], o, null) == null)
return true;
// The slot may be already set because we have added and removed the same method before.

View File

@ -34,7 +34,7 @@ namespace System.Reflection
#endregion
internal IntPtr GetUnderlyingNativeHandle() { return m_assembly; }
internal IntPtr GetUnderlyingNativeHandle() => m_assembly;
private sealed class ManifestResourceStream : UnmanagedMemoryStream
{
@ -52,17 +52,8 @@ namespace System.Reflection
// NOTE: no reason to override Write(Span<byte>), since a ManifestResourceStream is read-only.
}
internal object SyncRoot
{
get
{
if (m_syncRoot == null)
{
Interlocked.CompareExchange<object?>(ref m_syncRoot, new object(), null);
}
return m_syncRoot;
}
}
internal object SyncRoot =>
m_syncRoot ?? Interlocked.CompareExchange(ref m_syncRoot, new object(), null) ?? m_syncRoot;
public override event ModuleResolveEventHandler? ModuleResolve
{

View File

@ -1270,12 +1270,12 @@ namespace System.Reflection
for (int i = 0; i < pcas.Count; i++)
result.Add(pcas[i]);
while (type != (RuntimeType)typeof(object) && type != null)
do
{
AddCustomAttributes(ref result, type.GetRuntimeModule(), type.MetadataToken, caType, mustBeInheritable, result);
mustBeInheritable = true;
type = (type.BaseType as RuntimeType)!;
}
} while (type != (RuntimeType)typeof(object) && type != null);
object[] typedResult = CreateAttributeArrayHelper(caType, result.Count);
for (int i = 0; i < result.Count; i++)

View File

@ -61,6 +61,15 @@ namespace System.Runtime.CompilerServices
// OSR method saved in the beginning of 'Data', or -1 if the continuation
// belongs to a tier 0 method.
CORINFO_CONTINUATION_OSR_IL_OFFSET_IN_DATA = 4,
// If this bit is set the continuation should continue on the thread
// pool.
CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL = 8,
// If this bit is set the continuation has a SynchronizationContext
// that we should continue on.
CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT = 16,
// If this bit is set the continuation has a TaskScheduler
// that we should continue on.
CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER = 32,
}
internal sealed unsafe class Continuation
@ -93,6 +102,29 @@ namespace System.Runtime.CompilerServices
//
public byte[]? Data;
public object?[]? GCData;
public object GetContinuationContext()
{
int index = 0;
if ((Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA) != 0)
index++;
if ((Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION) != 0)
index++;
Debug.Assert(GCData != null && GCData.Length > index);
object? continuationContext = GCData[index];
Debug.Assert(continuationContext != null);
return continuationContext;
}
public void SetException(Exception ex)
{
int index = 0;
if ((Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA) != 0)
index++;
Debug.Assert(GCData != null && GCData.Length > index);
GCData[index] = ex;
}
}
public static partial class AsyncHelpers
@ -171,240 +203,385 @@ namespace System.Runtime.CompilerServices
return RuntimeTypeHandle.InternalAllocNoChecks((MethodTable*)pMT);
}
// wrapper to await a notifier
private struct AwaitableProxy : ICriticalNotifyCompletion
private interface IThunkTaskOps<T>
{
private readonly INotifyCompletion _notifier;
public AwaitableProxy(INotifyCompletion notifier)
{
_notifier = notifier;
}
public bool IsCompleted => false;
public void OnCompleted(Action action)
{
_notifier!.OnCompleted(action);
}
public AwaitableProxy GetAwaiter() { return this; }
public void UnsafeOnCompleted(Action action)
{
if (_notifier is ICriticalNotifyCompletion criticalNotification)
{
criticalNotification.UnsafeOnCompleted(action);
}
else
{
_notifier!.OnCompleted(action);
}
}
public void GetResult() { }
static abstract Action GetContinuationAction(T task);
static abstract Continuation GetContinuationState(T task);
static abstract void SetContinuationState(T task, Continuation value);
static abstract bool SetCompleted(T task, Continuation continuation);
static abstract void PostToSyncContext(T task, SynchronizationContext syncCtx);
}
private static Continuation UnlinkHeadContinuation(out AwaitableProxy awaitableProxy)
private sealed class ThunkTask<T> : Task<T>
{
ref RuntimeAsyncAwaitState state = ref t_runtimeAsyncAwaitState;
awaitableProxy = new AwaitableProxy(state.Notifier!);
state.Notifier = null;
Continuation sentinelContinuation = state.SentinelContinuation!;
Continuation head = sentinelContinuation.Next!;
sentinelContinuation.Next = null;
return head;
}
// When a Task-returning thunk gets a continuation result
// it calls here to make a Task that awaits on the current async state.
// NOTE: This cannot be Runtime Async. Must use C# state machine or make one by hand.
private static async Task<T?> FinalizeTaskReturningThunk<T>(Continuation continuation)
{
Continuation finalContinuation = new Continuation();
// Note that the exact location the return value is placed is tied
// into getAsyncResumptionStub in the VM, so do not change this
// without also changing that code (and the JIT).
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
public ThunkTask()
{
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA | CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
finalContinuation.GCData = new object[1];
}
else
{
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
finalContinuation.Data = new byte[Unsafe.SizeOf<T>()];
// We use the base Task's state object field to store the Continuation while posting the task around.
// Ensure that state object isn't published out for others to see.
Debug.Assert((m_stateFlags & (int)InternalTaskOptions.PromiseTask) != 0, "Expected state flags to already be configured.");
Debug.Assert(m_stateObject is null, "Expected to be able to use the state object field for Continuation.");
m_action = MoveNext;
m_stateFlags |= (int)InternalTaskOptions.HiddenState;
}
continuation.Next = finalContinuation;
while (true)
internal override void ExecuteFromThreadPool(Thread threadPoolThread)
{
Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy);
await awaitableProxy;
Continuation? finalResult = DispatchContinuations(headContinuation);
if (finalResult != null)
MoveNext();
}
private void MoveNext()
{
ThunkTaskCore.MoveNext<ThunkTask<T>, Ops>(this);
}
public void HandleSuspended()
{
ThunkTaskCore.HandleSuspended<ThunkTask<T>, Ops>(this);
}
private static readonly SendOrPostCallback s_postCallback = static state =>
{
Debug.Assert(state is ThunkTask<T>);
((ThunkTask<T>)state).MoveNext();
};
private struct Ops : IThunkTaskOps<ThunkTask<T>>
{
public static Action GetContinuationAction(ThunkTask<T> task) => (Action)task.m_action!;
public static void MoveNext(ThunkTask<T> task) => task.MoveNext();
public static Continuation GetContinuationState(ThunkTask<T> task) => (Continuation)task.m_stateObject!;
public static void SetContinuationState(ThunkTask<T> task, Continuation value)
{
Debug.Assert(finalResult == finalContinuation);
task.m_stateObject = value;
}
public static bool SetCompleted(ThunkTask<T> task, Continuation continuation)
{
T result;
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
if (typeof(T).IsValueType)
{
return Unsafe.As<byte, T>(ref finalResult.GCData![0]!.GetRawData());
result = Unsafe.As<byte, T>(ref continuation.GCData![0]!.GetRawData());
}
return Unsafe.As<object, T>(ref finalResult.GCData![0]!);
}
else
{
return Unsafe.As<byte, T>(ref finalResult.Data![0]);
}
}
}
}
private static async Task FinalizeTaskReturningThunk(Continuation continuation)
{
Continuation finalContinuation = new Continuation
{
Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION,
};
continuation.Next = finalContinuation;
while (true)
{
Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy);
await awaitableProxy;
Continuation? finalResult = DispatchContinuations(headContinuation);
if (finalResult != null)
{
Debug.Assert(finalResult == finalContinuation);
return;
}
}
}
private static async ValueTask<T?> FinalizeValueTaskReturningThunk<T>(Continuation continuation)
{
Continuation finalContinuation = new Continuation();
// Note that the exact location the return value is placed is tied
// into getAsyncResumptionStub in the VM, so do not change this
// without also changing that code (and the JIT).
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA | CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
finalContinuation.GCData = new object[1];
}
else
{
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
finalContinuation.Data = new byte[Unsafe.SizeOf<T>()];
}
continuation.Next = finalContinuation;
while (true)
{
Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy);
await awaitableProxy;
Continuation? finalResult = DispatchContinuations(headContinuation);
if (finalResult != null)
{
Debug.Assert(finalResult == finalContinuation);
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
if (typeof(T).IsValueType)
else
{
return Unsafe.As<byte, T>(ref finalResult.GCData![0]!.GetRawData());
result = Unsafe.As<object, T>(ref continuation.GCData![0]!);
}
return Unsafe.As<object, T>(ref finalResult.GCData![0]!);
}
else
{
return Unsafe.As<byte, T>(ref finalResult.Data![0]);
result = Unsafe.As<byte, T>(ref continuation.Data![0]);
}
return task.TrySetResult(result);
}
public static void PostToSyncContext(ThunkTask<T> task, SynchronizationContext syncContext)
{
syncContext.Post(s_postCallback, task);
}
}
}
private sealed class ThunkTask : Task
{
public ThunkTask()
{
// We use the base Task's state object field to store the Continuation while posting the task around.
// Ensure that state object isn't published out for others to see.
Debug.Assert((m_stateFlags & (int)InternalTaskOptions.PromiseTask) != 0, "Expected state flags to already be configured.");
Debug.Assert(m_stateObject is null, "Expected to be able to use the state object field for Continuation.");
m_action = MoveNext;
m_stateFlags |= (int)InternalTaskOptions.HiddenState;
}
internal override void ExecuteFromThreadPool(Thread threadPoolThread)
{
MoveNext();
}
private void MoveNext()
{
ThunkTaskCore.MoveNext<ThunkTask, Ops>(this);
}
public void HandleSuspended()
{
ThunkTaskCore.HandleSuspended<ThunkTask, Ops>(this);
}
private static readonly SendOrPostCallback s_postCallback = static state =>
{
Debug.Assert(state is ThunkTask);
((ThunkTask)state).MoveNext();
};
private struct Ops : IThunkTaskOps<ThunkTask>
{
public static Action GetContinuationAction(ThunkTask task) => (Action)task.m_action!;
public static void MoveNext(ThunkTask task) => task.MoveNext();
public static Continuation GetContinuationState(ThunkTask task) => (Continuation)task.m_stateObject!;
public static void SetContinuationState(ThunkTask task, Continuation value)
{
task.m_stateObject = value;
}
public static bool SetCompleted(ThunkTask task, Continuation continuation)
{
return task.TrySetResult();
}
public static void PostToSyncContext(ThunkTask task, SynchronizationContext syncContext)
{
syncContext.Post(s_postCallback, task);
}
}
}
private static class ThunkTaskCore
{
public static unsafe void MoveNext<T, TOps>(T task) where T : Task where TOps : IThunkTaskOps<T>
{
ExecutionAndSyncBlockStore contexts = default;
contexts.Push();
Continuation continuation = TOps.GetContinuationState(task);
while (true)
{
try
{
Continuation? newContinuation = continuation.Resume(continuation);
if (newContinuation != null)
{
newContinuation.Next = continuation.Next;
HandleSuspended<T, TOps>(task);
contexts.Pop();
return;
}
Debug.Assert(continuation.Next != null);
continuation = continuation.Next;
}
catch (Exception ex)
{
Continuation nextContinuation = UnwindToPossibleHandler(continuation);
if (nextContinuation.Resume == null)
{
// Tail of AsyncTaskMethodBuilderT.SetException
bool successfullySet = ex is OperationCanceledException oce ?
task.TrySetCanceled(oce.CancellationToken, oce) :
task.TrySetException(ex);
contexts.Pop();
if (!successfullySet)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
}
return;
}
nextContinuation.SetException(ex);
continuation = nextContinuation;
}
if (continuation.Resume == null)
{
bool successfullySet = TOps.SetCompleted(task, continuation);
contexts.Pop();
if (!successfullySet)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
}
return;
}
if (QueueContinuationFollowUpActionIfNecessary<T, TOps>(task, continuation))
{
contexts.Pop();
return;
}
}
}
}
private static async ValueTask FinalizeValueTaskReturningThunk(Continuation continuation)
{
Continuation finalContinuation = new Continuation
private static Continuation UnwindToPossibleHandler(Continuation continuation)
{
Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION,
};
continuation.Next = finalContinuation;
while (true)
{
Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy);
await awaitableProxy;
Continuation? finalResult = DispatchContinuations(headContinuation);
if (finalResult != null)
while (true)
{
Debug.Assert(finalResult == finalContinuation);
return;
Debug.Assert(continuation.Next != null);
continuation = continuation.Next;
if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION) != 0)
return continuation;
}
}
}
// Return a continuation object if that is the one which has the final
// result of the Task, if the real output of the series of continuations was
// an exception, it is allowed to propagate out.
// OR
// return NULL to indicate that this isn't yet done.
private static unsafe Continuation? DispatchContinuations(Continuation? continuation)
{
Debug.Assert(continuation != null);
while (true)
public static void HandleSuspended<T, TOps>(T task) where T : Task where TOps : IThunkTaskOps<T>
{
Continuation? newContinuation;
Continuation headContinuation = UnlinkHeadContinuation(out INotifyCompletion? notifier);
// Head continuation should be the result of async call to AwaitAwaiter or UnsafeAwaitAwaiter.
// These never have special continuation handling.
const CorInfoContinuationFlags continueFlags =
CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT |
CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL |
CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER;
Debug.Assert((headContinuation.Flags & continueFlags) == 0);
TOps.SetContinuationState(task, headContinuation);
try
{
newContinuation = continuation.Resume(continuation);
if (notifier is ICriticalNotifyCompletion crit)
{
crit.UnsafeOnCompleted(TOps.GetContinuationAction(task));
}
else
{
Debug.Assert(notifier != null);
notifier.OnCompleted(TOps.GetContinuationAction(task));
}
}
catch (Exception ex)
{
continuation = UnwindToPossibleHandler(continuation);
if (continuation.Resume == null)
Task.ThrowAsync(ex, targetContext: null);
}
}
private static Continuation UnlinkHeadContinuation(out INotifyCompletion? notifier)
{
ref RuntimeAsyncAwaitState state = ref t_runtimeAsyncAwaitState;
notifier = state.Notifier;
state.Notifier = null;
Continuation sentinelContinuation = state.SentinelContinuation!;
Continuation head = sentinelContinuation.Next!;
sentinelContinuation.Next = null;
return head;
}
private static bool QueueContinuationFollowUpActionIfNecessary<T, TOps>(T task, Continuation continuation) where T : Task where TOps : IThunkTaskOps<T>
{
if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL) != 0)
{
SynchronizationContext? ctx = Thread.CurrentThreadAssumedInitialized._synchronizationContext;
if (ctx == null || ctx.GetType() == typeof(SynchronizationContext))
{
throw;
TaskScheduler? sched = TaskScheduler.InternalCurrent;
if (sched == null || sched == TaskScheduler.Default)
{
// Can inline
return false;
}
}
continuation.GCData![(continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA) != 0 ? 1 : 0] = ex;
continue;
TOps.SetContinuationState(task, continuation);
ThreadPool.UnsafeQueueUserWorkItemInternal(task, preferLocal: true);
return true;
}
if (newContinuation != null)
if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT) != 0)
{
newContinuation.Next = continuation.Next;
return null;
object continuationContext = continuation.GetContinuationContext();
Debug.Assert(continuationContext is SynchronizationContext { });
SynchronizationContext continuationSyncCtx = (SynchronizationContext)continuationContext;
if (continuationSyncCtx == Thread.CurrentThreadAssumedInitialized._synchronizationContext)
{
// Inline
return false;
}
TOps.SetContinuationState(task, continuation);
try
{
TOps.PostToSyncContext(task, continuationSyncCtx);
}
catch (Exception ex)
{
Task.ThrowAsync(ex, targetContext: null);
}
return true;
}
continuation = continuation.Next;
Debug.Assert(continuation != null);
if (continuation.Resume == null)
if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER) != 0)
{
return continuation; // Return the result containing Continuation
object continuationContext = continuation.GetContinuationContext();
Debug.Assert(continuationContext is TaskScheduler { });
TaskScheduler sched = (TaskScheduler)continuationContext;
TOps.SetContinuationState(task, continuation);
// TODO: We do not need TaskSchedulerAwaitTaskContinuation here, just need to refactor its Run method...
var taskSchedCont = new TaskSchedulerAwaitTaskContinuation(sched, TOps.GetContinuationAction(task), flowExecutionContext: false);
taskSchedCont.Run(Task.CompletedTask, canInlineContinuationTask: true);
return true;
}
return false;
}
}
private static Continuation UnwindToPossibleHandler(Continuation continuation)
// Change return type to ThunkTask<T?> -- no benefit since this is used for Task returning thunks only
#pragma warning disable CA1859
// When a Task-returning thunk gets a continuation result
// it calls here to make a Task that awaits on the current async state.
private static Task<T?> FinalizeTaskReturningThunk<T>(Continuation continuation)
{
while (true)
Continuation finalContinuation = new Continuation();
// Note that the exact location the return value is placed is tied
// into getAsyncResumptionStub in the VM, so do not change this
// without also changing that code (and the JIT).
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
Debug.Assert(continuation.Next != null);
continuation = continuation.Next;
if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION) != 0)
return continuation;
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA | CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
finalContinuation.GCData = new object[1];
}
else
{
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
finalContinuation.Data = new byte[Unsafe.SizeOf<T>()];
}
continuation.Next = finalContinuation;
ThunkTask<T?> result = new();
result.HandleSuspended();
return result;
}
private static Task FinalizeTaskReturningThunk(Continuation continuation)
{
Continuation finalContinuation = new Continuation
{
Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION,
};
continuation.Next = finalContinuation;
ThunkTask result = new();
result.HandleSuspended();
return result;
}
private static ValueTask<T?> FinalizeValueTaskReturningThunk<T>(Continuation continuation)
{
// We only come to these methods in the expensive case (already
// suspended), so ValueTask optimization here is not relevant.
return new ValueTask<T?>(FinalizeTaskReturningThunk<T>(continuation));
}
private static ValueTask FinalizeValueTaskReturningThunk(Continuation continuation)
{
return new ValueTask(FinalizeTaskReturningThunk(continuation));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -414,14 +591,58 @@ namespace System.Runtime.CompilerServices
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void RestoreExecutionContext(ExecutionContext? previousExecutionCtx)
private static void RestoreExecutionContext(ExecutionContext? previousExecCtx)
{
Thread thread = Thread.CurrentThreadAssumedInitialized;
ExecutionContext? currentExecutionCtx = thread._executionContext;
if (previousExecutionCtx != currentExecutionCtx)
ExecutionContext? currentExecCtx = thread._executionContext;
if (previousExecCtx != currentExecCtx)
{
ExecutionContext.RestoreChangedContextToThread(thread, previousExecutionCtx, currentExecutionCtx);
ExecutionContext.RestoreChangedContextToThread(thread, previousExecCtx, currentExecCtx);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void CaptureContexts(out ExecutionContext? execCtx, out SynchronizationContext? syncCtx)
{
Thread thread = Thread.CurrentThreadAssumedInitialized;
execCtx = thread._executionContext;
syncCtx = thread._synchronizationContext;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void RestoreContexts(bool suspended, ExecutionContext? previousExecCtx, SynchronizationContext? previousSyncCtx)
{
Thread thread = Thread.CurrentThreadAssumedInitialized;
if (!suspended && previousSyncCtx != thread._synchronizationContext)
{
thread._synchronizationContext = previousSyncCtx;
}
ExecutionContext? currentExecCtx = thread._executionContext;
if (previousExecCtx != currentExecCtx)
{
ExecutionContext.RestoreChangedContextToThread(thread, previousExecCtx, currentExecCtx);
}
}
private static void CaptureContinuationContext(SynchronizationContext syncCtx, ref object context, ref CorInfoContinuationFlags flags)
{
if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext))
{
flags |= CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT;
context = syncCtx;
return;
}
TaskScheduler? sched = TaskScheduler.InternalCurrent;
if (sched != null && sched != TaskScheduler.Default)
{
flags |= CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER;
context = sched;
return;
}
flags |= CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL;
}
}
}

View File

@ -51,9 +51,9 @@ class AsmOffsets
public const int OFFSETOF__REGDISPLAY__SP = 0xba8;
public const int OFFSETOF__REGDISPLAY__ControlPC = 0xbb0;
#elif TARGET_WASM
public const int SIZEOF__REGDISPLAY = 0x3c;
public const int OFFSETOF__REGDISPLAY__SP = 0x34;
public const int OFFSETOF__REGDISPLAY__ControlPC = 0x38;
public const int SIZEOF__REGDISPLAY = 0x38;
public const int OFFSETOF__REGDISPLAY__SP = 0x30;
public const int OFFSETOF__REGDISPLAY__ControlPC = 0x34;
#endif
#if TARGET_64BIT
@ -73,9 +73,14 @@ class AsmOffsets
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3d0;
#else // TARGET_64BIT
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4;
#if FEATURE_INTERPRETER
public const int SIZEOF__StackFrameIterator = 0xdc;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xd8;
#else
public const int SIZEOF__StackFrameIterator = 0xcc;
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xba;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xc8;
#endif
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xba;
#endif // TARGET_64BIT
#else // DEBUG
@ -117,9 +122,9 @@ class AsmOffsets
public const int OFFSETOF__REGDISPLAY__SP = 0xba0;
public const int OFFSETOF__REGDISPLAY__ControlPC = 0xba8;
#elif TARGET_WASM
public const int SIZEOF__REGDISPLAY = 0x3c;
public const int OFFSETOF__REGDISPLAY__SP = 0x34;
public const int OFFSETOF__REGDISPLAY__ControlPC = 0x38;
public const int SIZEOF__REGDISPLAY = 0x34;
public const int OFFSETOF__REGDISPLAY__SP = 0x2c;
public const int OFFSETOF__REGDISPLAY__ControlPC = 0x30;
#endif
#if TARGET_64BIT
@ -139,9 +144,14 @@ class AsmOffsets
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3c8;
#else // TARGET_64BIT
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4;
#if FEATURE_INTERPRETER
public const int SIZEOF__StackFrameIterator = 0xd4;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xd0;
#else
public const int SIZEOF__StackFrameIterator = 0xc4;
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xb2;
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xc0;
#endif
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xb2;
#endif // TARGET_64BIT
#endif // DEBUG
@ -167,7 +177,7 @@ class AsmOffsets
#elif TARGET_LOONGARCH64
public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x520;
#elif TARGET_WASM
public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x08;
public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x04;
#endif
#if TARGET_AMD64

View File

@ -12,39 +12,24 @@ namespace System.Runtime.InteropServices.Java
{
public static unsafe void Initialize(delegate* unmanaged<MarkCrossReferencesArgs*, void> markCrossReferences)
{
#if NATIVEAOT
throw new NotImplementedException();
#elif FEATURE_JAVAMARSHAL
ArgumentNullException.ThrowIfNull(markCrossReferences);
if (!InitializeInternal((IntPtr)markCrossReferences))
{
throw new InvalidOperationException(SR.InvalidOperation_ReinitializeJavaMarshal);
}
#else
throw new PlatformNotSupportedException();
#endif
}
public static unsafe GCHandle CreateReferenceTrackingHandle(object obj, void* context)
{
#if NATIVEAOT
throw new NotImplementedException();
#elif FEATURE_JAVAMARSHAL
ArgumentNullException.ThrowIfNull(obj);
IntPtr handle = CreateReferenceTrackingHandleInternal(ObjectHandleOnStack.Create(ref obj), context);
return GCHandle.FromIntPtr(handle);
#else
throw new PlatformNotSupportedException();
#endif
}
public static unsafe void* GetContext(GCHandle obj)
{
#if NATIVEAOT
throw new NotImplementedException();
#elif FEATURE_JAVAMARSHAL
IntPtr handle = GCHandle.ToIntPtr(obj);
if (handle == IntPtr.Zero
|| !GetContextInternal(handle, out void* context))
@ -53,18 +38,12 @@ namespace System.Runtime.InteropServices.Java
}
return context;
#else
throw new PlatformNotSupportedException();
#endif
}
public static unsafe void FinishCrossReferenceProcessing(
MarkCrossReferencesArgs* crossReferences,
ReadOnlySpan<GCHandle> unreachableObjectHandles)
{
#if NATIVEAOT
throw new NotImplementedException();
#elif FEATURE_JAVAMARSHAL
fixed (GCHandle* pHandles = unreachableObjectHandles)
{
FinishCrossReferenceProcessing(
@ -72,12 +51,8 @@ namespace System.Runtime.InteropServices.Java
(nuint)unreachableObjectHandles.Length,
pHandles);
}
#else
throw new PlatformNotSupportedException();
#endif
}
#if FEATURE_JAVAMARSHAL && !NATIVEAOT
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "JavaMarshal_Initialize")]
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool InitializeInternal(IntPtr callback);
@ -92,6 +67,5 @@ namespace System.Runtime.InteropServices.Java
[SuppressGCTransition]
[return: MarshalAs(UnmanagedType.Bool)]
private static unsafe partial bool GetContextInternal(IntPtr handle, out void* context);
#endif
}
}

View File

@ -3974,6 +3974,11 @@ namespace System
throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, this));
}
if (IsByRefLike)
{
throw new NotSupportedException(SR.NotSupported_ByRefLike);
}
// Compat: allocation always takes place outside the try block so that OOMs
// bubble up to the caller; the ctor invocation is within the try block so
// that it can be wrapped in TIE if needed.
@ -3996,6 +4001,8 @@ namespace System
[DebuggerHidden]
internal object? CreateInstanceOfT()
{
Debug.Assert(!IsValueType);
ActivatorCache cache = GetOrCreateCacheEntry<ActivatorCache>();
if (!cache.CtorIsPublic)

View File

@ -1351,26 +1351,20 @@ namespace System.StubHelpers
internal static Exception GetHRExceptionObject(int hr)
{
Exception? ex = null;
GetHRExceptionObject(hr, ObjectHandleOnStack.Create(ref ex));
ex!.InternalPreserveStackTrace();
return ex!;
Exception ex = Marshal.GetExceptionForHR(hr)!;
ex.InternalPreserveStackTrace();
return ex;
}
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_GetHRExceptionObject")]
private static partial void GetHRExceptionObject(int hr, ObjectHandleOnStack throwable);
#if FEATURE_COMINTEROP
internal static Exception GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, object pThis)
internal static Exception GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, IntPtr pUnk)
{
Exception? ex = null;
GetCOMHRExceptionObject(hr, pCPCMD, ObjectHandleOnStack.Create(ref pThis), ObjectHandleOnStack.Create(ref ex));
ex!.InternalPreserveStackTrace();
return ex!;
RuntimeMethodHandle handle = RuntimeMethodHandle.FromIntPtr(pCPCMD);
RuntimeType declaringType = RuntimeMethodHandle.GetDeclaringType(handle.GetMethodInfo());
Exception ex = Marshal.GetExceptionForHR(hr, declaringType.GUID, pUnk)!;
ex.InternalPreserveStackTrace();
return ex;
}
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_GetCOMHRExceptionObject")]
private static partial void GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, ObjectHandleOnStack pThis, ObjectHandleOnStack throwable);
#endif // FEATURE_COMINTEROP
[ThreadStatic]
@ -1583,8 +1577,7 @@ namespace System.StubHelpers
internal static partial void ValidateByref(IntPtr byref, IntPtr pMD); // the byref is pinned so we can safely "cast" it to IntPtr
[Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern IntPtr GetStubContext();
internal static IntPtr GetStubContext() => throw new UnreachableException(); // Unconditionally expanded intrinsic
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void MulticastDebuggerTraceHelper(object o, int count)
@ -1596,11 +1589,10 @@ namespace System.StubHelpers
private static partial void MulticastDebuggerTraceHelperQCall(ObjectHandleOnStack obj, int count);
[Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern IntPtr NextCallReturnAddress();
internal static IntPtr NextCallReturnAddress() => throw new UnreachableException(); // Unconditionally expanded intrinsic
[Intrinsic]
internal static Continuation? AsyncCallContinuation() => null;
internal static Continuation? AsyncCallContinuation() => throw new UnreachableException(); // Unconditionally expanded intrinsic
} // class StubHelpers
#if FEATURE_COMINTEROP

View File

@ -152,8 +152,6 @@ if(FEATURE_OBJCMARSHAL)
add_compile_definitions(FEATURE_OBJCMARSHAL)
endif()
# add_compile_definitions(FEATURE_RUNTIME_ASYNC)
add_compile_definitions($<${FEATURE_JAVAMARSHAL}:FEATURE_JAVAMARSHAL>)
add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:DAC_COMPONENT>>>:FEATURE_PROFAPI_ATTACH_DETACH>)

View File

@ -2,6 +2,10 @@ if (NOT CLR_CMAKE_TARGET_ARCH_WASM)
set(FEATURE_JIT 1)
endif()
if (CLR_CMAKE_TARGET_ARCH_WASM OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
set(FEATURE_STATICALLY_LINKED 1)
endif()
if(CLR_CMAKE_TARGET_TIZEN_LINUX)
set(FEATURE_GDBJIT_LANGID_CS 1)
endif()
@ -32,13 +36,15 @@ endif(NOT DEFINED FEATURE_DBGIPC)
if(NOT DEFINED FEATURE_INTERPRETER)
if(CLR_CMAKE_TARGET_ANDROID)
set(FEATURE_INTERPRETER 0)
set(FEATURE_INTERPRETER 0)
elseif(CLR_CMAKE_TARGET_ARCH_WASM)
set(FEATURE_INTERPRETER 1)
else()
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
set(FEATURE_INTERPRETER $<IF:$<CONFIG:Debug,Checked>,1,0>)
else(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
set(FEATURE_INTERPRETER 0)
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
set(FEATURE_INTERPRETER $<IF:$<CONFIG:Debug,Checked>,1,0>)
else(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
set(FEATURE_INTERPRETER 0)
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
endif()
endif(NOT DEFINED FEATURE_INTERPRETER)
@ -54,7 +60,7 @@ if(NOT DEFINED FEATURE_SINGLE_FILE_DIAGNOSTICS)
set(FEATURE_SINGLE_FILE_DIAGNOSTICS 1)
endif(NOT DEFINED FEATURE_SINGLE_FILE_DIAGNOSTICS)
if (CLR_CMAKE_TARGET_WIN32 OR CLR_CMAKE_TARGET_UNIX)
if ((CLR_CMAKE_TARGET_WIN32 OR CLR_CMAKE_TARGET_UNIX) AND NOT CLR_CMAKE_TARGET_ARCH_WASM)
set(FEATURE_COMWRAPPERS 1)
endif()

View File

@ -3423,9 +3423,9 @@ void DacDbiInterfaceImpl::EnumerateMemRangesForJitCodeHeaps(CQuickArrayList<COR_
{
// We should always have a valid EEJitManager with at least one code heap.
EEJitManager *pEM = ExecutionManager::GetEEJitManager();
_ASSERTE(pEM != NULL && pEM->m_pCodeHeap.IsValid());
_ASSERTE(pEM != NULL && pEM->m_pAllCodeHeaps.IsValid());
PTR_HeapList pHeapList = pEM->m_pCodeHeap;
PTR_HeapList pHeapList = pEM->m_pAllCodeHeaps;
while (pHeapList != NULL)
{
CodeHeap *pHeap = pHeapList->pHeap;
@ -4963,9 +4963,21 @@ void DacDbiInterfaceImpl::Hijack(
// Setup context for hijack
//
T_CONTEXT ctx;
#if !defined(CROSS_COMPILE) && !defined(TARGET_WINDOWS) && (defined(DTCONTEXT_IS_AMD64) || defined(DTCONTEXT_IS_ARM64))
// If the host or target is not Windows, then we can assume that the DT_CONTEXT
// is the same as the T_CONTEXT, except for the XSTATE registers.
static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT does not include the XSTATE registers");
#else
// Since Dac + DBI are tightly coupled, context sizes should be the same.
static_assert(sizeof(DT_CONTEXT) == sizeof(T_CONTEXT), "DT_CONTEXT size must equal the T_CONTEXT size");
#endif
HRESULT hr = m_pTarget->GetThreadContext(
dwThreadId,
CONTEXT_FULL,
CONTEXT_FULL | CONTEXT_FLOATING_POINT
#ifdef CONTEXT_EXTENDED_REGISTERS
| CONTEXT_EXTENDED_REGISTERS
#endif
,
sizeof(DT_CONTEXT),
(BYTE*) &ctx);
IfFailThrow(hr);

View File

@ -169,7 +169,7 @@ extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction
*ppFunctions = 0;
*pnEntries = 0;
DWORD_PTR pHp = JitMan + (DWORD_PTR)offsetof(FakeEEJitManager, m_pCodeHeap);
DWORD_PTR pHp = JitMan + (DWORD_PTR)offsetof(FakeEEJitManager, m_pAllCodeHeaps);
move(pHp, pHp);

View File

@ -15,8 +15,8 @@ struct FakeEEJitManager
{
LPVOID __VFN_table;
LPVOID m_runtimeSupport;
LPVOID m_pCodeHeap;
// Nothing after this point matters: we only need the correct offset of m_pCodeHeap.
LPVOID m_pAllCodeHeaps;
// Nothing after this point matters: we only need the correct offset of m_pAllCodeHeaps.
};
struct FakeHeapList
@ -76,7 +76,7 @@ class CheckDuplicatedStructLayouts
{
#define CHECK_OFFSET(cls, fld) CPP_ASSERT(cls##fld, offsetof(Fake##cls, fld) == offsetof(cls, fld))
CHECK_OFFSET(EEJitManager, m_pCodeHeap);
CHECK_OFFSET(EEJitManager, m_pAllCodeHeaps);
CHECK_OFFSET(HeapList, hpNext);
CHECK_OFFSET(HeapList, startAddress);

View File

@ -38,9 +38,9 @@ DacGetThread(ULONG32 osThread)
UNREACHABLE();
}
// Note that if we had access to TLS, we could get this at index gThreadTLSIndex for the specified
// thread. However, this is the only place we might want to use TLS, and it's not performance critical,
// so we haven't added TLS support to ICorDebugDataTarget (the legacy ICLRDataTarget interface has it though)
// Note that if we had access to TLS, we could get this at TLS for the specified thread. However, this is
// the only place we might want to use TLS, and it's not performance critical, so we haven't added TLS support
// to ICorDebugDataTarget (the legacy ICLRDataTarget interface has it though)
// Scan the whole thread store to see if there's a matching thread.

View File

@ -362,7 +362,7 @@ ClrDataAccess::GetJitManagerList(unsigned int count, struct DacpJitManagerInfo m
currentPtr->codeType = managerPtr->GetCodeType();
EEJitManager *eeJitManager = PTR_EEJitManager(PTR_HOST_TO_TADDR(managerPtr));
currentPtr->ptrHeapList = HOST_CDADDR(eeJitManager->m_pCodeHeap);
currentPtr->ptrHeapList = HOST_CDADDR(eeJitManager->m_pAllCodeHeaps);
}
}
else if (pNeeded)
@ -528,7 +528,7 @@ ClrDataAccess::GetCodeHeapList(CLRDATA_ADDRESS jitManager, unsigned int count, s
SOSDacEnter();
EEJitManager *pJitManager = PTR_EEJitManager(TO_TADDR(jitManager));
HeapList *heapList = pJitManager->m_pCodeHeap;
HeapList *heapList = pJitManager->m_pAllCodeHeaps;
if (codeHeaps)
{
@ -2434,31 +2434,25 @@ ClrDataAccess::GetAppDomainData(CLRDATA_ADDRESS addr, struct DacpAppDomainData *
if (addr != HOST_CDADDR(SystemDomain::System()))
{
PTR_AppDomain pAppDomain = PTR_AppDomain(TO_TADDR(addr));
appdomainData->DomainLocalBlock = 0;
appdomainData->pDomainLocalModules = 0;
appdomainData->dwId = DefaultADID;
appdomainData->appDomainStage = (DacpAppDomainDataStage)pAppDomain->m_Stage.Load();
if (pAppDomain->IsActive())
AppDomain::AssemblyIterator i = pAppDomain->IterateAssembliesEx((AssemblyIterationFlags)(
kIncludeLoading | kIncludeLoaded | kIncludeExecution));
CollectibleAssemblyHolder<Assembly *> pAssembly;
while (i.Next(pAssembly.This()))
{
// The assembly list is not valid in a closed appdomain.
AppDomain::AssemblyIterator i = pAppDomain->IterateAssembliesEx((AssemblyIterationFlags)(
kIncludeLoading | kIncludeLoaded | kIncludeExecution));
CollectibleAssemblyHolder<Assembly *> pAssembly;
while (i.Next(pAssembly.This()))
if (pAssembly->IsLoaded())
{
if (pAssembly->IsLoaded())
{
appdomainData->AssemblyCount++;
}
appdomainData->AssemblyCount++;
}
}
AppDomain::FailedAssemblyIterator j = pAppDomain->IterateFailedAssembliesEx();
while (j.Next())
{
appdomainData->FailedAssemblyCount++;
}
AppDomain::FailedAssemblyIterator j = pAppDomain->IterateFailedAssembliesEx();
while (j.Next())
{
appdomainData->FailedAssemblyCount++;
}
}
}

View File

@ -42,6 +42,7 @@
#include <common.h>
#include <codeman.h>
#include <debugger.h>
#include <walker.h>
#include <controller.h>
#include <eedbginterfaceimpl.h>
#include <methoditer.h>

View File

@ -32,10 +32,9 @@
//-----------------------------------------------------------------------------
// In v1.0, we declared that mscordbi was a "shared" component, which means
// that we promised to provide it from now until the end of time. So every CLR implementation
// needs an Mscordbi that implements the everett guids for CorDebug + CorPublish.
// needs an Mscordbi that implements the everett guids for CorDebug
//
// This works fine for CorPublish, which is truly shared.
// CorDebug however is "versioned" not "shared" - each version of the CLR has its own disjoint copy.
// CorDebug is "versioned" not "shared" - each version of the CLR has its own disjoint copy.
//
// Thus creating a CorDebug object requires a version parameter.
// CoCreateInstance doesn't have a the version param, so we use the new (v2.0+)
@ -307,14 +306,6 @@ STDAPI DLLEXPORT DllGetClassObjectInternal( // Return code.
CClassFactory *pClassFactory; // To create class factory object.
PFN_CREATE_OBJ pfnCreateObject = NULL;
#if defined(FEATURE_DBG_PUBLISH)
if (rclsid == CLSID_CorpubPublish)
{
pfnCreateObject = CorpubPublish::CreateObject;
}
else
#endif
#if defined(FEATURE_DBGIPC_TRANSPORT_DI)
if (rclsid == CLSID_CorDebug_Telesto)
{

View File

@ -5061,6 +5061,23 @@ void CordbProcess::RawDispatchEvent(
case DB_IPCE_LOAD_MODULE:
{
LOG((LF_CORDB, LL_INFO100,
"RCET::HRCE: load module (includes assembly loading) on thread %#x Asm:0x%08x AD:0x%08x \n",
dwVolatileThreadId,
VmPtrToCookie(pEvent->LoadModuleData.vmDomainAssembly),
VmPtrToCookie(pEvent->vmAppDomain)));
_ASSERTE (pAppDomain != NULL);
// Determine if this Assembly is cached.
CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->LoadModuleData.vmDomainAssembly);
_ASSERTE(pAssembly != NULL); // throws on error
// If created, or have, an Assembly, notify callback.
{
PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
hr = pCallback1->LoadAssembly(pAppDomain, pAssembly);
}
_ASSERTE (pAppDomain != NULL);
CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadModuleData.vmDomainAssembly);
@ -5375,29 +5392,6 @@ void CordbProcess::RawDispatchEvent(
break;
case DB_IPCE_LOAD_ASSEMBLY:
{
LOG((LF_CORDB, LL_INFO100,
"RCET::HRCE: load assembly on thread %#x Asm:0x%08x AD:0x%08x \n",
dwVolatileThreadId,
VmPtrToCookie(pEvent->AssemblyData.vmDomainAssembly),
VmPtrToCookie(pEvent->vmAppDomain)));
_ASSERTE (pAppDomain != NULL);
// Determine if this Assembly is cached.
CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->AssemblyData.vmDomainAssembly);
_ASSERTE(pAssembly != NULL); // throws on error
// If created, or have, an Assembly, notify callback.
{
PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
hr = pCallback1->LoadAssembly(pAppDomain, pAssembly);
}
}
break;
case DB_IPCE_UNLOAD_ASSEMBLY:
{
LOG((LF_CORDB, LL_INFO100, "RCET::DRCE: unload assembly on thread %#x Asm:0x%x AD:0x%x\n",
@ -13281,9 +13275,9 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven
LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: hijack complete will restore context...\n"));
DT_CONTEXT tempContext = { 0 };
#if defined(DT_CONTEXT_EXTENDED_REGISTERS)
tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS;
tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS;
#else
tempContext.ContextFlags = DT_CONTEXT_FULL;
tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT;
#endif
HRESULT hr = pUnmanagedThread->GetThreadContext(&tempContext);
_ASSERTE(SUCCEEDED(hr));

File diff suppressed because it is too large Load Diff

View File

@ -452,7 +452,7 @@ void LeftSideResourceCleanupList::SweepNeuterLeftSideResources(CordbProcess * pP
* ------------------------------------------------------------------------- */
extern void* GetClrModuleBase();
// Do any initialization necessary for both CorPublish and CorDebug
// Do any initialization necessary for CorDebug
// This includes enabling logging and adding the SEDebug priv.
void CordbCommonBase::InitializeCommon()
{

View File

@ -114,13 +114,6 @@ class CordbEval;
class CordbMDA;
class CorpubPublish;
class CorpubProcess;
class CorpubAppDomain;
class CorpubProcessEnum;
class CorpubAppDomainEnum;
class RSLock;
class NeuterList;
@ -1094,11 +1087,11 @@ typedef enum {
enumCordbEnCSnapshot, // 21
enumCordbEval, // 22
enumCordbUnmanagedThread,// 23
enumCorpubPublish, // 24
enumCorpubProcess, // 25
enumCorpubAppDomain, // 26
enumCorpubProcessEnum, // 27
enumCorpubAppDomainEnum,// 28
// unused, // 24
// unused, // 25
// unused, // 26
// unused, // 27
// unused, // 28
enumCordbEnumFilter, // 29
enumCordbEnCErrorInfo, // 30
enumCordbEnCErrorInfoEnum,//31
@ -1157,7 +1150,7 @@ class CordbHashTable;
#define CORDB_COMMON_BASE_SIGNATURE 0x0d00d96a
#define CORDB_COMMON_BASE_SIGNATURE_DEAD 0x0dead0b1
// Common base for both CorPublish + CorDebug objects.
// Common base for CorDebug objects.
class CordbCommonBase : public IUnknown
{
public:
@ -10691,12 +10684,6 @@ public:
};
#endif // FEATURE_INTEROP_DEBUGGING
//********************************************************************************
//**************** App Domain Publishing Service API *****************************
//********************************************************************************
class EnumElement
{
public:
@ -10716,293 +10703,6 @@ private:
EnumElement *m_pNext;
};
#if defined(FEATURE_DBG_PUBLISH)
// Prototype of psapi!GetModuleFileNameEx.
typedef DWORD FPGetModuleFileNameEx(HANDLE, HMODULE, LPTSTR, DWORD);
class CorpubPublish : public CordbCommonBase, public ICorPublish
{
public:
CorpubPublish();
virtual ~CorpubPublish();
#ifdef _DEBUG
virtual const char * DbgGetName() { return "CordbPublish"; }
#endif
//-----------------------------------------------------------
// IUnknown
//-----------------------------------------------------------
ULONG STDMETHODCALLTYPE AddRef()
{
return (BaseAddRef());
}
ULONG STDMETHODCALLTYPE Release()
{
return (BaseRelease());
}
COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
//-----------------------------------------------------------
// ICorPublish
//-----------------------------------------------------------
COM_METHOD EnumProcesses(
COR_PUB_ENUMPROCESS Type,
ICorPublishProcessEnum **ppIEnum);
COM_METHOD GetProcess(
unsigned pid,
ICorPublishProcess **ppProcess);
//-----------------------------------------------------------
// CreateObject
//-----------------------------------------------------------
static COM_METHOD CreateObject(REFIID id, void **object)
{
*object = NULL;
if (id != IID_IUnknown && id != IID_ICorPublish)
return (E_NOINTERFACE);
CorpubPublish *pCorPub = new (nothrow) CorpubPublish();
if (pCorPub == NULL)
return (E_OUTOFMEMORY);
*object = (ICorPublish*)pCorPub;
pCorPub->AddRef();
return (S_OK);
}
private:
HRESULT GetProcessInternal( unsigned pid, CorpubProcess **ppProcess );
// Cached information to get the process name. Not available on all platforms, so may be null.
HModuleHolder m_hPSAPIdll;
FPGetModuleFileNameEx * m_fpGetModuleFileNameEx;
};
class CorpubProcess : public CordbCommonBase, public ICorPublishProcess
{
public:
CorpubProcess(const ProcessDescriptor * pProcessDescriptor,
bool fManaged,
HANDLE hProcess,
HANDLE hMutex,
AppDomainEnumerationIPCBlock *pAD,
#if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
IPCReaderInterface *pIPCReader,
#endif // !FEATURE_DBGIPC_TRANSPORT_DI
FPGetModuleFileNameEx * fpGetModuleFileNameEx);
virtual ~CorpubProcess();
#ifdef _DEBUG
virtual const char * DbgGetName() { return "CorpubProcess"; }
#endif
//-----------------------------------------------------------
// IUnknown
//-----------------------------------------------------------
ULONG STDMETHODCALLTYPE AddRef()
{
return (BaseAddRef());
}
ULONG STDMETHODCALLTYPE Release()
{
return (BaseRelease());
}
COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
//-----------------------------------------------------------
// ICorPublishProcess
//-----------------------------------------------------------
COM_METHOD IsManaged(BOOL *pbManaged);
/*
* Enumerate the list of known application domains in the target process.
*/
COM_METHOD EnumAppDomains(ICorPublishAppDomainEnum **ppEnum);
/*
* Returns the OS ID for the process in question.
*/
COM_METHOD GetProcessID(unsigned *pid);
/*
* Get the display name for a process.
*/
COM_METHOD GetDisplayName(ULONG32 cchName,
ULONG32 *pcchName,
_Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]);
CorpubProcess *GetNextProcess () { return m_pNext;}
void SetNext (CorpubProcess *pNext) { m_pNext = pNext;}
// Helper to tell if this process has exited
bool IsExited();
public:
ProcessDescriptor m_processDescriptor;
private:
bool m_fIsManaged;
HANDLE m_hProcess;
HANDLE m_hMutex;
AppDomainEnumerationIPCBlock *m_AppDomainCB;
#if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
IPCReaderInterface *m_pIPCReader; // controls the lifetime of the AppDomainEnumerationIPCBlock
#endif // !FEATURE_DBGIPC_TRANSPORT_DI
CorpubProcess *m_pNext; // pointer to the next process in the process list
WCHAR *m_szProcessName;
};
class CorpubAppDomain : public CordbCommonBase, public ICorPublishAppDomain
{
public:
CorpubAppDomain (_In_ LPWSTR szAppDomainName, ULONG Id);
virtual ~CorpubAppDomain();
#ifdef _DEBUG
virtual const char * DbgGetName() { return "CorpubAppDomain"; }
#endif
//-----------------------------------------------------------
// IUnknown
//-----------------------------------------------------------
ULONG STDMETHODCALLTYPE AddRef()
{
return (BaseAddRef());
}
ULONG STDMETHODCALLTYPE Release()
{
return (BaseRelease());
}
COM_METHOD QueryInterface (REFIID riid, void **ppInterface);
//-----------------------------------------------------------
// ICorPublishAppDomain
//-----------------------------------------------------------
/*
* Get the name and ID for an application domain.
*/
COM_METHOD GetID (ULONG32 *pId);
/*
* Get the name for an application domain.
*/
COM_METHOD GetName (ULONG32 cchName,
ULONG32 *pcchName,
_Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]);
CorpubAppDomain *GetNextAppDomain () { return m_pNext;}
void SetNext (CorpubAppDomain *pNext) { m_pNext = pNext;}
private:
CorpubAppDomain *m_pNext;
WCHAR *m_szAppDomainName;
ULONG m_id;
};
class CorpubProcessEnum : public CordbCommonBase, public ICorPublishProcessEnum
{
public:
CorpubProcessEnum(CorpubProcess *pFirst);
virtual ~CorpubProcessEnum();
#ifdef _DEBUG
virtual const char * DbgGetName() { return "CorpubProcessEnum"; }
#endif
//-----------------------------------------------------------
// IUnknown
//-----------------------------------------------------------
ULONG STDMETHODCALLTYPE AddRef()
{
return (BaseAddRef());
}
ULONG STDMETHODCALLTYPE Release()
{
return (BaseRelease());
}
COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
//-----------------------------------------------------------
// ICorPublishProcessEnum
//-----------------------------------------------------------
COM_METHOD Skip(ULONG celt);
COM_METHOD Reset();
COM_METHOD Clone(ICorPublishEnum **ppEnum);
COM_METHOD GetCount(ULONG *pcelt);
COM_METHOD Next(ULONG celt,
ICorPublishProcess *objects[],
ULONG *pceltFetched);
private:
CorpubProcess *m_pFirst;
CorpubProcess *m_pCurrent;
};
class CorpubAppDomainEnum : public CordbCommonBase, public ICorPublishAppDomainEnum
{
public:
CorpubAppDomainEnum(CorpubAppDomain *pFirst);
virtual ~CorpubAppDomainEnum();
#ifdef _DEBUG
virtual const char * DbgGetName() { return "CordbAppDomainEnum"; }
#endif
//-----------------------------------------------------------
// IUnknown
//-----------------------------------------------------------
ULONG STDMETHODCALLTYPE AddRef()
{
return (BaseAddRef());
}
ULONG STDMETHODCALLTYPE Release()
{
return (BaseRelease());
}
COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
//-----------------------------------------------------------
// ICorPublishAppDomainEnum
//-----------------------------------------------------------
COM_METHOD Skip(ULONG celt);
COM_METHOD Reset();
COM_METHOD Clone(ICorPublishEnum **ppEnum);
COM_METHOD GetCount(ULONG *pcelt);
COM_METHOD Next(ULONG celt,
ICorPublishAppDomain *objects[],
ULONG *pceltFetched);
private:
CorpubAppDomain *m_pFirst;
CorpubAppDomain *m_pCurrent;
};
#endif // defined(FEATURE_DBG_PUBLISH)
class CordbHeapEnum : public CordbBase, public ICorDebugHeapEnum
{
public:

View File

@ -3706,9 +3706,9 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync()
// to avoid getting incomplete information and corrupt the thread context
DT_CONTEXT context;
#if defined(DT_CONTEXT_EXTENDED_REGISTERS)
context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS;
context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS;
#else
context.ContextFlags = DT_CONTEXT_FULL;
context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT;
#endif
BOOL succ = DbiGetThreadContext(m_handle, &context);
_ASSERTE(succ);
@ -3719,9 +3719,9 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync()
LOG((LF_CORDB, LL_ERROR, "CUT::SFCHFS: DbiGetThreadContext error=0x%x\n", error));
}
#if defined(DT_CONTEXT_EXTENDED_REGISTERS)
GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS;
GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS;
#else
GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL;
GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT;
#endif
CORDbgCopyThreadContext(GetHijackCtx(), &context);
LOG((LF_CORDB, LL_INFO10000, "CUT::SFCHFS: thread=0x%x Hijacking for sync. Original context is:\n", this));

View File

@ -29,7 +29,6 @@ using std::max;
#include "ex.h"
#include "sigparser.h"
#include "corpub.h"
#include "rspriv.h"
// This is included to deal with GCC limitations around templates.

View File

@ -67,9 +67,79 @@ bool DebuggerControllerPatch::IsSafeForStackTrace()
}
#ifndef DACCESS_COMPILE
#ifndef FEATURE_EMULATE_SINGLESTEP
// returns a pointer to the shared buffer. each call will AddRef() the object
// before returning it so callers only need to Release() when they're finished with it.
//
// We have to have a whole separate function for this because you
// can't use __try in a function that requires object unwinding...
//
LONG FilterAccessViolation2(LPEXCEPTION_POINTERS ep, PVOID pv)
{
LIMITED_METHOD_CONTRACT;
return (ep->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
}
// This helper is required because the AVInRuntimeImplOkayHolder can not
// be directly placed inside the scope of a PAL_TRY
void _CopyInstructionBlockHelper(BYTE* to, const BYTE* from)
{
AVInRuntimeImplOkayHolder AVOkay;
// This function only copies the portion of the instruction that follows the
// breakpoint opcode, not the breakpoint itself
to += CORDbg_BREAK_INSTRUCTION_SIZE;
from += CORDbg_BREAK_INSTRUCTION_SIZE;
// If an AV occurs because we walked off a valid page then we need
// to be certain that all bytes on the previous page were copied.
// We are certain that we copied enough bytes to contain the instruction
// because it must have fit within the valid page.
for (int i = 0; i < MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE; i++)
{
*to++ = *from++;
}
}
// WARNING: this function skips copying the first CORDbg_BREAK_INSTRUCTION_SIZE bytes by design
// See the comment at the callsite in DebuggerPatchSkip::DebuggerPatchSkip for more details on
// this
void DebuggerControllerPatch::CopyInstructionBlock(BYTE *to, const BYTE* from)
{
// We wrap the memcpy in an exception handler to handle the
// extremely rare case where we're copying an instruction off the
// end of a method that is also at the end of a page, and the next
// page is unmapped.
struct Param
{
BYTE *to;
const BYTE* from;
} param;
param.to = to;
param.from = from;
PAL_TRY(Param *, pParam, &param)
{
_CopyInstructionBlockHelper(pParam->to, pParam->from);
}
PAL_EXCEPT_FILTER(FilterAccessViolation2)
{
// The whole point is that if we copy up the AV, then
// that's enough to execute, otherwise we would not have been
// able to execute the code anyway. So we just ignore the
// exception.
LOG((LF_CORDB, LL_INFO10000,
"DCP::CIP: AV copying instruction block ignored.\n"));
}
PAL_ENDTRY
}
// Creates a new shared patch bypass buffer
// AddRef() before returning it so callers need to Release() when they're finished with it.
SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBuffer()
{
CONTRACTL
@ -79,27 +149,110 @@ SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBu
}
CONTRACTL_END;
if (m_pSharedPatchBypassBuffer == NULL)
if (m_pSharedPatchBypassBuffer != NULL)
{
void *pSharedPatchBypassBufferRX = g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(SharedPatchBypassBuffer));
#if defined(HOST_OSX) && defined(HOST_ARM64)
ExecutableWriterHolder<SharedPatchBypassBuffer> sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX, sizeof(SharedPatchBypassBuffer));
void *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW();
#else // HOST_OSX && HOST_ARM64
void *pSharedPatchBypassBufferRW = pSharedPatchBypassBufferRX;
#endif // HOST_OSX && HOST_ARM64
new (pSharedPatchBypassBufferRW) SharedPatchBypassBuffer();
m_pSharedPatchBypassBuffer = (SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX;
_ASSERTE(m_pSharedPatchBypassBuffer);
TRACE_ALLOC(m_pSharedPatchBypassBuffer);
m_pSharedPatchBypassBuffer->AddRef();
return m_pSharedPatchBypassBuffer;
}
// NOTE: in order to correctly single-step RIP-relative writes on multiple threads we need to set up
// a shared buffer with the instruction and a buffer for the RIP-relative value so that all threads
// are working on the same copy. as the single-steps complete the modified data in the buffer is
// copied back to the real address to ensure proper execution of the program.
SharedPatchBypassBuffer *pSharedPatchBypassBufferRX = (SharedPatchBypassBuffer*)g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(SharedPatchBypassBuffer));
#if defined(HOST_OSX) && defined(HOST_ARM64)
ExecutableWriterHolder<SharedPatchBypassBuffer> sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX, sizeof(SharedPatchBypassBuffer));
SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW();
#else // HOST_OSX && HOST_ARM64
SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = pSharedPatchBypassBufferRX;
#endif // HOST_OSX && HOST_ARM64
new (pSharedPatchBypassBufferRW) SharedPatchBypassBuffer();
m_pSharedPatchBypassBuffer = (SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX;
_ASSERTE(m_pSharedPatchBypassBuffer);
TRACE_ALLOC(m_pSharedPatchBypassBuffer);
m_pSharedPatchBypassBuffer->AddRef();
BYTE* patchBypassRW = pSharedPatchBypassBufferRW->PatchBypass;
BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass;
LOG((LF_CORDB, LL_INFO10000, "DCP::CSPBB: Patch skip for opcode 0x%.4x at address %p buffer allocated at 0x%.8x\n", this->opcode, this->address, m_pSharedPatchBypassBuffer));
// CopyInstructionBlock copies all the code bytes except the breakpoint byte(s).
_ASSERTE( this->IsBound() );
CopyInstructionBlock(patchBypassRW, (const BYTE *)this->address);
// Technically, we could create a patch skipper for an inactive patch, but we rely on the opcode being
// set here.
_ASSERTE( this->IsActivated() );
CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypassRW, this->opcode);
LOG((LF_CORDB, LL_EVERYTHING, "DCP::CSPBB: SetInstruction was called\n"));
//
// Look at instruction to get some attributes
//
InstructionAttribute instrAttrib = { 0 };
NativeWalker::DecodeInstructionForPatchSkip(patchBypassRX, &instrAttrib);
#if defined(TARGET_AMD64)
// The code below handles RIP-relative addressing on AMD64. The original implementation made the assumption that
// we are only using RIP-relative addressing to access read-only data (see VSW 246145 for more information). This
// has since been expanded to handle RIP-relative writes as well.
if (instrAttrib.m_dwOffsetToDisp != 0)
{
_ASSERTE(pSharedPatchBypassBufferRW != NULL);
_ASSERTE(instrAttrib.m_cbInstr != 0);
//
// Populate the RIP-relative buffer with the current value if needed
//
BYTE* bufferBypassRW = pSharedPatchBypassBufferRW->BypassBuffer;
// Overwrite the *signed* displacement.
int dwOldDisp = *(int*)(&patchBypassRX[instrAttrib.m_dwOffsetToDisp]);
int dwNewDisp = offsetof(SharedPatchBypassBuffer, BypassBuffer) -
(offsetof(SharedPatchBypassBuffer, PatchBypass) + instrAttrib.m_cbInstr);
*(int*)(&patchBypassRW[instrAttrib.m_dwOffsetToDisp]) = dwNewDisp;
// This could be an LEA, which we'll just have to change into a MOV and copy the original address.
if (((patchBypassRX[0] == 0x4C) || (patchBypassRX[0] == 0x48)) && (patchBypassRX[1] == 0x8d))
{
patchBypassRW[1] = 0x8b; // MOV reg, mem
_ASSERTE((int)sizeof(void*) <= SharedPatchBypassBuffer::cbBufferBypass);
*(void**)bufferBypassRW = (void*)(this->address + instrAttrib.m_cbInstr + dwOldDisp);
}
else
{
_ASSERTE(instrAttrib.m_cOperandSize <= SharedPatchBypassBuffer::cbBufferBypass);
// Copy the data into our buffer.
memcpy(bufferBypassRW, this->address + instrAttrib.m_cbInstr + dwOldDisp, instrAttrib.m_cOperandSize);
if (instrAttrib.m_fIsWrite)
{
// save the actual destination address and size so when we TriggerSingleStep() we can update the value
pSharedPatchBypassBufferRW->RipTargetFixup = (UINT_PTR)(this->address + instrAttrib.m_cbInstr + dwOldDisp);
pSharedPatchBypassBufferRW->RipTargetFixupSize = instrAttrib.m_cOperandSize;
}
}
}
#endif // TARGET_AMD64
m_pSharedPatchBypassBuffer->SetInstructionAttrib(instrAttrib);
// Since we just created a new buffer of code, but the CPU caches code and may
// not be aware of our changes. This should force the CPU to dump any cached
// instructions it has in this region and load the new ones from memory
FlushInstructionCache(GetCurrentProcess(), patchBypassRW + CORDbg_BREAK_INSTRUCTION_SIZE,
MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE);
return m_pSharedPatchBypassBuffer;
}
#endif // !FEATURE_EMULATE_SINGLESTEP
#endif // !DACCESS_COMPILE
// @todo - remove all this splicing trash
// This Sort/Splice stuff just reorders the patches within a particular chain such
@ -4509,53 +4662,9 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread,
// the single-step emulation itself.
#ifndef FEATURE_EMULATE_SINGLESTEP
// NOTE: in order to correctly single-step RIP-relative writes on multiple threads we need to set up
// a shared buffer with the instruction and a buffer for the RIP-relative value so that all threads
// are working on the same copy. as the single-steps complete the modified data in the buffer is
// copied back to the real address to ensure proper execution of the program.
//
// Create the shared instruction block. this will also create the shared RIP-relative buffer
//
_ASSERTE(DebuggerController::HasLock());
m_pSharedPatchBypassBuffer = patch->GetOrCreateSharedPatchBypassBuffer();
#if defined(HOST_OSX) && defined(HOST_ARM64)
ExecutableWriterHolder<SharedPatchBypassBuffer> sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)m_pSharedPatchBypassBuffer, sizeof(SharedPatchBypassBuffer));
SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW();
#else // HOST_OSX && HOST_ARM64
SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = m_pSharedPatchBypassBuffer;
#endif // HOST_OSX && HOST_ARM64
BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass;
BYTE* patchBypassRW = pSharedPatchBypassBufferRW->PatchBypass;
LOG((LF_CORDB, LL_INFO10000, "DPS::DPS: Patch skip for opcode 0x%.4x at address %p buffer allocated at 0x%.8x\n", patch->opcode, patch->address, m_pSharedPatchBypassBuffer));
// Copy the instruction block over to the patch skip
// WARNING: there used to be an issue here because CopyInstructionBlock copied the breakpoint from the
// jitted code stream into the patch buffer. Further below CORDbgSetInstruction would correct the
// first instruction. This buffer is shared by all threads so if another thread executed the buffer
// between this thread's execution of CopyInstructionBlock and CORDbgSetInstruction the wrong
// code would be executed. The bug has been fixed by changing CopyInstructionBlock to only copy
// the code bytes after the breakpoint.
// You might be tempted to stop copying the code at all, however that wouldn't work well with rejit.
// If we skip a breakpoint that is sitting at the beginning of a method, then the profiler rejits that
// method causing a jump-stamp to be placed, then we skip the breakpoint again, we need to make sure
// the 2nd skip executes the new jump-stamp code and not the original method prologue code. Copying
// the code every time ensures that we have the most up-to-date version of the code in the buffer.
_ASSERTE( patch->IsBound() );
CopyInstructionBlock(patchBypassRW, (const BYTE *)patch->address);
// Technically, we could create a patch skipper for an inactive patch, but we rely on the opcode being
// set here.
_ASSERTE( patch->IsActivated() );
CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypassRW, patch->opcode);
LOG((LF_CORDB, LL_EVERYTHING, "SetInstruction was called\n"));
//
// Look at instruction to get some attributes
//
NativeWalker::DecodeInstructionForPatchSkip(patchBypassRX, &(m_instrAttrib));
m_instrAttrib = m_pSharedPatchBypassBuffer->GetInstructionAttrib();
#ifdef OUT_OF_PROCESS_SETTHREADCONTEXT
if (g_pDebugInterface->IsOutOfProcessSetContextEnabled() && m_instrAttrib.m_fIsCall)
@ -4564,51 +4673,6 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread,
}
#endif
#if defined(TARGET_AMD64)
// The code below handles RIP-relative addressing on AMD64. The original implementation made the assumption that
// we are only using RIP-relative addressing to access read-only data (see VSW 246145 for more information). This
// has since been expanded to handle RIP-relative writes as well.
if (m_instrAttrib.m_dwOffsetToDisp != 0 && !IsInPlaceSingleStep())
{
_ASSERTE(m_instrAttrib.m_cbInstr != 0);
//
// Populate the RIP-relative buffer with the current value if needed
//
BYTE* bufferBypassRW = pSharedPatchBypassBufferRW->BypassBuffer;
// Overwrite the *signed* displacement.
int dwOldDisp = *(int*)(&patchBypassRX[m_instrAttrib.m_dwOffsetToDisp]);
int dwNewDisp = offsetof(SharedPatchBypassBuffer, BypassBuffer) -
(offsetof(SharedPatchBypassBuffer, PatchBypass) + m_instrAttrib.m_cbInstr);
*(int*)(&patchBypassRW[m_instrAttrib.m_dwOffsetToDisp]) = dwNewDisp;
// This could be an LEA, which we'll just have to change into a MOV and copy the original address.
if (((patchBypassRX[0] == 0x4C) || (patchBypassRX[0] == 0x48)) && (patchBypassRX[1] == 0x8d))
{
patchBypassRW[1] = 0x8b; // MOV reg, mem
_ASSERTE((int)sizeof(void*) <= SharedPatchBypassBuffer::cbBufferBypass);
*(void**)bufferBypassRW = (void*)(patch->address + m_instrAttrib.m_cbInstr + dwOldDisp);
}
else
{
_ASSERTE(m_instrAttrib.m_cOperandSize <= SharedPatchBypassBuffer::cbBufferBypass);
// Copy the data into our buffer.
memcpy(bufferBypassRW, patch->address + m_instrAttrib.m_cbInstr + dwOldDisp, m_instrAttrib.m_cOperandSize);
if (m_instrAttrib.m_fIsWrite)
{
// save the actual destination address and size so when we TriggerSingleStep() we can update the value
pSharedPatchBypassBufferRW->RipTargetFixup = (UINT_PTR)(patch->address + m_instrAttrib.m_cbInstr + dwOldDisp);
pSharedPatchBypassBufferRW->RipTargetFixupSize = m_instrAttrib.m_cOperandSize;
}
}
}
#endif // TARGET_AMD64
#endif // !FEATURE_EMULATE_SINGLESTEP
// Signals our thread that the debugger will be manipulating the context
@ -4672,7 +4736,9 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread,
#else // FEATURE_EMULATE_SINGLESTEP
#ifdef TARGET_ARM64
patchBypassRX = NativeWalker::SetupOrSimulateInstructionForPatchSkip(context, m_pSharedPatchBypassBuffer, (const BYTE *)patch->address, patch->opcode);
BYTE* patchBypassRX = NativeWalker::SetupOrSimulateInstructionForPatchSkip(context, m_pSharedPatchBypassBuffer, (const BYTE *)patch->address, patch->opcode);
#else
BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass;
#endif //TARGET_ARM64
if (!IsInPlaceSingleStep())
@ -4742,80 +4808,6 @@ void DebuggerPatchSkip::DebuggerDetachClean()
#endif // !FEATURE_EMULATE_SINGLESTEP
}
//
// We have to have a whole separate function for this because you
// can't use __try in a function that requires object unwinding...
//
LONG FilterAccessViolation2(LPEXCEPTION_POINTERS ep, PVOID pv)
{
LIMITED_METHOD_CONTRACT;
return (ep->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
}
// This helper is required because the AVInRuntimeImplOkayHolder can not
// be directly placed inside the scope of a PAL_TRY
void _CopyInstructionBlockHelper(BYTE* to, const BYTE* from)
{
AVInRuntimeImplOkayHolder AVOkay;
// This function only copies the portion of the instruction that follows the
// breakpoint opcode, not the breakpoint itself
to += CORDbg_BREAK_INSTRUCTION_SIZE;
from += CORDbg_BREAK_INSTRUCTION_SIZE;
// If an AV occurs because we walked off a valid page then we need
// to be certain that all bytes on the previous page were copied.
// We are certain that we copied enough bytes to contain the instruction
// because it must have fit within the valid page.
for (int i = 0; i < MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE; i++)
{
*to++ = *from++;
}
}
// WARNING: this function skips copying the first CORDbg_BREAK_INSTRUCTION_SIZE bytes by design
// See the comment at the callsite in DebuggerPatchSkip::DebuggerPatchSkip for more details on
// this
void DebuggerPatchSkip::CopyInstructionBlock(BYTE *to, const BYTE* from)
{
// We wrap the memcpy in an exception handler to handle the
// extremely rare case where we're copying an instruction off the
// end of a method that is also at the end of a page, and the next
// page is unmapped.
struct Param
{
BYTE *to;
const BYTE* from;
} param;
param.to = to;
param.from = from;
PAL_TRY(Param *, pParam, &param)
{
_CopyInstructionBlockHelper(pParam->to, pParam->from);
}
PAL_EXCEPT_FILTER(FilterAccessViolation2)
{
// The whole point is that if we copy up the AV, then
// that's enough to execute, otherwise we would not have been
// able to execute the code anyway. So we just ignore the
// exception.
LOG((LF_CORDB, LL_INFO10000,
"DPS::DPS: AV copying instruction block ignored.\n"));
}
PAL_ENDTRY
// We just created a new buffer of code, but the CPU caches code and may
// not be aware of our changes. This should force the CPU to dump any cached
// instructions it has in this region and load the new ones from memory
FlushInstructionCache(GetCurrentProcess(), to + CORDbg_BREAK_INSTRUCTION_SIZE,
MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE);
}
TP_RESULT DebuggerPatchSkip::TriggerPatch(DebuggerControllerPatch *patch,
Thread *thread,
TRIGGER_WHY tyWhy)

View File

@ -312,7 +312,11 @@ public:
UINT_PTR RipTargetFixup;
#endif
const InstructionAttribute& GetInstructionAttrib() { return m_instrAttrib; }
void SetInstructionAttrib(const InstructionAttribute& instrAttrib) { m_instrAttrib = instrAttrib; }
private:
InstructionAttribute m_instrAttrib; // info about the instruction being skipped over
const static DWORD SentinelValue = 0xffffffff;
LONG m_refCount;
};
@ -550,10 +554,13 @@ public:
// Is this patch at a position at which it's safe to take a stack?
bool IsSafeForStackTrace();
#ifndef DACCESS_COMPILE
#ifndef FEATURE_EMULATE_SINGLESTEP
// gets a pointer to the shared buffer
SharedPatchBypassBuffer* GetOrCreateSharedPatchBypassBuffer();
void CopyInstructionBlock(BYTE *to, const BYTE* from);
// entry point for general initialization when the controller is being created
void Initialize()
{
@ -567,6 +574,7 @@ public:
m_pSharedPatchBypassBuffer->Release();
}
#endif // !FEATURE_EMULATE_SINGLESTEP
#endif // !DACCESS_COMPILE
void LogInstance()
{
@ -1515,8 +1523,6 @@ class DebuggerPatchSkip : public DebuggerController
virtual DEBUGGER_CONTROLLER_TYPE GetDCType(void)
{ return DEBUGGER_CONTROLLER_PATCH_SKIP; }
void CopyInstructionBlock(BYTE *to, const BYTE* from);
void DecodeInstruction(CORDB_ADDRESS_TYPE *code);
void DebuggerDetachClean();

View File

@ -22,12 +22,7 @@
#ifdef DEBUGGING_SUPPORTED
extern PTR_ECHash gFCallMethods[FCALL_HASH_SIZE];
extern TADDR gLowestFCall;
extern TADDR gHighestFCall;
extern PCODE g_FCDynamicallyAssignedImplementations[ECall::NUM_DYNAMICALLY_ASSIGNED_FCALL_IMPLEMENTATIONS];
extern DWORD gThreadTLSIndex;
extern DWORD gAppDomainTLSIndex;
extern "C" void STDCALL ThePreStubPatchLabel(void);
#ifdef FEATURE_COMWRAPPERS

View File

@ -926,7 +926,6 @@ Debugger::Debugger()
m_jitAttachInProgress(FALSE),
m_launchingDebugger(FALSE),
m_LoggingEnabled(TRUE),
m_pAppDomainCB(NULL),
m_dClassLoadCallbackCount(0),
m_pModules(NULL),
m_RSRequestedSync(FALSE),
@ -1896,22 +1895,6 @@ HRESULT Debugger::Startup(void)
InitializeHijackFunctionAddress();
// Also initialize the AppDomainEnumerationIPCBlock
#if !defined(FEATURE_IPCMAN) || defined(FEATURE_DBGIPC_TRANSPORT_VM)
m_pAppDomainCB = new (nothrow) AppDomainEnumerationIPCBlock();
#else
m_pAppDomainCB = g_pIPCManagerInterface->GetAppDomainBlock();
#endif
if (m_pAppDomainCB == NULL)
{
LOG((LF_CORDB, LL_INFO100, "D::S: Failed to get AppDomain IPC block from IPCManager.\n"));
ThrowHR(E_FAIL);
}
hr = InitAppDomainIPC();
_ASSERTE(SUCCEEDED(hr)); // throws on error.
// Allows the debugger (and profiler) diagnostics to be disabled so resources like
// the named pipes and semaphores are not created.
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableDiagnostics) == 0)
@ -1939,7 +1922,7 @@ HRESULT Debugger::Startup(void)
#if defined(FEATURE_DBGIPC_TRANSPORT_VM)
// Create transport session and initialize it.
g_pDbgTransport = new DbgTransportSession();
hr = g_pDbgTransport->Init(m_pRCThread->GetDCB(), m_pAppDomainCB);
hr = g_pDbgTransport->Init(m_pRCThread->GetDCB());
if (FAILED(hr))
{
ShutdownTransport();
@ -2286,10 +2269,10 @@ void DebuggerLazyInit::Init()
DebuggerLazyInit::~DebuggerLazyInit()
{
{
USHORT cBlobs = m_pMemBlobs.Count();
INT32 cBlobs = m_pMemBlobs.Count();
void **rgpBlobs = m_pMemBlobs.Table();
for (int i = 0; i < cBlobs; i++)
for (INT32 i = 0; i < cBlobs; i++)
{
g_pDebugger->ReleaseRemoteBuffer(rgpBlobs[i], false);
}
@ -2406,9 +2389,6 @@ void Debugger::StopDebugger(void)
m_pRCThread->AsyncStop();
}
// Also clean up the AppDomain stuff since this is cross-process.
TerminateAppDomainIPC ();
//
// Tell the VM to clear out all references to the debugger before we start cleaning up,
// so that nothing will reference (accidentally) through the partially cleaned up debugger.
@ -9180,7 +9160,7 @@ BOOL Debugger::SuspendComplete(bool isEESuspendedForGC)
//---------------------------------------------------------------------------------------
//
// Debugger::SendCreateAppDomainEvent - notify the RS of an AppDomain
// Debugger::AppDomainCreated - notify the RS of an AppDomain
//
// Arguments:
// pRuntimeAppdomain - pointer to the AppDomain
@ -9190,18 +9170,13 @@ BOOL Debugger::SuspendComplete(bool isEESuspendedForGC)
//
// Notes:
// This is used to notify the debugger of either a newly created
// AppDomain (when fAttaching is FALSE) or of existing AppDomains
// at attach time (fAttaching is TRUE). In both cases, this should
// AppDomain. This should
// be called before any LoadModule/LoadAssembly events are sent for
// this domain. Otherwise the RS will get an event for an AppDomain
// it doesn't recognize and ASSERT.
//
// For the non-attach case this means there is no need to enumerate
// the assemblies/modules in an AppDomain after sending this event
// because we know there won't be any.
//
void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain)
void Debugger::AppDomainCreated(AppDomain * pRuntimeAppDomain)
{
CONTRACTL
{
@ -9225,8 +9200,6 @@ void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain)
Thread *pThread = g_pEEInterface->GetThread();
SENDIPCEVENT_BEGIN(this, pThread);
// We may have detached while waiting in LockForEventSending,
// in which case we can't send the event.
if (CORDebuggerAttached())
@ -9250,62 +9223,6 @@ void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain)
}
//
// LoadAssembly is called when a new Assembly gets loaded.
//
void Debugger::LoadAssembly(DomainAssembly * pDomainAssembly)
{
CONTRACTL
{
MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
}
CONTRACTL_END;
if (CORDBUnrecoverableError(this))
return;
LOG((LF_CORDB, LL_INFO100, "D::LA: Load Assembly Asy:0x%p AD:0x%p which:%s\n",
pDomainAssembly, AppDomain::GetCurrentDomain(), pDomainAssembly->GetAssembly()->GetDebugName() ));
if (!CORDebuggerAttached())
{
return;
}
Thread *pThread = g_pEEInterface->GetThread();
SENDIPCEVENT_BEGIN(this, pThread)
if (CORDebuggerAttached())
{
// Send a load assembly event to the Right Side.
DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
InitIPCEvent(ipce,
DB_IPCE_LOAD_ASSEMBLY,
pThread);
ipce->AssemblyData.vmDomainAssembly.SetRawPtr(pDomainAssembly);
m_pRCThread->SendIPCEvent();
}
else
{
LOG((LF_CORDB,LL_INFO1000, "D::LA: Skipping SendIPCEvent because RS detached."));
}
// Stop all Runtime threads
if (CORDebuggerAttached())
{
TrapAllRuntimeThreads();
}
SENDIPCEVENT_END;
}
//
// UnloadAssembly is called when a Runtime thread unloads an assembly.
//
@ -9790,43 +9707,31 @@ BOOL Debugger::SendSystemClassLoadUnloadEvent(mdTypeDef classMetadataToken,
Assembly *pAssembly = classModule->GetAssembly();
if (!m_pAppDomainCB->Lock())
return (FALSE);
AppDomain *pAppDomain = GetAppDomain();
_ASSERTE(pAppDomain != NULL);
AppDomainInfo *pADInfo = m_pAppDomainCB->FindFirst();
while (pADInfo != NULL)
// Only notify for app domains where the module has been fully loaded already
// We used to make a different check here domain->ContainsAssembly() but that
// triggers too early in the loading process. FindDomainAssembly will not become
// non-NULL until the module is fully loaded into the domain which is what we
// want.
if (classModule->GetDomainAssembly() != NULL )
{
AppDomain *pAppDomain = pADInfo->m_pAppDomain;
_ASSERTE(pAppDomain != NULL);
// Find the Left Side module that this class belongs in.
DebuggerModule* pModule = LookupOrCreateModule(classModule);
_ASSERTE(pModule != NULL);
// Only notify for app domains where the module has been fully loaded already
// We used to make a different check here domain->ContainsAssembly() but that
// triggers too early in the loading process. FindDomainAssembly will not become
// non-NULL until the module is fully loaded into the domain which is what we
// want.
if (classModule->GetDomainAssembly() != NULL )
// Only send a class load event if they're enabled for this module.
if (pModule && pModule->ClassLoadCallbacksEnabled())
{
// Find the Left Side module that this class belongs in.
DebuggerModule* pModule = LookupOrCreateModule(classModule);
_ASSERTE(pModule != NULL);
// Only send a class load event if they're enabled for this module.
if (pModule && pModule->ClassLoadCallbacksEnabled())
{
SendClassLoadUnloadEvent(classMetadataToken,
pModule,
pAssembly,
fIsLoadEvent);
fRetVal = TRUE;
}
SendClassLoadUnloadEvent(classMetadataToken,
pModule,
pAssembly,
fIsLoadEvent);
fRetVal = TRUE;
}
pADInfo = m_pAppDomainCB->FindNext(pADInfo);
}
m_pAppDomainCB->Unlock();
return fRetVal;
}
@ -12154,10 +12059,10 @@ HRESULT Debugger::ReleaseRemoteBuffer(void *pBuffer, bool removeFromBlobList)
// Remove the buffer from the blob list if necessary.
if (removeFromBlobList)
{
USHORT cBlobs = GetMemBlobs()->Count();
INT32 cBlobs = GetMemBlobs()->Count();
void **rgpBlobs = GetMemBlobs()->Table();
USHORT i;
INT32 i;
for (i = 0; i < cBlobs; i++)
{
if (rgpBlobs[i] == pBuffer)
@ -14543,399 +14448,6 @@ void Debugger::SendCustomDebuggerNotification(Thread * pThread,
SENDIPCEVENT_END;
}
//-----------------------------------------------------------------------------
//
// Add the AppDomain to the list stored in the IPC block. It adds the id and
// the name.
//
// Arguments:
// pAppDomain - The runtime app domain object to add.
//
// Return Value:
// S_OK on success, else detailed error code.
//
HRESULT Debugger::AddAppDomainToIPC(AppDomain *pAppDomain)
{
CONTRACTL
{
MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
GC_TRIGGERS;
MODE_ANY;
}
CONTRACTL_END;
HRESULT hr = S_OK;
LPCWSTR szName = NULL;
LOG((LF_CORDB, LL_INFO100, "D::AADTIPC: Executing AADTIPC for AppDomain 0x%08x.\n",
pAppDomain));
STRESS_LOG1(LF_CORDB, LL_INFO10000, "D::AADTIPC: AddAppDomainToIPC:%#08x\n",
pAppDomain);
_ASSERTE(m_pAppDomainCB->m_iTotalSlots > 0);
_ASSERTE(m_pAppDomainCB->m_rgListOfAppDomains != NULL);
{
//
// We need to synchronize this routine with the attach logic. The "normal"
// attach case uses the HelperThread and TrapAllRuntimeThreads to synchronize
// the runtime before sending any of the events (including AppDomainCreates)
// to the right-side. Thus, we can synchronize with this case by forcing us
// to go co-operative. If we were already co-op, then the helper thread will
// wait to start the attach until all co-op threads are paused. If we were
// pre-emptive, then going co-op will suspend us until the HelperThread finishes.
//
// The second case is under the IPC event for ATTACHING, which is where there are
// zero app domains, so it is considered an 'early attach' case. To synchronize
// with this we have to grab and hold the AppDomainDB lock.
//
GCX_COOP();
// Lock the list
if (!m_pAppDomainCB->Lock())
{
return E_FAIL;
}
// Get a free entry from the list
AppDomainInfo *pAppDomainInfo = m_pAppDomainCB->GetFreeEntry();
// Function returns NULL if the list is full and a realloc failed.
if (!pAppDomainInfo)
{
hr = E_OUTOFMEMORY;
goto LErrExit;
}
// Now set the AppDomainName.
/*
* TODO :
*
* Make sure that returning NULL here does not result in a catastrophic
* failure.
*
* GetFriendlyNameNoThrow may call SetFriendlyName, which may call
* UpdateAppDomainEntryInIPC. There is no recursive death, however, because
* the AppDomainInfo object does not contain a pointer to the app domain
* yet.
*/
szName = pAppDomain->GetFriendlyNameForDebugger();
pAppDomainInfo->SetName(szName);
// Save on to the appdomain pointer
pAppDomainInfo->m_pAppDomain = pAppDomain;
// bump the used slot count
m_pAppDomainCB->m_iNumOfUsedSlots++;
LErrExit:
// UnLock the list
m_pAppDomainCB->Unlock();
// Send event to debugger if one is attached.
if (CORDebuggerAttached())
{
SendCreateAppDomainEvent(pAppDomain);
}
}
return hr;
}
/******************************************************************************
* Remove the AppDomain from the list stored in the IPC block and send an ExitAppDomain
* event to the debugger if attached.
******************************************************************************/
HRESULT Debugger::RemoveAppDomainFromIPC (AppDomain *pAppDomain)
{
CONTRACTL
{
MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
}
CONTRACTL_END;
HRESULT hr = E_FAIL;
LOG((LF_CORDB, LL_INFO100, "D::RADFIPC: Executing RADFIPC for AppDomain 0x%08x.\n",
pAppDomain));
// if none of the slots are occupied, then simply return.
if (m_pAppDomainCB->m_iNumOfUsedSlots == 0)
return hr;
// Lock the list
if (!m_pAppDomainCB->Lock())
return (E_FAIL);
// Look for the entry
AppDomainInfo *pADInfo = m_pAppDomainCB->FindEntry(pAppDomain);
// Shouldn't be trying to remove an appdomain that was never added
if (!pADInfo)
{
// We'd like to assert this, but there is a small window where we may have
// called AppDomain::Init (and so it's fair game to call Stop, and hence come here),
// but not yet published the app domain.
// _ASSERTE(!"D::RADFIPC: trying to remove an AppDomain that was never added");
hr = (E_FAIL);
goto ErrExit;
}
// Release the entry
m_pAppDomainCB->FreeEntry(pADInfo);
ErrExit:
// UnLock the list
m_pAppDomainCB->Unlock();
//
// The Debugger expects to never get an unload event for the default AppDomain.
//
return hr;
}
/******************************************************************************
* Update the AppDomain in the list stored in the IPC block.
******************************************************************************/
HRESULT Debugger::UpdateAppDomainEntryInIPC(AppDomain *pAppDomain)
{
CONTRACTL
{
NOTHROW;
if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
}
CONTRACTL_END;
HRESULT hr = S_OK;
LPCWSTR szName = NULL;
LOG((LF_CORDB, LL_INFO100,
"D::UADEIIPC: Executing UpdateAppDomainEntryInIPC ad:0x%x.\n",
pAppDomain));
// if none of the slots are occupied, then simply return.
if (m_pAppDomainCB->m_iNumOfUsedSlots == 0)
return (E_FAIL);
// Lock the list
if (!m_pAppDomainCB->Lock())
return (E_FAIL);
// Look up the info entry
AppDomainInfo *pADInfo = m_pAppDomainCB->FindEntry(pAppDomain);
if (!pADInfo)
{
hr = E_FAIL;
goto ErrExit;
}
// Update the name only if new name is non-null
szName = pADInfo->m_pAppDomain->GetFriendlyNameForDebugger();
pADInfo->SetName(szName);
ErrExit:
// UnLock the list
m_pAppDomainCB->Unlock();
return hr;
}
/******************************************************************************
*
******************************************************************************/
HRESULT Debugger::InitAppDomainIPC(void)
{
CONTRACTL
{
THROWS;
GC_NOTRIGGER;
PRECONDITION(CheckPointer(m_pAppDomainCB));
}
CONTRACTL_END;
// Ensure that if we throw here, the Terminate will get called and cleanup all resources.
// This will make Init an atomic operation - it either fully inits or fully fails.
class EnsureCleanup
{
Debugger * m_pThis;
public:
EnsureCleanup(Debugger * pThis)
{
m_pThis = pThis;
}
void SuppressCleanup()
{
m_pThis = NULL;
}
~EnsureCleanup()
{
if (m_pThis != NULL)
{
m_pThis->TerminateAppDomainIPC();
}
}
} hEnsureCleanup(this);
DWORD dwStrLen = 0;
SString szExeName;
int i;
// all fields in the object can be zero initialized.
// If we throw, before fully initializing this, then cleanup won't try to free
// uninited values.
ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB));
// Create a mutex to allow the Left and Right Sides to properly
// synchronize. The Right Side will spin until m_hMutex is valid,
// then it will acquire it before accessing the data.
HandleHolder hMutex(CreateMutex(NULL, TRUE/*hold*/, NULL));
if (hMutex == NULL)
{
ThrowLastError();
}
if (!m_pAppDomainCB->m_hMutex.SetLocal(hMutex))
{
ThrowLastError();
}
hMutex.SuppressRelease();
m_pAppDomainCB->m_iSizeInBytes = INITIAL_APP_DOMAIN_INFO_LIST_SIZE *
sizeof (AppDomainInfo);
// Number of slots in AppDomainListElement array
m_pAppDomainCB->m_rgListOfAppDomains = new AppDomainInfo[INITIAL_APP_DOMAIN_INFO_LIST_SIZE];
_ASSERTE(m_pAppDomainCB->m_rgListOfAppDomains != NULL); // throws on oom
m_pAppDomainCB->m_iTotalSlots = INITIAL_APP_DOMAIN_INFO_LIST_SIZE;
// Initialize each AppDomainListElement
for (i = 0; i < INITIAL_APP_DOMAIN_INFO_LIST_SIZE; i++)
{
m_pAppDomainCB->m_rgListOfAppDomains[i].FreeEntry();
}
// also initialize the process name
dwStrLen = WszGetModuleFileName(NULL,
szExeName);
// If we couldn't get the name, then use a nice default.
if (dwStrLen == 0)
{
szExeName.Set(W("<NoProcessName>"));
dwStrLen = szExeName.GetCount();
}
// If we got the name, copy it into a buffer. dwStrLen is the
// count of characters in the name, not including the null
// terminator.
m_pAppDomainCB->m_szProcessName = new WCHAR[dwStrLen + 1];
_ASSERTE(m_pAppDomainCB->m_szProcessName != NULL); // throws on oom
wcscpy_s(m_pAppDomainCB->m_szProcessName, dwStrLen + 1, szExeName);
// Add 1 to the string length so the Right Side will copy out the
// null terminator, too.
m_pAppDomainCB->m_iProcessNameLengthInBytes = (dwStrLen + 1) * sizeof(WCHAR);
if (m_pAppDomainCB->m_hMutex != NULL)
{
m_pAppDomainCB->Unlock();
}
hEnsureCleanup.SuppressCleanup();
return S_OK;
}
/******************************************************************************
* Uninitialize the AppDomain IPC block
* Returns:
* S_OK -if fully uninitialized
* E_FAIL - if we can't get ownership of the block, and thus no uninitialization
* work is done.
******************************************************************************/
HRESULT Debugger::TerminateAppDomainIPC(void)
{
CONTRACTL
{
NOTHROW;
GC_NOTRIGGER;
}
CONTRACTL_END;
// If we have no AppDomain block, then we can consider it's already terminated.
if (m_pAppDomainCB == NULL)
return S_OK;
HRESULT hr = S_OK;
// Lock the list
// If there's no mutex, then we're in a partially created state.
// This means InitAppDomainIPC failed halfway through. But we're still thread safe
// since other threads can't access us if we don't have the mutex.
if ((m_pAppDomainCB->m_hMutex != NULL) && !m_pAppDomainCB->Lock())
{
// The callers don't check our return value, we may want to know when we can't gracefully clean up
LOG((LF_CORDB, LL_INFO10, "Debugger::TerminateAppDomainIPC: Failed to get AppDomain IPC lock, not cleaning up.\n"));
// If the lock is valid, but we can't get it, then we can't really
// uninitialize since someone else is using the block.
return (E_FAIL);
}
// The shared IPC segment could still be around after the debugger
// object has been destroyed during process shutdown. So, reset
// the UsedSlots count to 0 so that any out of process clients
// enumeratingthe app domains in this process see 0 AppDomains.
m_pAppDomainCB->m_iNumOfUsedSlots = 0;
m_pAppDomainCB->m_iTotalSlots = 0;
// Now delete the memory allocated for AppDomainInfo array
delete [] m_pAppDomainCB->m_rgListOfAppDomains;
m_pAppDomainCB->m_rgListOfAppDomains = NULL;
delete [] m_pAppDomainCB->m_szProcessName;
m_pAppDomainCB->m_szProcessName = NULL;
m_pAppDomainCB->m_iProcessNameLengthInBytes = 0;
// Set the mutex handle to NULL.
// If the Right Side acquires the mutex, it will verify
// that the handle is still not NULL. If it is, then it knows it
// really lost.
RemoteHANDLE m = m_pAppDomainCB->m_hMutex;
m_pAppDomainCB->m_hMutex.m_hLocal = NULL;
// And bring us back to a fully uninitialized state.
ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB));
// We're done. release and close the mutex. Note that this must be done
// after we clear it out above to ensure there is no race condition.
if( m != NULL )
{
VERIFY(ReleaseMutex(m));
m.Close();
}
return hr;
}
#ifndef DACCESS_COMPILE
//

View File

@ -1116,8 +1116,8 @@ protected:
// different part of the address space (not on the heap).
// ------------------------------------------------------------------------ */
constexpr uint64_t DBG_MAX_EXECUTABLE_ALLOC_SIZE=112;
constexpr uint64_t EXPECTED_CHUNKSIZE=128;
constexpr uint64_t DBG_MAX_EXECUTABLE_ALLOC_SIZE=120; // sizeof (SharedPatchBypassBuffer)
constexpr uint64_t EXPECTED_CHUNKSIZE=256; // This must be a power of 2. It represents the size of DebuggerHeapExecutableMemoryChunk, can be the sizeof (DataChunk) or sizeof (BookkeepingChunk). Changes to DBG_MAX_EXECUTABLE_ALLOC_SIZE can affect this number. Currently we require 136 bytes, and so the closest power of 2 is 256.
constexpr uint64_t DEBUGGERHEAP_PAGESIZE=4096;
constexpr uint64_t CHUNKS_PER_DEBUGGERHEAP=(DEBUGGERHEAP_PAGESIZE / EXPECTED_CHUNKSIZE);
constexpr uint64_t MAX_CHUNK_MASK=((1ull << CHUNKS_PER_DEBUGGERHEAP) - 1);
@ -2617,14 +2617,7 @@ public:
BOOL ShouldAutoAttach();
BOOL FallbackJITAttachPrompt();
HRESULT AddAppDomainToIPC (AppDomain *pAppDomain);
HRESULT RemoveAppDomainFromIPC (AppDomain *pAppDomain);
HRESULT UpdateAppDomainEntryInIPC (AppDomain *pAppDomain);
void SendCreateAppDomainEvent(AppDomain * pAppDomain);
// Notify the debugger that an assembly has been loaded
void LoadAssembly(DomainAssembly * pDomainAssembly);
void AppDomainCreated(AppDomain * pAppDomain);
// Notify the debugger that an assembly has been unloaded
void UnloadAssembly(DomainAssembly * pDomainAssembly);
@ -2840,9 +2833,6 @@ private:
DebuggerLaunchSetting GetDbgJITDebugLaunchSetting();
public:
HRESULT InitAppDomainIPC(void);
HRESULT TerminateAppDomainIPC(void);
bool ResumeThreads(AppDomain* pAppDomain);
void ProcessAnyPendingEvals(Thread *pThread);
@ -2923,7 +2913,6 @@ private:
Volatile<BOOL> m_jitAttachInProgress;
BOOL m_launchingDebugger;
BOOL m_LoggingEnabled;
AppDomainEnumerationIPCBlock *m_pAppDomainCB;
LONG m_dClassLoadCallbackCount;

View File

@ -62,6 +62,8 @@ struct InstructionAttribute
}
};
#ifndef DACCESS_COMPILE
/* ------------------------------------------------------------------------- *
* Classes
* ------------------------------------------------------------------------- */
@ -280,4 +282,6 @@ private:
};
#endif
#endif // DACCESS_COMPILE
#endif // WALKER_H_

View File

@ -140,239 +140,6 @@ struct RemoteHANDLE {
}
};
// AppDomain publishing server support:
// Information about all appdomains in the process will be maintained
// in the shared memory block for use by the debugger, etc.
// This structure defines the layout of the information that will
// be maintained.
struct AppDomainEnumerationIPCBlock
{
// !!! The binary format of this layout must remain the same across versions so that
// !!! a V2.0 publisher can inspect a v1.0 app.
// lock for serialization while manipulating AppDomain list.
RemoteHANDLE m_hMutex;
// Number of slots in AppDomainListElement array
int m_iTotalSlots;
int m_iNumOfUsedSlots;
int m_iLastFreedSlot;
int m_iSizeInBytes; // Size of AppDomainInfo in bytes
// We can use psapi!GetModuleFileNameEx to get the module name.
// This provides an alternative.
int m_iProcessNameLengthInBytes;
WCHAR *m_szProcessName;
AppDomainInfo *m_rgListOfAppDomains;
BOOL m_fLockInvalid;
#ifndef RIGHT_SIDE_COMPILE
/*************************************************************************
* Locks the list
*************************************************************************/
BOOL Lock()
{
DWORD dwRes = WaitForSingleObject(m_hMutex, 3000);
if (dwRes == WAIT_TIMEOUT)
{
// Nobody should get stuck holding this lock.
// If we timeout on the wait, then either:
// - it's a really bad race and somebody got preempted for a long time
// - perhaps somebody's doing a DOS attack and holding onto the mutex.
m_fLockInvalid = TRUE;
}
// The only time this can happen is if we're in shutdown and a thread
// that held this lock is killed. If this happens, assume that this
// IPC block is in an invalid state and return FALSE to indicate
// that people shouldn't do anything with the block anymore.
if (dwRes == WAIT_ABANDONED)
{
m_fLockInvalid = TRUE;
}
if (m_fLockInvalid)
{
Unlock();
}
return (dwRes == WAIT_OBJECT_0 && !m_fLockInvalid);
}
/*************************************************************************
* Unlocks the list
*************************************************************************/
void Unlock()
{
// Lock may or may not be valid at this point. Thus Release may fail,
// but we'll just ignore that.
ReleaseMutex(m_hMutex);
}
/*************************************************************************
* Gets a free AppDomainInfo entry, and will allocate room if there are
* no free slots left.
*************************************************************************/
AppDomainInfo *GetFreeEntry()
{
// first check to see if there is space available. If not, then realloc.
if (m_iNumOfUsedSlots == m_iTotalSlots)
{
// need to realloc
AppDomainInfo *pTemp =
new (nothrow) AppDomainInfo [m_iTotalSlots*2];
if (pTemp == NULL)
{
return (NULL);
}
memcpy (pTemp, m_rgListOfAppDomains, m_iSizeInBytes);
delete [] m_rgListOfAppDomains;
// Initialize the increased portion of the realloced memory
int iNewSlotSize = m_iTotalSlots * 2;
for (int iIndex = m_iTotalSlots; iIndex < iNewSlotSize; iIndex++)
pTemp[iIndex].FreeEntry();
m_rgListOfAppDomains = pTemp;
m_iTotalSlots = iNewSlotSize;
m_iSizeInBytes *= 2;
}
// Walk the list looking for an empty slot. Start from the last
// one which was freed.
{
int i = m_iLastFreedSlot;
do
{
// Pointer to the entry being examined
AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]);
// is the slot available?
if (pADInfo->IsEmpty())
return (pADInfo);
i = (i + 1) % m_iTotalSlots;
} while (i != m_iLastFreedSlot);
}
_ASSERTE(!"ADInfo::GetFreeEntry: should never get here.");
return (NULL);
}
/*************************************************************************
* Returns an AppDomainInfo slot to the free list.
*************************************************************************/
void FreeEntry(AppDomainInfo *pADInfo)
{
_ASSERTE(pADInfo >= m_rgListOfAppDomains &&
pADInfo < m_rgListOfAppDomains + m_iSizeInBytes);
_ASSERTE(((size_t)pADInfo - (size_t)m_rgListOfAppDomains) %
sizeof(AppDomainInfo) == 0);
// Mark this slot as free
pADInfo->FreeEntry();
#ifdef _DEBUG
*pADInfo = {};
#endif
// decrement the used slot count
m_iNumOfUsedSlots--;
// Save the last freed slot.
m_iLastFreedSlot = (int)((size_t)pADInfo - (size_t)m_rgListOfAppDomains) /
sizeof(AppDomainInfo);
}
/*************************************************************************
* Finds an AppDomainInfo entry corresponding to the AppDomain pointer.
* Returns NULL if no such entry exists.
*************************************************************************/
AppDomainInfo *FindEntry(AppDomain *pAD)
{
// Walk the list looking for a matching entry
for (int i = 0; i < m_iTotalSlots; i++)
{
AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]);
if (!pADInfo->IsEmpty() &&
pADInfo->m_pAppDomain == pAD)
return pADInfo;
}
return (NULL);
}
/*************************************************************************
* Returns the first AppDomainInfo entry in the list. Returns NULL if
* no such entry exists.
*************************************************************************/
AppDomainInfo *FindFirst()
{
// Walk the list looking for a non-empty entry
for (int i = 0; i < m_iTotalSlots; i++)
{
AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]);
if (!pADInfo->IsEmpty())
return pADInfo;
}
return (NULL);
}
/*************************************************************************
* Returns the next AppDomainInfo entry after pADInfo. Returns NULL if
* pADInfo was the last in the list.
*************************************************************************/
AppDomainInfo *FindNext(AppDomainInfo *pADInfo)
{
_ASSERTE(pADInfo >= m_rgListOfAppDomains &&
pADInfo < m_rgListOfAppDomains + m_iSizeInBytes);
_ASSERTE(((size_t)pADInfo - (size_t)m_rgListOfAppDomains) %
sizeof(AppDomainInfo) == 0);
// Walk the list looking for the next non-empty entry
for (int i = (int)((size_t)pADInfo - (size_t)m_rgListOfAppDomains)
/ sizeof(AppDomainInfo) + 1;
i < m_iTotalSlots;
i++)
{
AppDomainInfo *pADInfoTemp = &(m_rgListOfAppDomains[i]);
if (!pADInfoTemp->IsEmpty())
return pADInfoTemp;
}
return (NULL);
}
#endif // RIGHT_SIDE_COMPILE
};
// Enforce the AppDomain IPC block binary layout doesn't change between versions.
// Only an issue for x86 since that's the only platform w/ multiple versions.
#if defined(TARGET_X86)
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_hMutex) == 0x0);
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iTotalSlots) == 0x4);
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iNumOfUsedSlots) == 0x8);
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iLastFreedSlot) == 0xc);
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iSizeInBytes) == 0x10);
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iProcessNameLengthInBytes) == 0x14);
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_szProcessName) == 0x18);
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_rgListOfAppDomains) == 0x1c);
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_fLockInvalid) == 0x20);
#endif
#endif //DbgAppDomain_H

View File

@ -474,7 +474,7 @@ typedef DECLSPEC_ALIGN(16) struct {
#if !defined(CROSS_COMPILE) && !defined(TARGET_WINDOWS)
static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT must not include the SVE registers on AMD64");
static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT must not include the SVE registers on ARM64");
#else
static_assert(sizeof(DT_CONTEXT) == sizeof(T_CONTEXT), "DT_CONTEXT size must equal the T_CONTEXT size on ARM64");
#endif

View File

@ -341,7 +341,7 @@ public:
#ifdef RIGHT_SIDE_COMPILE
HRESULT Init(const ProcessDescriptor& pd, HANDLE hProcessExited);
#else
HRESULT Init(DebuggerIPCControlBlock * pDCB, AppDomainEnumerationIPCBlock * pADB);
HRESULT Init(DebuggerIPCControlBlock * pDCB);
#endif // RIGHT_SIDE_COMPILE
// Drive the session to the SS_Closed state, which will deallocate all remaining transport resources
@ -426,9 +426,6 @@ public:
HRESULT GetDCB(DebuggerIPCControlBlock *pDCB);
HRESULT SetDCB(DebuggerIPCControlBlock *pDCB);
// Read the AppDomain control block on the LS from the RS.
HRESULT GetAppDomainCB(AppDomainEnumerationIPCBlock *pADB);
#endif // RIGHT_SIDE_COMPILE
private:
@ -469,7 +466,6 @@ private:
MT_WriteMemory, // RS <-> LS : RS wants to write LS memory block (or LS is replying to such a request)
MT_GetDCB, // RS <-> LS : RS wants to read LS DCB (or LS is replying to such a request)
MT_SetDCB, // RS <-> LS : RS wants to write LS DCB (or LS is replying to such a request)
MT_GetAppDomainCB, // RS <-> LS : RS wants to read LS AppDomainCB (or LS is replying to such a request)
};
// Reasons the LS can give for rejecting a session. These codes should *not* be changed other than by
@ -589,7 +585,6 @@ private:
LONG m_cSentWriteMemory;
LONG m_cSentGetDCB;
LONG m_cSentSetDCB;
LONG m_cSentGetAppDomainCB;
LONG m_cSentDDMessage;
// Message type counts for receives.
@ -603,7 +598,6 @@ private:
LONG m_cReceivedWriteMemory;
LONG m_cReceivedGetDCB;
LONG m_cReceivedSetDCB;
LONG m_cReceivedGetAppDomainCB;
LONG m_cReceivedDDMessage;
// Low level block counts.
@ -747,7 +741,6 @@ private:
// The LS requires the addresses of a couple of runtime data structures in order to service MT_GetDCB etc.
// These are provided by the runtime at initialization time.
DebuggerIPCControlBlock *m_pDCB;
AppDomainEnumerationIPCBlock *m_pADB;
#endif // !RIGHT_SIDE_COMPILE
HRESULT SendEventWorker(DebuggerIPCEvent * pEvent, IPCEventType type);

View File

@ -18,7 +18,7 @@ extern const uintptr_t contractDescriptorPointerData[];
const uintptr_t contractDescriptorPointerData[] = {
(uintptr_t)0, // placeholder
#define CDAC_GLOBAL_POINTER(name,value) (uintptr_t)(value),
#include "datadescriptor.h"
#include "datadescriptor.inc"
};
}

View File

@ -89,7 +89,7 @@ struct CDacStringPoolSizes
#define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name))
#define CDAC_GLOBAL(name,tyname,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) \
DECL_LEN(MAKE_GLOBALTYPELEN_NAME(name), sizeof(#tyname))
#include "datadescriptor.h"
#include "datadescriptor.inc"
char cdac_string_pool_trailing_nil;
#undef DECL_LEN
};
@ -107,7 +107,7 @@ enum
CDacBlobTypesCount =
#define CDAC_TYPES_BEGIN() 0
#define CDAC_TYPE_BEGIN(name) + 1
#include "datadescriptor.h"
#include "datadescriptor.inc"
};
// count the field pool size.
@ -118,7 +118,7 @@ enum
#define CDAC_TYPES_BEGIN() 1
#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) + 1
#define CDAC_TYPE_END(name) + 1
#include "datadescriptor.h"
#include "datadescriptor.inc"
};
// count the literal globals
@ -127,7 +127,7 @@ enum
CDacBlobGlobalLiteralsCount =
#define CDAC_GLOBALS_BEGIN() 0
#define CDAC_GLOBAL(name,tyname,value) + 1
#include "datadescriptor.h"
#include "datadescriptor.inc"
};
// count the aux vector globals
@ -136,7 +136,7 @@ enum
CDacBlobGlobalPointersCount =
#define CDAC_GLOBALS_BEGIN() 0
#define CDAC_GLOBAL_POINTER(name,value) + 1
#include "datadescriptor.h"
#include "datadescriptor.inc"
};
// count the global strings
@ -145,7 +145,7 @@ enum
CDacBlobGlobalStringsCount =
#define CDAC_GLOBALS_BEGIN() 0
#define CDAC_GLOBAL_STRING(name,value) + 1
#include "datadescriptor.h"
#include "datadescriptor.inc"
};
@ -175,7 +175,7 @@ struct CDacFieldsPoolSizes
#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) DECL_LEN(CONCAT4(cdac_fields_pool_member__, tyname, __, membername))
#define CDAC_TYPE_END(name) DECL_LEN(CONCAT4(cdac_fields_pool_member__, tyname, _, endmarker)) \
} MAKE_TYPEFIELDS_TYNAME(name);
#include "datadescriptor.h"
#include "datadescriptor.inc"
#undef DECL_LEN
};
@ -197,7 +197,7 @@ struct CDacGlobalPointerIndex
#define DECL_LEN(membername) char membername;
#define CDAC_GLOBALS_BEGIN() DECL_LEN(cdac_global_pointer_index_start_placeholder__)
#define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(CONCAT(cdac_global_pointer_index__, name))
#include "datadescriptor.h"
#include "datadescriptor.inc"
#undef DECL_LEN
};
@ -295,7 +295,7 @@ struct MagicAndBlob BlobDataDescriptor = {
#define CDAC_TYPE_INDETERMINATE(name) /*.Size = */ 0,
#define CDAC_TYPE_SIZE(size) /* .Size = */ size,
#define CDAC_TYPE_END(name) },
#include "datadescriptor.h"
#include "datadescriptor.inc"
},
/* .FieldsPool = */ {
@ -306,22 +306,22 @@ struct MagicAndBlob BlobDataDescriptor = {
/* .FieldOffset = */ offset, \
},
#define CDAC_TYPE_END(name) { 0, },
#include "datadescriptor.h"
#include "datadescriptor.inc"
},
/* .GlobalLiteralValues = */ {
#define CDAC_GLOBAL(name,tyname,value) { /*.Name = */ GET_GLOBAL_NAME(name), /* .TypeName = */ GET_GLOBALTYPE_NAME(name), /* .Value = */ value },
#include "datadescriptor.h"
#include "datadescriptor.inc"
},
/* .GlobalPointerValues = */ {
#define CDAC_GLOBAL_POINTER(name,value) { /* .Name = */ GET_GLOBAL_NAME(name), /* .PointerDataIndex = */ GET_GLOBAL_POINTER_INDEX(name) },
#include "datadescriptor.h"
#include "datadescriptor.inc"
},
/* .GlobalStringValues = */ {
#define CDAC_GLOBAL_STRING(name,value) { /* .Name = */ GET_GLOBAL_NAME(name), /* .Value = */ GET_GLOBALSTRING_VALUE(name) },
#include "datadescriptor.h"
#include "datadescriptor.inc"
},
/* .NamesPool = */ ("\0" // starts with a nul
@ -331,7 +331,7 @@ struct MagicAndBlob BlobDataDescriptor = {
#define CDAC_GLOBAL_STRING(name,value) #name "\0" STRINGIFY(value) "\0"
#define CDAC_GLOBAL_POINTER(name,value) #name "\0"
#define CDAC_GLOBAL(name,tyname,value) #name "\0" #tyname "\0"
#include "datadescriptor.h"
#include "datadescriptor.inc"
),
/* .EndMagic = */ { 0x01, 0x02, 0x03, 0x04 },

View File

@ -258,13 +258,22 @@ CDAC_TYPE_END(Assembly)
CDAC_TYPE_BEGIN(LoaderAllocator)
CDAC_TYPE_INDETERMINATE(LoaderAllocator)
CDAC_TYPE_FIELD(LoaderAllocator, /*uint32*/, ReferenceCount, cdac_data<LoaderAllocator>::ReferenceCount)
CDAC_TYPE_FIELD(LoaderAllocator, /*pointer*/, HighFrequencyHeap, cdac_data<LoaderAllocator>::HighFrequencyHeap)
CDAC_TYPE_FIELD(LoaderAllocator, /*pointer*/, LowFrequencyHeap, cdac_data<LoaderAllocator>::LowFrequencyHeap)
CDAC_TYPE_FIELD(LoaderAllocator, /*pointer*/, StubHeap, cdac_data<LoaderAllocator>::StubHeap)
CDAC_TYPE_END(LoaderAllocator)
CDAC_TYPE_BEGIN(PEAssembly)
CDAC_TYPE_INDETERMINATE(PEAssembly)
CDAC_TYPE_FIELD(PEAssembly, /*pointer*/, PEImage, cdac_data<PEAssembly>::PEImage)
CDAC_TYPE_FIELD(PEAssembly, /*pointer*/, AssemblyBinder, cdac_data<PEAssembly>::AssemblyBinder)
CDAC_TYPE_END(PEAssembly)
CDAC_TYPE_BEGIN(AssemblyBinder)
CDAC_TYPE_INDETERMINATE(AssemblyBinder)
CDAC_TYPE_FIELD(AssemblyBinder, /*pointer*/, ManagedAssemblyLoadContext, cdac_data<AssemblyBinder>::ManagedAssemblyLoadContext)
CDAC_TYPE_END(AssemblyBinder)
CDAC_TYPE_BEGIN(PEImage)
CDAC_TYPE_INDETERMINATE(PEImage)
CDAC_TYPE_FIELD(PEImage, /*pointer*/, LoadedImageLayout, cdac_data<PEImage>::LoadedImageLayout)
@ -292,8 +301,14 @@ CDAC_TYPE_BEGIN(AppDomain)
CDAC_TYPE_INDETERMINATE(AppDomain)
CDAC_TYPE_FIELD(AppDomain, /*pointer*/, RootAssembly, cdac_data<AppDomain>::RootAssembly)
CDAC_TYPE_FIELD(AppDomain, /*DomainAssemblyList*/, DomainAssemblyList, cdac_data<AppDomain>::DomainAssemblyList)
CDAC_TYPE_FIELD(AppDomain, /*pointer*/, FriendlyName, cdac_data<AppDomain>::FriendlyName)
CDAC_TYPE_END(AppDomain)
CDAC_TYPE_BEGIN(SystemDomain)
CDAC_TYPE_INDETERMINATE(SystemDomain)
CDAC_TYPE_FIELD(SystemDomain, /*GlobalLoaderAllocator*/, GlobalLoaderAllocator, cdac_data<SystemDomain>::GlobalLoaderAllocator)
CDAC_TYPE_END(SystemDomain)
CDAC_TYPE_BEGIN(ArrayListBase)
CDAC_TYPE_INDETERMINATE(ArrayListBase)
CDAC_TYPE_FIELD(ArrayListBase, /*uint32*/, Count, cdac_data<ArrayListBase>::Count)
@ -333,8 +348,12 @@ CDAC_TYPE_BEGIN(EEClass)
CDAC_TYPE_INDETERMINATE(EEClass)
CDAC_TYPE_FIELD(EEClass, /*pointer*/, MethodTable, cdac_data<EEClass>::MethodTable)
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumMethods, cdac_data<EEClass>::NumMethods)
CDAC_TYPE_FIELD(EEClass, /*pointer*/, FieldDescList, cdac_data<EEClass>::FieldDescList)
CDAC_TYPE_FIELD(EEClass, /*uint32*/, CorTypeAttr, cdac_data<EEClass>::CorTypeAttr)
CDAC_TYPE_FIELD(EEClass, /*uint8*/, InternalCorElementType, cdac_data<EEClass>::InternalCorElementType)
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumInstanceFields, cdac_data<EEClass>::NumInstanceFields)
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumStaticFields, cdac_data<EEClass>::NumStaticFields)
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumThreadStaticFields, cdac_data<EEClass>::NumThreadStaticFields)
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumNonVirtualSlots, cdac_data<EEClass>::NumNonVirtualSlots)
CDAC_TYPE_END(EEClass)
@ -927,7 +946,7 @@ CDAC_GLOBAL_STRING(RID, RID_STRING)
CDAC_GLOBAL(GCInfoVersion, uint32, GCINFO_VERSION)
CDAC_GLOBAL_POINTER(AppDomain, &AppDomain::m_pTheAppDomain)
CDAC_GLOBAL_POINTER(SystemDomain, cdac_data<SystemDomain>::SystemDomain)
CDAC_GLOBAL_POINTER(SystemDomain, cdac_data<SystemDomain>::SystemDomainPtr)
CDAC_GLOBAL_POINTER(ThreadStore, &ThreadStore::s_pThreadStore)
CDAC_GLOBAL_POINTER(FinalizerThread, &::g_pFinalizerThread)
CDAC_GLOBAL_POINTER(GCThread, &::g_pSuspensionThread)
@ -959,6 +978,9 @@ CDAC_GLOBAL(MethodDescAlignment, uint64, MethodDesc::ALIGNMENT)
CDAC_GLOBAL(ObjectHeaderSize, uint64, OBJHEADER_SIZE)
CDAC_GLOBAL(SyncBlockValueToObjectOffset, uint16, OBJHEADER_SIZE - cdac_data<ObjHeader>::SyncBlockValue)
CDAC_GLOBAL(StubCodeBlockLast, uint8, STUB_CODE_BLOCK_LAST)
CDAC_GLOBAL(DefaultADID, uint32, DefaultADID)
CDAC_GLOBAL(MaxClrNotificationArgs, uint32, MAX_CLR_NOTIFICATION_ARGS)
CDAC_GLOBAL_POINTER(ClrNotificationArguments, &::g_clrNotificationArguments)
CDAC_GLOBAL_POINTER(ArrayBoundsZero, cdac_data<ArrayBase>::ArrayBoundsZero)
CDAC_GLOBAL_POINTER(ExceptionMethodTable, &::g_pExceptionClass)
CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &::g_pFreeObjectMethodTable)
@ -968,6 +990,11 @@ CDAC_GLOBAL_POINTER(StringMethodTable, &::g_pStringClass)
CDAC_GLOBAL_POINTER(SyncTableEntries, &::g_pSyncTable)
CDAC_GLOBAL_POINTER(MiniMetaDataBuffAddress, &::g_MiniMetaDataBuffAddress)
CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize)
CDAC_GLOBAL_POINTER(DacNotificationFlags, &::g_dacNotificationFlags)
CDAC_GLOBAL_POINTER(OffsetOfCurrentThreadInfo, &::g_offsetOfCurrentThreadInfo)
#ifdef TARGET_WINDOWS
CDAC_GLOBAL_POINTER(TlsIndexBase, &::_tls_index)
#endif // TARGET_WINDOWS
#ifdef STRESS_LOG
CDAC_GLOBAL(StressLogEnabled, uint8, 1)
CDAC_GLOBAL_POINTER(StressLog, &g_pStressLog)

View File

@ -67,7 +67,7 @@ DbgTransportSession::~DbgTransportSession()
#ifdef RIGHT_SIDE_COMPILE
HRESULT DbgTransportSession::Init(const ProcessDescriptor& pd, HANDLE hProcessExited)
#else // RIGHT_SIDE_COMPILE
HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB, AppDomainEnumerationIPCBlock *pADB)
HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB)
#endif // RIGHT_SIDE_COMPILE
{
_ASSERTE(m_eState == SS_Closed);
@ -111,7 +111,6 @@ HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB, AppDomainEnumer
m_fDebuggerAttached = false;
#else // RIGHT_SIDE_COMPILE
m_pDCB = pDCB;
m_pADB = pADB;
#endif // RIGHT_SIDE_COMPILE
m_sStateLock.Init();
@ -555,17 +554,6 @@ HRESULT DbgTransportSession::SetDCB(DebuggerIPCControlBlock *pDCB)
}
// Read the AppDomain control block on the LS from the RS.
HRESULT DbgTransportSession::GetAppDomainCB(AppDomainEnumerationIPCBlock *pADB)
{
DbgTransportLog(LC_Requests, "Sending 'GetAppDomainCB'");
DBG_TRANSPORT_INC_STAT(SentGetAppDomainCB);
Message sMessage;
sMessage.Init(MT_GetAppDomainCB, NULL, 0, (PBYTE)pADB, sizeof(AppDomainEnumerationIPCBlock));
return SendRequestMessageAndWait(&sMessage);
}
#endif // RIGHT_SIDE_COMPILE
// Worker function for code:DbgTransportSession::SendEvent and code:DbgTransportSession::SendDebugEvent.
@ -948,8 +936,7 @@ void DbgTransportSession::FlushSendQueue(DWORD dwLastProcessedId)
if (eType != MT_ReadMemory &&
eType != MT_WriteMemory &&
eType != MT_GetDCB &&
eType != MT_SetDCB &&
eType != MT_GetAppDomainCB)
eType != MT_SetDCB)
#endif // RIGHT_SIDE_COMPILE
{
#ifdef RIGHT_SIDE_COMPILE
@ -1658,8 +1645,7 @@ void DbgTransportSession::TransportWorker()
// Since we care about security here, perform some additional validation checks that make it
// harder for a malicious sender to attack with random message data.
if (sReceiveHeader.m_eType > MT_GetAppDomainCB ||
(sReceiveHeader.m_dwId <= m_dwLastMessageIdSeen &&
if ((sReceiveHeader.m_dwId <= m_dwLastMessageIdSeen &&
sReceiveHeader.m_dwId != (DWORD)0) ||
(sReceiveHeader.m_dwReplyId >= m_dwNextMessageId &&
sReceiveHeader.m_dwReplyId != (DWORD)0) ||
@ -1974,17 +1960,6 @@ void DbgTransportSession::TransportWorker()
#endif // RIGHT_SIDE_COMPILE
break;
case MT_GetAppDomainCB:
#ifdef RIGHT_SIDE_COMPILE
if (!ProcessReply(&sReceiveHeader))
HANDLE_TRANSIENT_ERROR();
#else // RIGHT_SIDE_COMPILE
fReplyRequired = true;
pbOptReplyData = (PBYTE)m_pADB;
cbOptReplyData = sizeof(AppDomainEnumerationIPCBlock);
#endif // RIGHT_SIDE_COMPILE
break;
default:
_ASSERTE(!"Unknown message type");
HANDLE_CRITICAL_ERROR();
@ -2089,7 +2064,6 @@ void DbgTransportSession::TransportWorker()
case MT_WriteMemory:
case MT_GetDCB:
case MT_SetDCB:
case MT_GetAppDomainCB:
// On the RS these are the original requests. Signal the completion event.
SignalReplyEvent(pMsg);
break;
@ -2098,7 +2072,6 @@ void DbgTransportSession::TransportWorker()
case MT_WriteMemory:
case MT_GetDCB:
case MT_SetDCB:
case MT_GetAppDomainCB:
// On the LS these are replies to the original request. Nobody's waiting on these.
break;
#endif // RIGHT_SIDE_COMPILE
@ -2501,8 +2474,6 @@ const char *DbgTransportSession::MessageName(MessageType eType)
return "GetDCB";
case MT_SetDCB:
return "SetDCB";
case MT_GetAppDomainCB:
return "GetAppDomainCB";
default:
_ASSERTE(!"Unknown message type");
return NULL;
@ -2561,10 +2532,6 @@ void DbgTransportSession::DbgTransportLogMessageReceived(MessageHeader *pHeader)
DbgTransportLog(LC_Requests, "Received 'SetDCB' reply");
DBG_TRANSPORT_INC_STAT(ReceivedSetDCB);
return;
case MT_GetAppDomainCB:
DbgTransportLog(LC_Requests, "Received 'GetAppDomainCB' reply");
DBG_TRANSPORT_INC_STAT(ReceivedGetAppDomainCB);
return;
#else // RIGHT_SIDE_COMPILE
case MT_ReadMemory:
DbgTransportLog(LC_Requests, "Received 'ReadMemory(0x%08X, %u)'",
@ -2586,10 +2553,6 @@ void DbgTransportSession::DbgTransportLogMessageReceived(MessageHeader *pHeader)
DbgTransportLog(LC_Requests, "Received 'SetDCB'");
DBG_TRANSPORT_INC_STAT(ReceivedSetDCB);
return;
case MT_GetAppDomainCB:
DbgTransportLog(LC_Requests, "Received 'GetAppDomainCB'");
DBG_TRANSPORT_INC_STAT(ReceivedGetAppDomainCB);
return;
#endif // RIGHT_SIDE_COMPILE
default:
_ASSERTE(!"Unknown message type");

View File

@ -4,7 +4,7 @@
LIBRARY mscordbi
EXPORTS
// COM-instantiation - for CorPublish
// COM-instantiation
DllGetClassObjectInternal private
// In-proc (Whidbey-style) creation path from the shim - CDIFV and it's replacement

View File

@ -56,23 +56,28 @@ endif (CLR_CMAKE_HOST_WIN32)
add_definitions(-DFX_VER_INTERNALNAME_STR=CoreCLR.dll)
add_library_clr(coreclr
SHARED
${CLR_SOURCES}
)
if (NOT CLR_CMAKE_HOST_ARCH_WASM)
add_library_clr(coreclr
SHARED
${CLR_SOURCES}
)
add_custom_target(coreclr_exports DEPENDS ${EXPORTS_FILE})
add_custom_target(coreclr_def DEPENDS ${DEF_FILE})
add_custom_target(coreclr_exports DEPENDS ${EXPORTS_FILE})
add_custom_target(coreclr_def DEPENDS ${DEF_FILE})
add_dependencies(coreclr coreclr_def)
add_dependencies(coreclr coreclr_exports)
add_dependencies(coreclr coreclr_def)
add_dependencies(coreclr coreclr_exports)
set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION})
set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE})
set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION})
set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE})
set(LIB_CORDBEE cordbee_wks)
set(LIB_INTEROP interop)
set(LIB_CDAC_CONTRACT_DESCRIPTOR cdac_contract_descriptor)
endif(NOT CLR_CMAKE_HOST_ARCH_WASM)
if (CLR_CMAKE_HOST_UNIX)
if (CLR_CMAKE_HOST_UNIX AND NOT CLR_CMAKE_TARGET_ARCH_WASM)
set(LIB_UNWINDER unwinder_wks)
endif (CLR_CMAKE_HOST_UNIX)
endif (CLR_CMAKE_HOST_UNIX AND NOT CLR_CMAKE_TARGET_ARCH_WASM)
# IMPORTANT! Please do not rearrange the order of the libraries. The linker on Linux is
# order dependent and changing the order can result in undefined symbols in the shared
@ -80,7 +85,7 @@ endif (CLR_CMAKE_HOST_UNIX)
set(CORECLR_LIBRARIES
utilcode
${START_LIBRARY_GROUP} # Start group of libraries that have circular references
cordbee_wks
${LIB_CORDBEE}
debug-pal
${LIB_UNWINDER}
v3binder
@ -95,10 +100,10 @@ set(CORECLR_LIBRARIES
utilcode
v3binder
System.Globalization.Native-Static
interop
${LIB_INTEROP}
coreclrminipal
gc_pal
cdac_contract_descriptor
${LIB_CDAC_CONTRACT_DESCRIPTOR}
)
if(CLR_CMAKE_TARGET_ARCH_AMD64)
@ -168,16 +173,34 @@ if(FEATURE_PERFTRACING)
endif(CLR_CMAKE_TARGET_LINUX)
endif(FEATURE_PERFTRACING)
if(FEATURE_STATICALLY_LINKED)
set(CLRJIT_STATIC clrjit_static)
if (FEATURE_STATICALLY_LINKED)
if (FEATURE_JIT)
set(CLRJIT_STATIC clrjit_static gcinfo)
endif(FEATURE_JIT)
if (FEATURE_INTERPRETER)
set(CLRINTERPRETER_STATIC clrinterpreter)
endif(FEATURE_INTERPRETER)
endif(FEATURE_STATICALLY_LINKED)
if(FEATURE_JIT)
set(CORECLR_STATIC_CLRJIT_STATIC clrjit_static)
endif(FEATURE_JIT)
if(NOT CLR_CMAKE_HOST_ARCH_WASM)
set(CEE_WKS_STATIC cee_wks_mergeable)
else()
set(CEE_WKS_STATIC cee_wks)
endif(NOT CLR_CMAKE_HOST_ARCH_WASM)
if (CLR_CMAKE_TARGET_OSX)
find_library(FOUNDATION Foundation REQUIRED)
endif()
target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks_core cee_wks ${FOUNDATION})
target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} cee_wks_core clrjit_static cee_wks_mergeable ${FOUNDATION})
if(NOT CLR_CMAKE_HOST_ARCH_WASM)
target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} ${CLRINTERPRETER_STATIC} cee_wks_core cee_wks ${FOUNDATION})
endif(NOT CLR_CMAKE_HOST_ARCH_WASM)
target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} cee_wks_core ${CORECLR_STATIC_CLRJIT_STATIC} ${CEE_WKS_STATIC} ${FOUNDATION})
target_compile_definitions(coreclr_static PUBLIC CORECLR_EMBEDDED)
if (CLR_CMAKE_HOST_ANDROID)
@ -227,10 +250,13 @@ if(CLR_CMAKE_TARGET_WIN32)
endif(CLR_CMAKE_TARGET_WIN32)
# add the install targets
install_clr(TARGETS coreclr DESTINATIONS . sharedFramework COMPONENT runtime)
if(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID)
if(NOT CLR_CMAKE_HOST_ARCH_WASM)
install_clr(TARGETS coreclr DESTINATIONS . sharedFramework COMPONENT runtime)
endif(NOT CLR_CMAKE_HOST_ARCH_WASM)
if(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID OR CLR_CMAKE_HOST_ARCH_WASM)
install_clr(TARGETS coreclr_static DESTINATIONS . sharedFramework COMPONENT runtime)
endif(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID)
endif(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID OR CLR_CMAKE_HOST_ARCH_WASM)
# Enable profile guided optimization
add_pgo(coreclr)

View File

@ -308,6 +308,7 @@ BEGIN
IDS_CLASSLOAD_INLINE_ARRAY_FIELD_COUNT "InlineArrayAttribute requires that the target type has a single instance field. Type: '%1'. Assembly: '%2'."
IDS_CLASSLOAD_INLINE_ARRAY_LENGTH "InlineArrayAttribute requires that the length argument is greater than 0. Type: '%1'. Assembly: '%2'."
IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT "InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '%1'. Assembly: '%2'."
IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT_SIZE "InlineArrayAttribute cannot be applied to a type with explicit size. Type: '%1'. Assembly: '%2'."
IDS_CLASSLOAD_BYREF_OF_BYREF "Could not create a ByRef of a ByRef. Type: '%1'. Assembly: '%2'."
IDS_CLASSLOAD_POINTER_OF_BYREF "Could not create a pointer to a ByRef. Type: '%1'. Assembly: '%2'."

View File

@ -160,6 +160,8 @@
#define IDS_CLASSLOAD_BYREF_OF_BYREF 0x17af
#define IDS_CLASSLOAD_POINTER_OF_BYREF 0x17b0
#define IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT_SIZE 0x17b1
#define IDS_INVALID_REDIM 0x17c3
#define IDS_INVALID_PINVOKE_CALLCONV 0x17c4
#define IDS_CLASSLOAD_NSTRUCT_EXPLICIT_OFFSET 0x17c7

View File

@ -97,7 +97,6 @@ enum LogFacility
LF_GC = 0x00000001,
LF_GCALLOC = 0x00000100,
LF_GCROOTS = 0x00080000,
LF_ALWAYS = 0x80000000,
};
enum LogLevel
@ -192,19 +191,25 @@ struct StressLogMsg
}
};
template<>
void* StressLogMsg::ConvertArgument(float arg) = delete;
#if TARGET_64BIT
template<>
inline void* StressLogMsg::ConvertArgument(double arg)
{
return (void*)(size_t)(*((uint64_t*)&arg));
}
// COMPAT: Convert 32-bit floats to 64-bit doubles.
template<>
inline void* StressLogMsg::ConvertArgument(float arg)
{
return StressLogMsg::ConvertArgument((double)arg);
}
#else
template<>
void* StressLogMsg::ConvertArgument(double arg) = delete;
template<>
void* StressLogMsg::ConvertArgument(float arg) = delete;
// COMPAT: Truncate 64-bit integer arguments to 32-bit
template<>
inline void* StressLogMsg::ConvertArgument(uint64_t arg)
@ -234,7 +239,7 @@ public:
static void LogMsg(unsigned dprintfLevel, const StressLogMsg& msg)
{
GCToEEInterface::LogStressMsg(LL_ALWAYS, LF_ALWAYS|(dprintfLevel<<16)|LF_GC, msg);
GCToEEInterface::LogStressMsg(LL_ALWAYS, (dprintfLevel<<16)|LF_GC, msg);
}
static void LogMsg(unsigned level, unsigned facility, const StressLogMsg& msg)

View File

@ -7463,7 +7463,7 @@ bool gc_heap::virtual_commit (void* address, size_t size, int bucket, int h_numb
if ((base + size) > limit)
{
dprintf (1, ("%zd + %zd = %zd > limit %zd ", base, size, (base + size), limit));
dprintf (2, ("%zd + %zd = %zd > limit %zd ", base, size, (base + size), limit));
exceeded_p = true;
}
}
@ -8280,9 +8280,9 @@ uint8_t* get_plug_start_in_saved (uint8_t* old_loc, mark* pinned_plug_entry)
{
uint8_t* saved_pre_plug_info = (uint8_t*)(pinned_plug_entry->get_pre_plug_reloc_info());
uint8_t* plug_start_in_saved = saved_pre_plug_info + (old_loc - (pinned_plug (pinned_plug_entry) - sizeof (plug_and_gap)));
//dprintf (1, ("detected a very short plug: %zx before PP %zx, pad %zx",
//dprintf (2, ("detected a very short plug: %zx before PP %zx, pad %zx",
// old_loc, pinned_plug (pinned_plug_entry), plug_start_in_saved));
dprintf (1, ("EP: %p(%p), %p", old_loc, pinned_plug (pinned_plug_entry), plug_start_in_saved));
dprintf (2, ("EP: %p(%p), %p", old_loc, pinned_plug (pinned_plug_entry), plug_start_in_saved));
return plug_start_in_saved;
}
@ -13531,7 +13531,7 @@ void gc_heap::distribute_free_regions()
size_t total_basic_free_regions = total_num_free_regions[basic_free_region] + surplus_regions[basic_free_region].get_num_free_regions();
total_budget_in_region_units[basic_free_region] = compute_basic_region_budgets(heap_budget_in_region_units[basic_free_region], min_heap_budget_in_region_units[basic_free_region], total_basic_free_regions);
bool aggressive_decommit_large_p = joined_last_gc_before_oom || dt_high_memory_load_p() || near_heap_hard_limit_p();
int region_factor[count_distributed_free_region_kinds] = { 1, LARGE_REGION_FACTOR };
@ -31148,7 +31148,7 @@ void gc_heap::realloc_plan_generation_start (generation* gen, generation* consin
generation_allocation_pointer (consing_gen) += allocation_left;
}
dprintf (1, ("plan re-alloc gen%d start at %p (ptr: %p, limit: %p)", gen->gen_num,
dprintf (2, ("plan re-alloc gen%d start at %p (ptr: %p, limit: %p)", gen->gen_num,
generation_plan_allocation_start (consing_gen),
generation_allocation_pointer (consing_gen),
generation_allocation_limit (consing_gen)));
@ -32751,7 +32751,7 @@ void gc_heap::process_remaining_regions (int current_plan_gen_num, generation* c
}
}
dprintf (1, ("we still need %d regions, %d will be empty", plan_regions_needed, to_be_empty_regions));
dprintf (REGIONS_LOG, ("we still need %d regions, %d will be empty", plan_regions_needed, to_be_empty_regions));
if (plan_regions_needed > to_be_empty_regions)
{
dprintf (REGIONS_LOG, ("h%d %d regions will be empty but we still need %d regions!!", heap_number, to_be_empty_regions, plan_regions_needed));
@ -34104,7 +34104,7 @@ void gc_heap::plan_phase (int condemned_gen_number)
#else
0;
#endif //SHORT_PLUGS
dprintf (1, ("gen%d: NON PIN alloc: %zd, pin com: %zd, sweep: %zd, surv: %zd, pinsurv: %zd(%d%% added, %d%% art), np surv: %zd, pad: %zd",
dprintf (2, ("gen%d: NON PIN alloc: %zd, pin com: %zd, sweep: %zd, surv: %zd, pinsurv: %zd(%d%% added, %d%% art), np surv: %zd, pad: %zd",
gen_idx,
generation_allocation_size (temp_gen),
generation_pinned_allocation_compact_size (temp_gen),
@ -42140,10 +42140,13 @@ BOOL gc_heap::card_transition (uint8_t* po, uint8_t* end, size_t card_word_end,
//dprintf(3,(" Clearing cards [%zx, %zx[ ",
dprintf(3,(" CC [%zx, %zx[ ",
(size_t)card_address(card), (size_t)po));
clear_cards (card, card_of(po));
n_card_set -= (card_of (po) - card);
n_cards_cleared += (card_of (po) - card);
uint8_t* card_clearing_limit = po;
#ifdef FEATURE_CARD_MARKING_STEALING
card_clearing_limit = min (limit, po);
#endif // FEATURE_CARD_MARKING_STEALING
clear_cards (card, card_of (card_clearing_limit));
n_card_set -= (card_of (card_clearing_limit) - card);
n_cards_cleared += (card_of (card_clearing_limit) - card);
}
n_eph +=cg_pointers_found;
cg_pointers_found = 0;
@ -43929,7 +43932,7 @@ generation* gc_heap::expand_heap (int condemned_generation,
BOOL should_promote_ephemeral = FALSE;
ptrdiff_t eph_size = total_ephemeral_size;
#ifdef BACKGROUND_GC
dprintf(2,("%s: ---- Heap Expansion ----", (gc_heap::background_running_p() ? "FGC" : "NGC")));
dprintf(2,("%s: ---- Heap Expansion ----", get_str_gc_type()));
#endif //BACKGROUND_GC
settings.heap_expansion = TRUE;
@ -44431,7 +44434,7 @@ size_t gc_heap::desired_new_allocation (dynamic_data* dd,
{
size_t allocated = 0;
size_t committed = uoh_committed_size (gen_number, &allocated);
dprintf (1, ("GC#%zd h%d, GMI: UOH budget, UOH commit %zd (obj %zd, frag %zd), total commit: %zd (recorded: %zd)",
dprintf (2, ("GC#%zd h%d, GMI: UOH budget, UOH commit %zd (obj %zd, frag %zd), total commit: %zd (recorded: %zd)",
(size_t)settings.gc_index, heap_number,
committed, allocated,
dd_fragmentation (dynamic_data_of (gen_number)),
@ -44508,7 +44511,7 @@ size_t gc_heap::desired_new_allocation (dynamic_data* dd,
dd_surv (dd) = cst;
dprintf (1, (ThreadStressLog::gcDesiredNewAllocationMsg(),
dprintf (2, (ThreadStressLog::gcDesiredNewAllocationMsg(),
heap_number, gen_number, out, current_size, (dd_desired_allocation (dd) - dd_gc_new_allocation (dd)),
(int)(cst*100), (int)(f*100), current_size + new_allocation, new_allocation));
@ -47802,18 +47805,18 @@ void gc_heap::descr_generations (const char* msg)
#endif //!TRACE_GC
#ifdef STRESS_LOG
if (StressLog::StressLogOn(LF_GC, LL_INFO10))
if (StressLog::StressLogOn(LF_GC, LL_INFO1000))
{
gc_heap* hp = 0;
#ifdef MULTIPLE_HEAPS
hp= this;
#endif //MULTIPLE_HEAPS
STRESS_LOG1(LF_GC, LL_INFO10, "GC Heap %p\n", hp);
STRESS_LOG1(LF_GC, LL_INFO1000, "GC Heap %p\n", hp);
for (int n = max_generation; n >= 0; --n)
{
#ifndef USE_REGIONS
STRESS_LOG4(LF_GC, LL_INFO10, " Generation %d [%p, %p] cur = %p\n",
STRESS_LOG4(LF_GC, LL_INFO1000, " Generation %d [%p, %p] cur = %p\n",
n,
generation_allocation_start(generation_of(n)),
generation_allocation_limit(generation_of(n)),
@ -47823,7 +47826,7 @@ void gc_heap::descr_generations (const char* msg)
heap_segment* seg = generation_start_segment(generation_of(n));
while (seg)
{
STRESS_LOG4(LF_GC, LL_INFO10, " Segment mem %p alloc = %p used %p committed %p\n",
STRESS_LOG4(LF_GC, LL_INFO1000, " Segment mem %p alloc = %p used %p committed %p\n",
heap_segment_mem(seg),
heap_segment_allocated(seg),
heap_segment_used(seg),
@ -48653,7 +48656,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p)
dprintf (2,("[%s]GC#%zu(%s): Verifying heap - begin",
(begin_gc_p ? "BEG" : "END"),
VolatileLoad(&settings.gc_index),
(settings.concurrent ? "BGC" : (gc_heap::background_running_p() ? "FGC" : "NGC"))));
get_str_gc_type()));
#else
dprintf (2,("[%s]GC#%zu: Verifying heap - begin",
(begin_gc_p ? "BEG" : "END"), VolatileLoad(&settings.gc_index)));
@ -49060,7 +49063,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p)
#ifdef BACKGROUND_GC
dprintf (2, ("(%s)(%s)(%s) total_objects_verified is %zd, total_objects_verified_deep is %zd",
(settings.concurrent ? "BGC" : (gc_heap::background_running_p () ? "FGC" : "NGC")),
get_str_gc_type(),
(begin_gc_p ? "BEG" : "END"),
((current_c_gc_state == c_gc_state_planning) ? "in plan" : "not in plan"),
total_objects_verified, total_objects_verified_deep));
@ -49113,7 +49116,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p)
}
dprintf (2,("GC%zu(%s): Verifying heap - end",
VolatileLoad(&settings.gc_index),
(settings.concurrent ? "BGC" : (gc_heap::background_running_p() ? "FGC" : "NGC"))));
get_str_gc_type()));
#else
dprintf (2,("GC#d: Verifying heap - end", VolatileLoad(&settings.gc_index)));
#endif //BACKGROUND_GC
@ -49779,10 +49782,10 @@ HRESULT GCHeap::Initialize()
// GC callback functions
bool GCHeap::IsPromoted(Object* object)
{
return IsPromoted(object, true);
return IsPromoted2(object, true);
}
bool GCHeap::IsPromoted(Object* object, bool bVerifyNextHeader)
bool GCHeap::IsPromoted2(Object* object, bool bVerifyNextHeader)
{
uint8_t* o = (uint8_t*)object;
@ -50878,6 +50881,15 @@ last_recorded_gc_info* gc_heap::get_completed_bgc_info()
}
#endif //BACKGROUND_GC
const char* gc_heap::get_str_gc_type()
{
#ifdef BACKGROUND_GC
return (settings.concurrent ? "BGC" : (gc_heap::background_running_p () ? "FGC" : "NGC"));
#else // BACKGROUND_GC
return "NGC";
#endif // BACKGROUND_GC
}
void gc_heap::do_pre_gc()
{
STRESS_LOG_GC_STACK;
@ -50906,14 +50918,21 @@ void gc_heap::do_pre_gc()
#ifdef TRACE_GC
size_t total_allocated_since_last_gc[total_oh_count];
get_total_allocated_since_last_gc (total_allocated_since_last_gc);
bool compatibleWithStressLog = true;
#ifdef SIMPLE_DPRINTF
compatibleWithStressLog = false;
#endif //SIMPLE_DPRINTF
bgc_state b_state = bgc_not_in_process;
#ifdef BACKGROUND_GC
b_state = settings.b_state;
#endif //BACKGROUND_GC
size_t heap_size_before = get_total_heap_size();
uint64_t start_gc_time = GetHighPrecisionTimeStamp();
uint64_t elapsed_since_last_gc_us = start_gc_time - last_alloc_reset_suspended_end_time;
max_peak_heap_size = max (max_peak_heap_size, heap_size_before);
dprintf (6666, (ThreadStressLog::gcDetailedStartMsg(),
dprintf (6666, (ThreadStressLog::gcDetailedStartMsg(compatibleWithStressLog),
VolatileLoad(&settings.gc_index),
dd_collection_count (hp->dynamic_data_of (0)),
settings.condemned_generation,
@ -50926,18 +50945,11 @@ void gc_heap::do_pre_gc()
(elapsed_since_last_gc_us ? (total_allocated_since_last_gc[gc_oh_num::loh] / 1000.0 / elapsed_since_last_gc_us) : 0),
total_allocated_since_last_gc[gc_oh_num::poh],
(elapsed_since_last_gc_us ? (total_allocated_since_last_gc[gc_oh_num::poh] / 1000.0 / elapsed_since_last_gc_us) : 0),
(settings.concurrent ? "BGC" : (gc_heap::background_running_p() ? "FGC" : "NGC")),
settings.b_state,
n_heaps,
(heap_size_before / 1000.0 / 1000.0),
(max_peak_heap_size / 1000.0 / 1000.0)));
#else
dprintf (1, ("*GC* %d(gen0:%d)(%d)(alloc: %zd)",
VolatileLoad(&settings.gc_index),
dd_collection_count(hp->dynamic_data_of(0)),
settings.condemned_generation,
(total_allocated_since_last_gc[0] + total_allocated_since_last_gc[1] + total_allocated_since_last_gc[2])));
#endif //BACKGROUND_GC
get_str_gc_type(),
b_state,
n_heaps
SIMPLE_DPRINTF_ARG(heap_size_before / 1000.0 / 1000.0)
SIMPLE_DPRINTF_ARG(max_peak_heap_size / 1000.0 / 1000.0)));
if (heap_hard_limit)
{
@ -51356,18 +51368,12 @@ void gc_heap::do_post_gc()
}
#endif //BGC_SERVO_TUNING
#ifdef BACKGROUND_GC
const char* str_gc_type = (settings.concurrent ? "BGC" : (gc_heap::background_running_p () ? "FGC" : "NGC"));
#else
const char* str_gc_type = "NGC";
#endif //BACKGROUND_GC
dprintf (6666, (ThreadStressLog::gcDetailedEndMsg(),
VolatileLoad (&settings.gc_index),
dd_collection_count (hp->dynamic_data_of (0)),
(get_total_heap_size() / 1000.0 / 1000.0),
settings.condemned_generation,
str_gc_type,
get_str_gc_type(),
(settings.compaction ? "C" : "S"),
(settings.promotion ? "P" : "S"),
settings.entry_memory_load,

View File

@ -285,11 +285,16 @@ struct alloc_context : gc_alloc_context
#endif // FEATURE_SVR_GC
};
// NOTE!
// Do not add overloaded methods, always use a different name, different from any methods declared here or
// on the IGCHeap interface.
class IGCHeapInternal : public IGCHeap {
public:
virtual int GetNumberOfHeaps () PURE_VIRTUAL
virtual int GetHomeHeapNumber () PURE_VIRTUAL
virtual size_t GetPromotedBytes(int heap_index) PURE_VIRTUAL
// Used by the bridge code.
virtual bool IsPromoted2(Object* object, bool bVerifyNextHeader) PURE_VIRTUAL
unsigned GetMaxGeneration()
{
@ -344,9 +349,23 @@ inline bool IsServerHeap()
#define MAX_LONGPATH 1024
#endif // MAX_LONGPATH
// #define TRACE_GC
// TRACE_GC has two sub-modes: the standard VM stress log mechanism and
// SIMPLE_DPRINTF, which is text output. By default, we enable TRACE_GC (not
// SIMPLE_DPRINTF) for debug/checked builds so that we can catch build breaks.
// HOST_64BIT is required because logging dprintf to the stress log is only
// supported on 64 bit platforms. We could consider enabling it in release
// builds and for more logging sites (see below for details) but are being
// conservative about performance impact.
//
// Normal development time changes are to enable SIMPLE_DPRINTF here (which
// will automatically set TRACE_GC) or to only enable TRACE_GC.
// #define SIMPLE_DPRINTF
#if defined(SIMPLE_DPRINTF) || (defined(_DEBUG) && defined(HOST_64BIT))
#define TRACE_GC
#endif // _DEBUG
#ifdef TRACE_GC
#define MIN_CUSTOM_LOG_LEVEL 7
#define SEG_REUSE_LOG_0 (MIN_CUSTOM_LOG_LEVEL)
@ -375,10 +394,79 @@ HRESULT initialize_log_file();
void flush_gc_log (bool);
void GCLog (const char *fmt, ... );
#define dprintf(l,x) {if ((l == 1) || (l == GTC_LOG)) {GCLog x;}}
#define SIMPLE_DPRINTF_ARG(x) , x
#else //SIMPLE_DPRINTF
#ifdef HOST_64BIT
#define dprintf(l,x) STRESS_LOG_VA(l,x);
// -------------------------------
// Stress log / dprintf background
// -------------------------------
//
// This code connects dprintf to the stress log mechanism. These machanisms
// and their usage has evolved a bit separately over time, so there are some
// rough edges here.
//
// The stress log mechanism has a LogFacility and a LogLevel. Facilities can be
// chosen through DOTNET_LogFacility, and the facility is recorded in the
// stress log. LogFacility is a bitmask. The GC only has a few bits reserved
// in the bitmask, and most GC logging uses a single value (LF_GC, which is 0x1).
//
// The stress log logging level can be chosen through DOTNET_LogLevel. This
// causes filtering at runtime, and the level is not recorded in the stress log.
// The first argument to dprintf is similar, though it can record either a level
// (values below 7) or a GC area (values starting with SEG_REUSE_LOG_0 above).
// Developers often use StressLogAnalyzer to filter by this value at _analysis_
// time, which doesn't match usual stress log usage.
//
// In practice, dprintf(1) and LL_INFO10 (which has the value 4) have been used
// similarly on log messages. A dprintf(1) is generally called about a few times per
// GC, and LL_INFO10 is "10 logs per small but not trivial run". Other values
// have been audited. We could consider moving the GC values to be in line with
// the rest of the runtime (change 1 to 4 to make room for errors/warnings, etc.)
// or (to avoid churn) convert them by adding 3.
//
// To allow StressLogAnalyzer to use the GC level values, we abuse the stress
// log LogLevel by storing the GC value in the upper 16 bits of LogLevel and
// also settings LF_GC (0x1). This works because we don't enable other logging
// when doing GC investigations. However, we don't want to do this by default
// because setting the upper bits will cause GC logging to masquerade as non-GC
// logging. For example, dprintf(3) would use (3 << 16) | LF_GC == 0x30001,
// which is LF_ASSERT | LF_VERIFIER | LF_GC in other contexts.
//
// Lastly, we have GC logging for some very low level operations, so by default
// we don't want to even have the check that logging is enabled for performance
// reasons. Right now we are very conservative and only allow dprintf(1) to go
// to the stress log in default builds, but we could consider allowing more in
// the future.
// -----------------------------
// Stress log / dprintf settings
// -----------------------------
//
// (See above for details.)
//
// The following line works for normal debug/checked builds (where STRESS_LOG is
// defined and SIMPLE_DPRINTF is not). All dprintf sites are checked for
// compilation errors, yet all but those with level 1 can be statically
// optimized away. In the future after more auditing, this could be expanded to
// more levels.
//
// Note that zero is passed because STRESS_LOG_VA/LogMsg will add LF_GC and in
// normal builds we don't want conflicts in the upper bits of LogFacility.
#define dprintf(l,x) if (l == 1) {STRESS_LOG_VA(0,x);}
// For private builds where it is ok (and useful) to have conflicts in the upper
// bits of LogFacility, more events can be allowed and the dprintf level can be
// passed through. Usually this is going to be a GC investigation and the other
// logging will be disabled, so the theoretical conflict won't happen in
// practice. Note that in these examples, 'l' ("ell", not "one") is passed
// rather than '0'.
//#define dprintf(l,x) STRESS_LOG_VA(l,x);
//#define dprintf(l,x) {if ((l <= 2) || (l == 6666)) {STRESS_LOG_VA(l,x);}}
#define SIMPLE_DPRINTF_ARG(x)
#else //HOST_64BIT
#error Logging dprintf to stress log on 32 bits platforms is not supported.
#endif //HOST_64BIT

View File

@ -666,7 +666,7 @@ static bool PushObject(Object* obj, void* unused)
}
// We only care about dead objects
if (!data && g_theGCHeap->IsPromoted(obj, false))
if (!data && g_theGCHeap->IsPromoted2(obj, false))
{
#if DUMP_GRAPH
printf ("alive\n");

View File

@ -126,7 +126,7 @@ public:
// Check if an argument is promoted (ONLY CALL DURING
// THE PROMOTIONSGRANTED CALLBACK.)
bool IsPromoted (Object *object);
bool IsPromoted (Object *object, bool bVerifyNextHeader);
bool IsPromoted2 (Object *object, bool bVerifyNextHeader);
size_t GetPromotedBytes (int heap_index);

View File

@ -644,6 +644,9 @@ enum class GCConfigurationType
using ConfigurationValueFunc = void (*)(void* context, void* name, void* publicKey, GCConfigurationType type, int64_t data);
// IGCHeap is the interface that the VM will use when interacting with the GC.
// NOTE!
// Only add methods to the end.
// Do not add overloaded methods. Always use a different name.
class IGCHeap {
public:
/*
@ -1065,9 +1068,6 @@ public:
virtual void DiagWalkHeapWithACHandling(walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p) PURE_VIRTUAL
virtual void NullBridgeObjectsWeakRefs(size_t length, void* unreachableObjectHandles) PURE_VIRTUAL;
// Returns whether nor this GC was promoted by the last GC.
virtual bool IsPromoted(Object* object, bool bVerifyNextHeader) PURE_VIRTUAL
};
#ifdef WRITE_BARRIER_CHECK

View File

@ -1578,6 +1578,8 @@ public:
private:
PER_HEAP_ISOLATED_METHOD const char* get_str_gc_type();
#ifdef TRACE_GC
PER_HEAP_METHOD void print_free_list (int gen, heap_segment* seg);
#endif // TRACE_GC

View File

@ -222,7 +222,7 @@ bool GCToOSInterface::Initialize()
//
// support for FlusProcessWriteBuffers
//
#ifndef TARGET_WASM
assert(s_flushUsingMemBarrier == 0);
if (CanFlushUsingMembarrier())
@ -262,6 +262,7 @@ bool GCToOSInterface::Initialize()
}
}
#endif // !TARGET_APPLE
#endif // !TARGET_WASM
InitializeCGroup();
@ -412,6 +413,7 @@ bool GCToOSInterface::CanGetCurrentProcessorNumber()
// Flush write buffers of processors that are executing threads of the current process
void GCToOSInterface::FlushProcessWriteBuffers()
{
#ifndef TARGET_WASM
#if defined(__linux__) || HAVE_SYS_MEMBARRIER_H
if (s_flushUsingMemBarrier)
{
@ -490,6 +492,7 @@ void GCToOSInterface::FlushProcessWriteBuffers()
CHECK_MACH("vm_deallocate()", machret);
}
#endif // TARGET_APPLE
#endif // !TARGET_WASM
}
// Break into a debugger. Uses a compiler intrinsic if one is available,
@ -576,7 +579,7 @@ static void* VirtualReserveInner(size_t size, size_t alignment, uint32_t flags,
}
pRetVal = pAlignedRetVal;
#ifdef MADV_DONTDUMP
#if defined(MADV_DONTDUMP) && !defined(TARGET_WASM)
// Do not include reserved uncommitted memory in coredump.
if (!committing)
{
@ -624,9 +627,13 @@ bool GCToOSInterface::VirtualRelease(void* address, size_t size)
// true if it has succeeded, false if it has failed
static bool VirtualCommitInner(void* address, size_t size, uint16_t node, bool newMemory)
{
#ifndef TARGET_WASM
bool success = mprotect(address, size, PROT_WRITE | PROT_READ) == 0;
#else
bool success = true;
#endif // !TARGET_WASM
#ifdef MADV_DODUMP
#if defined(MADV_DONTDUMP) && !defined(TARGET_WASM)
if (success && !newMemory)
{
// Include committed memory in coredump. New memory is included by default.

View File

@ -1,7 +1,11 @@
include_directories(inc)
if(CLR_CMAKE_HOST_WIN32)
add_subdirectory(coreshim)
endif(CLR_CMAKE_HOST_WIN32)
if (CLR_CMAKE_TARGET_ARCH_WASM)
add_subdirectory(corewasmrun)
else()
if(CLR_CMAKE_HOST_WIN32)
add_subdirectory(coreshim)
endif(CLR_CMAKE_HOST_WIN32)
add_subdirectory(corerun)
add_subdirectory(corerun)
endif()

View File

@ -0,0 +1,28 @@
project(corewasmrun)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
if (DEFINED CLR_CMAKE_ICU_DIR)
link_directories(${CLR_CMAKE_ICU_DIR}/lib)
endif(DEFINED CLR_CMAKE_ICU_DIR)
add_executable_clr(corewasmrun
corewasmrun.cpp
)
set(_WASM_PRELOAD_DIR "${CMAKE_INSTALL_PREFIX}/IL")
if (EXISTS "${_WASM_PRELOAD_DIR}")
set(_WASM_PRELOAD_FILE --preload-file ${_WASM_PRELOAD_DIR}@/)
endif (EXISTS "${_WASM_PRELOAD_DIR}")
target_compile_options(corewasmrun PRIVATE -fwasm-exceptions)
target_link_options(corewasmrun PRIVATE -fwasm-exceptions -sEXIT_RUNTIME=1 -sINITIAL_MEMORY=134217728 -sFORCE_FILESYSTEM=1 ${_WASM_PRELOAD_FILE} -Wl,-error-limit=0)
target_link_libraries(corewasmrun PRIVATE coreclr_static)
target_link_libraries(corewasmrun PRIVATE clrinterpreter)
target_link_libraries(corewasmrun PRIVATE icuuc)
target_link_libraries(corewasmrun PRIVATE icui18n)
target_link_libraries(corewasmrun PRIVATE icudata)
install_clr(TARGETS corewasmrun DESTINATIONS . COMPONENT hosts)

View File

@ -0,0 +1,49 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
#include <cstdio>
#include <coreclrhost.h>
static void log_error_info(const char* line)
{
std::fprintf(stderr, "log error: %s\n", line);
}
// The current CoreCLR instance details.
static void* CurrentClrInstance;
static unsigned int CurrentAppDomainId;
static int run()
{
const char* exe_path = "<coreclr-wasm>";
const char* app_domain_name = "corewasmrun";
const char* entry_assembly = "ManagedAssembly.dll";
coreclr_set_error_writer(log_error_info);
printf("call coreclr_initialize\n");
int retval = coreclr_initialize(exe_path, app_domain_name, 0, nullptr, nullptr, &CurrentClrInstance, &CurrentAppDomainId);
if (retval < 0)
{
std::fprintf(stderr, "coreclr_initialize failed - Error: 0x%08x\n", retval);
return -1;
}
else
{
printf("coreclr_initialize succeeded - retval: 0x%08x\n", retval);
}
// coreclr_execute_assembly();
// coreclr_shutdown();
return retval;
}
int main()
{
int retval = run();
return retval;
}

View File

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>corewasmrun</title>
</head>
<body>
<h1>corewasmrun</h1>
<pre id="log"></pre>
<script>
Module = {
preRun: [ function () {
ENV.PAL_DBG_CHANNELS="+all.all";
// ENV.PAL_DBG_CHANNELS="+all.ERROR";
}],
onExit: function (code) {
console.log("onExit, code: " + code);
},
};
const originalConsoleLog = console.log;
console.log = function(message) {
originalConsoleLog(message);
fetch('/log=corewasmrun-log.txt', {
method: 'POST',
body: ('stdout: ' + message),
headers: {
'Content-Type': 'text/plain'
}
});
const elt = document.createElement("span");
elt.textContent = message + "\n";
document.querySelector("#log").appendChild(elt);
};
const originalConsoleError = console.error;
console.error = function(message) {
originalConsoleError(message);
fetch('/log=corewasmrun-log.txt', {
method: 'POST',
body: ('stderr: ' + message),
headers: {
'Content-Type': 'text/plain'
}
});
const elt = document.createElement("span");
elt.textContent = message + "\n";
elt.style.color = "red";
document.querySelector("#log").appendChild(elt);
};
</script>
<script src="corewasmrun.js"></script>
</body>

View File

@ -5,7 +5,6 @@ set( CORGUIDS_IDL_SOURCES
clrinternal.idl
xclrdata.idl
corprof.idl
corpub.idl
corsym.idl
sospriv.idl
)

View File

@ -78,7 +78,7 @@ Crst AppDomainCache
End
Crst PinnedHeapHandleTable
AcquiredBefore AvailableParamTypes HandleTable IbcProfile SyncBlockCache SystemDomainDelayedUnloadList
AcquiredBefore AvailableParamTypes HandleTable SyncBlockCache SystemDomainDelayedUnloadList
SystemDomain
End
@ -91,7 +91,7 @@ Crst AvailableClass
End
Crst AvailableParamTypes
AcquiredBefore ModuleLookupTable IbcProfile LoaderHeap
AcquiredBefore ModuleLookupTable LoaderHeap
End
Crst CCompRC
@ -103,7 +103,7 @@ Crst ClassFactInfoHash
End
Crst ClassInit
AcquiredBefore DeadlockDetection IbcProfile
AcquiredBefore DeadlockDetection
SameLevelAs Jit
End
@ -176,14 +176,14 @@ Crst DbgTransport
End
Crst GenericDictionaryExpansion
AcquiredBefore PinnedHeapHandleTable IbcProfile LoaderHeap SystemDomainDelayedUnloadList UniqueStack
AcquiredBefore PinnedHeapHandleTable LoaderHeap SystemDomainDelayedUnloadList UniqueStack
End
Crst DynamicIL
End
Crst DynamicMT
AcquiredBefore IbcProfile CodeVersioning
AcquiredBefore CodeVersioning
End
Crst EventStore
@ -209,7 +209,7 @@ Crst MethodTableExposedObject
End
Crst FuncPtrStubs
AcquiredBefore IbcProfile LoaderHeap UniqueStack CodeFragmentHeap JumpStubCache
AcquiredBefore LoaderHeap UniqueStack CodeFragmentHeap JumpStubCache
End
Crst FusionAppCtx
@ -221,16 +221,13 @@ Crst GCCover
End
Crst GlobalStrLiteralMap
AcquiredBefore PinnedHeapHandleTable HandleTable IbcProfile SyncBlockCache SystemDomainDelayedUnloadList ThreadStore UniqueStack
AcquiredBefore PinnedHeapHandleTable HandleTable SyncBlockCache SystemDomainDelayedUnloadList ThreadStore UniqueStack
End
Crst HandleTable
SameLevelAs HandleTable
End
Crst IbcProfile
End
Crst IJWFixupData
AcquiredBefore FuncPtrStubs IJWHash LoaderHeap
End
@ -329,7 +326,7 @@ Crst PendingTypeLoadEntry
AcquiredBefore AppDomainCache PinnedHeapHandleTable AssemblyLoader AvailableClass AvailableParamTypes
ClassInit DeadlockDetection DebuggerController DebuggerJitInfo DebuggerMutex
GenericDictionaryExpansion Exception FuncPtrStubs
FusionAppCtx GlobalStrLiteralMap HandleTable IbcProfile
FusionAppCtx GlobalStrLiteralMap HandleTable
IJWFixupData IJWHash ISymUnmanagedReader Jit JumpStubCache LoaderHeap
Module ModuleLookupTable PEImage
SigConvert SingleUseLock StubDispatchCache
@ -352,7 +349,7 @@ Crst ProfilingAPIStatus
End
Crst RCWCache
AcquiredBefore IbcProfile LoaderHeap RCWCleanupList
AcquiredBefore LoaderHeap RCWCleanupList
End
Crst RCWCleanupList
@ -415,7 +412,7 @@ Crst SyncHashLock
End
Crst SystemDomain
AcquiredBefore DebuggerMutex HandleTable IbcProfile
AcquiredBefore DebuggerMutex HandleTable
ThreadIdDispenser ThreadStore
End
@ -431,7 +428,7 @@ End
Crst ThreadStore
AcquiredBefore AvailableParamTypes DeadlockDetection DebuggerController
DebuggerHeapLock DebuggerJitInfo DynamicIL HandleTable IbcProfile
DebuggerHeapLock DebuggerJitInfo DynamicIL HandleTable
JumpStubCache LoaderHeap ModuleLookupTable ProfilerGCRefDataFreeList
SingleUseLock SyncBlockCache SystemDomainDelayedUnloadList ThreadIdDispenser DebuggerMutex
JitInlineTrackingMap
@ -453,11 +450,11 @@ Crst UniqueStack
End
Crst UnresolvedClassLock
AcquiredBefore AvailableParamTypes IbcProfile JumpStubCache
AcquiredBefore AvailableParamTypes JumpStubCache
End
Crst WrapperTemplate
AcquiredBefore IbcProfile
AcquiredBefore ExecutableAllocatorLock
End
Crst UMEntryThunkCache
@ -479,7 +476,6 @@ Crst MulticoreJitManager
End
Crst InlineTrackingMap
AcquiredBefore IbcProfile
End
Crst JitInlineTrackingMap

View File

@ -453,7 +453,7 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadSuspendInjection, W("INTERNAL_ThreadSusp
///
/// Thread (miscellaneous)
///
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(EXTERNAL_Thread_DefaultStackSize, W("Thread_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.")
@ -708,6 +708,9 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zba, W("EnableRiscV64
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zbb, W("EnableRiscV64Zbb"), 1, "Allows RiscV64 Zbb hardware intrinsics to be disabled")
#endif
// Runtime-async
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_RuntimeAsync, W("RuntimeAsync"), 0, "Enables runtime async method support")
///
/// Uncategorized
///

Some files were not shown because too many files have changed in this diff Show More