diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index bd60f2e67ceacc..72af997c0c2543 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -15,7 +15,7 @@
]
},
"microsoft.dotnet.xharness.cli": {
- "version": "8.0.0-prerelease.23407.2",
+ "version": "8.0.0-prerelease.24060.1",
"commands": [
"xharness"
]
diff --git a/NuGet.config b/NuGet.config
index f34253e5b0e2fe..874a54ee27326c 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -9,9 +9,11 @@
+
-
-
+
+
+
diff --git a/docs/design/coreclr/botr/clr-abi.md b/docs/design/coreclr/botr/clr-abi.md
index 825ad5820a920e..9141613db0c0da 100644
--- a/docs/design/coreclr/botr/clr-abi.md
+++ b/docs/design/coreclr/botr/clr-abi.md
@@ -205,7 +205,7 @@ For non-rude thread abort, the VM walks the stack, running any catch handler tha
For example:
-```
+```cs
try { // try 1
try { // try 2
System.Threading.Thread.CurrentThread.Abort();
@@ -221,7 +221,7 @@ L:
In this case, if the address returned in catch 2 corresponding to label L is outside try 1, then the ThreadAbortException re-raised by the VM will not be caught by catch 1, as is expected. The JIT needs to insert a block such that this is the effective code generation:
-```
+```cs
try { // try 1
try { // try 2
System.Threading.Thread.CurrentThread.Abort();
@@ -238,7 +238,7 @@ L:
Similarly, the automatic re-raise address for a ThreadAbortException can't be within a finally handler, or the VM will abort the re-raise and swallow the exception. This can happen due to call-to-finally thunks marked as "cloned finally", as described above. For example (this is pseudo-assembly-code, not C#):
-```
+```cs
try { // try 1
try { // try 2
System.Threading.Thread.CurrentThread.Abort();
@@ -254,7 +254,7 @@ L:
This would generate something like:
-```
+```asm
// beginning of 'try 1'
// beginning of 'try 2'
System.Threading.Thread.CurrentThread.Abort();
@@ -279,7 +279,7 @@ Finally1:
Note that the JIT must already insert a "step" block so the finally will be called. However, this isn't sufficient to support ThreadAbortException processing, because "L1" is marked as "cloned finally". In this case, the JIT must insert another step block that is within "try 1" but outside the cloned finally block, that will allow for correct re-raise semantics. For example:
-```
+```asm
// beginning of 'try 1'
// beginning of 'try 2'
System.Threading.Thread.CurrentThread.Abort();
@@ -397,7 +397,7 @@ To implement this requirement, for any function with EH, we create a frame-local
Note that the since a slot on x86 is 4 bytes, the minimum size is 16 bytes. The idea is to have 1 slot for each handler that could be possibly be invoked at the same time. For example, for:
-```
+```cs
try {
...
} catch {
@@ -417,7 +417,7 @@ When calling a finally, we set the appropriate level to 0xFC (aka "finally call"
Thus, calling a finally from JIT generated code looks like:
-```
+```asm
mov dword ptr [L_02+0x4 ebp-10H], 0 // This must happen before the 0xFC is written
mov dword ptr [L_02+0x8 ebp-0CH], 252 // 0xFC
push G_M52300_IG07
@@ -428,7 +428,7 @@ In this case, `G_M52300_IG07` is not the address after the 'jmp', so a simple 'c
The code this finally returns to looks like this:
-```
+```asm
mov dword ptr [L_02+0x8 ebp-0CH], 0
jmp SHORT G_M52300_IG05
```
@@ -477,7 +477,7 @@ Because a main function body will **always** be on the stack when one of its fun
There is one "corner case" in the VM implementation of WantsReportOnlyLeaf model that has implications for the code the JIT is allowed to generate. Consider this function with nested exception handling:
-```
+```cs
public void runtest() {
try {
try {
@@ -804,3 +804,29 @@ In addition to the usual registers it also preserves all float registers and `rc
`CORINFO_HELP_DISPATCH_INDIRECT_CALL` takes the call address in `rax` and it reserves the right to use and trash `r10` and `r11`.
The JIT uses the dispatch helper on x64 whenever possible as it is expected that the code size benefits outweighs the less accurate branch prediction.
However, note that the use of `r11` in the dispatcher makes it incompatible with VSD calls where the JIT must fall back to the validator and a manual call.
+
+# Notes on Memset/Memcpy
+
+Generally, `memset` and `memcpy` do not provide any guarantees of atomicity. This implies that they should only be used when the memory being modified by `memset`/`memcpy` is not observable by any other thread (including GC), or when there are no atomicity requirements according to our [Memory Model](../../specs/Memory-model.md). It's especially important when we modify heap containing managed pointers - those must be updated atomically, e.g. using pointer-sized `mov` instruction (managed pointers are always aligned) - see [Atomic Memory Access](../../specs/Memory-model.md#Atomic-memory-accesses). It's worth noting that by "update" it's implied "set to zero", otherwise, we need a write barrier.
+
+Examples:
+
+```cs
+struct MyStruct
+{
+ long a;
+ string b;
+}
+
+void Test1(ref MyStruct m)
+{
+ // We're not allowed to use memset here
+ m = default;
+}
+
+MyStruct Test2()
+{
+ // We can use memset here
+ return default;
+}
+```
\ No newline at end of file
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index c8a893de7d463b..95c24b9f3675f5 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -90,30 +90,30 @@
45dd3a73dd5b64b010c4251303b3664bb30df029
-
+
https://github.com/dotnet/emsdk
- 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0
+ 2fc2ffd960930318f33fcaa690cbdbc55d72f52d
-
+
https://github.com/dotnet/emsdk
- 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0
+ 2fc2ffd960930318f33fcaa690cbdbc55d72f52d
-
+
https://github.com/dotnet/source-build-reference-packages
- 95f83e27806330fec09edd96e06bba3acabe3f35
+ 453a37ef7ae6c335cd49b3b9ab7713c87faeb265
-
+
https://github.com/dotnet/source-build-externals
- e844aa02a05b90d8cbe499676ec6ee0f19ec4980
+ 83274d94c7e2ff21081b0d75ecbec2da2241f831
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
@@ -121,121 +121,121 @@
73f0850939d96131c28cf6ea6ee5aacb4da0083a
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
https://github.com/dotnet/llvm-project
@@ -322,21 +322,21 @@
https://github.com/dotnet/runtime
edbd5c769a19798b6955050baccf99e6797d3208
-
+
https://github.com/dotnet/xharness
- 480b9159eb7e69b182a87581d5a336e97e0b6dae
+ a417169d3ba558fd6daa522f04e686574bbce520
-
+
https://github.com/dotnet/xharness
- 480b9159eb7e69b182a87581d5a336e97e0b6dae
+ a417169d3ba558fd6daa522f04e686574bbce520
-
+
https://github.com/dotnet/xharness
- 480b9159eb7e69b182a87581d5a336e97e0b6dae
+ a417169d3ba558fd6daa522f04e686574bbce520
-
+
https://github.com/dotnet/arcade
- 0aaeafef60933f87b0b50350313bb2fd77defb5d
+ 61ae141d2bf3534619265c8f691fd55dc3e75147
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
@@ -354,13 +354,13 @@
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
67613417f5e1af250e6ddfba79f8f2885d8e90fb
-
+
https://github.com/dotnet/hotreload-utils
- 5524f726f92ef862b415793758cebbd2a1950b70
+ 3b7da338c73b31b943c5512dcf0e2f6dd75f601c
-
+
https://github.com/dotnet/runtime-assets
- 57ca3048e3bf7c0755add6569809270290040f5d
+ 3b165c269b12cc194f48fde6a1a7694bece8931b
https://github.com/dotnet/roslyn
@@ -375,13 +375,13 @@
https://github.com/dotnet/roslyn
7b75981cf3bd520b86ec4ed00ec156c8bc48e4eb
-
+
https://github.com/dotnet/roslyn-analyzers
- b4d9a1334d5189172977ba8fddd00bda70161e4a
+ abef8ced132657943b7150f01a308e2199a17d5d
-
+
https://github.com/dotnet/roslyn-analyzers
- b4d9a1334d5189172977ba8fddd00bda70161e4a
+ abef8ced132657943b7150f01a308e2199a17d5d
https://github.com/dotnet/sdk
diff --git a/eng/Versions.props b/eng/Versions.props
index da037c2c7ca922..55ce55ada067df 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -1,11 +1,11 @@
- 8.0.1
+ 8.0.2
8
0
- 1
+ 2
8.0.100
7.0.$([MSBuild]::Add($(PatchVersion),14))
6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet7)').Build),11))
@@ -36,8 +36,8 @@
- 3.11.0-beta1.23525.2
- 8.0.0-preview.23525.2
+ 3.11.0-beta1.23614.1
+ 8.0.0-preview.23614.1
8.0.100
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 2.5.1-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
- 8.0.0-beta.23564.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 2.5.1-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
+ 8.0.0-beta.24059.4
6.0.0-preview.1.102
@@ -143,20 +143,20 @@
4.5.0
8.0.0-rc.1.23406.6
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
- 8.0.0-beta.23566.1
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
+ 8.0.0-beta.24060.2
1.0.0-prerelease.23566.3
1.0.0-prerelease.23566.3
@@ -183,10 +183,10 @@
1.1.0
17.4.0-preview-20220707-01
- 8.0.0-prerelease.23407.2
- 8.0.0-prerelease.23407.2
- 8.0.0-prerelease.23407.2
- 8.0.0-alpha.0.23570.2
+ 8.0.0-prerelease.24060.1
+ 8.0.0-prerelease.24060.1
+ 8.0.0-prerelease.24060.1
+ 8.0.0-alpha.0.24060.1
2.4.2
1.0.0
2.4.5
@@ -240,7 +240,7 @@
Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml
like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-8_0_100_Transport
-->
- 8.0.1
+ 8.0.2
$(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version)
1.1.87-gba258badda
@@ -258,7 +258,7 @@
3.1.7
1.0.406601
- 8.0.100
+ 8.0.101
$(MicrosoftDotnetSdkInternalVersion)
diff --git a/eng/common/darc-init.ps1 b/eng/common/darc-init.ps1
index 435e7641341b16..8fda30bdce2b09 100644
--- a/eng/common/darc-init.ps1
+++ b/eng/common/darc-init.ps1
@@ -1,6 +1,6 @@
param (
$darcVersion = $null,
- $versionEndpoint = 'https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16',
+ $versionEndpoint = 'https://maestro.dot.net/api/assets/darc-version?api-version=2019-01-16',
$verbosity = 'minimal',
$toolpath = $null
)
diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh
index 84c1d0cc2e75ac..c305ae6bd771ef 100755
--- a/eng/common/darc-init.sh
+++ b/eng/common/darc-init.sh
@@ -2,7 +2,7 @@
source="${BASH_SOURCE[0]}"
darcVersion=''
-versionEndpoint='https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16'
+versionEndpoint='https://maestro.dot.net/api/assets/darc-version?api-version=2019-01-16'
verbosity='minimal'
while [[ $# > 0 ]]; do
diff --git a/eng/common/post-build/add-build-to-channel.ps1 b/eng/common/post-build/add-build-to-channel.ps1
index de2d957922a653..49938f0c89f768 100644
--- a/eng/common/post-build/add-build-to-channel.ps1
+++ b/eng/common/post-build/add-build-to-channel.ps1
@@ -2,7 +2,7 @@ param(
[Parameter(Mandatory=$true)][int] $BuildId,
[Parameter(Mandatory=$true)][int] $ChannelId,
[Parameter(Mandatory=$true)][string] $MaestroApiAccessToken,
- [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com',
+ [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net',
[Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16'
)
diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1
index 8508397d77640e..1e779fec4dd1ea 100644
--- a/eng/common/post-build/publish-using-darc.ps1
+++ b/eng/common/post-build/publish-using-darc.ps1
@@ -3,7 +3,7 @@ param(
[Parameter(Mandatory=$true)][int] $PublishingInfraVersion,
[Parameter(Mandatory=$true)][string] $AzdoToken,
[Parameter(Mandatory=$true)][string] $MaestroToken,
- [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com',
+ [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net',
[Parameter(Mandatory=$true)][string] $WaitPublishingFinish,
[Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters,
[Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters
diff --git a/eng/common/post-build/trigger-subscriptions.ps1 b/eng/common/post-build/trigger-subscriptions.ps1
index 55dea518ac5850..ac9a95778fcd9e 100644
--- a/eng/common/post-build/trigger-subscriptions.ps1
+++ b/eng/common/post-build/trigger-subscriptions.ps1
@@ -2,7 +2,7 @@ param(
[Parameter(Mandatory=$true)][string] $SourceRepo,
[Parameter(Mandatory=$true)][int] $ChannelId,
[Parameter(Mandatory=$true)][string] $MaestroApiAccessToken,
- [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com',
+ [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net',
[Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16'
)
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index e20ee3a983cb05..e24ca2f46f98f9 100644
--- a/eng/common/templates/job/job.yml
+++ b/eng/common/templates/job/job.yml
@@ -136,7 +136,7 @@ jobs:
condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
- ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}:
- - task: NuGetAuthenticate@0
+ - task: NuGetAuthenticate@1
- ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}:
- task: DownloadPipelineArtifact@2
diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml
index 42017109f374d6..fa5446c093dd11 100644
--- a/eng/common/templates/job/publish-build-assets.yml
+++ b/eng/common/templates/job/publish-build-assets.yml
@@ -72,7 +72,7 @@ jobs:
condition: ${{ parameters.condition }}
continueOnError: ${{ parameters.continueOnError }}
- - task: NuGetAuthenticate@0
+ - task: NuGetAuthenticate@1
- task: PowerShell@2
displayName: Publish Build Assets
@@ -81,7 +81,7 @@ jobs:
arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet
/p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests'
/p:BuildAssetRegistryToken=$(MaestroAccessToken)
- /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com
+ /p:MaestroApiEndpoint=https://maestro.dot.net
/p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }}
/p:OfficialBuildId=$(Build.BuildNumber)
condition: ${{ parameters.condition }}
diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml
index c24193acfc981f..173914f2364a70 100644
--- a/eng/common/templates/post-build/common-variables.yml
+++ b/eng/common/templates/post-build/common-variables.yml
@@ -7,7 +7,7 @@ variables:
# Default Maestro++ API Endpoint and API Version
- name: MaestroApiEndPoint
- value: "https://maestro-prod.westus2.cloudapp.azure.com"
+ value: "https://maestro.dot.net"
- name: MaestroApiAccessToken
value: $(MaestroAccessToken)
- name: MaestroApiVersion
diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml
index ef720f9d781989..3f74abf7ce0f8a 100644
--- a/eng/common/templates/post-build/post-build.yml
+++ b/eng/common/templates/post-build/post-build.yml
@@ -169,7 +169,7 @@ stages:
# This is necessary whenever we want to publish/restore to an AzDO private feed
# Since sdk-task.ps1 tries to restore packages we need to do this authentication here
# otherwise it'll complain about accessing a private feed.
- - task: NuGetAuthenticate@0
+ - task: NuGetAuthenticate@1
displayName: 'Authenticate to AzDO Feeds'
# Signing validation will optionally work with the buildmanifest file which is downloaded from
@@ -266,7 +266,7 @@ stages:
BARBuildId: ${{ parameters.BARBuildId }}
PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
- - task: NuGetAuthenticate@0
+ - task: NuGetAuthenticate@1
- task: PowerShell@2
displayName: Publish Using Darc
diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1
index fdd0cbb91f8596..eb188cfda415b4 100644
--- a/eng/common/tools.ps1
+++ b/eng/common/tools.ps1
@@ -601,7 +601,15 @@ function InitializeBuildTool() {
ExitWithExitCode 1
}
$dotnetPath = Join-Path $dotnetRoot (GetExecutableFileName 'dotnet')
- $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = 'net8.0' }
+
+ # Use override if it exists - commonly set by source-build
+ if ($null -eq $env:_OverrideArcadeInitializeBuildToolFramework) {
+ $initializeBuildToolFramework="net8.0"
+ } else {
+ $initializeBuildToolFramework=$env:_OverrideArcadeInitializeBuildToolFramework
+ }
+
+ $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = $initializeBuildToolFramework }
} elseif ($msbuildEngine -eq "vs") {
try {
$msbuildPath = InitializeVisualStudioMSBuild -install:$restore
diff --git a/eng/common/tools.sh b/eng/common/tools.sh
index e8d478943341df..3392e3a99921f7 100755
--- a/eng/common/tools.sh
+++ b/eng/common/tools.sh
@@ -341,7 +341,12 @@ function InitializeBuildTool {
# return values
_InitializeBuildTool="$_InitializeDotNetCli/dotnet"
_InitializeBuildToolCommand="msbuild"
- _InitializeBuildToolFramework="net8.0"
+ # use override if it exists - commonly set by source-build
+ if [[ "${_OverrideArcadeInitializeBuildToolFramework:-x}" == "x" ]]; then
+ _InitializeBuildToolFramework="net8.0"
+ else
+ _InitializeBuildToolFramework="${_OverrideArcadeInitializeBuildToolFramework}"
+ fi
}
# Set RestoreNoCache as a workaround for https://github.com/NuGet/Home/issues/3116
diff --git a/eng/pipelines/common/restore-internal-tools.yml b/eng/pipelines/common/restore-internal-tools.yml
index eead4b67c30f64..fdec41da53da55 100644
--- a/eng/pipelines/common/restore-internal-tools.yml
+++ b/eng/pipelines/common/restore-internal-tools.yml
@@ -1,5 +1,5 @@
steps:
- - task: NuGetAuthenticate@0
+ - task: NuGetAuthenticate@1
inputs:
nuGetServiceConnections: 'devdiv/dotnet-core-internal-tooling'
forceReinstallCredentialProvider: true
diff --git a/eng/pipelines/common/templates/browser-wasm-build-tests.yml b/eng/pipelines/common/templates/browser-wasm-build-tests.yml
index 28d659e1607f48..742ad88de1c80a 100644
--- a/eng/pipelines/common/templates/browser-wasm-build-tests.yml
+++ b/eng/pipelines/common/templates/browser-wasm-build-tests.yml
@@ -110,7 +110,7 @@ jobs:
/p:InstallWorkloadForTesting=true
/p:WasmSkipMissingRuntimePackBuild=true
/p:PreparePackagesForWorkloadInstall=false
- timeoutInMinutes: 120
+ timeoutInMinutes: 180
condition: >-
or(
eq(variables['alwaysRunVar'], true),
diff --git a/eng/pipelines/coreclr/ci.yml b/eng/pipelines/coreclr/ci.yml
index 209314a136702f..adf052b014f455 100644
--- a/eng/pipelines/coreclr/ci.yml
+++ b/eng/pipelines/coreclr/ci.yml
@@ -155,13 +155,3 @@ extends:
readyToRun: true
displayNameArgs: R2R_CG2
liveLibrariesBuildConfig: Release
-
- #
- # Formatting
- #
- - template: /eng/pipelines/common/platform-matrix.yml
- parameters:
- jobTemplate: /eng/pipelines/coreclr/templates/format-job.yml
- platforms:
- - linux_x64
- - windows_x64
diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml
index 240c010b8c9da5..8e5ddd36759581 100644
--- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml
+++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml
@@ -44,7 +44,7 @@ jobs:
# Android arm64
- ${{ if in(parameters.platform, 'android_arm64') }}:
- - Windows.10.Amd64.Android.Open
+ - Windows.11.Amd64.Android.Open
# Android x64
- ${{ if in(parameters.platform, 'android_x64') }}:
@@ -86,9 +86,9 @@ jobs:
# Linux musl arm32
- ${{ if eq(parameters.platform, 'linux_musl_arm') }}:
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- - (Alpine.315.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7-20230807201723-7ea784e
+ - (Alpine.315.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- - (Alpine.315.Arm32)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7-20230807201723-7ea784e
+ - (Alpine.315.Arm32)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.15-helix-arm32v7
# Linux musl arm64
- ${{ if eq(parameters.platform, 'linux_musl_arm64') }}:
diff --git a/eng/pipelines/installer/jobs/steps/build-linux-package.yml b/eng/pipelines/installer/jobs/steps/build-linux-package.yml
index 645b3edefa7ef5..a5645af3d9ccd3 100644
--- a/eng/pipelines/installer/jobs/steps/build-linux-package.yml
+++ b/eng/pipelines/installer/jobs/steps/build-linux-package.yml
@@ -8,7 +8,7 @@ parameters:
steps:
## Run NuGet Authentication for each of the side containers
- ${{ if ne(variables['System.TeamProject'], 'public') }}:
- - task: NuGetAuthenticate@0
+ - task: NuGetAuthenticate@1
target: ${{ parameters.target }}
- script: |
$(Build.SourcesDirectory)/build.sh \
diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml
index 987d7f99c41f4a..dd80cdc85095ad 100644
--- a/eng/pipelines/libraries/helix-queues-setup.yml
+++ b/eng/pipelines/libraries/helix-queues-setup.yml
@@ -101,7 +101,7 @@ jobs:
- ${{ if in(parameters.platform, 'android_x86', 'android_x64', 'linux_bionic_x64') }}:
- Ubuntu.1804.Amd64.Android.29.Open
- ${{ if in(parameters.platform, 'android_arm', 'android_arm64', 'linux_bionic_arm64') }}:
- - Windows.10.Amd64.Android.Open
+ - Windows.11.Amd64.Android.Open
# iOS Simulator/Mac Catalyst arm64
- ${{ if in(parameters.platform, 'maccatalyst_arm64', 'iossimulator_arm64') }}:
diff --git a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml
index c6d1624603fe1c..908f2b64c71c22 100644
--- a/eng/pipelines/official/jobs/prepare-signed-artifacts.yml
+++ b/eng/pipelines/official/jobs/prepare-signed-artifacts.yml
@@ -26,7 +26,7 @@ jobs:
fetchDepth: 20
- ${{ if eq(parameters.isOfficialBuild, true) }}:
- - task: NuGetAuthenticate@0
+ - task: NuGetAuthenticate@1
- task: MicroBuildSigningPlugin@2
displayName: Install MicroBuild plugin for Signing
diff --git a/eng/testing/performance/performance-setup.ps1 b/eng/testing/performance/performance-setup.ps1
index 8a8cd269dbe454..c18445bff8aaec 100644
--- a/eng/testing/performance/performance-setup.ps1
+++ b/eng/testing/performance/performance-setup.ps1
@@ -51,7 +51,7 @@ if ($Internal) {
"perftiger_crossgen" { $Queue = "Windows.10.Amd64.19H1.Tiger.Perf" }
"perfowl" { $Queue = "Windows.10.Amd64.20H2.Owl.Perf" }
"perfsurf" { $Queue = "Windows.10.Arm64.Perf.Surf" }
- "perfpixel4a" { $Queue = "Windows.10.Amd64.Pixel.Perf" }
+ "perfpixel4a" { $Queue = "Windows.11.Amd64.Pixel.Perf" }
"perfampere" { $Queue = "Windows.Server.Arm64.Perf" }
"cloudvm" { $Queue = "Windows.10.Amd64" }
Default { $Queue = "Windows.10.Amd64.19H1.Tiger.Perf" }
diff --git a/eng/testing/performance/performance-setup.sh b/eng/testing/performance/performance-setup.sh
index c53ca6924b97b4..4853f0e6fb3bdb 100755
--- a/eng/testing/performance/performance-setup.sh
+++ b/eng/testing/performance/performance-setup.sh
@@ -275,7 +275,7 @@ if [[ "$internal" == true ]]; then
extra_benchmark_dotnet_arguments=
if [[ "$logical_machine" == "perfiphone12mini" ]]; then
- queue=OSX.1015.Amd64.Iphone.Perf
+ queue=OSX.13.Amd64.Iphone.Perf
elif [[ "$logical_machine" == "perfampere" ]]; then
queue=Ubuntu.2004.Arm64.Perf
elif [[ "$logical_machine" == "cloudvm" ]]; then
diff --git a/global.json b/global.json
index 517059ae7a3859..13f92203054630 100644
--- a/global.json
+++ b/global.json
@@ -1,16 +1,16 @@
{
"sdk": {
- "version": "8.0.100",
+ "version": "8.0.101",
"allowPrerelease": true,
"rollForward": "major"
},
"tools": {
- "dotnet": "8.0.100"
+ "dotnet": "8.0.101"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23564.4",
- "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23564.4",
- "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.23564.4",
+ "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24059.4",
+ "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24059.4",
+ "Microsoft.DotNet.SharedFramework.Sdk": "8.0.0-beta.24059.4",
"Microsoft.Build.NoTargets": "3.7.0",
"Microsoft.Build.Traversal": "3.4.0",
"Microsoft.NET.Sdk.IL": "8.0.0-rc.1.23406.6"
diff --git a/src/coreclr/debug/createdump/crashinfo.cpp b/src/coreclr/debug/createdump/crashinfo.cpp
index 8af6ec4a54f5bd..996f3a81935d0f 100644
--- a/src/coreclr/debug/createdump/crashinfo.cpp
+++ b/src/coreclr/debug/createdump/crashinfo.cpp
@@ -9,6 +9,9 @@ typedef HINSTANCE (PALAPI_NOEXPORT *PFN_REGISTER_MODULE)(LPCSTR); /* u
// This is for the PAL_VirtualUnwindOutOfProc read memory adapter.
CrashInfo* g_crashInfo;
+// This is the NativeAOT DotNetRuntimeDebugHeader signature
+uint8_t g_debugHeaderCookie[4] = { 0x44, 0x4E, 0x44, 0x48 };
+
static bool ModuleInfoCompare(const ModuleInfo* lhs, const ModuleInfo* rhs) { return lhs->BaseAddress() < rhs->BaseAddress(); }
CrashInfo::CrashInfo(const CreateDumpOptions& options) :
@@ -30,6 +33,7 @@ CrashInfo::CrashInfo(const CreateDumpOptions& options) :
m_enumMemoryPagesAdded(0)
{
g_crashInfo = this;
+ m_runtimeBaseAddress = 0;
#ifdef __APPLE__
m_task = 0;
#else
diff --git a/src/coreclr/debug/createdump/crashinfomac.cpp b/src/coreclr/debug/createdump/crashinfomac.cpp
index 90a31f106d6845..89c71c9e586c85 100644
--- a/src/coreclr/debug/createdump/crashinfomac.cpp
+++ b/src/coreclr/debug/createdump/crashinfomac.cpp
@@ -3,6 +3,8 @@
#include "createdump.h"
+extern uint8_t g_debugHeaderCookie[4];
+
int g_readProcessMemoryResult = KERN_SUCCESS;
bool
@@ -263,6 +265,24 @@ void CrashInfo::VisitModule(MachOModule& module)
}
}
}
+ else if (m_appModel == AppModelType::NativeAOT)
+ {
+ uint64_t symbolOffset;
+ if (module.TryLookupSymbol("DotNetRuntimeDebugHeader", &symbolOffset))
+ {
+ m_coreclrPath = GetDirectory(module.Name());
+ m_runtimeBaseAddress = module.BaseAddress();
+
+ uint8_t cookie[sizeof(g_debugHeaderCookie)];
+ if (ReadMemory((void*)(module.BaseAddress() + symbolOffset), cookie, sizeof(cookie)))
+ {
+ if (memcmp(cookie, g_debugHeaderCookie, sizeof(g_debugHeaderCookie)) == 0)
+ {
+ TRACE("Found valid NativeAOT runtime module\n");
+ }
+ }
+ }
+ }
}
// VisitSegment is called for each segment of the module
module.EnumerateSegments();
diff --git a/src/coreclr/debug/createdump/crashinfounix.cpp b/src/coreclr/debug/createdump/crashinfounix.cpp
index 70b2ddb270d74f..24b975e3d65559 100644
--- a/src/coreclr/debug/createdump/crashinfounix.cpp
+++ b/src/coreclr/debug/createdump/crashinfounix.cpp
@@ -8,6 +8,7 @@
#endif
extern CrashInfo* g_crashInfo;
+extern uint8_t g_debugHeaderCookie[4];
int g_readProcessMemoryErrno = 0;
@@ -383,6 +384,27 @@ CrashInfo::VisitModule(uint64_t baseAddress, std::string& moduleName)
}
}
}
+ else if (m_appModel == AppModelType::NativeAOT)
+ {
+ if (PopulateForSymbolLookup(baseAddress))
+ {
+ uint64_t symbolOffset;
+ if (TryLookupSymbol("DotNetRuntimeDebugHeader", &symbolOffset))
+ {
+ m_coreclrPath = GetDirectory(moduleName);
+ m_runtimeBaseAddress = baseAddress;
+
+ uint8_t cookie[sizeof(g_debugHeaderCookie)];
+ if (ReadMemory((void*)(baseAddress + symbolOffset), cookie, sizeof(cookie)))
+ {
+ if (memcmp(cookie, g_debugHeaderCookie, sizeof(g_debugHeaderCookie)) == 0)
+ {
+ TRACE("Found valid NativeAOT runtime module\n");
+ }
+ }
+ }
+ }
+ }
}
EnumerateProgramHeaders(baseAddress);
}
diff --git a/src/coreclr/debug/createdump/dumpwriter.cpp b/src/coreclr/debug/createdump/dumpwriter.cpp
index 5153ba790154ff..0e39b52b3a7d4c 100644
--- a/src/coreclr/debug/createdump/dumpwriter.cpp
+++ b/src/coreclr/debug/createdump/dumpwriter.cpp
@@ -39,7 +39,8 @@ DumpWriter::WriteDiagInfo(size_t size)
SpecialDiagInfoHeader header = {
{SPECIAL_DIAGINFO_SIGNATURE},
SPECIAL_DIAGINFO_VERSION,
- m_crashInfo.ExceptionRecord()
+ m_crashInfo.ExceptionRecord(),
+ m_crashInfo.RuntimeBaseAddress()
};
if (!WriteData(&header, sizeof(header))) {
return false;
diff --git a/src/coreclr/debug/createdump/specialdiaginfo.h b/src/coreclr/debug/createdump/specialdiaginfo.h
index a857129c9c91ff..84f79f00a160df 100644
--- a/src/coreclr/debug/createdump/specialdiaginfo.h
+++ b/src/coreclr/debug/createdump/specialdiaginfo.h
@@ -8,11 +8,11 @@
// ******************************************************************************
// This is a special memory region added to ELF and MachO dumps that contains extra diagnostics
-// information like the exception record for a crash for a NativeAOT app. The exception record
-// contains the pointer to the JSON formatted crash info.
+// information like the exception record address for a NativeAOT app crash or the runtime module
+// base address. The exception record contains the pointer to the JSON formatted crash info.
#define SPECIAL_DIAGINFO_SIGNATURE "DIAGINFOHEADER"
-#define SPECIAL_DIAGINFO_VERSION 1
+#define SPECIAL_DIAGINFO_VERSION 2
#ifdef __APPLE__
const uint64_t SpecialDiagInfoAddress = 0x7fffffff10000000;
@@ -31,4 +31,5 @@ struct SpecialDiagInfoHeader
char Signature[16];
int32_t Version;
uint64_t ExceptionRecordAddress;
+ uint64_t RuntimeBaseAddress;
};
diff --git a/src/coreclr/debug/daccess/request_svr.cpp b/src/coreclr/debug/daccess/request_svr.cpp
index ac0010e3e9af90..d1dd6f046e8370 100644
--- a/src/coreclr/debug/daccess/request_svr.cpp
+++ b/src/coreclr/debug/daccess/request_svr.cpp
@@ -335,7 +335,7 @@ HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount)
for (int i = 0; i < heaps; ++i)
{
// Basic heap info.
- TADDR heapAddress = HeapTableIndex(g_gcDacGlobals->g_heaps, i);
+ TADDR heapAddress = HeapTableIndex(g_gcDacGlobals->g_heaps, i);
dac_gc_heap heap = LoadGcHeapData(heapAddress);
dac_gc_heap* pHeap = &heap;
dac_generation gen0 = ServerGenerationTableIndex(heapAddress, 0);
@@ -395,17 +395,16 @@ HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount)
seg = gen0.start_segment;
for (; seg && (j < count); ++j)
{
+ pHeaps[i].Segments[j].Generation = CorDebug_Gen0;
pHeaps[i].Segments[j].Start = (CORDB_ADDRESS)seg->mem;
if (seg.GetAddr() == pHeap->ephemeral_heap_segment.GetAddr())
{
pHeaps[i].Segments[j].End = (CORDB_ADDRESS)pHeap->alloc_allocated;
pHeaps[i].EphemeralSegment = j;
- pHeaps[i].Segments[j].Generation = CorDebug_Gen0;
}
else
{
pHeaps[i].Segments[j].End = (CORDB_ADDRESS)seg->allocated;
- pHeaps[i].Segments[j].Generation = seg->flags & HEAP_SEGMENT_FLAGS_READONLY ? CorDebug_NonGC : CorDebug_Gen2;;
}
seg = seg->next;
@@ -471,11 +470,11 @@ void DacFreeRegionEnumerator::AddServerRegions()
TADDR heapAddress = (TADDR)HeapTableIndex(g_gcDacGlobals->g_heaps, i);
if (heapAddress == 0)
continue;
-
+
dac_gc_heap heap = LoadGcHeapData(heapAddress);
for (int i = 0; i < count_free_region_kinds; i++)
AddSegmentList(heap.free_regions[i].head_free_region, FreeRegionKind::FreeRegion, i);
-
+
AddSegmentList(heap.freeable_soh_segment, FreeRegionKind::FreeSohSegment, i);
AddSegmentList(heap.freeable_uoh_segment, FreeRegionKind::FreeUohSegment, i);
}
diff --git a/src/coreclr/debug/ee/amd64/walker.cpp b/src/coreclr/debug/ee/amd64/walker.cpp
index 79f0952dee1c47..815366def5b0d6 100644
--- a/src/coreclr/debug/ee/amd64/walker.cpp
+++ b/src/coreclr/debug/ee/amd64/walker.cpp
@@ -929,7 +929,6 @@ void NativeWalker::DecodeInstructionForPatchSkip(const BYTE *address, Instructio
case 0x45:
case 0x46:
case 0x47:
- done = true;
break;
// REX register extension prefixes with W
@@ -942,7 +941,6 @@ void NativeWalker::DecodeInstructionForPatchSkip(const BYTE *address, Instructio
case 0x4e:
case 0x4f:
W = true;
- done = true;
break;
default:
diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h
index eb190f97f0e479..dda0d1871e4bf1 100644
--- a/src/coreclr/jit/codegen.h
+++ b/src/coreclr/jit/codegen.h
@@ -1226,6 +1226,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#ifndef TARGET_X86
void genCodeForInitBlkHelper(GenTreeBlk* initBlkNode);
#endif
+ void genCodeForInitBlkLoop(GenTreeBlk* initBlkNode);
void genCodeForInitBlkRepStos(GenTreeBlk* initBlkNode);
void genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode);
void genJumpTable(GenTree* tree);
diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp
index 5434ef7b722ef9..562dad738bd3e1 100644
--- a/src/coreclr/jit/codegenarmarch.cpp
+++ b/src/coreclr/jit/codegenarmarch.cpp
@@ -3114,6 +3114,72 @@ void CodeGen::genCodeForInitBlkHelper(GenTreeBlk* initBlkNode)
genEmitHelperCall(CORINFO_HELP_MEMSET, 0, EA_UNKNOWN);
}
+//------------------------------------------------------------------------
+// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop.
+// It's needed for cases when size is too big to unroll and we're not allowed
+// to use memset call due to atomicity requirements.
+//
+// Arguments:
+// initBlkNode - the GT_STORE_BLK node
+//
+void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode)
+{
+ GenTree* const dstNode = initBlkNode->Addr();
+ genConsumeReg(dstNode);
+ const regNumber dstReg = dstNode->GetRegNum();
+
+#ifndef TARGET_ARM64
+ GenTree* const zeroNode = initBlkNode->Data();
+ genConsumeReg(zeroNode);
+ const regNumber zeroReg = zeroNode->GetRegNum();
+#else
+ const regNumber zeroReg = REG_ZR;
+#endif
+
+ if (initBlkNode->IsVolatile())
+ {
+ // issue a full memory barrier before a volatile initBlock Operation
+ instGen_MemoryBarrier();
+ }
+
+ // str xzr, [dstReg]
+ // mov offsetReg,
+ //.LOOP:
+ // str xzr, [dstReg, offsetReg]
+ // subs offsetReg, offsetReg, #8
+ // bne .LOOP
+
+ const unsigned size = initBlkNode->GetLayout()->GetSize();
+ assert((size >= TARGET_POINTER_SIZE) && ((size % TARGET_POINTER_SIZE) == 0));
+
+ // The loop is reversed - it makes it smaller.
+ // Although, we zero the first pointer before the loop (the loop doesn't zero it)
+ // it works as a nullcheck, otherwise the first iteration would try to access
+ // "null + potentially large offset" and hit AV.
+ GetEmitter()->emitIns_R_R(INS_str, EA_PTRSIZE, zeroReg, dstReg);
+ if (size > TARGET_POINTER_SIZE)
+ {
+ // Extend liveness of dstReg in case if it gets killed by the store.
+ gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet());
+
+ const regNumber offsetReg = initBlkNode->GetSingleTempReg();
+ instGen_Set_Reg_To_Imm(EA_PTRSIZE, offsetReg, size - TARGET_POINTER_SIZE);
+
+ BasicBlock* loop = genCreateTempLabel();
+ genDefineTempLabel(loop);
+
+ GetEmitter()->emitIns_R_R_R(INS_str, EA_PTRSIZE, zeroReg, dstReg, offsetReg);
+#ifdef TARGET_ARM64
+ GetEmitter()->emitIns_R_R_I(INS_subs, EA_PTRSIZE, offsetReg, offsetReg, TARGET_POINTER_SIZE);
+#else
+ GetEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, offsetReg, offsetReg, TARGET_POINTER_SIZE, INS_FLAGS_SET);
+#endif
+ inst_JMP(EJ_ne, loop);
+
+ gcInfo.gcMarkRegSetNpt(genRegMask(dstReg));
+ }
+}
+
//------------------------------------------------------------------------
// genCall: Produce code for a GT_CALL node
//
@@ -4384,6 +4450,11 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp)
genCodeForCpObj(blkOp->AsBlk());
break;
+ case GenTreeBlk::BlkOpKindLoop:
+ assert(!isCopyBlk);
+ genCodeForInitBlkLoop(blkOp);
+ break;
+
case GenTreeBlk::BlkOpKindHelper:
assert(!blkOp->gtBlkOpGcUnsafe);
if (isCopyBlk)
diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp
index 33bd2a77486c65..2f7444e0825ae4 100644
--- a/src/coreclr/jit/codegenloongarch64.cpp
+++ b/src/coreclr/jit/codegenloongarch64.cpp
@@ -6375,6 +6375,54 @@ void CodeGen::genCodeForInitBlkHelper(GenTreeBlk* initBlkNode)
genEmitHelperCall(CORINFO_HELP_MEMSET, 0, EA_UNKNOWN);
}
+//------------------------------------------------------------------------
+// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop.
+// It's needed for cases when size is too big to unroll and we're not allowed
+// to use memset call due to atomicity requirements.
+//
+// Arguments:
+// initBlkNode - the GT_STORE_BLK node
+//
+void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode)
+{
+ GenTree* const dstNode = initBlkNode->Addr();
+ genConsumeReg(dstNode);
+ const regNumber dstReg = dstNode->GetRegNum();
+
+ if (initBlkNode->IsVolatile())
+ {
+ // issue a full memory barrier before a volatile initBlock Operation
+ instGen_MemoryBarrier();
+ }
+
+ const unsigned size = initBlkNode->GetLayout()->GetSize();
+ assert((size >= TARGET_POINTER_SIZE) && ((size % TARGET_POINTER_SIZE) == 0));
+
+ // The loop is reversed - it makes it smaller.
+ // Although, we zero the first pointer before the loop (the loop doesn't zero it)
+ // it works as a nullcheck, otherwise the first iteration would try to access
+ // "null + potentially large offset" and hit AV.
+ GetEmitter()->emitIns_R_R_I(INS_st_d, EA_PTRSIZE, REG_R0, dstReg, 0);
+ if (size > TARGET_POINTER_SIZE)
+ {
+ // Extend liveness of dstReg in case if it gets killed by the store.
+ gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet());
+
+ const regNumber offsetReg = initBlkNode->GetSingleTempReg();
+ instGen_Set_Reg_To_Imm(EA_PTRSIZE, offsetReg, size - TARGET_POINTER_SIZE);
+
+ // loop begin:
+ // *(dstReg + offsetReg) = 0
+ GetEmitter()->emitIns_R_R_R(INS_stx_d, EA_PTRSIZE, REG_R0, dstReg, offsetReg);
+ // offsetReg = offsetReg - 8
+ GetEmitter()->emitIns_R_R_I(INS_addi_d, EA_PTRSIZE, offsetReg, offsetReg, -8);
+ // if (offsetReg != 0) goto loop;
+ GetEmitter()->emitIns_R_I(INS_bnez, EA_8BYTE, offsetReg, -2 << 2);
+
+ gcInfo.gcMarkRegSetNpt(genRegMask(dstReg));
+ }
+}
+
// Generate code for a load from some address + offset
// base: tree node which can be either a local address or arbitrary node
// offset: distance from the base from which to load
@@ -7286,6 +7334,11 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp)
genCodeForCpObj(blkOp->AsBlk());
break;
+ case GenTreeBlk::BlkOpKindLoop:
+ assert(!isCopyBlk);
+ genCodeForInitBlkLoop(blkOp);
+ break;
+
case GenTreeBlk::BlkOpKindHelper:
if (isCopyBlk)
{
diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp
index 39d25e316e529e..df5b47554d8b95 100644
--- a/src/coreclr/jit/codegenriscv64.cpp
+++ b/src/coreclr/jit/codegenriscv64.cpp
@@ -5958,6 +5958,61 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode)
}
}
+//------------------------------------------------------------------------
+// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop.
+// It's needed for cases when size is too big to unroll and we're not allowed
+// to use memset call due to atomicity requirements.
+//
+// Arguments:
+// initBlkNode - the GT_STORE_BLK node
+//
+void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode)
+{
+ GenTree* const dstNode = initBlkNode->Addr();
+ genConsumeReg(dstNode);
+ const regNumber dstReg = dstNode->GetRegNum();
+
+ if (initBlkNode->IsVolatile())
+ {
+ // issue a full memory barrier before a volatile initBlock Operation
+ instGen_MemoryBarrier();
+ }
+
+ const unsigned size = initBlkNode->GetLayout()->GetSize();
+ assert((size >= TARGET_POINTER_SIZE) && ((size % TARGET_POINTER_SIZE) == 0));
+
+ // The loop is reversed - it makes it smaller.
+ // Although, we zero the first pointer before the loop (the loop doesn't zero it)
+ // it works as a nullcheck, otherwise the first iteration would try to access
+ // "null + potentially large offset" and hit AV.
+ GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_R0, dstReg, 0);
+ if (size > TARGET_POINTER_SIZE)
+ {
+ // Extend liveness of dstReg in case if it gets killed by the store.
+ gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet());
+
+ const regNumber tempReg = initBlkNode->GetSingleTempReg();
+ instGen_Set_Reg_To_Imm(EA_PTRSIZE, tempReg, size - TARGET_POINTER_SIZE);
+
+ // tempReg = dstReg + tempReg (a new interior pointer, but in a nongc region)
+ GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, tempReg, dstReg, tempReg);
+
+ BasicBlock* loop = genCreateTempLabel();
+ genDefineTempLabel(loop);
+ GetEmitter()->emitDisableGC(); // TODO: add gcinfo to tempReg and remove nogc
+
+ // *tempReg = 0
+ GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_R0, tempReg, 0);
+ // tempReg = tempReg - 8
+ GetEmitter()->emitIns_R_R_I(INS_addi, EA_PTRSIZE, tempReg, tempReg, -8);
+ // if (tempReg != dstReg) goto loop;
+ GetEmitter()->emitIns_J(INS_bne, loop, (int)tempReg | ((int)dstReg << 5));
+ GetEmitter()->emitEnableGC();
+
+ gcInfo.gcMarkRegSetNpt(genRegMask(dstReg));
+ }
+}
+
//------------------------------------------------------------------------
// genCodeForInitBlkHelper - Generate code for an InitBlk node by the means of the VM memcpy helper call
//
@@ -6853,6 +6908,11 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp)
genCodeForCpObj(blkOp->AsBlk());
break;
+ case GenTreeBlk::BlkOpKindLoop:
+ assert(!isCopyBlk);
+ genCodeForInitBlkLoop(blkOp);
+ break;
+
case GenTreeBlk::BlkOpKindHelper:
if (isCopyBlk)
{
diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp
index 5847b40ffd32e2..12764affdd92e4 100644
--- a/src/coreclr/jit/codegenxarch.cpp
+++ b/src/coreclr/jit/codegenxarch.cpp
@@ -3034,6 +3034,11 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* storeBlkNode)
genCodeForCpObj(storeBlkNode->AsBlk());
break;
+ case GenTreeBlk::BlkOpKindLoop:
+ assert(!isCopyBlk);
+ genCodeForInitBlkLoop(storeBlkNode);
+ break;
+
#ifdef TARGET_AMD64
case GenTreeBlk::BlkOpKindHelper:
assert(!storeBlkNode->gtBlkOpGcUnsafe);
@@ -3312,6 +3317,60 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node)
#endif
}
+//------------------------------------------------------------------------
+// genCodeForInitBlkLoop - Generate code for an InitBlk using an inlined for-loop.
+// It's needed for cases when size is too big to unroll and we're not allowed
+// to use memset call due to atomicity requirements.
+//
+// Arguments:
+// initBlkNode - the GT_STORE_BLK node
+//
+void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode)
+{
+ GenTree* const dstNode = initBlkNode->Addr();
+ GenTree* const zeroNode = initBlkNode->Data();
+
+ genConsumeReg(dstNode);
+ genConsumeReg(zeroNode);
+
+ const regNumber dstReg = dstNode->GetRegNum();
+ const regNumber zeroReg = zeroNode->GetRegNum();
+
+ // xor zeroReg, zeroReg
+ // mov qword ptr [dstReg], zeroReg
+ // mov offsetReg,
+ //.LOOP:
+ // mov qword ptr [dstReg + offsetReg], zeroReg
+ // sub offsetReg, 8
+ // jne .LOOP
+
+ const unsigned size = initBlkNode->GetLayout()->GetSize();
+ assert((size >= TARGET_POINTER_SIZE) && ((size % TARGET_POINTER_SIZE) == 0));
+
+ // The loop is reversed - it makes it smaller.
+ // Although, we zero the first pointer before the loop (the loop doesn't zero it)
+ // it works as a nullcheck, otherwise the first iteration would try to access
+ // "null + potentially large offset" and hit AV.
+ GetEmitter()->emitIns_AR_R(INS_mov, EA_PTRSIZE, zeroReg, dstReg, 0);
+ if (size > TARGET_POINTER_SIZE)
+ {
+ // Extend liveness of dstReg in case if it gets killed by the store.
+ gcInfo.gcMarkRegPtrVal(dstReg, dstNode->TypeGet());
+
+ const regNumber offsetReg = initBlkNode->GetSingleTempReg();
+ instGen_Set_Reg_To_Imm(EA_PTRSIZE, offsetReg, size - TARGET_POINTER_SIZE);
+
+ BasicBlock* loop = genCreateTempLabel();
+ genDefineTempLabel(loop);
+
+ GetEmitter()->emitIns_ARX_R(INS_mov, EA_PTRSIZE, zeroReg, dstReg, offsetReg, 1, 0);
+ GetEmitter()->emitIns_R_I(INS_sub, EA_PTRSIZE, offsetReg, TARGET_POINTER_SIZE);
+ inst_JMP(EJ_jne, loop);
+
+ gcInfo.gcMarkRegSetNpt(genRegMask(dstReg));
+ }
+}
+
#ifdef TARGET_AMD64
//------------------------------------------------------------------------
// genCodeForInitBlkHelper - Generate code for an InitBlk node by the means of the VM memcpy helper call
diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h
index 8339d6d274f4f5..dd23c482559155 100644
--- a/src/coreclr/jit/compiler.h
+++ b/src/coreclr/jit/compiler.h
@@ -9905,6 +9905,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
STRESS_MODE(IF_CONVERSION_COST) \
STRESS_MODE(IF_CONVERSION_INNER_LOOPS) \
STRESS_MODE(POISON_IMPLICIT_BYREFS) \
+ STRESS_MODE(STORE_BLOCK_UNROLLING) \
STRESS_MODE(COUNT)
enum compStressArea
diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp
index 7c34c51571e66d..31be03bda15b7e 100644
--- a/src/coreclr/jit/gentree.cpp
+++ b/src/coreclr/jit/gentree.cpp
@@ -12227,6 +12227,11 @@ void Compiler::gtDispTree(GenTree* tree,
printf(" (Helper)");
break;
#endif
+
+ case GenTreeBlk::BlkOpKindLoop:
+ printf(" (Loop)");
+ break;
+
default:
unreached();
}
diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h
index 109da6a15c30d8..5a06113fa8d717 100644
--- a/src/coreclr/jit/gentree.h
+++ b/src/coreclr/jit/gentree.h
@@ -7248,6 +7248,7 @@ struct GenTreeBlk : public GenTreeIndir
#ifdef TARGET_XARCH
BlkOpKindRepInstr,
#endif
+ BlkOpKindLoop,
BlkOpKindUnroll,
BlkOpKindUnrollMemmove,
} gtBlkOpKind;
@@ -7256,12 +7257,20 @@ struct GenTreeBlk : public GenTreeIndir
bool gtBlkOpGcUnsafe;
#endif
-#ifdef TARGET_XARCH
+ bool ContainsReferences()
+ {
+ return (m_layout != nullptr) && m_layout->HasGCPtr();
+ }
+
bool IsOnHeapAndContainsReferences()
{
- return (m_layout != nullptr) && m_layout->HasGCPtr() && !Addr()->OperIs(GT_LCL_ADDR);
+ return ContainsReferences() && !Addr()->OperIs(GT_LCL_ADDR);
+ }
+
+ bool IsZeroingGcPointersOnHeap()
+ {
+ return OperIs(GT_STORE_BLK) && Data()->IsIntegralConst(0) && IsOnHeapAndContainsReferences();
}
-#endif
GenTreeBlk(genTreeOps oper, var_types type, GenTree* addr, ClassLayout* layout)
: GenTreeIndir(oper, type, addr, nullptr)
@@ -7272,6 +7281,10 @@ struct GenTreeBlk : public GenTreeIndir
GenTreeBlk(genTreeOps oper, var_types type, GenTree* addr, GenTree* data, ClassLayout* layout)
: GenTreeIndir(oper, type, addr, data)
{
+ if (data->IsIntegralConst(0))
+ {
+ data->gtFlags |= GTF_DONT_CSE;
+ }
Initialize(layout);
}
diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp
index e8fa8a3db39eeb..6087b1499301cf 100644
--- a/src/coreclr/jit/importer.cpp
+++ b/src/coreclr/jit/importer.cpp
@@ -453,6 +453,11 @@ void Compiler::impAppendStmt(Statement* stmt, unsigned chkLevel, bool checkConsu
}
}
+ // In the case of GT_RET_EXPR any subsequent spills will appear in the wrong place -- after
+ // the call. We need to move them to before the call
+ //
+ Statement* lastStmt = impLastStmt;
+
if ((dstVarDsc != nullptr) && !dstVarDsc->IsAddressExposed() && !dstVarDsc->lvHasLdAddrOp)
{
impSpillLclRefs(lvaGetLclNum(dstVarDsc), chkLevel);
@@ -480,6 +485,40 @@ void Compiler::impAppendStmt(Statement* stmt, unsigned chkLevel, bool checkConsu
{
impSpillSpecialSideEff();
}
+
+ if ((lastStmt != impLastStmt) && expr->OperIs(GT_RET_EXPR))
+ {
+ GenTree* const call = expr->AsRetExpr()->gtInlineCandidate;
+ JITDUMP("\nimpAppendStmt: after sinking a local struct store into inline candidate [%06u], we need to "
+ "reorder subsequent spills.\n",
+ dspTreeID(call));
+
+ // Move all newly appended statements to just before the call's statement.
+ // First, find the statement containing the call.
+ //
+ Statement* insertBeforeStmt = lastStmt;
+
+ while (insertBeforeStmt->GetRootNode() != call)
+ {
+ assert(insertBeforeStmt != impStmtList);
+ insertBeforeStmt = insertBeforeStmt->GetPrevStmt();
+ }
+
+ Statement* movingStmt = lastStmt->GetNextStmt();
+
+ JITDUMP("Moving " FMT_STMT " through " FMT_STMT " before " FMT_STMT "\n", movingStmt->GetID(),
+ impLastStmt->GetID(), insertBeforeStmt->GetID());
+
+ // We move these backwards, so must keep moving the insert
+ // point to keep them in order.
+ //
+ while (impLastStmt != lastStmt)
+ {
+ Statement* movingStmt = impExtractLastStmt();
+ impInsertStmtBefore(movingStmt, insertBeforeStmt);
+ insertBeforeStmt = movingStmt;
+ }
+ }
}
impAppendStmtCheck(stmt, chkLevel);
@@ -9478,6 +9517,13 @@ void Compiler::impImportBlockCode(BasicBlock* block)
op1 = gtNewLclVarAddrNode(stackallocAsLocal);
convertedToLocal = true;
+ if (compIsForInlining() && info.compInitMem && !impInlineRoot()->info.compInitMem)
+ {
+ // Explicitly zero out the local if we're inlining a method with InitLocals into a
+ // method without InitLocals.
+ impStoreTemp(stackallocAsLocal, gtNewIconNode(0), CHECK_SPILL_ALL);
+ }
+
if (!this->opts.compDbgEnC)
{
// Ensure we have stack security for this method.
diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp
index 2e454e64c14eb1..2231a044b04cdb 100644
--- a/src/coreclr/jit/lower.cpp
+++ b/src/coreclr/jit/lower.cpp
@@ -7973,6 +7973,15 @@ void Lowering::LowerBlockStoreCommon(GenTreeBlk* blkNode)
{
assert(blkNode->OperIs(GT_STORE_BLK, GT_STORE_DYN_BLK));
+ if (blkNode->ContainsReferences() && !blkNode->OperIsCopyBlkOp())
+ {
+ // Make sure we don't use GT_STORE_DYN_BLK
+ assert(blkNode->OperIs(GT_STORE_BLK));
+
+ // and we only zero it (and that zero is better to be not hoisted/CSE'd)
+ assert(blkNode->Data()->IsIntegralConst(0));
+ }
+
// Lose the type information stored in the source - we no longer need it.
if (blkNode->Data()->OperIs(GT_BLK))
{
diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp
index 2536d44aa00c56..c58456940bf5e1 100644
--- a/src/coreclr/jit/lowerarmarch.cpp
+++ b/src/coreclr/jit/lowerarmarch.cpp
@@ -554,6 +554,16 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
if (blkNode->OperIsInitBlkOp())
{
+#ifdef DEBUG
+ // Use BlkOpKindLoop for more cases under stress mode
+ if (comp->compStressCompile(Compiler::STRESS_STORE_BLOCK_UNROLLING, 50) && blkNode->OperIs(GT_STORE_BLK) &&
+ ((blkNode->GetLayout()->GetSize() % TARGET_POINTER_SIZE) == 0) && src->IsIntegralConst(0))
+ {
+ blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop;
+ return;
+ }
+#endif
+
if (src->OperIs(GT_INIT_VAL))
{
src->SetContained();
@@ -598,6 +608,15 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
ContainBlockStoreAddress(blkNode, size, dstAddr, nullptr);
}
+ else if (blkNode->IsZeroingGcPointersOnHeap())
+ {
+ blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop;
+#ifdef TARGET_ARM64
+ // On ARM64 we can just use REG_ZR instead of having to load
+ // the constant into a real register like on ARM32.
+ src->SetContained();
+#endif
+ }
else
{
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper;
diff --git a/src/coreclr/jit/lowerloongarch64.cpp b/src/coreclr/jit/lowerloongarch64.cpp
index d89c8723e80f66..d522a85ab0f966 100644
--- a/src/coreclr/jit/lowerloongarch64.cpp
+++ b/src/coreclr/jit/lowerloongarch64.cpp
@@ -326,6 +326,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
ContainBlockStoreAddress(blkNode, size, dstAddr, nullptr);
}
+ else if (blkNode->IsZeroingGcPointersOnHeap())
+ {
+ blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop;
+ // We're going to use REG_R0 for zero
+ src->SetContained();
+ }
else
{
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper;
diff --git a/src/coreclr/jit/lowerriscv64.cpp b/src/coreclr/jit/lowerriscv64.cpp
index 37848fc5909de3..0c0f0aafc34bcc 100644
--- a/src/coreclr/jit/lowerriscv64.cpp
+++ b/src/coreclr/jit/lowerriscv64.cpp
@@ -280,6 +280,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
ContainBlockStoreAddress(blkNode, size, dstAddr, nullptr);
}
+ else if (blkNode->IsZeroingGcPointersOnHeap())
+ {
+ blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop;
+ // We're going to use REG_R0 for zero
+ src->SetContained();
+ }
else
{
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper;
diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp
index 150ad04a55d99f..f0e7fc6322f2be 100644
--- a/src/coreclr/jit/lowerxarch.cpp
+++ b/src/coreclr/jit/lowerxarch.cpp
@@ -310,6 +310,16 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
if (blkNode->OperIsInitBlkOp())
{
+#ifdef DEBUG
+ // Use BlkOpKindLoop for more cases under stress mode
+ if (comp->compStressCompile(Compiler::STRESS_STORE_BLOCK_UNROLLING, 50) && blkNode->OperIs(GT_STORE_BLK) &&
+ ((blkNode->GetLayout()->GetSize() % TARGET_POINTER_SIZE) == 0) && src->IsIntegralConst(0))
+ {
+ blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindLoop;
+ return;
+ }
+#endif
+
if (src->OperIs(GT_INIT_VAL))
{
src->SetContained();
@@ -375,10 +385,12 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
{
TOO_BIG_TO_UNROLL:
#ifdef TARGET_AMD64
- blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper;
+ blkNode->gtBlkOpKind =
+ blkNode->IsZeroingGcPointersOnHeap() ? GenTreeBlk::BlkOpKindLoop : GenTreeBlk::BlkOpKindHelper;
#else
// TODO-X86-CQ: Investigate whether a helper call would be beneficial on x86
- blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindRepInstr;
+ blkNode->gtBlkOpKind =
+ blkNode->IsZeroingGcPointersOnHeap() ? GenTreeBlk::BlkOpKindLoop : GenTreeBlk::BlkOpKindRepInstr;
#endif
}
}
@@ -7656,7 +7668,10 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre
const unsigned expectedSize = genTypeSize(parentNode->TypeGet()) / 2;
const unsigned operandSize = genTypeSize(childNode->TypeGet());
- supportsGeneralLoads = supportsUnalignedSIMDLoads && (operandSize >= expectedSize);
+ // For broadcasts we can only optimize constants and memory operands
+ const bool broadcastIsContainable = childNode->OperIsConst() || childNode->isMemoryOp();
+ supportsGeneralLoads =
+ broadcastIsContainable && supportsUnalignedSIMDLoads && (operandSize >= expectedSize);
break;
}
diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp
index e72ff23df3375d..b87e0f80539fdc 100644
--- a/src/coreclr/jit/lsraarmarch.cpp
+++ b/src/coreclr/jit/lsraarmarch.cpp
@@ -631,6 +631,11 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode)
#endif // TARGET_ARM64
break;
+ case GenTreeBlk::BlkOpKindLoop:
+ // Needed for offsetReg
+ buildInternalIntRegisterDefForNode(blkNode, availableIntRegs);
+ break;
+
case GenTreeBlk::BlkOpKindHelper:
assert(!src->isContained());
dstAddrRegMask = RBM_ARG_0;
diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp
index 8c9025f61b703a..22efbf53b82cb9 100644
--- a/src/coreclr/jit/lsrabuild.cpp
+++ b/src/coreclr/jit/lsrabuild.cpp
@@ -968,6 +968,7 @@ regMaskTP LinearScan::getKillSetForBlockStore(GenTreeBlk* blkNode)
#endif
case GenTreeBlk::BlkOpKindUnrollMemmove:
case GenTreeBlk::BlkOpKindUnroll:
+ case GenTreeBlk::BlkOpKindLoop:
case GenTreeBlk::BlkOpKindInvalid:
// for these 'gtBlkOpKind' kinds, we leave 'killMask' = RBM_NONE
break;
diff --git a/src/coreclr/jit/lsraloongarch64.cpp b/src/coreclr/jit/lsraloongarch64.cpp
index 7ab333630c046a..0312342a38914e 100644
--- a/src/coreclr/jit/lsraloongarch64.cpp
+++ b/src/coreclr/jit/lsraloongarch64.cpp
@@ -1114,6 +1114,11 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode)
}
break;
+ case GenTreeBlk::BlkOpKindLoop:
+ // Needed for offsetReg
+ buildInternalIntRegisterDefForNode(blkNode, availableIntRegs);
+ break;
+
case GenTreeBlk::BlkOpKindHelper:
assert(!src->isContained());
dstAddrRegMask = RBM_ARG_0;
diff --git a/src/coreclr/jit/lsrariscv64.cpp b/src/coreclr/jit/lsrariscv64.cpp
index 4be7a391d26a70..09d8a8daf905a8 100644
--- a/src/coreclr/jit/lsrariscv64.cpp
+++ b/src/coreclr/jit/lsrariscv64.cpp
@@ -1129,6 +1129,11 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode)
}
break;
+ case GenTreeBlk::BlkOpKindLoop:
+ // Needed for tempReg
+ buildInternalIntRegisterDefForNode(blkNode, availableIntRegs);
+ break;
+
case GenTreeBlk::BlkOpKindHelper:
assert(!src->isContained());
dstAddrRegMask = RBM_ARG_0;
diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp
index 5d54c08ebb7902..678aa6bd596bb9 100644
--- a/src/coreclr/jit/lsraxarch.cpp
+++ b/src/coreclr/jit/lsraxarch.cpp
@@ -1406,6 +1406,11 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode)
sizeRegMask = RBM_RCX;
break;
+ case GenTreeBlk::BlkOpKindLoop:
+ // Needed for offsetReg
+ buildInternalIntRegisterDefForNode(blkNode, availableIntRegs);
+ break;
+
#ifdef TARGET_AMD64
case GenTreeBlk::BlkOpKindHelper:
dstAddrRegMask = RBM_ARG_0;
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index 1f5b2cd681095c..71acdacdadd10a 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -33,6 +33,7 @@ The .NET Foundation licenses this file to you under the MIT license.
$(RuntimeIdentifier)
+ $(RuntimeIdentifier)
x86_64
@@ -122,10 +123,6 @@ The .NET Foundation licenses this file to you under the MIT license.
-
-
-
-
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets
index e9462399741c5e..e379eb457bdc6c 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets
@@ -81,7 +81,7 @@ The .NET Foundation licenses this file to you under the MIT license.
$(NativeIntermediateOutputPath)$(TargetName)$(NativeObjectExt)
$(NativeOutputPath)$(TargetName)$(NativeBinaryExt)
true
- $(NativeIntermediateOutputPath)$(TargetName)$(ExportsFileExt)
+ $(NativeIntermediateOutputPath)$(TargetName)$(ExportsFileExt)
$(NativeObject)
@@ -240,7 +240,10 @@ The .NET Foundation licenses this file to you under the MIT license.
-
+
+
+
+
@@ -334,8 +337,8 @@ The .NET Foundation licenses this file to you under the MIT license.
-
-
+
+
diff --git a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp
index 121fdec1019e0f..8cafe9e1dab835 100644
--- a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp
+++ b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp
@@ -36,12 +36,12 @@ struct GlobalValueEntry
// This size should be one bigger than the number of entries since a null entry
// signifies the end of the array.
-static constexpr size_t DebugTypeEntriesArraySize = 96;
+static constexpr size_t DebugTypeEntriesArraySize = 100;
static DebugTypeEntry s_DebugEntries[DebugTypeEntriesArraySize];
// This size should be one bigger than the number of entries since a null entry
// signifies the end of the array.
-static constexpr size_t GlobalEntriesArraySize = 6;
+static constexpr size_t GlobalEntriesArraySize = 8;
static GlobalValueEntry s_GlobalEntries[GlobalEntriesArraySize];
// This structure is part of a in-memory serialization format that is used by diagnostic tools to
@@ -107,10 +107,11 @@ struct DotNetRuntimeDebugHeader
GlobalValueEntry (* volatile GlobalEntries)[GlobalEntriesArraySize] = nullptr;
};
-#ifdef TARGET_WINDOWS
-#pragma comment (linker, "/EXPORT:DotNetRuntimeDebugHeader,DATA")
-#endif
extern "C" struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader;
+
+#ifdef HOST_UNIX
+__attribute__ ((visibility ("default")))
+#endif
struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader = {};
#define MAKE_DEBUG_ENTRY(TypeName, FieldName, Value) \
@@ -118,7 +119,7 @@ struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader = {};
{ \
s_DebugEntries[currentDebugPos] = { #TypeName, #FieldName, Value, 0 }; \
++currentDebugPos; \
- ASSERT(currentDebugPos <= DebugTypeEntriesArraySize); \
+ ASSERT(currentDebugPos < DebugTypeEntriesArraySize); \
} while(0)
#define MAKE_DEBUG_FIELD_ENTRY(TypeName, FieldName) MAKE_DEBUG_ENTRY(TypeName, FieldName, offsetof(TypeName, FieldName))
@@ -132,7 +133,7 @@ struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader = {};
{ \
s_GlobalEntries[currentGlobalPos] = { #Name, Name }; \
++currentGlobalPos; \
- ASSERT(currentGlobalPos <= GlobalEntriesArraySize) \
+ ASSERT(currentGlobalPos < GlobalEntriesArraySize); \
} while(0) \
extern "C" void PopulateDebugHeaders()
diff --git a/src/coreclr/nativeaot/Runtime/PalRedhawk.h b/src/coreclr/nativeaot/Runtime/PalRedhawk.h
index d15969eab3784b..581fbf29d12e9f 100644
--- a/src/coreclr/nativeaot/Runtime/PalRedhawk.h
+++ b/src/coreclr/nativeaot/Runtime/PalRedhawk.h
@@ -752,7 +752,7 @@ REDHAWK_PALIMPORT uint32_t REDHAWK_PALAPI PalEventWrite(REGHANDLE arg1, const EV
#endif
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalAllocateThunksFromTemplate(_In_ HANDLE hTemplateModule, uint32_t templateRva, size_t templateSize, _Outptr_result_bytebuffer_(templateSize) void** newThunksOut);
-REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(_In_ void *pBaseAddress);
+REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(_In_ void *pBaseAddress, size_t templateSize);
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalMarkThunksAsValidCallTargets(
void *virtualAddress,
diff --git a/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp b/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp
index 2b877fc9bfd226..68a346596b529f 100644
--- a/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp
+++ b/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp
@@ -329,6 +329,7 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping()
int thunkBlockSize = RhpGetThunkBlockSize();
int templateSize = thunkBlocksPerMapping * thunkBlockSize;
+#ifndef TARGET_APPLE // Apple platforms cannot use the initial template
if (pThunksTemplateAddress == NULL)
{
// First, we use the thunks directly from the thunks template sections in the module until all
@@ -337,12 +338,13 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping()
pThunkMap = pThunksTemplateAddress;
}
else
+#endif
{
// We've already used the thunks template in the module for some previous thunks, and we
// cannot reuse it here. Now we need to create a new mapping of the thunks section in order to have
// more thunks
- uint8_t* pModuleBase = (uint8_t*)PalGetModuleHandleFromPointer(pThunksTemplateAddress);
+ uint8_t* pModuleBase = (uint8_t*)PalGetModuleHandleFromPointer(RhpGetThunksBase());
int templateRva = (int)((uint8_t*)RhpGetThunksBase() - pModuleBase);
if (!PalAllocateThunksFromTemplate((HANDLE)pModuleBase, templateRva, templateSize, &pThunkMap))
@@ -357,7 +359,7 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping()
thunkBlocksPerMapping))
{
if (pThunkMap != pThunksTemplateAddress)
- PalFreeThunksFromTemplate(pThunkMap);
+ PalFreeThunksFromTemplate(pThunkMap, templateSize);
return NULL;
}
diff --git a/src/coreclr/nativeaot/Runtime/amd64/InteropThunksHelpers.S b/src/coreclr/nativeaot/Runtime/amd64/InteropThunksHelpers.S
index 5c0b6f631ef539..a53dd3c63624f6 100644
--- a/src/coreclr/nativeaot/Runtime/amd64/InteropThunksHelpers.S
+++ b/src/coreclr/nativeaot/Runtime/amd64/InteropThunksHelpers.S
@@ -14,7 +14,11 @@ LEAF_ENTRY RhCommonStub, _TEXT
alloc_stack SIZEOF_FP_REGS
SAVE_FLOAT_ARGUMENT_REGISTERS 0
+#ifdef FEATURE_EMULATED_TLS
+ call C_FUNC(RhpGetThunkData)
+#else
INLINE_GET_TLS_VAR tls_thunkData
+#endif
RESTORE_FLOAT_ARGUMENT_REGISTERS 0
free_stack SIZEOF_FP_REGS
@@ -36,6 +40,7 @@ LEAF_ENTRY RhGetCommonStubAddress, _TEXT
LEAF_END RhGetCommonStubAddress, _TEXT
+#ifndef FEATURE_EMULATED_TLS
LEAF_ENTRY RhGetCurrentThunkContext, _TEXT
INLINE_GET_TLS_VAR tls_thunkData
@@ -43,3 +48,4 @@ LEAF_ENTRY RhGetCurrentThunkContext, _TEXT
mov rax, qword ptr [rax]
ret
LEAF_END RhGetCurrentThunkContext, _TEXT
+#endif //FEATURE_EMULATED_TLS
diff --git a/src/coreclr/nativeaot/Runtime/amd64/ThunkPoolThunks.S b/src/coreclr/nativeaot/Runtime/amd64/ThunkPoolThunks.S
index 259d698002b490..f79ace1ca4996a 100644
--- a/src/coreclr/nativeaot/Runtime/amd64/ThunkPoolThunks.S
+++ b/src/coreclr/nativeaot/Runtime/amd64/ThunkPoolThunks.S
@@ -38,11 +38,8 @@
.endm
#ifdef TARGET_APPLE
- // Create two segments in the Mach-O file:
- // __THUNKS with executable permissions
- // __THUNKS_DATA with read/write permissions
-
- .section __THUNKS,__thunks,regular,pure_instructions
+// Thunk pool
+ .text
.p2align PAGE_SIZE_LOG2
PATCH_LABEL ThunkPool
.rept (THUNKS_MAP_SIZE / PAGE_SIZE)
@@ -50,10 +47,6 @@ PATCH_LABEL ThunkPool
THUNKS_PAGE_BLOCK
.endr
.p2align PAGE_SIZE_LOG2
- .section __THUNKS_DATA,__thunks,regular
- .p2align PAGE_SIZE_LOG2
- .space THUNKS_MAP_SIZE
- .p2align PAGE_SIZE_LOG2
#else
#error Unsupported OS
#endif
diff --git a/src/coreclr/nativeaot/Runtime/arm64/ThunkPoolThunks.S b/src/coreclr/nativeaot/Runtime/arm64/ThunkPoolThunks.S
index d93d9f959506e5..1b0ea7e0291166 100644
--- a/src/coreclr/nativeaot/Runtime/arm64/ThunkPoolThunks.S
+++ b/src/coreclr/nativeaot/Runtime/arm64/ThunkPoolThunks.S
@@ -46,11 +46,8 @@
.endm
#ifdef TARGET_APPLE
- // Create two segments in the Mach-O file:
- // __THUNKS with executable permissions
- // __THUNKS_DATA with read/write permissions
-
- .section __THUNKS,__thunks,regular,pure_instructions
+// Thunk pool
+ .text
.p2align PAGE_SIZE_LOG2
PATCH_LABEL ThunkPool
.rept (THUNKS_MAP_SIZE / PAGE_SIZE)
@@ -58,10 +55,6 @@ PATCH_LABEL ThunkPool
THUNKS_PAGE_BLOCK
.endr
.p2align PAGE_SIZE_LOG2
- .section __THUNKS_DATA,__thunks,regular
- .p2align PAGE_SIZE_LOG2
- .space THUNKS_MAP_SIZE
- .p2align PAGE_SIZE_LOG2
#else
#error Unsupported OS
#endif
diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt
index cedb910ac093ea..27f07197287994 100644
--- a/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt
+++ b/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt
@@ -158,12 +158,15 @@ add_library(eventpipe-enabled STATIC ${EVENTPIPE_SOURCES})
add_library(eventpipe-disabled STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES})
if (CLR_CMAKE_TARGET_WIN32)
+ add_library(eventpipe-enabled.GuardCF STATIC ${EVENTPIPE_SOURCES})
add_library(eventpipe-disabled.GuardCF STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES})
+ target_compile_options(eventpipe-enabled.GuardCF PRIVATE $<$,$>:/guard:cf>)
target_compile_options(eventpipe-disabled.GuardCF PRIVATE $<$,$>:/guard:cf>)
endif (CLR_CMAKE_TARGET_WIN32)
install_static_library(eventpipe-enabled aotsdk nativeaot)
install_static_library(eventpipe-disabled aotsdk nativeaot)
if (CLR_CMAKE_TARGET_WIN32)
+ install_static_library(eventpipe-enabled.GuardCF aotsdk nativeaot)
install_static_library(eventpipe-disabled.GuardCF aotsdk nativeaot)
endif (CLR_CMAKE_TARGET_WIN32)
diff --git a/src/coreclr/nativeaot/Runtime/thread.cpp b/src/coreclr/nativeaot/Runtime/thread.cpp
index 4c924524fd4d73..53b86b4e3d0b2b 100644
--- a/src/coreclr/nativeaot/Runtime/thread.cpp
+++ b/src/coreclr/nativeaot/Runtime/thread.cpp
@@ -263,7 +263,7 @@ void Thread::Construct()
m_pDeferredTransitionFrame = TOP_OF_STACK_MARKER;
m_hPalThread = INVALID_HANDLE_VALUE;
- m_threadId.SetToCurrentThread();
+ m_threadId = PalGetCurrentOSThreadId();
HANDLE curProcessPseudo = PalGetCurrentProcess();
HANDLE curThreadPseudo = PalGetCurrentThread();
@@ -328,12 +328,7 @@ bool Thread::CatchAtSafePoint()
uint64_t Thread::GetPalThreadIdForLogging()
{
- return *(uint64_t*)&m_threadId;
-}
-
-bool Thread::IsCurrentThread()
-{
- return m_threadId.IsCurrentThread();
+ return m_threadId;
}
void Thread::Detach()
diff --git a/src/coreclr/nativeaot/Runtime/thread.h b/src/coreclr/nativeaot/Runtime/thread.h
index 7aa473eb6763d4..688a84c30340ee 100644
--- a/src/coreclr/nativeaot/Runtime/thread.h
+++ b/src/coreclr/nativeaot/Runtime/thread.h
@@ -102,7 +102,7 @@ struct ThreadBuffer
GCFrameRegistration* m_pGCFrameRegistrations;
PTR_VOID m_pStackLow;
PTR_VOID m_pStackHigh;
- EEThreadId m_threadId; // OS thread ID
+ uint64_t m_threadId; // OS thread ID
PTR_VOID m_pThreadStressLog; // pointer to head of thread's StressLogChunks
NATIVE_CONTEXT* m_interruptedContext; // context for an asynchronously interrupted thread.
#ifdef FEATURE_SUSPEND_REDIRECTION
@@ -209,7 +209,6 @@ class Thread : private ThreadBuffer
#ifndef DACCESS_COMPILE
uint64_t GetPalThreadIdForLogging();
- bool IsCurrentThread();
void GcScanRoots(void * pfnEnumCallback, void * pvCallbackData);
#else
diff --git a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
index 5b184882830a80..9d6f45c8fee8a0 100644
--- a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
+++ b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
@@ -56,8 +56,7 @@
#endif
#ifdef TARGET_APPLE
-#include
-#include
+#include
#endif
using std::nullptr_t;
@@ -520,59 +519,61 @@ extern "C" bool PalDetachThread(void* thread)
#if !defined(USE_PORTABLE_HELPERS) && !defined(FEATURE_RX_THUNKS)
-#ifdef TARGET_APPLE
-static const struct section_64 *thunks_section;
-static const struct section_64 *thunks_data_section;
-#endif
-
REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalAllocateThunksFromTemplate(HANDLE hTemplateModule, uint32_t templateRva, size_t templateSize, void** newThunksOut)
{
#ifdef TARGET_APPLE
- int f;
- Dl_info info;
+ vm_address_t addr, taddr;
+ vm_prot_t prot, max_prot;
+ kern_return_t ret;
- int st = dladdr((const void*)hTemplateModule, &info);
- if (st == 0)
+ // Allocate two contiguous ranges of memory: the first range will contain the trampolines
+ // and the second range will contain their data.
+ do
{
- return UInt32_FALSE;
- }
+ ret = vm_allocate(mach_task_self(), &addr, templateSize * 2, VM_FLAGS_ANYWHERE);
+ } while (ret == KERN_ABORTED);
- f = open(info.dli_fname, O_RDONLY);
- if (f < 0)
+ if (ret != KERN_SUCCESS)
{
return UInt32_FALSE;
}
- // NOTE: We ignore templateRva since we would need to convert it to file offset
- // and templateSize is useless too. Instead we read the sections from the
- // executable and determine the size from them.
- if (thunks_section == NULL)
+ do
+ {
+ ret = vm_remap(
+ mach_task_self(), &addr, templateSize, 0, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE,
+ mach_task_self(), ((vm_address_t)hTemplateModule + templateRva), FALSE, &prot, &max_prot, VM_INHERIT_SHARE);
+ } while (ret == KERN_ABORTED);
+
+ if (ret != KERN_SUCCESS)
{
- const struct mach_header_64 *hdr = (const struct mach_header_64 *)hTemplateModule;
- thunks_section = getsectbynamefromheader_64(hdr, "__THUNKS", "__thunks");
- thunks_data_section = getsectbynamefromheader_64(hdr, "__THUNKS_DATA", "__thunks");
+ do
+ {
+ ret = vm_deallocate(mach_task_self(), addr, templateSize * 2);
+ } while (ret == KERN_ABORTED);
+
+ return UInt32_FALSE;
}
- *newThunksOut = mmap(
- NULL,
- thunks_section->size + thunks_data_section->size,
- PROT_READ | PROT_EXEC,
- MAP_PRIVATE,
- f,
- thunks_section->offset);
- close(f);
+ *newThunksOut = (void*)addr;
- return *newThunksOut == NULL ? UInt32_FALSE : UInt32_TRUE;
+ return UInt32_TRUE;
#else
PORTABILITY_ASSERT("UNIXTODO: Implement this function");
#endif
}
-REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(void *pBaseAddress)
+REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(void *pBaseAddress, size_t templateSize)
{
#ifdef TARGET_APPLE
- int ret = munmap(pBaseAddress, thunks_section->size + thunks_data_section->size);
- return ret == 0 ? UInt32_TRUE : UInt32_FALSE;
+ kern_return_t ret;
+
+ do
+ {
+ ret = vm_deallocate(mach_task_self(), (vm_address_t)pBaseAddress, templateSize * 2);
+ } while (ret == KERN_ABORTED);
+
+ return ret == KERN_SUCCESS ? UInt32_TRUE : UInt32_FALSE;
#else
PORTABILITY_ASSERT("UNIXTODO: Implement this function");
#endif
diff --git a/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc b/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc
index ab64ef9ce92b49..11225c0ad5ed2b 100644
--- a/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc
+++ b/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosamd64.inc
@@ -300,8 +300,12 @@ C_FUNC(\Name):
.macro INLINE_GETTHREAD
+#ifdef FEATURE_EMULATED_TLS
+ call C_FUNC(RhpGetThread)
+#else
// Inlined version of call C_FUNC(RhpGetThread)
INLINE_GET_TLS_VAR tls_CurrentThread
+#endif
.endm
.macro INLINE_THREAD_UNHIJACK threadReg, trashReg1, trashReg2
diff --git a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
index 964a3b52b09e42..9850fed10b11a2 100644
--- a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
+++ b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
@@ -259,7 +259,7 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalAllocateThunksFromTemplate(_In_
#endif
}
-REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(_In_ void *pBaseAddress)
+REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalFreeThunksFromTemplate(_In_ void *pBaseAddress, size_t templateSize)
{
#ifdef XBOX_ONE
return TRUE;
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs
index c2421fc6b4ceb9..a92f64f368cfe4 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/CrashInfo.cs
@@ -170,7 +170,8 @@ private bool WriteExceptionHelper(ReadOnlySpan key, Exception exception, i
if (!OpenValue(key, '{'))
return false;
- if (!WriteHexValue("address"u8, (ulong)Unsafe.AsPointer(ref exception)))
+ ulong address = Unsafe.As(ref exception);
+ if (!WriteHexValue("address"u8, address))
return false;
if (!WriteHexValue("hr"u8, exception.HResult))
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
index 9d98650b91bbb9..01d2d15fc2997e 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
@@ -707,9 +707,15 @@ private void CompileMethodCleanup()
_instantiationToJitVisibleInstantiation = null;
_pgoResults.Clear();
+
+ // We need to clear out this cache because the next compilation could actually come up
+ // with a different MethodIL for the same MethodDesc. This happens when we need to replace
+ // a MethodIL with a throw helper.
+ _methodILScopeToHandle.Clear();
}
private Dictionary