diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 2f4ce2358e0207..058644afd46753 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -15,7 +15,7 @@
]
},
"microsoft.dotnet.xharness.cli": {
- "version": "9.0.0-prerelease.24405.1",
+ "version": "9.0.0-prerelease.25113.3",
"commands": [
"xharness"
]
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 2d544524862e2d..6d8489e86c472d 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -113,3 +113,4 @@
/docs/area-owners.* @jeffhandley
/docs/issue*.md @jeffhandley
/.github/policies/ @jeffhandley @mkArtakMSFT
+/.github/workflows/ @jeffhandley @dotnet/runtime-infrastructure
diff --git a/.github/PULL_REQUEST_TEMPLATE/servicing_pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/servicing_pull_request_template.md
index 9a748a085a20f1..cfd64682e8313e 100644
--- a/.github/PULL_REQUEST_TEMPLATE/servicing_pull_request_template.md
+++ b/.github/PULL_REQUEST_TEMPLATE/servicing_pull_request_template.md
@@ -22,6 +22,7 @@ main PR
-# Package authoring signed off?
+# Package authoring no longer needed in .NET 9
-IMPORTANT: If this change touches code that ships in a NuGet package, please make certain that you have added any necessary [package authoring](../../docs/project/library-servicing.md) and gotten it explicitly reviewed.
+IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
+Keep in mind that we still need package authoring in .NET 8 and older versions.
\ No newline at end of file
diff --git a/.github/workflows/README.md b/.github/workflows/README.md
new file mode 100644
index 00000000000000..f5e7799b30e2a2
--- /dev/null
+++ b/.github/workflows/README.md
@@ -0,0 +1,22 @@
+# Workflows
+
+General guidance:
+
+Please make sure to include the @dotnet/runtime-infrastructure group as a reviewer of your PRs.
+
+For workflows that are triggered by pull requests, refer to GitHub's documentation for the `pull_request` and `pull_request_target` events. The `pull_request_target` event is the more common use case in this repository as it runs the workflow in the context of the target branch instead of in the context of the pull request's fork or branch. However, workflows that need to consume the contents of the pull request need to use the `pull_request` event. There are security considerations with each of the events though.
+
+Most workflows are intended to run only in the `dotnet/runtime` repository and not in forks. To force workflow jobs to be skipped in forks, each job should apply an `if` statement that checks the repository name or owner. Either approach works, but checking only the repository owner allows the workflow to run in copies or forks withing the dotnet org.
+
+```yaml
+jobs:
+ job-1:
+ # Do not run this job in forks
+ if: github.repository == 'dotnet/runtime'
+
+ job-2:
+ # Do not run this job in forks outside the dotnet org
+ if: github.repository_owner == 'dotnet'
+```
+
+Refer to GitHub's [Workflows in forked repositories](https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflows-in-forked-repositories) and [pull_request_target](https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_target) documentation for more information.
diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml
index f8165363070ea5..67ddf782dc0d14 100644
--- a/.github/workflows/backport.yml
+++ b/.github/workflows/backport.yml
@@ -48,4 +48,7 @@ jobs:
- The PR target branch is `release/X.0-staging`, not `release/X.0`.
- - If the change touches code that ships in a NuGet package, you have added the necessary [package authoring](https://github.com/dotnet/runtime/blob/main/docs/project/library-servicing.md) and gotten it explicitly reviewed.
+ ## Package authoring no longer needed in .NET 9
+
+ **IMPORTANT**: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
+ Keep in mind that we still need package authoring in .NET 8 and older versions.
\ No newline at end of file
diff --git a/.github/workflows/check-no-merge-label.yml b/.github/workflows/check-no-merge-label.yml
new file mode 100644
index 00000000000000..d503400b0e154c
--- /dev/null
+++ b/.github/workflows/check-no-merge-label.yml
@@ -0,0 +1,25 @@
+name: check-no-merge-label
+
+permissions:
+ pull-requests: read
+
+on:
+ pull_request_target:
+ types: [opened, reopened, labeled, unlabeled]
+ branches:
+ - 'release/**'
+
+jobs:
+ check-labels:
+ if: github.repository == 'dotnet/runtime'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check 'NO-MERGE' label
+ run: |
+ echo "Merging permission is disabled when the 'NO-MERGE' label is applied."
+ if [ "${{ contains(github.event.pull_request.labels.*.name, 'NO-MERGE') }}" = "false" ]; then
+ exit 0
+ else
+ echo "::error:: The 'NO-MERGE' label was applied to the PR. Merging is disabled."
+ exit 1
+ fi
diff --git a/.github/workflows/check-service-labels.yml b/.github/workflows/check-service-labels.yml
index 5261cc165ee128..c158ff6f1520d6 100644
--- a/.github/workflows/check-service-labels.yml
+++ b/.github/workflows/check-service-labels.yml
@@ -4,18 +4,19 @@ permissions:
pull-requests: read
on:
- pull_request:
- types: [opened, edited, reopened, labeled, unlabeled, synchronize]
+ pull_request_target:
+ types: [opened, reopened, labeled, unlabeled]
branches:
- 'release/**'
jobs:
check-labels:
+ if: github.repository == 'dotnet/runtime'
runs-on: ubuntu-latest
steps:
- name: Check 'Servicing-approved' label
run: |
- echo "Merging permission is enabled for servicing PRs when the `Servicing-approved` label is applied."
+ echo "Merging permission is enabled for servicing PRs when the 'Servicing-approved' label is applied."
if [ "${{ contains(github.event.pull_request.labels.*.name, 'Servicing-approved') }}" = "true" ]; then
exit 0
else
diff --git a/.github/workflows/jit-format.yml b/.github/workflows/jit-format.yml
index be0a5d854a9caa..18fb209c628afc 100644
--- a/.github/workflows/jit-format.yml
+++ b/.github/workflows/jit-format.yml
@@ -15,7 +15,7 @@ jobs:
os:
- name: linux
image: ubuntu-latest
- container: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-net9.0
+ container: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-amd64
extension: '.sh'
cross: '--cross'
rootfs: '/crossrootfs/x64'
diff --git a/Directory.Build.props b/Directory.Build.props
index 688fcaec63b4f6..530286a2719d7e 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -121,9 +121,8 @@
-
- 8.0.0
- net8.0
+ 9.0.0
+ net9.0
diff --git a/NuGet.config b/NuGet.config
index c35709acd8020a..deafa2a01414c9 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -9,8 +9,11 @@
-
+
+
+
+
-
+
https://github.com/dotnet/cecil
- e51bd3677d5674fa34bf5676c5fc5562206bf94e
+ 8debcd23b73a27992a5fdb2229f546e453619d11
-
+
https://github.com/dotnet/emsdk
- 763d10a1a251be35337ee736832bfde3f9200672
+ 78be8cdf4f0bfd93018fd7a87f8282a41d041298
-
+
https://github.com/dotnet/emsdk
- 763d10a1a251be35337ee736832bfde3f9200672
+ 78be8cdf4f0bfd93018fd7a87f8282a41d041298
-
+
https://github.com/dotnet/emsdk
- 763d10a1a251be35337ee736832bfde3f9200672
+ 78be8cdf4f0bfd93018fd7a87f8282a41d041298
-
+
https://github.com/dotnet/source-build-reference-packages
- c43ee853e96528e2f2eb0f6d8c151ddc07b6a844
+ 1cec3b4a8fb07138136a1ca1e04763bfcf7841db
-
+
https://github.com/dotnet/source-build-externals
- 4df883d781a4290873b3b968afc0ff0df7132507
+ ab469606a3e6b026dcac301e2dab96117c94faeb
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
-
+
https://github.com/dotnet/llvm-project
- 966011b3b666d1bf58d86666add23a9d401ee26a
+ f98a0db595fe3f28dac4594acc7114b16281d090
https://github.com/dotnet/runtime
@@ -320,21 +320,21 @@
https://github.com/dotnet/runtime
b030c4dfdfa1bf287f10f96006619a06bc2000ae
-
+
https://github.com/dotnet/xharness
- 9794254fa909ff5adc46326e9b54009793f61dcd
+ edc52ac68c1bf77e3b107fc8a448674a6d058d8a
-
+
https://github.com/dotnet/xharness
- 9794254fa909ff5adc46326e9b54009793f61dcd
+ edc52ac68c1bf77e3b107fc8a448674a6d058d8a
-
+
https://github.com/dotnet/xharness
- 9794254fa909ff5adc46326e9b54009793f61dcd
+ edc52ac68c1bf77e3b107fc8a448674a6d058d8a
-
+
https://github.com/dotnet/arcade
- 3c393bbd85ae16ddddba20d0b75035b0c6f1a52d
+ f33d9e642f0e68a61312164cd9e0baf4e142a999
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
@@ -352,48 +352,48 @@
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
9d7532585ce71e30ab55f0364d3cecccaf0775d1
-
+
https://github.com/dotnet/hotreload-utils
- bf7e87a8574449a441bf905e2acd38e4aa25b3d4
+ fd21b154f1152569e7fa49a4e030927eccbf4aaa
-
+
https://github.com/dotnet/runtime-assets
- e98370e661a19bdfed31eefb8740ecfad255f9ed
+ 739921bd3405841c06d3f74701c9e6ccfbd19e2e
-
+
https://github.com/dotnet/roslyn
- 3bff3622487486dec7794dfd0c71e05a52c313a4
+ 3f5cf9fbbd91f2047e988801a5142ca1cb6bab45
-
+
https://github.com/dotnet/roslyn
- 3bff3622487486dec7794dfd0c71e05a52c313a4
+ 3f5cf9fbbd91f2047e988801a5142ca1cb6bab45
-
+
https://github.com/dotnet/roslyn
- 3bff3622487486dec7794dfd0c71e05a52c313a4
+ 3f5cf9fbbd91f2047e988801a5142ca1cb6bab45
-
+
https://github.com/dotnet/roslyn-analyzers
- 3d61c57c73c3dd5f1f407ef9cd3414d94bf0eaf2
+ 16865ea61910500f1022ad2b96c499e5df02c228
-
+
https://github.com/dotnet/roslyn-analyzers
- 3d61c57c73c3dd5f1f407ef9cd3414d94bf0eaf2
+ 16865ea61910500f1022ad2b96c499e5df02c228
-
+
https://github.com/dotnet/roslyn
- 3bff3622487486dec7794dfd0c71e05a52c313a4
+ 3f5cf9fbbd91f2047e988801a5142ca1cb6bab45
-
+
https://github.com/dotnet/sdk
- 5b9d9d4677ea31d954533e9de2f95a3ea638135d
+ 346d06baea1cf7113e181e779b056b955973c633
-
+
https://github.com/dotnet/sdk
- 5b9d9d4677ea31d954533e9de2f95a3ea638135d
+ 346d06baea1cf7113e181e779b056b955973c633
diff --git a/eng/Versions.props b/eng/Versions.props
index 24c0c9e1048042..8ba353723841c2 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -1,16 +1,16 @@
- 9.0.0
+ 9.0.4
9
0
- 0
+ 4
9.0.100
- 8.0.11
+ 8.0.$([MSBuild]::Add($(PatchVersion),11))
7.0.20
6.0.36
- rtm
+ servicing
@@ -36,17 +36,17 @@
- 3.11.0-beta1.24508.2
- 9.0.0-preview.24508.2
+ 3.11.0-beta1.25123.3
+ 9.0.0-preview.25123.3
- 4.12.0-3.24516.15
- 4.12.0-3.24516.15
- 4.12.0-3.24516.15
+ 4.12.0-3.25124.2
+ 4.12.0-3.25124.2
+ 4.12.0-3.25124.2
- 9.0.100-rtm.24512.1
+ 9.0.104
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
- 2.9.0-beta.24516.2
- 9.0.0-beta.24516.2
- 2.9.0-beta.24516.2
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
- 9.0.0-beta.24516.2
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 2.9.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 2.9.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
+ 9.0.0-beta.25161.4
1.4.0
@@ -141,20 +141,20 @@
8.0.0
8.0.0
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
- 9.0.0-beta.24459.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
+ 9.0.0-beta.25113.2
1.0.0-prerelease.24462.2
1.0.0-prerelease.24462.2
@@ -164,7 +164,7 @@
1.0.0-prerelease.24462.2
2.0.0
- 17.10.0-beta1.24272.1
+ 17.12.0-beta1.24603.5
2.0.0-beta4.24324.3
3.1.7
2.1.0
@@ -184,10 +184,10 @@
1.4.0
17.4.0-preview-20220707-01
- 9.0.0-prerelease.24405.1
- 9.0.0-prerelease.24405.1
- 9.0.0-prerelease.24405.1
- 9.0.0-alpha.0.24514.3
+ 9.0.0-prerelease.25113.3
+ 9.0.0-prerelease.25113.3
+ 9.0.0-prerelease.25113.3
+ 9.0.0-alpha.0.25153.2
3.12.0
4.5.0
6.0.0
@@ -215,54 +215,55 @@
9.0.0-preview-20241010.1
- 0.11.5-alpha.24515.1
+ 0.11.5-alpha.25112.2
9.0.0-rtm.24511.16
- 9.0.0-rtm.24516.3
+ 9.0.0-rtm.25157.1
9.0.0-rtm.24466.4
- 2.4.3
+ 2.4.8
9.0.0-alpha.1.24167.3
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
- 9.0.0-rtm.24528.2
- 9.0.0
+ 9.0.4-servicing.25157.2
+ 9.0.4
$(MicrosoftNETWorkloadEmscriptenCurrentManifest90100Version)
1.1.87-gba258badda
1.0.0-v3.14.0.5722
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
- 19.1.0-alpha.1.24519.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
+ 19.1.0-alpha.1.25113.2
3.1.7
1.0.406601
$(MicrosoftDotNetApiCompatTaskVersion)
+
9.0.0-alpha.1.24175.1
$(MicrosoftNETRuntimeEmscriptenVersion)
$(runtimewinx64MicrosoftNETCoreRuntimeWasmNodeTransportPackageVersion)
diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml
index d938b60e1bb534..56a090094824f4 100644
--- a/eng/common/core-templates/steps/generate-sbom.yml
+++ b/eng/common/core-templates/steps/generate-sbom.yml
@@ -38,7 +38,7 @@ steps:
PackageName: ${{ parameters.packageName }}
BuildDropPath: ${{ parameters.buildDropPath }}
PackageVersion: ${{ parameters.packageVersion }}
- ManifestDirPath: ${{ parameters.manifestDirPath }}
+ ManifestDirPath: ${{ parameters.manifestDirPath }}/$(ARTIFACT_NAME)
${{ if ne(parameters.IgnoreDirectories, '') }}:
AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}'
diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake
index 9a4e285a5ae3f0..9a7ecfbd42c5f3 100644
--- a/eng/common/cross/toolchain.cmake
+++ b/eng/common/cross/toolchain.cmake
@@ -40,7 +40,7 @@ if(TARGET_ARCH_NAME STREQUAL "arm")
set(TOOLCHAIN "arm-linux-gnueabihf")
endif()
if(TIZEN)
- set(TIZEN_TOOLCHAIN "armv7hl-tizen-linux-gnueabihf/9.2.0")
+ set(TIZEN_TOOLCHAIN "armv7hl-tizen-linux-gnueabihf")
endif()
elseif(TARGET_ARCH_NAME STREQUAL "arm64")
set(CMAKE_SYSTEM_PROCESSOR aarch64)
@@ -49,7 +49,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "arm64")
elseif(LINUX)
set(TOOLCHAIN "aarch64-linux-gnu")
if(TIZEN)
- set(TIZEN_TOOLCHAIN "aarch64-tizen-linux-gnu/9.2.0")
+ set(TIZEN_TOOLCHAIN "aarch64-tizen-linux-gnu")
endif()
elseif(FREEBSD)
set(triple "aarch64-unknown-freebsd12")
@@ -58,7 +58,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "armel")
set(CMAKE_SYSTEM_PROCESSOR armv7l)
set(TOOLCHAIN "arm-linux-gnueabi")
if(TIZEN)
- set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi/9.2.0")
+ set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi")
endif()
elseif(TARGET_ARCH_NAME STREQUAL "armv6")
set(CMAKE_SYSTEM_PROCESSOR armv6l)
@@ -81,7 +81,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "riscv64")
else()
set(TOOLCHAIN "riscv64-linux-gnu")
if(TIZEN)
- set(TIZEN_TOOLCHAIN "riscv64-tizen-linux-gnu/13.1.0")
+ set(TIZEN_TOOLCHAIN "riscv64-tizen-linux-gnu")
endif()
endif()
elseif(TARGET_ARCH_NAME STREQUAL "s390x")
@@ -98,7 +98,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "x64")
elseif(LINUX)
set(TOOLCHAIN "x86_64-linux-gnu")
if(TIZEN)
- set(TIZEN_TOOLCHAIN "x86_64-tizen-linux-gnu/9.2.0")
+ set(TIZEN_TOOLCHAIN "x86_64-tizen-linux-gnu")
endif()
elseif(FREEBSD)
set(triple "x86_64-unknown-freebsd12")
@@ -115,7 +115,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "x86")
set(TOOLCHAIN "i686-linux-gnu")
endif()
if(TIZEN)
- set(TIZEN_TOOLCHAIN "i586-tizen-linux-gnu/9.2.0")
+ set(TIZEN_TOOLCHAIN "i586-tizen-linux-gnu")
endif()
else()
message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm, arm64, armel, armv6, ppc64le, riscv64, s390x, x64 and x86 are supported!")
@@ -127,30 +127,25 @@ endif()
# Specify include paths
if(TIZEN)
- if(TARGET_ARCH_NAME STREQUAL "arm")
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/)
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/armv7hl-tizen-linux-gnueabihf)
- endif()
- if(TARGET_ARCH_NAME STREQUAL "armel")
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/)
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/armv7l-tizen-linux-gnueabi)
- endif()
- if(TARGET_ARCH_NAME STREQUAL "arm64")
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/)
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/aarch64-tizen-linux-gnu)
- endif()
- if(TARGET_ARCH_NAME STREQUAL "x86")
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/)
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/i586-tizen-linux-gnu)
- endif()
- if(TARGET_ARCH_NAME STREQUAL "x64")
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/)
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/x86_64-tizen-linux-gnu)
- endif()
- if(TARGET_ARCH_NAME STREQUAL "riscv64")
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/)
- include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/riscv64-tizen-linux-gnu)
+ function(find_toolchain_dir prefix)
+ # Dynamically find the version subdirectory
+ file(GLOB DIRECTORIES "${prefix}/*")
+ list(GET DIRECTORIES 0 FIRST_MATCH)
+ get_filename_component(TOOLCHAIN_VERSION ${FIRST_MATCH} NAME)
+
+ set(TIZEN_TOOLCHAIN_PATH "${prefix}/${TOOLCHAIN_VERSION}" PARENT_SCOPE)
+ endfunction()
+
+ if(TARGET_ARCH_NAME MATCHES "^(arm|armel|x86)$")
+ find_toolchain_dir("${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}")
+ else()
+ find_toolchain_dir("${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}")
endif()
+
+ message(STATUS "TIZEN_TOOLCHAIN_PATH set to: ${TIZEN_TOOLCHAIN_PATH}")
+
+ include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++)
+ include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++/${TIZEN_TOOLCHAIN})
endif()
if(ANDROID)
@@ -272,21 +267,21 @@ endif()
if(TARGET_ARCH_NAME MATCHES "^(arm|armel)$")
if(TIZEN)
- add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}")
+ add_toolchain_linker_flag("-B${TIZEN_TOOLCHAIN_PATH}")
add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib")
add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib")
- add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}")
+ add_toolchain_linker_flag("-L${TIZEN_TOOLCHAIN_PATH}")
endif()
elseif(TARGET_ARCH_NAME MATCHES "^(arm64|x64|riscv64)$")
if(TIZEN)
- add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}")
+ add_toolchain_linker_flag("-B${TIZEN_TOOLCHAIN_PATH}")
add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib64")
add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64")
- add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}")
+ add_toolchain_linker_flag("-L${TIZEN_TOOLCHAIN_PATH}")
add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/lib64")
add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64")
- add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}")
+ add_toolchain_linker_flag("-Wl,--rpath-link=${TIZEN_TOOLCHAIN_PATH}")
endif()
elseif(TARGET_ARCH_NAME STREQUAL "s390x")
add_toolchain_linker_flag("--target=${TOOLCHAIN}")
@@ -297,10 +292,10 @@ elseif(TARGET_ARCH_NAME STREQUAL "x86")
endif()
add_toolchain_linker_flag(-m32)
if(TIZEN)
- add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}")
+ add_toolchain_linker_flag("-B${TIZEN_TOOLCHAIN_PATH}")
add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib")
add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib")
- add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}")
+ add_toolchain_linker_flag("-L${TIZEN_TOOLCHAIN_PATH}")
endif()
elseif(ILLUMOS)
add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib/amd64")
diff --git a/eng/common/generate-sbom-prep.ps1 b/eng/common/generate-sbom-prep.ps1
index 3e5c1c74a1c50d..a0c7d792a76fbe 100644
--- a/eng/common/generate-sbom-prep.ps1
+++ b/eng/common/generate-sbom-prep.ps1
@@ -4,18 +4,26 @@ Param(
. $PSScriptRoot\pipeline-logging-functions.ps1
+# Normally - we'd listen to the manifest path given, but 1ES templates will overwrite if this level gets uploaded directly
+# with their own overwriting ours. So we create it as a sub directory of the requested manifest path.
+$ArtifactName = "${env:SYSTEM_STAGENAME}_${env:AGENT_JOBNAME}_SBOM"
+$SafeArtifactName = $ArtifactName -replace '["/:<>\\|?@*"() ]', '_'
+$SbomGenerationDir = Join-Path $ManifestDirPath $SafeArtifactName
+
+Write-Host "Artifact name before : $ArtifactName"
+Write-Host "Artifact name after : $SafeArtifactName"
+
Write-Host "Creating dir $ManifestDirPath"
+
# create directory for sbom manifest to be placed
-if (!(Test-Path -path $ManifestDirPath))
+if (!(Test-Path -path $SbomGenerationDir))
{
- New-Item -ItemType Directory -path $ManifestDirPath
- Write-Host "Successfully created directory $ManifestDirPath"
+ New-Item -ItemType Directory -path $SbomGenerationDir
+ Write-Host "Successfully created directory $SbomGenerationDir"
}
else{
Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder."
}
Write-Host "Updating artifact name"
-$artifact_name = "${env:SYSTEM_STAGENAME}_${env:AGENT_JOBNAME}_SBOM" -replace '["/:<>\\|?@*"() ]', '_'
-Write-Host "Artifact name $artifact_name"
-Write-Host "##vso[task.setvariable variable=ARTIFACT_NAME]$artifact_name"
+Write-Host "##vso[task.setvariable variable=ARTIFACT_NAME]$SafeArtifactName"
diff --git a/eng/common/generate-sbom-prep.sh b/eng/common/generate-sbom-prep.sh
index d5c76dc827b496..b8ecca72bbf506 100644
--- a/eng/common/generate-sbom-prep.sh
+++ b/eng/common/generate-sbom-prep.sh
@@ -14,19 +14,24 @@ done
scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
. $scriptroot/pipeline-logging-functions.sh
+
+# replace all special characters with _, some builds use special characters like : in Agent.Jobname, that is not a permissible name while uploading artifacts.
+artifact_name=$SYSTEM_STAGENAME"_"$AGENT_JOBNAME"_SBOM"
+safe_artifact_name="${artifact_name//["/:<>\\|?@*$" ]/_}"
manifest_dir=$1
-if [ ! -d "$manifest_dir" ] ; then
- mkdir -p "$manifest_dir"
- echo "Sbom directory created." $manifest_dir
+# Normally - we'd listen to the manifest path given, but 1ES templates will overwrite if this level gets uploaded directly
+# with their own overwriting ours. So we create it as a sub directory of the requested manifest path.
+sbom_generation_dir="$manifest_dir/$safe_artifact_name"
+
+if [ ! -d "$sbom_generation_dir" ] ; then
+ mkdir -p "$sbom_generation_dir"
+ echo "Sbom directory created." $sbom_generation_dir
else
Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder."
fi
-artifact_name=$SYSTEM_STAGENAME"_"$AGENT_JOBNAME"_SBOM"
echo "Artifact name before : "$artifact_name
-# replace all special characters with _, some builds use special characters like : in Agent.Jobname, that is not a permissible name while uploading artifacts.
-safe_artifact_name="${artifact_name//["/:<>\\|?@*$" ]/_}"
echo "Artifact name after : "$safe_artifact_name
export ARTIFACT_NAME=$safe_artifact_name
echo "##vso[task.setvariable variable=ARTIFACT_NAME]$safe_artifact_name"
diff --git a/eng/common/internal/Tools.csproj b/eng/common/internal/Tools.csproj
index 32f79dfb3402c0..feaa6d20812d8f 100644
--- a/eng/common/internal/Tools.csproj
+++ b/eng/common/internal/Tools.csproj
@@ -15,16 +15,6 @@
-
-
-
- https://devdiv.pkgs.visualstudio.com/_packaging/dotnet-core-internal-tooling/nuget/v3/index.json;
-
-
- $(RestoreSources);
- https://devdiv.pkgs.visualstudio.com/_packaging/VS/nuget/v3/index.json;
-
-
diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1
index aab40de3fd9aca..4f0546dce1208d 100644
--- a/eng/common/sdk-task.ps1
+++ b/eng/common/sdk-task.ps1
@@ -64,7 +64,7 @@ try {
$GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty
}
if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) {
- $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.10.0-pre.4.0" -MemberType NoteProperty
+ $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.12.0" -MemberType NoteProperty
}
if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") {
$xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true
diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md
index 5ef6c30ba92465..98bbc1ded0ba88 100644
--- a/eng/common/template-guidance.md
+++ b/eng/common/template-guidance.md
@@ -57,7 +57,7 @@ extends:
Note: Multiple outputs are ONLY applicable to 1ES PT publishing (only usable when referencing `templates-official`).
-# Development notes
+## Development notes
**Folder / file structure**
diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml
index 605692d2fb770c..817555505aa602 100644
--- a/eng/common/templates-official/job/job.yml
+++ b/eng/common/templates-official/job/job.yml
@@ -16,6 +16,7 @@ jobs:
parameters:
PackageVersion: ${{ parameters.packageVersion }}
BuildDropPath: ${{ parameters.buildDropPath }}
+ ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
publishArtifacts: false
# publish artifacts
diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1
index 22954477a5747f..a46b6deb75986b 100644
--- a/eng/common/tools.ps1
+++ b/eng/common/tools.ps1
@@ -320,7 +320,7 @@ function InstallDotNet([string] $dotnetRoot,
$variations += @($installParameters)
$dotnetBuilds = $installParameters.Clone()
- $dotnetbuilds.AzureFeed = "https://dotnetbuilds.azureedge.net/public"
+ $dotnetbuilds.AzureFeed = "https://ci.dot.net/public"
$variations += @($dotnetBuilds)
if ($runtimeSourceFeed) {
@@ -383,8 +383,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements =
# If the version of msbuild is going to be xcopied,
# use this version. Version matches a package here:
- # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.10.0-pre.4.0
- $defaultXCopyMSBuildVersion = '17.10.0-pre.4.0'
+ # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.12.0
+ $defaultXCopyMSBuildVersion = '17.12.0'
if (!$vsRequirements) {
if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') {
diff --git a/eng/common/tools.sh b/eng/common/tools.sh
index 00473c9f918d47..1159726a10fd6f 100755
--- a/eng/common/tools.sh
+++ b/eng/common/tools.sh
@@ -232,7 +232,7 @@ function InstallDotNet {
local public_location=("${installParameters[@]}")
variations+=(public_location)
- local dotnetbuilds=("${installParameters[@]}" --azure-feed "https://dotnetbuilds.azureedge.net/public")
+ local dotnetbuilds=("${installParameters[@]}" --azure-feed "https://ci.dot.net/public")
variations+=(dotnetbuilds)
if [[ -n "${6:-}" ]]; then
diff --git a/eng/install-native-dependencies.sh b/eng/install-native-dependencies.sh
index 41895e0b9254c8..f8c9db632860de 100755
--- a/eng/install-native-dependencies.sh
+++ b/eng/install-native-dependencies.sh
@@ -44,7 +44,7 @@ case "$os" in
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
# Skip brew update for now, see https://github.com/actions/setup-python/issues/577
# brew update --preinstall
- brew bundle --no-upgrade --no-lock --file "$(dirname "$0")/Brewfile"
+ brew bundle --no-upgrade --file "$(dirname "$0")/Brewfile"
;;
*)
diff --git a/eng/packaging.targets b/eng/packaging.targets
index 99912459fe02c1..a14c954df54dbc 100644
--- a/eng/packaging.targets
+++ b/eng/packaging.targets
@@ -27,8 +27,6 @@
PACKAGE.md
$(BeforePack);ValidatePackageReadmeExists
-
- false
true
-
- true
false
@@ -58,18 +48,6 @@
$(NoWarn);CP0003
-
-
- 0
-
-
- $(MajorVersion).$(MinorVersion).$(ServicingVersion)
- $(Version)-$(VersionSuffix)
-
-
@@ -155,7 +133,7 @@
- <_RuntimeSymbolPath Include="$(RuntimeSymbolPath)" />
+ <_RuntimeSymbolPath Include="@(TfmRuntimeSpecificPackageFile->'%(RootDir)%(Directory)%(FileName).pdb')" Condition="'%(TfmRuntimeSpecificPackageFile.Extension)' == '.dll'" KeepMetadata="None" />
-
-
-
-
diff --git a/eng/pipelines/common/templates/pipeline-with-resources.yml b/eng/pipelines/common/templates/pipeline-with-resources.yml
index cf2b9f53e528b5..90851b8d725ee6 100644
--- a/eng/pipelines/common/templates/pipeline-with-resources.yml
+++ b/eng/pipelines/common/templates/pipeline-with-resources.yml
@@ -17,7 +17,7 @@ extends:
containers:
linux_arm:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-arm
env:
ROOTFS_DIR: /crossrootfs/arm
@@ -27,44 +27,44 @@ extends:
ROOTFS_DIR: /crossrootfs/armv6
linux_arm64:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm64-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-arm64
env:
ROOTFS_DIR: /crossrootfs/arm64
linux_musl_x64:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-alpine-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-amd64-alpine
env:
ROOTFS_DIR: /crossrootfs/x64
linux_musl_arm:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm-alpine-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-arm-alpine
env:
ROOTFS_DIR: /crossrootfs/arm
linux_musl_arm64:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-arm64-alpine-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-arm64-alpine
env:
ROOTFS_DIR: /crossrootfs/arm64
# This container contains all required toolsets to build for Android and for Linux with bionic libc.
android:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-android-amd64-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-android-amd64
# This container contains all required toolsets to build for Android and for Linux with bionic libc and a special layout of OpenSSL.
linux_bionic:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-android-openssl-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-android-openssl
# This container contains all required toolsets to build for Android as well as tooling to build docker images.
android_docker:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-android-docker-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-android-docker
linux_x64:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-amd64
env:
ROOTFS_DIR: /crossrootfs/x64
linux_x86:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-x86-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-x86
env:
ROOTFS_DIR: /crossrootfs/x86
@@ -75,7 +75,7 @@ extends:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.19-WithNode
linux_x64_sanitizer:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-amd64-net9.0-sanitizer
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-amd64-sanitizer
env:
ROOTFS_DIR: /crossrootfs/x64
@@ -88,17 +88,17 @@ extends:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:almalinux-8-source-build
linux_s390x:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-s390x-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-s390x
env:
ROOTFS_DIR: /crossrootfs/s390x
linux_ppc64le:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-ppc64le-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-ppc64le
env:
ROOTFS_DIR: /crossrootfs/ppc64le
linux_riscv64:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-riscv64-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-riscv64
env:
ROOTFS_DIR: /crossrootfs/riscv64
@@ -109,17 +109,17 @@ extends:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8
browser_wasm:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-webassembly-amd64-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-webassembly-amd64
env:
ROOTFS_DIR: /crossrootfs/x64
wasi_wasm:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-webassembly-amd64-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-webassembly-amd64
env:
ROOTFS_DIR: /crossrootfs/x64
freebsd_x64:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-cross-freebsd-13-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-cross-freebsd-13
env:
ROOTFS_DIR: /crossrootfs/x64
@@ -132,4 +132,4 @@ extends:
image: mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-debpkg
rpmpkg:
- image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-fpm-net9.0
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net9.0-fpm
diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml
index f50a2db9e81ec5..39676f8fd9b292 100644
--- a/eng/pipelines/common/xplat-setup.yml
+++ b/eng/pipelines/common/xplat-setup.yml
@@ -170,12 +170,12 @@ jobs:
# OSX Public Build Pool (we don't have on-prem OSX BuildPool).
${{ if and(in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator'), eq(variables['System.TeamProject'], 'public')) }}:
- vmImage: 'macos-12'
+ vmImage: 'macos-13'
# OSX Internal Pool
${{ if and(in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator'), ne(variables['System.TeamProject'], 'public')) }}:
name: "Azure Pipelines"
- vmImage: 'macOS-12'
+ vmImage: 'macOS-13'
os: macOS
# Official Build Windows Pool
diff --git a/eng/pipelines/coreclr/perf-non-wasm-jobs.yml b/eng/pipelines/coreclr/perf-non-wasm-jobs.yml
index df9c99e5297d63..78b035fa0228ea 100644
--- a/eng/pipelines/coreclr/perf-non-wasm-jobs.yml
+++ b/eng/pipelines/coreclr/perf-non-wasm-jobs.yml
@@ -374,7 +374,7 @@ jobs:
nameSuffix: PerfBDNApp
isOfficialBuild: false
pool:
- vmImage: 'macos-12'
+ vmImage: 'macos-13'
postBuildSteps:
- template: /eng/pipelines/coreclr/templates/build-perf-bdn-app.yml
parameters:
diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml
index a9dae35f177eb4..815f297ff3060f 100644
--- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml
+++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml
@@ -63,37 +63,37 @@ jobs:
# Linux arm
- ${{ if eq(parameters.platform, 'linux_arm') }}:
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- - (Debian.12.Arm32.Open)Ubuntu.2004.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-helix-arm32v7
+ - (Debian.12.Arm32.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-helix-arm32v7
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- - (Debian.12.Arm32)Ubuntu.2004.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-helix-arm32v7
+ - (Debian.12.Arm32)Ubuntu.2204.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-helix-arm32v7
# Linux arm64
- ${{ if eq(parameters.platform, 'linux_arm64') }}:
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- - (Ubuntu.2004.Arm64.Open)Ubuntu.2004.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-helix-arm64v8
+ - (Ubuntu.2004.Arm64.Open)Ubuntu.2204.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-helix-arm64v8
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- - (Ubuntu.2004.Arm64)Ubuntu.2004.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-helix-arm64v8
+ - (Ubuntu.2004.Arm64)Ubuntu.2204.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-20.04-helix-arm64v8
# Linux musl x64
- ${{ if eq(parameters.platform, 'linux_musl_x64') }}:
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- - (Alpine.317.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-amd64
+ - (Alpine.321.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.21-helix-amd64
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- - (Alpine.317.Amd64)Ubuntu.2204.Amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-amd64
+ - (Alpine.321.Amd64)Ubuntu.2204.Amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.21-helix-amd64
# Linux musl arm32
- ${{ if eq(parameters.platform, 'linux_musl_arm') }}:
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- - (Alpine.316.Arm32.Open)Ubuntu.2004.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-arm32v7
+ - (Alpine.321.Arm32.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.21-helix-arm32v7
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- - (Alpine.316.Arm32)Ubuntu.2004.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-arm32v7
+ - (Alpine.321.Arm32)Ubuntu.2204.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.21-helix-arm32v7
# Linux musl arm64
- ${{ if eq(parameters.platform, 'linux_musl_arm64') }}:
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- - (Alpine.317.Arm64.Open)Ubuntu.2004.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-arm64v8
+ - (Alpine.320.Arm64.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.20-helix-arm64v8
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- - (Alpine.317.Arm64)Ubuntu.2004.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-arm64v8
+ - (Alpine.320.Arm64)Ubuntu.2204.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.20-helix-arm64v8
# Linux x64
- ${{ if eq(parameters.platform, 'linux_x64') }}:
diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml
index 5b660a70bf7680..d6c83bd12137da 100644
--- a/eng/pipelines/libraries/helix-queues-setup.yml
+++ b/eng/pipelines/libraries/helix-queues-setup.yml
@@ -26,31 +26,28 @@ jobs:
# Linux arm
- ${{ if eq(parameters.platform, 'linux_arm') }}:
- ${{ if or(eq(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- - (Debian.12.Arm32.Open)Ubuntu.2004.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-helix-arm32v7
+ - (Debian.12.Arm32.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-helix-arm32v7
# Linux armv6
- ${{ if eq(parameters.platform, 'linux_armv6') }}:
- - (Raspbian.10.Armv6.Open)Ubuntu.2004.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:raspbian-10-helix-arm32v6
+ - (Raspbian.10.Armv6.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:raspbian-10-helix-arm32v6
# Linux arm64
- ${{ if eq(parameters.platform, 'linux_arm64') }}:
- - (Ubuntu.2204.Arm64.Open)Ubuntu.2004.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-arm64v8
+ - (Ubuntu.2204.Arm64.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-arm64v8
- ${{ if or(ne(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- - (Debian.11.Arm64.Open)Ubuntu.2004.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm64v8
+ - (Debian.11.Arm64.Open)Ubuntu.2204.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm64v8
# Linux musl x64
- ${{ if eq(parameters.platform, 'linux_musl_x64') }}:
- ${{ if or(ne(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- - (Alpine.317.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-amd64
+ - (Alpine.321.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.21-helix-amd64
- ${{ if or(eq(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- - (Alpine.320.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.20-helix-amd64
- - (Alpine.318.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.18-helix-amd64
+ - (Alpine.321.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.21-helix-amd64
# Linux musl arm64
- ${{ if and(eq(parameters.platform, 'linux_musl_arm64'), or(eq(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true))) }}:
- (Alpine.320.Arm64.Open)ubuntu.2004.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.20-helix-arm64v8
- - (Alpine.318.Arm64.Open)ubuntu.2004.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.18-helix-arm64v8
- - (Alpine.317.Arm64.Open)ubuntu.2004.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.17-helix-arm64v8
# Linux x64
- ${{ if eq(parameters.platform, 'linux_x64') }}:
@@ -58,21 +55,21 @@ jobs:
- ${{ if and(eq(parameters.jobParameters.testScope, 'outerloop'), eq(parameters.jobParameters.runtimeFlavor, 'mono')) }}:
- SLES.15.Amd64.Open
- (Centos.8.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8-helix
- - (Fedora.38.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-38-helix
+ - (Fedora.41.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-41-helix
- (Ubuntu.2204.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-22.04-helix-amd64
- (Debian.11.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64
- ${{ if or(ne(parameters.jobParameters.testScope, 'outerloop'), ne(parameters.jobParameters.runtimeFlavor, 'mono')) }}:
- ${{ if or(eq(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- SLES.15.Amd64.Open
- - (Fedora.38.Amd64.Open)ubuntu.2204.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-38-helix
+ - (Fedora.41.Amd64.Open)ubuntu.2204.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-41-helix
- Ubuntu.2204.Amd64.Open
- - (Debian.11.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64
+ - (Debian.12.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-helix-amd64
- (Mariner.2.0.Amd64.Open)Ubuntu.2204.Amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-helix-amd64
- (AzureLinux.3.0.Amd64.Open)Ubuntu.2204.Amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-helix-amd64
- (openSUSE.15.2.Amd64.Open)Ubuntu.2204.Amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:opensuse-15.2-helix-amd64
- ${{ if or(ne(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- (Centos.8.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8-helix
- - (Debian.11.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64
+ - (Debian.12.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-12-helix-amd64
- Ubuntu.2204.Amd64.Open
- ${{ if or(eq(parameters.jobParameters.interpreter, 'true'), eq(parameters.jobParameters.isSingleFile, true)) }}:
# Limiting interp runs as we don't need as much coverage.
@@ -130,7 +127,6 @@ jobs:
- ${{ if ne(parameters.jobParameters.testScope, 'outerloop') }}:
- (Windows.10.Amd64.ServerRS5.Open)windows.10.amd64.serverrs5.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2019-helix-amd64
- ${{ if or(ne(parameters.jobParameters.isExtraPlatformsBuild, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- - Windows.81.Amd64.Open
- Windows.Amd64.Server2022.Open
- Windows.11.Amd64.Client.Open
- ${{ if eq(parameters.jobParameters.testScope, 'outerloop') }}:
@@ -180,6 +176,6 @@ jobs:
# Browser WebAssembly windows
- ${{ if in(parameters.platform, 'browser_wasm_win', 'wasi_wasm_win') }}:
- - (Windows.Amd64.Server2022.Open)windows.amd64.server2022.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2022-helix-webassembly-20240702174122-7aba2af
+ - (Windows.Amd64.Server2022.Open)windows.amd64.server2022.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2022-helix-webassembly
${{ insert }}: ${{ parameters.jobParameters }}
diff --git a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml
index eb25d311890a98..482e2cc2b1e6f5 100644
--- a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml
+++ b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml
@@ -8,6 +8,9 @@ jobs:
parameters:
name: 'PrepareSignedArtifacts'
displayName: 'Prepare Signed Artifacts'
+
+ # Disable SBOM at job template level
+ enableSbom: false
pool:
name: $(DncEngInternalBuildPool)
@@ -52,7 +55,11 @@ jobs:
/p:DotNetSignType=$(_SignType)
/bl:$(Build.SourcesDirectory)\prepare-artifacts.binlog
displayName: Prepare artifacts and upload to build
-
+
+ - template: /eng/common/templates-official/steps/generate-sbom.yml
+ parameters:
+ BuildDropPath: $(Build.SourcesDirectory)\artifacts
+
- task: CopyFiles@2
displayName: Copy Files to $(Build.StagingDirectory)\BuildLogs
inputs:
diff --git a/eng/pipelines/runtime-ioslike.yml b/eng/pipelines/runtime-ioslike.yml
index 1100ec500ce6ff..11477a3e175cba 100644
--- a/eng/pipelines/runtime-ioslike.yml
+++ b/eng/pipelines/runtime-ioslike.yml
@@ -4,6 +4,24 @@
trigger: none
+# To reduce the load on the pipeline, enable it only for PRs that affect Mono LLVM related code.
+pr:
+ branches:
+ include:
+ - main
+ - release/*.*
+
+ paths:
+ include:
+ - src/mono/mono/mini/aot-*.*
+ - src/mono/mono/mini/llvm-*.*
+ - src/mono/mono/mini/mini-llvm-*.*
+ - src/mono/mono/mini/intrinsics.c
+ - src/mono/mono/mini/simd-*.*
+ - src/mono/mono/mini/decompose.c
+ - src/mono/mono/mini/method-to-ir.c
+ - src/mono/mono/mini/mini.c
+
variables:
- template: /eng/pipelines/common/variables.yml
diff --git a/eng/pipelines/runtime-llvm.yml b/eng/pipelines/runtime-llvm.yml
index 5be2a5b063aaaa..6f3d16767ddbb3 100644
--- a/eng/pipelines/runtime-llvm.yml
+++ b/eng/pipelines/runtime-llvm.yml
@@ -28,6 +28,24 @@ schedules:
- main
always: false # run only if there were changes since the last successful scheduled run.
+# To reduce the load on the pipeline, enable it only for PRs that affect Mono LLVM related code.
+pr:
+ branches:
+ include:
+ - main
+ - release/*.*
+
+ paths:
+ include:
+ - src/mono/mono/mini/aot-*.*
+ - src/mono/mono/mini/llvm-*.*
+ - src/mono/mono/mini/mini-llvm-*.*
+ - src/mono/mono/mini/intrinsics.c
+ - src/mono/mono/mini/simd-*.*
+ - src/mono/mono/mini/decompose.c
+ - src/mono/mono/mini/method-to-ir.c
+ - src/mono/mono/mini/mini.c
+
variables:
- template: /eng/pipelines/common/variables.yml
diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml
index 55021be6e29ed4..e3c7dc5050005f 100644
--- a/eng/pipelines/runtime-official.yml
+++ b/eng/pipelines/runtime-official.yml
@@ -41,11 +41,11 @@ extends:
# Localization build
#
- - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/9.0') }}:
+ - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
- template: /eng/common/templates-official/job/onelocbuild.yml
parameters:
MirrorRepo: runtime
- MirrorBranch: release/9.0
+ MirrorBranch: main
LclSource: lclFilesfromPackage
LclPackageId: 'LCL-JUNO-PROD-RUNTIME'
@@ -661,7 +661,7 @@ extends:
flattenFolders: true
buildArgs: -s mono.workloads -c $(_BuildConfig) /p:PackageSource=$(Build.SourcesDirectory)/artifacts/workloadPackages /p:WorkloadOutputPath=$(Build.SourcesDirectory)/artifacts/workloads
-
+
postBuildSteps:
# Upload packages wrapping msis
- template: /eng/pipelines/common/upload-intermediate-artifacts-step.yml
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index bcab359dde5792..f06667f3e8e6e2 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -926,25 +926,25 @@ extends:
# WASI/WASM
- - template: /eng/pipelines/common/templates/wasm-library-tests.yml
- parameters:
- platforms:
- - wasi_wasm
- - wasi_wasm_win
- nameSuffix: '_Smoke'
- extraBuildArgs: /p:EnableAggressiveTrimming=true /p:RunWasmSamples=true /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS)
- shouldRunSmokeOnly: true
- alwaysRun: ${{ variables.isRollingBuild }}
- scenarios:
- - WasmTestOnWasmtime
-
- - 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/wasm-library-tests.yml
+ # parameters:
+ # platforms:
+ # - wasi_wasm
+ # - wasi_wasm_win
+ # nameSuffix: '_Smoke'
+ # extraBuildArgs: /p:EnableAggressiveTrimming=true /p:RunWasmSamples=true /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS)
+ # shouldRunSmokeOnly: true
+ # alwaysRun: ${{ variables.isRollingBuild }}
+ # scenarios:
+ # - WasmTestOnWasmtime
+
+ # - 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
diff --git a/eng/testing/scenarios/BuildWasiAppsJobsList.txt b/eng/testing/scenarios/BuildWasiAppsJobsList.txt
index 86c0517585a480..e69de29bb2d1d6 100644
--- a/eng/testing/scenarios/BuildWasiAppsJobsList.txt
+++ b/eng/testing/scenarios/BuildWasiAppsJobsList.txt
@@ -1,7 +0,0 @@
-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
diff --git a/global.json b/global.json
index 26b27962d3def5..ebf092e8e505d2 100644
--- a/global.json
+++ b/global.json
@@ -1,16 +1,16 @@
{
"sdk": {
- "version": "9.0.100-rc.2.24474.11",
+ "version": "9.0.104",
"allowPrerelease": true,
"rollForward": "major"
},
"tools": {
- "dotnet": "9.0.100-rc.2.24474.11"
+ "dotnet": "9.0.104"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24516.2",
- "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24516.2",
- "Microsoft.DotNet.SharedFramework.Sdk": "9.0.0-beta.24516.2",
+ "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25161.4",
+ "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.25161.4",
+ "Microsoft.DotNet.SharedFramework.Sdk": "9.0.0-beta.25161.4",
"Microsoft.Build.NoTargets": "3.7.0",
"Microsoft.Build.Traversal": "3.4.0",
"Microsoft.NET.Sdk.IL": "9.0.0-rtm.24511.16"
diff --git a/src/coreclr/.nuget/Directory.Build.props b/src/coreclr/.nuget/Directory.Build.props
index 4a765f85b5bdcc..6f4d7a0cfb51dc 100644
--- a/src/coreclr/.nuget/Directory.Build.props
+++ b/src/coreclr/.nuget/Directory.Build.props
@@ -19,11 +19,6 @@
true
-
-
- false
-
-
diff --git a/src/coreclr/.nuget/Directory.Build.targets b/src/coreclr/.nuget/Directory.Build.targets
index 379fbd65030b32..f30471ded8ae4f 100644
--- a/src/coreclr/.nuget/Directory.Build.targets
+++ b/src/coreclr/.nuget/Directory.Build.targets
@@ -4,7 +4,7 @@
$(ProductVersion)
- $(PackageVersion)
+ $(PackageVersion)
diff --git a/src/coreclr/debug/ee/controller.cpp b/src/coreclr/debug/ee/controller.cpp
index fd26e7fe3135dd..1738eb5862fee7 100644
--- a/src/coreclr/debug/ee/controller.cpp
+++ b/src/coreclr/debug/ee/controller.cpp
@@ -25,6 +25,11 @@ const char *GetTType( TraceType tt);
#define IsSingleStep(exception) ((exception) == EXCEPTION_SINGLE_STEP)
+typedef enum __TailCallFunctionType {
+ TailCallThatReturns = 1,
+ StoreTailCallArgs = 2
+} TailCallFunctionType;
+
// -------------------------------------------------------------------------
// DebuggerController routines
// -------------------------------------------------------------------------
@@ -5631,10 +5636,10 @@ static bool IsTailCallJitHelper(const BYTE * ip)
// control flow will be a little peculiar in that the function will return
// immediately, so we need special handling in the debugger for it. This
// function detects that case to be used for those scenarios.
-static bool IsTailCallThatReturns(const BYTE * ip, ControllerStackInfo* info)
+static bool IsTailCall(const BYTE * ip, ControllerStackInfo* info, TailCallFunctionType type)
{
MethodDesc* pTailCallDispatcherMD = TailCallHelp::GetTailCallDispatcherMD();
- if (pTailCallDispatcherMD == NULL)
+ if (pTailCallDispatcherMD == NULL && type == TailCallFunctionType::TailCallThatReturns)
{
return false;
}
@@ -5650,6 +5655,11 @@ static bool IsTailCallThatReturns(const BYTE * ip, ControllerStackInfo* info)
? trace.GetMethodDesc()
: g_pEEInterface->GetNativeCodeMethodDesc(trace.GetAddress());
+ if (type == TailCallFunctionType::StoreTailCallArgs)
+ {
+ return (pTargetMD && pTargetMD->IsDynamicMethod() && pTargetMD->AsDynamicMethodDesc()->GetILStubType() == DynamicMethodDesc::StubTailCallStoreArgs);
+ }
+
if (pTargetMD != pTailCallDispatcherMD)
{
return false;
@@ -5881,6 +5891,13 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
fCallingIntoFunclet = IsAddrWithinMethodIncludingFunclet(ji, info->m_activeFrame.md, walker.GetNextIP()) &&
((CORDB_ADDRESS)(SIZE_T)walker.GetNextIP() != ji->m_addrOfCode);
#endif
+ // If we are stepping into a tail call that uses the StoreTailCallArgs
+ // we need to enable the method enter, otherwise it will behave like a resume
+ if (in && IsTailCall(walker.GetNextIP(), info, TailCallFunctionType::StoreTailCallArgs))
+ {
+ EnableMethodEnter();
+ return true;
+ }
// At this point, we know that the call/branch target is not
// in the current method. The possible cases is that this is
// a jump or a tailcall-via-helper. There are two separate
@@ -5892,7 +5909,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
// is done by stepping out to the previous user function
// (non IL stub).
if ((fIsJump && !fCallingIntoFunclet) || IsTailCallJitHelper(walker.GetNextIP()) ||
- IsTailCallThatReturns(walker.GetNextIP(), info))
+ IsTailCall(walker.GetNextIP(), info, TailCallFunctionType::TailCallThatReturns))
{
// A step-over becomes a step-out for a tail call.
if (!in)
@@ -6038,7 +6055,7 @@ bool DebuggerStepper::TrapStep(ControllerStackInfo *info, bool in)
return true;
}
- if (IsTailCallJitHelper(walker.GetNextIP()) || IsTailCallThatReturns(walker.GetNextIP(), info))
+ if (IsTailCallJitHelper(walker.GetNextIP()) || IsTailCall(walker.GetNextIP(), info, TailCallFunctionType::TailCallThatReturns))
{
if (!in)
{
@@ -7410,7 +7427,15 @@ bool DebuggerStepper::TriggerSingleStep(Thread *thread, const BYTE *ip)
if (!g_pEEInterface->IsManagedNativeCode(ip))
{
LOG((LF_CORDB,LL_INFO10000, "DS::TSS: not in managed code, Returning false (case 0)!\n"));
- DisableSingleStep();
+ // Sometimes we can get here with a callstack that is coming from an APC
+ // this will disable the single stepping and incorrectly resume an app that the user
+ // is stepping through.
+#ifdef FEATURE_THREAD_ACTIVATION
+ if ((thread->m_State & Thread::TS_DebugWillSync) == 0)
+#endif
+ {
+ DisableSingleStep();
+ }
return false;
}
diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp
index 217e90d38c0228..9336ae7363631a 100644
--- a/src/coreclr/gc/gc.cpp
+++ b/src/coreclr/gc/gc.cpp
@@ -2890,10 +2890,14 @@ bool gc_heap::trigger_initial_gen2_p = false;
#ifdef BACKGROUND_GC
bool gc_heap::trigger_bgc_for_rethreading_p = false;
+int gc_heap::total_bgc_threads = 0;
+int gc_heap::last_bgc_n_heaps = 0;
+int gc_heap::last_total_bgc_threads = 0;
#endif //BACKGROUND_GC
#ifdef STRESS_DYNAMIC_HEAP_COUNT
int gc_heap::heaps_in_this_gc = 0;
+int gc_heap::bgc_to_ngc2_ratio = 0;
#endif //STRESS_DYNAMIC_HEAP_COUNT
#endif // DYNAMIC_HEAP_COUNT
@@ -6404,7 +6408,11 @@ class heap_select
if (GCToOSInterface::CanGetCurrentProcessorNumber())
{
uint32_t proc_no = GCToOSInterface::GetCurrentProcessorNumber();
- proc_no_to_heap_no[proc_no] = (uint16_t)heap_number;
+ // For a 32-bit process running on a machine with > 64 procs,
+ // even though the process can only use up to 32 procs, the processor
+ // index can be >= 64; or in the cpu group case, if the process is not running in cpu group #0,
+ // the GetCurrentProcessorNumber will return a number that's >= 64.
+ proc_no_to_heap_no[proc_no % MAX_SUPPORTED_CPUS] = (uint16_t)heap_number;
}
}
@@ -6426,7 +6434,11 @@ class heap_select
if (GCToOSInterface::CanGetCurrentProcessorNumber())
{
uint32_t proc_no = GCToOSInterface::GetCurrentProcessorNumber();
- int adjusted_heap = proc_no_to_heap_no[proc_no];
+ // For a 32-bit process running on a machine with > 64 procs,
+ // even though the process can only use up to 32 procs, the processor
+ // index can be >= 64; or in the cpu group case, if the process is not running in cpu group #0,
+ // the GetCurrentProcessorNumber will return a number that's >= 64.
+ int adjusted_heap = proc_no_to_heap_no[proc_no % MAX_SUPPORTED_CPUS];
// with dynamic heap count, need to make sure the value is in range.
if (adjusted_heap >= gc_heap::n_heaps)
{
@@ -14182,6 +14194,11 @@ HRESULT gc_heap::initialize_gc (size_t soh_segment_size,
if ((dynamic_adaptation_mode == dynamic_adaptation_to_application_sizes) && (conserve_mem_setting == 0))
conserve_mem_setting = 5;
+
+#ifdef STRESS_DYNAMIC_HEAP_COUNT
+ bgc_to_ngc2_ratio = (int)GCConfig::GetGCDBGCRatio();
+ dprintf (1, ("bgc_to_ngc2_ratio is %d", bgc_to_ngc2_ratio));
+#endif
#endif //DYNAMIC_HEAP_COUNT
if (conserve_mem_setting < 0)
@@ -21071,6 +21088,18 @@ int gc_heap::joined_generation_to_condemn (BOOL should_evaluate_elevation,
if (!((n == max_generation) && *blocking_collection_p))
{
n = max_generation;
+
+#ifdef STRESS_DYNAMIC_HEAP_COUNT
+ if (bgc_to_ngc2_ratio)
+ {
+ int r = (int)gc_rand::get_rand ((bgc_to_ngc2_ratio + 1) * 10);
+ dprintf (6666, ("%d - making this full GC %s", r, ((r < 10) ? "NGC2" : "BGC")));
+ if (r < 10)
+ {
+ *blocking_collection_p = TRUE;
+ }
+ }
+#endif //STRESS_DYNAMIC_HEAP_COUNT
}
}
}
@@ -24332,12 +24361,37 @@ void gc_heap::garbage_collect (int n)
size_t saved_bgc_th_count_creation_failed = bgc_th_count_creation_failed;
#endif //DYNAMIC_HEAP_COUNT
+ // This is the count of threads that GCToEEInterface::CreateThread reported successful for.
+ int total_bgc_threads_running = 0;
for (int i = 0; i < n_heaps; i++)
{
- prepare_bgc_thread (g_heaps[i]);
+ gc_heap* hp = g_heaps[i];
+ if (prepare_bgc_thread (hp))
+ {
+ assert (hp->bgc_thread_running);
+ if (!hp->bgc_thread_running)
+ {
+ dprintf (6666, ("h%d prepare succeeded but running is still false!", i));
+ GCToOSInterface::DebugBreak();
+ }
+ total_bgc_threads_running++;
+ }
+ else
+ {
+ break;
+ }
}
#ifdef DYNAMIC_HEAP_COUNT
+ // Even if we don't do a BGC, we need to record how many threads were successfully created because those will
+ // be running.
+ total_bgc_threads = max (total_bgc_threads, total_bgc_threads_running);
+
+ if (total_bgc_threads_running != n_heaps)
+ {
+ dprintf (6666, ("wanted to have %d BGC threads but only have %d", n_heaps, total_bgc_threads_running));
+ }
+
add_to_bgc_th_creation_history (current_gc_index,
(bgc_th_count_created - saved_bgc_th_count_created),
(bgc_th_count_created_th_existed - saved_bgc_th_count_created_th_existed),
@@ -24369,7 +24423,15 @@ void gc_heap::garbage_collect (int n)
for (int i = 0; i < n_heaps; i++)
{
gc_heap* hp = g_heaps[i];
- if (!(hp->bgc_thread) || !hp->commit_mark_array_bgc_init())
+
+ if (!(hp->bgc_thread_running))
+ {
+ assert (!(hp->bgc_thread));
+ }
+
+ // In theory we could be in a situation where bgc_thread_running is false but bgc_thread is non NULL. We don't
+ // support this scenario so don't do a BGC.
+ if (!(hp->bgc_thread_running && hp->bgc_thread && hp->commit_mark_array_bgc_init()))
{
do_concurrent_p = FALSE;
break;
@@ -24389,8 +24451,37 @@ void gc_heap::garbage_collect (int n)
}
#endif //MULTIPLE_HEAPS
+#ifdef DYNAMIC_HEAP_COUNT
+ dprintf (6666, ("last BGC saw %d heaps and %d total threads, currently %d heaps and %d total threads, %s BGC",
+ last_bgc_n_heaps, last_total_bgc_threads, n_heaps, total_bgc_threads, (do_concurrent_p ? "doing" : "not doing")));
+#endif //DYNAMIC_HEAP_COUNT
+
if (do_concurrent_p)
{
+#ifdef DYNAMIC_HEAP_COUNT
+ int diff = n_heaps - last_bgc_n_heaps;
+ if (diff > 0)
+ {
+ int saved_idle_bgc_thread_count = dynamic_heap_count_data.idle_bgc_thread_count;
+ int max_idle_event_count = min (n_heaps, last_total_bgc_threads);
+ int idle_events_to_set = max_idle_event_count - last_bgc_n_heaps;
+ if (idle_events_to_set > 0)
+ {
+ Interlocked::ExchangeAdd (&dynamic_heap_count_data.idle_bgc_thread_count, -idle_events_to_set);
+ dprintf (6666, ("%d BGC threads exist, setting %d idle events for h%d-h%d, total idle %d -> %d",
+ total_bgc_threads, idle_events_to_set, last_bgc_n_heaps, (last_bgc_n_heaps + idle_events_to_set - 1),
+ saved_idle_bgc_thread_count, VolatileLoadWithoutBarrier (&dynamic_heap_count_data.idle_bgc_thread_count)));
+ for (int heap_idx = last_bgc_n_heaps; heap_idx < max_idle_event_count; heap_idx++)
+ {
+ g_heaps[heap_idx]->bgc_idle_thread_event.Set();
+ }
+ }
+ }
+
+ last_bgc_n_heaps = n_heaps;
+ last_total_bgc_threads = total_bgc_threads;
+#endif //DYNAMIC_HEAP_COUNT
+
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
SoftwareWriteWatch::EnableForGCHeap();
#endif //FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
@@ -25918,9 +26009,6 @@ void gc_heap::check_heap_count ()
for (int heap_idx = n_heaps; heap_idx < new_n_heaps; heap_idx++)
{
g_heaps[heap_idx]->gc_idle_thread_event.Set();
-#ifdef BACKGROUND_GC
- g_heaps[heap_idx]->bgc_idle_thread_event.Set();
-#endif //BACKGROUND_GC
}
}
@@ -37637,6 +37725,19 @@ void gc_heap::gc_thread_stub (void* arg)
void gc_heap::bgc_thread_stub (void* arg)
{
gc_heap* heap = (gc_heap*)arg;
+
+#ifdef STRESS_DYNAMIC_HEAP_COUNT
+ // We should only do this every so often; otherwise we'll never be able to do a BGC
+ int r = (int)gc_rand::get_rand (30);
+ bool wait_p = (r < 10);
+
+ if (wait_p)
+ {
+ GCToOSInterface::Sleep (100);
+ }
+ dprintf (6666, ("h%d %s", heap->heap_number, (wait_p ? "waited" : "did not wait")));
+#endif
+
heap->bgc_thread = GCToEEInterface::GetThread();
assert(heap->bgc_thread != nullptr);
heap->bgc_thread_function();
@@ -39429,6 +39530,8 @@ void gc_heap::add_to_bgc_th_creation_history (size_t gc_index, size_t count_crea
}
#endif //DYNAMIC_HEAP_COUNT
+// If this returns TRUE, we are saying we expect that thread to be there. However, when that thread is available to work is indeterministic.
+// But when we actually start a BGC, naturally we'll need to wait till it gets to the point it can work.
BOOL gc_heap::prepare_bgc_thread(gc_heap* gh)
{
BOOL success = FALSE;
@@ -39440,7 +39543,19 @@ BOOL gc_heap::prepare_bgc_thread(gc_heap* gh)
dprintf (2, ("GC thread not running"));
if (gh->bgc_thread == 0)
{
+#ifdef STRESS_DYNAMIC_HEAP_COUNT
+ // to stress, we just don't actually try to create the thread to simulate a failure
+ int r = (int)gc_rand::get_rand (100);
+ bool try_to_create_p = (r > 10);
+ BOOL thread_created_p = (try_to_create_p ? create_bgc_thread (gh) : FALSE);
+ if (!thread_created_p)
+ {
+ dprintf (6666, ("h%d we failed to create the thread, %s", gh->heap_number, (try_to_create_p ? "tried" : "didn't try")));
+ }
+ if (thread_created_p)
+#else //STRESS_DYNAMIC_HEAP_COUNT
if (create_bgc_thread(gh))
+#endif //STRESS_DYNAMIC_HEAP_COUNT
{
success = TRUE;
thread_created = TRUE;
@@ -39458,8 +39573,11 @@ BOOL gc_heap::prepare_bgc_thread(gc_heap* gh)
else
{
#ifdef DYNAMIC_HEAP_COUNT
+ // This would be a very unusual scenario where GCToEEInterface::CreateThread told us it failed yet the thread was created.
bgc_th_count_created_th_existed++;
+ dprintf (6666, ("h%d we cannot have a thread that runs yet CreateThread reported it failed to create it", gh->heap_number));
#endif //DYNAMIC_HEAP_COUNT
+ assert (!"GCToEEInterface::CreateThread returned FALSE yet the thread was created!");
}
}
else
@@ -39657,7 +39775,7 @@ void gc_heap::bgc_thread_function()
while (1)
{
// Wait for work to do...
- dprintf (3, ("bgc thread: waiting..."));
+ dprintf (6666, ("h%d bgc thread: waiting...", heap_number));
cooperative_mode = enable_preemptive ();
//current_thread->m_fPreemptiveGCDisabled = 0;
@@ -39706,36 +39824,71 @@ void gc_heap::bgc_thread_function()
continue;
}
}
+
+#ifdef STRESS_DYNAMIC_HEAP_COUNT
+ if (n_heaps <= heap_number)
+ {
+ uint32_t delay_ms = (uint32_t)gc_rand::get_rand (200);
+ GCToOSInterface::Sleep (delay_ms);
+ }
+#endif //STRESS_DYNAMIC_HEAP_COUNT
+
// if we signal the thread with no concurrent work to do -> exit
if (!settings.concurrent)
{
- dprintf (3, ("no concurrent GC needed, exiting"));
+ dprintf (6666, ("h%d no concurrent GC needed, exiting", heap_number));
+
+#ifdef STRESS_DYNAMIC_HEAP_COUNT
+ flush_gc_log (true);
+ GCToOSInterface::DebugBreak();
+#endif
break;
}
- gc_background_running = TRUE;
- dprintf (2, (ThreadStressLog::gcStartBgcThread(), heap_number,
- generation_free_list_space (generation_of (max_generation)),
- generation_free_obj_space (generation_of (max_generation)),
- dd_fragmentation (dynamic_data_of (max_generation))));
#ifdef DYNAMIC_HEAP_COUNT
if (n_heaps <= heap_number)
{
+ Interlocked::Increment (&dynamic_heap_count_data.idle_bgc_thread_count);
add_to_bgc_hc_history (hc_record_bgc_inactive);
// this is the case where we have more background GC threads than heaps
// - wait until we're told to continue...
- dprintf (9999, ("BGC thread %d idle (%d heaps) (gc%Id)", heap_number, n_heaps, VolatileLoadWithoutBarrier (&settings.gc_index)));
+ dprintf (6666, ("BGC%Id h%d going idle (%d heaps), idle count is now %d",
+ VolatileLoadWithoutBarrier (&settings.gc_index), heap_number, n_heaps, VolatileLoadWithoutBarrier (&dynamic_heap_count_data.idle_bgc_thread_count)));
bgc_idle_thread_event.Wait(INFINITE, FALSE);
- dprintf (9999, ("BGC thread %d waking from idle (%d heaps) (gc%Id)", heap_number, n_heaps, VolatileLoadWithoutBarrier (&settings.gc_index)));
+ dprintf (6666, ("BGC%Id h%d woke from idle (%d heaps), idle count is now %d",
+ VolatileLoadWithoutBarrier (&settings.gc_index), heap_number, n_heaps, VolatileLoadWithoutBarrier (&dynamic_heap_count_data.idle_bgc_thread_count)));
continue;
}
else
{
+ if (heap_number == 0)
+ {
+ const int spin_count = 1024;
+ int idle_bgc_thread_count = total_bgc_threads - n_heaps;
+ dprintf (6666, ("n_heaps %d, total %d bgc threads, bgc idle should be %d and is %d",
+ n_heaps, total_bgc_threads, idle_bgc_thread_count, VolatileLoadWithoutBarrier (&dynamic_heap_count_data.idle_bgc_thread_count)));
+ if (idle_bgc_thread_count != dynamic_heap_count_data.idle_bgc_thread_count)
+ {
+ dprintf (6666, ("current idle is %d, trying to get to %d",
+ VolatileLoadWithoutBarrier (&dynamic_heap_count_data.idle_bgc_thread_count), idle_bgc_thread_count));
+ spin_and_wait (spin_count, (idle_bgc_thread_count == dynamic_heap_count_data.idle_bgc_thread_count));
+ }
+ }
+
add_to_bgc_hc_history (hc_record_bgc_active);
}
#endif //DYNAMIC_HEAP_COUNT
+ if (heap_number == 0)
+ {
+ gc_background_running = TRUE;
+ dprintf (6666, (ThreadStressLog::gcStartBgcThread(), heap_number,
+ generation_free_list_space (generation_of (max_generation)),
+ generation_free_obj_space (generation_of (max_generation)),
+ dd_fragmentation (dynamic_data_of (max_generation))));
+ }
+
gc1();
#ifndef DOUBLY_LINKED_FL
diff --git a/src/coreclr/gc/gcconfig.h b/src/coreclr/gc/gcconfig.h
index 6952355a677bd2..c74a3b1f286ab7 100644
--- a/src/coreclr/gc/gcconfig.h
+++ b/src/coreclr/gc/gcconfig.h
@@ -142,8 +142,9 @@ class GCConfigStringHolder
INT_CONFIG (GCSpinCountUnit, "GCSpinCountUnit", NULL, 0, "Specifies the spin count unit used by the GC.") \
INT_CONFIG (GCDynamicAdaptationMode, "GCDynamicAdaptationMode", "System.GC.DynamicAdaptationMode", 1, "Enable the GC to dynamically adapt to application sizes.") \
INT_CONFIG (GCDTargetTCP, "GCDTargetTCP", "System.GC.DTargetTCP", 0, "Specifies the target tcp for DATAS") \
- BOOL_CONFIG (GCLogBGCThreadId, "GCLogBGCThreadId", NULL, false, "Specifies if BGC ThreadId should be logged")
-
+ INT_CONFIG (GCDBGCRatio, " GCDBGCRatio", NULL, 0, "Specifies the ratio of BGC to NGC2 for HC change") \
+ BOOL_CONFIG (GCLogBGCThreadId, "GCLogBGCThreadId", NULL, false, "Specifies if BGC ThreadId should be logged") \
+ BOOL_CONFIG (GCCacheSizeFromSysConf, "GCCacheSizeFromSysConf", NULL, false, "Specifies using sysconf to retrieve the last level cache size for Unix.")
// This class is responsible for retreiving configuration information
// for how the GC should operate.
diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h
index 9486645259936a..0d1d31daeb6173 100644
--- a/src/coreclr/gc/gcpriv.h
+++ b/src/coreclr/gc/gcpriv.h
@@ -5175,6 +5175,9 @@ class gc_heap
int last_n_heaps;
// don't start a GC till we see (n_max_heaps - new_n_heaps) number of threads idling
VOLATILE(int32_t) idle_thread_count;
+#ifdef BACKGROUND_GC
+ VOLATILE(int32_t) idle_bgc_thread_count;
+#endif
bool init_only_p;
bool should_change_heap_count;
@@ -5202,6 +5205,17 @@ class gc_heap
// This is set when change_heap_count wants the next GC to be a BGC for rethreading gen2 FL
// and reset during that BGC.
PER_HEAP_ISOLATED_FIELD_MAINTAINED bool trigger_bgc_for_rethreading_p;
+ // BGC threads are created on demand but we don't destroy the ones we created. This
+ // is to track how many we've created. They may or may not be active depending on
+ // if they are needed.
+ PER_HEAP_ISOLATED_FIELD_MAINTAINED int total_bgc_threads;
+
+ // HC last BGC observed.
+ PER_HEAP_ISOLATED_FIELD_MAINTAINED int last_bgc_n_heaps;
+ // Number of total BGC threads last BGC observed. This tells us how many new BGC threads have
+ // been created since. Note that just because a BGC thread is created doesn't mean it's used.
+ // We can fail at committing mark array and not proceed with the BGC.
+ PER_HEAP_ISOLATED_FIELD_MAINTAINED int last_total_bgc_threads;
#endif //BACKGROUND_GC
#endif //DYNAMIC_HEAP_COUNT
@@ -5352,6 +5366,9 @@ class gc_heap
#ifdef DYNAMIC_HEAP_COUNT
PER_HEAP_ISOLATED_FIELD_INIT_ONLY int dynamic_adaptation_mode;
+#ifdef STRESS_DYNAMIC_HEAP_COUNT
+ PER_HEAP_ISOLATED_FIELD_INIT_ONLY int bgc_to_ngc2_ratio;
+#endif //STRESS_DYNAMIC_HEAP_COUNT
#endif //DYNAMIC_HEAP_COUNT
/********************************************/
diff --git a/src/coreclr/gc/unix/CMakeLists.txt b/src/coreclr/gc/unix/CMakeLists.txt
index 83c0bf8a67d8b4..f88b039609881e 100644
--- a/src/coreclr/gc/unix/CMakeLists.txt
+++ b/src/coreclr/gc/unix/CMakeLists.txt
@@ -1,5 +1,6 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
include_directories("../env")
+include_directories("..")
include(configure.cmake)
diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp
index 879397c4493c40..7c2101431c9128 100644
--- a/src/coreclr/gc/unix/gcenv.unix.cpp
+++ b/src/coreclr/gc/unix/gcenv.unix.cpp
@@ -18,8 +18,10 @@
#include "gcenv.structs.h"
#include "gcenv.base.h"
#include "gcenv.os.h"
+#include "gcenv.ee.h"
#include "gcenv.unix.inl"
#include "volatile.h"
+#include "gcconfig.h"
#include "numasupport.h"
#if HAVE_SWAPCTL
@@ -862,10 +864,10 @@ bool ReadMemoryValueFromFile(const char* filename, uint64_t* val)
return result;
}
-static size_t GetLogicalProcessorCacheSizeFromOS()
+static void GetLogicalProcessorCacheSizeFromSysConf(size_t* cacheLevel, size_t* cacheSize)
{
- size_t cacheLevel = 0;
- size_t cacheSize = 0;
+ assert (cacheLevel != nullptr);
+ assert (cacheSize != nullptr);
#if defined(_SC_LEVEL1_DCACHE_SIZE) || defined(_SC_LEVEL2_CACHE_SIZE) || defined(_SC_LEVEL3_CACHE_SIZE) || defined(_SC_LEVEL4_CACHE_SIZE)
const int cacheLevelNames[] =
@@ -881,47 +883,105 @@ static size_t GetLogicalProcessorCacheSizeFromOS()
long size = sysconf(cacheLevelNames[i]);
if (size > 0)
{
- cacheSize = (size_t)size;
- cacheLevel = i + 1;
+ *cacheSize = (size_t)size;
+ *cacheLevel = i + 1;
break;
}
}
#endif
+}
+
+static void GetLogicalProcessorCacheSizeFromSysFs(size_t* cacheLevel, size_t* cacheSize)
+{
+ assert (cacheLevel != nullptr);
+ assert (cacheSize != nullptr);
#if defined(TARGET_LINUX) && !defined(HOST_ARM) && !defined(HOST_X86)
- if (cacheSize == 0)
+ //
+ // Retrieve cachesize via sysfs by reading the file /sys/devices/system/cpu/cpu0/cache/index{LastLevelCache}/size
+ // for the platform. Currently musl and arm64 should be only cases to use
+ // this method to determine cache size.
+ //
+ size_t level;
+ char path_to_size_file[] = "/sys/devices/system/cpu/cpu0/cache/index-/size";
+ char path_to_level_file[] = "/sys/devices/system/cpu/cpu0/cache/index-/level";
+ int index = 40;
+ assert(path_to_size_file[index] == '-');
+ assert(path_to_level_file[index] == '-');
+
+ for (int i = 0; i < 5; i++)
{
- //
- // Fallback to retrieve cachesize via /sys/.. if sysconf was not available
- // for the platform. Currently musl and arm64 should be only cases to use
- // this method to determine cache size.
- //
- size_t level;
- char path_to_size_file[] = "/sys/devices/system/cpu/cpu0/cache/index-/size";
- char path_to_level_file[] = "/sys/devices/system/cpu/cpu0/cache/index-/level";
- int index = 40;
- assert(path_to_size_file[index] == '-');
- assert(path_to_level_file[index] == '-');
-
- for (int i = 0; i < 5; i++)
- {
- path_to_size_file[index] = (char)(48 + i);
+ path_to_size_file[index] = (char)(48 + i);
- uint64_t cache_size_from_sys_file = 0;
+ uint64_t cache_size_from_sys_file = 0;
- if (ReadMemoryValueFromFile(path_to_size_file, &cache_size_from_sys_file))
- {
- cacheSize = std::max(cacheSize, (size_t)cache_size_from_sys_file);
+ if (ReadMemoryValueFromFile(path_to_size_file, &cache_size_from_sys_file))
+ {
+ *cacheSize = std::max(*cacheSize, (size_t)cache_size_from_sys_file);
- path_to_level_file[index] = (char)(48 + i);
- if (ReadMemoryValueFromFile(path_to_level_file, &level))
- {
- cacheLevel = level;
- }
+ path_to_level_file[index] = (char)(48 + i);
+ if (ReadMemoryValueFromFile(path_to_level_file, &level))
+ {
+ *cacheLevel = level;
}
}
}
+#endif
+}
+
+static void GetLogicalProcessorCacheSizeFromHeuristic(size_t* cacheLevel, size_t* cacheSize)
+{
+ assert (cacheLevel != nullptr);
+ assert (cacheSize != nullptr);
+
+#if (defined(TARGET_LINUX) && !defined(TARGET_APPLE))
+ {
+ // Use the following heuristics at best depending on the CPU count
+ // 1 ~ 4 : 4 MB
+ // 5 ~ 16 : 8 MB
+ // 17 ~ 64 : 16 MB
+ // 65+ : 32 MB
+ DWORD logicalCPUs = g_processAffinitySet.Count();
+ if (logicalCPUs < 5)
+ {
+ *cacheSize = 4;
+ }
+ else if (logicalCPUs < 17)
+ {
+ *cacheSize = 8;
+ }
+ else if (logicalCPUs < 65)
+ {
+ *cacheSize = 16;
+ }
+ else
+ {
+ *cacheSize = 32;
+ }
+
+ *cacheSize *= (1024 * 1024);
+ }
#endif
+}
+
+static size_t GetLogicalProcessorCacheSizeFromOS()
+{
+ size_t cacheLevel = 0;
+ size_t cacheSize = 0;
+
+ if (GCConfig::GetGCCacheSizeFromSysConf())
+ {
+ GetLogicalProcessorCacheSizeFromSysConf(&cacheLevel, &cacheSize);
+ }
+
+ if (cacheSize == 0)
+ {
+ GetLogicalProcessorCacheSizeFromSysFs(&cacheLevel, &cacheSize);
+ if (cacheSize == 0)
+ {
+ GetLogicalProcessorCacheSizeFromHeuristic(&cacheLevel, &cacheSize);
+ }
+ }
#if HAVE_SYSCTLBYNAME
if (cacheSize == 0)
@@ -948,32 +1008,7 @@ static size_t GetLogicalProcessorCacheSizeFromOS()
#if (defined(HOST_ARM64) || defined(HOST_LOONGARCH64)) && !defined(TARGET_APPLE)
if (cacheLevel != 3)
{
- // We expect to get the L3 cache size for Arm64 but currently expected to be missing that info
- // from most of the machines.
- // Hence, just use the following heuristics at best depending on the CPU count
- // 1 ~ 4 : 4 MB
- // 5 ~ 16 : 8 MB
- // 17 ~ 64 : 16 MB
- // 65+ : 32 MB
- DWORD logicalCPUs = g_processAffinitySet.Count();
- if (logicalCPUs < 5)
- {
- cacheSize = 4;
- }
- else if (logicalCPUs < 17)
- {
- cacheSize = 8;
- }
- else if (logicalCPUs < 65)
- {
- cacheSize = 16;
- }
- else
- {
- cacheSize = 32;
- }
-
- cacheSize *= (1024 * 1024);
+ GetLogicalProcessorCacheSizeFromHeuristic(&cacheLevel, &cacheSize);
}
#endif
diff --git a/src/coreclr/ildasm/dasm.cpp b/src/coreclr/ildasm/dasm.cpp
index f94a5846672d96..7c2b3eabd36597 100644
--- a/src/coreclr/ildasm/dasm.cpp
+++ b/src/coreclr/ildasm/dasm.cpp
@@ -1914,7 +1914,7 @@ BYTE* PrettyPrintCABlobValue(PCCOR_SIGNATURE &typePtr,
for(n=0; n < numElements; n++)
{
if(n) appendStr(out," ");
- sprintf_s(str, 64, "%.*g", 8, (double)(*((float*)dataPtr)));
+ sprintf_s(str, 64, "%#.8g", (double)(*((float*)dataPtr)));
float df = (float)atof(str);
// Must compare as underlying bytes, not floating point otherwise optimizer will
// try to enregister and compare 80-bit precision number with 32-bit precision number!!!!
@@ -1933,7 +1933,7 @@ BYTE* PrettyPrintCABlobValue(PCCOR_SIGNATURE &typePtr,
{
if(n) appendStr(out," ");
char *pch;
- sprintf_s(str, 64, "%.*g", 17, *((double*)dataPtr));
+ sprintf_s(str, 64, "%#.17g", *((double*)dataPtr));
double df = strtod(str, &pch);
// Must compare as underlying bytes, not floating point otherwise optimizer will
// try to enregister and compare 80-bit precision number with 64-bit precision number!!!!
@@ -2605,7 +2605,7 @@ void DumpDefaultValue(mdToken tok, __inout __nullterminated char* szString, void
case ELEMENT_TYPE_R4:
{
char szf[32];
- sprintf_s(szf, 32, "%.*g", 8, (double)MDDV.m_fltValue);
+ sprintf_s(szf, 32, "%#.8g", (double)MDDV.m_fltValue);
float df = (float)atof(szf);
// Must compare as underlying bytes, not floating point otherwise optimizer will
// try to enregister and compare 80-bit precision number with 32-bit precision number!!!!
@@ -2619,7 +2619,7 @@ void DumpDefaultValue(mdToken tok, __inout __nullterminated char* szString, void
case ELEMENT_TYPE_R8:
{
char szf[32], *pch;
- sprintf_s(szf, 32, "%.*g", 17, MDDV.m_dblValue);
+ sprintf_s(szf, 32, "%#.17g", MDDV.m_dblValue);
double df = strtod(szf, &pch); //atof(szf);
szf[31]=0;
// Must compare as underlying bytes, not floating point otherwise optimizer will
diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h
index 068ee41bbb72a5..cab2f6c71d7447 100644
--- a/src/coreclr/inc/corinfo.h
+++ b/src/coreclr/inc/corinfo.h
@@ -2374,10 +2374,10 @@ class ICorStaticInfo
bool fDoubleAlignHint = false
) = 0;
- // This is only called for Value classes. It returns a boolean array
- // in representing of 'cls' from a GC perspective. The class is
- // assumed to be an array of machine words
- // (of length // getClassSize(cls) / TARGET_POINTER_SIZE),
+ // Returns a boolean array representing 'cls' from a GC perspective.
+ // The class is assumed to be an array of machine words
+ // (of length getClassSize(cls) / TARGET_POINTER_SIZE for value classes
+ // and getHeapClassSize(cls) / TARGET_POINTER_SIZE for reference types),
// 'gcPtrs' is a pointer to an array of uint8_ts of this length.
// getClassGClayout fills in this array so that gcPtrs[i] is set
// to one of the CorInfoGCType values which is the GC type of
diff --git a/src/coreclr/inc/eetwain.h b/src/coreclr/inc/eetwain.h
index c7b1be02e5c638..4ee7b9a7b84b6e 100644
--- a/src/coreclr/inc/eetwain.h
+++ b/src/coreclr/inc/eetwain.h
@@ -273,6 +273,7 @@ virtual GenericParamContextType GetParamContextType(PREGDISPLAY pContext,
*/
virtual void * GetGSCookieAddr(PREGDISPLAY pContext,
EECodeInfo * pCodeInfo,
+ unsigned flags,
CodeManState * pState) = 0;
#ifndef USE_GC_INFO_DECODER
@@ -541,6 +542,7 @@ PTR_VOID GetExactGenericsToken(SIZE_T baseStackSlot,
virtual
void * GetGSCookieAddr(PREGDISPLAY pContext,
EECodeInfo * pCodeInfo,
+ unsigned flags,
CodeManState * pState);
diff --git a/src/coreclr/interop/trackerobjectmanager.cpp b/src/coreclr/interop/trackerobjectmanager.cpp
index d4302054baedba..0df78164906dcc 100644
--- a/src/coreclr/interop/trackerobjectmanager.cpp
+++ b/src/coreclr/interop/trackerobjectmanager.cpp
@@ -84,7 +84,10 @@ namespace
STDMETHODIMP HostServices::ReleaseDisconnectedReferenceSources()
{
- return InteropLibImports::WaitForRuntimeFinalizerForExternal();
+ // We'd like to call InteropLibImports::WaitForRuntimeFinalizerForExternal() here, but this could
+ // lead to deadlock if the finalizer thread is trying to get back to this thread, because we are
+ // not pumping anymore. Disable this for now. See: https://github.com/dotnet/runtime/issues/109538.
+ return S_OK;
}
STDMETHODIMP HostServices::NotifyEndOfReferenceTrackingOnThread()
diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp
index 3d61a698a08d5c..f720ca6c826cba 100644
--- a/src/coreclr/jit/assertionprop.cpp
+++ b/src/coreclr/jit/assertionprop.cpp
@@ -2211,6 +2211,22 @@ AssertionInfo Compiler::optAssertionGenJtrue(GenTree* tree)
// If op1 is lcl and op2 is const or lcl, create assertion.
if ((op1->gtOper == GT_LCL_VAR) && (op2->OperIsConst() || (op2->gtOper == GT_LCL_VAR))) // Fix for Dev10 851483
{
+ // Watch out for cases where long local(s) are implicitly truncated.
+ //
+ LclVarDsc* const lcl1Dsc = lvaGetDesc(op1->AsLclVarCommon());
+ if ((lcl1Dsc->TypeGet() == TYP_LONG) && (op1->TypeGet() != TYP_LONG))
+ {
+ return NO_ASSERTION_INDEX;
+ }
+ if (op2->OperIs(GT_LCL_VAR))
+ {
+ LclVarDsc* const lcl2Dsc = lvaGetDesc(op2->AsLclVarCommon());
+ if ((lcl2Dsc->TypeGet() == TYP_LONG) && (op2->TypeGet() != TYP_LONG))
+ {
+ return NO_ASSERTION_INDEX;
+ }
+ }
+
return optCreateJtrueAssertions(op1, op2, assertionKind);
}
else if (!optLocalAssertionProp)
diff --git a/src/coreclr/jit/block.cpp b/src/coreclr/jit/block.cpp
index be2ba15e254690..b00dc1282a2900 100644
--- a/src/coreclr/jit/block.cpp
+++ b/src/coreclr/jit/block.cpp
@@ -267,15 +267,21 @@ FlowEdge* Compiler::BlockPredsWithEH(BasicBlock* blk)
// 'blk'.
//
// Arguments:
-// blk - Block to get dominance predecessors for.
+// blk - Block to get dominance predecessors for.
//
// Returns:
-// List of edges.
+// List of edges.
//
// Remarks:
-// Differs from BlockPredsWithEH only in the treatment of handler blocks;
-// enclosed blocks are never dominance preds, while all predecessors of
-// blocks in the 'try' are (currently only the first try block expected).
+// Differs from BlockPredsWithEH only in the treatment of handler blocks;
+// enclosed blocks are never dominance preds, while all predecessors of
+// blocks in the 'try' are (currently only the first try block expected).
+//
+// There are additional complications due to spurious flow because of
+// two-pass EH. In the flow graph with EH edges we can see entries into the
+// try from filters outside the try, to blocks other than the "try-begin"
+// block. Hence we need to consider the full set of blocks in the try region
+// when considering the block dominance preds.
//
FlowEdge* Compiler::BlockDominancePreds(BasicBlock* blk)
{
@@ -284,14 +290,6 @@ FlowEdge* Compiler::BlockDominancePreds(BasicBlock* blk)
return blk->bbPreds;
}
- EHblkDsc* ehblk = ehGetBlockHndDsc(blk);
- if (!ehblk->HasFinallyOrFaultHandler() || (ehblk->ebdHndBeg != blk))
- {
- return ehblk->ebdTryBeg->bbPreds;
- }
-
- // Finally/fault handlers can be preceded by enclosing filters due to 2
- // pass EH, so add those and keep them cached.
BlockToFlowEdgeMap* domPreds = GetDominancePreds();
FlowEdge* res;
if (domPreds->Lookup(blk, &res))
@@ -299,29 +297,11 @@ FlowEdge* Compiler::BlockDominancePreds(BasicBlock* blk)
return res;
}
- res = ehblk->ebdTryBeg->bbPreds;
- if (ehblk->HasFinallyOrFaultHandler() && (ehblk->ebdHndBeg == blk))
+ EHblkDsc* ehblk = ehGetBlockHndDsc(blk);
+ res = BlockPredsWithEH(blk);
+ for (BasicBlock* predBlk : ehblk->ebdTryBeg->PredBlocks())
{
- // block is a finally or fault handler; all enclosing filters are predecessors
- unsigned enclosing = ehblk->ebdEnclosingTryIndex;
- while (enclosing != EHblkDsc::NO_ENCLOSING_INDEX)
- {
- EHblkDsc* enclosingDsc = ehGetDsc(enclosing);
- if (enclosingDsc->HasFilter())
- {
- for (BasicBlock* filterBlk = enclosingDsc->ebdFilter; filterBlk != enclosingDsc->ebdHndBeg;
- filterBlk = filterBlk->Next())
- {
- res = new (this, CMK_FlowEdge) FlowEdge(filterBlk, blk, res);
-
- assert(filterBlk->VisitEHEnclosedHandlerSecondPassSuccs(this, [blk](BasicBlock* succ) {
- return succ == blk ? BasicBlockVisit::Abort : BasicBlockVisit::Continue;
- }) == BasicBlockVisit::Abort);
- }
- }
-
- enclosing = enclosingDsc->ebdEnclosingTryIndex;
- }
+ res = new (this, CMK_FlowEdge) FlowEdge(predBlk, blk, res);
}
domPreds->Set(blk, res);
diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp
index 2a5c947de175c5..624a737234fcbb 100644
--- a/src/coreclr/jit/emitarm64.cpp
+++ b/src/coreclr/jit/emitarm64.cpp
@@ -217,7 +217,6 @@ void emitter::emitInsSanityCheck(instrDesc* id)
case IF_BR_1B: // BR_1B ................ ......nnnnn..... Rn
if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && id->idIsTlsGD())
{
- assert(isGeneralRegister(id->idReg1()));
assert(id->idAddr()->iiaAddr != nullptr);
}
else
@@ -9184,11 +9183,14 @@ void emitter::emitIns_Call(EmitCallType callType,
if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && EA_IS_CNS_TLSGD_RELOC(retSize))
{
// For NativeAOT linux/arm64, we need to also record the relocation of methHnd.
- // Since we do not have space to embed it in instrDesc, we store the register in
- // reg1 and instead use the `iiaAdd` to store the method handle. Likewise, during
- // emitOutputInstr, we retrieve the register from reg1 for this specific case.
+ // Since we do not have space to embed it in instrDesc, we use the `iiaAddr` to
+ // store the method handle.
+ // The target handle need to be always in R2 and hence the assert check.
+ // We cannot use reg1 and reg2 fields of instrDesc because they contain the gc
+ // registers (emitEncodeCallGCregs()) that are live across the call.
+
+ assert(ireg == REG_R2);
id->idSetTlsGD();
- id->idReg1(ireg);
id->idAddr()->iiaAddr = (BYTE*)methHnd;
}
else
@@ -10990,12 +10992,13 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
{
emitRecordRelocation(odst, (CORINFO_METHOD_HANDLE)id->idAddr()->iiaAddr,
IMAGE_REL_AARCH64_TLSDESC_CALL);
- code |= insEncodeReg_Rn(id->idReg1()); // nnnnn
+ code |= insEncodeReg_Rn(REG_R2); // nnnnn
}
else
{
code |= insEncodeReg_Rn(id->idReg3()); // nnnnn
}
+
dst += emitOutputCall(ig, dst, id, code);
sz = id->idIsLargeCall() ? sizeof(instrDescCGCA) : sizeof(instrDesc);
break;
@@ -13315,7 +13318,15 @@ void emitter::emitDispInsHelp(
case IF_BR_1B: // BR_1B ................ ......nnnnn..... Rn
// The size of a branch target is always EA_PTRSIZE
assert(insOptsNone(id->idInsOpt()));
- emitDispReg(id->idReg3(), EA_PTRSIZE, false);
+
+ if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && id->idIsTlsGD())
+ {
+ emitDispReg(REG_R2, EA_PTRSIZE, false);
+ }
+ else
+ {
+ emitDispReg(id->idReg3(), EA_PTRSIZE, false);
+ }
break;
case IF_LS_1A: // LS_1A XX...V..iiiiiiii iiiiiiiiiiittttt Rt PC imm(1MB)
diff --git a/src/coreclr/jit/promotion.cpp b/src/coreclr/jit/promotion.cpp
index 7fe9bffa70e943..c426cf37e2e1a0 100644
--- a/src/coreclr/jit/promotion.cpp
+++ b/src/coreclr/jit/promotion.cpp
@@ -1885,41 +1885,79 @@ void ReplaceVisitor::InsertPreStatementReadBacks()
// 3. Creating embedded stores in ReplaceLocal disables local copy prop for
// that local (see ReplaceLocal).
- for (GenTreeLclVarCommon* lcl : m_currentStmt->LocalsTreeList())
+ // Normally, we read back only for the uses we will see. However, with
+ // implicit EH flow we may also read back all replacements mid-tree (see
+ // InsertMidTreeReadBacks). So for that case we read back everything. This
+ // is a correctness requirement for QMARKs, but we do it indiscriminately
+ // for the same reasons as mentioned above.
+ if (((m_currentStmt->GetRootNode()->gtFlags & (GTF_EXCEPT | GTF_CALL)) != 0) &&
+ m_compiler->ehBlockHasExnFlowDsc(m_currentBlock))
{
- if (lcl->TypeIs(TYP_STRUCT))
- {
- continue;
- }
+ JITDUMP(
+ "Reading back pending replacements before statement with possible exception side effect inside block in try region\n");
- AggregateInfo* agg = m_aggregates.Lookup(lcl->GetLclNum());
- if (agg == nullptr)
+ for (AggregateInfo* agg : m_aggregates)
{
- continue;
+ for (Replacement& rep : agg->Replacements)
+ {
+ InsertPreStatementReadBackIfNecessary(agg->LclNum, rep);
+ }
}
-
- size_t index = Promotion::BinarySearch(agg->Replacements, lcl->GetLclOffs());
- if ((ssize_t)index < 0)
+ }
+ else
+ {
+ // Otherwise just read back the locals we see uses of.
+ for (GenTreeLclVarCommon* lcl : m_currentStmt->LocalsTreeList())
{
- continue;
- }
+ if (lcl->TypeIs(TYP_STRUCT))
+ {
+ continue;
+ }
- Replacement& rep = agg->Replacements[index];
- if (rep.NeedsReadBack)
- {
- JITDUMP("Reading back replacement V%02u.[%03u..%03u) -> V%02u before [%06u]:\n", agg->LclNum, rep.Offset,
- rep.Offset + genTypeSize(rep.AccessType), rep.LclNum,
- Compiler::dspTreeID(m_currentStmt->GetRootNode()));
+ AggregateInfo* agg = m_aggregates.Lookup(lcl->GetLclNum());
+ if (agg == nullptr)
+ {
+ continue;
+ }
- GenTree* readBack = Promotion::CreateReadBack(m_compiler, agg->LclNum, rep);
- Statement* stmt = m_compiler->fgNewStmtFromTree(readBack);
- DISPSTMT(stmt);
- m_compiler->fgInsertStmtBefore(m_currentBlock, m_currentStmt, stmt);
- ClearNeedsReadBack(rep);
+ size_t index =
+ Promotion::BinarySearch(agg->Replacements, lcl->GetLclOffs());
+ if ((ssize_t)index < 0)
+ {
+ continue;
+ }
+
+ InsertPreStatementReadBackIfNecessary(agg->LclNum, agg->Replacements[index]);
}
}
}
+//------------------------------------------------------------------------
+// InsertPreStatementReadBackIfNecessary:
+// Insert a read back of the specified replacement before the current
+// statement, if the replacement needs it.
+//
+// Parameters:
+// aggLclNum - Struct local
+// rep - The replacement
+//
+void ReplaceVisitor::InsertPreStatementReadBackIfNecessary(unsigned aggLclNum, Replacement& rep)
+{
+ if (!rep.NeedsReadBack)
+ {
+ return;
+ }
+
+ JITDUMP("Reading back replacement V%02u.[%03u..%03u) -> V%02u before [%06u]:\n", aggLclNum, rep.Offset,
+ rep.Offset + genTypeSize(rep.AccessType), rep.LclNum, Compiler::dspTreeID(m_currentStmt->GetRootNode()));
+
+ GenTree* readBack = Promotion::CreateReadBack(m_compiler, aggLclNum, rep);
+ Statement* stmt = m_compiler->fgNewStmtFromTree(readBack);
+ DISPSTMT(stmt);
+ m_compiler->fgInsertStmtBefore(m_currentBlock, m_currentStmt, stmt);
+ ClearNeedsReadBack(rep);
+}
+
//------------------------------------------------------------------------
// VisitOverlappingReplacements:
// Call a function for every replacement that overlaps a specified segment.
diff --git a/src/coreclr/jit/promotion.h b/src/coreclr/jit/promotion.h
index 28481a97eaf88b..a8c54d4000f341 100644
--- a/src/coreclr/jit/promotion.h
+++ b/src/coreclr/jit/promotion.h
@@ -290,6 +290,7 @@ class ReplaceVisitor : public GenTreeVisitor
bool VisitOverlappingReplacements(unsigned lcl, unsigned offs, unsigned size, Func func);
void InsertPreStatementReadBacks();
+ void InsertPreStatementReadBackIfNecessary(unsigned aggLclNum, Replacement& rep);
void InsertPreStatementWriteBacks();
GenTree** InsertMidTreeReadBacks(GenTree** use);
diff --git a/src/coreclr/jit/simdashwintrinsic.cpp b/src/coreclr/jit/simdashwintrinsic.cpp
index bfb24b6c7ed317..fbd4762544644d 100644
--- a/src/coreclr/jit/simdashwintrinsic.cpp
+++ b/src/coreclr/jit/simdashwintrinsic.cpp
@@ -917,6 +917,11 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdCeilNode(retType, op1, simdBaseJitType, simdSize);
}
+ case NI_VectorT_Create:
+ {
+ return gtNewSimdCreateBroadcastNode(simdType, op1, simdBaseJitType, simdSize);
+ }
+
case NI_VectorT_Floor:
{
return gtNewSimdFloorNode(retType, op1, simdBaseJitType, simdSize);
@@ -1247,15 +1252,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
return gtNewSimdBinOpNode(GT_OR, retType, op1, op2, simdBaseJitType, simdSize);
}
- case NI_VectorT_Create:
- {
- assert(retType == TYP_VOID);
-
- copyBlkDst = op1;
- copyBlkSrc = gtNewSimdCreateBroadcastNode(simdType, op2, simdBaseJitType, simdSize);
- break;
- }
-
case NI_VectorT_CreateSequence:
{
return gtNewSimdCreateSequenceNode(simdType, op1, op2, simdBaseJitType, simdSize);
diff --git a/src/coreclr/jit/simdashwintrinsiclistarm64.h b/src/coreclr/jit/simdashwintrinsiclistarm64.h
index 6bbea32494f315..2ca159110dc4c7 100644
--- a/src/coreclr/jit/simdashwintrinsiclistarm64.h
+++ b/src/coreclr/jit/simdashwintrinsiclistarm64.h
@@ -64,8 +64,8 @@ SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32,
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt32Native, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64Native}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(VectorT, Create, 1, {NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(VectorT, CreateSequence, 2, {NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
+SIMD_AS_HWINTRINSIC_ID(VectorT, Create, 1, {NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create}, SimdAsHWIntrinsicFlag::KeepBaseTypeFromRet)
+SIMD_AS_HWINTRINSIC_ID(VectorT, CreateSequence, 2, {NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence}, SimdAsHWIntrinsicFlag::KeepBaseTypeFromRet | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
SIMD_AS_HWINTRINSIC_ID(VectorT, Dot, 2, {NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_Illegal, NI_Illegal, NI_VectorT_Dot, NI_VectorT_Dot}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, Equals, 2, {NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, EqualsAny, 2, {NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny}, SimdAsHWIntrinsicFlag::None)
diff --git a/src/coreclr/jit/simdashwintrinsiclistxarch.h b/src/coreclr/jit/simdashwintrinsiclistxarch.h
index 1d769f27e4f97d..6baf3143cd02d3 100644
--- a/src/coreclr/jit/simdashwintrinsiclistxarch.h
+++ b/src/coreclr/jit/simdashwintrinsiclistxarch.h
@@ -64,8 +64,8 @@ SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32,
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt32Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt32Native, NI_Illegal}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, ConvertToUInt64Native, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT_ConvertToUInt64Native}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(VectorT, Create, 1, {NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create}, SimdAsHWIntrinsicFlag::None)
-SIMD_AS_HWINTRINSIC_ID(VectorT, CreateSequence, 2, {NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence}, SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
+SIMD_AS_HWINTRINSIC_ID(VectorT, Create, 1, {NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create, NI_VectorT_Create}, SimdAsHWIntrinsicFlag::KeepBaseTypeFromRet)
+SIMD_AS_HWINTRINSIC_ID(VectorT, CreateSequence, 2, {NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence, NI_VectorT_CreateSequence}, SimdAsHWIntrinsicFlag::KeepBaseTypeFromRet | SimdAsHWIntrinsicFlag::SpillSideEffectsOp1)
SIMD_AS_HWINTRINSIC_ID(VectorT, Dot, 2, {NI_Illegal, NI_Illegal, NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_VectorT_Dot, NI_Illegal, NI_Illegal, NI_VectorT_Dot, NI_VectorT_Dot}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, Equals, 2, {NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals, NI_VectorT_Equals}, SimdAsHWIntrinsicFlag::None)
SIMD_AS_HWINTRINSIC_ID(VectorT, EqualsAny, 2, {NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny, NI_VectorT_EqualsAny}, SimdAsHWIntrinsicFlag::None)
diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs
index 7a242497f30826..9a1b1ad7ef985a 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs
@@ -82,14 +82,46 @@ private static IntPtr RhResolveDispatch(object pObject, MethodTable* interfaceTy
}
[RuntimeExport("RhResolveDispatchOnType")]
- private static IntPtr RhResolveDispatchOnType(MethodTable* pInstanceType, MethodTable* pInterfaceType, ushort slot, MethodTable** ppGenericContext)
+ private static IntPtr RhResolveDispatchOnType(MethodTable* pInstanceType, MethodTable* pInterfaceType, ushort slot)
{
return DispatchResolve.FindInterfaceMethodImplementationTarget(pInstanceType,
pInterfaceType,
slot,
+ flags: default,
+ ppGenericContext: null);
+ }
+
+ [RuntimeExport("RhResolveStaticDispatchOnType")]
+ private static IntPtr RhResolveStaticDispatchOnType(MethodTable* pInstanceType, MethodTable* pInterfaceType, ushort slot, MethodTable** ppGenericContext)
+ {
+ return DispatchResolve.FindInterfaceMethodImplementationTarget(pInstanceType,
+ pInterfaceType,
+ slot,
+ DispatchResolve.ResolveFlags.Static,
ppGenericContext);
}
+ [RuntimeExport("RhResolveDynamicInterfaceCastableDispatchOnType")]
+ private static IntPtr RhResolveDynamicInterfaceCastableDispatchOnType(MethodTable* pInstanceType, MethodTable* pInterfaceType, ushort slot, MethodTable** ppGenericContext)
+ {
+ IntPtr result = DispatchResolve.FindInterfaceMethodImplementationTarget(pInstanceType,
+ pInterfaceType,
+ slot,
+ DispatchResolve.ResolveFlags.IDynamicInterfaceCastable,
+ ppGenericContext);
+
+ if ((result & (nint)DispatchMapCodePointerFlags.RequiresInstantiatingThunkFlag) != 0)
+ {
+ result &= ~(nint)DispatchMapCodePointerFlags.RequiresInstantiatingThunkFlag;
+ }
+ else
+ {
+ *ppGenericContext = null;
+ }
+
+ return result;
+ }
+
private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void* cell, ref DispatchCellInfo cellInfo)
{
// Type of object we're dispatching on.
@@ -97,13 +129,10 @@ private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void* cell,
if (cellInfo.CellType == DispatchCellType.InterfaceAndSlot)
{
- // Type whose DispatchMap is used. Usually the same as the above but for types which implement IDynamicInterfaceCastable
- // we may repeat this process with an alternate type.
- MethodTable* pResolvingInstanceType = pInstanceType;
-
- IntPtr pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType,
+ IntPtr pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pInstanceType,
cellInfo.InterfaceType,
cellInfo.InterfaceSlot,
+ flags: default,
ppGenericContext: null);
if (pTargetCode == IntPtr.Zero && pInstanceType->IsIDynamicInterfaceCastable)
{
diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/DispatchResolve.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/DispatchResolve.cs
index 349415c743aa9a..271fdd231c611a 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/DispatchResolve.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/DispatchResolve.cs
@@ -13,21 +13,21 @@ internal static unsafe class DispatchResolve
public static IntPtr FindInterfaceMethodImplementationTarget(MethodTable* pTgtType,
MethodTable* pItfType,
ushort itfSlotNumber,
+ ResolveFlags flags,
/* out */ MethodTable** ppGenericContext)
{
+ // We set this bit below during second pass, callers should not set it.
+ Debug.Assert((flags & ResolveFlags.DefaultInterfaceImplementation) == 0);
+
// Start at the current type and work up the inheritance chain
MethodTable* pCur = pTgtType;
- // We first look at non-default implementation. Default implementations are only considered
- // if the "old algorithm" didn't come up with an answer.
- bool fDoDefaultImplementationLookup = false;
-
again:
while (pCur != null)
{
ushort implSlotNumber;
if (FindImplSlotForCurrentType(
- pCur, pItfType, itfSlotNumber, fDoDefaultImplementationLookup, &implSlotNumber, ppGenericContext))
+ pCur, pItfType, itfSlotNumber, flags, &implSlotNumber, ppGenericContext))
{
IntPtr targetMethod;
if (implSlotNumber < pCur->NumVtableSlots)
@@ -58,9 +58,9 @@ public static IntPtr FindInterfaceMethodImplementationTarget(MethodTable* pTgtTy
}
// If we haven't found an implementation, do a second pass looking for a default implementation.
- if (!fDoDefaultImplementationLookup)
+ if ((flags & ResolveFlags.DefaultInterfaceImplementation) == 0)
{
- fDoDefaultImplementationLookup = true;
+ flags |= ResolveFlags.DefaultInterfaceImplementation;
pCur = pTgtType;
goto again;
}
@@ -72,10 +72,13 @@ public static IntPtr FindInterfaceMethodImplementationTarget(MethodTable* pTgtTy
private static bool FindImplSlotForCurrentType(MethodTable* pTgtType,
MethodTable* pItfType,
ushort itfSlotNumber,
- bool fDoDefaultImplementationLookup,
+ ResolveFlags flags,
ushort* pImplSlotNumber,
MethodTable** ppGenericContext)
{
+ // We set this below during second pass, callers should not set this.
+ Debug.Assert((flags & ResolveFlags.Variant) == 0);
+
bool fRes = false;
// If making a call and doing virtual resolution don't look into the dispatch map,
@@ -96,16 +99,14 @@ private static bool FindImplSlotForCurrentType(MethodTable* pTgtType,
// result in interesting behavior such as a derived type only overriding one particular instantiation
// and funneling all the dispatches to it, but its the algorithm.
- bool fDoVariantLookup = false; // do not check variance for first scan of dispatch map
-
fRes = FindImplSlotInSimpleMap(
- pTgtType, pItfType, itfSlotNumber, pImplSlotNumber, ppGenericContext, fDoVariantLookup, fDoDefaultImplementationLookup);
+ pTgtType, pItfType, itfSlotNumber, pImplSlotNumber, ppGenericContext, flags);
if (!fRes)
{
- fDoVariantLookup = true; // check variance for second scan of dispatch map
+ flags |= ResolveFlags.Variant; // check variance for second scan of dispatch map
fRes = FindImplSlotInSimpleMap(
- pTgtType, pItfType, itfSlotNumber, pImplSlotNumber, ppGenericContext, fDoVariantLookup, fDoDefaultImplementationLookup);
+ pTgtType, pItfType, itfSlotNumber, pImplSlotNumber, ppGenericContext, flags);
}
}
@@ -117,8 +118,7 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType,
uint itfSlotNumber,
ushort* pImplSlotNumber,
MethodTable** ppGenericContext,
- bool actuallyCheckVariance,
- bool checkDefaultImplementations)
+ ResolveFlags flags)
{
Debug.Assert(pTgtType->HasDispatchMap, "Missing dispatch map");
@@ -130,7 +130,7 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType,
bool fCheckVariance = false;
bool fArrayCovariance = false;
- if (actuallyCheckVariance)
+ if ((flags & ResolveFlags.Variant) != 0)
{
fCheckVariance = pItfType->HasGenericVariance;
fArrayCovariance = pTgtType->IsArray;
@@ -166,8 +166,8 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType,
}
}
- // It only makes sense to ask for generic context if we're asking about a static method
- bool fStaticDispatch = ppGenericContext != null;
+ bool fStaticDispatch = (flags & ResolveFlags.Static) != 0;
+ bool checkDefaultImplementations = (flags & ResolveFlags.DefaultInterfaceImplementation) != 0;
// We either scan the instance or static portion of the dispatch map. Depends on what the caller wants.
DispatchMap* pMap = pTgtType->DispatchMap;
@@ -190,8 +190,11 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType,
// If this is a static method, the entry point is not usable without generic context.
// (Instance methods acquire the generic context from their `this`.)
+ // Same for IDynamicInterfaceCastable (that has a `this` but it's not useful)
if (fStaticDispatch)
*ppGenericContext = GetGenericContextSource(pTgtType, i);
+ else if ((flags & ResolveFlags.IDynamicInterfaceCastable) != 0)
+ *ppGenericContext = pTgtType;
return true;
}
@@ -231,8 +234,11 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType,
// If this is a static method, the entry point is not usable without generic context.
// (Instance methods acquire the generic context from their `this`.)
+ // Same for IDynamicInterfaceCastable (that has a `this` but it's not useful)
if (fStaticDispatch)
*ppGenericContext = GetGenericContextSource(pTgtType, i);
+ else if ((flags & ResolveFlags.IDynamicInterfaceCastable) != 0)
+ *ppGenericContext = pTgtType;
return true;
}
@@ -253,5 +259,13 @@ private static bool FindImplSlotInSimpleMap(MethodTable* pTgtType,
_ => pTgtType->InterfaceMap[usEncodedValue - StaticVirtualMethodContextSource.ContextFromFirstInterface]
};
}
+
+ public enum ResolveFlags
+ {
+ Variant = 0x1,
+ DefaultInterfaceImplementation = 0x2,
+ Static = 0x4,
+ IDynamicInterfaceCastable = 0x8,
+ }
}
}
diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
index c3f92d067dd243..20427987539c39 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
@@ -1066,10 +1066,14 @@ private static unsafe bool CacheMiss(MethodTable* pSourceType, MethodTable* pTar
bool result = TypeCast.AreTypesAssignableInternalUncached(pSourceType, pTargetType, variation, &newList);
//
- // Update the cache
+ // Update the cache. We only consider type-based conversion rules here.
+ // Therefore a negative result cannot rule out convertibility for IDynamicInterfaceCastable.
//
- nuint sourceAndVariation = (nuint)pSourceType + (uint)variation;
- s_castCache.TrySet(sourceAndVariation, (nuint)pTargetType, result);
+ if (result || !(pTargetType->IsInterface && pSourceType->IsIDynamicInterfaceCastable))
+ {
+ nuint sourceAndVariation = (nuint)pSourceType + (uint)variation;
+ s_castCache.TrySet(sourceAndVariation, (nuint)pTargetType, result);
+ }
return result;
}
@@ -1252,13 +1256,11 @@ internal static unsafe bool AreTypesAssignableInternalUncached(MethodTable* pSou
}
//
- // Update the cache
+ // Update the cache. We only consider type-based conversion rules here.
+ // Therefore a negative result cannot rule out convertibility for IDynamicInterfaceCastable.
//
- if (!pSourceType->IsIDynamicInterfaceCastable)
+ if (retObj != null || !(pTargetType->IsInterface && pSourceType->IsIDynamicInterfaceCastable))
{
- //
- // Update the cache
- //
nuint sourceAndVariation = (nuint)pSourceType + (uint)AssignmentVariation.BoxedSource;
s_castCache.TrySet(sourceAndVariation, (nuint)pTargetType, retObj != null);
}
@@ -1293,14 +1295,11 @@ private static unsafe object CheckCastAny_NoCacheLookup(MethodTable* pTargetType
obj = CheckCastClass(pTargetType, obj);
}
- if (!pSourceType->IsIDynamicInterfaceCastable)
- {
- //
- // Update the cache
- //
- nuint sourceAndVariation = (nuint)pSourceType + (uint)AssignmentVariation.BoxedSource;
- s_castCache.TrySet(sourceAndVariation, (nuint)pTargetType, true);
- }
+ //
+ // Update the cache
+ //
+ nuint sourceAndVariation = (nuint)pSourceType + (uint)AssignmentVariation.BoxedSource;
+ s_castCache.TrySet(sourceAndVariation, (nuint)pTargetType, true);
return obj;
}
diff --git a/src/coreclr/nativeaot/Runtime/EHHelpers.cpp b/src/coreclr/nativeaot/Runtime/EHHelpers.cpp
index 060e19f3c525e2..569cf36e84fa50 100644
--- a/src/coreclr/nativeaot/Runtime/EHHelpers.cpp
+++ b/src/coreclr/nativeaot/Runtime/EHHelpers.cpp
@@ -485,6 +485,9 @@ int32_t __stdcall RhpHardwareExceptionHandler(uintptr_t faultCode, uintptr_t fau
#else // TARGET_UNIX
+uintptr_t GetSSP(CONTEXT *pContext);
+void SetSSP(CONTEXT *pContext, uintptr_t ssp);
+
static bool g_ContinueOnFatalErrors = false;
// Set the runtime to continue search when encountering an unhandled runtime exception. Once done it is forever.
@@ -539,22 +542,16 @@ int32_t __stdcall RhpVectoredExceptionHandler(PEXCEPTION_POINTERS pExPtrs)
// When the CET is enabled, the interruption happens on the ret instruction in the calee.
// We need to "pop" rsp to the caller, as if the ret has consumed it.
interruptedContext->SetSp(interruptedContext->GetSp() + 8);
+ uintptr_t ssp = GetSSP(interruptedContext);
+ SetSSP(interruptedContext, ssp + 8);
}
// Change the IP to be at the original return site, as if we have returned to the caller.
// That IP is an interruptible safe point, so we can suspend right there.
- uintptr_t origIp = interruptedContext->GetIp();
interruptedContext->SetIp((uintptr_t)pThread->GetHijackedReturnAddress());
pThread->InlineSuspend(interruptedContext);
- if (areShadowStacksEnabled)
- {
- // Undo the "pop", so that the ret could now succeed.
- interruptedContext->SetSp(interruptedContext->GetSp() - 8);
- interruptedContext->SetIp(origIp);
- }
-
ASSERT(!pThread->IsHijacked());
return EXCEPTION_CONTINUE_EXECUTION;
}
diff --git a/src/coreclr/nativeaot/Runtime/HandleTableHelpers.cpp b/src/coreclr/nativeaot/Runtime/HandleTableHelpers.cpp
index 23e985357d343a..8eddc1d3440d26 100644
--- a/src/coreclr/nativeaot/Runtime/HandleTableHelpers.cpp
+++ b/src/coreclr/nativeaot/Runtime/HandleTableHelpers.cpp
@@ -70,3 +70,57 @@ FCIMPL2(void, RhUnregisterRefCountedHandleCallback, void * pCallout, MethodTable
RestrictedCallouts::UnregisterRefCountedHandleCallback(pCallout, pTypeFilter);
}
FCIMPLEND
+
+// This structure mirrors the managed type System.Runtime.InteropServices.ComWrappers.ManagedObjectWrapper.
+struct ManagedObjectWrapper
+{
+ intptr_t HolderHandle;
+ uint64_t RefCount;
+
+ int32_t UserDefinedCount;
+ void* /* ComInterfaceEntry */ UserDefined;
+ void* /* InternalComInterfaceDispatch* */ Dispatches;
+
+ int32_t /* CreateComInterfaceFlagsEx */ Flags;
+
+ uint32_t AddRef()
+ {
+ return GetComCount((uint64_t)PalInterlockedIncrement64((int64_t*)&RefCount));
+ }
+
+ static const uint64_t ComRefCountMask = 0x000000007fffffffUL;
+
+ static uint32_t GetComCount(uint64_t c)
+ {
+ return (uint32_t)(c & ComRefCountMask);
+ }
+};
+
+// This structure mirrors the managed type System.Runtime.InteropServices.ComWrappers.InternalComInterfaceDispatch.
+struct InternalComInterfaceDispatch
+{
+ void* Vtable;
+ ManagedObjectWrapper* _thisPtr;
+};
+
+static ManagedObjectWrapper* ToManagedObjectWrapper(void* dispatchPtr)
+{
+ return ((InternalComInterfaceDispatch*)dispatchPtr)->_thisPtr;
+}
+
+//
+// AddRef is implemented in native code so that it does not need to synchronize with the GC. This is important because Xaml
+// invokes AddRef while holding a lock that it *also* holds while a GC is in progress. If AddRef was managed, we would have
+// to synchronize with the GC before entering AddRef, which would deadlock with the other thread holding Xaml's lock.
+//
+static uint32_t __stdcall IUnknown_AddRef(void* pComThis)
+{
+ ManagedObjectWrapper* wrapper = ToManagedObjectWrapper(pComThis);
+ return wrapper->AddRef();
+}
+
+FCIMPL0(void*, RhGetIUnknownAddRef)
+{
+ return (void*)&IUnknown_AddRef;
+}
+FCIMPLEND
diff --git a/src/coreclr/nativeaot/Runtime/RestrictedCallouts.h b/src/coreclr/nativeaot/Runtime/RestrictedCallouts.h
index 2c1a2e61e0951b..cf0295db456038 100644
--- a/src/coreclr/nativeaot/Runtime/RestrictedCallouts.h
+++ b/src/coreclr/nativeaot/Runtime/RestrictedCallouts.h
@@ -97,6 +97,6 @@ class RestrictedCallouts
static CrstStatic s_sLock;
// Prototypes for the callouts.
- typedef void (F_CALL_CONV * GcRestrictedCallbackFunction)(uint32_t uiCondemnedGeneration);
+ typedef void (* GcRestrictedCallbackFunction)(uint32_t uiCondemnedGeneration);
typedef CLR_BOOL (* HandleTableRestrictedCallbackFunction)(Object * pObject);
};
diff --git a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkInline.h b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkInline.h
index 983f17a36aba0a..2380bacdf02a1b 100644
--- a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkInline.h
+++ b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkInline.h
@@ -30,6 +30,13 @@ FORCEINLINE int32_t PalInterlockedIncrement(_Inout_ int32_t volatile *pDst)
return result;
}
+FORCEINLINE int64_t PalInterlockedIncrement64(_Inout_ int64_t volatile *pDst)
+{
+ int64_t result = __sync_add_and_fetch(pDst, 1);
+ PalInterlockedOperationBarrier();
+ return result;
+}
+
FORCEINLINE int32_t PalInterlockedDecrement(_Inout_ int32_t volatile *pDst)
{
int32_t result = __sync_sub_and_fetch(pDst, 1);
diff --git a/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc b/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc
index b1a437d8b57ead..b12b4071593ab4 100644
--- a/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc
+++ b/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc
@@ -16,15 +16,6 @@
.macro NESTED_END Name, Section
LEAF_END \Name, \Section
-#if defined(__APPLE__)
- .set LOCAL_LABEL(\Name\()_Size), . - C_FUNC(\Name)
- .section __LD,__compact_unwind,regular,debug
- .quad C_FUNC(\Name)
- .long LOCAL_LABEL(\Name\()_Size)
- .long 0x04000000 # DWARF
- .quad 0
- .quad 0
-#endif
.endm
.macro PATCH_LABEL Name
diff --git a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkInline.h b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkInline.h
index 1f2a74dcd15100..595c7f663b9d13 100644
--- a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkInline.h
+++ b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkInline.h
@@ -67,6 +67,17 @@ FORCEINLINE int64_t PalInterlockedExchange64(_Inout_ int64_t volatile *pDst, int
iOldValue) != iOldValue);
return iOldValue;
}
+
+FORCEINLINE int64_t PalInterlockedIncrement64(_Inout_ int64_t volatile *Addend)
+{
+ int64_t Old;
+ do {
+ Old = *Addend;
+ } while (PalInterlockedCompareExchange64(Addend,
+ Old + 1,
+ Old) != Old);
+ return Old + 1;
+}
#else // HOST_X86
EXTERN_C int64_t _InterlockedExchange64(int64_t volatile *, int64_t);
#pragma intrinsic(_InterlockedExchange64)
@@ -74,6 +85,13 @@ FORCEINLINE int64_t PalInterlockedExchange64(_Inout_ int64_t volatile *pDst, int
{
return _InterlockedExchange64(pDst, iValue);
}
+
+EXTERN_C int64_t _InterlockedIncrement64(int64_t volatile *);
+#pragma intrinsic(_InterlockedIncrement64)
+FORCEINLINE int64_t PalInterlockedIncrement64(_Inout_ int64_t volatile *pDst)
+{
+ return _InterlockedIncrement64(pDst);
+}
#endif // HOST_X86
#if defined(HOST_AMD64) || defined(HOST_ARM64)
diff --git a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
index 86013f7a964d28..f7bfcd68bdad75 100644
--- a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
+++ b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
@@ -1006,3 +1006,25 @@ REDHAWK_PALEXPORT void PalFlushInstructionCache(_In_ void* pAddress, size_t size
FlushInstructionCache(GetCurrentProcess(), pAddress, size);
}
+#ifdef TARGET_AMD64
+uintptr_t GetSSP(CONTEXT *pContext)
+{
+ XSAVE_CET_U_FORMAT* pCET = (XSAVE_CET_U_FORMAT*)LocateXStateFeature(pContext, XSTATE_CET_U, NULL);
+ if ((pCET != NULL) && (pCET->Ia32CetUMsr != 0))
+ {
+ return pCET->Ia32Pl3SspMsr;
+ }
+
+ return 0;
+}
+
+void SetSSP(CONTEXT *pContext, uintptr_t ssp)
+{
+ XSAVE_CET_U_FORMAT* pCET = (XSAVE_CET_U_FORMAT*)LocateXStateFeature(pContext, XSTATE_CET_U, NULL);
+ if (pCET != NULL)
+ {
+ pCET->Ia32Pl3SspMsr = ssp;
+ pCET->Ia32CetUMsr = 1;
+ }
+}
+#endif // TARGET_AMD64
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml
index 507b4c14936921..6bfe8b6b9ffdda 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml
@@ -825,6 +825,10 @@
CP0001
T:System.Runtime.CompilerServices.StaticClassConstructionContext
+
+ CP0001
+ T:Internal.TypeSystem.LockFreeReaderHashtableOfPointers`2
+
CP0002
M:System.Reflection.MethodBase.GetParametersAsSpan
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
index 7db11a82041778..4e376c5b803922 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
@@ -493,7 +493,7 @@ public static bool IsDynamicType(RuntimeTypeHandle typeHandle)
public static unsafe IntPtr ResolveStaticDispatchOnType(RuntimeTypeHandle instanceType, RuntimeTypeHandle interfaceType, int slot, out RuntimeTypeHandle genericContext)
{
MethodTable* genericContextPtr = default;
- IntPtr result = RuntimeImports.RhResolveDispatchOnType(instanceType.ToMethodTable(), interfaceType.ToMethodTable(), checked((ushort)slot), &genericContextPtr);
+ IntPtr result = RuntimeImports.RhResolveStaticDispatchOnType(instanceType.ToMethodTable(), interfaceType.ToMethodTable(), checked((ushort)slot), &genericContextPtr);
if (result != IntPtr.Zero)
genericContext = new RuntimeTypeHandle(genericContextPtr);
else
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/SharedCodeHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/SharedCodeHelpers.cs
index 482a9a7b357a7e..172f7a6590e35d 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/SharedCodeHelpers.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/SharedCodeHelpers.cs
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Runtime;
+
using Debug = System.Diagnostics.Debug;
namespace Internal.Runtime.CompilerHelpers
@@ -12,15 +14,13 @@ internal static class SharedCodeHelpers
{
public static unsafe MethodTable* GetOrdinalInterface(MethodTable* pType, ushort interfaceIndex)
{
- Debug.Assert(interfaceIndex <= pType->NumInterfaces);
+ Debug.Assert(interfaceIndex < pType->NumInterfaces);
return pType->InterfaceMap[interfaceIndex];
}
public static unsafe MethodTable* GetCurrentSharedThunkContext()
{
- // TODO: We should return the current context from the ThunkPool
- // https://github.com/dotnet/runtimelab/issues/1442
- return null;
+ return (MethodTable*)RuntimeImports.GetCurrentInteropThunkContext();
}
}
}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/IDynamicInterfaceCastableSupport.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/IDynamicInterfaceCastableSupport.cs
index 54878128ff9823..a1e146fb1b0a8c 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/IDynamicInterfaceCastableSupport.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/IDynamicInterfaceCastableSupport.cs
@@ -4,6 +4,12 @@
using System;
using System.Runtime;
using System.Runtime.InteropServices;
+using System.Threading;
+
+using Internal.Runtime.Augments;
+using Internal.TypeSystem;
+
+using Debug = System.Diagnostics.Debug;
namespace Internal.Runtime
{
@@ -15,6 +21,8 @@ internal static bool IDynamicCastableIsInterfaceImplemented(IDynamicInterfaceCas
return instance.IsInterfaceImplemented(new RuntimeTypeHandle(interfaceType), throwIfNotImplemented);
}
+ private static readonly object s_thunkPoolHeap = RuntimeAugments.CreateThunksHeap(RuntimeImports.GetInteropCommonStubAddress());
+
[RuntimeExport("IDynamicCastableGetInterfaceImplementation")]
internal static IntPtr IDynamicCastableGetInterfaceImplementation(IDynamicInterfaceCastable instance, MethodTable* interfaceType, ushort slot)
{
@@ -28,11 +36,30 @@ internal static IntPtr IDynamicCastableGetInterfaceImplementation(IDynamicInterf
{
ThrowInvalidOperationException(implType);
}
- IntPtr result = RuntimeImports.RhResolveDispatchOnType(implType, interfaceType, slot);
+
+ MethodTable* genericContext = null;
+ IntPtr result = RuntimeImports.RhResolveDynamicInterfaceCastableDispatchOnType(implType, interfaceType, slot, &genericContext);
if (result == IntPtr.Zero)
{
IDynamicCastableGetInterfaceImplementationFailure(instance, interfaceType, implType);
}
+
+ if (genericContext != null)
+ {
+ if (!s_thunkHashtable.TryGetValue(new InstantiatingThunkKey(result, (nint)genericContext), out nint thunk))
+ {
+ thunk = RuntimeAugments.AllocateThunk(s_thunkPoolHeap);
+ RuntimeAugments.SetThunkData(s_thunkPoolHeap, thunk, (nint)genericContext, result);
+ nint thunkInHashtable = s_thunkHashtable.AddOrGetExisting(thunk);
+ if (thunkInHashtable != thunk)
+ {
+ RuntimeAugments.FreeThunk(s_thunkPoolHeap, thunk);
+ thunk = thunkInHashtable;
+ }
+ }
+
+ result = thunk;
+ }
return result;
}
@@ -67,5 +94,46 @@ private static void IDynamicCastableGetInterfaceImplementationFailure(object ins
throw new EntryPointNotFoundException();
}
+
+ private static readonly InstantiatingThunkHashtable s_thunkHashtable = new InstantiatingThunkHashtable();
+
+ private class InstantiatingThunkHashtable : LockFreeReaderHashtableOfPointers
+ {
+ protected override bool CompareKeyToValue(InstantiatingThunkKey key, nint value)
+ {
+ bool result = RuntimeAugments.TryGetThunkData(s_thunkPoolHeap, value, out nint context, out nint target);
+ Debug.Assert(result);
+ return key.Target == target && key.Context == context;
+ }
+
+ protected override bool CompareValueToValue(nint value1, nint value2)
+ {
+ bool result1 = RuntimeAugments.TryGetThunkData(s_thunkPoolHeap, value1, out nint context1, out nint target1);
+ Debug.Assert(result1);
+
+ bool result2 = RuntimeAugments.TryGetThunkData(s_thunkPoolHeap, value2, out nint context2, out nint target2);
+ Debug.Assert(result2);
+ return context1 == context2 && target1 == target2;
+ }
+
+ protected override nint ConvertIntPtrToValue(nint pointer) => pointer;
+ protected override nint ConvertValueToIntPtr(nint value) => value;
+ protected override nint CreateValueFromKey(InstantiatingThunkKey key) => throw new NotImplementedException();
+ protected override int GetKeyHashCode(InstantiatingThunkKey key) => HashCode.Combine(key.Target, key.Context);
+
+ protected override int GetValueHashCode(nint value)
+ {
+ bool result = RuntimeAugments.TryGetThunkData(s_thunkPoolHeap, value, out nint context, out nint target);
+ Debug.Assert(result);
+ return HashCode.Combine(target, context);
+ }
+ }
+
+ private struct InstantiatingThunkKey
+ {
+ public readonly nint Target;
+ public readonly nint Context;
+ public InstantiatingThunkKey(nint target, nint context) => (Target, Context) = (target, context);
+ }
}
}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
index fc97632716fd2a..06d92c3b8b5d5e 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
@@ -332,6 +332,9 @@
Utilities\LockFreeReaderHashtable.cs
+
+ Utilities\LockFreeReaderHashtableOfPointers.cs
+
System\Collections\Generic\LowLevelList.cs
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs
index cc33e85d73917c..87eb31d58022fe 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs
@@ -40,37 +40,36 @@ public abstract partial class ComWrappers
private static readonly Guid IID_IInspectable = new Guid(0xAF86E2E0, 0xB12D, 0x4c6a, 0x9C, 0x5A, 0xD7, 0xAA, 0x65, 0x10, 0x1E, 0x90);
private static readonly Guid IID_IWeakReferenceSource = new Guid(0x00000038, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46);
- private static readonly ConditionalWeakTable