diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index f6ec0a4e1da7e..015825df43d7a 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -15,7 +15,7 @@
]
},
"microsoft.dotnet.xharness.cli": {
- "version": "1.0.0-prerelease.22074.1",
+ "version": "1.0.0-prerelease.22062.1",
"commands": [
"xharness"
]
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 2634a9528f1ee..31ff731b02911 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -10,12 +10,3 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
build-essential python curl git lldb-6.0 liblldb-6.0-dev \
libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev \
libssl-dev libnuma-dev libkrb5-dev zlib1g-dev ninja-build
-
-# Install V8 Engine
-SHELL ["/bin/bash", "-c"]
-
-RUN curl -sSL "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/linux/chromium-v8/v8-linux64-rel-8.5.183.zip" -o ./v8.zip \
- && unzip ./v8.zip -d /usr/local/v8 \
- && echo $'#!/usr/bin/env bash\n\
-"/usr/local/v8/d8" --snapshot_blob="/usr/local/v8/snapshot_blob.bin" "$@"\n' > /usr/local/bin/v8 \
- && chmod +x /usr/local/bin/v8
\ No newline at end of file
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index d7b5a8b0efb57..41e9c94c00dee 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -4,7 +4,7 @@
"name": "C# (.NET)",
"build": {
"dockerfile": "Dockerfile",
- "args": {
+ "args": {
// Update 'VARIANT' to pick a .NET Core version: 2.1, 3.1, 5.0
"VARIANT": "5.0",
}
@@ -32,22 +32,11 @@
// Add the locally installed dotnet to the path to ensure that it is activated
// This allows developers to just use 'dotnet build' on the command-line, and the local dotnet version will be used.
- // Add the global tools dir to the PATH so that globally installed tools will work
"remoteEnv": {
- "PATH": "${containerWorkspaceFolder}/.dotnet:${containerWorkspaceFolder}/.dotnet-tools-global:${containerEnv:PATH}",
- "DOTNET_MULTILEVEL_LOOKUP": "0",
- // Path to provisioned Emscripten SDK, for rebuilding the wasm runtime
- "EMSDK_PATH": "${containerWorkspaceFolder}/src/mono/wasm/emsdk",
+ "PATH": "${containerWorkspaceFolder}/.dotnet:${containerEnv:PATH}",
+ "DOTNET_MULTILEVEL_LOOKUP": "0"
},
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
- "remoteUser": "vscode",
-
- // Forward mono samples port
- "forwardPorts": [8000],
- "portsAttributes": {
- "8000": {
- "label": "mono wasm samples (8000)",
- }
- }
+ "remoteUser": "vscode"
}
diff --git a/.devcontainer/scripts/onCreateCommand.sh b/.devcontainer/scripts/onCreateCommand.sh
index 48850f5f00b71..faf7cb08d1afa 100755
--- a/.devcontainer/scripts/onCreateCommand.sh
+++ b/.devcontainer/scripts/onCreateCommand.sh
@@ -7,13 +7,5 @@ set -e
# restore libs tests so that the project is ready to be loaded by OmniSharp
./build.sh libs.tests -restore
-# prebuild for WASM, so it is ready for wasm development
-make -C src/mono/wasm provision-wasm
-export EMSDK_PATH=$PWD/src/mono/wasm/emsdk
-./build.sh mono+libs -os Browser -c release
-
-# install dotnet-serve for running wasm samples
-./dotnet.sh tool install dotnet-serve --tool-path ./.dotnet-tools-global
-
# save the commit hash of the currently built assemblies, so developers know which version was built
git rev-parse HEAD > ./artifacts/prebuild.sha
diff --git a/.github/fabricbot.json b/.github/fabricbot.json
index accae195f26ee..72acfd8440a06 100644
--- a/.github/fabricbot.json
+++ b/.github/fabricbot.json
@@ -13,7 +13,8 @@
],
"mentionees": [
"dotnet/area-system-security",
- "vcsjones"
+ "vcsjones",
+ "krwq"
]
},
{
@@ -32,7 +33,8 @@
"area-System.Linq.Parallel"
],
"mentionees": [
- "dotnet/area-system-linq-parallel"
+ "dotnet/area-system-linq-parallel",
+ "tarekgh"
]
},
{
@@ -40,7 +42,8 @@
"area-System.Text.Encoding"
],
"mentionees": [
- "dotnet/area-system-text-encoding"
+ "dotnet/area-system-text-encoding",
+ "tarekgh"
]
},
{
@@ -48,7 +51,8 @@
"area-System.Text.Encodings.Web"
],
"mentionees": [
- "dotnet/area-system-text-encodings-web"
+ "dotnet/area-system-text-encodings-web",
+ "tarekgh"
]
},
{
@@ -171,7 +175,8 @@
"area-System.Buffers"
],
"mentionees": [
- "dotnet/area-system-buffers"
+ "dotnet/area-system-buffers",
+ "GrabYourPitchforks"
]
},
{
@@ -372,7 +377,8 @@
"area-Extensions-FileSystem"
],
"mentionees": [
- "dotnet/area-extensions-filesystem"
+ "dotnet/area-extensions-filesystem",
+ "maryamariyan"
]
},
{
@@ -770,7 +776,8 @@
"area-System.Resources"
],
"mentionees": [
- "dotnet/area-system-resources"
+ "dotnet/area-system-resources",
+ "tarekgh"
]
},
{
@@ -989,7 +996,7 @@
"subCapability": "IssueCommentResponder",
"version": "1.0",
"config": {
- "taskName": "Replace `needs-author-action` label with `needs-further-triage` label when the author comments on an issue",
+ "taskName": "Replace `needs more info` label with `needs further triage` label when the author comments on an issue",
"conditions": {
"operator": "and",
"operands": [
@@ -1010,7 +1017,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-author-action"
+ "label": "needs more info"
}
},
{
@@ -1023,13 +1030,13 @@
{
"name": "addLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
"name": "removeLabel",
"parameters": {
- "label": "needs-author-action"
+ "label": "needs more info"
}
}
],
@@ -1045,7 +1052,7 @@
"subCapability": "IssuesOnlyResponder",
"version": "1.0",
"config": {
- "taskName": "Remove `no-recent-activity` label from issues when issue is modified",
+ "taskName": "Remove `no recent activity` label from issues when issue is modified",
"conditions": {
"operator": "and",
"operands": [
@@ -1063,7 +1070,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
},
{
@@ -1072,7 +1079,7 @@
{
"name": "labelAdded",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
]
@@ -1083,7 +1090,7 @@
{
"name": "removeLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
],
@@ -1100,14 +1107,14 @@
"subCapability": "IssueCommentResponder",
"version": "1.0",
"config": {
- "taskName": "Remove `no-recent-activity` label when an issue is commented on",
+ "taskName": "Remove `no recent activity` label when an issue is commented on",
"conditions": {
"operator": "and",
"operands": [
{
"name": "hasLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
]
@@ -1116,7 +1123,7 @@
{
"name": "removeLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
],
@@ -1142,7 +1149,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
},
{
@@ -1151,7 +1158,7 @@
{
"name": "labelAdded",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
]
@@ -1164,12 +1171,12 @@
"issues",
"project_card"
],
- "taskName": "Remove `no-recent-activity` label from PRs when modified",
+ "taskName": "Remove `no recent activity` label from PRs when modified",
"actions": [
{
"name": "removeLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
]
@@ -1187,7 +1194,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
},
{
@@ -1200,12 +1207,12 @@
"eventNames": [
"issue_comment"
],
- "taskName": "Remove `no-recent-activity` label from PRs when commented on",
+ "taskName": "Remove `no recent activity` label from PRs when commented on",
"actions": [
{
"name": "removeLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
]
@@ -1223,7 +1230,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
},
{
@@ -1236,12 +1243,12 @@
"eventNames": [
"pull_request_review"
],
- "taskName": "Remove `no-recent-activity` label from PRs when new review is added",
+ "taskName": "Remove `no recent activity` label from PRs when new review is added",
"actions": [
{
"name": "removeLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
]
@@ -1338,7 +1345,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
},
{
@@ -1352,7 +1359,7 @@
{
"name": "addReply",
"parameters": {
- "comment": "This issue will now be closed since it had been marked `no-recent-activity` but received no further activity in the past 14 days. It is still possible to reopen or comment on the issue, but please note that the issue will be locked if it remains inactive for another 30 days."
+ "comment": "This issue will now be closed since it had been marked `no recent activity` but received no further activity in the past 14 days. It is still possible to reopen or comment on the issue, but please note that the issue will be locked if it remains inactive for another 30 days."
}
},
{
@@ -1368,7 +1375,7 @@
"subCapability": "ScheduledSearch",
"version": "1.1",
"config": {
- "taskName": "Close PRs with no-recent-activity",
+ "taskName": "Close PRs with no recent activity",
"frequency": [
{
"weekDay": 0,
@@ -1453,7 +1460,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
},
{
@@ -1467,7 +1474,7 @@
{
"name": "addReply",
"parameters": {
- "comment": "This pull request will now be closed since it had been marked `no-recent-activity` but received no further activity in the past 14 days. It is still possible to reopen or comment on the pull request, but please note that it will be locked if it remains inactive for another 30 days."
+ "comment": "This pull request will now be closed since it had been marked `no recent activity` but received no further activity in the past 14 days. It is still possible to reopen or comment on the pull request, but please note that it will be locked if it remains inactive for another 30 days."
}
},
{
@@ -1483,7 +1490,7 @@
"subCapability": "ScheduledSearch",
"version": "1.1",
"config": {
- "taskName": "Add no-recent-activity label to issues",
+ "taskName": "Add no recent activity label to issues",
"frequency": [
{
"weekDay": 0,
@@ -1568,7 +1575,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-author-action"
+ "label": "needs more info"
}
},
{
@@ -1580,7 +1587,7 @@
{
"name": "noLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
],
@@ -1588,13 +1595,13 @@
{
"name": "addLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
},
{
"name": "addReply",
"parameters": {
- "comment": "This issue has been automatically marked `no-recent-activity` because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will remove `no-recent-activity`."
+ "comment": "This issue has been automatically marked `no recent activity` because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will remove `no recent activity`."
}
}
]
@@ -1607,7 +1614,7 @@
"subCapability": "ScheduledSearch",
"version": "1.1",
"config": {
- "taskName": "Add no-recent-activity label to PRs",
+ "taskName": "Add no recent activity label to PRs",
"frequency": [
{
"weekDay": 0,
@@ -1704,7 +1711,7 @@
{
"name": "noLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
],
@@ -1712,13 +1719,13 @@
{
"name": "addLabel",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
},
{
"name": "addReply",
"parameters": {
- "comment": "This pull request has been automatically marked `no-recent-activity` because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will remove `no-recent-activity`."
+ "comment": "This pull request has been automatically marked `no recent activity` because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will remove `no recent activity`."
}
}
]
@@ -1735,7 +1742,7 @@
"inPrLabelText": "Status: In PR",
"fixedLabelText": "Status: Fixed",
"fixedLabelEnabled": false,
- "label_inPr": "in-pr"
+ "label_inPr": "in pr"
}
},
{
@@ -2232,7 +2239,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -2260,7 +2267,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -2273,7 +2280,7 @@
{
"name": "labelRemoved",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -2495,7 +2502,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -2517,7 +2524,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -2536,7 +2543,7 @@
{
"name": "labelRemoved",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -2618,7 +2625,7 @@
{
"name": "labelAdded",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -2921,7 +2928,7 @@
{
"name": "addLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -2999,7 +3006,7 @@
{
"name": "addLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -3123,7 +3130,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -3145,7 +3152,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -3164,7 +3171,7 @@
{
"name": "labelRemoved",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -3251,7 +3258,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -3273,7 +3280,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -3292,7 +3299,7 @@
{
"name": "labelRemoved",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -3362,7 +3369,7 @@
{
"name": "labelRemoved",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -3391,7 +3398,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -3830,7 +3837,7 @@
{
"name": "labelAdded",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -3982,7 +3989,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -4011,7 +4018,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -4022,7 +4029,7 @@
{
"name": "labelRemoved",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -4203,7 +4210,7 @@
{
"name": "labelAdded",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -4310,7 +4317,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -4343,7 +4350,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -4362,7 +4369,7 @@
{
"name": "labelRemoved",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -5152,7 +5159,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -5180,7 +5187,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -5208,7 +5215,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -5280,7 +5287,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -5308,7 +5315,7 @@
{
"name": "hasLabel",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
}
]
@@ -5321,7 +5328,7 @@
{
"name": "labelRemoved",
"parameters": {
- "label": "needs-further-triage"
+ "label": "needs further triage"
}
},
{
@@ -5376,7 +5383,7 @@
{
"name": "labelAdded",
"parameters": {
- "label": "no-recent-activity"
+ "label": "no recent activity"
}
}
]
@@ -5409,7 +5416,7 @@
{
"name": "labelAdded",
"parameters": {
- "label": "needs-author-action"
+ "label": "needs more info"
}
}
]
@@ -5419,12 +5426,12 @@
"issues",
"project_card"
],
- "taskName": "Needs-author-action notification",
+ "taskName": "Needs more info notification",
"actions": [
{
"name": "addReply",
"parameters": {
- "comment": "This issue has been marked `needs-author-action` since it may be missing important information. Please refer to our [contribution guidelines](https://github.com/dotnet/runtime/blob/main/CONTRIBUTING.md#writing-a-good-bug-report) for tips on how to report issues effectively."
+ "comment": "This issue has been marked `needs more info` since it may be missing important information. Please refer to our [contribution guidelines](https://github.com/dotnet/runtime/blob/main/CONTRIBUTING.md#writing-a-good-bug-report) for tips on how to report issues effectively."
}
}
]
@@ -5944,7 +5951,7 @@
{
"name": "labelAdded",
"parameters": {
- "label": "needs-author-action"
+ "label": "needs more info"
}
},
{
@@ -5996,7 +6003,25 @@
{
"name": "hasLabel",
"parameters": {
- "label": "area-Meta"
+ "label": "area-System.Collections"
+ }
+ },
+ {
+ "name": "hasLabel",
+ "parameters": {
+ "label": "area-System.Linq"
+ }
+ },
+ {
+ "name": "hasLabel",
+ "parameters": {
+ "label": "area-System.Text.Json"
+ }
+ },
+ {
+ "name": "hasLabel",
+ "parameters": {
+ "label": "area-System.Xml"
}
}
]
@@ -6007,7 +6032,7 @@
{
"name": "isInProject",
"parameters": {
- "projectName": "Area Pod: Eric / Jeff - PRs",
+ "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs",
"isOrgProject": true
}
}
@@ -6021,12 +6046,12 @@
"issues",
"project_card"
],
- "taskName": "[Area Pod: Eric / Jeff - PRs] Add new PR to Board",
+ "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - PRs] Add new PR to Board",
"actions": [
{
"name": "addToProject",
"parameters": {
- "projectName": "Area Pod: Eric / Jeff - PRs",
+ "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs",
"columnName": "Needs Champion",
"isOrgProject": true
}
@@ -6661,7 +6686,7 @@
{
"name": "labelAdded",
"parameters": {
- "label": "needs-author-action"
+ "label": "needs more info"
}
},
{
@@ -6698,119 +6723,6 @@
]
}
},
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "PullRequestResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.CodeDom"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Configuration"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Reflection"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Reflection.Emit"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Reflection.Metadata"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Resources"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Runtime.CompilerServices"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Text.RegularExpressions"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Threading.Channels"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Threading.Tasks"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.DirectoryServices"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Buyaa / Jose / Steve - PRs",
- "isOrgProject": true
- }
- }
- ]
- }
- ]
- },
- "eventType": "pull_request",
- "eventNames": [
- "pull_request",
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Buyaa / Jose / Steve - PRs] Add new PR to Board",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Buyaa / Jose / Steve - PRs",
- "columnName": "Needs Champion",
- "isOrgProject": true
- }
- }
- ]
- }
- },
{
"taskType": "trigger",
"capabilityId": "IssueResponder",
@@ -7345,7 +7257,7 @@
{
"name": "labelAdded",
"parameters": {
- "label": "needs-author-action"
+ "label": "needs more info"
}
},
{
@@ -7382,77 +7294,6 @@
]
}
},
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "PullRequestResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Collections"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Linq"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Text.Json"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Xml"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs",
- "isOrgProject": true
- }
- }
- ]
- }
- ]
- },
- "eventType": "pull_request",
- "eventNames": [
- "pull_request",
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Eirik / Krzysztof / Layomi - PRs] Add new PR to Board",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Eirik / Krzysztof / Layomi - PRs",
- "columnName": "Needs Champion",
- "isOrgProject": true
- }
- }
- ]
- }
- },
{
"taskType": "trigger",
"capabilityId": "IssueResponder",
@@ -7538,2436 +7379,5 @@
}
]
}
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssuesOnlyResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-DependencyModel"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Caching"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Configuration"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-DependencyInjection"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Hosting"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Logging"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Options"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Primitives"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ComponentModel"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ComponentModel.Composition"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Composition"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.Activity"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Globalization"
- }
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "name": "isAction",
- "parameters": {
- "action": "reopened"
- }
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInMilestone",
- "parameters": {}
- }
- ]
- }
- ]
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-DependencyModel"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-Extensions-Caching"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-Extensions-Configuration"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-Extensions-DependencyInjection"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-Extensions-Hosting"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-Extensions-Logging"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-Extensions-Options"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-Extensions-Primitives"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.ComponentModel"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.ComponentModel.Composition"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Composition"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Diagnostics.Activity"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Globalization"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "isOpen",
- "parameters": {}
- },
- {
- "operator": "or",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "isOrgProject": true
- }
- }
- ]
- },
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "isOrgProject": true,
- "columnName": "Triaged"
- }
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Add new issue to Board",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "columnName": "Needs Triage",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssueCommentResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-DependencyModel"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Caching"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Configuration"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-DependencyInjection"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Hosting"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Logging"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Options"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Primitives"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ComponentModel"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ComponentModel.Composition"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Composition"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.Activity"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Globalization"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isCloseAndComment",
- "parameters": {}
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "activitySenderHasPermissions",
- "parameters": {
- "permissions": "write"
- }
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "isOrgProject": true
- }
- }
- ]
- },
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "columnName": "Triaged",
- "isOrgProject": true
- }
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issue_comment"
- ],
- "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Needs Further Triage",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "columnName": "Needs Triage",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssuesOnlyResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "columnName": "Needs Triage",
- "isOrgProject": true
- }
- },
- {
- "operator": "and",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-DependencyModel"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Caching"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Configuration"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-DependencyInjection"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Hosting"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Logging"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Options"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Primitives"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ComponentModel"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ComponentModel.Composition"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Composition"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.Activity"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Globalization"
- }
- }
- ]
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Remove relabeled issues",
- "actions": [
- {
- "name": "removeFromProject",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssuesOnlyResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "isOrgProject": true
- }
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "columnName": "Triaged"
- }
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "name": "addedToMilestone",
- "parameters": {}
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "needs more info"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "api-ready-for-review"
- }
- },
- {
- "name": "isAction",
- "parameters": {
- "action": "closed"
- }
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Eric / Maryam / Tarek - Issue Triage] Move to Triaged Column",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - Issue Triage",
- "columnName": "Triaged",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "PullRequestResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-DependencyModel"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Caching"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Configuration"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-DependencyInjection"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Hosting"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Logging"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Options"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Primitives"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ComponentModel"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ComponentModel.Composition"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Composition"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.Activity"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Globalization"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - PRs",
- "isOrgProject": true
- }
- }
- ]
- }
- ]
- },
- "eventType": "pull_request",
- "eventNames": [
- "pull_request",
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Eric / Maryam / Tarek - PRs] Add new PR to Board",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - PRs",
- "columnName": "Needs Champion",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "PullRequestResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - PRs",
- "columnName": "Needs Champion",
- "isOrgProject": true
- }
- },
- {
- "operator": "and",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-DependencyModel"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Caching"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Configuration"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-DependencyInjection"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Hosting"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Logging"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Options"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-Primitives"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ComponentModel"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ComponentModel.Composition"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Composition"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.Activity"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Globalization"
- }
- }
- ]
- }
- ]
- }
- ]
- },
- "eventType": "pull_request",
- "eventNames": [
- "pull_request",
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Eric / Maryam / Tarek - PRs] Remove relabeled PRs",
- "actions": [
- {
- "name": "removeFromProject",
- "parameters": {
- "projectName": "Area Pod: Eric / Maryam / Tarek - PRs",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssuesOnlyResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Infrastructure-libraries"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Microsoft.Win32"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.EventLog"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.PerformanceCounter"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.TraceSource"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Drawing"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Management"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ServiceProcess"
- }
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "name": "isAction",
- "parameters": {
- "action": "reopened"
- }
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInMilestone",
- "parameters": {}
- }
- ]
- }
- ]
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-Infrastructure-libraries"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-Microsoft.Win32"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Diagnostics.EventLog"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Diagnostics.PerformanceCounter"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Diagnostics.TraceSource"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Drawing"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Management"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.ServiceProcess"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "isOpen",
- "parameters": {}
- },
- {
- "operator": "or",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "isOrgProject": true
- }
- }
- ]
- },
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "isOrgProject": true,
- "columnName": "Triaged"
- }
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Add new issue to Board",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "columnName": "Needs Triage",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssueCommentResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Infrastructure-libraries"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Microsoft.Win32"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.EventLog"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.PerformanceCounter"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.TraceSource"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Drawing"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Management"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ServiceProcess"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isCloseAndComment",
- "parameters": {}
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "activitySenderHasPermissions",
- "parameters": {
- "permissions": "write"
- }
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "isOrgProject": true
- }
- }
- ]
- },
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "columnName": "Triaged",
- "isOrgProject": true
- }
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issue_comment"
- ],
- "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Needs Further Triage",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "columnName": "Needs Triage",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssuesOnlyResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "columnName": "Needs Triage",
- "isOrgProject": true
- }
- },
- {
- "operator": "and",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Infrastructure-libraries"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Microsoft.Win32"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.EventLog"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.PerformanceCounter"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.TraceSource"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Drawing"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Management"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ServiceProcess"
- }
- }
- ]
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Remove relabeled issues",
- "actions": [
- {
- "name": "removeFromProject",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssuesOnlyResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "isOrgProject": true
- }
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "columnName": "Triaged"
- }
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "name": "addedToMilestone",
- "parameters": {}
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "needs-author-action"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "api-ready-for-review"
- }
- },
- {
- "name": "isAction",
- "parameters": {
- "action": "closed"
- }
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Carlos / Santi - Issue Triage] Move to Triaged Column",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - Issue Triage",
- "columnName": "Triaged",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "PullRequestResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Infrastructure-libraries"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Microsoft.Win32"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.EventLog"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.PerformanceCounter"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.TraceSource"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Drawing"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Management"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ServiceProcess"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - PRs",
- "isOrgProject": true
- }
- }
- ]
- }
- ]
- },
- "eventType": "pull_request",
- "eventNames": [
- "pull_request",
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Carlos / Santi - PRs] Add new PR to Board",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - PRs",
- "columnName": "Needs Champion",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "PullRequestResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - PRs",
- "columnName": "Needs Champion",
- "isOrgProject": true
- }
- },
- {
- "operator": "and",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Infrastructure-libraries"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Microsoft.Win32"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.EventLog"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.PerformanceCounter"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.TraceSource"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Drawing"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Management"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.ServiceProcess"
- }
- }
- ]
- }
- ]
- }
- ]
- },
- "eventType": "pull_request",
- "eventNames": [
- "pull_request",
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Carlos / Santi - PRs] Remove relabeled PRs",
- "actions": [
- {
- "name": "removeFromProject",
- "parameters": {
- "projectName": "Area Pod: Carlos / Santi - PRs",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssuesOnlyResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-FileSystem"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Console"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.Process"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.IO"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.IO.Compression"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Linq.Parallel"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Memory"
- }
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "name": "isAction",
- "parameters": {
- "action": "reopened"
- }
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInMilestone",
- "parameters": {}
- }
- ]
- }
- ]
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-Extensions-FileSystem"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Console"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Diagnostics.Process"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.IO"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.IO.Compression"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Linq.Parallel"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "area-System.Memory"
- }
- }
- ]
- }
- ]
- },
- {
- "name": "isOpen",
- "parameters": {}
- },
- {
- "operator": "or",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "isOrgProject": true
- }
- }
- ]
- },
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "isOrgProject": true,
- "columnName": "Triaged"
- }
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Adam / David - Issue Triage] Add new issue to Board",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "columnName": "Needs Triage",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssueCommentResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-FileSystem"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Console"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.Process"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.IO"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.IO.Compression"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Linq.Parallel"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Memory"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isCloseAndComment",
- "parameters": {}
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "activitySenderHasPermissions",
- "parameters": {
- "permissions": "write"
- }
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "isOrgProject": true
- }
- }
- ]
- },
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "columnName": "Triaged",
- "isOrgProject": true
- }
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issue_comment"
- ],
- "taskName": "[Area Pod: Adam / David - Issue Triage] Needs Further Triage",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "columnName": "Needs Triage",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssuesOnlyResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "columnName": "Needs Triage",
- "isOrgProject": true
- }
- },
- {
- "operator": "and",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-FileSystem"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Console"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.Process"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.IO"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.IO.Compression"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Linq.Parallel"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Memory"
- }
- }
- ]
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Adam / David - Issue Triage] Remove relabeled issues",
- "actions": [
- {
- "name": "removeFromProject",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "IssuesOnlyResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "isOrgProject": true
- }
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "columnName": "Triaged"
- }
- }
- ]
- },
- {
- "operator": "or",
- "operands": [
- {
- "name": "addedToMilestone",
- "parameters": {}
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "needs-author-action"
- }
- },
- {
- "name": "labelAdded",
- "parameters": {
- "label": "api-ready-for-review"
- }
- },
- {
- "name": "isAction",
- "parameters": {
- "action": "closed"
- }
- }
- ]
- }
- ]
- },
- "eventType": "issue",
- "eventNames": [
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Adam / David - Issue Triage] Move to Triaged Column",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Adam / David - Issue Triage",
- "columnName": "Triaged",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "PullRequestResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "operator": "or",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-FileSystem"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Console"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.Process"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.IO"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.IO.Compression"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Linq.Parallel"
- }
- },
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Memory"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "isInProject",
- "parameters": {
- "projectName": "Area Pod: Adam / David - PRs",
- "isOrgProject": true
- }
- }
- ]
- }
- ]
- },
- "eventType": "pull_request",
- "eventNames": [
- "pull_request",
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Adam / David - PRs] Add new PR to Board",
- "actions": [
- {
- "name": "addToProject",
- "parameters": {
- "projectName": "Area Pod: Adam / David - PRs",
- "columnName": "Needs Champion",
- "isOrgProject": true
- }
- }
- ]
- }
- },
- {
- "taskType": "trigger",
- "capabilityId": "IssueResponder",
- "subCapability": "PullRequestResponder",
- "version": "1.0",
- "config": {
- "conditions": {
- "operator": "and",
- "operands": [
- {
- "name": "isInProjectColumn",
- "parameters": {
- "projectName": "Area Pod: Adam / David - PRs",
- "columnName": "Needs Champion",
- "isOrgProject": true
- }
- },
- {
- "operator": "and",
- "operands": [
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-Extensions-FileSystem"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Console"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Diagnostics.Process"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.IO"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.IO.Compression"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Linq.Parallel"
- }
- }
- ]
- },
- {
- "operator": "not",
- "operands": [
- {
- "name": "hasLabel",
- "parameters": {
- "label": "area-System.Memory"
- }
- }
- ]
- }
- ]
- }
- ]
- },
- "eventType": "pull_request",
- "eventNames": [
- "pull_request",
- "issues",
- "project_card"
- ],
- "taskName": "[Area Pod: Adam / David - PRs] Remove relabeled PRs",
- "actions": [
- {
- "name": "removeFromProject",
- "parameters": {
- "projectName": "Area Pod: Adam / David - PRs",
- "isOrgProject": true
- }
- }
- ]
- }
}
]
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index a4848da2e9ca5..6627d2c2d0a75 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,6 @@ syntax: glob
# instead of directories), git will still ignore them.
.dotnet
.dotnet-mono
-.dotnet-tools-global
.packages
.tools
diff --git a/Directory.Build.props b/Directory.Build.props
index d862ee091fe81..e9e6fc4e36234 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -29,7 +29,6 @@
<_hostArch>$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant)
$(_hostArch)
arm
- armv6
armel
arm64
loongarch64
diff --git a/NuGet.config b/NuGet.config
index 01da668976261..f74e0c4a70248 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -15,7 +15,6 @@
-
diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT
index 55329a8b02294..e38f6ef907d43 100644
--- a/THIRD-PARTY-NOTICES.TXT
+++ b/THIRD-PARTY-NOTICES.TXT
@@ -697,35 +697,6 @@ License for fastmod (https://github.com/lemire/fastmod) and ibm-fpgen (https://g
See the License for the specific language governing permissions and
limitations under the License.
-License for sse4-strstr (https://github.com/WojciechMula/sse4-strstr)
---------------------------------------
-
- Copyright (c) 2008-2016, Wojciech Muła
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
License notice for The C++ REST SDK
-----------------------------------
diff --git a/docs/coding-guidelines/libraries-packaging.md b/docs/coding-guidelines/libraries-packaging.md
index 66909e4df855c..9e07a0683fd8d 100644
--- a/docs/coding-guidelines/libraries-packaging.md
+++ b/docs/coding-guidelines/libraries-packaging.md
@@ -86,12 +86,5 @@ In the analyzer project make sure to do the following. Ensure it only targets `n
```
-In order to mitigate design-time/build-time performance issues with source generators, we generate build logic to allow the end user to disable the source generator from the package. By default, the MSBuild property an end user can set is named `Disable{PackageId}SourceGenerator`. If a package needs a custom property name, this can be overriden by setting the following property in the project that produces the package
-```xml
-
- CustomPropertyName
-
-```
-
### .NETFramework RID specific assets
When targeting .NETFramework, RID specific assets are automatically added to the package if the project contains other compatible RID specific assets, mainly `netstandard2.0-windows`.
diff --git a/docs/design/features/standalone-gc-loading.md b/docs/design/features/standalone-gc-loading.md
index ed7440002e8da..3373bf5559f55 100644
--- a/docs/design/features/standalone-gc-loading.md
+++ b/docs/design/features/standalone-gc-loading.md
@@ -47,7 +47,7 @@ Worth noting is that the JIT (both RyuJIT and the legacy JIT(s) before it) can b
and have realized these same benefits. The existence of an interface and an implementation loadable
from shared libraries has enabled RyuJIT in particular to be used as the code generator for both the
CoreRT compiler and crossgen, while still being flexible enough to be tested using tools that implement
-very non-standard execution engines such as [SuperPMI](https://github.com/dotnet/runtime/blob/main/src/coreclr/tools/superpmi/readme.md).
+very non-standard execution engines such as [SuperPMI](https://github.com/dotnet/runtime/blob/main/src/coreclr/ToolBox/superpmi/readme.txt).
The below loading protocol is inspired directly by the JIT loader and many aspects of the GC loader are identical
to what the JIT does when loading dynamic shared libraries.
diff --git a/docs/design/libraries/DllImportGenerator/StructMarshalling.md b/docs/design/libraries/DllImportGenerator/StructMarshalling.md
index 63781d6d77dbb..ab332616b7413 100644
--- a/docs/design/libraries/DllImportGenerator/StructMarshalling.md
+++ b/docs/design/libraries/DllImportGenerator/StructMarshalling.md
@@ -6,11 +6,10 @@ These types pose an interesting problem for a number of reasons listed below. Wi
## Problems
-- What types require marshalling and what types can be passed as-is to native code?
- - Unmanaged vs Blittable
- - The C# language (and Roslyn) do not have a concept of "blittable types". It only has the concept of "unmanaged types", which is similar to blittable, but differs for `bool`s and `char`s. `bool` and `char` types are "unmanaged", but are never (in the case of `bool`), or only sometimes (in the case of `char`) blittable. As a result, we cannot use the "is this type unmanaged" check in Roslyn for structures without an additional mechanism provided by the runtime.
+- Unmanaged vs Blittable
+ - The C# language (and Roslyn) do not have a concept of "blittable types". It only has the concept of "unmanaged types", which is similar to blittable, but differs for `bool`s and `char`s. `bool` and `char` types are "unmanaged", but are never (in the case of `bool`), or only sometimes (in the case of `char`) blittable. As a result, we cannot use the "is this type unmanaged" check in Roslyn for structures.
- Limited type information in ref assemblies.
- - In the ref assemblies generated by dotnet/arcade's GenAPI (used in dotnet/runtime), we save space and prevent users from relying on private implementation details of structures by emitting limited information about their fields. Structures that have at least one non-object field are given a private `int` field, and structures that have at least one field that transitively contains an object are given one private `object`-typed field. As a result, we do not have full type information at code-generation time for any structures defined in the BCL when compiling a library that uses the ref assemblies.
+ - In the ref assemblies generated by dotnet/runtime, we save space and prevent users from relying on private implementation details of structures by emitting limited information about their fields. Structures that have at least one non-object field are given a private `int` field, and structures that have at least one field that transitively contains an object are given one private `object`-typed field. As a result, we do not have full type information at code-generation time for any structures defined in the BCL when compiling a library that uses the ref assemblies.
- Private reflection
- Even when we do have information about all of the fields, we can't emit code that references them if they are private, so we would have to emit unsafe code and calculate offsets manually to support marshaling them.
@@ -20,13 +19,16 @@ We've been working around another problem for a while in the runtime-integrated
I propose an opt-in design where the owner of a struct has to explicitly opt-in to usage for interop. This enables our team to add special support as desired for various types such as `Span` while also avoiding the private reflection and limited type information issues mentioned above.
-All design options would use these attributes:
+This design would use these attributes:
```csharp
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class)]
public class GeneratedMarshallingAttribute : Attribute {}
+[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class)]
+public class BlittableTypeAttribute : Attribute {}
+
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class)]
public class NativeMarshallingAttribute : Attribute
{
@@ -40,7 +42,7 @@ public class MarshalUsingAttribute : Attribute
}
```
-The `NativeMarshallingAttribute` and `MarshalUsingAttribute` attributes would require that the provided native type `TNative` is a `struct` that does not require any marshalling and has a subset of three methods with the following names and shapes (with the managed type named TManaged):
+The `NativeMarshallingAttribute` and `MarshalUsingAttribute` attributes would require that the provided native type `TNative` is a blittable `struct` and has a subset of three methods with the following names and shapes (with the managed type named TManaged):
```csharp
partial struct TNative
@@ -57,7 +59,7 @@ The analyzer will report an error if neither the constructor nor the `ToManaged`
> :question: Does this API surface and shape work for all marshalling scenarios we plan on supporting? It may have issues with the current "layout class" by-value `[Out]` parameter marshalling where the runtime updates a `class` typed object in place. We already recommend against using classes for interop for performance reasons and a struct value passed via `ref` or `out` with the same members would cover this scenario.
-If the native type `TNative` also has a public `Value` property, then the value of the `Value` property will be passed to native code instead of the `TNative` value itself. As a result, the type `TNative` will be allowed to require marshalling and the type of the `Value` property will be required be passable to native code without any additional marshalling. If the `Value` property is settable, then when marshalling in the native-to-managed direction, a default value of `TNative` will have its `Value` property set to the native value. If `Value` does not have a setter, then marshalling from native to managed is not supported.
+If the native type `TNative` also has a public `Value` property, then the value of the `Value` property will be passed to native code instead of the `TNative` value itself. As a result, the type `TNative` will be allowed to be non-blittable and the type of the `Value` property will be required to be blittable. If the `Value` property is settable, then when marshalling in the native-to-managed direction, a default value of `TNative` will have its `Value` property set to the native value. If `Value` does not have a setter, then marshalling from native to managed is not supported.
If a `Value` property is provided, the developer may also provide a ref-returning or readonly-ref-returning `GetPinnableReference` method. The `GetPinnableReference` method will be called before the `Value` property getter is called. The ref returned by `GetPinnableReference` will be pinned with a `fixed` statement, but the pinned value will not be used (it acts exclusively as a side-effect).
@@ -88,7 +90,7 @@ public struct TMarshaler
#### Pinning
-Since C# 7.3 added a feature to enable custom pinning logic for user types, we should also add support for custom pinning logic. If the user provides a `GetPinnableReference` method on the managed type that matches the requirements to be used in a `fixed` statement and the pointed-to type would not require any additional marshalling, then we will support using pinning to marshal the managed value when possible. The analyzer should issue a warning when the pointed-to type would not match the final native type, accounting for the `Value` property on the native type. Since `MarshalUsingAttribute` is applied at usage time instead of at type authoring time, we will not enable the pinning feature since the implementation of `GetPinnableReference` is likely designed to match the default marshalling rules provided by the type author, not the rules provided by the marshaller provided by the `MarshalUsingAttribute`.
+Since C# 7.3 added a feature to enable custom pinning logic for user types, we should also add support for custom pinning logic. If the user provides a `GetPinnableReference` method on the managed type that matches the requirements to be used in a `fixed` statement and the pointed-to type is blittable, then we will support using pinning to marshal the managed value when possible. The analyzer should issue a warning when the pointed-to type would not match the final native type, accounting for the `Value` property on the native type. Since `MarshalUsingAttribute` is applied at usage time instead of at type authoring time, we will not enable the pinning feature since the implementation of `GetPinnableReference` is likely designed to match the default marshalling rules provided by the type author, not the rules provided by the marshaller provided by the `MarshalUsingAttribute`.
#### Caller-allocated memory
@@ -109,18 +111,27 @@ When these members are present, the source generator will call the two-parameter
Type authors can pass down the `buffer` pointer to native code by defining a `Value` property that returns a pointer to the first element, generally through code using `MemoryMarshal.GetReference()` and `Unsafe.AsPointer`. If `RequiresStackBuffer` is not provided or set to `false`, the `buffer` span must be pinned to be used safely. The `buffer` span can be pinned by defining a `GetPinnableReference()` method on the native type that returns a reference to the first element of the span.
-### Determining if a type is doesn't need marshalling
+### Usage
-For this design, we need to decide how to determine a type doesn't need to be marshalled and already has a representation we can pass directly to native code - that is, we need a definition for "does not require marshalling". We have two designs that we have experimented with below, and we have decided to go with design 2.
+There are 2 usage mechanisms of these attributes.
-#### Design 1: Introducing `BlittableTypeAttribute`
+#### Usage 1, Source-generated interop
-Traditionally, the concept of "does not require marshalling" is referred to as "blittable". The built-in runtime marshalling system has an issue as mentioned above that the concept of `unmanaged` is not the same as the concept of `blittable`. Additionally, due to the ref assembly issue above, we cannot rely on ref assemblies to have accurate information in terms of fields of a type. To solve these issues in combination with the desire to enable manual interop, we need to provide a way for users to signal that a given type should be blittable and that the source generator should not generate marshalling code. We'll introduce a new attribute, the `BlittableTypeAttribute`:
+The user can apply the `GeneratedMarshallingAttribute` to their structure `S`. The source generator will determine if the type is blittable. If it is blittable, the source generator will generate a partial definition and apply the `BlittableTypeAttribute` to the struct type `S`. Otherwise, it will generate a blittable representation of the struct with the aformentioned required shape and apply the `NativeMarshallingAttribute` and point it to the blittable representation. The blittable representation can either be generated as a separate top-level type or as a nested type on `S`.
-```csharp
-[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class)]
-public class BlittableTypeAttribute : Attribute {}
-```
+#### Usage 2, Manual interop
+
+The user may want to manually mark their types as marshalable in this system due to specific restrictions in their code base around marshaling specific types that the source generator does not account for. We could also use this internally to support custom types in source instead of in the code generator. In this scenario, the user would apply either the `BlittableTypeAttribute` or the `NativeMarshallingAttribute` attribute to their struct type. An analyzer would validate that the struct is blittable if the `BlittableTypeAttribute` is applied or validate that the native struct type is blittable and has marshalling methods of the required shape when the `NativeMarshallingAttribute` is applied.
+
+The P/Invoke source generator (as well as the struct source generator when nested struct types are used) would use the `BlittableTypeAttribute` and `NativeMarshallingAttribute` to determine how to marshal a value type parameter or field instead of looking at the fields of the struct directly.
+
+If a structure type does not have either the `BlittableTypeAttribute` or the `NativeMarshallingAttribute` applied at the type definition, the user can supply a `MarshalUsingAttribute` at the marshalling location (field, parameter, or return value) with a native type matching the same requirements as `NativeMarshallingAttribute`'s native type.
+
+All generated stubs will be marked with [`SkipLocalsInitAttribute`](https://docs.microsoft.com/dotnet/api/system.runtime.compilerservices.skiplocalsinitattribute) on supported frameworks. This does require attention when performing custom marshalling as the state of stub allocated memory will be in an undefined state.
+
+### Why do we need `BlittableTypeAttribute`?
+
+Based on the design above, it seems that we wouldn't need `BlittableTypeAttribute`. However, due to the ref assembly issue above in combination with the desire to enable manual interop, we need to provide a way for users to signal that a given type should be blittable and that the source generator should not generate marshalling code.
I'll give a specific example for where we need the `BlittableTypeAttribute` below. Let's take a scenario where we don't have `BlittableTypeAttribute`.
@@ -199,7 +210,7 @@ When the source generator (either Struct, P/Invoke, Reverse P/Invoke, etc.) enco
If someone actively disables the analyzer or writes their types in IL, then they have stepped out of the supported scenarios and marshalling code generated for their types may be inaccurate.
-##### Exception: Generics
+#### Exception: Generics
Because the Roslyn compiler needs to be able to validate that there are not recursive struct definitions, reference assemblies have to contain a field of a type parameter type in the reference assembly if they do in the runtime assembly. As a result, we can inspect private generic fields reliably.
@@ -210,32 +221,6 @@ To enable blittable generics support in this struct marshalling model, we extend
Since all fields typed with non-parameterized types are validated to be blittable at type definition time, we know that they are all blittable at type usage time. So, we only need to validate that the generic fields are instantiated with blittable types.
-#### Design 2: [`DisableRuntimeMarshallingAttribute`](https://github.com/dotnet/runtime/issues/60639)
-
-As an alternative design, we can use a different definition of "does not require marshalling". This design proposes changing the definition from "the runtime's definition of blittable" to "types considered `unmanaged` in C#". The `DisableRuntimeMarshallingAttribute` attribute helps us solve this problem. When applied to an assembly, this attribute causes the runtime to not do any marshalling for any types that are `unmanaged` types and do not have any auto-layout fields for all P/Invokes in the assembly; this includes when the types do not fit the runtime's definition of "blittable". This definition of "does not require marshalling" will work for all of our scenarios, with one issue listed below.
-
-For the auto-layout clause, we have one small issue; today, our ref-assemblies do not expose if a value type is marked as `[StructLayout(LayoutKind.Auto)]`, so we'd still have some cases where we might have runtime failures. However, we can update the tooling used in dotnet/runtime, GenAPI, to expose this information if we so desire. Once that case is handled, we have a mechanism that we can safely use to determine, at compile time, which types will not require marshalling. If we decide to not cover this case (as cases where users mark types as `LayoutKind.Auto` manually are exceptionally rare), we still have a solid design as Roslyn will automatically determine for us if a type is `unmanaged`, so we don't need to do any additional work.
-
-As `unmanaged` is a C# language concept, we can use Roslyn's APIs to determine if a type is `unmanaged` to determine if it does not require marshalling without needing to define any new attributes and reshape the ecosystem. However, to enable this work, the DllImportGenerator, as well as any other source generators that generate calls to native code using the interop team's infrastructure, will need to require that the user applies the `DisableRuntimeMarshallingAttribute` to their assembly when custom user-defined types are used. As we believe that users should be able to move over their assemblies to the new source-generated interop world as a whole assembly, we do not believe that this will cause any serious issues in adoption. To help support users in this case, the interop team will provide a code-fix that will generate the `DisableRuntimeMarshallingAttribute` for users when they use the source generator.
-
-### Usage
-
-There are 2 usage mechanisms of these attributes.
-
-#### Usage 1, Source-generated interop
-
-The user can apply the `GeneratedMarshallingAttribute` to their structure `S`. The source generator will determine if the type requires marshalling. If it does, it will generate a representation of the struct that does not require marshalling with the aformentioned required shape and apply the `NativeMarshallingAttribute` and point it to that new type. This generated representation can either be generated as a separate top-level type or as a nested type on `S`.
-
-#### Usage 2, Manual interop
-
-The user may want to manually mark their types as marshalable with custom marshalling rules in this system due to specific restrictions in their code base around marshaling specific types that the source generator does not account for. We could also use this internally to support custom types in source instead of in the code generator. In this scenario, the user would apply either the `NativeMarshallingAttribute` attribute to their struct type. An analyzer would validate that the native struct type does not require marshalling and has marshalling methods of the required shape when the `NativeMarshallingAttribute` is applied.
-
-The P/Invoke source generator (as well as the struct source generator when nested struct types are used) would use the `NativeMarshallingAttribute` to determine how to marshal a parameter or field with an unknown type.
-
-If a structure type does not meet the requirements to not require marshalling or does not have the `NativeMarshallingAttribute` applied at the type definition, the user can supply a `MarshalUsingAttribute` at the marshalling location (field, parameter, or return value) with a native type matching the same requirements as `NativeMarshallingAttribute`'s native type.
-
-All generated stubs will be marked with [`SkipLocalsInitAttribute`](https://docs.microsoft.com/dotnet/api/system.runtime.compilerservices.skiplocalsinitattribute) on supported frameworks. This does require attention when performing custom marshalling as the state of stub allocated memory will be in an undefined state.
-
### Special case: Transparent Structures
There has been discussion about Transparent Structures, structure types that are treated as their underlying types when passed to native code. The support for a `Value` property on a generated marshalling type supports the transparent struct support. For example, we could support strongly typed `HRESULT` returns with this model as shown below:
@@ -265,7 +250,7 @@ struct HRESULT
In this case, the underlying native type would actually be an `int`, but the user could use the strongly-typed `HResult` type as the public surface area.
-> :question: Should we support transparent structures on manually annotated types that wouldn't need marshalling otherwise? If we do, we should do so in an opt-in manner to make it possible to have a `Value` property on the type without assuming that it is for interop in all cases.
+> :question: Should we support transparent structures on manually annotated blittable types? If we do, we should do so in an opt-in manner to make it possible to have a `Value` property on the blittable type.
#### Example: ComWrappers marshalling with Transparent Structures
diff --git a/docs/design/specs/Ecma-335-Augments.md b/docs/design/specs/Ecma-335-Augments.md
index 6e1900c1dc6bd..1c52fedd4d84c 100644
--- a/docs/design/specs/Ecma-335-Augments.md
+++ b/docs/design/specs/Ecma-335-Augments.md
@@ -13,7 +13,6 @@ This is a list of additions and edits to be made in ECMA-335 specifications. It
- [Static Interface Methods](#static-interface-methods)
- [Covariant Return Types](#covariant-return-types)
- [Unsigned data conversion with overflow detection](#unsigned-data-conversion-with-overflow-detection)
-- [Rules for IL rewriters](#rules-for-il-rewriters)
## Signatures
@@ -949,12 +948,3 @@ Conversions from floating-point numbers to integral values truncate the number t
on the top of the stack is reinterpreted as an unsigned value before the conversion.
Note that integer values of less than 4 bytes are extended to int32 (not native int) on the
evaluation stack.
-
-## Rules for IL Rewriters
-
-There are apis such as `System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(...)` which require that the PE file have a particular structure. In particular, that api requires that the associated RVA of a FieldDef which is used to create a span must be naturally aligned over the data type that `CreateSpan` is instantiated over. There are 2 major concerns.
-
-1. That the RVA be aligned when the PE file is constructed. This may be achieved by whatever means is most convenient for the compiler.
-2. That in the presence of IL rewriters that the RVA remains aligned. This section descibes metadata which will be processed by IL rewriters in order to maintain the required alignment.
-
-In order to maintain alignment, if the field needs alignment to be preserved, the field must be of a type locally defined within the module which has a Pack (§II.10.7) value of the desired alignment. Unlike other uses of the .pack directive, in this circumstance the .pack specifies a minimum alignment.
diff --git a/docs/design/specs/PortablePdb-Metadata.md b/docs/design/specs/PortablePdb-Metadata.md
index c1d8e3c442066..811af00510bea 100644
--- a/docs/design/specs/PortablePdb-Metadata.md
+++ b/docs/design/specs/PortablePdb-Metadata.md
@@ -64,8 +64,6 @@ There shall be no duplicate rows in the _Document_ table, based upon document na
_Name_ shall not be nil. It can however encode an empty name string.
-_Hash_ is the file content hashed using the specified _HashAlgorithm_. It is used to validate that a source file matches the one used by the compiler when compiling the source code.
-
The values for which field _Language_ has a defined meaning are listed in the following tables along with the corresponding interpretation:
| _Language_ field value | language |
diff --git a/docs/pr-builds.md b/docs/pr-builds.md
deleted file mode 100644
index f5f7555ae7e67..0000000000000
--- a/docs/pr-builds.md
+++ /dev/null
@@ -1,94 +0,0 @@
-## PR Builds
-When submitting a PR to the `dotnet/runtime` repository various builds will run validation in many areas to ensure we keep productivity and quality high.
-
-The `dotnet/runtime` validation system can become overwhelming as we need to cover a lot of build scenarios and test in all the platforms that we support. In order to try to make this more reliable and spend the least amount of time testing what the PR changes need we have various pipelines, required and optional that are covered in this document.
-
-Most of the repository pipelines use a custom mechanism to evaluate paths based on the changes contained in the PR to try and build/test the least that we can without compromising quality. This is the initial step on every pipeline that depends on this infrastructure, called "Evalute Paths". In this step you can see the result of the evaluation for each subset of the repository. For more details on which subsets we have based on paths see [here](https://github.com/dotnet/runtime/blob/513fe2863ad5ec6dc453d223d4b60f787a0ffa78/eng/pipelines/common/evaluate-default-paths.yml). Also to understand how this mechanism works you can read this [comment](https://github.com/dotnet/runtime/blob/513fe2863ad5ec6dc453d223d4b60f787a0ffa78/eng/pipelines/evaluate-changed-paths.sh#L3-L12).
-
-### Runtime pipeline
-This is the "main" pipeline for the runtime product. In this pipeline we include the most critical tests and platforms where we have enough test resources in order to deliver test results in a reasonable amount of time. The tests executed in this pipeline for runtime and libraries are considered innerloop, are the tests that are executed locally when one runs tests locally.
-
-For mobile platforms and wasm we run some smoke tests that aim to protect the quality of these platforms. We had to move to a smoke test approach given the hardware and time limitations that we encountered and contributors were affected by this with unstability and long wait times for their PRs to finish validation.
-
-### Runtime-dev-innerloop pipeline
-This pipeline is also required, and its intent is to cover a developer innerloop scenarios that could be affected by any change, like running a specific build command or running tests inside Visual Studio, etc.
-
-### Dotnet-linker-tests
-This is also a required pipeline. The purpose of this pipeline is to test that the libraries code is linker friendly. Meaning that when we trim our libraries using the ILLink, we don't have any trimming bugs, like a required method on a specific scenario is trimmed away by accident.
-
-### Runtime-staging
-This pipeline runs on every change, however it behaves a little different than the other pipelines. This pipeline, will not fail if there are test failures, however it will fail if there is a timeout or a build failure. The reason why we fail on build failures is because we want to protect the developer innerloop (building the repository) for this platform.
-
-The tests will not fail because the intent of this platform is to stage new platforms where the test infrastructure is new and we need to test if we have enough capacity to include that new platform on the "main" runtime pipeline without causing flakiness. Once we analyze data and a platform is stable when running on PRs in this pipeline for at least a weak it can be promoted either to the `runtime-extra-platforms` pipeline or to the `runtime` pipeline.
-
-### Runtime-extra-platforms
-This pipeline does not run by default as it is not required for a PR, but it runs twice a day, and it can also be invoked in specific PRs by commenting `/azp run runtime-extra-platforms`. However, this pipeline is still an important part of our testing.
-
-This pipeline runs innerloop tests on platforms where we don't have enough hardware capacity to run tests (mobile, browser) or on platforms where we believe tests should organically pass based on the coverage we have in the "main" runtime pipeline. For example, in the "main" pipeline we run tests on Ubuntu 21.10 but since we also support Ubuntu 18.04 which is an LTS release, we run tests on Ubuntu 18.04 of this pipeline just to make sure we have healthy tests on those platforms which we are releasing a product for.
-
-Another concrete scenario would be windows arm64 for libraries tests. Where we don't have enough hardware, but the JIT is the most important piece to test as that is what generates the native code to run on that platform, so we run JIT tests on arm64 in the "main" pipeline, but our libraries tests are only run on the `runtime-extra-platforms` pipeline.
-
-### Outerloop pipelines
-We have various pipelines that their names contain `Outerloop` on them. These pipelines will not run by default on every PR, they can also be invoked using the `/azp run` comment and will run on a daily basis to analyze test results.
-
-These pipelines will run tests that take very long, that are not very stable (i.e some networking tests), or that modify machine state. Such tests are called `Outerloop` tests rather than `innerloop`.
-
-## Rerunning Validation
-
-Validation may fail for several reasons:
-
-### Option 1: You have a defect in your PR
-
-* Simply push the fix to your PR branch, and validation will start over.
-
-### Option 2: There is a flaky test that is not related to your PR
-
-* Your assumption should be that a failed test indicates a problem in your PR. (If we don't operate this way, chaos ensues.) If the test fails when run again, it is almost surely a failure caused by your PR. However, there are occasions where unrelated failures occur. Here's some ways to know:
- * Perhaps you see the same failure in CI results for unrelated active PR's.
- * It's a known issue listed in our [big tracking issue](https://github.com/dotnet/runtime/issues/702) or tagged `blocking-clean-ci` [(query here)](https://github.com/dotnet/runtime/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Ablocking-clean-ci+)
- * It's otherwise beyond any reasonable doubt that your code changes could not have caused this.
- * If the tests pass on rerun, that may suggest it's not related.
-* In this situation, you want to re-run but not necessarily rebase on main.
- * To rerun just the failed leg(s):
- * Click on any leg. Navigate through the Azure DevOps UI, find the "..." button and choose "Retry failed legs"
- * Or, on the GitHub Checks tab choose "re-run failed checks". This will not rebase your change.
- * To rerun all validation:
- * Add a comment `/azp run runtime`
- * Or, click on "re-run all checks" in the GitHub Checks tab
- * Or, simply close and reopen the PR.
-* If you have established that it is an unrelated failure, please ensure we have an active issue for it. See the [unrelated failure](#what-to-do-if-you-determine-the-failure-is-unrelated) section below.
-* Whoever merges the PR should be satisfied that the failure is unrelated, is not introduced by the change, and that we are appropriately tracking it.
-
-### Option 3: The state of the main branch HEAD is bad.
-
-* This is the very rare case where there was a build break in main, and you got unlucky. Hopefully the break has been fixed, and you want CI to rebase your change and rerun validation.
-* To rebase and rerun all validation:
- * Add a comment `/azp run runtime`
- * Or, click on "re-run all checks" in the GitHub Checks tab
- * Or, simply close and reopen the PR.
- * Or, ammend your commit with `--amend --no-edit` and force push to your branch.
-
-### Additional information:
- * You can list the available pipelines by adding a comment like `/azp list` or get the available commands by adding a comment like `azp help`.
- * In the rare case the license/cla check fails to register a response, it can be rerun by issuing a GET request to `https://cla.dotnetfoundation.org/check/dotnet/runtime?pullRequest={pr_number}`. A successful response may be a redirect to `https://github.com`.
- * Reach out to the infrastructure team for assistance on [Teams channel](https://teams.microsoft.com/l/channel/19%3ab27b36ecd10a46398da76b02f0411de7%40thread.skype/Infrastructure?groupId=014ca51d-be57-47fa-9628-a15efcc3c376&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47) (for corpnet users) or on [Gitter](https://gitter.im/dotnet/community) in other cases.
-
-## What to do if you determine the failure is unrelated
-
-If you have determined the failure is definitely not caused by changes in your PR, please do this:
-
-* Search for an [existing issue](https://github.com/dotnet/runtime/issues). Usually the test method name or (if a crash/hang) the test assembly name are good search parameters.
- * If there's an existing issue, add a comment with
- * a) the link to the build
- * b) the affected configuration (ie `net6.0-windows-Release-x64-Windows.81.Amd64.Open`)
- * c) all console output including the error message and stack trace from the Azure DevOps tab (This is necessary as retention policies are in place that recycle old builds.)
- * d) if there's a dump file (see Attachments tab in Azure DevOps) include that
- * If the issue is already closed, reopen it and update the labels to reflect the current failure state.
- * If there's no existing issue, create an issue with the same information listed above.
- * Update the original pull request with a comment linking to the new or existing issue.
-* In a follow-up Pull Request, disable the failing test(s) with the corresponding issue link tracking the disable.
- * Update the tracking issue with the label `disabled-test`.
- * For libraries tests add a [`[ActiveIssue(link)]`](https://github.com/dotnet/arcade/blob/master/src/Microsoft.DotNet.XUnitExtensions/src/Attributes/ActiveIssueAttribute.cs) attribute on the test method. You can narrow the disabling down to runtime variant, flavor, and platform. For an example see [File_AppendAllLinesAsync_Encoded](https://github.com/dotnet/runtime/blob/cf49643711ad8aa4685a8054286c1348cef6e1d8/src/libraries/System.IO.FileSystem/tests/File/AppendAsync.cs#L74)
- * For runtime tests found under `src/tests`, please edit [`issues.targets`](https://github.com/dotnet/runtime/blob/main/src/tests/issues.targets). There are several groups for different types of disable (mono vs. coreclr, different platforms, different scenarios). Add the folder containing the test and issue mimicking any of the samples in the file.
-
-There are plenty of possible bugs, e.g. race conditions, where a failure might highlight a real problem and it won't manifest again on a retry. Therefore these steps should be followed for every iteration of the PR build, e.g. before retrying/rebuilding.
\ No newline at end of file
diff --git a/docs/pr-guide.md b/docs/pr-guide.md
index eb7dea7a01ba7..b250efd6e12dd 100644
--- a/docs/pr-guide.md
+++ b/docs/pr-guide.md
@@ -24,10 +24,71 @@ Anyone with write access can merge a pull request manually or by setting the [au
* The PR has been approved by at least one reviewer and any other objections are addressed.
* You can request another review from the original reviewer.
-* The PR successfully builds and passes all tests in the Continuous Integration (CI) system. For more information please read to our [PR Builds](pr-builds.md) doc.
+* The PR successfully builds and passes all tests in the Continuous Integration (CI) system.
+ * Depending on your change, you may need to re-run validation. See [rerunning validation](#rerunning-validation) below.
Typically, PRs are merged as one commit. It creates a simpler history than a Merge Commit. "Special circumstances" are rare, and typically mean that there are a series of cleanly separated changes that will be too hard to understand if squashed together, or for some reason we want to preserve the ability to bisect them.
+## Rerunning Validation
+
+Validation may fail for several reasons:
+
+### Option 1: You have a defect in your PR
+
+* Simply push the fix to your PR branch, and validation will start over.
+
+### Option 2: There is a flaky test that is not related to your PR
+
+* Your assumption should be that a failed test indicates a problem in your PR. (If we don't operate this way, chaos ensues.) If the test fails when run again, it is almost surely a failure caused by your PR. However, there are occasions where unrelated failures occur. Here's some ways to know:
+ * Perhaps you see the same failure in CI results for unrelated active PR's.
+ * It's a known issue listed in our [big tracking issue](https://github.com/dotnet/runtime/issues/702) or tagged `blocking-clean-ci` [(query here)](https://github.com/dotnet/runtime/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Ablocking-clean-ci+)
+ * Its otherwise beyond any reasonable doubt that your code changes could not have caused this.
+ * If the tests pass on rerun, that may suggest it's not related.
+* In this situation, you want to re-run but not necessarily rebase on main.
+ * To rerun just the failed leg(s):
+ * Click on any leg. Navigate through the Azure DevOps UI, find the "..." button and choose "Retry failed legs"
+ * Or, on the GitHub Checks tab choose "re-run failed checks". This will not rebase your change.
+ * To rerun all validation:
+ * Add a comment `/azp run runtime`
+ * Or, click on "re-run all checks" in the GitHub Checks tab
+ * Or, simply close and reopen the PR.
+* If you have established that it is an unrelated failure, please ensure we have an active issue for it. See the [unrelated failure](#what-to-do-if-you-determine-the-failure-is-unrelated) section below.
+* Whoever merges the PR should be satisfied that the failure is unrelated, is not introduced by the change, and that we are appropriately tracking it.
+
+### Option 3: The state of the main branch HEAD is bad.
+
+* This is the very rare case where there was a build break in main, and you got unlucky. Hopefully the break has been fixed, and you want CI to rebase your change and rerun validation.
+* To rebase and rerun all validation:
+ * Add a comment `/azp run runtime`
+ * Or, click on "re-run all checks" in the GitHub Checks tab
+ * Or, simply close and reopen the PR.
+ * Or, ammend your commit with `--amend --no-edit` and force push to your branch.
+
+### Additional information:
+ * You can list the available pipelines by adding a comment like `/azp list` or get the available commands by adding a comment like `azp help`.
+ * In the rare case the license/cla check fails to register a response, it can be rerun by issuing a GET request to `https://cla.dotnetfoundation.org/check/dotnet/runtime?pullRequest={pr_number}`. A successful response may be a redirect to `https://github.com`.
+ * Reach out to the infrastructure team for assistance on [Teams channel](https://teams.microsoft.com/l/channel/19%3ab27b36ecd10a46398da76b02f0411de7%40thread.skype/Infrastructure?groupId=014ca51d-be57-47fa-9628-a15efcc3c376&tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47) (for corpnet users) or on [Gitter](https://gitter.im/dotnet/community) in other cases.
+
+## What to do if you determine the failure is unrelated
+
+If you have determined the failure is definitely not caused by changes in your PR, please do this:
+
+* Search for an [existing issue](https://github.com/dotnet/runtime/issues). Usually the test method name or (if a crash/hang) the test assembly name are good search parameters.
+ * If there's an existing issue, add a comment with
+ * a) the link to the build
+ * b) the affected configuration (ie `net6.0-windows-Release-x64-Windows.81.Amd64.Open`)
+ * c) all console output including the error message and stack trace from the Azure DevOps tab (This is necessary as retention policies are in place that recycle old builds.)
+ * d) if there's a dump file (see Attachments tab in Azure DevOps) include that
+ * If the issue is already closed, reopen it and update the labels to reflect the current failure state.
+ * If there's no existing issue, create an issue with the same information listed above.
+ * Update the original pull request with a comment linking to the new or existing issue.
+* In a follow-up Pull Request, disable the failing test(s) with the corresponding issue link tracking the disable.
+ * Update the tracking issue with the label `disabled-test`.
+ * For libraries tests add a [`[ActiveIssue(link)]`](https://github.com/dotnet/arcade/blob/master/src/Microsoft.DotNet.XUnitExtensions/src/Attributes/ActiveIssueAttribute.cs) attribute on the test method. You can narrow the disabling down to runtime variant, flavor, and platform. For an example see [File_AppendAllLinesAsync_Encoded](https://github.com/dotnet/runtime/blob/a259ec2e967d502f82163beba6b84da5319c5e08/src/libraries/System.IO.FileSystem/tests/File/AppendAsync.cs#L899)
+ * For runtime tests found under `src/tests`, please edit [`issues.targets`](https://github.com/dotnet/runtime/blob/main/src/tests/issues.targets). There are several groups for different types of disable (mono vs. coreclr, different platforms, different scenarios). Add the folder containing the test and issue mimicking any of the samples in the file.
+
+There are plenty of possible bugs, e.g. race conditions, where a failure might highlight a real problem and it won't manifest again on a retry. Therefore these steps should be followed for every iteration of the PR build, e.g. before retrying/rebuilding.
+
## Blocking Pull Request Merging
If for whatever reason you would like to move your pull request back to an in-progress status to avoid merging it in the current form, you can do that by adding [WIP] prefix to the pull request title.
diff --git a/docs/project/glossary.md b/docs/project/glossary.md
index 28fed9e8e160d..cb7e0b21538b8 100644
--- a/docs/project/glossary.md
+++ b/docs/project/glossary.md
@@ -43,7 +43,7 @@ terminology.
| SDK | Software Development Kit. The [.NET SDK](https://docs.microsoft.com/dotnet/core/sdk) contains the .NET CLI, .NET libraries and runtime, and the dotnet driver. |
| SEH | [Structured Exception Handling](https://docs.microsoft.com/windows/win32/debug/structured-exception-handling). Unified mechanism for handling hardware and software exceptions on Windows. |
| SOS | [Son of Strike](https://docs.microsoft.com/archive/blogs/jasonz/sos-debugging-of-the-clr-part-1). The debugging extension for DbgEng based debuggers. Uses the DAC as an abstraction layer for its operation. |
-| SuperPMI | JIT component test framework (super fast JIT testing - it mocks/replays EE in EE-JIT interface) - see [SuperPMI details](https://github.com/dotnet/runtime/blob/main/src/coreclr/tools/superpmi/readme.md). |
+| SuperPMI | JIT component test framework (super fast JIT testing - it mocks/replays EE in EE-JIT interface) - see [SuperPMI details](https://github.com/dotnet/runtime/blob/main/src/coreclr/ToolBox/superpmi/readme.txt). |
| SVR | The CLR used to be built as two variants, with one called "mscorsvr.dll", to mean the "server" version. In particular, it contained the server GC implementation, which was intended for multi-threaded apps capable of taking advantage of multiple processors. In the .NET Framework 2 release, the two variants were merged into "mscorwks.dll". The WKS version was the default, however the SVR version remained available. |
| TFM | [Target Framework Moniker](https://docs.microsoft.com/dotnet/standard/frameworks) such as `net6.0` or `netstandard2.0`. |
| TPA | Trusted Platform Assemblies used to be a special set of assemblies that comprised the platform assemblies, when it was originally designed. As of today, it is simply the set of assemblies known to constitute the application. |
@@ -187,7 +187,8 @@ by Mono runtime in environments that allow fallback to JIT or need IL interprete
[Native AOT](https://github.com/dotnet/designs/blob/main/accepted/2020/form-factors.md#native-aot-form-factors) is
a .NET runtime form factor with key performance characteristics (startup time, binary size and steady state throughput and predictability)
-competitive with statically compiled languages.
+competitive with statically compiled languages. A .NET runtime flavor based on CoreCLR with these characteristics is being developed as
+experimental project in [dotnet/runtimelab](https://github.com/dotnet/runtimelab/tree/feature/NativeAOT) repo.
## Frameworks
diff --git a/docs/workflow/building/coreclr/nativeaot.md b/docs/workflow/building/coreclr/nativeaot.md
index 3206fc7349c20..968bb5fa89243 100644
--- a/docs/workflow/building/coreclr/nativeaot.md
+++ b/docs/workflow/building/coreclr/nativeaot.md
@@ -21,7 +21,7 @@ The executable looks like a native executable, in the sense that it can be debug
## Building
- [Install pre-requisites](../../README.md#build-requirements)
-- Run `build[.cmd|.sh] clr+libs -rc [Debug|Release] -lc Release` from the repo root. This will restore nuget packages required for building and build the parts of the repo required for general CoreCLR development. Alternatively, instead of specifying `clr+libs`, you can specify `clr.jit+clr.tools+clr.nativeaotlibs+clr.nativeaotruntime+libs` which is more targeted and builds faster. Replace `clr.jit` with `clr.alljits` if you need to crosscompile.
+- Run `build[.cmd|.sh] clr+libs -rc [Debug|Release] -lc Release` from the repo root. This will restore nuget packages required for building and build the parts of the repo required for general CoreCLR development. Alternatively, instead of specifying `clr+libs`, you can specify `clr.jit+clr.tools+clr.nativeaotlibs+libs` which is more targeted and builds faster. Replace `clr.jit` with `clr.alljits` if you need to crosscompile.
- [NOT PORTED OVER YET] The build will place the toolchain packages at `artifacts\packages\[Debug|Release]\Shipping`. To publish your project using these packages:
- [NOT PORTED OVER YET] Add the package directory to your `nuget.config` file. For example, replace `dotnet-experimental` line in `samples\HelloWorld\nuget.config` with ``
- [NOT PORTED OVER YET] Run `dotnet publish --packages pkg -r [win-x64|linux-x64|osx-64] -c [Debug|Release]` to publish your project. `--packages pkg` option restores the package into a local directory that is easy to cleanup once you are done. It avoids polluting the global nuget cache with your locally built dev package.
diff --git a/docs/workflow/building/coreclr/osx-instructions.md b/docs/workflow/building/coreclr/osx-instructions.md
index 41e8d87de1a7e..d8bf4fe604fcb 100644
--- a/docs/workflow/building/coreclr/osx-instructions.md
+++ b/docs/workflow/building/coreclr/osx-instructions.md
@@ -1,12 +1,49 @@
-Build CoreCLR on macOS
+Build CoreCLR on OS X
=====================
-This guide will walk you through building CoreCLR on macOS. We'll start by showing how to set up your environment from scratch.
+This guide will walk you through building CoreCLR on OS X. We'll start by showing how to set up your environment from scratch.
Environment
===========
-Ensure you have all of the prerequisites installed from the [macOS Requirements](/docs/workflow/requirements/macos-requirements.md).
+These instructions were validated on macOS 10.12. Sierra. On older versions coreFX will fail to build properly because of SSL API changes.
+
+If your machine has Command Line Tools for XCode 6.3 installed, you'll need to update them to the 6.3.1 version or higher in order to successfully build. There was an issue with the headers that shipped with version 6.3 that was subsequently fixed in 6.3.1.
+
+Git Setup
+---------
+
+Clone the CoreCLR and CoreFX repositories (either upstream or a fork).
+
+```sh
+git clone https://github.com/dotnet/runtime
+# Cloning into 'runtime'...
+```
+
+CMake
+-----
+
+CoreCLR has a dependency on CMake for the build. You can install it with [Homebrew](https://brew.sh/).
+
+```sh
+brew install cmake
+```
+
+ICU
+---
+ICU (International Components for Unicode) is also required to build and run. It can be obtained via [Homebrew](https://brew.sh/).
+
+```sh
+brew install icu4c
+```
+
+pkg-config
+----------
+pkg-config is also required to build. It can be obtained via [Homebrew](https://brew.sh/).
+
+```sh
+brew install pkg-config
+```
Build the Runtime and System.Private.CoreLib
============================================
diff --git a/docs/workflow/debugging/libraries/debugging-corelib.md b/docs/workflow/debugging/libraries/debugging-corelib.md
deleted file mode 100644
index 9dd817d5bf7ff..0000000000000
--- a/docs/workflow/debugging/libraries/debugging-corelib.md
+++ /dev/null
@@ -1,7 +0,0 @@
-Debugging System.Private.CoreLib
-==========================
-
-`System.Console.Write`/`System.Console.WriteLine` cannot be used in `System.Private.CoreLib`. Instead, use `Internal.Console.Write` to add temporary logging for printf-style debugging.
-
-### Android
-The logs can be found through the generated Android Debug Bridge log or viewed directly through ADB logcat.
diff --git a/docs/workflow/debugging/mono/wasm-debugging.md b/docs/workflow/debugging/mono/wasm-debugging.md
index 4e7945ce515b6..cfc98c1be2dbd 100644
--- a/docs/workflow/debugging/mono/wasm-debugging.md
+++ b/docs/workflow/debugging/mono/wasm-debugging.md
@@ -2,7 +2,7 @@
WASM runtime debugging
======================
-- Disable symbol stripping by setting the `WasmNativeStrip` msbuild property to `false`. See also, [collecting stack traces with symbols in Blazor](#collecting-stack-traces-with-symbols-in-blazor)
+- Disable symbol stripping by setting the `WasmNativeStrip` msbuild property to `false`.
- Emscripten generates dwarf debug info and Chrome 80 and later can use it.
@@ -133,131 +133,3 @@ These kinds of faults usually happen because the mono runtime has some helper fu
never meant to be reached, i.e. `no_gsharedvt_in_wrapper` or `no_llvmonly_interp_method_pointer`.
These functions are used as placeholders for function pointers with different signatures, so
if they do end up being called due to a bug, a signature mismatch error happens.
-
-# Collecting stack traces with symbols in Blazor
-
-When debugging a native crash in a .NET 6 Blazor app or another WebAssembly
-framework that uses our default `dotnet.wasm`, the native stack frames will not
-have C symbol names, but will instead look like `$func1234`.
-
-For example this Razor page will crash when a user clicks on the `Crash` button
-
-```csharp
-
-
-@code {
- private void Crash ()
- {
- IntPtr p = (IntPtr)0x01;
- Console.WriteLine ("About to crash");
- System.Runtime.InteropServices.Marshal.FreeHGlobal(p);
- }
-}
-```
-
-Clicking on the `Crash` button will produce the following output in the console (the function indices may be different):
-
-```console
-dotnet.wasm:0x1d8355 Uncaught (in promise) RuntimeError: memory access out of bounds
- at _framework/dotnet.wasm
- at _framework/dotnet.wasm
- at _framework/dotnet.wasm
- at _framework/dotnet.wasm
- at _framework/dotnet.wasm
- at _framework/dotnet.wasm
- at _framework/dotnet.wasm
- at _framework/dotnet.wasm
- at _framework/dotnet.wasm
- at _framework/dotnet.wasm
-$free @ dotnet.wasm:0x1d8355
-$func4027 @ dotnet.wasm:0xead6a
-$func219 @ dotnet.wasm:0x1a03a
-$func167 @ dotnet.wasm:0xcaf7
-$func166 @ dotnet.wasm:0xba0a
-$func2810 @ dotnet.wasm:0xabacf
-$func1615 @ dotnet.wasm:0x6f8eb
-$func1613 @ dotnet.wasm:0x6f85d
-$func966 @ dotnet.wasm:0x502dc
-$func219 @ dotnet.wasm:0x1a0e2
-$func167 @ dotnet.wasm:0xcaf7
-$func166 @ dotnet.wasm:0xba0a
-$func2810 @ dotnet.wasm:0xabacf
-$func1615 @ dotnet.wasm:0x6f8eb
-$func1619 @ dotnet.wasm:0x6ff58
-$mono_wasm_invoke_method @ dotnet.wasm:0x96c9
-Module._mono_wasm_invoke_method @ dotnet.6.0.1.hopd7ipo8x.js:1
-managed__Microsoft_AspNetCore_Components_WebAssembly__Microsoft_AspNetCore_Components_WebAssembly_Services_DefaultWebAssemblyJSRuntime_BeginInvokeDotNet @ managed__Microsoft_AspNetCore_Components_WebAssembly__Microsoft_AspNetCore_Components_WebAssembly_Services_DefaultWebAssemblyJSRuntime_BeginInvokeDotNet:19
-beginInvokeDotNetFromJS @ blazor.webassembly.js:1
-b @ blazor.webassembly.js:1
-invokeMethodAsync @ blazor.webassembly.js:1
-(anonymous) @ blazor.webassembly.js:1
-invokeWhenHeapUnlocked @ blazor.webassembly.js:1
-S @ blazor.webassembly.js:1
-C @ blazor.webassembly.js:1
-dispatchGlobalEventToAllElements @ blazor.webassembly.js:1
-onGlobalEvent @ blazor.webassembly.js:1
-```
-
-In order to get symbols, the user should:
-
-1. Install the `wasm-tools` workload using `dotnet workload install wasm-tools`
-2. Set these additional properties in their `.csproj` file:
-
- ```xml
-
-
- true
- false
-
- ```
-
-3. Delete the `bin` and `obj` folders, re-build the project and run it again.
-
-Now clicking on the `Crash` button will produce a stack trace with symbols:
-
-```console
-dotnet.wasm:0x224878 Uncaught (in promise) RuntimeError: memory access out of bounds
- at dlfree (dotnet.wasm:0x224878)
- at SystemNative_Free (dotnet.wasm:0x20f0e2)
- at do_icall (dotnet.wasm:0x190f9)
- at do_icall_wrapper (dotnet.wasm:0x18429)
- at interp_exec_method (dotnet.wasm:0xa56c)
- at interp_runtime_invoke (dotnet.wasm:0x943a)
- at mono_jit_runtime_invoke (dotnet.wasm:0x1dec32)
- at do_runtime_invoke (dotnet.wasm:0x95fca)
- at mono_runtime_invoke_checked (dotnet.wasm:0x95f57)
- at mono_runtime_try_invoke_array (dotnet.wasm:0x9a87e)
-$dlfree @ dotnet.wasm:0x224878
-$SystemNative_Free @ dotnet.wasm:0x20f0e2
-$do_icall @ dotnet.wasm:0x190f9
-$do_icall_wrapper @ dotnet.wasm:0x18429
-$interp_exec_method @ dotnet.wasm:0xa56c
-$interp_runtime_invoke @ dotnet.wasm:0x943a
-$mono_jit_runtime_invoke @ dotnet.wasm:0x1dec32
-$do_runtime_invoke @ dotnet.wasm:0x95fca
-$mono_runtime_invoke_checked @ dotnet.wasm:0x95f57
-$mono_runtime_try_invoke_array @ dotnet.wasm:0x9a87e
-$mono_runtime_invoke_array_checked @ dotnet.wasm:0x9af17
-$ves_icall_InternalInvoke @ dotnet.wasm:0x702ed
-$ves_icall_InternalInvoke_raw @ dotnet.wasm:0x7777f
-$do_icall @ dotnet.wasm:0x191c5
-$do_icall_wrapper @ dotnet.wasm:0x18429
-$interp_exec_method @ dotnet.wasm:0xa56c
-$interp_runtime_invoke @ dotnet.wasm:0x943a
-$mono_jit_runtime_invoke @ dotnet.wasm:0x1dec32
-$do_runtime_invoke @ dotnet.wasm:0x95fca
-$mono_runtime_try_invoke @ dotnet.wasm:0x966fe
-$mono_runtime_invoke @ dotnet.wasm:0x98982
-$mono_wasm_invoke_method @ dotnet.wasm:0x227de2
-Module._mono_wasm_invoke_method @ dotnet..y6ggkhlo8e.js:9927
-managed__Microsoft_AspNetCore_Components_WebAssembly__Microsoft_AspNetCore_Components_WebAssembly_Services_DefaultWebAssemblyJSRuntime_BeginInvokeDotNet @ managed__Microsoft_AspNetCore_Components_WebAssembly__Microsoft_AspNetCore_Components_WebAssembly_Services_DefaultWebAssemblyJSRuntime_BeginInvokeDotNet:19
-beginInvokeDotNetFromJS @ blazor.webassembly.js:1
-b @ blazor.webassembly.js:1
-invokeMethodAsync @ blazor.webassembly.js:1
-(anonymous) @ blazor.webassembly.js:1
-invokeWhenHeapUnlocked @ blazor.webassembly.js:1
-S @ blazor.webassembly.js:1
-C @ blazor.webassembly.js:1
-dispatchGlobalEventToAllElements @ blazor.webassembly.js:1
-onGlobalEvent @ blazor.webassembly.js:1
-```
diff --git a/eng/CodeAnalysis.src.globalconfig b/eng/CodeAnalysis.src.globalconfig
index e5ae41903b5a7..0fc9bf8e5a7ee 100644
--- a/eng/CodeAnalysis.src.globalconfig
+++ b/eng/CodeAnalysis.src.globalconfig
@@ -152,10 +152,10 @@ dotnet_diagnostic.CA1064.severity = none
dotnet_diagnostic.CA1065.severity = none
# CA1066: Implement IEquatable when overriding Object.Equals
-dotnet_diagnostic.CA1066.severity = warning
+dotnet_diagnostic.CA1066.severity = none
# CA1067: Override Object.Equals(object) when implementing IEquatable
-dotnet_diagnostic.CA1067.severity = warning
+dotnet_diagnostic.CA1067.severity = none
# CA1068: CancellationToken parameters must come last
dotnet_diagnostic.CA1068.severity = none
diff --git a/eng/CodeAnalysis.test.globalconfig b/eng/CodeAnalysis.test.globalconfig
index f56a38cfa707c..572310d3b86d0 100644
--- a/eng/CodeAnalysis.test.globalconfig
+++ b/eng/CodeAnalysis.test.globalconfig
@@ -1681,7 +1681,7 @@ dotnet_diagnostic.xUnit2012.severity = warning
dotnet_diagnostic.xUnit2013.severity = none
# xUnit2014: Do not use throws check to check for asynchronously thrown exception
-dotnet_diagnostic.xUnit2014.severity = none
+dotnet_diagnostic.xUnit2014.severity = warning
# xUnit2015: Do not use typeof expression to check the exception type
dotnet_diagnostic.xUnit2015.severity = warning
diff --git a/eng/Subsets.props b/eng/Subsets.props
index 5ea1ff48e23f4..772fbfcb99532 100644
--- a/eng/Subsets.props
+++ b/eng/Subsets.props
@@ -27,7 +27,7 @@
flavor is used to decide when to build the hosts and installers. -->
CoreCLR
- Mono
+ Mono
@@ -58,7 +58,7 @@
- clr.native+linuxdac+clr.corelib+clr.tools+clr.nativecorelib+clr.packages+clr.nativeaotlibs+clr.spmi
+ clr.native+linuxdac+clr.corelib+clr.tools+clr.nativecorelib+clr.packages+clr.nativeaotlibs
clr.iltools+clr.packages
@@ -106,14 +106,12 @@
-
-
+
-
@@ -204,14 +202,10 @@
$(ClrRuntimeBuildSubsets);ClrILToolsSubset=true
-
+
$(ClrRuntimeBuildSubsets);ClrNativeAotSubset=true
-
- $(ClrRuntimeBuildSubsets);ClrSpmiSubset=true
-
-
@@ -364,7 +358,6 @@
-
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 3da43d2ed21e2..a2cfe2c769fe8 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -1,258 +1,258 @@
-
+
https://github.com/dotnet/icu
- 80a658fa6aa6601d67bfe5a294e0d1b7e1184a5c
+ aae7d341a8ee7841ed0cb1cf298ab17fe04c187b
https://github.com/dotnet/msquic
a7213b4676c1803bb251771291a525482d42e511
-
+
https://github.com/dotnet/emsdk
- aaa56a6622c4991cf65d553250af3c0ade1320bc
+ 4eb953d7051890da4f36167125c6b41e06d7f56d
https://github.com/dotnet/wcf
7f504aabb1988e9a093c1e74d8040bd52feb2f01
-
+
https://github.com/dotnet/llvm-project
- afc9070f64d110ce2bf029a4a624b9dd1c6dbffd
+ e7e0ebc663c70ccb19c331af50d418a06dc92df8
-
+
https://github.com/dotnet/llvm-project
- afc9070f64d110ce2bf029a4a624b9dd1c6dbffd
+ e7e0ebc663c70ccb19c331af50d418a06dc92df8
-
+
https://github.com/dotnet/llvm-project
- afc9070f64d110ce2bf029a4a624b9dd1c6dbffd
+ e7e0ebc663c70ccb19c331af50d418a06dc92df8
-
+
https://github.com/dotnet/llvm-project
- afc9070f64d110ce2bf029a4a624b9dd1c6dbffd
+ e7e0ebc663c70ccb19c331af50d418a06dc92df8
-
+
https://github.com/dotnet/llvm-project
- afc9070f64d110ce2bf029a4a624b9dd1c6dbffd
+ e7e0ebc663c70ccb19c331af50d418a06dc92df8
-
+
https://github.com/dotnet/llvm-project
- afc9070f64d110ce2bf029a4a624b9dd1c6dbffd
+ e7e0ebc663c70ccb19c331af50d418a06dc92df8
-
+
https://github.com/dotnet/llvm-project
- afc9070f64d110ce2bf029a4a624b9dd1c6dbffd
+ e7e0ebc663c70ccb19c331af50d418a06dc92df8
-
+
https://github.com/dotnet/llvm-project
- afc9070f64d110ce2bf029a4a624b9dd1c6dbffd
+ e7e0ebc663c70ccb19c331af50d418a06dc92df8
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
https://github.com/microsoft/vstest
140434f7109d357d0158ade9e5164a4861513965
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/llvm-project
- 44adf6c047663fe20c388bfb769e18dd3c91f7e0
+ 662aff66999c435aec09c58643e9fd703eadc3e0
-
+
https://github.com/dotnet/llvm-project
- 44adf6c047663fe20c388bfb769e18dd3c91f7e0
+ 662aff66999c435aec09c58643e9fd703eadc3e0
-
+
https://github.com/dotnet/llvm-project
- 44adf6c047663fe20c388bfb769e18dd3c91f7e0
+ 662aff66999c435aec09c58643e9fd703eadc3e0
-
+
https://github.com/dotnet/llvm-project
- 44adf6c047663fe20c388bfb769e18dd3c91f7e0
+ 662aff66999c435aec09c58643e9fd703eadc3e0
-
+
https://github.com/dotnet/llvm-project
- 44adf6c047663fe20c388bfb769e18dd3c91f7e0
+ 662aff66999c435aec09c58643e9fd703eadc3e0
-
+
https://github.com/dotnet/llvm-project
- 44adf6c047663fe20c388bfb769e18dd3c91f7e0
+ 662aff66999c435aec09c58643e9fd703eadc3e0
-
+
https://github.com/dotnet/llvm-project
- 44adf6c047663fe20c388bfb769e18dd3c91f7e0
+ 662aff66999c435aec09c58643e9fd703eadc3e0
-
+
https://github.com/dotnet/llvm-project
- 44adf6c047663fe20c388bfb769e18dd3c91f7e0
+ 662aff66999c435aec09c58643e9fd703eadc3e0
-
+
https://github.com/dotnet/runtime
- 09ff1acdad2e7789908b5db9bb89896144c13042
+ a2af6294767b4a3f4c2ce787c5dda2abeeda7a00
-
+
https://github.com/dotnet/runtime
- 09ff1acdad2e7789908b5db9bb89896144c13042
+ a2af6294767b4a3f4c2ce787c5dda2abeeda7a00
-
+
https://github.com/dotnet/runtime
- 09ff1acdad2e7789908b5db9bb89896144c13042
+ a2af6294767b4a3f4c2ce787c5dda2abeeda7a00
-
+
https://github.com/dotnet/runtime
- 09ff1acdad2e7789908b5db9bb89896144c13042
+ a2af6294767b4a3f4c2ce787c5dda2abeeda7a00
-
+
https://github.com/dotnet/runtime
- 09ff1acdad2e7789908b5db9bb89896144c13042
+ a2af6294767b4a3f4c2ce787c5dda2abeeda7a00
-
+
https://github.com/dotnet/runtime
- 09ff1acdad2e7789908b5db9bb89896144c13042
+ a2af6294767b4a3f4c2ce787c5dda2abeeda7a00
-
+
https://github.com/dotnet/runtime
- 09ff1acdad2e7789908b5db9bb89896144c13042
+ a2af6294767b4a3f4c2ce787c5dda2abeeda7a00
-
+
https://github.com/dotnet/runtime
- 09ff1acdad2e7789908b5db9bb89896144c13042
+ a2af6294767b4a3f4c2ce787c5dda2abeeda7a00
-
+
https://github.com/dotnet/linker
- e485816b48273d03bd6266a64dad9bea97f861d5
+ 1a6468ff722c8d362f37638989ec01ab9975ac28
-
+
https://github.com/dotnet/xharness
- 0137095821e2e5a9e030d97248503387b8d72a18
+ d33e67a6c2cc5fe415917c6f9bd17046a929dcc0
-
+
https://github.com/dotnet/xharness
- 0137095821e2e5a9e030d97248503387b8d72a18
+ d33e67a6c2cc5fe415917c6f9bd17046a929dcc0
-
+
https://github.com/dotnet/xharness
- 0137095821e2e5a9e030d97248503387b8d72a18
+ d33e67a6c2cc5fe415917c6f9bd17046a929dcc0
-
+
https://github.com/dotnet/arcade
- 86a931a4ebfa4d65630f0ff6cedf787d2e48a3b9
+ 34bc5b1611e13bd0ee6a9f38ab8524d2ee489be5
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
@@ -270,17 +270,17 @@
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
91d6b3c1f51888d166701510189505f35714665c
-
+
https://github.com/dotnet/hotreload-utils
- d3e96c2e8ed4d58de217c44423c9ba3b90333724
+ 5bc948c6242bc9423c3269d122dcdf0ad6c06a83
-
+
https://github.com/dotnet/runtime-assets
- 8813c6d9e73b5cb0b4ccf4c0b8c609ad344636a7
+ a597df23119faf540d95cebab14b82f084c47384
-
+
https://github.com/dotnet/roslyn-analyzers
- f471d3381584f10f9908432e0b2b2b8ef07a0aa6
+ e101c379c6e3c7011562ee3af3e3de066da0048f
https://github.com/dotnet/sdk
diff --git a/eng/Versions.props b/eng/Versions.props
index aae2d08e09018..8bc9373cc09ac 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -7,8 +7,8 @@
0
0
7.0.100
- preview
- 2
+ alpha
+ 1
$(MajorVersion).$(MinorVersion).0.0
@@ -50,42 +50,42 @@
3.3.2
4.0.1
4.0.1
- 7.0.0-preview1.22068.2
+ 7.0.0-preview1.21613.1
2.0.0-alpha.1.21525.11
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 2.5.1-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
- 7.0.0-beta.22075.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 2.5.1-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
+ 7.0.0-beta.22056.6
6.0.0-preview.1.102
- 7.0.0-alpha.1.22073.5
- 7.0.0-alpha.1.22073.5
- 7.0.0-alpha.1.22073.5
+ 7.0.0-alpha.1.22059.2
+ 7.0.0-alpha.1.22059.2
+ 7.0.0-alpha.1.22059.2
3.1.0
- 7.0.0-alpha.1.22073.5
- 1.0.0-alpha.1.22073.1
- 1.0.0-alpha.1.22073.1
- 1.0.0-alpha.1.22073.1
- 1.0.0-alpha.1.22073.1
- 1.0.0-alpha.1.22073.1
- 1.0.0-alpha.1.22073.1
- 1.0.0-alpha.1.22073.1
- 1.0.0-alpha.1.22073.1
+ 7.0.0-alpha.1.22059.2
+ 1.0.0-alpha.1.22060.1
+ 1.0.0-alpha.1.22060.1
+ 1.0.0-alpha.1.22060.1
+ 1.0.0-alpha.1.22060.1
+ 1.0.0-alpha.1.22060.1
+ 1.0.0-alpha.1.22060.1
+ 1.0.0-alpha.1.22060.1
+ 1.0.0-alpha.1.22060.1
5.0.0
4.3.0
@@ -114,30 +114,30 @@
4.3.0
4.3.0
4.3.0
- 6.0.0
+ 6.0.0-rc.2.21454.1
4.3.1
5.0.0
5.0.0
5.0.0
4.9.0-rc2.21473.1
- 7.0.0-alpha.1.22073.5
- 7.0.0-alpha.1.22073.5
+ 7.0.0-alpha.1.22059.2
+ 7.0.0-alpha.1.22059.2
4.5.4
4.5.0
- 7.0.0-alpha.1.22073.5
+ 7.0.0-alpha.1.22059.2
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
- 7.0.0-beta.22075.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
+ 7.0.0-beta.22060.1
1.0.0-prerelease.21577.2
1.0.0-prerelease.21577.2
@@ -160,12 +160,11 @@
1.0.1-prerelease-00006
16.9.0-preview-20201201-01
- 1.0.0-prerelease.22074.1
- 1.0.0-prerelease.22074.1
- 1.0.0-prerelease.22074.1
- 1.0.2-alpha.0.22074.1
- 2.4.2-pre.22
- 0.12.0-pre.20
+ 1.0.0-prerelease.22062.1
+ 1.0.0-prerelease.22062.1
+ 1.0.0-prerelease.22062.1
+ 1.0.2-alpha.0.22060.2
+ 2.4.2-pre.9
2.4.2
3.1.0
12.0.3
@@ -175,25 +174,25 @@
7.0.100-alpha.1.21528.1
1.1.1-beta1.21467.5
- 6.0.0-preview-20220104.1
+ 6.0.0-preview-20211019.1
- 7.0.100-1.22063.2
+ 7.0.100-1.22053.1
$(MicrosoftNETILLinkTasksVersion)
- 7.0.0-preview.2.22074.5
+ 7.0.0-alpha.1.22060.1
7.0.0-alpha.1.21529.3
- 11.1.0-alpha.1.22074.2
- 11.1.0-alpha.1.22074.2
- 11.1.0-alpha.1.22074.2
- 11.1.0-alpha.1.22074.2
- 11.1.0-alpha.1.22074.2
- 11.1.0-alpha.1.22074.2
- 11.1.0-alpha.1.22074.2
- 11.1.0-alpha.1.22074.2
+ 11.1.0-alpha.1.21615.1
+ 11.1.0-alpha.1.21615.1
+ 11.1.0-alpha.1.21615.1
+ 11.1.0-alpha.1.21615.1
+ 11.1.0-alpha.1.21615.1
+ 11.1.0-alpha.1.21615.1
+ 11.1.0-alpha.1.21615.1
+ 11.1.0-alpha.1.21615.1
- 7.0.0-alpha.2.22071.3
+ 7.0.0-alpha.1.21601.1
$(MicrosoftNETWorkloadEmscriptenManifest70100Version)
1.1.87-gba258badda
diff --git a/eng/build.sh b/eng/build.sh
index 167f8e2014182..ea8e3089e95f4 100755
--- a/eng/build.sh
+++ b/eng/build.sh
@@ -17,7 +17,7 @@ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
usage()
{
echo "Common settings:"
- echo " --arch (-a) Target platform: x86, x64, arm, armv6, armel, arm64, loongarch64, s390x or wasm."
+ echo " --arch (-a) Target platform: x86, x64, arm, armel, arm64, loongarch64, s390x or wasm."
echo " [Default: Your machine's architecture.]"
echo " --binaryLog (-bl) Output binary log."
echo " --cross Optional argument to signify cross compilation."
@@ -206,12 +206,12 @@ while [[ $# > 0 ]]; do
fi
passedArch="$(echo "$2" | tr "[:upper:]" "[:lower:]")"
case "$passedArch" in
- x64|x86|arm|armv6|armel|arm64|loongarch64|s390x|wasm)
+ x64|x86|arm|armel|arm64|loongarch64|s390x|wasm)
arch=$passedArch
;;
*)
echo "Unsupported target architecture '$2'."
- echo "The allowed values are x86, x64, arm, armv6, armel, arm64, loongarch64, s390x, and wasm."
+ echo "The allowed values are x86, x64, arm, armel, arm64, loongarch64, s390x, and wasm."
exit 1
;;
esac
diff --git a/eng/common/cross/arm/tizen-build-rootfs.sh b/eng/common/cross/arm/tizen-build-rootfs.sh
old mode 100755
new mode 100644
diff --git a/eng/common/cross/arm/tizen-fetch.sh b/eng/common/cross/arm/tizen-fetch.sh
old mode 100755
new mode 100644
diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh
index f97dca7705408..e94d13d62ef64 100755
--- a/eng/common/cross/build-rootfs.sh
+++ b/eng/common/cross/build-rootfs.sh
@@ -7,7 +7,7 @@ usage()
echo "Usage: $0 [BuildArch] [CodeName] [lldbx.y] [--skipunmount] --rootfsdir ]"
echo "BuildArch can be: arm(default), armel, arm64, x86"
echo "CodeName - optional, Code name for Linux, can be: xenial(default), zesty, bionic, alpine, alpine3.13 or alpine3.14. If BuildArch is armel, LinuxCodeName is jessie(default) or tizen."
- echo " for FreeBSD can be: freebsd12, freebsd13"
+ echo " for FreeBSD can be: freebsd11, freebsd12, freebsd13"
echo " for illumos can be: illumos."
echo "lldbx.y - optional, LLDB version, can be: lldb3.9(default), lldb4.0, lldb5.0, lldb6.0 no-lldb. Ignored for alpine and FreeBSD"
echo "--skipunmount - optional, will skip the unmount of rootfs folder."
@@ -60,13 +60,13 @@ __AlpinePackages+=" krb5-dev"
__AlpinePackages+=" openssl-dev"
__AlpinePackages+=" zlib-dev"
-__FreeBSDBase="12.3-RELEASE"
-__FreeBSDPkg="1.17.0"
+__FreeBSDBase="12.2-RELEASE"
+__FreeBSDPkg="1.12.0"
__FreeBSDABI="12"
__FreeBSDPackages="libunwind"
__FreeBSDPackages+=" icu"
__FreeBSDPackages+=" libinotify"
-__FreeBSDPackages+=" openssl"
+__FreeBSDPackages+=" lttng-ust"
__FreeBSDPackages+=" krb5"
__FreeBSDPackages+=" terminfo-db"
@@ -206,6 +206,10 @@ while :; do
__AlpineVersion=3.14
__AlpinePackages+=" llvm11-libs"
;;
+ freebsd11)
+ __FreeBSDBase="11.3-RELEASE"
+ __FreeBSDABI="11"
+ ;&
freebsd12)
__CodeName=freebsd
__BuildArch=x64
diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake
index fba2afda438b6..f7878dddd3921 100644
--- a/eng/common/cross/toolchain.cmake
+++ b/eng/common/cross/toolchain.cmake
@@ -37,13 +37,6 @@ elseif(TARGET_ARCH_NAME STREQUAL "arm")
if(TIZEN)
set(TIZEN_TOOLCHAIN "armv7hl-tizen-linux-gnueabihf/9.2.0")
endif()
-elseif(TARGET_ARCH_NAME STREQUAL "armv6")
- set(CMAKE_SYSTEM_PROCESSOR armv6l)
- if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf)
- set(TOOLCHAIN "armv6-alpine-linux-musleabihf")
- else()
- set(TOOLCHAIN "arm-linux-gnueabihf")
- endif()
elseif(TARGET_ARCH_NAME STREQUAL "arm64")
set(CMAKE_SYSTEM_PROCESSOR aarch64)
if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/aarch64-alpine-linux-musl)
@@ -67,7 +60,7 @@ elseif (ILLUMOS)
set(CMAKE_SYSTEM_PROCESSOR "x86_64")
set(TOOLCHAIN "x86_64-illumos")
else()
- message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, armv6, arm64, s390x and x86 are supported!")
+ message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, arm64, s390x and x86 are supported!")
endif()
if(DEFINED ENV{TOOLCHAIN})
@@ -201,7 +194,7 @@ endif()
# Specify compile options
-if((TARGET_ARCH_NAME MATCHES "^(arm|armv6|armel|arm64|s390x)$" AND NOT ANDROID) OR ILLUMOS)
+if((TARGET_ARCH_NAME MATCHES "^(arm|armel|arm64|s390x)$" AND NOT ANDROID) OR ILLUMOS)
set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN})
set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN})
set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN})
diff --git a/eng/common/internal/NuGet.config b/eng/common/internal/NuGet.config
deleted file mode 100644
index 769650362f4aa..0000000000000
--- a/eng/common/internal/NuGet.config
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1
index 8508397d77640..2427ca6b6aec7 100644
--- a/eng/common/post-build/publish-using-darc.ps1
+++ b/eng/common/post-build/publish-using-darc.ps1
@@ -5,8 +5,13 @@ param(
[Parameter(Mandatory=$true)][string] $MaestroToken,
[Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro-prod.westus2.cloudapp.azure.com',
[Parameter(Mandatory=$true)][string] $WaitPublishingFinish,
+ [Parameter(Mandatory=$false)][string] $EnableSourceLinkValidation,
+ [Parameter(Mandatory=$false)][string] $EnableSigningValidation,
+ [Parameter(Mandatory=$false)][string] $EnableNugetValidation,
+ [Parameter(Mandatory=$false)][string] $PublishInstallersAndChecksums,
[Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters,
- [Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters
+ [Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters,
+ [Parameter(Mandatory=$false)][string] $SigningValidationAdditionalParameters
)
try {
@@ -30,6 +35,27 @@ try {
$optionalParams.Add("--no-wait") | Out-Null
}
+ if ("false" -ne $PublishInstallersAndChecksums) {
+ $optionalParams.Add("--publish-installers-and-checksums") | Out-Null
+ }
+
+ if ("true" -eq $EnableNugetValidation) {
+ $optionalParams.Add("--validate-nuget") | Out-Null
+ }
+
+ if ("true" -eq $EnableSourceLinkValidation) {
+ $optionalParams.Add("--validate-sourcelinkchecksums") | Out-Null
+ }
+
+ if ("true" -eq $EnableSigningValidation) {
+ $optionalParams.Add("--validate-signingchecksums") | Out-Null
+
+ if ("" -ne $SigningValidationAdditionalParameters) {
+ $optionalParams.Add("--signing-validation-parameters") | Out-Null
+ $optionalParams.Add($SigningValidationAdditionalParameters) | Out-Null
+ }
+ }
+
& $darc add-build-to-channel `
--id $buildId `
--publishing-infra-version $PublishingInfraVersion `
diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml
index 24cec0424e5d6..8cf772b3cbf81 100644
--- a/eng/common/templates/job/execute-sdl.yml
+++ b/eng/common/templates/job/execute-sdl.yml
@@ -29,6 +29,14 @@ parameters:
# Optional: download a list of pipeline artifacts. 'downloadArtifacts' controls build artifacts,
# not pipeline artifacts, so doesn't affect the use of this parameter.
pipelineArtifactNames: []
+ # Optional: location and ID of the AzDO build that the build/pipeline artifacts should be
+ # downloaded from. By default, uses runtime expressions to decide based on the variables set by
+ # the 'setupMaestroVars' dependency. Overriding this parameter is necessary if SDL tasks are
+ # running without Maestro++/BAR involved, or to download artifacts from a specific existing build
+ # to iterate quickly on SDL changes.
+ AzDOProjectName: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ]
+ AzDOPipelineId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ]
+ AzDOBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ]
jobs:
- job: Run_SDL
@@ -47,20 +55,11 @@ jobs:
- name: GuardianVersion
value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}
pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: NetCore1ESPool-Internal
- demands: ImageOverride -equals Build.Server.Amd64.VS2019
+ vmImage: windows-2019
steps:
- checkout: self
clean: true
- - template: /eng/common/templates/post-build/setup-maestro-vars.yml
-
- ${{ if ne(parameters.downloadArtifacts, 'false')}}:
- ${{ if ne(parameters.artifactNames, '') }}:
- ${{ each artifactName in parameters.artifactNames }}:
diff --git a/eng/common/templates/job/onelocbuild.yml b/eng/common/templates/job/onelocbuild.yml
index 9d1e3042d8a6c..c4fc18b3ee77a 100644
--- a/eng/common/templates/job/onelocbuild.yml
+++ b/eng/common/templates/job/onelocbuild.yml
@@ -3,8 +3,9 @@ parameters:
dependsOn: ''
# Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
- pool: ''
-
+ pool:
+ vmImage: 'windows-2019'
+
CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex
GithubPat: $(BotAccount-dotnet-bot-repo-PAT)
@@ -30,18 +31,7 @@ jobs:
displayName: OneLocBuild
- ${{ if ne(parameters.pool, '') }}:
- pool: ${{ parameters.pool }}
- ${{ if eq(parameters.pool, '') }}:
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: NetCore1ESPool-Internal
- demands: ImageOverride -equals Build.Server.Amd64.VS2019
+ pool: ${{ parameters.pool }}
variables:
- group: OneLocBuildVariables # Contains the CeapexPat and GithubPat
diff --git a/eng/common/templates/jobs/jobs.yml b/eng/common/templates/jobs/jobs.yml
index 554e71cfc436d..ff4ab75c886dc 100644
--- a/eng/common/templates/jobs/jobs.yml
+++ b/eng/common/templates/jobs/jobs.yml
@@ -83,15 +83,7 @@ jobs:
- ${{ if eq(parameters.enableSourceBuild, true) }}:
- Source_Build_Complete
pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: NetCore1ESPool-Internal
- demands: ImageOverride -equals Build.Server.Amd64.VS2019
-
+ vmImage: 'windows-2019'
runAsPublic: ${{ parameters.runAsPublic }}
publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }}
enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }}
diff --git a/eng/common/templates/post-build/channels/generic-internal-channel.yml b/eng/common/templates/post-build/channels/generic-internal-channel.yml
new file mode 100644
index 0000000000000..8990dfc8c87cc
--- /dev/null
+++ b/eng/common/templates/post-build/channels/generic-internal-channel.yml
@@ -0,0 +1,190 @@
+parameters:
+ BARBuildId: ''
+ PromoteToChannelIds: ''
+ artifactsPublishingAdditionalParameters: ''
+ dependsOn:
+ - Validate
+ publishInstallersAndChecksums: true
+ symbolPublishingAdditionalParameters: ''
+ stageName: ''
+ channelName: ''
+ channelId: ''
+ transportFeed: ''
+ shippingFeed: ''
+ symbolsFeed: ''
+
+stages:
+- stage: ${{ parameters.stageName }}
+ dependsOn: ${{ parameters.dependsOn }}
+ variables:
+ - template: ../common-variables.yml
+ displayName: ${{ parameters.channelName }} Publishing
+ jobs:
+ - template: ../setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+
+ - job: publish_symbols
+ displayName: Symbol Publishing
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.TargetChannels'], format('[{0}]', ${{ parameters.channelId }} ))
+ variables:
+ - group: DotNet-Symbol-Server-Pats
+ - name: AzDOProjectName
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ]
+ - name: AzDOPipelineId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ]
+ - name: AzDOBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ]
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - script: echo "##vso[task.logissue type=warning]Going forward, v2 Arcade publishing is no longer supported. Please read https://github.com/dotnet/arcade/blob/main/Documentation/CorePackages/Publishing.md for details, then contact dnceng if you have further questions."
+ displayName: Warn about v2 Arcade Publishing Usage
+
+ # This is necessary whenever we want to publish/restore to an AzDO private feed
+ - task: NuGetAuthenticate@0
+ displayName: 'Authenticate to AzDO Feeds'
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Build Assets
+ continueOnError: true
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ downloadType: 'specific'
+ itemPattern: |
+ PdbArtifacts/**
+ BlobArtifacts/**
+ downloadPath: '$(Build.ArtifactStagingDirectory)'
+ checkDownloadedFiles: true
+
+ # 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
+ displayName: 'Authenticate to AzDO Feeds'
+
+ - task: PowerShell@2
+ displayName: Enable cross-org publishing
+ inputs:
+ filePath: eng\common\enable-cross-org-publishing.ps1
+ arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
+
+ - task: PowerShell@2
+ displayName: Publish
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishToSymbolServers -restore -msbuildEngine dotnet
+ /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+ /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
+ /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
+ /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
+ /p:Configuration=Release
+ /p:PublishToMSDL=false
+ ${{ parameters.symbolPublishingAdditionalParameters }}
+
+ - template: ../../steps/publish-logs.yml
+ parameters:
+ StageLabel: '${{ parameters.stageName }}'
+ JobLabel: 'SymbolPublishing'
+
+ - job: publish_assets
+ displayName: Publish Assets
+ dependsOn: setupMaestroVars
+ timeoutInMinutes: 120
+ variables:
+ - name: BARBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
+ - name: IsStableBuild
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
+ - name: AzDOProjectName
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ]
+ - name: AzDOPipelineId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ]
+ - name: AzDOBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ]
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.TargetChannels'], format('[{0}]', ${{ parameters.channelId }} ))
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - script: echo "##vso[task.logissue type=warning]Going forward, v2 Arcade publishing is no longer supported. Please read https://github.com/dotnet/arcade/blob/main/Documentation/CorePackages/Publishing.md for details, then contact dnceng if you have further questions."
+ displayName: Warn about v2 Arcade Publishing Usage
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Build Assets
+ continueOnError: true
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ downloadType: 'specific'
+ itemPattern: |
+ PackageArtifacts/**
+ BlobArtifacts/**
+ AssetManifests/**
+ downloadPath: '$(Build.ArtifactStagingDirectory)'
+ checkDownloadedFiles: true
+
+ - task: NuGetToolInstaller@1
+ displayName: 'Install NuGet.exe'
+
+ # This is necessary whenever we want to publish/restore to an AzDO private feed
+ - task: NuGetAuthenticate@0
+ displayName: 'Authenticate to AzDO Feeds'
+
+ - task: PowerShell@2
+ displayName: Enable cross-org publishing
+ inputs:
+ filePath: eng\common\enable-cross-org-publishing.ps1
+ arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
+
+ - task: PowerShell@2
+ displayName: Publish Assets
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+ /p:PublishingInfraVersion=2
+ /p:IsStableBuild=$(IsStableBuild)
+ /p:IsInternalBuild=$(IsInternalBuild)
+ /p:RepositoryName=$(Build.Repository.Name)
+ /p:CommitSha=$(Build.SourceVersion)
+ /p:NugetPath=$(NuGetExeToolPath)
+ /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-packages-rw)'
+ /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
+ /p:BARBuildId=$(BARBuildId)
+ /p:MaestroApiEndpoint='$(MaestroApiEndPoint)'
+ /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)'
+ /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
+ /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/'
+ /p:Configuration=Release
+ /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
+ /p:ChecksumsTargetStaticFeed=$(InternalChecksumsBlobFeedUrl)
+ /p:ChecksumsAzureAccountKey=$(InternalChecksumsBlobFeedKey)
+ /p:InstallersTargetStaticFeed=$(InternalInstallersBlobFeedUrl)
+ /p:InstallersAzureAccountKey=$(InternalInstallersBlobFeedKey)
+ /p:AzureDevOpsStaticShippingFeed='${{ parameters.shippingFeed }}'
+ /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+ /p:AzureDevOpsStaticTransportFeed='${{ parameters.transportFeed }}'
+ /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+ /p:AzureDevOpsStaticSymbolsFeed='${{ parameters.symbolsFeed }}'
+ /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+ /p:PublishToMSDL=false
+ ${{ parameters.artifactsPublishingAdditionalParameters }}
+
+ - template: ../../steps/publish-logs.yml
+ parameters:
+ StageLabel: '${{ parameters.stageName }}'
+ JobLabel: 'AssetsPublishing'
+
+ - template: ../../steps/add-build-to-channel.yml
+ parameters:
+ ChannelId: ${{ parameters.channelId }}
diff --git a/eng/common/templates/post-build/channels/generic-public-channel.yml b/eng/common/templates/post-build/channels/generic-public-channel.yml
new file mode 100644
index 0000000000000..3220c6a4f92ff
--- /dev/null
+++ b/eng/common/templates/post-build/channels/generic-public-channel.yml
@@ -0,0 +1,192 @@
+parameters:
+ BARBuildId: ''
+ PromoteToChannelIds: ''
+ artifactsPublishingAdditionalParameters: ''
+ dependsOn:
+ - Validate
+ publishInstallersAndChecksums: true
+ symbolPublishingAdditionalParameters: ''
+ stageName: ''
+ channelName: ''
+ channelId: ''
+ transportFeed: ''
+ shippingFeed: ''
+ symbolsFeed: ''
+ # If the channel name is empty, no links will be generated
+ akaMSChannelName: ''
+
+stages:
+- stage: ${{ parameters.stageName }}
+ dependsOn: ${{ parameters.dependsOn }}
+ variables:
+ - template: ../common-variables.yml
+ displayName: ${{ parameters.channelName }} Publishing
+ jobs:
+ - template: ../setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+
+ - job: publish_symbols
+ displayName: Symbol Publishing
+ dependsOn: setupMaestroVars
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.TargetChannels'], format('[{0}]', ${{ parameters.channelId }} ))
+ variables:
+ - group: DotNet-Symbol-Server-Pats
+ - name: AzDOProjectName
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ]
+ - name: AzDOPipelineId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ]
+ - name: AzDOBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ]
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - script: echo "##vso[task.logissue type=warning]Going forward, v2 Arcade publishing is no longer supported. Please read https://github.com/dotnet/arcade/blob/main/Documentation/CorePackages/Publishing.md for details, then contact dnceng if you have further questions."
+ displayName: Warn about v2 Arcade Publishing Usage
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Build Assets
+ continueOnError: true
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ downloadType: 'specific'
+ itemPattern: |
+ PdbArtifacts/**
+ BlobArtifacts/**
+ downloadPath: '$(Build.ArtifactStagingDirectory)'
+ checkDownloadedFiles: true
+
+ # 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
+ displayName: 'Authenticate to AzDO Feeds'
+
+ - task: PowerShell@2
+ displayName: Enable cross-org publishing
+ inputs:
+ filePath: eng\common\enable-cross-org-publishing.ps1
+ arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
+
+ - task: PowerShell@2
+ displayName: Publish
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishToSymbolServers -restore -msbuildEngine dotnet
+ /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
+ /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
+ /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
+ /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
+ /p:Configuration=Release
+ ${{ parameters.symbolPublishingAdditionalParameters }}
+
+ - template: ../../steps/publish-logs.yml
+ parameters:
+ StageLabel: '${{ parameters.stageName }}'
+ JobLabel: 'SymbolPublishing'
+
+ - job: publish_assets
+ displayName: Publish Assets
+ dependsOn: setupMaestroVars
+ timeoutInMinutes: 120
+ variables:
+ - name: BARBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
+ - name: IsStableBuild
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
+ - name: AzDOProjectName
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ]
+ - name: AzDOPipelineId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ]
+ - name: AzDOBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ]
+ - name: ArtifactsCategory
+ value: ${{ coalesce(variables._DotNetArtifactsCategory, '.NETCore') }}
+ condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.TargetChannels'], format('[{0}]', ${{ parameters.channelId }} ))
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - script: echo "##vso[task.logissue type=warning]Going forward, v2 Arcade publishing is no longer supported. Please read https://github.com/dotnet/arcade/blob/main/Documentation/CorePackages/Publishing.md for details, then contact dnceng if you have further questions."
+ displayName: Warn about v2 Arcade Publishing Usage
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Build Assets
+ continueOnError: true
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ downloadType: 'specific'
+ itemPattern: |
+ PackageArtifacts/**
+ BlobArtifacts/**
+ AssetManifests/**
+ downloadPath: '$(Build.ArtifactStagingDirectory)'
+ checkDownloadedFiles: true
+
+ - task: NuGetToolInstaller@1
+ displayName: 'Install NuGet.exe'
+
+ # This is necessary whenever we want to publish/restore to an AzDO private feed
+ - task: NuGetAuthenticate@0
+ displayName: 'Authenticate to AzDO Feeds'
+
+ - task: PowerShell@2
+ displayName: Enable cross-org publishing
+ inputs:
+ filePath: eng\common\enable-cross-org-publishing.ps1
+ arguments: -token $(dn-bot-dnceng-artifact-feeds-rw)
+
+ - task: PowerShell@2
+ displayName: Publish Assets
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+ /p:PublishingInfraVersion=2
+ /p:ArtifactsCategory=$(ArtifactsCategory)
+ /p:IsStableBuild=$(IsStableBuild)
+ /p:IsInternalBuild=$(IsInternalBuild)
+ /p:RepositoryName=$(Build.Repository.Name)
+ /p:CommitSha=$(Build.SourceVersion)
+ /p:NugetPath=$(NuGetExeToolPath)
+ /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-universal-packages-rw)'
+ /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
+ /p:BARBuildId=$(BARBuildId)
+ /p:MaestroApiEndpoint='$(MaestroApiEndPoint)'
+ /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)'
+ /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
+ /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
+ /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/'
+ /p:Configuration=Release
+ /p:PublishInstallersAndChecksums=${{ parameters.publishInstallersAndChecksums }}
+ /p:InstallersTargetStaticFeed=$(InstallersBlobFeedUrl)
+ /p:InstallersAzureAccountKey=$(dotnetcli-storage-key)
+ /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl)
+ /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key)
+ /p:AzureDevOpsStaticShippingFeed='${{ parameters.shippingFeed }}'
+ /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+ /p:AzureDevOpsStaticTransportFeed='${{ parameters.transportFeed }}'
+ /p:AzureDevOpsStaticTransportFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+ /p:AzureDevOpsStaticSymbolsFeed='${{ parameters.symbolsFeed }}'
+ /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)'
+ /p:LatestLinkShortUrlPrefix=dotnet/'${{ parameters.akaMSChannelName }}'
+ /p:AkaMSClientId=$(akams-client-id)
+ /p:AkaMSClientSecret=$(akams-client-secret)
+ ${{ parameters.artifactsPublishingAdditionalParameters }}
+
+ - template: ../../steps/publish-logs.yml
+ parameters:
+ StageLabel: '${{ parameters.stageName }}'
+ JobLabel: 'AssetsPublishing'
+
+ - template: ../../steps/add-build-to-channel.yml
+ parameters:
+ ChannelId: ${{ parameters.channelId }}
diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml
index c830e6f277606..c99fd7503767c 100644
--- a/eng/common/templates/post-build/common-variables.yml
+++ b/eng/common/templates/post-build/common-variables.yml
@@ -4,6 +4,54 @@ variables:
- group: DotNet-DotNetCli-Storage
- group: DotNet-MSRC-Storage
- group: Publish-Build-Assets
+
+ # .NET Core 3.1 Dev
+ - name: PublicDevRelease_31_Channel_Id
+ value: 128
+
+ # .NET 5 Dev
+ - name: Net_5_Dev_Channel_Id
+ value: 131
+
+ # .NET Eng - Validation
+ - name: Net_Eng_Validation_Channel_Id
+ value: 9
+
+ # .NET Eng - Latest
+ - name: Net_Eng_Latest_Channel_Id
+ value: 2
+
+ # .NET 3 Eng - Validation
+ - name: NET_3_Eng_Validation_Channel_Id
+ value: 390
+
+ # .NET 3 Eng
+ - name: NetCore_3_Tools_Channel_Id
+ value: 344
+
+ # .NET Core 3.0 Internal Servicing
+ - name: InternalServicing_30_Channel_Id
+ value: 184
+
+ # .NET Core 3.0 Release
+ - name: PublicRelease_30_Channel_Id
+ value: 19
+
+ # .NET Core 3.1 Release
+ - name: PublicRelease_31_Channel_Id
+ value: 129
+
+ # General Testing
+ - name: GeneralTesting_Channel_Id
+ value: 529
+
+ # .NET Core 3.1 Blazor Features
+ - name: NetCore_31_Blazor_Features_Channel_Id
+ value: 531
+
+ # .NET Core Experimental
+ - name: NetCore_Experimental_Channel_Id
+ value: 562
# Whether the build is internal or not
- name: IsInternalBuild
@@ -22,6 +70,27 @@ variables:
- name: SymbolToolVersion
value: 1.0.1
+ # Feed Configurations
+ # These should include the suffix "/index.json"
+
+ # Default locations for Installers and checksums
+ # Public Locations
+ - name: ChecksumsBlobFeedUrl
+ value: https://dotnetclichecksums.blob.core.windows.net/dotnet/index.json
+ - name: InstallersBlobFeedUrl
+ value: https://dotnetcli.blob.core.windows.net/dotnet/index.json
+
+ # Private Locations
+ - name: InternalChecksumsBlobFeedUrl
+ value: https://dotnetclichecksumsmsrc.blob.core.windows.net/dotnet/index.json
+ - name: InternalChecksumsBlobFeedKey
+ value: $(dotnetclichecksumsmsrc-storage-key)
+
+ - name: InternalInstallersBlobFeedUrl
+ value: https://dotnetclimsrc.blob.core.windows.net/dotnet/index.json
+ - name: InternalInstallersBlobFeedKey
+ value: $(dotnetclimsrc-access-key)
+
# Skip component governance and codesign validation for SDL. These jobs
# create no content.
- name: skipComponentGovernanceDetection
diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml
index 2f176571f020c..4f79cf0f33703 100644
--- a/eng/common/templates/post-build/post-build.yml
+++ b/eng/common/templates/post-build/post-build.yml
@@ -1,114 +1,113 @@
parameters:
- # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST.
- # Publishing V1 is no longer supported
- # Publishing V2 is no longer supported
- # Publishing V3 is the default
- - name: publishingInfraVersion
- displayName: Which version of publishing should be used to promote the build definition?
- type: number
- default: 3
- values:
- - 3
-
- - name: BARBuildId
- displayName: BAR Build Id
- type: number
- default: 0
-
- - name: PromoteToChannelIds
- displayName: Channel to promote BARBuildId to
- type: string
- default: ''
-
- - name: enableSourceLinkValidation
- displayName: Enable SourceLink validation
- type: boolean
- default: false
-
- - name: enableSigningValidation
- displayName: Enable signing validation
- type: boolean
- default: true
-
- - name: enableSymbolValidation
- displayName: Enable symbol validation
- type: boolean
- default: false
-
- - name: enableNugetValidation
- displayName: Enable NuGet validation
- type: boolean
- default: true
-
- - name: publishInstallersAndChecksums
- displayName: Publish installers and checksums
- type: boolean
- default: true
-
- - name: SDLValidationParameters
- type: object
- default:
- enable: false
- continueOnError: false
- params: ''
- artifactNames: ''
- downloadArtifacts: true
+ # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST.
+ # Publishing V2 accepts optionally outlining the publishing stages - default is inline.
+ # Publishing V3 DOES NOT accept inlining the publishing stages.
+ publishingInfraVersion: 2
+ # When set to true the publishing templates from the repo will be used
+ # otherwise Darc add-build-to-channel will be used to trigger the promotion pipeline
+ inline: true
- # These parameters let the user customize the call to sdk-task.ps1 for publishing
- # symbols & general artifacts as well as for signing validation
- - name: symbolPublishingAdditionalParameters
- displayName: Symbol publishing additional parameters
- type: string
- default: ''
+ # Only used if inline==false. When set to true will stall the current build until
+ # the Promotion Pipeline build finishes. Otherwise, the current build will continue
+ # execution concurrently with the promotion build.
+ waitPublishingFinish: true
+
+ BARBuildId: ''
+ PromoteToChannelIds: ''
- - name: artifactsPublishingAdditionalParameters
- displayName: Artifact publishing additional parameters
- type: string
- default: ''
+ enableSourceLinkValidation: false
+ enableSigningValidation: true
+ enableSymbolValidation: false
+ enableNugetValidation: true
+ publishInstallersAndChecksums: true
+ SDLValidationParameters:
+ enable: false
+ continueOnError: false
+ params: ''
+ artifactNames: ''
+ downloadArtifacts: true
- - name: signingValidationAdditionalParameters
- displayName: Signing validation additional parameters
- type: string
- default: ''
+ # These parameters let the user customize the call to sdk-task.ps1 for publishing
+ # symbols & general artifacts as well as for signing validation
+ symbolPublishingAdditionalParameters: ''
+ artifactsPublishingAdditionalParameters: ''
+ signingValidationAdditionalParameters: ''
# Which stages should finish execution before post-build stages start
- - name: validateDependsOn
- type: object
- default:
- - build
+ validateDependsOn:
+ - build
+ publishDependsOn:
+ - Validate
- - name: publishDependsOn
- type: object
- default:
- - Validate
+ # Channel ID's instantiated in this file.
+ # When adding a new channel implementation the call to `check-channel-consistency.ps1`
+ # needs to be updated with the new channel ID
+ NetEngLatestChannelId: 2
+ NetEngValidationChannelId: 9
+ NetDev5ChannelId: 131
+ NetDev6ChannelId: 1296
+ GeneralTestingChannelId: 529
+ NETCoreToolingDevChannelId: 548
+ NETCoreToolingReleaseChannelId: 549
+ NETInternalToolingChannelId: 551
+ NETCoreExperimentalChannelId: 562
+ NetEngServicesIntChannelId: 678
+ NetEngServicesProdChannelId: 679
+ NetCoreSDK313xxChannelId: 759
+ NetCoreSDK313xxInternalChannelId: 760
+ NetCoreSDK314xxChannelId: 921
+ NetCoreSDK314xxInternalChannelId: 922
+ VS166ChannelId: 1010
+ VS167ChannelId: 1011
+ VS168ChannelId: 1154
+ VSMasterChannelId: 1012
+ VS169ChannelId: 1473
+ VS1610ChannelId: 1692
stages:
-- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
+- ${{ if or(and(le(parameters.publishingInfraVersion, 2), eq(parameters.inline, 'true')), eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
- stage: Validate
dependsOn: ${{ parameters.validateDependsOn }}
displayName: Validate Build Assets
variables:
- template: common-variables.yml
jobs:
+ - template: setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+
+ - ${{ if and(le(parameters.publishingInfraVersion, 2), eq(parameters.inline, 'true')) }}:
+ - job:
+ displayName: Post-build Checks
+ dependsOn: setupMaestroVars
+ variables:
+ - name: TargetChannels
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.TargetChannels'] ]
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: PowerShell@2
+ displayName: Maestro Channels Consistency
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/check-channel-consistency.ps1
+ arguments: -PromoteToChannels "$(TargetChannels)"
+ -AvailableChannelIds ${{parameters.NetEngLatestChannelId}},${{parameters.NetEngValidationChannelId}},${{parameters.NetDev5ChannelId}},${{parameters.NetDev6ChannelId}},${{parameters.GeneralTestingChannelId}},${{parameters.NETCoreToolingDevChannelId}},${{parameters.NETCoreToolingReleaseChannelId}},${{parameters.NETInternalToolingChannelId}},${{parameters.NETCoreExperimentalChannelId}},${{parameters.NetEngServicesIntChannelId}},${{parameters.NetEngServicesProdChannelId}},${{parameters.NetCoreSDK313xxChannelId}},${{parameters.NetCoreSDK313xxInternalChannelId}},${{parameters.NetCoreSDK314xxChannelId}},${{parameters.NetCoreSDK314xxInternalChannelId}},${{parameters.VS166ChannelId}},${{parameters.VS167ChannelId}},${{parameters.VS168ChannelId}},${{parameters.VSMasterChannelId}},${{parameters.VS169ChannelId}},${{parameters.VS1610ChannelId}}
+
- job:
displayName: NuGet Validation
+ dependsOn: setupMaestroVars
condition: eq( ${{ parameters.enableNugetValidation }}, 'true')
pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: NetCore1ESPool-Internal
- demands: ImageOverride -equals Build.Server.Amd64.VS2019
-
+ vmImage: 'windows-2019'
+ variables:
+ - name: AzDOProjectName
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ]
+ - name: AzDOPipelineId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ]
+ - name: AzDOBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ]
steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- task: DownloadBuildArtifacts@0
displayName: Download Package Artifacts
inputs:
@@ -129,22 +128,19 @@ stages:
- job:
displayName: Signing Validation
+ dependsOn: setupMaestroVars
condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true'))
+ variables:
+ - template: common-variables.yml
+ - name: AzDOProjectName
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ]
+ - name: AzDOPipelineId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ]
+ - name: AzDOBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ]
pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: NetCore1ESPool-Internal
- demands: ImageOverride -equals Build.Server.Amd64.VS2019
+ vmImage: 'windows-2019'
steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- task: DownloadBuildArtifacts@0
displayName: Download Package Artifacts
inputs:
@@ -189,22 +185,19 @@ stages:
- job:
displayName: SourceLink Validation
+ dependsOn: setupMaestroVars
condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true')
+ variables:
+ - template: common-variables.yml
+ - name: AzDOProjectName
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOProjectName'] ]
+ - name: AzDOPipelineId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOPipelineId'] ]
+ - name: AzDOBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.AzDOBuildId'] ]
pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: NetCore1ESPool-Internal
- demands: ImageOverride -equals Build.Server.Amd64.VS2019
+ vmImage: 'windows-2019'
steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- task: DownloadBuildArtifacts@0
displayName: Download Blob Artifacts
inputs:
@@ -230,48 +223,367 @@ stages:
- template: /eng/common/templates/job/execute-sdl.yml
parameters:
enable: ${{ parameters.SDLValidationParameters.enable }}
+ dependsOn: setupMaestroVars
additionalParameters: ${{ parameters.SDLValidationParameters.params }}
continueOnError: ${{ parameters.SDLValidationParameters.continueOnError }}
artifactNames: ${{ parameters.SDLValidationParameters.artifactNames }}
downloadArtifacts: ${{ parameters.SDLValidationParameters.downloadArtifacts }}
-- stage: publish_using_darc
- ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
- dependsOn: ${{ parameters.publishDependsOn }}
- ${{ if and(ne(parameters.enableNugetValidation, 'true'), ne(parameters.enableSigningValidation, 'true'), ne(parameters.enableSourceLinkValidation, 'true'), ne(parameters.SDLValidationParameters.enable, 'true')) }}:
- dependsOn: ${{ parameters.validateDependsOn }}
- displayName: Publish using Darc
- variables:
- - template: common-variables.yml
- jobs:
- - job:
- displayName: Publish Using Darc
- timeoutInMinutes: 120
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: NetCore1ESPool-Internal
- demands: ImageOverride -equals Build.Server.Amd64.VS2019
- steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: NuGetAuthenticate@0
-
- - task: PowerShell@2
- displayName: Publish Using Darc
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
- arguments: -BuildId $(BARBuildId)
- -PublishingInfraVersion ${{ parameters.publishingInfraVersion }}
- -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)'
- -MaestroToken '$(MaestroApiAccessToken)'
- -WaitPublishingFinish true
- -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
- -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
\ No newline at end of file
+- ${{ if or(ge(parameters.publishingInfraVersion, 3), eq(parameters.inline, 'false')) }}:
+ - stage: publish_using_darc
+ ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
+ dependsOn: ${{ parameters.publishDependsOn }}
+ ${{ if and(ne(parameters.enableNugetValidation, 'true'), ne(parameters.enableSigningValidation, 'true'), ne(parameters.enableSourceLinkValidation, 'true'), ne(parameters.SDLValidationParameters.enable, 'true')) }}:
+ dependsOn: ${{ parameters.validateDependsOn }}
+ displayName: Publish using Darc
+ variables:
+ - template: common-variables.yml
+ jobs:
+ - template: setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+
+ - job:
+ displayName: Publish Using Darc
+ dependsOn: setupMaestroVars
+ timeoutInMinutes: 120
+ variables:
+ - name: BARBuildId
+ value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - task: PowerShell@2
+ displayName: Publish Using Darc
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
+ arguments: -BuildId $(BARBuildId)
+ -PublishingInfraVersion ${{ parameters.PublishingInfraVersion }}
+ -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)'
+ -MaestroToken '$(MaestroApiAccessToken)'
+ -WaitPublishingFinish ${{ parameters.waitPublishingFinish }}
+ -PublishInstallersAndChecksums ${{ parameters.publishInstallersAndChecksums }}
+ -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
+ -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
+
+- ${{ if and(le(parameters.publishingInfraVersion, 2), eq(parameters.inline, 'true')) }}:
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'NetCore_Dev5_Publish'
+ channelName: '.NET 5 Dev'
+ akaMSChannelName: 'net5/dev'
+ channelId: ${{ parameters.NetDev5ChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'NetCore_Dev6_Publish'
+ channelName: '.NET 6 Dev'
+ akaMSChannelName: 'net6/dev'
+ channelId: ${{ parameters.NetDev6ChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'Net_Eng_Latest_Publish'
+ channelName: '.NET Eng - Latest'
+ akaMSChannelName: 'eng/daily'
+ channelId: ${{ parameters.NetEngLatestChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'Net_Eng_Validation_Publish'
+ channelName: '.NET Eng - Validation'
+ akaMSChannelName: 'eng/validation'
+ channelId: ${{ parameters.NetEngValidationChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'General_Testing_Publish'
+ channelName: 'General Testing'
+ akaMSChannelName: 'generaltesting'
+ channelId: ${{ parameters.GeneralTestingChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'NETCore_Tooling_Dev_Publishing'
+ channelName: '.NET Core Tooling Dev'
+ channelId: ${{ parameters.NETCoreToolingDevChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'NETCore_Tooling_Release_Publishing'
+ channelName: '.NET Core Tooling Release'
+ channelId: ${{ parameters.NETCoreToolingReleaseChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-internal-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'NET_Internal_Tooling_Publishing'
+ channelName: '.NET Internal Tooling'
+ channelId: ${{ parameters.NETInternalToolingChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'NETCore_Experimental_Publishing'
+ channelName: '.NET Core Experimental'
+ channelId: ${{ parameters.NETCoreExperimentalChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'Net_Eng_Services_Int_Publish'
+ channelName: '.NET Eng Services - Int'
+ channelId: ${{ parameters.NetEngServicesIntChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'Net_Eng_Services_Prod_Publish'
+ channelName: '.NET Eng Services - Prod'
+ channelId: ${{ parameters.NetEngServicesProdChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'NETCore_SDK_314xx_Publishing'
+ channelName: '.NET Core SDK 3.1.4xx'
+ channelId: ${{ parameters.NetCoreSDK314xxChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-internal-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'NETCore_SDK_314xx_Internal_Publishing'
+ channelName: '.NET Core SDK 3.1.4xx Internal'
+ channelId: ${{ parameters.NetCoreSDK314xxInternalChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'NETCore_SDK_313xx_Publishing'
+ channelName: '.NET Core SDK 3.1.3xx'
+ channelId: ${{ parameters.NetCoreSDK313xxChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-internal-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'NETCore_SDK_313xx_Internal_Publishing'
+ channelName: '.NET Core SDK 3.1.3xx Internal'
+ channelId: ${{ parameters.NetCoreSDK313xxInternalChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'VS16_6_Publishing'
+ channelName: 'VS 16.6'
+ channelId: ${{ parameters.VS166ChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'VS16_7_Publishing'
+ channelName: 'VS 16.7'
+ channelId: ${{ parameters.VS167ChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'VS16_8_Publishing'
+ channelName: 'VS 16.8'
+ channelId: ${{ parameters.VS168ChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'VS_Master_Publishing'
+ channelName: 'VS Master'
+ channelId: ${{ parameters.VSMasterChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'VS_16_9_Publishing'
+ channelName: 'VS 16.9'
+ channelId: ${{ parameters.VS169ChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
+
+ - template: \eng\common\templates\post-build\channels\generic-public-channel.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ dependsOn: ${{ parameters.publishDependsOn }}
+ publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }}
+ symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }}
+ stageName: 'VS_16_10_Publishing'
+ channelName: 'VS 16.10'
+ channelId: ${{ parameters.VS1610ChannelId }}
+ transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-transport/nuget/v3/index.json'
+ shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json'
+ symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json'
diff --git a/eng/common/templates/post-build/setup-maestro-vars.yml b/eng/common/templates/post-build/setup-maestro-vars.yml
index 0c87f149a4ad7..4a22b2e6f6de7 100644
--- a/eng/common/templates/post-build/setup-maestro-vars.yml
+++ b/eng/common/templates/post-build/setup-maestro-vars.yml
@@ -2,69 +2,77 @@ parameters:
BARBuildId: ''
PromoteToChannelIds: ''
-steps:
- - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}:
- - task: DownloadBuildArtifacts@0
- displayName: Download Release Configs
- inputs:
- buildType: current
- artifactName: ReleaseConfigs
- checkDownloadedFiles: true
+jobs:
+- job: setupMaestroVars
+ displayName: Setup Maestro Vars
+ variables:
+ - template: common-variables.yml
+ pool:
+ vmImage: 'windows-2019'
+ steps:
+ - checkout: none
- - task: PowerShell@2
- name: setReleaseVars
- displayName: Set Release Configs Vars
- inputs:
- targetType: inline
- pwsh: true
- script: |
- try {
- if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') {
- $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt
+ - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Release Configs
+ inputs:
+ buildType: current
+ artifactName: ReleaseConfigs
+ checkDownloadedFiles: true
- $BarId = $Content | Select -Index 0
- $Channels = $Content | Select -Index 1
- $IsStableBuild = $Content | Select -Index 2
+ - task: PowerShell@2
+ name: setReleaseVars
+ displayName: Set Release Configs Vars
+ inputs:
+ targetType: inline
+ script: |
+ try {
+ if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') {
+ $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt
- $AzureDevOpsProject = $Env:System_TeamProject
- $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId
- $AzureDevOpsBuildId = $Env:Build_BuildId
- }
- else {
- $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}"
+ $BarId = $Content | Select -Index 0
+ $Channels = $Content | Select -Index 1
+ $IsStableBuild = $Content | Select -Index 2
- $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'
- $apiHeaders.Add('Accept', 'application/json')
- $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}")
+ $AzureDevOpsProject = $Env:System_TeamProject
+ $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId
+ $AzureDevOpsBuildId = $Env:Build_BuildId
+ }
+ else {
+ $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}"
- $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" }
-
- $BarId = $Env:BARBuildId
- $Channels = $Env:PromoteToMaestroChannels -split ","
- $Channels = $Channels -join "]["
- $Channels = "[$Channels]"
+ $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'
+ $apiHeaders.Add('Accept', 'application/json')
+ $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}")
- $IsStableBuild = $buildInfo.stable
- $AzureDevOpsProject = $buildInfo.azureDevOpsProject
- $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId
- $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId
- }
+ $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" }
+
+ $BarId = $Env:BARBuildId
+ $Channels = $Env:PromoteToMaestroChannels -split ","
+ $Channels = $Channels -join "]["
+ $Channels = "[$Channels]"
- Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId"
- Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels"
- Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild"
+ $IsStableBuild = $buildInfo.stable
+ $AzureDevOpsProject = $buildInfo.azureDevOpsProject
+ $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId
+ $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId
+ }
- Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject"
- Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId"
- Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId"
- }
- catch {
- Write-Host $_
- Write-Host $_.Exception
- Write-Host $_.ScriptStackTrace
- exit 1
- }
- env:
- MAESTRO_API_TOKEN: $(MaestroApiAccessToken)
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }}
+ Write-Host "##vso[task.setvariable variable=BARBuildId;isOutput=true]$BarId"
+ Write-Host "##vso[task.setvariable variable=TargetChannels;isOutput=true]$Channels"
+ Write-Host "##vso[task.setvariable variable=IsStableBuild;isOutput=true]$IsStableBuild"
+
+ Write-Host "##vso[task.setvariable variable=AzDOProjectName;isOutput=true]$AzureDevOpsProject"
+ Write-Host "##vso[task.setvariable variable=AzDOPipelineId;isOutput=true]$AzureDevOpsBuildDefinitionId"
+ Write-Host "##vso[task.setvariable variable=AzDOBuildId;isOutput=true]$AzureDevOpsBuildId"
+ }
+ catch {
+ Write-Host $_
+ Write-Host $_.Exception
+ Write-Host $_.ScriptStackTrace
+ exit 1
+ }
+ env:
+ MAESTRO_API_TOKEN: $(MaestroApiAccessToken)
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }}
diff --git a/eng/common/templates/steps/source-build.yml b/eng/common/templates/steps/source-build.yml
index d85d6d07d5c7b..ba40dc82f1411 100644
--- a/eng/common/templates/steps/source-build.yml
+++ b/eng/common/templates/steps/source-build.yml
@@ -23,7 +23,7 @@ steps:
# In addition, add an msbuild argument to copy the WIP from the repo to the target build location.
# This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those
# changes.
- internalRestoreArgs=
+ $internalRestoreArgs=
if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then
# Temporarily work around https://github.com/dotnet/arcade/issues/7709
chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
diff --git a/eng/formatting/format.sh b/eng/formatting/format.sh
old mode 100755
new mode 100644
diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets
index aab934c42ae6b..bc2e7e5dff9a0 100644
--- a/eng/liveBuilds.targets
+++ b/eng/liveBuilds.targets
@@ -24,9 +24,6 @@
$([MSBuild]::NormalizeDirectory('$(CoreCLRArtifactsPath)', 'sharedFramework'))
$([MSBuild]::NormalizeDirectory('$(CoreCLRArtifactsPath)', 'crossgen2'))
- $([MSBuild]::NormalizeDirectory('$(CoreCLRArtifactsPath)', 'ilc'))
- $([MSBuild]::NormalizeDirectory('$(CoreCLRArtifactsPath)', 'aotsdk'))
- $([MSBuild]::NormalizeDirectory('$(CoreCLRArtifactsPath)', 'build'))
$([MSBuild]::NormalizeDirectory('$(MonoArtifactsPath)', 'cross', $(TargetOS.ToLowerInvariant())-$(TargetArchitecture.ToLowerInvariant())))
diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh
index 294e9832ad310..373091b13a001 100755
--- a/eng/native/build-commons.sh
+++ b/eng/native/build-commons.sh
@@ -197,7 +197,7 @@ usage()
echo ""
echo "Common Options:"
echo ""
- echo "BuildArch can be: -arm, -armv6, -armel, -arm64, -loongarch64, -s390x, x64, x86, -wasm"
+ echo "BuildArch can be: -arm, -armel, -arm64, -loongarch64, -s390x, x64, x86, -wasm"
echo "BuildType can be: -debug, -checked, -release"
echo "-os: target OS (defaults to running OS)"
echo "-bindir: output directory (defaults to $__ProjectRoot/artifacts)"
@@ -270,10 +270,6 @@ while :; do
__BuildArch=arm
;;
- armv6|-armv6)
- __BuildArch=armv6
- ;;
-
arm64|-arm64)
__BuildArch=arm64
;;
diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake
index b67594cb60fb2..fad1ac58d39c8 100644
--- a/eng/native/configurecompiler.cmake
+++ b/eng/native/configurecompiler.cmake
@@ -213,9 +213,6 @@ elseif (CLR_CMAKE_HOST_ARCH_I386)
elseif (CLR_CMAKE_HOST_ARCH_ARM)
set(ARCH_HOST_NAME arm)
add_definitions(-DHOST_ARM)
-elseif (CLR_CMAKE_HOST_ARCH_ARMV6)
- set(ARCH_HOST_NAME armv6)
- add_definitions(-DHOST_ARMV6)
elseif (CLR_CMAKE_HOST_ARCH_ARM64)
set(ARCH_HOST_NAME arm64)
add_definitions(-DHOST_ARM64 -DHOST_64BIT)
@@ -241,8 +238,6 @@ if (CLR_CMAKE_HOST_UNIX)
message("Detected Linux x86_64")
elseif(CLR_CMAKE_HOST_UNIX_ARM)
message("Detected Linux ARM")
- elseif(CLR_CMAKE_HOST_UNIX_ARMV6)
- message("Detected Linux ARMv6")
elseif(CLR_CMAKE_HOST_UNIX_ARM64)
message("Detected Linux ARM64")
elseif(CLR_CMAKE_HOST_UNIX_LOONGARCH64)
@@ -306,12 +301,6 @@ elseif (CLR_CMAKE_TARGET_ARCH_ARM)
set(ARCH_TARGET_NAME arm)
add_compile_definitions($<$>>:TARGET_ARM>)
add_compile_definitions($<$>>:TARGET_32BIT>)
-elseif (CLR_CMAKE_TARGET_ARCH_ARMV6)
- set(ARCH_SOURCES_DIR arm)
- set(ARCH_TARGET_NAME armv6)
- add_compile_definitions($<$>>:TARGET_ARM>)
- add_compile_definitions($<$>>:TARGET_ARMV6>)
- add_compile_definitions($<$>>:TARGET_32BIT>)
elseif (CLR_CMAKE_TARGET_ARCH_I386)
set(ARCH_TARGET_NAME x86)
set(ARCH_SOURCES_DIR i386)
@@ -518,14 +507,6 @@ if(CLR_CMAKE_HOST_UNIX_ARM)
endif(ARM_SOFTFP)
endif(CLR_CMAKE_HOST_UNIX_ARM)
-if(CLR_CMAKE_HOST_UNIX_ARMV6)
- add_compile_options(-mfpu=vfp)
- add_definitions(-DCLR_ARM_FPU_CAPABILITY=0x0)
- add_compile_options(-march=armv6zk)
- add_compile_options(-mcpu=arm1176jzf-s)
- add_compile_options(-mfloat-abi=hard)
-endif(CLR_CMAKE_HOST_UNIX_ARMV6)
-
if(CLR_CMAKE_HOST_UNIX_X86)
add_compile_options(-msse2)
endif()
diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake
index ecf10a8d4c39e..cdf33430b49f1 100644
--- a/eng/native/configureplatform.cmake
+++ b/eng/native/configureplatform.cmake
@@ -41,8 +41,6 @@ if(CLR_CMAKE_HOST_OS STREQUAL Linux)
set(CLR_CMAKE_HOST_UNIX_ARMV7L 1)
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL arm OR CMAKE_SYSTEM_PROCESSOR STREQUAL armv7-a)
set(CLR_CMAKE_HOST_UNIX_ARM 1)
- elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv6 OR CMAKE_SYSTEM_PROCESSOR STREQUAL armv6l)
- set(CLR_CMAKE_HOST_UNIX_ARMV6 1)
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL arm64)
set(CLR_CMAKE_HOST_UNIX_ARM64 1)
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL loongarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL loongarch64)
@@ -219,13 +217,6 @@ if(CLR_CMAKE_HOST_UNIX_ARM)
if(CLR_CMAKE_HOST_UNIX_ARMV7L)
set(CLR_CMAKE_HOST_ARCH_ARMV7L 1)
endif()
-elseif(CLR_CMAKE_HOST_UNIX_ARMV6)
- set(CLR_CMAKE_HOST_ARCH_ARMV6 1)
- set(CLR_CMAKE_HOST_ARCH "armv6")
-
- if(CLR_CMAKE_HOST_UNIX_ARMV6L)
- set(CLR_CMAKE_HOST_ARCH_ARMV6L 1)
- endif()
elseif(CLR_CMAKE_HOST_UNIX_ARM64)
set(CLR_CMAKE_HOST_ARCH_ARM64 1)
set(CLR_CMAKE_HOST_ARCH "arm64")
@@ -286,8 +277,6 @@ if (CLR_CMAKE_TARGET_ARCH STREQUAL x64)
set(CLR_CMAKE_TARGET_ARCH_LOONGARCH64 1)
elseif(CLR_CMAKE_TARGET_ARCH STREQUAL arm)
set(CLR_CMAKE_TARGET_ARCH_ARM 1)
- elseif(CLR_CMAKE_TARGET_ARCH STREQUAL armv6)
- set(CLR_CMAKE_TARGET_ARCH_ARMV6 1)
elseif(CLR_CMAKE_TARGET_ARCH STREQUAL armel)
set(CLR_CMAKE_TARGET_ARCH_ARM 1)
set(CLR_CMAKE_TARGET_ARCH_ARMV7L 1)
@@ -390,8 +379,6 @@ if(CLR_CMAKE_TARGET_UNIX)
set(CLR_CMAKE_TARGET_UNIX_ARM 1)
elseif(CLR_CMAKE_TARGET_ARCH STREQUAL arm)
set(CLR_CMAKE_TARGET_UNIX_ARM 1)
- elseif(CLR_CMAKE_TARGET_ARCH STREQUAL armv6)
- set(CLR_CMAKE_TARGET_UNIX_ARMV6 1)
elseif(CLR_CMAKE_TARGET_ARCH STREQUAL arm64)
set(CLR_CMAKE_TARGET_UNIX_ARM64 1)
elseif(CLR_CMAKE_TARGET_ARCH STREQUAL loongarch64)
diff --git a/eng/native/configuretools.cmake b/eng/native/configuretools.cmake
index 860e46427b6b0..136cd67925d0c 100644
--- a/eng/native/configuretools.cmake
+++ b/eng/native/configuretools.cmake
@@ -7,15 +7,15 @@ if (CMAKE_C_COMPILER MATCHES "-?[0-9]+(\.[0-9]+)?$")
endif()
if(NOT WIN32 AND NOT CLR_CMAKE_TARGET_BROWSER)
- if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(APPLE)
set(TOOLSET_PREFIX "")
else()
set(TOOLSET_PREFIX "llvm-")
endif()
- elseif(CMAKE_C_COMPILER_ID MATCHES "GNU")
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
if(CMAKE_CROSSCOMPILING)
- set(TOOLSET_PREFIX "${CMAKE_C_COMPILER_TARGET}-")
+ set(TOOLSET_PREFIX "${CMAKE_CXX_COMPILER_TARGET}-")
else()
set(TOOLSET_PREFIX "")
endif()
@@ -52,8 +52,8 @@ if(NOT WIN32 AND NOT CLR_CMAKE_TARGET_BROWSER)
if(CLR_CMAKE_TARGET_ANDROID)
set(TOOLSET_PREFIX ${ANDROID_TOOLCHAIN_PREFIX})
- elseif(CMAKE_CROSSCOMPILING AND NOT DEFINED CLR_CROSS_COMPONENTS_BUILD AND
- CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7l|armv6l|aarch64|arm|s390x)$")
+ elseif(CMAKE_CROSSCOMPILING AND NOT DEFINED CLR_CROSS_COMPONENTS_BUILD AND (CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l OR
+ CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL arm OR CMAKE_SYSTEM_PROCESSOR STREQUAL s390x))
set(TOOLSET_PREFIX "${TOOLCHAIN}-")
else()
set(TOOLSET_PREFIX "")
diff --git a/eng/native/functions.cmake b/eng/native/functions.cmake
index 0c28f75706de1..c4af68ba7dc61 100644
--- a/eng/native/functions.cmake
+++ b/eng/native/functions.cmake
@@ -4,7 +4,7 @@ function(clr_unknown_arch)
elseif(CLR_CROSS_COMPONENTS_BUILD)
message(FATAL_ERROR "Only AMD64, I386 host are supported for linux cross-architecture component. Found: ${CMAKE_SYSTEM_PROCESSOR}")
else()
- message(FATAL_ERROR "Only AMD64, ARMV6, ARM64, LOONGARCH64 and ARM are supported. Found: ${CMAKE_SYSTEM_PROCESSOR}")
+ message(FATAL_ERROR "Only AMD64, ARM64, LOONGARCH64 and ARM are supported. Found: ${CMAKE_SYSTEM_PROCESSOR}")
endif()
endfunction()
@@ -155,10 +155,6 @@ function(find_unwind_libs UnwindLibs)
find_library(UNWIND_ARCH NAMES unwind-arm)
endif()
- if(CLR_CMAKE_HOST_ARCH_ARMV6)
- find_library(UNWIND_ARCH NAMES unwind-arm)
- endif()
-
if(CLR_CMAKE_HOST_ARCH_ARM64)
find_library(UNWIND_ARCH NAMES unwind-aarch64)
endif()
diff --git a/eng/native/init-os-and-arch.sh b/eng/native/init-os-and-arch.sh
index eda07a5feebbd..586534be1c8aa 100644
--- a/eng/native/init-os-and-arch.sh
+++ b/eng/native/init-os-and-arch.sh
@@ -53,10 +53,6 @@ case "$CPUName" in
fi
;;
- armv6l)
- arch=armv6
- ;;
-
i[3-6]86)
echo "Unsupported CPU $CPUName detected, build might not succeed!"
arch=x86
diff --git a/eng/native/tryrun.cmake b/eng/native/tryrun.cmake
index fca410fcb4b42..e8a04c5698ad3 100644
--- a/eng/native/tryrun.cmake
+++ b/eng/native/tryrun.cmake
@@ -68,7 +68,7 @@ if(DARWIN)
else()
message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm64 or x64 is supported for OSX cross build!")
endif()
-elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|armv6|arm64|loongarch64|s390x|x86)$" OR FREEBSD OR ILLUMOS)
+elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|arm64|loongarch64|s390x|x86)$" OR FREEBSD OR ILLUMOS)
set_cache_value(FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL_EXITCODE 1)
set_cache_value(GETPWUID_R_SETS_ERRNO_EXITCODE 0)
set_cache_value(HAS_POSIX_SEMAPHORES_EXITCODE 0)
@@ -146,9 +146,9 @@ elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|armv6|arm64|loongarch64|s390x|x86)$
set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0)
endif()
else()
- message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, armv6, arm64, loongarch64, s390x and x86 are supported!")
+ message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, arm64, loongarch64, s390x and x86 are supported!")
endif()
-if(TARGET_ARCH_NAME STREQUAL "x86" OR TARGET_ARCH_NAME STREQUAL "s390x" OR TARGET_ARCH_NAME STREQUAL "armv6" OR TARGET_ARCH_NAME STREQUAL "loongarch64")
+if(TARGET_ARCH_NAME STREQUAL "x86" OR TARGET_ARCH_NAME STREQUAL "s390x" OR TARGET_ARCH_NAME STREQUAL "loongarch64")
set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0)
endif()
diff --git a/eng/packaging.targets b/eng/packaging.targets
index c305c64dd9409..667837fbff106 100644
--- a/eng/packaging.targets
+++ b/eng/packaging.targets
@@ -162,18 +162,19 @@
<_MultiTargetRoslynComponentTargetPrefix>$(PackageId.Replace('.', '_'))
- Disable$(PackageId.Replace('.', ''))SourceGenerator
+ <_MultiTargetRoslynComponentDisableSourceGeneratorPropertyName>Disable$(PackageId.Replace('.', ''))SourceGenerator
+ <_MultiTargetRoslynComponentDisableSourceGeneratorPropertyName>$(_MultiTargetRoslynComponentDisableSourceGeneratorPropertyName.Replace('Abstractions', ''))
diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml
index c9015681d1e17..cf30d702dda60 100644
--- a/eng/pipelines/common/global-build-job.yml
+++ b/eng/pipelines/common/global-build-job.yml
@@ -3,7 +3,6 @@ parameters:
nameSuffix: ''
buildArgs: ''
archType: ''
- hostedOs: ''
osGroup: ''
osSubgroup: ''
container: ''
@@ -36,12 +35,8 @@ parameters:
jobs:
- template: /eng/common/templates/job/job.yml
parameters:
- ${{ if eq(parameters.hostedOs, '') }}:
- name: ${{ format('build_{0}{1}_{2}_{3}_{4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.nameSuffix) }}
- displayName: ${{ format('Build {0}{1} {2} {3} {4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.nameSuffix) }}
- ${{ if ne(parameters.hostedOs, '') }}:
- name: ${{ format('build_{0}{1}_{2}_{3}_{4}_{5}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.hostedOs, parameters.buildConfig, parameters.nameSuffix) }}
- displayName: ${{ format('Build {0}{1} {2} {3} {4} {5}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.hostedOs, parameters.buildConfig, parameters.nameSuffix) }}
+ name: ${{ format('build_{0}{1}_{2}_{3}_{4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.nameSuffix) }}
+ displayName: ${{ format('Build {0}{1} {2} {3} {4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.nameSuffix) }}
pool: ${{ parameters.pool }}
container: ${{ parameters.container }}
condition: and(succeeded(), ${{ parameters.condition }})
@@ -141,7 +136,7 @@ jobs:
df -h
displayName: Disk Usage before Build
- - ${{ if eq(parameters.platform, 'Browser_wasm_win') }}:
+ - ${{ if contains(parameters.nameSuffix, 'Windows_wasm') }}:
# Update machine certs
- task: PowerShell@2
displayName: Update machine certs
diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml
index 4f0200380bc9f..ade8c7aab981b 100644
--- a/eng/pipelines/common/platform-matrix.yml
+++ b/eng/pipelines/common/platform-matrix.yml
@@ -52,31 +52,6 @@ jobs:
crossrootfsDir: '/crossrootfs/arm'
${{ insert }}: ${{ parameters.jobParameters }}
-# Linux armv6
-- ${{ if or(containsValue(parameters.platforms, 'Linux_armv6'), or(and(ne(parameters.runtimeFlavor, 'mono'), in(parameters.platformGroup, 'gcstress')), and(eq(parameters.runtimeFlavor, 'mono'), in(parameters.platformGroup, 'all', 'gcstress')))) }}:
- - template: xplat-setup.yml
- parameters:
- jobTemplate: ${{ parameters.jobTemplate }}
- helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }}
- variables: ${{ parameters.variables }}
- osGroup: Linux
- archType: armv6
- targetRid: linux-armv6
- platform: Linux_armv6
- container:
- image: ubuntu-20.04-cross-armv6-raspbian-10-20211208135931-e6e3ac4
- registry: mcr
- jobParameters:
- runtimeFlavor: ${{ parameters.runtimeFlavor }}
- stagedBuild: ${{ parameters.stagedBuild }}
- buildConfig: ${{ parameters.buildConfig }}
- ${{ if eq(parameters.passPlatforms, true) }}:
- platforms: ${{ parameters.platforms }}
- helixQueueGroup: ${{ parameters.helixQueueGroup }}
- crossBuild: true
- crossrootfsDir: '/crossrootfs/armv6'
- ${{ insert }}: ${{ parameters.jobParameters }}
-
# Linux arm64
- ${{ if or(containsValue(parameters.platforms, 'Linux_arm64'), in(parameters.platformGroup, 'all', 'gcstress')) }}:
@@ -298,6 +273,7 @@ jobs:
jobTemplate: ${{ parameters.jobTemplate }}
helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }}
variables: ${{ parameters.variables }}
+ hostedOs: Linux
osGroup: Browser
archType: wasm
targetRid: browser-wasm
@@ -306,7 +282,6 @@ jobs:
image: ubuntu-18.04-webassembly-20210707133424-12f133e
registry: mcr
jobParameters:
- hostedOs: Linux
runtimeFlavor: ${{ parameters.runtimeFlavor }}
stagedBuild: ${{ parameters.stagedBuild }}
buildConfig: ${{ parameters.buildConfig }}
@@ -322,12 +297,12 @@ jobs:
jobTemplate: ${{ parameters.jobTemplate }}
helixQueuesTemplate: ${{ parameters.helixQueuesTemplate }}
variables: ${{ parameters.variables }}
+ hostedOs: windows
osGroup: Browser
archType: wasm
targetRid: browser-wasm
platform: Browser_wasm_win
jobParameters:
- hostedOs: windows
runtimeFlavor: ${{ parameters.runtimeFlavor }}
stagedBuild: ${{ parameters.stagedBuild }}
buildConfig: ${{ parameters.buildConfig }}
diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml
index f944ad47ba203..04399d26a6a22 100644
--- a/eng/pipelines/common/templates/runtimes/run-test-job.yml
+++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml
@@ -73,7 +73,7 @@ jobs:
- ${{ if not(or(eq(parameters.runtimeVariant, 'minijit'), eq(parameters.runtimeVariant, 'monointerpreter'))) }}:
- ${{ if eq(parameters.runtimeVariant, 'llvmfullaot') }}:
- ${{ format('{0}_llvmaot_product_build_{1}{2}_{3}_{4}', parameters.runtimeFlavor, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
- - ${{ if ne(parameters.runtimeVariant, 'llvmfullaot') }}:
+ - ${{ if not(eq(parameters.runtimeVariant, 'llvmfullaot')) }}:
- ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
- ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}:
- ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }}
@@ -109,7 +109,7 @@ jobs:
- name: runtimeVariantArg
value: ''
- - ${{ if ne(parameters.runtimeVariant, '') }}:
+ - ${{ if not(eq(parameters.runtimeVariant, '')) }}:
- name: runtimeVariantArg
value: '/p:RuntimeVariant=${{ parameters.runtimeVariant }}'
@@ -319,7 +319,7 @@ jobs:
- script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) $(logRootNameArg)MonoAot $(monoAotBuildshCommand) $(buildConfig) $(archType) $(runtimeVariantArg)
displayName: "LLVM AOT compile CoreCLR tests"
- ${{ if eq(parameters.archType, 'arm64') }}:
- - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) $(logRootNameArg)MonoAot $(monoAotBuildshCommand) $(buildConfig) $(archType) cross $(runtimeVariantArg) -maxcpucount:2
+ - script: $(Build.SourcesDirectory)/src/tests/build$(scriptExt) $(logRootNameArg)MonoAot $(monoAotBuildshCommand) $(buildConfig) $(archType) cross $(runtimeVariantArg)
displayName: "LLVM AOT cross-compile CoreCLR tests"
env:
__MonoToolPrefix: aarch64-linux-gnu-
@@ -546,7 +546,6 @@ jobs:
- jitosr
- jitosr_stress
- jitosr_pgo
- - jitosr_stress_random
- jitpartialcompilation
- jitpartialcompilation_osr
- jitpartialcompilation_osr_pgo
diff --git a/eng/pipelines/common/variables.yml b/eng/pipelines/common/variables.yml
index 6e378369aa4fc..d6b84f837c327 100644
--- a/eng/pipelines/common/variables.yml
+++ b/eng/pipelines/common/variables.yml
@@ -11,17 +11,19 @@ variables:
- name: isOfficialBuild
value: ${{ and(ne(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}
-- name: isRollingBuild
+- name: isFullMatrix
value: ${{ and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}
-- name: isExtraPlatformsBuild
- value: ${{ eq(variables['Build.DefinitionName'], 'runtime-extra-platforms') }}
-- name: isNotExtraPlatformsBuild
- value: ${{ ne(variables['Build.DefinitionName'], 'runtime-extra-platforms') }}
+- name: isNotFullMatrix
+ value: ${{ and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}
+- name: isNotManualAndIsPR
+ value: ${{ and(not(in(variables['Build.DefinitionName'], 'runtime-staging-manual', 'runtime-manual')), eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}
+- name: isManualOrIsNotPR
+ value: ${{ or(in(variables['Build.DefinitionName'], 'runtime-staging-manual', 'runtime-manual'), and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest'))) }}
# We only run evaluate paths on runtime, runtime-staging and runtime-community pipelines on PRs
# keep in sync with /eng/pipelines/common/xplat-setup.yml
- name: dependOnEvaluatePaths
- value: ${{ and(eq(variables['Build.Reason'], 'PullRequest'), in(variables['Build.DefinitionName'], 'runtime', 'runtime-staging', 'runtime-community', 'runtime-extra-platforms')) }}
+ value: ${{ and(eq(variables['Build.Reason'], 'PullRequest'), in(variables['Build.DefinitionName'], 'runtime', 'runtime-staging', 'runtime-community')) }}
- name: debugOnPrReleaseOnRolling
${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
value: Release
diff --git a/eng/pipelines/common/xplat-setup.yml b/eng/pipelines/common/xplat-setup.yml
index e397bcdd456a6..05a6bc7c4a63c 100644
--- a/eng/pipelines/common/xplat-setup.yml
+++ b/eng/pipelines/common/xplat-setup.yml
@@ -22,7 +22,8 @@ jobs:
shouldContinueOnError: ${{ and(endsWith(variables['Build.DefinitionName'], 'staging'), eq(variables['Build.Reason'], 'PullRequest')) }}
# keep in sync with /eng/pipelines/common/variables.yml
- dependOnEvaluatePaths: ${{ and(eq(variables['Build.Reason'], 'PullRequest'), in(variables['Build.DefinitionName'], 'runtime', 'runtime-staging', 'runtime-community', 'runtime-extra-platforms')) }}
+ nonPRBuild: ${{ and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}
+ dependOnEvaluatePaths: ${{ and(eq(variables['Build.Reason'], 'PullRequest'), in(variables['Build.DefinitionName'], 'runtime', 'runtime-staging', 'runtime-community')) }}
variables:
# Disable component governance in our CI builds. These builds are not shipping nor
@@ -49,12 +50,8 @@ jobs:
value: $(buildConfigUpper)
- name: _runSmokeTestsOnlyArg
- value: '/p:RunSmokeTestsOnly=$(isNotExtraPlatformsBuild)'
-
- - name: _hostedOs
- value: ${{ parameters.jobParameters.hostedOs }}
-
- - ${{ if or(eq(parameters.osGroup, 'windows'), eq(parameters.jobParameters.hostedOs, 'windows')) }}:
+ value: '/p:RunSmokeTestsOnly=$(isNotManualAndIsPR)'
+ - ${{ if or(eq(parameters.osGroup, 'windows'), eq(parameters.hostedOs, 'windows')) }}:
- name: archiveExtension
value: '.zip'
- name: archiveType
@@ -72,7 +69,7 @@ jobs:
- name: logRootNameArg
value: 'log '
- - ${{ if and(ne(parameters.osGroup, 'windows'), ne(parameters.jobParameters.hostedOs, 'windows')) }}:
+ - ${{ if and(ne(parameters.osGroup, 'windows'), ne(parameters.hostedOs, 'windows')) }}:
- name: archiveExtension
value: '.tar.gz'
- name: archiveType
@@ -120,12 +117,12 @@ jobs:
${{ if eq(parameters.jobParameters.pool, '') }}:
pool:
# Public Linux Build Pool
- ${{ if and(or(in(parameters.osGroup, 'Linux', 'FreeBSD', 'Android', 'Tizen'), eq(parameters.jobParameters.hostedOs, 'Linux')), eq(variables['System.TeamProject'], 'public')) }}:
+ ${{ if and(or(in(parameters.osGroup, 'Linux', 'FreeBSD', 'Android', 'Tizen'), eq(parameters.hostedOs, 'Linux')), eq(variables['System.TeamProject'], 'public')) }}:
name: NetCore1ESPool-Public
demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open
# Official Build Linux Pool
- ${{ if and(or(in(parameters.osGroup, 'Linux', 'FreeBSD', 'Browser', 'Android', 'Tizen'), eq(parameters.jobParameters.hostedOs, 'Linux')), ne(variables['System.TeamProject'], 'public')) }}:
+ ${{ if and(or(in(parameters.osGroup, 'Linux', 'FreeBSD', 'Browser', 'Android', 'Tizen'), eq(parameters.hostedOs, 'Linux')), ne(variables['System.TeamProject'], 'public')) }}:
name: NetCore1ESPool-Internal
demands: ImageOverride -equals Build.Ubuntu.1804.Amd64
@@ -139,7 +136,7 @@ jobs:
demands: ImageOverride -equals Build.Windows.10.Amd64.VS2019
# Public Windows Build Pool
- ${{ if and(or(eq(parameters.osGroup, 'windows'), eq(parameters.jobParameters.hostedOs, 'windows')), eq(variables['System.TeamProject'], 'public')) }}:
+ ${{ if and(or(eq(parameters.osGroup, 'windows'), eq(parameters.hostedOs, 'windows')), eq(variables['System.TeamProject'], 'public')) }}:
name: NetCore1ESPool-Public
demands: ImageOverride -equals Build.Windows.10.Amd64.VS2019.Open
diff --git a/eng/pipelines/coreclr/templates/build-jit-job.yml b/eng/pipelines/coreclr/templates/build-jit-job.yml
index b5ff3df213af3..c251c06f28679 100644
--- a/eng/pipelines/coreclr/templates/build-jit-job.yml
+++ b/eng/pipelines/coreclr/templates/build-jit-job.yml
@@ -107,10 +107,10 @@ jobs:
# Build CoreCLR JIT
- ${{ if ne(parameters.osGroup, 'windows') }}:
- - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) $(crossArg) -ci $(compilerArg) -component alljits -component spmi
+ - script: $(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) $(crossArg) -ci $(compilerArg) -component alljits
displayName: Build CoreCLR JIT
- ${{ if eq(parameters.osGroup, 'windows') }}:
- - script: set __TestIntermediateDir=int&&$(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) -ci -component alljits -component spmi
+ - script: set __TestIntermediateDir=int&&$(Build.SourcesDirectory)/src/coreclr/build-runtime$(scriptExt) $(buildConfig) $(archType) -ci -component alljits
displayName: Build CoreCLR JIT
- ${{ if eq(parameters.uploadAs, 'azureBlob') }}:
@@ -118,7 +118,7 @@ jobs:
- script: $(PipScript) install --user --upgrade pip && $(PipScript) install --user azure.storage.blob==12.5.0 --force-reinstall
displayName: Upgrade Pip to latest and install azure-storage-blob Python package
- - script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/jitrollingbuild.py upload -build_type $(buildConfig) -arch $(archType) -host_os $(osGroup) -git_hash $(Build.SourceVersion) --use_latest_jit_change
+ - script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/jitrollingbuild.py upload -build_type $(buildConfig) -arch $(archType) -host_os $(osGroup) -git_hash $(Build.SourceVersion)
displayName: Upload JIT to Azure Storage
env:
CLRJIT_AZ_KEY: $(clrjit_key1) # secret key stored as variable in pipeline
diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml
index 9048e8ed4fe8a..b89cd621eda1e 100644
--- a/eng/pipelines/coreclr/templates/build-job.yml
+++ b/eng/pipelines/coreclr/templates/build-job.yml
@@ -132,10 +132,10 @@ jobs:
value: ''
- ${{ if ne(parameters.testGroup, 'innerloop') }}:
- name: clrRuntimeComponentsBuildArg
- value: '-component runtime -component alljits -component paltests -component nativeaot -component spmi '
+ value: '-component runtime -component alljits -component paltests -component nativeaot '
- ${{ if and(eq(parameters.osGroup, 'Linux'), eq(parameters.archType, 'x86')) }}:
- name: clrRuntimeComponentsBuildArg
- value: '-component runtime -component jit -component iltools -component spmi '
+ value: '-component runtime -component jit -component iltools '
- name: pgoInstrumentArg
value: ''
@@ -212,7 +212,7 @@ jobs:
# Build CoreCLR Managed Components
- ${{ if or(ne(parameters.osGroup, 'Linux'), ne(parameters.archType, 'x86')) }}:
- - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib+clr.nativecorelib+clr.nativeaotlibs+clr.tools+clr.packages+clr.paltestlist $(crossArg) -arch $(archType) $(osArg) -c $(buildConfig) $(pgoInstrumentArg) $(officialBuildIdArg) -ci
+ - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib+clr.nativecorelib+clr.tools+clr.packages+clr.paltestlist $(crossArg) -arch $(archType) $(osArg) -c $(buildConfig) $(pgoInstrumentArg) $(officialBuildIdArg) -ci
displayName: Build managed product components and packages
- ${{ if and(eq(parameters.osGroup, 'Linux'), eq(parameters.archType, 'x86')) }}:
- script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib $(crossArg) -arch $(archType) $(osArg) -c $(buildConfig) $(pgoInstrumentArg) $(officialBuildIdArg) -ci
diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml
index 0b2e6f7f80ed2..1a5a346758702 100644
--- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml
+++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml
@@ -21,7 +21,6 @@ jobs:
archType: ${{ parameters.archType }}
container: ${{ parameters.container }}
pool: ${{ parameters.pool }}
- platform: ${{ parameters.platform }}
shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
dependOnEvaluatePaths: ${{ parameters.dependOnEvaluatePaths}}
runtimeFlavorDisplayName: ${{ parameters.runtimeFlavorDisplayName }}
diff --git a/eng/pipelines/coreclr/templates/perf-job.yml b/eng/pipelines/coreclr/templates/perf-job.yml
index 627d42fd7add1..dd1ff0ebd3b24 100644
--- a/eng/pipelines/coreclr/templates/perf-job.yml
+++ b/eng/pipelines/coreclr/templates/perf-job.yml
@@ -57,7 +57,7 @@ jobs:
- ${{ if and(eq(parameters.runtimeType, 'mono'), ne(parameters.codeGenType, 'AOT')) }}:
- ${{ format('mono_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }}
- ${{ if eq(parameters.runtimeType, 'wasm')}}:
- - ${{ format('build_{0}{1}_{2}_{3}_{4}_{5}', 'Browser', '', 'wasm', 'Linux', parameters.buildConfig, parameters.runtimeType) }}
+ - ${{ format('build_{0}{1}_{2}_{3}_{4}', 'Browser', '', 'wasm', parameters.buildConfig, parameters.runtimeType) }}
- ${{ if and(eq(parameters.codeGenType, 'AOT'), ne(parameters.runtimeType, 'wasm'))}}:
- ${{ format('build_{0}{1}_{2}_{3}_{4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.codeGenType) }}
- ${{ if eq(parameters.runtimeType, 'AndroidMono')}}:
diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml
index f82e09c9e0a12..ac074ab9903f8 100644
--- a/eng/pipelines/libraries/helix-queues-setup.yml
+++ b/eng/pipelines/libraries/helix-queues-setup.yml
@@ -21,7 +21,6 @@ jobs:
archType: ${{ parameters.archType }}
container: ${{ parameters.container }}
pool: ${{ parameters.pool }}
- platform: ${{ parameters.platform }}
shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
dependOnEvaluatePaths: ${{ parameters.dependOnEvaluatePaths}}
runtimeFlavorDisplayName: ${{ parameters.runtimeFlavorDisplayName }}
@@ -29,31 +28,26 @@ jobs:
# Linux arm
- ${{ if eq(parameters.platform, 'Linux_arm') }}:
- - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
+ - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}:
- (Debian.10.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-arm32v7-20210304164340-6616c63
- (Debian.11.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm32v7-20210304164347-5a7c380
- # Linux armv6
- - ${{ if eq(parameters.platform, 'Linux_armv6') }}:
-# - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}:
- - (Raspbian.10.Armv6.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:raspbian-10-helix-arm32v6-20211215185610-60748cc
-
# Linux arm64
- ${{ if eq(parameters.platform, 'Linux_arm64') }}:
- - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
+ - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}:
+ - (Ubuntu.1804.ArmArch.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-helix-arm64v8-20210106155927-56c6673
- (Ubuntu.2110.Arm64.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-21.10-helix-arm64v8-20211116135000-0f8d97e
- - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
+ - ${{ if eq(parameters.jobParameters.isFullMatrix, false) }}:
- (Ubuntu.1804.ArmArch.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-16.04-helix-arm64v8-20210106155927-56c6673
# Linux musl x64
- ${{ if eq(parameters.platform, 'Linux_musl_x64') }}:
- - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- - (Alpine.314.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-amd64-20210910135833-1848e19
- - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
+ - (Alpine.314.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-amd64-20210910135833-1848e19
+ - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}:
- (Alpine.313.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.13-helix-amd64-20210910135845-8a6f4f3
# Linux musl arm64
- - ${{ if and(eq(parameters.platform, 'Linux_musl_arm64'), or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true))) }}:
+ - ${{ if and(eq(parameters.platform, 'Linux_musl_arm64'), eq(parameters.jobParameters.isFullMatrix, true)) }}:
- (Alpine.313.Arm64.Open)ubuntu.1804.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.13-helix-arm64v8-20210910135808-8a6f4f3
- (Alpine.314.Arm64.Open)ubuntu.1804.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-arm64v8-20210910135810-8a6f4f3
@@ -68,16 +62,21 @@ jobs:
- (Ubuntu.2110.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-21.10-helix-amd64-20211116135132-0f8d97e
- (Debian.10.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-bfcd90a-20200121150006
- ${{ if or(ne(parameters.jobParameters.testScope, 'outerloop'), ne(parameters.jobParameters.runtimeFlavor, 'mono')) }}:
- - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- - (Centos.8.Amd64.Open)Ubuntu.1604.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-8-helix-20201229003624-c1bf759
+ - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}:
+ - (Centos.7.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-mlnet-helix-20210714125435-dde38af
+ - (Centos.8.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-8-helix-20201229003624-c1bf759
+ - RedHat.7.Amd64.Open
+ - Ubuntu.1804.Amd64.Open
+ - SLES.12.Amd64.Open
- SLES.15.Amd64.Open
- - (Fedora.34.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-34-helix-20210913123654-4f64125
- - (Ubuntu.2110.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-21.04-helix-amd64-20210922170909-34a2d72
+ - (Fedora.34.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-34-helix-20210913123654-4f64125
+ - (Ubuntu.2110.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-21.10-helix-amd64-20211116135132-0f8d97e
+ - (Debian.10.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-20210304164434-56c6673
- (Debian.11.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64-20210304164428-5a7c380
- - (Mariner.1.0.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-1.0-helix-20210528192219-92bf620
- - (openSUSE.15.2.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:opensuse-15.2-helix-amd64-20211018152525-9cc02fe
- - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- - (Centos.7.Amd64.Open)Ubuntu.1604.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-mlnet-helix-20210714125435-dde38af
+ - (Mariner.1.0.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-1.0-helix-20210528192219-92bf620
+ - (openSUSE.15.2.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:opensuse-15.2-helix-amd64-20211018152525-9cc02fe
+ - ${{ if eq(parameters.jobParameters.isFullMatrix, false) }}:
+ - (Centos.7.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-mlnet-helix-20210714125435-dde38af
- RedHat.7.Amd64.Open
- (Debian.10.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-20210304164434-56c6673
- Ubuntu.1804.Amd64.Open
@@ -95,9 +94,10 @@ jobs:
# OSX x64
- ${{ if eq(parameters.platform, 'OSX_x64') }}:
- - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
+ - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}:
- OSX.1014.Amd64.Open
- - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
+ - OSX.1015.Amd64.Open
+ - ${{ if eq(parameters.jobParameters.isFullMatrix, false) }}:
- OSX.1015.Amd64.Open
# Android
@@ -126,18 +126,18 @@ jobs:
- ${{ if eq(parameters.platform, 'windows_x64') }}:
# netcoreapp
- ${{ if notIn(parameters.jobParameters.framework, 'net48') }}:
- # libraries on mono outerloop
- ${{ if and(eq(parameters.jobParameters.testScope, 'outerloop'), eq(parameters.jobParameters.runtimeFlavor, 'mono')) }}:
- Windows.81.Amd64.Open
- Windows.10.Amd64.Server19H1.Open
- # libraries on coreclr (outerloop and innerloop), or libraries on mono innerloop
- ${{ if or(ne(parameters.jobParameters.testScope, 'outerloop'), ne(parameters.jobParameters.runtimeFlavor, 'mono')) }}:
- - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
+ - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}:
+ - Windows.81.Amd64.Open
- Windows.10.Amd64.ServerRS5.Open
- - ${{ if ne(parameters.jobParameters.testScope, 'outerloop') }}:
- - Windows.10.Amd64.Server19H1.Open
+ - Windows.10.Amd64.Server19H1.Open
+ - ${{ if ne(parameters.jobParameters.runtimeFlavor, 'mono') }}:
+ - (Windows.Nano.1809.Amd64.Open)windows.10.amd64.serverrs5.open@mcr.microsoft.com/dotnet-buildtools/prereqs:nanoserver-1809-helix-amd64-08e8e40-20200107182504
- (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h1.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-amd64-20200904200251-272704c
- - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
+ - ${{ if ne(parameters.jobParameters.isFullMatrix, true) }}:
- Windows.81.Amd64.Open
- Windows.10.Amd64.Server19H1.ES.Open
- Windows.11.Amd64.ClientPre.Open
@@ -154,18 +154,20 @@ jobs:
- ${{ if eq(parameters.platform, 'windows_x86') }}:
# netcoreapp
- ${{ if notIn(parameters.jobParameters.framework, 'net48') }}:
- # mono outerloop
- ${{ if and(eq(parameters.jobParameters.testScope, 'outerloop'), eq(parameters.jobParameters.runtimeFlavor, 'mono')) }}:
- Windows.7.Amd64.Open
- Windows.10.Amd64.ServerRS5.Open
- # libraries on coreclr (outerloop and innerloop), or libraries on mono innerloop
- ${{ if or(ne(parameters.jobParameters.testScope, 'outerloop'), ne(parameters.jobParameters.runtimeFlavor, 'mono')) }}:
- - ${{ if or(eq(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
+ - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}:
+ - Windows.7.Amd64.Open
- Windows.10.Amd64.ServerRS5.Open
- Windows.10.Amd64.Server19H1.Open
- - ${{ if or(ne(parameters.jobParameters.isExtraPlatforms, true), eq(parameters.jobParameters.includeAllPlatforms, true)) }}:
- - Windows.10.Amd64.Server19H1.ES.Open
- - Windows.7.Amd64.Open
+ - ${{ if ne(parameters.jobParameters.isFullMatrix, true) }}:
+ - ${{ if eq(parameters.jobParameters.buildConfig, 'Release') }}:
+ - Windows.10.Amd64.Server19H1.ES.Open
+ - ${{ if eq(parameters.jobParameters.buildConfig, 'Debug') }}:
+ - Windows.7.Amd64.Open
+ - Windows.10.Amd64.Server19H1.Open
# .NETFramework
- ${{ if eq(parameters.jobParameters.framework, 'net48') }}:
diff --git a/eng/pipelines/libraries/outerloop-mono.yml b/eng/pipelines/libraries/outerloop-mono.yml
index 17a7101e26004..1267cf72a62de 100644
--- a/eng/pipelines/libraries/outerloop-mono.yml
+++ b/eng/pipelines/libraries/outerloop-mono.yml
@@ -23,7 +23,7 @@ jobs:
platforms:
- windows_x86
- Browser_wasm
- - ${{ if eq(variables['isRollingBuild'], true) }}:
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
- windows_x64
- Linux_x64
- Linux_arm
@@ -34,7 +34,7 @@ jobs:
nameSuffix: AllSubsets_Mono
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) -testscope outerloop /p:ArchiveTests=true
timeoutInMinutes: 180
- includeAllPlatforms: ${{ variables['isRollingBuild'] }}
+ isFullMatrix: ${{ variables['isFullMatrix'] }}
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -44,7 +44,7 @@ jobs:
creator: dotnet-bot
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
- - ${{ if eq(variables['isRollingBuild'], false) }}:
+ - ${{ if eq(variables['isFullMatrix'], false) }}:
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
@@ -61,7 +61,7 @@ jobs:
nameSuffix: AllSubsets_Mono
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) -testscope outerloop /p:ArchiveTests=true
timeoutInMinutes: 180
- includeAllPlatforms: ${{ variables['isRollingBuild'] }}
+ isFullMatrix: ${{ variables['isFullMatrix'] }}
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
diff --git a/eng/pipelines/libraries/outerloop.yml b/eng/pipelines/libraries/outerloop.yml
index 72c2de49363a2..28932a0baff3c 100644
--- a/eng/pipelines/libraries/outerloop.yml
+++ b/eng/pipelines/libraries/outerloop.yml
@@ -27,7 +27,7 @@ jobs:
- ${{ if eq(variables['includeLinuxOuterloop'], true) }}:
- Linux_x64
- Linux_musl_x64
- - ${{ if eq(variables['isRollingBuild'], true) }}:
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
- Linux_arm
- Linux_arm64
- Linux_musl_arm64
@@ -46,27 +46,27 @@ jobs:
platforms:
- ${{ if eq(variables['includeWindowsOuterloop'], true) }}:
- windows_x86
- - ${{ if eq(variables['isRollingBuild'], true) }}:
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
- windows_x64
- ${{ if eq(variables['includeLinuxOuterloop'], true) }}:
- - ${{ if eq(variables['isRollingBuild'], true) }}:
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
- Linux_x64
- Linux_arm
- Linux_arm64
- Linux_musl_x64
- Linux_musl_arm64
- - ${{ if and(eq(variables['includeOsxOuterloop'], true), eq(variables['isRollingBuild'], true)) }}:
+ - ${{ if and(eq(variables['includeOsxOuterloop'], true), eq(variables['isFullMatrix'], true)) }}:
- OSX_arm64
- OSX_x64
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
isOfficialBuild: ${{ variables['isOfficialBuild'] }}
- includeAllPlatforms: ${{ variables['isRollingBuild'] }}
+ isFullMatrix: ${{ variables['isFullMatrix'] }}
runTests: true
testScope: outerloop
liveRuntimeBuildConfig: release
- - ${{ if eq(variables['isRollingBuild'], false) }}:
+ - ${{ if eq(variables['isFullMatrix'], false) }}:
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/libraries/build-job.yml
@@ -83,7 +83,7 @@ jobs:
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
isOfficialBuild: ${{ variables['isOfficialBuild'] }}
- includeAllPlatforms: ${{ variables['isRollingBuild'] }}
+ isFullMatrix: ${{ variables['isFullMatrix'] }}
runTests: true
testScope: outerloop
liveRuntimeBuildConfig: release
@@ -95,12 +95,12 @@ jobs:
buildConfig: Release
platforms:
- windows_x86
- - ${{ if eq(variables['isRollingBuild'], true) }}:
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
- windows_x64
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
isOfficialBuild: ${{ variables['isOfficialBuild'] }}
- includeAllPlatforms: ${{ variables['isRollingBuild'] }}
+ isFullMatrix: ${{ variables['isFullMatrix'] }}
framework: net48
runTests: true
testScope: outerloop
diff --git a/eng/pipelines/libraries/run-test-job.yml b/eng/pipelines/libraries/run-test-job.yml
index 0f2070a49bfbf..d864487760908 100644
--- a/eng/pipelines/libraries/run-test-job.yml
+++ b/eng/pipelines/libraries/run-test-job.yml
@@ -191,8 +191,4 @@ jobs:
- fullpgo_random_gdv
- fullpgo_random_edge
- fullpgo_random_gdv_edge
- - jitosr
- - jitosr_stress
- - jitosr_stress_random
- - jitosr_pgo
diff --git a/eng/pipelines/libraries/variables.yml b/eng/pipelines/libraries/variables.yml
index 2abd5adabe2c9..9bb89d7d49384 100644
--- a/eng/pipelines/libraries/variables.yml
+++ b/eng/pipelines/libraries/variables.yml
@@ -6,7 +6,7 @@ variables:
value: $(Build.SourcesDirectory)/src/libraries
- name: pipelinesPath
value: /eng/pipelines/libraries
- - name: isRollingBuild
+ - name: isFullMatrix
value: ${{ notIn(variables['Build.Reason'], 'PullRequest') }}
- name: includeWindowsOuterloop
value: ${{ or(endsWith(variables['Build.DefinitionName'], 'windows'), endsWith(variables['Build.DefinitionName'], 'outerloop')) }}
diff --git a/eng/pipelines/runtime-community.yml b/eng/pipelines/runtime-community.yml
index f588ad52b0f33..5bebcc00a2663 100644
--- a/eng/pipelines/runtime-community.yml
+++ b/eng/pipelines/runtime-community.yml
@@ -46,7 +46,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -56,4 +56,4 @@ jobs:
or(
eq(variables['librariesContainsChange'], true),
eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
diff --git a/eng/pipelines/runtime-extra-platforms.yml b/eng/pipelines/runtime-manual.yml
similarity index 59%
rename from eng/pipelines/runtime-extra-platforms.yml
rename to eng/pipelines/runtime-manual.yml
index a0642f4ab521c..997849ed2b86c 100644
--- a/eng/pipelines/runtime-extra-platforms.yml
+++ b/eng/pipelines/runtime-manual.yml
@@ -1,217 +1,295 @@
-# This pipeline includes the platforms that we don't have resources to run on every PR but that we want
-# to still have test coverage, we run this pipeline on a schedule and also developers can run it
-# via /azp run command on PRs. This pipeline permits us to have the main runtime pipeline run the same
-# platforms in PRs and Scheduled builds.
-
-# Setting batch to true, triggers one build at a time.
-# if there is a push while a build in progress, it will wait,
-# until the running build finishes, and produce a build with all the changes
-# that happened during the last build.
trigger: none
-schedules:
- - cron: "0 9,21 * * *" # run at 9:00 and 21:00 (UTC) which is 1:00 and 13:00 (PST).
- displayName: Runtime extra main schedule
- branches:
- include:
- - main
- always: false # run only if there were changes since the last successful scheduled run.
- - cron: "0 6,18 * * *" # run at 6:00 and 18:00 (UTC) which is 22:00 and 10:00 (PST).
- displayName: Runtime extra release schedule
- branches:
- include:
- - release/*
- always: false # run only if there were changes since the last successful scheduled run.
-
variables:
- template: /eng/pipelines/common/variables.yml
jobs:
#
-# Evaluate paths
+# iOS/tvOS interp - requires AOT Compilation and Interp flags
+# Build the whole product using Mono and run libraries tests
#
-- ${{ if eq(variables.dependOnEvaluatePaths, true) }}:
- - template: /eng/pipelines/common/evaluate-default-paths.yml
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: mono
+ platforms:
+ - iOSSimulator_x64
+ - tvOSSimulator_x64
+ - iOSSimulator_arm64
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildDarwinFrameworks=true
+ timeoutInMinutes: 180
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ interpreter: true
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
#
-# Build CoreCLR release
-# Always as they are needed by Installer and we always build and test the Installer.
+# MacCatalyst interp - requires AOT Compilation and Interp flags
+# Build the whole product using Mono and run libraries tests
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
- jobTemplate: /eng/pipelines/coreclr/templates/build-job.yml
- buildConfig: release
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: mono
platforms:
- - Linux_x64
- - Linux_arm
- - Linux_arm64
- - Linux_musl_x64
- - OSX_x64
- - windows_x64
- - windows_x86
- - windows_arm64
+ - MacCatalyst_x64
+ # don't run tests on arm64 PRs until we can get significantly more devices
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
+ - MacCatalyst_arm64
jobParameters:
testGroup: innerloop
+ nameSuffix: AllSubsets_Mono
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=adhoc /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildDarwinFrameworks=true
+ timeoutInMinutes: 180
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ interpreter: true
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
#
-# Build libraries using live CoreLib
+# MacCatalyst interp - requires AOT Compilation and Interp flags
+# Build the whole product using Mono and run libraries tests
+# The test app is built with the App Sandbox entitlement
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
- jobTemplate: /eng/pipelines/libraries/build-job.yml
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: Release
+ runtimeFlavor: mono
platforms:
- - Linux_x64
- - Linux_arm
- - Linux_arm64
- - Linux_musl_x64
- - OSX_x64
- - windows_x64
- - windows_x86
- - windows_arm64
+ - MacCatalyst_x64
+ # don't run tests on arm64 PRs until we can get significantly more devices
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
+ - MacCatalyst_arm64
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono_AppSandbox
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=adhoc /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildDarwinFrameworks=true /p:EnableAppSandbox=true
+ timeoutInMinutes: 180
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ interpreter: true
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
#
-# Libraries Release Test Execution against a release coreclr runtime
-# Only when the PR contains a libraries change
+# iOS/tvOS devices - Full AOT + AggressiveTrimming to reduce size
+# Build the whole product using Mono and run libraries tests
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
- jobTemplate: /eng/pipelines/libraries/run-test-job.yml
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: Release
+ runtimeFlavor: mono
platforms:
- - Linux_x64
- - Linux_arm
- - Linux_arm64
- - Linux_musl_x64
- - OSX_x64
- - windows_x64
- - windows_x86
- - windows_arm64
+ - iOS_arm64
+ - tvOS_arm64
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono
+ buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:BuildTestsOnHelix=true /p:UsePortableRuntimePack=true /p:BuildDarwinFrameworks=true
+ timeoutInMinutes: 180
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true
+
+#
+# Build the whole product using Mono and run libraries tests
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: mono
+ platforms:
+ - Android_x86
+ - Android_x64
jobParameters:
- isOfficialBuild: false
- isExtraPlatforms: ${{ variables.isExtraPlatformsBuild }}
- testScope: innerloop
- liveRuntimeBuildConfig: release
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg)
+ timeoutInMinutes: 180
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
-# Run net48 tests on win-x64
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
- jobTemplate: /eng/pipelines/libraries/build-job.yml
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: Release
+ runtimeFlavor: mono
platforms:
- - windows_x64
+ - Android_arm
+ - Android_arm64
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg)
+ timeoutInMinutes: 180
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+
+#
+# Build the whole product using Mono and run libraries tests
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: mono
+ platforms:
+ - Windows_x64
jobParameters:
- framework: net48
- runTests: true
testScope: innerloop
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(variables['isRollingBuild'], true))
-
-#### MONO LEGS
+ nameSuffix: AllSubsets_Mono
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true
+ timeoutInMinutes: 120
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
#
-# Build the whole product using Mono and run libraries tests, for Wasm.Build.Tests
+# Build the whole product using Mono for Android and run runtime tests with interpreter
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
- helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
buildConfig: Release
runtimeFlavor: mono
platforms:
- # BuildWasmApps should only happen on the extra platforms build as we already have coverage for this build on PRs.
- - Browser_wasm
- - Browser_wasm_win
+ - Android_x64
variables:
- # map dependencies variables to local variables
- - name: wasmbuildtestsContainsChange
- value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'] ]
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: pr/dotnet/runtime/$(Build.SourceBranch)
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: ci/dotnet/runtime/$(Build.SourceBranch)
+ - name: timeoutPerTestInMinutes
+ value: 60
+ - name: timeoutPerTestCollectionInMinutes
+ value: 180
jobParameters:
- isExtraPlatforms: ${{ variables.isExtraPlatformsBuild }}
testGroup: innerloop
- nameSuffix: WasmBuildTests
- buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmBuildTests=true /p:TestAssemblies=false /p:BrowserHost=$(_hostedOs)
- timeoutInMinutes: 180
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ nameSuffix: AllSubsets_Mono_RuntimeTests_Interp
+ buildArgs: -s mono+libs -c $(_BuildConfig)
+ timeoutInMinutes: 240
+ runtimeVariant: monointerpreter
# extra steps, run tests
- extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml
extraStepsParameters:
creator: dotnet-bot
- testRunNamePrefixSuffix: Mono_$(_BuildConfig)_$(_hostedOs)
- extraHelixArguments: /p:BrowserHost=$(_hostedOs)
- scenarios:
- - buildwasmapps
- condition: >-
- or(
- eq(variables['wasmbuildtestsContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
#
-# Build Browser_wasm, on windows, run console and browser tests
+# Build the whole product using Mono and run runtime tests with the JIT.
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
- helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
- buildConfig: release
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
+ buildConfig: Release
runtimeFlavor: mono
platforms:
- - Browser_wasm_win
+ - iOSSimulator_x64
variables:
- # map dependencies variables to local variables
- - name: librariesContainsChange
- value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
- - name: monoContainsChange
- value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: pr/dotnet/runtime/$(Build.SourceBranch)
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: ci/dotnet/runtime/$(Build.SourceBranch)
+ - name: timeoutPerTestInMinutes
+ value: 60
+ - name: timeoutPerTestCollectionInMinutes
+ value: 180
jobParameters:
testGroup: innerloop
- nameSuffix: LibraryTests
- buildArgs: -subset mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=windows
- timeoutInMinutes: 180
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ nameSuffix: AllSubsets_Mono_RuntimeTests
+ buildArgs: -s mono+libs -c $(_BuildConfig)
+ timeoutInMinutes: 240
# extra steps, run tests
- extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml
extraStepsParameters:
creator: dotnet-bot
- testRunNamePrefixSuffix: Windows_wasm_$(_BuildConfig)
- extraHelixArguments: /p:BrowserHost=windows
- scenarios:
- - normal
- - wasmtestonbrowser
- condition: >-
- or(
- eq(variables['librariesContainsChange'], true),
- eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
#
-# Build for Browser/wasm, with EnableAggressiveTrimming=true
+# Build the whole product using Mono for Android and run runtime tests with Android devices
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
- helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
buildConfig: Release
runtimeFlavor: mono
platforms:
- - Browser_wasm
+ - Android_arm64
+ variables:
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: pr/dotnet/runtime/$(Build.SourceBranch)
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: ci/dotnet/runtime/$(Build.SourceBranch)
+ - name: timeoutPerTestInMinutes
+ value: 60
+ - name: timeoutPerTestCollectionInMinutes
+ value: 180
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono_RuntimeTests
+ buildArgs: -s mono+libs -c $(_BuildConfig)
+ timeoutInMinutes: 240
+ # don't run tests on PRs until we can get significantly more devices
+ # Turn off the testing for now, until https://github.com/dotnet/xharness/issues/663 gets resolved
+ # ${{ if eq(variables['isFullMatrix'], true) }}:
+ # # extra steps, run tests
+ # extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml
+ # extraStepsParameters:
+ # creator: dotnet-bot
+ # testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+
+#
+# Build Browser_wasm, on windows, run console and browser tests
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: release
+ runtimeFlavor: mono
+ platforms:
+ - Browser_wasm_win
variables:
# map dependencies variables to local variables
- name: librariesContainsChange
@@ -219,86 +297,78 @@ jobs:
- name: monoContainsChange
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
jobParameters:
- isExtraPlatforms: ${{ variables.isExtraPlatformsBuild }}
testGroup: innerloop
- nameSuffix: LibraryTests_EAT
- buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=false
+ nameSuffix: Windows_wasm
+ buildArgs: -subset mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=windows
timeoutInMinutes: 180
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
creator: dotnet-bot
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
- extraHelixArguments: /p:NeedsToBuildWasmAppsOnHelix=true $(_runSmokeTestsOnlyArg)
+ extraHelixArguments: /p:BrowserHost=windows
scenarios:
- normal
+ - WasmTestOnBrowser
+ - WasmTestOnNodeJs
condition: >-
or(
eq(variables['librariesContainsChange'], true),
eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
-#
-# Build for Browser/wasm with RunAOTCompilation=true
-#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
- buildConfig: Release
+ buildConfig: release
runtimeFlavor: mono
platforms:
- - Browser_wasm
- Browser_wasm_win
variables:
# map dependencies variables to local variables
- - name: librariesContainsChange
- value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
- - name: monoContainsChange
- value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
+ - name: wasmbuildtestsContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'] ]
jobParameters:
- isExtraPlatforms: ${{ variables.isExtraPlatformsBuild }}
testGroup: innerloop
- nameSuffix: LibraryTests_AOT
- buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=true /p:BrowserHost=$(_hostedOs)
+ nameSuffix: Windows_wasm_WBT
+ buildArgs: -subset mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=windows /p:TestWasmBuildTests=true /p:TestAssemblies=false
timeoutInMinutes: 180
condition: >-
or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
creator: dotnet-bot
- testRunNamePrefixSuffix: Mono_AOT_$(_BuildConfig)_$(_hostedOs)
- extraHelixArguments: /p:NeedsToBuildWasmAppsOnHelix=true $(_runSmokeTestsOnlyArg) /p:BrowserHost=$(_hostedOs)
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ extraHelixArguments: /p:BrowserHost=windows
scenarios:
- - normal
+ - buildwasmapps
condition: >-
or(
- eq(variables['librariesContainsChange'], true),
- eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['wasmbuildtestsContainsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
-#
-# Build the whole product using Mono and run libraries tests
-#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
- buildConfig: Release
+ buildConfig: release
runtimeFlavor: mono
platforms:
- - Windows_x64
+ - Browser_wasm_win
variables:
# map dependencies variables to local variables
- name: librariesContainsChange
@@ -306,30 +376,34 @@ jobs:
- name: monoContainsChange
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
jobParameters:
- testScope: innerloop
- nameSuffix: AllSubsets_Mono
- buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true
- timeoutInMinutes: 120
+ testGroup: innerloop
+ nameSuffix: Windows_wasm_AOT
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=windows /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg)
+ timeoutInMinutes: 180
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
creator: dotnet-bot
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ extraHelixArguments: /p:BrowserHost=windows /p:NeedsToBuildWasmAppsOnHelix=true $(_runSmokeTestsOnlyArg)
+ scenarios:
+ - normal
condition: >-
or(
eq(variables['librariesContainsChange'], true),
eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
#
-# iOS/tvOS devices - Full AOT + AggressiveTrimming to reduce size
-# Build the whole product using Mono and run libraries tests
+# Build for Browser/wasm, with EnableAggressiveTrimming=true
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -338,8 +412,7 @@ jobs:
buildConfig: Release
runtimeFlavor: mono
platforms:
- - iOS_arm64
- - tvOS_arm64
+ - Browser_wasm
variables:
# map dependencies variables to local variables
- name: librariesContainsChange
@@ -348,26 +421,21 @@ jobs:
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
jobParameters:
testGroup: innerloop
- nameSuffix: AllSubsets_Mono
- buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:UsePortableRuntimePack=true /p:BuildDarwinFrameworks=true
+ nameSuffix: AllSubsets_Mono_EAT
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=false /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=false
timeoutInMinutes: 180
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
creator: dotnet-bot
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
- extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true
- condition: >-
- or(
- eq(variables['librariesContainsChange'], true),
- eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ extraHelixArguments: /p:NeedsToBuildWasmAppsOnHelix=true /p:RunSmokeTestsOnly=false
+ scenarios:
+ - normal
+#
+# Build for Browser/wasm with RunAOTCompilation=true
+#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
@@ -375,8 +443,7 @@ jobs:
buildConfig: Release
runtimeFlavor: mono
platforms:
- - Android_arm
- - Android_arm64
+ - Browser_wasm
variables:
# map dependencies variables to local variables
- name: librariesContainsChange
@@ -385,24 +452,17 @@ jobs:
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
jobParameters:
testGroup: innerloop
- nameSuffix: AllSubsets_Mono
- buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg)
+ nameSuffix: AllSubsets_Mono_AOT
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=false /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=true
timeoutInMinutes: 180
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
creator: dotnet-bot
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
- condition: >-
- or(
- eq(variables['librariesContainsChange'], true),
- eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ extraHelixArguments: /p:NeedsToBuildWasmAppsOnHelix=true /p:RunSmokeTestsOnly=false
+ scenarios:
+ - normal
#
# Build for Browser/wasm and test it on v8, browser, and nodejs
@@ -417,6 +477,8 @@ jobs:
- Browser_wasm
variables:
# map dependencies variables to local variables
+ - name: librariesContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
- name: monoContainsChange
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
jobParameters:
@@ -426,8 +488,8 @@ jobs:
timeoutInMinutes: 180
condition: >-
or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -439,46 +501,44 @@ jobs:
- WasmTestOnNodeJs
condition: >-
or(
+ eq(variables['librariesContainsChange'], true),
eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
#
# Build the whole product using Mono and run runtime tests
-# Build Mono release
-# Only when libraries, mono, or the runtime tests changed
-# Currently only these architectures are needed for the runtime tests.
-- template: /eng/pipelines/common/platform-matrix.yml
- parameters:
- jobTemplate: /eng/pipelines/mono/templates/build-job.yml
- runtimeFlavor: mono
- buildConfig: release
- platforms:
- - Linux_arm64
- jobParameters:
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
-
#
-# Mono Test builds with CoreCLR runtime tests using live libraries debug build
-# Only when Mono is changed
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
- jobTemplate: /eng/pipelines/common/templates/runtimes/build-test-job.yml
- buildConfig: release
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
+ buildConfig: Release
runtimeFlavor: mono
platforms:
- - CoreClrTestBuildHost # Either OSX_x64 or Linux_x64
+ - Browser_wasm
+ variables:
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: pr/dotnet/runtime/$(Build.SourceBranch)
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: ci/dotnet/runtime/$(Build.SourceBranch)
+ - name: timeoutPerTestInMinutes
+ value: 10
+ - name: timeoutPerTestCollectionInMinutes
+ value: 200
jobParameters:
testGroup: innerloop
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ nameSuffix: AllSubsets_Mono_RuntimeTests
+ buildArgs: -s mono+libs -c $(_BuildConfig)
+ timeoutInMinutes: 180
+ # NOTE: Per PR test execution is not recommended for mobile runtime tests
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/common/templates/runtimes/wasm-runtime-and-send-to-helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
# Wasm debugger tests
- template: /eng/pipelines/common/platform-matrix.yml
@@ -501,7 +561,8 @@ jobs:
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -525,13 +586,14 @@ jobs:
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'] ]
jobParameters:
testGroup: innerloop
- nameSuffix: Mono_DebuggerTests
+ nameSuffix: Windows_wasm_DebuggerTests
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false /p:BrowserHost=windows
timeoutInMinutes: 180
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -568,100 +630,9 @@ jobs:
nameSuffix: AllSubsets_Mono_RuntimeTests
buildArgs: -s mono+libs -c $(_BuildConfig)
timeoutInMinutes: 240
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ # NOTE: Per PR test execution is not recommended for mobile runtime tests
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml
extraStepsParameters:
creator: dotnet-bot
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
-
-#
-# Build the whole product using Mono for Android and run runtime tests with interpreter
-#
-- template: /eng/pipelines/common/platform-matrix.yml
- parameters:
- jobTemplate: /eng/pipelines/common/global-build-job.yml
- helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
- buildConfig: Release
- runtimeFlavor: mono
- platforms:
- - Android_x64
- variables:
- - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
- - name: _HelixSource
- value: pr/dotnet/runtime/$(Build.SourceBranch)
- - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}:
- - name: _HelixSource
- value: ci/dotnet/runtime/$(Build.SourceBranch)
- - name: timeoutPerTestInMinutes
- value: 60
- - name: timeoutPerTestCollectionInMinutes
- value: 180
- jobParameters:
- testGroup: innerloop
- nameSuffix: AllSubsets_Mono_RuntimeTests_Interp
- buildArgs: -s mono+libs -c $(_BuildConfig)
- timeoutInMinutes: 240
- runtimeVariant: monointerpreter
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
- # NOTE: Per PR test execution is not recommended for runtime tests
- ${{ if eq(variables['isRollingBuild'], true) }}:
- # extra steps, run tests
- extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml
- extraStepsParameters:
- creator: dotnet-bot
- testRunNamePrefixSuffix: Mono_$(_BuildConfig)
-
-#
-# Mono CoreCLR runtime Test executions using live libraries in jit mode
-# Only when Mono is changed
-- template: /eng/pipelines/common/platform-matrix.yml
- parameters:
- jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml
- buildConfig: release
- runtimeFlavor: mono
- platforms:
- - Linux_arm64
- helixQueueGroup: pr
- helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
- jobParameters:
- testGroup: innerloop
- liveLibrariesBuildConfig: Release
- liveRuntimeBuildConfig: release
- runtimeVariant: minijit
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
-
-#
-# Mono CoreCLR runtime Test executions using live libraries in interpreter mode
-# Only when Mono is changed
-- template: /eng/pipelines/common/platform-matrix.yml
- parameters:
- jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml
- buildConfig: release
- runtimeFlavor: mono
- platforms:
- - Linux_arm64
- helixQueueGroup: pr
- helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
- jobParameters:
- testGroup: innerloop
- liveLibrariesBuildConfig: Release
- liveRuntimeBuildConfig: release
- runtimeVariant: monointerpreter
- condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml
index 1ad7ad72d3171..34b0ae68c78e2 100644
--- a/eng/pipelines/runtime-official.yml
+++ b/eng/pipelines/runtime-official.yml
@@ -416,7 +416,7 @@ stages:
- Build_Android_arm64_release_AllSubsets_Mono
- Build_Android_x86_release_AllSubsets_Mono
- Build_Android_x64_release_AllSubsets_Mono
- - Build_Browser_wasm_Linux_release_AllSubsets_Mono
+ - Build_Browser_wasm_release_AllSubsets_Mono
- Build_iOS_arm_release_AllSubsets_Mono
- Build_iOS_arm64_release_AllSubsets_Mono
- Build_iOSSimulator_x64_release_AllSubsets_Mono
diff --git a/eng/pipelines/runtime-staging.yml b/eng/pipelines/runtime-staging.yml
index c51d639d29f0f..4288d372433df 100644
--- a/eng/pipelines/runtime-staging.yml
+++ b/eng/pipelines/runtime-staging.yml
@@ -75,7 +75,7 @@ jobs:
- iOSSimulator_x64
- tvOSSimulator_x64
# don't run tests on arm64 PRs until we can get significantly more devices
- - ${{ if eq(variables['isRollingBuild'], true) }}:
+ - ${{ if eq(variables['isManualOrIsNotPR'], true) }}:
- iOSSimulator_arm64
variables:
# map dependencies variables to local variables
@@ -93,7 +93,8 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -104,7 +105,8 @@ jobs:
or(
eq(variables['librariesContainsChange'], true),
eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
#
# MacCatalyst interp - requires AOT Compilation and Interp flags
@@ -119,7 +121,7 @@ jobs:
platforms:
- MacCatalyst_x64
# don't run tests on arm64 PRs until we can get significantly more devices
- - ${{ if eq(variables['isRollingBuild'], true) }}:
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
- MacCatalyst_arm64
variables:
# map dependencies variables to local variables
@@ -137,7 +139,8 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -146,9 +149,10 @@ jobs:
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
condition: >-
or(
- eq(variables['librariesContainsChange'], true),
- eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['monoContainsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
#
# MacCatalyst interp - requires AOT Compilation and Interp flags
@@ -164,7 +168,7 @@ jobs:
platforms:
- MacCatalyst_x64
# don't run tests on arm64 PRs until we can get significantly more devices
- - ${{ if eq(variables['isRollingBuild'], true) }}:
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
- MacCatalyst_arm64
variables:
# map dependencies variables to local variables
@@ -181,7 +185,8 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -190,9 +195,53 @@ jobs:
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
condition: >-
or(
- eq(variables['librariesContainsChange'], true),
- eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['monoContainsChange'], true),
+ eq(variables['isFullMatrix'], true))
+
+#
+# iOS/tvOS devices - Full AOT + AggressiveTrimming to reduce size
+# Build the whole product using Mono and run libraries tests
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: mono
+ platforms:
+ - iOS_arm64
+ - tvOS_arm64
+ variables:
+ # map dependencies variables to local variables
+ - name: librariesContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
+ - name: monoContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono
+ buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:UsePortableRuntimePack=true /p:BuildDarwinFrameworks=true
+ timeoutInMinutes: 180
+ condition: >-
+ or(
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ extraHelixArguments: /p:NeedsToBuildAppsOnHelix=true
+ condition: >-
+ or(
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['monoContainsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
#
# Build the whole product using Mono and run libraries tests
@@ -222,7 +271,8 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -232,7 +282,47 @@ jobs:
or(
eq(variables['librariesContainsChange'], true),
eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
+
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: mono
+ platforms:
+ - Android_arm
+ - Android_arm64
+ variables:
+ # map dependencies variables to local variables
+ - name: librariesContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
+ - name: monoContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg)
+ timeoutInMinutes: 180
+ condition: >-
+ or(
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ condition: >-
+ or(
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['monoContainsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
#
# Build the whole product using Mono and run libraries tests
@@ -244,7 +334,7 @@ jobs:
buildConfig: Release
runtimeFlavor: mono
platforms:
- - Linux_armv6
+ - Windows_x64
variables:
# map dependencies variables to local variables
- name: librariesContainsChange
@@ -254,17 +344,65 @@ jobs:
jobParameters:
testScope: innerloop
nameSuffix: AllSubsets_Mono
- buildArgs: -s mono+clr+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true
timeoutInMinutes: 120
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
- ${{ if eq(variables['isRollingBuild'], true) }}:
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ condition: >-
+ or(
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['monoContainsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
+
+#
+# Build the whole product using Mono for Android and run runtime tests with interpreter
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
+ buildConfig: Release
+ runtimeFlavor: mono
+ platforms:
+ - Android_x64
+ variables:
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: pr/dotnet/runtime/$(Build.SourceBranch)
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: ci/dotnet/runtime/$(Build.SourceBranch)
+ - name: timeoutPerTestInMinutes
+ value: 60
+ - name: timeoutPerTestCollectionInMinutes
+ value: 180
+ jobParameters:
+ testGroup: innerloop
+ nameSuffix: AllSubsets_Mono_RuntimeTests_Interp
+ buildArgs: -s mono+libs -c $(_BuildConfig)
+ timeoutInMinutes: 240
+ runtimeVariant: monointerpreter
+ condition: >-
+ or(
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
+ # NOTE: Per PR test execution is not recommended for runtime tests
+ ${{ if eq(variables['isManualOrIsNotPR'], true) }}:
# extra steps, run tests
- extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml
extraStepsParameters:
creator: dotnet-bot
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
@@ -300,8 +438,9 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
- ${{ if eq(variables['isRollingBuild'], true) }}:
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
+ ${{ if eq(variables['isManualOrIsNotPR'], true) }}:
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml
extraStepsParameters:
@@ -309,38 +448,46 @@ jobs:
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
#
-# Build the whole product using Mono and run libraries tests, for Wasm.Build.Tests
+# Build the whole product using Mono for Android and run runtime tests with Android devices
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
- helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
buildConfig: Release
runtimeFlavor: mono
platforms:
- - Browser_wasm_win
+ - Android_arm64
variables:
- # map dependencies variables to local variables
- - name: wasmbuildtestsContainsChange
- value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'] ]
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: pr/dotnet/runtime/$(Build.SourceBranch)
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: ci/dotnet/runtime/$(Build.SourceBranch)
+ - name: timeoutPerTestInMinutes
+ value: 60
+ - name: timeoutPerTestCollectionInMinutes
+ value: 180
jobParameters:
- isExtraPlatforms: ${{ variables.isExtraPlatformsBuild }}
testGroup: innerloop
- nameSuffix: WasmBuildTests
- buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmBuildTests=true /p:TestAssemblies=false /p:BrowserHost=$(_hostedOs)
- timeoutInMinutes: 180
+ nameSuffix: AllSubsets_Mono_RuntimeTests
+ buildArgs: -s mono+libs -c $(_BuildConfig)
+ timeoutInMinutes: 240
condition: >-
- eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'], true)
- # extra steps, run tests
- extraStepsTemplate: /eng/pipelines/libraries/helix.yml
- extraStepsParameters:
- creator: dotnet-bot
- testRunNamePrefixSuffix: Mono_$(_BuildConfig)_$(_hostedOs)
- extraHelixArguments: /p:BrowserHost=$(_hostedOs)
- scenarios:
- - buildwasmapps
- condition: >-
- eq(variables['wasmbuildtestsContainsChange'], true)
+ or(
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
+ # don't run tests on PRs until we can get significantly more devices
+ # Turn off the testing for now, until https://github.com/dotnet/runtime/issues/60128 gets resolved
+ # ${{ if eq(variables['isFullMatrix'], true) }}:
+ # # extra steps, run tests
+ # extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml
+ # extraStepsParameters:
+ # creator: dotnet-bot
+ # testRunNamePrefixSuffix: Mono_$(_BuildConfig)
#
# Build Browser_wasm, on windows, run console and browser tests
@@ -361,37 +508,41 @@ jobs:
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
jobParameters:
testGroup: innerloop
- nameSuffix: LibraryTests
- buildArgs: -subset mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=windows
+ nameSuffix: Windows_wasm
+ buildArgs: -subset mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=windows $(_runSmokeTestsOnlyArg)
timeoutInMinutes: 180
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true))
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
creator: dotnet-bot
- testRunNamePrefixSuffix: Windows_wasm_$(_BuildConfig)
- extraHelixArguments: /p:BrowserHost=windows
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ extraHelixArguments: /p:BrowserHost=windows $(_runSmokeTestsOnlyArg)
scenarios:
- normal
- - wasmtestonbrowser
+ - WasmTestOnBrowser
condition: >-
or(
- eq(variables['librariesContainsChange'], true),
- eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['librariesContainsChange'], true),
+ eq(variables['monoContainsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
#
-# Build for Browser/wasm with RunAOTCompilation=true
+# Build Browser_wasm, on windows, and run tests with AOT
#
+# Disabled due to https://github.com/dotnet/runtime/issues/61721
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
- buildConfig: Release
+ buildConfig: release
runtimeFlavor: mono
platforms:
- Browser_wasm_win
@@ -402,49 +553,55 @@ jobs:
- name: monoContainsChange
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
jobParameters:
- isExtraPlatforms: ${{ variables.isExtraPlatformsBuild }}
testGroup: innerloop
- nameSuffix: LibraryTests_AOT
- buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=true /p:BrowserHost=$(_hostedOs)
+ nameSuffix: Windows_wasm_AOT
+ buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=windows /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg)
timeoutInMinutes: 180
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true))
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
creator: dotnet-bot
- testRunNamePrefixSuffix: Mono_AOT_$(_BuildConfig)_$(_hostedOs)
- extraHelixArguments: /p:NeedsToBuildWasmAppsOnHelix=true $(_runSmokeTestsOnlyArg) /p:BrowserHost=$(_hostedOs)
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ extraHelixArguments: /p:BrowserHost=windows /p:NeedsToBuildWasmAppsOnHelix=true $(_runSmokeTestsOnlyArg)
scenarios:
- normal
condition: >-
or(
eq(variables['librariesContainsChange'], true),
- eq(variables['monoContainsChange'], true))
+ eq(variables['monoContainsChange'], true),
+ eq(variables['isFullMatrix'], true))
-# Wasm debugger tests - windows
+#
+# Build Browser_wasm, on windows, and run Wasm.Build.Tests
+#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
- buildConfig: Release
+ buildConfig: release
runtimeFlavor: mono
platforms:
- Browser_wasm_win
variables:
# map dependencies variables to local variables
- - name: wasmdebuggertestsContainsChange
- value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'] ]
+ - name: wasmbuildtestsContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'] ]
jobParameters:
testGroup: innerloop
- nameSuffix: Mono_DebuggerTests
- buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false /p:BrowserHost=windows
+ nameSuffix: Windows_wasm_WBT
+ buildArgs: -subset mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:BrowserHost=windows /p:TestWasmBuildTests=true /p:TestAssemblies=false
timeoutInMinutes: 180
condition: >-
- eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true)
+ or(
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -452,7 +609,12 @@ jobs:
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
extraHelixArguments: /p:BrowserHost=windows
scenarios:
- - wasmdebuggertests
+ - buildwasmapps
+ condition: >-
+ or(
+ eq(variables['wasmbuildtestsContainsChange'], true),
+ eq(variables['isManualOrIsNotPR'], true),
+ eq(variables['isFullMatrix'], true))
# Wasm debugger tests
- template: /eng/pipelines/common/platform-matrix.yml
@@ -473,7 +635,9 @@ jobs:
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false
timeoutInMinutes: 180
condition: >-
- eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true)
+ or(
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true),
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -482,46 +646,36 @@ jobs:
scenarios:
- wasmdebuggertests
-#
-# Build the whole product using Mono for Android and run runtime tests with Android devices
-#
+# Wasm debugger tests - windows
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
- helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: Release
runtimeFlavor: mono
platforms:
- - Android_arm64
+ - Browser_wasm_win
variables:
- - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
- - name: _HelixSource
- value: pr/dotnet/runtime/$(Build.SourceBranch)
- - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}:
- - name: _HelixSource
- value: ci/dotnet/runtime/$(Build.SourceBranch)
- - name: timeoutPerTestInMinutes
- value: 60
- - name: timeoutPerTestCollectionInMinutes
- value: 180
+ # map dependencies variables to local variables
+ - name: wasmdebuggertestsContainsChange
+ value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'] ]
jobParameters:
testGroup: innerloop
- nameSuffix: AllSubsets_Mono_RuntimeTests
- buildArgs: -s mono+libs -c $(_BuildConfig)
- timeoutInMinutes: 240
+ nameSuffix: Windows_wasm_DebuggerTests
+ buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmDebuggerTests=true /p:TestAssemblies=false /p:BrowserHost=windows
+ timeoutInMinutes: 180
condition: >-
or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
- # don't run tests on PRs until we can get significantly more devices
- # Turn off the testing for now, until https://github.com/dotnet/runtime/issues/60128 gets resolved
- # ${{ if eq(variables['isRollingBuild'], true) }}:
- # # extra steps, run tests
- # extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml
- # extraStepsParameters:
- # creator: dotnet-bot
- # testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmdebuggertests.containsChange'], true),
+ eq(variables['isFullMatrix'], true))
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
+ extraHelixArguments: /p:BrowserHost=windows
+ scenarios:
+ - wasmdebuggertests
#
# CoreCLR Build for running Apple Silicon libraries-innerloop
@@ -531,7 +685,7 @@ jobs:
jobTemplate: /eng/pipelines/coreclr/templates/build-job.yml
buildConfig: release
platforms:
- - ${{ if eq(variables['isRollingBuild'], true) }}:
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
- OSX_arm64
jobParameters:
testGroup: innerloop
@@ -543,11 +697,12 @@ jobs:
jobTemplate: /eng/pipelines/libraries/build-job.yml
buildConfig: Release
platforms:
- - ${{ if eq(variables['isRollingBuild'], true) }}:
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
- OSX_arm64
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
isOfficialBuild: ${{ variables['isOfficialBuild'] }}
+ isFullMatrix: ${{ variables['isFullMatrix'] }}
runTests: true
testScope: innerloop
liveRuntimeBuildConfig: release
diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml
index 9d3bbfe477d8e..5d7f3ffde2f81 100644
--- a/eng/pipelines/runtime.yml
+++ b/eng/pipelines/runtime.yml
@@ -91,7 +91,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build the whole product using GNU compiler toolchain
@@ -114,7 +114,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build CoreCLR OSX_x64 checked
@@ -133,7 +133,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build CoreCLR release
@@ -178,7 +178,7 @@ jobs:
#
# Build CoreCLR Formatting Job
# Only when CoreCLR is changed, and only in the 'main' branch (no release branches;
-# both Rolling and PR builds).
+# both CI and PR builds).
#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -194,7 +194,7 @@ jobs:
eq(variables['System.PullRequest.TargetBranch'], 'main')),
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr_jit.containsChange'], true),
- eq(variables['isRollingBuild'], true)))
+ eq(variables['isFullMatrix'], true)))
#
# CoreCLR NativeAOT debug build and smoke tests
@@ -211,7 +211,7 @@ jobs:
testGroup: innerloop
timeoutInMinutes: 120
nameSuffix: NativeAOT
- buildArgs: -s clr.jit+clr.tools+clr.nativeaotlibs+clr.nativeaotruntime+libs -rc $(_BuildConfig) -lc Release
+ buildArgs: -s clr.jit+clr.tools+clr.nativeaotlibs+libs -rc $(_BuildConfig) -lc Release
extraStepsTemplate: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml
condition: >-
or(
@@ -233,7 +233,7 @@ jobs:
testGroup: innerloop
timeoutInMinutes: 120
nameSuffix: NativeAOT
- buildArgs: -s clr.jit+clr.tools+clr.nativeaotlibs+clr.nativeaotruntime+libs -rc $(_BuildConfig) -lc Release
+ buildArgs: -s clr.jit+clr.tools+clr.nativeaotlibs+libs -rc $(_BuildConfig) -lc Release
extraStepsTemplate: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml
condition: >-
or(
@@ -257,7 +257,7 @@ jobs:
testGroup: innerloop
timeoutInMinutes: 120
nameSuffix: NativeAOT
- buildArgs: -s clr.jit+clr.tools+clr.nativeaotlibs+clr.nativeaotruntime+libs -rc $(_BuildConfig) -lc Release
+ buildArgs: -s clr.jit+clr.tools+clr.nativeaotlibs+libs -rc $(_BuildConfig) -lc Release
extraStepsTemplate: /eng/pipelines/coreclr/nativeaot-post-build-steps.yml
condition: >-
or(
@@ -277,7 +277,7 @@ jobs:
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
# Build Mono AOT offset headers once, for consumption elsewhere
# Only when mono changed
@@ -297,7 +297,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
# Build the whole product using Mono runtime
# Only when libraries, mono or installer are changed
@@ -323,7 +323,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -343,7 +343,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build the whole product using Mono and run libraries tests, multi-scenario
@@ -364,7 +364,7 @@ jobs:
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
jobParameters:
testGroup: innerloop
- nameSuffix: LibraryTests
+ nameSuffix: AllSubsets_Mono
buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true
timeoutInMinutes: 180
condition: >-
@@ -372,7 +372,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -385,7 +385,7 @@ jobs:
or(
eq(variables['librariesContainsChange'], true),
eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build the whole product using Mono and run libraries tests, for Wasm.Build.Tests
@@ -404,13 +404,13 @@ jobs:
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'] ]
jobParameters:
testGroup: innerloop
- nameSuffix: WasmBuildTests
+ nameSuffix: AllSubsets_Mono_WasmBuildTests
buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:TestWasmBuildTests=true /p:TestAssemblies=false
timeoutInMinutes: 180
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_wasmbuildtests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -420,8 +420,8 @@ jobs:
- buildwasmapps
condition: >-
or(
- eq(variables['wasmbuildtestsContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['wasmbuildtestsContainsChange'], true),
+ eq(variables['isFullMatrix'], true))
#
# Build for Browser/wasm, with EnableAggressiveTrimming=true
@@ -442,7 +442,7 @@ jobs:
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
jobParameters:
testGroup: innerloop
- nameSuffix: LibraryTests_EAT
+ nameSuffix: AllSubsets_Mono_EAT
buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=false
timeoutInMinutes: 180
condition: >-
@@ -450,7 +450,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -463,7 +463,7 @@ jobs:
or(
eq(variables['librariesContainsChange'], true),
eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build for Browser/wasm with RunAOTCompilation=true
@@ -484,7 +484,7 @@ jobs:
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
jobParameters:
testGroup: innerloop
- nameSuffix: LibraryTests_AOT
+ nameSuffix: AllSubsets_Mono_AOT
buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAggressiveTrimming=true /p:BuildAOTTestsOnHelix=true /p:RunAOTCompilation=true
timeoutInMinutes: 180
condition: >-
@@ -492,7 +492,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
# extra steps, run tests
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
extraStepsParameters:
@@ -505,7 +505,29 @@ jobs:
or(
eq(variables['librariesContainsChange'], true),
eq(variables['monoContainsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
+
+# Build and test libraries under single-file publishing
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/global-build-job.yml
+ helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ buildConfig: Release
+ platforms:
+ - windows_x64
+ - Linux_x64
+ jobParameters:
+ testGroup: innerloop
+ isFullMatrix: ${{ variables.isFullMatrix }}
+ isSingleFile: true
+ nameSuffix: SingleFile
+ buildArgs: -s clr+libs+libs.tests -c $(_BuildConfig) /p:TestSingleFile=true /p:ArchiveTests=true
+ timeoutInMinutes: 120
+ # extra steps, run tests
+ extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsParameters:
+ creator: dotnet-bot
+ testRunNamePrefixSuffix: SingleFile_$(_BuildConfig)
#
# Build the whole product using Mono and run runtime tests
@@ -535,35 +557,49 @@ jobs:
buildArgs: -s mono+libs -c $(_BuildConfig)
timeoutInMinutes: 180
condition: >-
- or(
- eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true)
+ # NOTE: Per PR test execution is not recommended for mobile runtime tests
+ # extra steps, run tests
extraStepsTemplate: /eng/pipelines/common/templates/runtimes/wasm-runtime-and-send-to-helix.yml
extraStepsParameters:
creator: dotnet-bot
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
-# Build and test libraries under single-file publishing
+#
+# Build the whole product using Mono for Android and run runtime tests with Android emulator
+#
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
- helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
buildConfig: Release
+ runtimeFlavor: mono
platforms:
- - windows_x64
- - Linux_x64
+ - Android_x64
+ variables:
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), eq(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: pr/dotnet/runtime/$(Build.SourceBranch)
+ - ${{ if and(eq(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: _HelixSource
+ value: ci/dotnet/runtime/$(Build.SourceBranch)
+ - name: timeoutPerTestInMinutes
+ value: 60
+ - name: timeoutPerTestCollectionInMinutes
+ value: 180
jobParameters:
testGroup: innerloop
- isSingleFile: true
- nameSuffix: SingleFile
- buildArgs: -s clr+libs+libs.tests -c $(_BuildConfig) /p:TestSingleFile=true /p:ArchiveTests=true
- timeoutInMinutes: 120
+ nameSuffix: AllSubsets_Mono_RuntimeTests
+ buildArgs: -s mono+libs -c $(_BuildConfig)
+ timeoutInMinutes: 240
+ condition: >-
+ eq(variables['isFullMatrix'], true)
+ # NOTE: Per PR test execution is not recommended for mobile runtime tests
# extra steps, run tests
- extraStepsTemplate: /eng/pipelines/libraries/helix.yml
+ extraStepsTemplate: /eng/pipelines/common/templates/runtimes/android-runtime-and-send-to-helix.yml
extraStepsParameters:
creator: dotnet-bot
- testRunNamePrefixSuffix: SingleFile_$(_BuildConfig)
+ testRunNamePrefixSuffix: Mono_$(_BuildConfig)
#
# Build Mono and Installer on LLVMJIT mode
@@ -585,7 +621,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -605,7 +641,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build Mono and Installer on LLVMAOT mode
@@ -628,7 +664,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -647,7 +683,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build Mono debug
@@ -673,7 +709,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build Mono release AOT cross-compilers
@@ -704,7 +740,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -731,7 +767,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build Mono release
@@ -754,7 +790,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build Mono release
@@ -774,7 +810,7 @@ jobs:
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build Mono release with LLVM AOT
@@ -794,7 +830,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Build libraries using live CoreLib
@@ -813,6 +849,8 @@ jobs:
- windows_arm
- windows_arm64
- windows_x86
+ jobParameters:
+ liveRuntimeBuildConfig: release
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -826,12 +864,9 @@ jobs:
- OSX_x64
- windows_x64
- FreeBSD_x64
- - ${{ if eq(variables['isRollingBuild'], false) }}:
- # we need to build windows_x86 for debug on PRs in order to test
- # against a checked runtime when the PR contains coreclr changes
- - windows_x86
jobParameters:
testScope: innerloop
+ liveRuntimeBuildConfig: release
#
# Libraries Build that only run when coreclr is changed
@@ -839,7 +874,7 @@ jobs:
# and those are already built above
#
-- ${{ if eq(variables['isRollingBuild'], false) }}:
+- ${{ if eq(variables['isFullMatrix'], false) }}:
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/libraries/build-job.yml
@@ -849,24 +884,45 @@ jobs:
- Linux_musl_arm
- Linux_musl_arm64
jobParameters:
+ liveRuntimeBuildConfig: release
condition: >-
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true)
+#
+# Libraries Build that only run when libraries is changed
+#
+- template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/libraries/build-job.yml
+ buildConfig: ${{ variables.debugOnPrReleaseOnRolling }}
+ platforms:
+ - ${{ if eq(variables['isFullMatrix'], false) }}:
+ - windows_x86
+ jobParameters:
+ liveRuntimeBuildConfig: release
+ condition: >-
+ or(
+ eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
+ eq(variables['isFullMatrix'], true))
+
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/libraries/build-job.yml
buildConfig: Release
platforms:
- windows_x86
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
+ - windows_x64
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
+ isFullMatrix: ${{ variables.isFullMatrix }}
framework: net48
runTests: true
testScope: innerloop
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -875,13 +931,14 @@ jobs:
platforms:
- windows_x64
jobParameters:
+ isFullMatrix: ${{ variables.isFullMatrix }}
framework: allConfigurations
runTests: true
useHelix: false
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Installer Build and Test
@@ -949,7 +1006,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# CoreCLR Test executions using live libraries
@@ -972,7 +1029,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -992,7 +1049,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -1008,7 +1065,7 @@ jobs:
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr_AppleSilicon.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Mono Test builds with CoreCLR runtime tests using live libraries debug build
@@ -1026,7 +1083,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Mono CoreCLR runtime Test executions using live libraries in jit mode
@@ -1038,6 +1095,8 @@ jobs:
runtimeFlavor: mono
platforms:
- OSX_x64
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
+ - Linux_arm64
helixQueueGroup: pr
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
jobParameters:
@@ -1049,7 +1108,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Mono CoreCLR runtime Test executions using live libraries in interpreter mode
@@ -1061,6 +1120,8 @@ jobs:
runtimeFlavor: mono
platforms:
- OSX_x64
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
+ - Linux_arm64
helixQueueGroup: pr
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
jobParameters:
@@ -1072,7 +1133,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Mono CoreCLR runtime Test executions using live libraries and LLVM AOT
# Only when Mono is changed
@@ -1097,7 +1158,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Mono CoreCLR runtime Test executions using live libraries and LLVM Full AOT
@@ -1110,7 +1171,8 @@ jobs:
runtimeFlavor: mono
platforms:
- Linux_x64
- - Linux_arm64
+ # Disabled pending outcome of https://github.com/dotnet/runtime/issues/60234 investigation
+ #- Linux_arm64
helixQueueGroup: pr
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
jobParameters:
@@ -1122,7 +1184,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_runtimetests.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Libraries Release Test Execution against a release mono runtime.
@@ -1141,6 +1203,7 @@ jobs:
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
isOfficialBuild: false
+ isFullMatrix: ${{ variables.isFullMatrix }}
runtimeDisplayName: mono
testScope: innerloop
liveRuntimeBuildConfig: release
@@ -1148,7 +1211,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Libraries Release Test Execution against a release mono interpreter runtime.
@@ -1166,6 +1229,7 @@ jobs:
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
isOfficialBuild: false
+ isFullMatrix: ${{ variables.isFullMatrix }}
interpreter: true
runtimeDisplayName: mono_interpreter
testScope: innerloop
@@ -1174,7 +1238,7 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Libraries Release Test Execution against a release coreclr runtime
@@ -1186,15 +1250,18 @@ jobs:
buildConfig: Release
platforms:
- windows_x86
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
+ - windows_arm64
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
isOfficialBuild: false
+ isFullMatrix: ${{ variables.isFullMatrix }}
testScope: innerloop
liveRuntimeBuildConfig: release
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Libraries Debug Test Execution against a release coreclr runtime
@@ -1209,15 +1276,20 @@ jobs:
- OSX_x64
- Linux_x64
- Linux_musl_x64
+ - ${{ if eq(variables['isFullMatrix'], true) }}:
+ - Linux_arm64
+ - ${{ if eq(variables['isFullMatrix'], false) }}:
+ - windows_x86
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
isOfficialBuild: false
+ isFullMatrix: ${{ variables.isFullMatrix }}
testScope: innerloop
liveRuntimeBuildConfig: release
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Libraries Test Execution against a checked runtime
@@ -1241,7 +1313,7 @@ jobs:
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
#
# Libraries Test Execution against a checked runtime
@@ -1263,7 +1335,7 @@ jobs:
condition: >-
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
- template: /eng/pipelines/common/platform-matrix.yml
parameters:
@@ -1280,4 +1352,4 @@ jobs:
or(
eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true),
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
- eq(variables['isRollingBuild'], true))
+ eq(variables['isFullMatrix'], true))
diff --git a/eng/pipelines/runtimelab.yml b/eng/pipelines/runtimelab.yml
index 27e954a9a7026..9f1cd90822e83 100644
--- a/eng/pipelines/runtimelab.yml
+++ b/eng/pipelines/runtimelab.yml
@@ -190,7 +190,7 @@ stages:
- Linux_x64
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
- isRollingBuild: false
+ isFullMatrix: false
isOfficialBuild: false
testScope: innerloop
liveRuntimeBuildConfig: Release
@@ -207,7 +207,7 @@ stages:
- windows_x64
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
jobParameters:
- isRollingBuild: false
+ isFullMatrix: false
isOfficialBuild: false
testScope: innerloop
liveRuntimeBuildConfig: Release
diff --git a/eng/targetingpacks.targets b/eng/targetingpacks.targets
index 150ddf7401c9e..4213c84e709d9 100644
--- a/eng/targetingpacks.targets
+++ b/eng/targetingpacks.targets
@@ -43,13 +43,13 @@
RuntimeFrameworkName="$(LocalFrameworkOverrideName)"
LatestRuntimeFrameworkVersion="$(ProductVersion)"
RuntimePackNamePatterns="$(LocalFrameworkOverrideName).Runtime.Mono.**RID**"
- RuntimePackRuntimeIdentifiers="linux-arm;linux-armv6;linux-arm64;linux-musl-arm64;linux-loongarch64;linux-musl-x64;linux-x64;osx-x64;rhel.6-x64;win-arm;win-arm64;win-x64;win-x86;linux-musl-arm;osx-arm64;maccatalyst-x64;maccatalyst-arm64;browser-wasm;ios-arm64;ios-arm;iossimulator-arm64;iossimulator-x64;iossimulator-x86;tvos-arm64;tvossimulator-arm64;tvossimulator-x64;android-arm64;android-arm;android-x64;android-x86"
+ RuntimePackRuntimeIdentifiers="linux-arm;linux-arm64;linux-musl-arm64;linux-loongarch64;linux-musl-x64;linux-x64;osx-x64;rhel.6-x64;win-arm;win-arm64;win-x64;win-x86;linux-musl-arm;osx-arm64;maccatalyst-x64;maccatalyst-arm64;browser-wasm;ios-arm64;ios-arm;iossimulator-arm64;iossimulator-x64;iossimulator-x86;tvos-arm64;tvossimulator-arm64;tvossimulator-x64;android-arm64;android-arm;android-x64;android-x86"
RuntimePackLabels="Mono"
Condition="'@(KnownRuntimePack)' == '' or !@(KnownRuntimePack->AnyHaveMetadataValue('TargetFramework', '$(NetCoreAppCurrent)'))"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/eng/testing/tests.props b/eng/testing/tests.props
index 3025ab6233504..86c661d4bb281 100644
--- a/eng/testing/tests.props
+++ b/eng/testing/tests.props
@@ -7,7 +7,6 @@
$(TestDependsOn);GenerateRunScript;RunTests
true
$(MSBuildThisFileDirectory)ILLinkDescriptors\
- true
diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets
index e6783add3640a..85ee6deb32db3 100644
--- a/eng/testing/tests.singlefile.targets
+++ b/eng/testing/tests.singlefile.targets
@@ -12,7 +12,7 @@
chmod +rwx $(AssemblyName) && ./$(AssemblyName)
-
+
true
true
true
@@ -20,30 +20,6 @@
$(SingleFileHostSourcePath).exe
-
- $(CoreCLRILCompilerDir)
- $(CoreCLRILCompilerDir)netstandard/ILCompiler.Build.Tasks.dll
- $(CoreCLRAotSdkDir)
- $(NetCoreAppCurrentTestHostSharedFrameworkPath)
- $(NoWarn);IL3050;IL3052;IL3055;IL1005
- false
-
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/eng/testing/tests.wasm.targets b/eng/testing/tests.wasm.targets
index bed571a306402..191d2c2295690 100644
--- a/eng/testing/tests.wasm.targets
+++ b/eng/testing/tests.wasm.targets
@@ -29,13 +29,13 @@
See also eng\testing\WasmRunnerTemplate.sh
-->
-
+
-
+
diff --git a/eng/testing/xunit/xunit.props b/eng/testing/xunit/xunit.props
index a2ed68f1ecbc9..3f9c4b67141a2 100644
--- a/eng/testing/xunit/xunit.props
+++ b/eng/testing/xunit/xunit.props
@@ -10,7 +10,6 @@
-
diff --git a/global.json b/global.json
index 43ff763c74d86..f191cfdd2e352 100644
--- a/global.json
+++ b/global.json
@@ -12,12 +12,12 @@
"python3": "3.7.1"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "7.0.0-beta.22075.6",
- "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22075.6",
- "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22075.6",
- "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.22075.6",
+ "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "7.0.0-beta.22056.6",
+ "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22056.6",
+ "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22056.6",
+ "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.22056.6",
"Microsoft.Build.NoTargets": "3.1.0",
"Microsoft.Build.Traversal": "3.0.23",
- "Microsoft.NET.Sdk.IL": "7.0.0-alpha.1.22073.5"
+ "Microsoft.NET.Sdk.IL": "7.0.0-alpha.1.22059.2"
}
}
diff --git a/src/coreclr/.nuget/Microsoft.ILVerification/Microsoft.ILVerification.pkgproj b/src/coreclr/.nuget/Microsoft.ILVerification/Microsoft.ILVerification.pkgproj
index 685f941510195..db820d395a125 100644
--- a/src/coreclr/.nuget/Microsoft.ILVerification/Microsoft.ILVerification.pkgproj
+++ b/src/coreclr/.nuget/Microsoft.ILVerification/Microsoft.ILVerification.pkgproj
@@ -15,7 +15,7 @@
lib\netstandard2.0\ILVerification.dll
- $(SystemReflectionMetadataVersion)
+ 1.8.1
netstandard2.0
Build,Analyzers
diff --git a/src/coreclr/CMakeLists.txt b/src/coreclr/CMakeLists.txt
index 38e5488938b6d..2440f6ca999ca 100644
--- a/src/coreclr/CMakeLists.txt
+++ b/src/coreclr/CMakeLists.txt
@@ -247,6 +247,7 @@ add_subdirectory(debug)
add_subdirectory(binder)
add_subdirectory(classlibnative)
add_subdirectory(dlls)
+add_subdirectory(ToolBox)
add_subdirectory(tools)
add_subdirectory(unwinder)
add_subdirectory(interop)
diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
index 3d21bffd3d24f..e1230d59401d8 100644
--- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
+++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
@@ -140,6 +140,8 @@
+
+
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/SymbolStore/SymAddressKind.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/SymbolStore/SymAddressKind.cs
new file mode 100644
index 0000000000000..dc2a0a05708c1
--- /dev/null
+++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/SymbolStore/SymAddressKind.cs
@@ -0,0 +1,49 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*============================================================
+**
+**
+**
+** Represents address Kinds used with local variables, parameters, and
+** fields.
+**
+**
+===========================================================*/
+// Only statics, does not need to be marked with the serializable attribute
+
+namespace System.Diagnostics.SymbolStore
+{
+ internal enum SymAddressKind
+ {
+ // ILOffset: addr1 = IL local var or param index.
+ ILOffset = 1,
+
+ // NativeRVA: addr1 = RVA into module.
+ NativeRVA = 2,
+
+ // NativeRegister: addr1 = register the var is stored in.
+ NativeRegister = 3,
+
+ // NativeRegisterRelative: addr1 = register, addr2 = offset.
+ NativeRegisterRelative = 4,
+
+ // NativeOffset: addr1 = offset from start of parent.
+ NativeOffset = 5,
+
+ // NativeRegisterRegister: addr1 = reg low, addr2 = reg high.
+ NativeRegisterRegister = 6,
+
+ // NativeRegisterStack: addr1 = reg low, addr2 = reg stk, addr3 = offset.
+ NativeRegisterStack = 7,
+
+ // NativeStackRegister: addr1 = reg stk, addr2 = offset, addr3 = reg high.
+ NativeStackRegister = 8,
+
+ // BitField: addr1 = field start, addr = field length.
+ BitField = 9,
+
+ // NativeSectionOffset: addr1 = section, addr = offset
+ NativeSectionOffset = 10,
+ }
+}
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/SymbolStore/Token.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/SymbolStore/Token.cs
new file mode 100644
index 0000000000000..fbd9f7e4bc1ae
--- /dev/null
+++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/SymbolStore/Token.cs
@@ -0,0 +1,39 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*============================================================
+**
+**
+** Small value class used by the SymbolStore package for passing
+** around metadata tokens.
+**
+===========================================================*/
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace System.Diagnostics.SymbolStore
+{
+ internal struct SymbolToken
+ {
+ internal int m_token;
+
+ public SymbolToken(int val) { m_token = val; }
+
+ public int GetToken() { return m_token; }
+
+ public override int GetHashCode() { return m_token; }
+
+ public override bool Equals([NotNullWhen(true)] object? obj)
+ {
+ if (obj is SymbolToken)
+ return Equals((SymbolToken)obj);
+ else
+ return false;
+ }
+
+ public bool Equals(SymbolToken obj)
+ {
+ return obj.m_token == m_token;
+ }
+ }
+}
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs
index a619dc4b1ca79..c86aa1b2e62bf 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Math.CoreCLR.cs
@@ -16,6 +16,14 @@ namespace System
{
public static partial class Math
{
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public static extern double Abs(double value);
+
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public static extern float Abs(float value);
+
[Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern double Acos(double d);
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/AssemblyName.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/AssemblyName.CoreCLR.cs
index bfe5bcce8db99..f45b3837abdd9 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/AssemblyName.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/AssemblyName.CoreCLR.cs
@@ -11,6 +11,18 @@ namespace System.Reflection
{
public sealed partial class AssemblyName : ICloneable, IDeserializationCallback, ISerializable
{
+ public AssemblyName(string assemblyName)
+ {
+ if (assemblyName == null)
+ throw new ArgumentNullException(nameof(assemblyName));
+ if ((assemblyName.Length == 0) ||
+ (assemblyName[0] == '\0'))
+ throw new ArgumentException(SR.Format_StringZeroLength);
+
+ _name = assemblyName;
+ nInit();
+ }
+
internal AssemblyName(string? name,
byte[]? publicKey,
byte[]? publicKeyToken,
@@ -32,6 +44,23 @@ internal AssemblyName(string? name,
_flags = flags;
}
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern void nInit();
+
+ // This call opens and closes the file, but does not add the
+ // assembly to the domain.
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal static extern AssemblyName nGetFileInformation(string s);
+
+ internal static AssemblyName GetFileInformationCore(string assemblyFile)
+ {
+ string fullPath = Path.GetFullPath(assemblyFile);
+ return nGetFileInformation(fullPath);
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern byte[]? ComputePublicKeyToken();
+
internal void SetProcArchIndex(PortableExecutableKinds pek, ImageFileMachine ifm)
{
#pragma warning disable SYSLIB0037 // AssemblyName.ProcessorArchitecture is obsolete
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
index 9def7541aa4c6..70cd4fb988f08 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
@@ -314,7 +314,14 @@ public ModuleBuilder DefineDynamicModule(string name)
private ModuleBuilder DefineDynamicModuleInternalNoLock(string name)
{
- ArgumentException.ThrowIfNullOrEmpty(name);
+ if (name == null)
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+ if (name.Length == 0)
+ {
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
+ }
if (name[0] == '\0')
{
throw new ArgumentException(SR.Argument_InvalidName, nameof(name));
@@ -460,7 +467,14 @@ public override Assembly GetSatelliteAssembly(CultureInfo culture, Version? vers
/// The name of module for the look up.
private ModuleBuilder? GetDynamicModuleNoLock(string name)
{
- ArgumentException.ThrowIfNullOrEmpty(name);
+ if (name == null)
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+ if (name.Length == 0)
+ {
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
+ }
for (int i = 0; i < _assemblyData._moduleBuilderList.Count; i++)
{
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.cs
index c3e22c5d34071..e4c35c9dbbc03 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.cs
@@ -20,12 +20,17 @@ public sealed class FieldBuilder : FieldInfo
internal FieldBuilder(TypeBuilder typeBuilder, string fieldName, Type type,
Type[]? requiredCustomModifiers, Type[]? optionalCustomModifiers, FieldAttributes attributes)
{
- ArgumentException.ThrowIfNullOrEmpty(fieldName);
+ if (fieldName == null)
+ throw new ArgumentNullException(nameof(fieldName));
+
+ if (fieldName.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(fieldName));
if (fieldName[0] == '\0')
throw new ArgumentException(SR.Argument_IllegalName, nameof(fieldName));
- ArgumentNullException.ThrowIfNull(type);
+ if (type == null)
+ throw new ArgumentNullException(nameof(type));
if (type == typeof(void))
throw new ArgumentException(SR.Argument_BadFieldType);
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs
index 1b35f5cdbb15f..275cecbead57a 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs
@@ -1273,7 +1273,11 @@ public virtual void UsingNamespace(string usingNamespace)
// Specifying the namespace to be used in evaluating locals and watches
// for the current active lexical scope.
- ArgumentException.ThrowIfNullOrEmpty(usingNamespace);
+ if (usingNamespace == null)
+ throw new ArgumentNullException(nameof(usingNamespace));
+
+ if (usingNamespace.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(usingNamespace));
MethodBuilder? methodBuilder = m_methodBuilder as MethodBuilder;
if (methodBuilder == null)
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs
index 9d11aacaf53ea..176f5a3fd3729 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/MethodBuilder.cs
@@ -61,18 +61,24 @@ internal MethodBuilder(string name, MethodAttributes attributes, CallingConventi
Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers,
ModuleBuilder mod, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] TypeBuilder type)
{
- ArgumentException.ThrowIfNullOrEmpty(name);
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+
+ if (name.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
if (name[0] == '\0')
throw new ArgumentException(SR.Argument_IllegalName, nameof(name));
- ArgumentNullException.ThrowIfNull(mod);
+ if (mod == null)
+ throw new ArgumentNullException(nameof(mod));
if (parameterTypes != null)
{
foreach (Type t in parameterTypes)
{
- ArgumentNullException.ThrowIfNull(t, nameof(parameterTypes));
+ if (t == null)
+ throw new ArgumentNullException(nameof(parameterTypes));
}
}
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs
index cbe0a7b39dde5..fe5da8367cdd4 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs
@@ -233,7 +233,7 @@ private int GetTypeRefNested(Type type, Module? refedModule, string? strRefedMod
typeName = UnmangleTypeName(typeName);
}
- Debug.Assert(!type.IsByRef, "Must not be ByRef. Get token from TypeSpec.");
+ Debug.Assert(!type.IsByRef, "Must not be ByRef.");
Debug.Assert(!type.IsGenericType || type.IsGenericTypeDefinition, "Must not have generic arguments.");
ModuleBuilder thisModule = this;
@@ -948,7 +948,14 @@ private MethodBuilder DefineGlobalMethodNoLock(string name, MethodAttributes att
{
throw new InvalidOperationException(SR.InvalidOperation_GlobalsHaveBeenCreated);
}
- ArgumentException.ThrowIfNullOrEmpty(name);
+ if (name == null)
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+ if (name.Length == 0)
+ {
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
+ }
if ((attributes & MethodAttributes.Static) == 0)
{
throw new ArgumentException(SR.Argument_GlobalFunctionHasToBeStatic);
@@ -1074,16 +1081,19 @@ private int GetTypeTokenWorkerNoLock(Type type, bool getGenericDefinition)
// instructions. Tokens are always relative to the Module. For example,
// the token value for System.String is likely to be different from
// Module to Module. Calling GetTypeToken will cause a reference to be
- // added to the Module. This reference becomes a permanent part of the Module,
- // multiple calls to this method with the same class have no additional side-effects.
- // This function is optimized to use the TypeDef token if the Type is within the
- // same module. We should also be aware of multiple dynamic modules and multiple
- // implementations of a Type.
- if ((type.IsGenericType && (!type.IsGenericTypeDefinition || !getGenericDefinition))
- || type.IsGenericParameter
- || type.IsArray
- || type.IsPointer
- || type.IsByRef)
+ // added to the Module. This reference becomes a perminate part of the Module,
+ // multiple calles to this method with the same class have no additional side affects.
+ // This function is optimized to use the TypeDef token if Type is within the same module.
+ // We should also be aware of multiple dynamic modules and multiple implementation of Type!!!
+ if (type.IsByRef)
+ {
+ throw new ArgumentException(SR.Argument_CannotGetTypeTokenForByRef);
+ }
+
+ if ((type.IsGenericType && (!type.IsGenericTypeDefinition || !getGenericDefinition)) ||
+ type.IsGenericParameter ||
+ type.IsArray ||
+ type.IsPointer)
{
byte[] sig = SignatureHelper.GetTypeSigToken(this, type).InternalGetSignature(out int length);
return GetTokenFromTypeSpec(sig, length);
@@ -1345,8 +1355,18 @@ internal int GetArrayMethodToken(Type arrayClass, string methodName, CallingConv
private int GetArrayMethodTokenNoLock(Type arrayClass, string methodName, CallingConventions callingConvention,
Type? returnType, Type[]? parameterTypes)
{
- ArgumentNullException.ThrowIfNull(arrayClass);
- ArgumentException.ThrowIfNullOrEmpty(methodName);
+ if (arrayClass == null)
+ {
+ throw new ArgumentNullException(nameof(arrayClass));
+ }
+ if (methodName == null)
+ {
+ throw new ArgumentNullException(nameof(methodName));
+ }
+ if (methodName.Length == 0)
+ {
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(methodName));
+ }
if (!arrayClass.IsArray)
{
throw new ArgumentException(SR.Argument_HasToBeArrayClass);
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/PropertyBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/PropertyBuilder.cs
index 89accc39caeb9..ae6e704b2a5c8 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/PropertyBuilder.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/PropertyBuilder.cs
@@ -34,7 +34,10 @@ internal PropertyBuilder(
int prToken, // the metadata token for this property
TypeBuilder containingType) // the containing type
{
- ArgumentException.ThrowIfNullOrEmpty(name);
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ if (name.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
if (name[0] == '\0')
throw new ArgumentException(SR.Argument_IllegalName, nameof(name));
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs
index ad80acad07835..6d9b8121fa6b4 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs
@@ -480,7 +480,11 @@ internal TypeBuilder(
string fullname, TypeAttributes attr, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, Type[]? interfaces, ModuleBuilder module,
PackingSize iPackingSize, int iTypeSize, TypeBuilder? enclosingType)
{
- ArgumentException.ThrowIfNullOrEmpty(fullname);
+ if (fullname == null)
+ throw new ArgumentNullException(nameof(fullname));
+
+ if (fullname.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(fullname));
if (fullname[0] == '\0')
throw new ArgumentException(SR.Argument_IllegalName, nameof(fullname));
@@ -577,7 +581,11 @@ private FieldBuilder DefineDataHelper(string name, byte[]? data, int size, Field
FieldBuilder fdBuilder;
TypeAttributes typeAttributes;
- ArgumentException.ThrowIfNullOrEmpty(name);
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+
+ if (name.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
if (size <= 0 || size >= 0x003f0000)
throw new ArgumentException(SR.Argument_BadSizeForData);
@@ -1274,7 +1282,11 @@ private MethodBuilder DefineMethodNoLock(string name, MethodAttributes attribute
Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers,
Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers)
{
- ArgumentException.ThrowIfNullOrEmpty(name);
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+
+ if (name.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
AssemblyBuilder.CheckContext(returnType);
AssemblyBuilder.CheckContext(returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes);
@@ -1362,9 +1374,23 @@ private MethodBuilder DefinePInvokeMethodHelper(
lock (SyncRoot)
{
- ArgumentException.ThrowIfNullOrEmpty(name);
- ArgumentException.ThrowIfNullOrEmpty(dllName);
- ArgumentException.ThrowIfNullOrEmpty(importName);
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+
+ if (name.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
+
+ if (dllName == null)
+ throw new ArgumentNullException(nameof(dllName));
+
+ if (dllName.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(dllName));
+
+ if (importName == null)
+ throw new ArgumentNullException(nameof(importName));
+
+ if (importName.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(importName));
if ((attributes & MethodAttributes.Abstract) != 0)
throw new ArgumentException(SR.Argument_BadPInvokeMethod);
@@ -1766,7 +1792,10 @@ private PropertyBuilder DefinePropertyNoLock(string name, PropertyAttributes att
Type returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers,
Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers)
{
- ArgumentException.ThrowIfNullOrEmpty(name);
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ if (name.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
AssemblyBuilder.CheckContext(returnType);
AssemblyBuilder.CheckContext(returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes);
@@ -1818,7 +1847,10 @@ public EventBuilder DefineEvent(string name, EventAttributes attributes, Type ev
private EventBuilder DefineEventNoLock(string name, EventAttributes attributes, Type eventtype)
{
- ArgumentException.ThrowIfNullOrEmpty(name);
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ if (name.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
if (name[0] == '\0')
throw new ArgumentException(SR.Argument_IllegalName, nameof(name));
@@ -1890,9 +1922,7 @@ private EventBuilder DefineEventNoLock(string name, EventAttributes attributes,
int tkParent = 0;
if (m_typeParent != null)
- {
tkParent = m_module.GetTypeTokenInternal(m_typeParent);
- }
ModuleBuilder module = m_module;
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdImport.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdImport.cs
index cdc15dc8fb6e0..9368fc25d340b 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdImport.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MdImport.cs
@@ -194,9 +194,7 @@ public int this[int index]
}
}
-#pragma warning disable CA1066 // IEquatable interface implementation isn't used
internal readonly struct MetadataImport
-#pragma warning restore CA1067
{
private readonly IntPtr m_metadataImport2;
private readonly object? m_keepalive;
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
index 3708e71cb4510..977d73e5c3b99 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
@@ -558,7 +558,8 @@ private static partial void GetTypeByName(string name, bool throwOnError, bool i
internal static RuntimeType GetTypeByNameUsingCARules(string name, RuntimeModule scope)
{
- ArgumentException.ThrowIfNullOrEmpty(name);
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentException(null, nameof(name));
RuntimeType? type = null;
GetTypeByNameUsingCARules(name, new QCallModule(ref scope), ObjectHandleOnStack.Create(ref type));
@@ -1245,7 +1246,7 @@ public void GetObjectData(SerializationInfo info, StreamingContext context)
}
}
- public unsafe partial struct ModuleHandle : IEquatable
+ public unsafe partial struct ModuleHandle
{
#region Public Static Members
public static readonly ModuleHandle EmptyHandle;
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
index bf83df6c0f975..a0d7026b54407 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
@@ -1941,7 +1941,7 @@ private static PropertyInfo GetPropertyInfo(RuntimeType reflectedType, int tkPro
}
Debug.Fail("Unreachable code");
- throw new UnreachableException();
+ throw new SystemException();
}
internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception? e)
diff --git a/src/coreclr/ToolBox/CMakeLists.txt b/src/coreclr/ToolBox/CMakeLists.txt
new file mode 100644
index 0000000000000..4e7f4368681d1
--- /dev/null
+++ b/src/coreclr/ToolBox/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(SOS)
+add_subdirectory(superpmi)
diff --git a/src/coreclr/tools/SOS/CMakeLists.txt b/src/coreclr/ToolBox/SOS/CMakeLists.txt
similarity index 100%
rename from src/coreclr/tools/SOS/CMakeLists.txt
rename to src/coreclr/ToolBox/SOS/CMakeLists.txt
diff --git a/src/coreclr/tools/SOS/DIALib/DIALib.il b/src/coreclr/ToolBox/SOS/DIALib/DIALib.il
similarity index 100%
rename from src/coreclr/tools/SOS/DIALib/DIALib.il
rename to src/coreclr/ToolBox/SOS/DIALib/DIALib.il
diff --git a/src/coreclr/tools/SOS/DIALib/DIALib.ilproj b/src/coreclr/ToolBox/SOS/DIALib/DIALib.ilproj
similarity index 100%
rename from src/coreclr/tools/SOS/DIALib/DIALib.ilproj
rename to src/coreclr/ToolBox/SOS/DIALib/DIALib.ilproj
diff --git a/src/coreclr/tools/SOS/DacTableGen/DacTableGen.csproj b/src/coreclr/ToolBox/SOS/DacTableGen/DacTableGen.csproj
similarity index 100%
rename from src/coreclr/tools/SOS/DacTableGen/DacTableGen.csproj
rename to src/coreclr/ToolBox/SOS/DacTableGen/DacTableGen.csproj
diff --git a/src/coreclr/tools/SOS/DacTableGen/MapSymbolProvider.cs b/src/coreclr/ToolBox/SOS/DacTableGen/MapSymbolProvider.cs
similarity index 100%
rename from src/coreclr/tools/SOS/DacTableGen/MapSymbolProvider.cs
rename to src/coreclr/ToolBox/SOS/DacTableGen/MapSymbolProvider.cs
diff --git a/src/coreclr/tools/SOS/DacTableGen/cvconst.cs b/src/coreclr/ToolBox/SOS/DacTableGen/cvconst.cs
similarity index 100%
rename from src/coreclr/tools/SOS/DacTableGen/cvconst.cs
rename to src/coreclr/ToolBox/SOS/DacTableGen/cvconst.cs
diff --git a/src/coreclr/tools/SOS/DacTableGen/diautil.cs b/src/coreclr/ToolBox/SOS/DacTableGen/diautil.cs
similarity index 100%
rename from src/coreclr/tools/SOS/DacTableGen/diautil.cs
rename to src/coreclr/ToolBox/SOS/DacTableGen/diautil.cs
diff --git a/src/coreclr/tools/SOS/DacTableGen/main.cs b/src/coreclr/ToolBox/SOS/DacTableGen/main.cs
similarity index 100%
rename from src/coreclr/tools/SOS/DacTableGen/main.cs
rename to src/coreclr/ToolBox/SOS/DacTableGen/main.cs
diff --git a/src/coreclr/tools/SOS/Directory.Build.props b/src/coreclr/ToolBox/SOS/Directory.Build.props
similarity index 100%
rename from src/coreclr/tools/SOS/Directory.Build.props
rename to src/coreclr/ToolBox/SOS/Directory.Build.props
diff --git a/src/coreclr/tools/SOS/SOS_README.md b/src/coreclr/ToolBox/SOS/SOS_README.md
similarity index 100%
rename from src/coreclr/tools/SOS/SOS_README.md
rename to src/coreclr/ToolBox/SOS/SOS_README.md
diff --git a/src/coreclr/tools/superpmi/.clang-format b/src/coreclr/ToolBox/superpmi/.clang-format
similarity index 100%
rename from src/coreclr/tools/superpmi/.clang-format
rename to src/coreclr/ToolBox/superpmi/.clang-format
diff --git a/src/coreclr/tools/superpmi/CMakeLists.txt b/src/coreclr/ToolBox/superpmi/CMakeLists.txt
similarity index 100%
rename from src/coreclr/tools/superpmi/CMakeLists.txt
rename to src/coreclr/ToolBox/superpmi/CMakeLists.txt
diff --git a/src/coreclr/tools/superpmi/mcs/CMakeLists.txt b/src/coreclr/ToolBox/superpmi/mcs/CMakeLists.txt
similarity index 96%
rename from src/coreclr/tools/superpmi/mcs/CMakeLists.txt
rename to src/coreclr/ToolBox/superpmi/mcs/CMakeLists.txt
index 8ce4c19725082..56dcaff658cc5 100644
--- a/src/coreclr/tools/superpmi/mcs/CMakeLists.txt
+++ b/src/coreclr/ToolBox/superpmi/mcs/CMakeLists.txt
@@ -68,4 +68,4 @@ else()
endif(CLR_CMAKE_HOST_UNIX)
-install_clr(TARGETS mcs DESTINATIONS . COMPONENT spmi)
+install_clr(TARGETS mcs DESTINATIONS .)
diff --git a/src/coreclr/tools/superpmi/mcs/commandline.cpp b/src/coreclr/ToolBox/superpmi/mcs/commandline.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/commandline.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/commandline.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/commandline.h b/src/coreclr/ToolBox/superpmi/mcs/commandline.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/commandline.h
rename to src/coreclr/ToolBox/superpmi/mcs/commandline.h
diff --git a/src/coreclr/tools/superpmi/mcs/mcs.cpp b/src/coreclr/ToolBox/superpmi/mcs/mcs.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/mcs.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/mcs.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/mcs.h b/src/coreclr/ToolBox/superpmi/mcs/mcs.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/mcs.h
rename to src/coreclr/ToolBox/superpmi/mcs/mcs.h
diff --git a/src/coreclr/tools/superpmi/mcs/removedup.cpp b/src/coreclr/ToolBox/superpmi/mcs/removedup.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/removedup.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/removedup.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/removedup.h b/src/coreclr/ToolBox/superpmi/mcs/removedup.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/removedup.h
rename to src/coreclr/ToolBox/superpmi/mcs/removedup.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbasmdump.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbasmdump.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbasmdump.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbasmdump.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbasmdump.h b/src/coreclr/ToolBox/superpmi/mcs/verbasmdump.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbasmdump.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbasmdump.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbconcat.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbconcat.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbconcat.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbconcat.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbconcat.h b/src/coreclr/ToolBox/superpmi/mcs/verbconcat.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbconcat.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbconcat.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbdump.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbdump.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbdump.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbdump.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbdump.h b/src/coreclr/ToolBox/superpmi/mcs/verbdump.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbdump.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbdump.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbdumpmap.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbdumpmap.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbdumpmap.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbdumpmap.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbdumpmap.h b/src/coreclr/ToolBox/superpmi/mcs/verbdumpmap.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbdumpmap.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbdumpmap.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbdumptoc.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbdumptoc.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbdumptoc.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbdumptoc.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbdumptoc.h b/src/coreclr/ToolBox/superpmi/mcs/verbdumptoc.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbdumptoc.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbdumptoc.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbfracture.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbfracture.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbfracture.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbfracture.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbfracture.h b/src/coreclr/ToolBox/superpmi/mcs/verbfracture.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbfracture.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbfracture.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbildump.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbildump.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbildump.h b/src/coreclr/ToolBox/superpmi/mcs/verbildump.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbildump.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbildump.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbinteg.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbinteg.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbinteg.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbinteg.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbinteg.h b/src/coreclr/ToolBox/superpmi/mcs/verbinteg.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbinteg.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbinteg.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbjitflags.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbjitflags.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbjitflags.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbjitflags.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbjitflags.h b/src/coreclr/ToolBox/superpmi/mcs/verbjitflags.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbjitflags.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbjitflags.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbmerge.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbmerge.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbmerge.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.h b/src/coreclr/ToolBox/superpmi/mcs/verbmerge.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbmerge.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbmerge.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbprintjiteeversion.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbprintjiteeversion.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbprintjiteeversion.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbprintjiteeversion.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbprintjiteeversion.h b/src/coreclr/ToolBox/superpmi/mcs/verbprintjiteeversion.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbprintjiteeversion.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbprintjiteeversion.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbremovedup.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbremovedup.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbremovedup.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbremovedup.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbremovedup.h b/src/coreclr/ToolBox/superpmi/mcs/verbremovedup.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbremovedup.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbremovedup.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbstat.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbstat.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbstat.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbstat.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbstat.h b/src/coreclr/ToolBox/superpmi/mcs/verbstat.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbstat.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbstat.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbstrip.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbstrip.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbstrip.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbstrip.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbstrip.h b/src/coreclr/ToolBox/superpmi/mcs/verbstrip.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbstrip.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbstrip.h
diff --git a/src/coreclr/tools/superpmi/mcs/verbtoc.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbtoc.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbtoc.cpp
rename to src/coreclr/ToolBox/superpmi/mcs/verbtoc.cpp
diff --git a/src/coreclr/tools/superpmi/mcs/verbtoc.h b/src/coreclr/ToolBox/superpmi/mcs/verbtoc.h
similarity index 100%
rename from src/coreclr/tools/superpmi/mcs/verbtoc.h
rename to src/coreclr/ToolBox/superpmi/mcs/verbtoc.h
diff --git a/src/coreclr/tools/superpmi/readme.md b/src/coreclr/ToolBox/superpmi/readme.md
similarity index 99%
rename from src/coreclr/tools/superpmi/readme.md
rename to src/coreclr/ToolBox/superpmi/readme.md
index b84e8d01697bd..c3de3dfe94288 100644
--- a/src/coreclr/tools/superpmi/readme.md
+++ b/src/coreclr/ToolBox/superpmi/readme.md
@@ -1,6 +1,6 @@
# Overview
-This directory (`src/coreclr/tools/superpmi` in the GitHub
+This directory (`src/coreclr/ToolBox/superpmi` in the GitHub
https://github.com/dotnet/runtime repository) contains the SuperPMI
tool used for testing the .NET just-in-time (JIT) compiler.
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/agnostic.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/agnostic.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/asmdumper.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/asmdumper.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/asmdumper.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/asmdumper.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/asmdumper.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/asmdumper.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/callutils.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/callutils.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/callutils.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/callutils.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/compileresult.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/compileresult.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/crlwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/crlwmlist.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/crlwmlist.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/crlwmlist.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/errorhandling.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/errorhandling.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/errorhandling.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/errorhandling.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/hash.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/hash.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/hash.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/hash.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/hash.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/hash.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/hash.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/hash.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/icorjitcompilerimpl.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/icorjitcompilerimpl.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/icorjithostimpl.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjithostimpl.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/icorjithostimpl.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/icorjithostimpl.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/icorjitinfoimpl.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lightweightmap.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lightweightmap.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/lightweightmap.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/lightweightmap.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/logging.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/logging.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/logging.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/logging.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/logging.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/logging.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/logging.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/logging.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/mclist.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/mclist.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/mclist.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/mclist.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/mclist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/mclist.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/mclist.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/mclist.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontextiterator.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontextiterator.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontextiterator.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontextiterator.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontextreader.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontextreader.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontextreader.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontextreader.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/runtimedetails.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/runtimedetails.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/runtimedetails.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/runtimedetails.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/simpletimer.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/simpletimer.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/simpletimer.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/simpletimer.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/simpletimer.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/simpletimer.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/simpletimer.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/simpletimer.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmidumphelper.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/spmidumphelper.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmidumphelper.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/spmidumphelper.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmirecordhelper.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/spmirecordhelper.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/standardpch.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/standardpch.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/standardpch.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/standardpch.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/tocfile.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/tocfile.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/tocfile.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/tocfile.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/tocfile.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/tocfile.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/tocfile.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/tocfile.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/typeutils.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/typeutils.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/typeutils.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/typeutils.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shared/typeutils.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/typeutils.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shared/typeutils.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shared/typeutils.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/CMakeLists.txt b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/CMakeLists.txt
similarity index 95%
rename from src/coreclr/tools/superpmi/superpmi-shim-collector/CMakeLists.txt
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-collector/CMakeLists.txt
index 5090fd411dfc9..1eb640c4cb9c0 100644
--- a/src/coreclr/tools/superpmi/superpmi-shim-collector/CMakeLists.txt
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/CMakeLists.txt
@@ -61,4 +61,4 @@ else()
)
endif(CLR_CMAKE_HOST_UNIX)
-install_clr(TARGETS superpmi-shim-collector DESTINATIONS . COMPONENT spmi)
+install_clr(TARGETS superpmi-shim-collector DESTINATIONS .)
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/jithost.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-collector/jithost.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/jithost.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-collector/jithost.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-collector/jithost.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/superpmi-shim-collector.def b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/superpmi-shim-collector.def
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-collector/superpmi-shim-collector.def
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-collector/superpmi-shim-collector.def
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/superpmi-shim-collector.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/superpmi-shim-collector.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-collector/superpmi-shim-collector.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-collector/superpmi-shim-collector.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/CMakeLists.txt b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/CMakeLists.txt
similarity index 96%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/CMakeLists.txt
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/CMakeLists.txt
index 403841d95c8ed..602a6751b02da 100644
--- a/src/coreclr/tools/superpmi/superpmi-shim-counter/CMakeLists.txt
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/CMakeLists.txt
@@ -63,4 +63,4 @@ else()
)
endif(CLR_CMAKE_HOST_UNIX)
-install_clr(TARGETS superpmi-shim-counter DESTINATIONS . COMPONENT spmi)
+install_clr(TARGETS superpmi-shim-counter DESTINATIONS .)
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitcompiler.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitcompiler.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitcompiler.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitcompiler.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/jithost.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/jithost.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/jithost.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/jithost.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/jithost.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/jithost.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/jithost.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/jithost.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/methodcallsummarizer.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/methodcallsummarizer.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/methodcallsummarizer.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/methodcallsummarizer.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/methodcallsummarizer.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/methodcallsummarizer.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/methodcallsummarizer.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/methodcallsummarizer.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/superpmi-shim-counter.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/superpmi-shim-counter.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/superpmi-shim-counter.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/superpmi-shim-counter.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/superpmi-shim-counter.def b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/superpmi-shim-counter.def
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/superpmi-shim-counter.def
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/superpmi-shim-counter.def
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/superpmi-shim-counter.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/superpmi-shim-counter.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-counter/superpmi-shim-counter.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-counter/superpmi-shim-counter.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/CMakeLists.txt b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/CMakeLists.txt
similarity index 96%
rename from src/coreclr/tools/superpmi/superpmi-shim-simple/CMakeLists.txt
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-simple/CMakeLists.txt
index e1c168ef9d9dd..b6f4d52ea4cab 100644
--- a/src/coreclr/tools/superpmi/superpmi-shim-simple/CMakeLists.txt
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/CMakeLists.txt
@@ -62,4 +62,4 @@ else()
)
endif(CLR_CMAKE_HOST_UNIX)
-install_clr(TARGETS superpmi-shim-simple DESTINATIONS . COMPONENT spmi)
+install_clr(TARGETS superpmi-shim-simple DESTINATIONS .)
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitcompiler.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitcompiler.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitcompiler.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitcompiler.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/jithost.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/jithost.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-simple/jithost.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-simple/jithost.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/jithost.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/jithost.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-simple/jithost.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-simple/jithost.h
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/superpmi-shim-simple.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/superpmi-shim-simple.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-simple/superpmi-shim-simple.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-simple/superpmi-shim-simple.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/superpmi-shim-simple.def b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/superpmi-shim-simple.def
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-simple/superpmi-shim-simple.def
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-simple/superpmi-shim-simple.def
diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/superpmi-shim-simple.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/superpmi-shim-simple.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi-shim-simple/superpmi-shim-simple.h
rename to src/coreclr/ToolBox/superpmi/superpmi-shim-simple/superpmi-shim-simple.h
diff --git a/src/coreclr/tools/superpmi/superpmi/CMakeLists.txt b/src/coreclr/ToolBox/superpmi/superpmi/CMakeLists.txt
similarity index 96%
rename from src/coreclr/tools/superpmi/superpmi/CMakeLists.txt
rename to src/coreclr/ToolBox/superpmi/superpmi/CMakeLists.txt
index 63237450898e3..4827c195dc299 100644
--- a/src/coreclr/tools/superpmi/superpmi/CMakeLists.txt
+++ b/src/coreclr/ToolBox/superpmi/superpmi/CMakeLists.txt
@@ -64,4 +64,4 @@ else()
)
endif(CLR_CMAKE_HOST_UNIX)
-install_clr(TARGETS superpmi DESTINATIONS . COMPONENT spmi)
+install_clr(TARGETS superpmi DESTINATIONS .)
diff --git a/src/coreclr/tools/superpmi/superpmi/commandline.cpp b/src/coreclr/ToolBox/superpmi/superpmi/commandline.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/commandline.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/commandline.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/commandline.h b/src/coreclr/ToolBox/superpmi/superpmi/commandline.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/commandline.h
rename to src/coreclr/ToolBox/superpmi/superpmi/commandline.h
diff --git a/src/coreclr/tools/superpmi/superpmi/cycletimer.cpp b/src/coreclr/ToolBox/superpmi/superpmi/cycletimer.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/cycletimer.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/cycletimer.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/cycletimer.h b/src/coreclr/ToolBox/superpmi/superpmi/cycletimer.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/cycletimer.h
rename to src/coreclr/ToolBox/superpmi/superpmi/cycletimer.h
diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.h b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/icorjitinfo.h
rename to src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.h
diff --git a/src/coreclr/tools/superpmi/superpmi/jitdebugger.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitdebugger.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/jitdebugger.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/jitdebugger.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/jitdebugger.h b/src/coreclr/ToolBox/superpmi/superpmi/jitdebugger.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/jitdebugger.h
rename to src/coreclr/ToolBox/superpmi/superpmi/jitdebugger.h
diff --git a/src/coreclr/tools/superpmi/superpmi/jithost.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jithost.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/jithost.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/jithost.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/jithost.h b/src/coreclr/ToolBox/superpmi/superpmi/jithost.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/jithost.h
rename to src/coreclr/ToolBox/superpmi/superpmi/jithost.h
diff --git a/src/coreclr/tools/superpmi/superpmi/jitinstance.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/jitinstance.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/jitinstance.h b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/jitinstance.h
rename to src/coreclr/ToolBox/superpmi/superpmi/jitinstance.h
diff --git a/src/coreclr/tools/superpmi/superpmi/methodstatsemitter.cpp b/src/coreclr/ToolBox/superpmi/superpmi/methodstatsemitter.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/methodstatsemitter.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/methodstatsemitter.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/methodstatsemitter.h b/src/coreclr/ToolBox/superpmi/superpmi/methodstatsemitter.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/methodstatsemitter.h
rename to src/coreclr/ToolBox/superpmi/superpmi/methodstatsemitter.h
diff --git a/src/coreclr/tools/superpmi/superpmi/metricssummary.cpp b/src/coreclr/ToolBox/superpmi/superpmi/metricssummary.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/metricssummary.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/metricssummary.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/metricssummary.h b/src/coreclr/ToolBox/superpmi/superpmi/metricssummary.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/metricssummary.h
rename to src/coreclr/ToolBox/superpmi/superpmi/metricssummary.h
diff --git a/src/coreclr/tools/superpmi/superpmi/neardiffer.cpp b/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/neardiffer.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/neardiffer.h b/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/neardiffer.h
rename to src/coreclr/ToolBox/superpmi/superpmi/neardiffer.h
diff --git a/src/coreclr/tools/superpmi/superpmi/parallelsuperpmi.cpp b/src/coreclr/ToolBox/superpmi/superpmi/parallelsuperpmi.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/parallelsuperpmi.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/parallelsuperpmi.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/superpmi.cpp b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/superpmi.cpp
rename to src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp
diff --git a/src/coreclr/tools/superpmi/superpmi/superpmi.h b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.h
similarity index 100%
rename from src/coreclr/tools/superpmi/superpmi/superpmi.h
rename to src/coreclr/ToolBox/superpmi/superpmi/superpmi.h
diff --git a/src/coreclr/binder/assemblybindercommon.cpp b/src/coreclr/binder/assemblybindercommon.cpp
index 7b48a0a90ce83..830c673ea06a6 100644
--- a/src/coreclr/binder/assemblybindercommon.cpp
+++ b/src/coreclr/binder/assemblybindercommon.cpp
@@ -972,7 +972,7 @@ namespace BINDER_SPACE
{
// Search Assembly.ni.dll, then Assembly.dll
// The Assembly.ni.dll paths are rare, and intended for supporting managed C++ R2R assemblies.
- const WCHAR* const candidates[] = { W(".ni.dll"), W(".dll") };
+ SString candidates[] = { W(".ni.dll"), W(".dll") };
// Loop through the binding paths looking for a matching assembly
for (int i = 0; i < 2; i++)
diff --git a/src/coreclr/binder/bindertracing.cpp b/src/coreclr/binder/bindertracing.cpp
index e349b99b3c14e..499e20d928887 100644
--- a/src/coreclr/binder/bindertracing.cpp
+++ b/src/coreclr/binder/bindertracing.cpp
@@ -176,8 +176,8 @@ namespace BinderTracing
{
static thread_local bool t_AssemblyLoadStartInProgress = false;
- AssemblyBindOperation::AssemblyBindOperation(AssemblySpec *assemblySpec, const SString& assemblyPath)
- : m_bindRequest { assemblySpec, SString::Empty(), assemblyPath }
+ AssemblyBindOperation::AssemblyBindOperation(AssemblySpec *assemblySpec, const WCHAR *assemblyPath)
+ : m_bindRequest { assemblySpec, nullptr, assemblyPath }
, m_populatedBindRequest { false }
, m_checkedIgnoreBind { false }
, m_ignoreBind { false }
diff --git a/src/coreclr/binder/inc/assemblyidentity.hpp b/src/coreclr/binder/inc/assemblyidentity.hpp
index ef4768d3b8cd9..cc0916c8780af 100644
--- a/src/coreclr/binder/inc/assemblyidentity.hpp
+++ b/src/coreclr/binder/inc/assemblyidentity.hpp
@@ -30,9 +30,12 @@ namespace BINDER_SPACE
IDENTITY_FLAG_PUBLIC_KEY_TOKEN = 0x004,
IDENTITY_FLAG_PUBLIC_KEY = 0x008,
IDENTITY_FLAG_CULTURE = 0x010,
+ IDENTITY_FLAG_LANGUAGE = 0x020,
IDENTITY_FLAG_PROCESSOR_ARCHITECTURE = 0x040,
IDENTITY_FLAG_RETARGETABLE = 0x080,
IDENTITY_FLAG_PUBLIC_KEY_TOKEN_NULL = 0x100,
+ IDENTITY_FLAG_CUSTOM = 0x200,
+ IDENTITY_FLAG_CUSTOM_NULL = 0x400,
IDENTITY_FLAG_CONTENT_TYPE = 0x800,
IDENTITY_FLAG_FULL_NAME = (IDENTITY_FLAG_SIMPLE_NAME |
IDENTITY_FLAG_VERSION)
@@ -47,6 +50,7 @@ namespace BINDER_SPACE
// Need to pre-populate SBuffers because of bogus asserts
static const BYTE byteArr[] = { 0 };
m_publicKeyOrTokenBLOB.SetImmutable(byteArr, sizeof(byteArr));
+ m_customBLOB.SetImmutable(byteArr, sizeof(byteArr));
}
~AssemblyIdentity()
{
@@ -79,6 +83,7 @@ namespace BINDER_SPACE
SBuffer m_publicKeyOrTokenBLOB;
PEKIND m_kProcessorArchitecture;
AssemblyContentType m_kContentType;
+ SBuffer m_customBLOB;
DWORD m_dwIdentityFlags;
};
diff --git a/src/coreclr/binder/inc/bindertracing.h b/src/coreclr/binder/inc/bindertracing.h
index ca28c04519638..75d8270b8eee5 100644
--- a/src/coreclr/binder/inc/bindertracing.h
+++ b/src/coreclr/binder/inc/bindertracing.h
@@ -27,7 +27,7 @@ namespace BinderTracing
{
public:
// This class assumes the assembly spec will have a longer lifetime than itself
- AssemblyBindOperation(AssemblySpec *assemblySpec, const SString& assemblyPath = SString::Empty());
+ AssemblyBindOperation(AssemblySpec *assemblySpec, const WCHAR *assemblyPath = nullptr);
~AssemblyBindOperation();
void SetResult(PEAssembly *assembly, bool cached = false);
diff --git a/src/coreclr/binder/inc/stringlexer.hpp b/src/coreclr/binder/inc/stringlexer.hpp
index f08e046982c56..41af7e7baa18d 100644
--- a/src/coreclr/binder/inc/stringlexer.hpp
+++ b/src/coreclr/binder/inc/stringlexer.hpp
@@ -55,28 +55,32 @@ namespace BINDER_SPACE
inline StringLexer();
inline ~StringLexer();
- inline void Init(SString &inputString);
+ inline void Init(SString &inputString, BOOL fSupportEscaping);
static inline BOOL IsWhitespace(WCHAR wcChar);
static inline BOOL IsEOS(WCHAR wcChar);
static inline BOOL IsQuoteCharacter(WCHAR wcChar);
- BOOL IsSeparatorChar(WCHAR wcChar);
- LEXEME_TYPE GetLexemeType(WCHAR wcChar);
+ virtual BOOL IsSeparatorChar(WCHAR wcChar) = NULL;
+ virtual LEXEME_TYPE GetLexemeType(WCHAR wcChar) = NULL;
protected:
static const WCHAR INVALID_CHARACTER = -1;
- LEXEME_TYPE GetNextLexeme(SString ¤tString);
+ LEXEME_TYPE GetNextLexeme(SString ¤tString, BOOL fPermitUnescapedQuotes = FALSE);
inline WCHAR PopCharacter(BOOL *pfIsEscaped);
inline void PushCharacter(WCHAR wcCurrentChar,
BOOL fIsEscaped);
inline WCHAR GetRawCharacter();
+ inline void PushRawCharacter();
+ inline WCHAR DecodeUTF16Character();
inline WCHAR GetNextCharacter(BOOL *pfIsEscaped);
- LEXEME_TYPE ParseString(SString ¤tString);
+ inline WCHAR ParseUnicode();
+ LEXEME_TYPE ParseString(SString ¤tString,
+ BOOL fPermitUnescapeQuotes);
void TrimTrailingWhiteSpaces(SString ¤tString);
@@ -85,6 +89,8 @@ namespace BINDER_SPACE
WCHAR m_wcCurrentChar;
BOOL m_fCurrentCharIsEscaped;
+ BOOL m_fSupportEscaping;
+ BOOL m_fReadRawCharacter;
};
#include "stringlexer.inl"
diff --git a/src/coreclr/binder/inc/stringlexer.inl b/src/coreclr/binder/inc/stringlexer.inl
index 42f7f73ed0bbc..bfe4bddeaa4c1 100644
--- a/src/coreclr/binder/inc/stringlexer.inl
+++ b/src/coreclr/binder/inc/stringlexer.inl
@@ -25,10 +25,12 @@ StringLexer::~StringLexer()
// Nothing to do here
}
-void StringLexer::Init(SString &inputString)
+void StringLexer::Init(SString &inputString, BOOL fSupportEscaping)
{
m_cursor = inputString.Begin();
m_end = inputString.End();
+ m_fSupportEscaping = fSupportEscaping;
+ m_fReadRawCharacter = FALSE;
}
BOOL StringLexer::IsWhitespace(WCHAR wcChar)
@@ -53,7 +55,6 @@ WCHAR StringLexer::PopCharacter(BOOL *pfIsEscaped)
{
m_wcCurrentChar = INVALID_CHARACTER;
*pfIsEscaped = m_fCurrentCharIsEscaped;
- m_cursor++;
}
else
{
@@ -70,63 +71,172 @@ void StringLexer::PushCharacter(WCHAR wcCurrentChar,
m_wcCurrentChar = wcCurrentChar;
m_fCurrentCharIsEscaped = fIsEscaped;
- m_cursor--;
}
WCHAR StringLexer::GetRawCharacter()
{
WCHAR wcCurrentChar = 0;
- if (m_cursor < m_end)
+ if (m_cursor <= m_end)
{
wcCurrentChar = m_cursor[0];
+ m_fReadRawCharacter = TRUE;
m_cursor++;
+ }
+ else
+ {
+ m_fReadRawCharacter = FALSE;
+ }
- // do not allow \0 anywhere in the string.
- if (wcCurrentChar == 0)
- {
- wcCurrentChar = INVALID_CHARACTER;
- }
+ return wcCurrentChar;
+}
+
+void StringLexer::PushRawCharacter()
+{
+ if (m_fReadRawCharacter)
+ {
+ m_cursor--;
+ m_fReadRawCharacter = FALSE;
+ }
+}
+
+WCHAR StringLexer::DecodeUTF16Character()
+{
+ // See http://www.ietf.org/rfc/rfc2781.txt for details on UTF-16 encoding.
+
+ WCHAR wcCurrentChar = 0;
+ SCOUNT_T nCharacters = m_end - m_cursor + 1;
+ WCHAR wcChar1 = GetRawCharacter();
+
+ if (wcChar1 < 0xd800)
+ {
+ wcCurrentChar = wcChar1;
}
else
{
- // EOS
- wcCurrentChar = 0;
+ // StringLexer is not designed to handle UTF-16 characters beyond the Basic Multilingual Plane,
+ // since it stores all characters in 16-bit WCHARs.
+ // However, since the vast majority of the time, we (Microsoft) produce the manifests,
+ // this is likely a non-scenario, as the other Unicode planes would never be used in practice.
+
+ if (wcChar1 <= 0xdbff) // 0xd800 - 0xdbff indicates the first WCHAR of a surrogate pair
+ {
+ if (nCharacters >= 2)
+ {
+ GetRawCharacter(); // Skip the second WCHAR of the surrogate pair
+ }
+ }
+ // Otherwise, the character is either in the 0xdc00 - 0xdfff range, indicating the second WCHAR of a surrogate pair,
+ // or in the 0xE000 - 0xFFFF range, which has within it ranges of invalid characters, and which we conservatively treat
+ // as invalid.
+
+ wcCurrentChar = INVALID_CHARACTER;
}
return wcCurrentChar;
}
+
WCHAR StringLexer::GetNextCharacter(BOOL *pfIsEscaped)
{
*pfIsEscaped = FALSE;
- WCHAR wcCurrentChar = GetRawCharacter();
+ WCHAR wcCurrentChar = GetRawCharacter(); // DecodeUTF16Character()
if (wcCurrentChar == L'\\')
{
- WCHAR wcTempChar = GetRawCharacter();
+ WCHAR wcTempChar = GetRawCharacter(); // DecodeUTF16Character()
- // Handle standard escapes
- switch (wcTempChar)
+ if (m_fSupportEscaping)
+ {
+ // Handle standard escapes
+ switch (wcTempChar)
+ {
+ case L'"':
+ case L'\'':
+ case L',':
+ case L'\\':
+ case L'/':
+ case L'=':
+ break;
+ case L't':
+ wcTempChar = 9;
+ break;
+ case L'n':
+ wcTempChar = 10;
+ break;
+ case L'r':
+ wcTempChar = 13;
+ break;
+ case L'u':
+ wcTempChar = ParseUnicode();
+ break;
+ default:
+ return INVALID_CHARACTER;
+ }
+
+ *pfIsEscaped = TRUE;
+ wcCurrentChar = wcTempChar;
+ }
+ else
+ {
+ // Do not handle escapes except for quotes
+ switch (wcTempChar)
+ {
+ case L'"':
+ case L'\'':
+ *pfIsEscaped = TRUE;
+ wcCurrentChar = wcTempChar;
+ break;
+ default:
+ PushRawCharacter();
+ break;
+ }
+ }
+ }
+
+ return wcCurrentChar;
+}
+
+WCHAR StringLexer::ParseUnicode()
+{
+ int nCharacters = 0;
+ WCHAR wcUnicodeChar = 0;
+
+ for(;;)
+ {
+ WCHAR wcCurrentChar = DecodeUTF16Character();
+ nCharacters++;
+
+ if (wcCurrentChar == L';')
{
- case L'"':
- case L'\'':
- case L',':
- case L'\\':
- case L'=':
- case L't':
- case L'n':
- case L'r':
break;
- default:
+ }
+ else if ((wcCurrentChar == INVALID_CHARACTER) || (nCharacters >= 9))
+ {
return INVALID_CHARACTER;
}
- *pfIsEscaped = TRUE;
- wcCurrentChar = wcTempChar;
+ wcUnicodeChar <<= 4;
+
+ if ((wcCurrentChar >= L'0') && (wcCurrentChar <= L'9'))
+ {
+ wcUnicodeChar += (wcCurrentChar - L'0');
+ }
+ else if ((wcCurrentChar >= L'a') && (wcCurrentChar <= L'f'))
+ {
+ wcUnicodeChar += (wcCurrentChar - L'a') + 10;
+ }
+ else if ((wcCurrentChar >= L'A') && (wcCurrentChar <= L'F'))
+ {
+ wcUnicodeChar += (wcCurrentChar - L'A') + 10;
+ }
+ else
+ {
+ return INVALID_CHARACTER;
+ }
}
- return wcCurrentChar;
+ return wcUnicodeChar;
}
#endif
diff --git a/src/coreclr/binder/inc/textualidentityparser.hpp b/src/coreclr/binder/inc/textualidentityparser.hpp
index 2b60c3110f37f..a5187d254a652 100644
--- a/src/coreclr/binder/inc/textualidentityparser.hpp
+++ b/src/coreclr/binder/inc/textualidentityparser.hpp
@@ -28,9 +28,12 @@ namespace BINDER_SPACE
TextualIdentityParser(AssemblyIdentity *pAssemblyIdentity);
~TextualIdentityParser();
- static HRESULT Parse(/* in */ SString &textualIdentity,
- /* out */ AssemblyIdentity *pAssemblyIdentity);
+ virtual BOOL IsSeparatorChar(WCHAR wcChar);
+ virtual StringLexer::LEXEME_TYPE GetLexemeType(WCHAR wcChar);
+ static HRESULT Parse(/* in */ SString &textualIdentity,
+ /* out */ AssemblyIdentity *pAssemblyIdentity,
+ /* in */ BOOL fPermitUnescapedQuotes = FALSE);
static HRESULT ToString(/* in */ AssemblyIdentity *pAssemblyIdentity,
/* in */ DWORD dwIdentityFlags,
/* out */ SString &textualIdentity);
@@ -42,7 +45,6 @@ namespace BINDER_SPACE
/* in */ BOOL fValidateHex,
/* in */ BOOL fIsToken,
/* out */ SBuffer &publicKeyOrTokenBLOB);
-
static void BlobToHex(/* in */ SBuffer &publicKeyOrTokenBLOB,
/* out */ SString &publicKeyOrToken);
@@ -50,7 +52,8 @@ namespace BINDER_SPACE
/* out */ SString &contentString);
protected:
- BOOL Parse(/* in */ SString &textualIdentity);
+ BOOL Parse(/* in */ SString &textualIdentity,
+ /* in */ BOOL fPermitUnescapedQuotes = FALSE);
BOOL PopulateAssemblyIdentity(/* in */ SString &attributeString,
/* in */ SString &valueString);
diff --git a/src/coreclr/binder/stringlexer.cpp b/src/coreclr/binder/stringlexer.cpp
index 44ec23e3b517c..b6b722fa77ab9 100644
--- a/src/coreclr/binder/stringlexer.cpp
+++ b/src/coreclr/binder/stringlexer.cpp
@@ -19,7 +19,7 @@
namespace BINDER_SPACE
{
StringLexer::LEXEME_TYPE
- StringLexer::GetNextLexeme(SString ¤tString)
+ StringLexer::GetNextLexeme(SString ¤tString, BOOL fPermitUnescapedQuotes)
{
BOOL fIsEscaped = FALSE;
WCHAR wcCurrentChar = INVALID_CHARACTER;
@@ -43,11 +43,11 @@ namespace BINDER_SPACE
// First character of string lexeme; push it back
PushCharacter(wcCurrentChar, fIsEscaped);
- return ParseString(currentString);
+ return ParseString(currentString, fPermitUnescapedQuotes);
}
StringLexer::LEXEME_TYPE
- StringLexer::ParseString(SString ¤tString)
+ StringLexer::ParseString(SString ¤tString, BOOL fPermitUnescapedQuotes)
{
BOOL fIsFirstCharacter = TRUE;
WCHAR wcCurrentChar = INVALID_CHARACTER;
@@ -99,7 +99,7 @@ namespace BINDER_SPACE
break;
}
- if (!fIsEscaped && IsQuoteCharacter(wcCurrentChar) && !IsQuoteCharacter(wcOpeningQuote))
+ if (!fPermitUnescapedQuotes && !fIsEscaped && IsQuoteCharacter(wcCurrentChar) && !IsQuoteCharacter(wcOpeningQuote))
{
// Unescaped quotes in the middle of the string are an error
return LEXEME_TYPE_INVALID;
@@ -147,24 +147,4 @@ namespace BINDER_SPACE
currentString.Truncate(cursor + 1);
}
}
-
- BOOL StringLexer::IsSeparatorChar(WCHAR wcChar)
- {
- return ((wcChar == W(',')) || (wcChar == W('=')));
- }
-
- StringLexer::LEXEME_TYPE StringLexer::GetLexemeType(WCHAR wcChar)
- {
- switch (wcChar)
- {
- case W('='):
- return LEXEME_TYPE_EQUALS;
- case W(','):
- return LEXEME_TYPE_COMMA;
- case 0:
- return LEXEME_TYPE_END_OF_STREAM;
- default:
- return LEXEME_TYPE_STRING;
- }
- }
};
diff --git a/src/coreclr/binder/textualidentityparser.cpp b/src/coreclr/binder/textualidentityparser.cpp
index 35587df3cb7e4..f69e0bf66b202 100644
--- a/src/coreclr/binder/textualidentityparser.cpp
+++ b/src/coreclr/binder/textualidentityparser.cpp
@@ -200,9 +200,30 @@ namespace BINDER_SPACE
// Nothing to do here
}
+ BOOL TextualIdentityParser::IsSeparatorChar(WCHAR wcChar)
+ {
+ return ((wcChar == W(',')) || (wcChar == W('=')));
+ }
+
+ StringLexer::LEXEME_TYPE TextualIdentityParser::GetLexemeType(WCHAR wcChar)
+ {
+ switch (wcChar)
+ {
+ case W('='):
+ return LEXEME_TYPE_EQUALS;
+ case W(','):
+ return LEXEME_TYPE_COMMA;
+ case 0:
+ return LEXEME_TYPE_END_OF_STREAM;
+ default:
+ return LEXEME_TYPE_STRING;
+ }
+ }
+
/* static */
HRESULT TextualIdentityParser::Parse(SString &textualIdentity,
- AssemblyIdentity *pAssemblyIdentity)
+ AssemblyIdentity *pAssemblyIdentity,
+ BOOL fPermitUnescapedQuotes)
{
HRESULT hr = S_OK;
@@ -212,7 +233,7 @@ namespace BINDER_SPACE
{
TextualIdentityParser identityParser(pAssemblyIdentity);
- if (!identityParser.Parse(textualIdentity))
+ if (!identityParser.Parse(textualIdentity, fPermitUnescapedQuotes))
{
IF_FAIL_GO(FUSION_E_INVALID_NAME);
}
@@ -314,6 +335,18 @@ namespace BINDER_SPACE
textualIdentity.Append(ContentTypeToString(pAssemblyIdentity->m_kContentType));
}
+ if (AssemblyIdentity::Have(dwIdentityFlags, AssemblyIdentity::IDENTITY_FLAG_CUSTOM))
+ {
+ textualIdentity.Append(W(", Custom="));
+ tmpString.Clear();
+ BlobToHex(pAssemblyIdentity->m_customBLOB, tmpString);
+ textualIdentity.Append(tmpString);
+ }
+ else if (AssemblyIdentity::Have(dwIdentityFlags,
+ AssemblyIdentity::IDENTITY_FLAG_CUSTOM_NULL))
+ {
+ textualIdentity.Append(W(", Custom=null"));
+ }
}
EX_CATCH_HRESULT(hr);
@@ -453,19 +486,19 @@ namespace BINDER_SPACE
publicKeyOrToken.CloseBuffer(cbPublicKeyOrTokenBLOB * 2);
}
- BOOL TextualIdentityParser::Parse(SString &textualIdentity)
+ BOOL TextualIdentityParser::Parse(SString &textualIdentity, BOOL fPermitUnescapedQuotes)
{
BOOL fIsValid = TRUE;
SString unicodeTextualIdentity;
// Lexer modifies input string
textualIdentity.ConvertToUnicode(unicodeTextualIdentity);
- Init(unicodeTextualIdentity);
+ Init(unicodeTextualIdentity, TRUE /* fSupportEscaping */);
SmallStackSString currentString;
// Identity format is simple name (, attr = value)*
- GO_IF_NOT_EXPECTED(GetNextLexeme(currentString), LEXEME_TYPE_STRING);
+ GO_IF_NOT_EXPECTED(GetNextLexeme(currentString, fPermitUnescapedQuotes), LEXEME_TYPE_STRING);
m_pAssemblyIdentity->m_simpleName.Set(currentString);
m_pAssemblyIdentity->m_simpleName.Normalize();
m_pAssemblyIdentity->SetHave(AssemblyIdentity::IDENTITY_FLAG_SIMPLE_NAME);
@@ -499,7 +532,7 @@ namespace BINDER_SPACE
// Lexer modifies input string
textualString.ConvertToUnicode(unicodeTextualString);
- Init(unicodeTextualString);
+ Init(unicodeTextualString, TRUE /* fSupportEscaping */);
SmallStackSString currentString;
GO_IF_NOT_EXPECTED(GetNextLexeme(currentString), LEXEME_TYPE_STRING);
@@ -516,7 +549,8 @@ namespace BINDER_SPACE
{
BOOL fIsValid = TRUE;
- if (EqualsCaseInsensitive(attributeString, W("culture")))
+ if (EqualsCaseInsensitive(attributeString, W("culture")) ||
+ EqualsCaseInsensitive(attributeString, W("language")))
{
GO_IF_SEEN(AssemblyIdentity::IDENTITY_FLAG_CULTURE);
GO_IF_WILDCARD(valueString);
@@ -552,7 +586,8 @@ namespace BINDER_SPACE
GO_IF_SEEN(AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN);
GO_IF_WILDCARD(valueString);
- if (!EqualsCaseInsensitive(valueString, W("null")))
+ if (!EqualsCaseInsensitive(valueString, W("null")) &&
+ !EqualsCaseInsensitive(valueString, W("neutral")))
{
GO_IF_VALIDATE_FAILED(ValidatePublicKeyToken,
AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN);
@@ -571,7 +606,8 @@ namespace BINDER_SPACE
GO_IF_SEEN(AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY_TOKEN);
GO_IF_SEEN(AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY);
- if (!EqualsCaseInsensitive(valueString, W("null")))
+ if (!EqualsCaseInsensitive(valueString, W("null")) &&
+ !EqualsCaseInsensitive(valueString, W("neutral")))
{
GO_IF_VALIDATE_FAILED(ValidatePublicKey, AssemblyIdentity::IDENTITY_FLAG_PUBLIC_KEY);
HexToBlob(valueString,
@@ -625,6 +661,23 @@ namespace BINDER_SPACE
fIsValid = FALSE;
}
}
+ else if (EqualsCaseInsensitive(attributeString, W("custom")))
+ {
+ GO_IF_SEEN(AssemblyIdentity::IDENTITY_FLAG_CUSTOM);
+
+ if (EqualsCaseInsensitive(valueString, W("null")))
+ {
+ m_pAssemblyIdentity->SetHave(AssemblyIdentity::IDENTITY_FLAG_CUSTOM_NULL);
+ }
+ else
+ {
+ GO_IF_VALIDATE_FAILED(ValidateHex, AssemblyIdentity::IDENTITY_FLAG_CUSTOM);
+ HexToBlob(valueString,
+ FALSE /* fValidateHex */,
+ FALSE /* fIsToken */,
+ m_pAssemblyIdentity->m_customBLOB);
+ }
+ }
Exit:
return fIsValid;
diff --git a/src/coreclr/build-runtime.cmd b/src/coreclr/build-runtime.cmd
index 30cd7d2785267..ed9d735a7d428 100644
--- a/src/coreclr/build-runtime.cmd
+++ b/src/coreclr/build-runtime.cmd
@@ -345,9 +345,6 @@ for /f "delims=" %%a in ("-%__RequestedBuildComponents%-") do (
if not "!string:-nativeaot-=!"=="!string!" (
set __CMakeTarget=!__CMakeTarget! nativeaot
)
- if not "!string:-spmi-=!"=="!string!" (
- set __CMakeTarget=!__CMakeTarget! spmi
- )
)
if [!__CMakeTarget!] == [] (
set __CMakeTarget=install
@@ -748,7 +745,7 @@ echo -all: Builds all configurations and platforms.
echo Build architecture: one of -x64, -x86, -arm, -arm64 ^(default: -x64^).
echo Build type: one of -Debug, -Checked, -Release ^(default: -Debug^).
echo -component ^ : specify this option one or more times to limit components built to those specified.
-echo Allowed ^: hosts jit alljits runtime paltests iltools nativeaot spmi
+echo Allowed ^: hosts jit alljits runtime paltests iltools
echo -enforcepgo: verify after the build that PGO was used for key DLLs, and fail the build if not
echo -pgoinstrument: generate instrumented code for profile guided optimization enabled binaries.
echo -cmakeargs: user-settable additional arguments passed to CMake.
diff --git a/src/coreclr/build-runtime.sh b/src/coreclr/build-runtime.sh
index a1e03198ac6df..8d42b92ce95c0 100755
--- a/src/coreclr/build-runtime.sh
+++ b/src/coreclr/build-runtime.sh
@@ -22,7 +22,7 @@ usage_list+=("-pgodatapath: path to profile guided optimization data.")
usage_list+=("-pgoinstrument: generate instrumented code for profile guided optimization enabled binaries.")
usage_list+=("-skipcrossarchnative: Skip building cross-architecture native binaries.")
usage_list+=("-staticanalyzer: use scan_build static analyzer.")
-usage_list+=("-component: Build individual components instead of the full project. Available options are 'hosts', 'jit', 'runtime', 'paltests', 'alljits', 'iltools', 'nativeaot', and 'spmi'. Can be specified multiple times.")
+usage_list+=("-component: Build individual components instead of the full project. Available options are 'hosts', 'jit', 'runtime', 'paltests', 'alljits', 'iltools', and 'nativeaot'. Can be specified multiple times.")
setup_dirs_local()
{
diff --git a/src/coreclr/classlibnative/float/floatdouble.cpp b/src/coreclr/classlibnative/float/floatdouble.cpp
index d20b772eb2207..67aceb60ea13e 100644
--- a/src/coreclr/classlibnative/float/floatdouble.cpp
+++ b/src/coreclr/classlibnative/float/floatdouble.cpp
@@ -42,6 +42,15 @@
#pragma float_control(precise, off)
#endif
+/*=====================================Abs======================================
+**
+==============================================================================*/
+FCIMPL1_V(double, COMDouble::Abs, double x)
+ FCALL_CONTRACT;
+
+ return fabs(x);
+FCIMPLEND
+
/*=====================================Acos=====================================
**
==============================================================================*/
diff --git a/src/coreclr/classlibnative/float/floatsingle.cpp b/src/coreclr/classlibnative/float/floatsingle.cpp
index 1694fd78cb846..965998fbaa2ba 100644
--- a/src/coreclr/classlibnative/float/floatsingle.cpp
+++ b/src/coreclr/classlibnative/float/floatsingle.cpp
@@ -8,6 +8,18 @@
#include "floatsingle.h"
+// Windows x86 and Windows ARM/ARM64 may not define _isnanf() or _copysignf() but they do
+// define _isnan() and _copysign(). We will redirect the macros to these other functions if
+// the macro is not defined for the platform. This has the side effect of a possible implicit
+// upcasting for arguments passed in and an explicit downcasting for the _copysign() call.
+#if (defined(TARGET_X86) || defined(TARGET_ARM) || defined(TARGET_ARM64)) && !defined(TARGET_UNIX)
+
+#if !defined(_copysignf)
+#define _copysignf (float)_copysign
+#endif
+
+#endif
+
// The default compilation mode is /fp:precise, which disables floating-point intrinsics. This
// default compilation mode has previously caused performance regressions in floating-point code.
// We enable /fp:fast semantics for the majority of the math functions, as it will speed up performance
@@ -28,6 +40,15 @@
#pragma float_control(precise, off)
#endif
+/*=====================================Abs=====================================
+**
+==============================================================================*/
+FCIMPL1_V(float, COMSingle::Abs, float x)
+ FCALL_CONTRACT;
+
+ return fabsf(x);
+FCIMPLEND
+
/*=====================================Acos=====================================
**
==============================================================================*/
diff --git a/src/coreclr/classlibnative/inc/floatdouble.h b/src/coreclr/classlibnative/inc/floatdouble.h
index 43fecbd47431f..9163349127ca1 100644
--- a/src/coreclr/classlibnative/inc/floatdouble.h
+++ b/src/coreclr/classlibnative/inc/floatdouble.h
@@ -9,6 +9,7 @@
class COMDouble {
public:
+ FCDECL1_V(static double, Abs, double x);
FCDECL1_V(static double, Acos, double x);
FCDECL1_V(static double, Acosh, double x);
FCDECL1_V(static double, Asin, double x);
diff --git a/src/coreclr/classlibnative/inc/floatsingle.h b/src/coreclr/classlibnative/inc/floatsingle.h
index 765032ce6371e..09a0512b230db 100644
--- a/src/coreclr/classlibnative/inc/floatsingle.h
+++ b/src/coreclr/classlibnative/inc/floatsingle.h
@@ -9,6 +9,7 @@
class COMSingle {
public:
+ FCDECL1_V(static float, Abs, float x);
FCDECL1_V(static float, Acos, float x);
FCDECL1_V(static float, Acosh, float x);
FCDECL1_V(static float, Asin, float x);
diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake
index 533d5255002b4..d5fc9f5e1ee8e 100644
--- a/src/coreclr/clrdefinitions.cmake
+++ b/src/coreclr/clrdefinitions.cmake
@@ -92,6 +92,7 @@ endif(CLR_CMAKE_TARGET_WIN32)
add_definitions(-DFEATURE_BASICFREEZE)
add_definitions(-DFEATURE_CORECLR)
+add_definitions(-DFEATURE_CORESYSTEM)
if(FEATURE_DBGIPC)
add_definitions(-DFEATURE_DBGIPC_TRANSPORT_DI)
add_definitions(-DFEATURE_DBGIPC_TRANSPORT_VM)
diff --git a/src/coreclr/components.cmake b/src/coreclr/components.cmake
index 3eaa2c966bf32..c23a38539247e 100644
--- a/src/coreclr/components.cmake
+++ b/src/coreclr/components.cmake
@@ -6,7 +6,6 @@ add_component(runtime)
add_component(paltests paltests_install)
add_component(iltools)
add_component(nativeaot)
-add_component(spmi)
# Define coreclr_all as the fallback component and make every component depend on this component.
# iltools and paltests should be minimal subsets, so don't add a dependency on coreclr_misc
diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp
index 7936b3a1279a8..9aaf6e6e4cb17 100644
--- a/src/coreclr/debug/daccess/daccess.cpp
+++ b/src/coreclr/debug/daccess/daccess.cpp
@@ -6542,6 +6542,61 @@ bool ClrDataAccess::GetILImageInfoFromNgenPEFile(PEAssembly *pPEAssembly,
return true;
}
+#if defined(FEATURE_CORESYSTEM)
+/* static */
+// We extract "ni.dll from the NGEN image name to obtain the IL image name.
+// In the end we add given ilExtension.
+// This dependecy is based on Apollo installer behavior.
+bool ClrDataAccess::GetILImageNameFromNgenImage( LPCWSTR ilExtension,
+ _Out_writes_(cchFilePath) LPWSTR wszFilePath,
+ const DWORD cchFilePath)
+{
+ if (wszFilePath == NULL || cchFilePath == 0)
+ {
+ return false;
+ }
+
+ _wcslwr_s(wszFilePath, cchFilePath);
+ // Find the "ni.dll" extension.
+ // If none exists use NGEN image name.
+ //
+ const WCHAR* ngenExtension = W("ni.dll");
+
+ if (wcslen(ilExtension) <= wcslen(ngenExtension))
+ {
+ LPWSTR wszFileExtension = wcsstr(wszFilePath, ngenExtension);
+ if (wszFileExtension != 0)
+ {
+ LPWSTR wszNextFileExtension = wszFileExtension;
+ // Find last occurrence
+ do
+ {
+ wszFileExtension = wszNextFileExtension;
+ wszNextFileExtension = wcsstr(wszFileExtension + 1, ngenExtension);
+ } while (wszNextFileExtension != 0);
+
+ // Overwrite ni.dll with ilExtension
+ if (!memcpy_s(wszFileExtension,
+ wcslen(ngenExtension)*sizeof(WCHAR),
+ ilExtension,
+ wcslen(ilExtension)*sizeof(WCHAR)))
+ {
+ wszFileExtension[wcslen(ilExtension)] = '\0';
+ return true;
+ }
+ }
+ }
+
+ //Use ngen filename if there is no ".ni"
+ if (wcsstr(wszFilePath, W(".ni")) == 0)
+ {
+ return true;
+ }
+
+ return false;
+}
+#endif // FEATURE_CORESYSTEM
+
void *
ClrDataAccess::GetMetaDataFromHost(PEAssembly* pPEAssembly,
bool* isAlternate)
@@ -6650,6 +6705,7 @@ ClrDataAccess::GetMetaDataFromHost(PEAssembly* pPEAssembly,
goto ErrExit;
}
+#if defined(FEATURE_CORESYSTEM)
const WCHAR* ilExtension = W("dll");
WCHAR ngenImageName[MAX_LONGPATH] = {0};
if (wcscpy_s(ngenImageName, ARRAY_SIZE(ngenImageName), uniPath) != 0)
@@ -6660,6 +6716,12 @@ ClrDataAccess::GetMetaDataFromHost(PEAssembly* pPEAssembly,
{
goto ErrExit;
}
+ // Transform NGEN image name into IL Image name
+ if (!GetILImageNameFromNgenImage(ilExtension, uniPath, ARRAY_SIZE(uniPath)))
+ {
+ goto ErrExit;
+ }
+#endif//FEATURE_CORESYSTEM
// RVA size in ngen image and IL image is the same. Because the only
// different is in RVA. That is 4 bytes column fixed.
@@ -6881,6 +6943,11 @@ bool ClrDataAccess::TargetConsistencyAssertsEnabled()
return m_fEnableTargetConsistencyAsserts;
}
+#ifdef FEATURE_CORESYSTEM
+#define ctime_s _ctime32_s
+#define time_t __time32_t
+#endif
+
//
// VerifyDlls - Validate that the mscorwks in the target matches this version of mscordacwks
// Only done on Windows and Mac builds at the moment.
@@ -7436,8 +7503,34 @@ BOOL OutOfProcessExceptionEventGetProcessIdAndThreadId(HANDLE hProcess, HANDLE h
*pPId = (DWORD)(SIZE_T)hProcess;
*pThreadId = (DWORD)(SIZE_T)hThread;
#else
- *pPId = GetProcessIdOfThread(hThread);
- *pThreadId = GetThreadId(hThread);
+#if !defined(FEATURE_CORESYSTEM)
+ HMODULE hKernel32 = WszGetModuleHandle(W("kernel32.dll"));
+#else
+ HMODULE hKernel32 = WszGetModuleHandle(W("api-ms-win-core-processthreads-l1-1-1.dll"));
+#endif
+ if (hKernel32 == NULL)
+ {
+ return FALSE;
+ }
+
+ typedef WINBASEAPI DWORD (WINAPI GET_PROCESSID_OF_THREAD)(HANDLE);
+ GET_PROCESSID_OF_THREAD * pGetProcessIdOfThread;
+
+ typedef WINBASEAPI DWORD (WINAPI GET_THREADID)(HANDLE);
+ GET_THREADID * pGetThreadId;
+
+ pGetProcessIdOfThread = (GET_PROCESSID_OF_THREAD *)GetProcAddress(hKernel32, "GetProcessIdOfThread");
+ pGetThreadId = (GET_THREADID *)GetProcAddress(hKernel32, "GetThreadId");
+
+ // OOP callbacks are used on Win7 or later. We should have having below two APIs available.
+ _ASSERTE((pGetProcessIdOfThread != NULL) && (pGetThreadId != NULL));
+ if ((pGetProcessIdOfThread == NULL) || (pGetThreadId == NULL))
+ {
+ return FALSE;
+ }
+
+ *pPId = (*pGetProcessIdOfThread)(hThread);
+ *pThreadId = (*pGetThreadId)(hThread);
#endif // TARGET_UNIX
return TRUE;
}
diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp
index 1ff143cf7cce1..ebb5d12c0ce3a 100644
--- a/src/coreclr/debug/daccess/dacdbiimpl.cpp
+++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp
@@ -657,21 +657,21 @@ void DacDbiInterfaceImpl::GetAppDomainFullName(
// Get the values of the JIT Optimization and EnC flags.
void DacDbiInterfaceImpl::GetCompilerFlags (
- VMPTR_DomainAssembly vmDomainAssembly,
+ VMPTR_DomainFile vmDomainFile,
BOOL *pfAllowJITOpts,
BOOL *pfEnableEnC)
{
DD_ENTER_MAY_THROW;
- DomainAssembly * pDomainAssembly = vmDomainAssembly.GetDacPtr();
+ DomainFile * pDomainFile = vmDomainFile.GetDacPtr();
- if (pDomainAssembly == NULL)
+ if (pDomainFile == NULL)
{
ThrowHR(E_FAIL);
}
// Get the underlying module - none of this is AppDomain specific
- Module * pModule = pDomainAssembly->GetModule();
+ Module * pModule = pDomainFile->GetModule();
DWORD dwBits = pModule->GetDebuggerInfoBits();
*pfAllowJITOpts = !CORDisableJITOptimizations(dwBits);
*pfEnableEnC = pModule->IsEditAndContinueEnabled();
@@ -712,15 +712,15 @@ bool DacDbiInterfaceImpl::CanSetEnCBits(Module * pModule)
} // DacDbiInterfaceImpl::SetEnCBits
// Set the values of the JIT optimization and EnC flags.
-HRESULT DacDbiInterfaceImpl::SetCompilerFlags(VMPTR_DomainAssembly vmDomainAssembly,
+HRESULT DacDbiInterfaceImpl::SetCompilerFlags(VMPTR_DomainFile vmDomainFile,
BOOL fAllowJitOpts,
BOOL fEnableEnC)
{
DD_ENTER_MAY_THROW;
DWORD dwBits = 0;
- DomainAssembly * pDomainAssembly = vmDomainAssembly.GetDacPtr();
- Module * pModule = pDomainAssembly->GetModule();
+ DomainFile * pDomainFile = vmDomainFile.GetDacPtr();
+ Module * pModule = pDomainFile->GetCurrentModule();
HRESULT hr = S_OK;
@@ -1082,15 +1082,15 @@ ULONG DacDbiInterfaceImpl::TranslateInstrumentedILOffsetToOriginal(ULONG
// a module and a token. The info will come from a MethodDesc, if
// one exists or from metadata.
//
-void DacDbiInterfaceImpl::GetILCodeAndSig(VMPTR_DomainAssembly vmDomainAssembly,
+void DacDbiInterfaceImpl::GetILCodeAndSig(VMPTR_DomainFile vmDomainFile,
mdToken functionToken,
TargetBuffer * pCodeInfo,
mdToken * pLocalSigToken)
{
DD_ENTER_MAY_THROW;
- DomainAssembly * pDomainAssembly = vmDomainAssembly.GetDacPtr();
- Module * pModule = pDomainAssembly->GetModule();
+ DomainFile * pDomainFile = vmDomainFile.GetDacPtr();
+ Module * pModule = pDomainFile->GetCurrentModule();
RVA methodRVA = 0;
DWORD implFlags;
@@ -1323,7 +1323,7 @@ void DacDbiInterfaceImpl::GetMethodRegionInfo(MethodDesc * pMethodDe
// isn't currently available. In this case, all values in pCodeInfo will be
// cleared.
-void DacDbiInterfaceImpl::GetNativeCodeInfo(VMPTR_DomainAssembly vmDomainAssembly,
+void DacDbiInterfaceImpl::GetNativeCodeInfo(VMPTR_DomainFile vmDomainFile,
mdToken functionToken,
NativeCodeFunctionData * pCodeInfo)
{
@@ -1334,8 +1334,8 @@ void DacDbiInterfaceImpl::GetNativeCodeInfo(VMPTR_DomainAssembly vmDomai
// pre-initialize:
pCodeInfo->Clear();
- DomainAssembly * pDomainAssembly = vmDomainAssembly.GetDacPtr();
- Module * pModule = pDomainAssembly->GetModule();
+ DomainFile * pDomainFile = vmDomainFile.GetDacPtr();
+ Module * pModule = pDomainFile->GetCurrentModule();
MethodDesc* pMethodDesc = FindLoadedMethodRefOrDef(pModule, functionToken);
pCodeInfo->vmNativeCodeMethodDescToken.SetHostPtr(pMethodDesc);
@@ -1760,7 +1760,7 @@ void DacDbiInterfaceImpl::GetClassInfo(VMPTR_AppDomain vmAppDomain,
} // DacDbiInterfaceImpl::GetClassInfo
// DacDbi API: Get field information and object size for an instantiated generic type
-void DacDbiInterfaceImpl::GetInstantiationFieldInfo (VMPTR_DomainAssembly vmDomainAssembly,
+void DacDbiInterfaceImpl::GetInstantiationFieldInfo (VMPTR_DomainFile vmDomainFile,
VMPTR_TypeHandle vmThExact,
VMPTR_TypeHandle vmThApprox,
DacDbiArrayList * pFieldList,
@@ -1768,9 +1768,9 @@ void DacDbiInterfaceImpl::GetInstantiationFieldInfo (VMPTR_DomainAssembly
{
DD_ENTER_MAY_THROW;
- DomainAssembly * pDomainAssembly = vmDomainAssembly.GetDacPtr();
- _ASSERTE(pDomainAssembly != NULL);
- AppDomain * pAppDomain = pDomainAssembly->GetAppDomain();
+ DomainFile * pDomainFile = vmDomainFile.GetDacPtr();
+ _ASSERTE(pDomainFile != NULL);
+ AppDomain * pAppDomain = pDomainFile->GetAppDomain();
TypeHandle thExact;
TypeHandle thApprox;
@@ -2503,11 +2503,11 @@ void DacDbiInterfaceImpl::GetClassTypeInfo(TypeHandle typeH
pTypeInfo->ClassTypeData.vmModule.SetDacTargetPtr(PTR_HOST_TO_TADDR(pModule));
if (pAppDomain)
{
- pTypeInfo->ClassTypeData.vmDomainAssembly.SetDacTargetPtr(PTR_HOST_TO_TADDR(pModule->GetDomainAssembly()));
+ pTypeInfo->ClassTypeData.vmDomainFile.SetDacTargetPtr(PTR_HOST_TO_TADDR(pModule->GetDomainFile()));
}
else
{
- pTypeInfo->ClassTypeData.vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ pTypeInfo->ClassTypeData.vmDomainFile = VMPTR_DomainFile::NullPtr();
}
} // DacDbiInterfaceImpl::GetClassTypeInfo
@@ -2567,7 +2567,7 @@ void DacDbiInterfaceImpl::TypeHandleToBasicTypeInfo(TypeHandle
case ELEMENT_TYPE_BYREF:
pTypeInfo->vmTypeHandle.SetDacTargetPtr(typeHandle.AsTAddr());
pTypeInfo->metadataToken = mdTokenNil;
- pTypeInfo->vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ pTypeInfo->vmDomainFile = VMPTR_DomainFile::NullPtr();
break;
case ELEMENT_TYPE_CLASS:
@@ -2590,11 +2590,11 @@ void DacDbiInterfaceImpl::TypeHandleToBasicTypeInfo(TypeHandle
pTypeInfo->vmModule.SetDacTargetPtr(PTR_HOST_TO_TADDR(pModule));
if (pAppDomain)
{
- pTypeInfo->vmDomainAssembly.SetDacTargetPtr(PTR_HOST_TO_TADDR(pModule->GetDomainAssembly()));
+ pTypeInfo->vmDomainFile.SetDacTargetPtr(PTR_HOST_TO_TADDR(pModule->GetDomainFile()));
}
else
{
- pTypeInfo->vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ pTypeInfo->vmDomainFile = VMPTR_DomainFile::NullPtr();
}
break;
}
@@ -2602,7 +2602,7 @@ void DacDbiInterfaceImpl::TypeHandleToBasicTypeInfo(TypeHandle
default:
pTypeInfo->vmTypeHandle = VMPTR_TypeHandle::NullPtr();
pTypeInfo->metadataToken = mdTokenNil;
- pTypeInfo->vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ pTypeInfo->vmDomainFile = VMPTR_DomainFile::NullPtr();
break;
}
return;
@@ -2889,8 +2889,8 @@ TypeHandle DacDbiInterfaceImpl::GetClassOrValueTypeHandle(DebuggerIPCE_BasicType
// otherwise, have the loader look it up using the metadata token and domain file
else
{
- DomainAssembly * pDomainAssembly = pData->vmDomainAssembly.GetDacPtr();
- Module * pModule = pDomainAssembly->GetModule();
+ DomainFile * pDomainFile = pData->vmDomainFile.GetDacPtr();
+ Module * pModule = pDomainFile->GetModule();
typeHandle = ClassLoader::LookupTypeDefOrRefInModule(pModule, pData->metadataToken);
if (typeHandle.IsNull())
@@ -3292,7 +3292,7 @@ void DacDbiInterfaceImpl::GetSimpleType(VMPTR_AppDomain vmAppDomain,
CorElementType simpleType,
mdTypeDef *pMetadataToken,
VMPTR_Module *pVmModule,
- VMPTR_DomainAssembly *pVmDomainAssembly)
+ VMPTR_DomainFile *pVmDomainFile)
{
DD_ENTER_MAY_THROW;
@@ -3300,8 +3300,8 @@ void DacDbiInterfaceImpl::GetSimpleType(VMPTR_AppDomain vmAppDomain,
// if we fail to get either a valid type handle or module, we will want to send back
// a NULL domain file too, so we'll to preinitialize this here.
- _ASSERTE(pVmDomainAssembly != NULL);
- *pVmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ _ASSERTE(pVmDomainFile != NULL);
+ *pVmDomainFile = VMPTR_DomainFile::NullPtr();
// FindLoadedElementType will return NULL if the type hasn't been loaded yet.
TypeHandle typeHandle = FindLoadedElementType(simpleType);
@@ -3322,8 +3322,8 @@ void DacDbiInterfaceImpl::GetSimpleType(VMPTR_AppDomain vmAppDomain,
if (pAppDomain)
{
- pVmDomainAssembly->SetHostPtr(pModule->GetDomainAssembly());
- if (pVmDomainAssembly->IsNull())
+ pVmDomainFile->SetHostPtr(pModule->GetDomainFile());
+ if (pVmDomainFile->IsNull())
ThrowHR(CORDBG_E_TARGET_INCONSISTENT);
}
}
@@ -3483,7 +3483,7 @@ HRESULT DacDbiInterfaceImpl::GetDelegateType(VMPTR_Object delegateObject, Delega
HRESULT DacDbiInterfaceImpl::GetDelegateFunctionData(
DelegateType delegateType,
VMPTR_Object delegateObject,
- OUT VMPTR_DomainAssembly *ppFunctionDomainAssembly,
+ OUT VMPTR_DomainFile *ppFunctionDomainFile,
OUT mdMethodDef *pMethodDef)
{
DD_ENTER_MAY_THROW;
@@ -3514,7 +3514,7 @@ HRESULT DacDbiInterfaceImpl::GetDelegateFunctionData(
if (hr != S_OK)
return hr;
- ppFunctionDomainAssembly->SetDacTargetPtr(dac_cast(pMD.GetDacPtr()->GetModule()->GetDomainAssembly()));
+ ppFunctionDomainFile->SetDacTargetPtr(dac_cast(pMD.GetDacPtr()->GetModule()->GetDomainFile()));
*pMethodDef = pMD.GetDacPtr()->GetMemberDef();
return hr;
@@ -3725,17 +3725,17 @@ void DacDbiInterfaceImpl::GetStackFramesFromException(VMPTR_Object vmObject, Dac
BaseDomain* pBaseDomain = currentElement.pFunc->GetAssembly()->GetDomain();
AppDomain* pDomain = NULL;
- DomainAssembly* pDomainAssembly = NULL;
+ DomainFile* pDomainFile = NULL;
pDomain = pBaseDomain->AsAppDomain();
_ASSERTE(pDomain != NULL);
- pDomainAssembly = pModule->GetDomainAssembly();
- _ASSERTE(pDomainAssembly != NULL);
+ pDomainFile = pModule->GetDomainFile();
+ _ASSERTE(pDomainFile != NULL);
currentFrame.vmAppDomain.SetHostPtr(pDomain);
- currentFrame.vmDomainAssembly.SetHostPtr(pDomainAssembly);
+ currentFrame.vmDomainFile.SetHostPtr(pDomainFile);
currentFrame.ip = currentElement.ip;
currentFrame.methodDef = currentElement.pFunc->GetMemberDef();
currentFrame.isLastForeignExceptionFrame = (currentElement.flags & STEF_LAST_FRAME_FROM_FOREIGN_STACK_TRACE) != 0;
@@ -3879,8 +3879,8 @@ FieldDesc * DacDbiInterfaceImpl::GetEnCFieldDesc(const EnCHangingFieldInfo * pEn
{
FieldDesc * pFD = NULL;
- DomainAssembly * pDomainAssembly = pEnCFieldInfo->GetObjectTypeData().vmDomainAssembly.GetDacPtr();
- Module * pModule = pDomainAssembly->GetModule();
+ DomainFile * pDomainFile = pEnCFieldInfo->GetObjectTypeData().vmDomainFile.GetDacPtr();
+ Module * pModule = pDomainFile->GetModule();
// get the type handle for the object
TypeHandle typeHandle = ClassLoader::LookupTypeDefOrRefInModule(pModule,
@@ -3918,8 +3918,8 @@ PTR_CBYTE DacDbiInterfaceImpl::GetPtrToEnCField(FieldDesc * pFD, const EnCHangin
#else
PTR_EditAndContinueModule pEnCModule;
- DomainAssembly * pDomainAssembly = pEnCFieldInfo->GetObjectTypeData().vmDomainAssembly.GetDacPtr();
- Module * pModule = pDomainAssembly->GetModule();
+ DomainFile * pDomainFile = pEnCFieldInfo->GetObjectTypeData().vmDomainFile.GetDacPtr();
+ Module * pModule = pDomainFile->GetModule();
// make sure we actually have an EditAndContinueModule
_ASSERTE(pModule->IsEditAndContinueCapable());
@@ -4066,7 +4066,7 @@ BOOL DacDbiInterfaceImpl::GetAssemblyPath(
// Get the manifest module for this assembly
Assembly * pAssembly = vmAssembly.GetDacPtr();
- Module * pManifestModule = pAssembly->GetModule();
+ Module * pManifestModule = pAssembly->GetManifestModule();
// Get the path for the manifest module.
// since we no longer support Win9x, we assume all paths will be in unicode format already
@@ -4090,8 +4090,8 @@ void DacDbiInterfaceImpl::ResolveTypeReference(const TypeRefData * pTypeRefInfo,
TypeRefData * pTargetRefInfo)
{
DD_ENTER_MAY_THROW;
- DomainAssembly * pDomainAssembly = pTypeRefInfo->vmDomainAssembly.GetDacPtr();
- Module * pReferencingModule = pDomainAssembly->GetModule();
+ DomainFile * pDomainFile = pTypeRefInfo->vmDomainFile.GetDacPtr();
+ Module * pReferencingModule = pDomainFile->GetCurrentModule();
BOOL fSuccess = FALSE;
// Resolve the type ref
@@ -4117,9 +4117,9 @@ void DacDbiInterfaceImpl::ResolveTypeReference(const TypeRefData * pTypeRefInfo,
_ASSERTE(pTargetModule != NULL);
_ASSERTE( TypeFromToken(targetTypeDef) == mdtTypeDef );
- AppDomain * pAppDomain = pDomainAssembly->GetAppDomain();
+ AppDomain * pAppDomain = pDomainFile->GetAppDomain();
- pTargetRefInfo->vmDomainAssembly.SetDacTargetPtr(PTR_HOST_TO_TADDR(pTargetModule->GetDomainAssembly()));
+ pTargetRefInfo->vmDomainFile.SetDacTargetPtr(PTR_HOST_TO_TADDR(pTargetModule->GetDomainFile()));
pTargetRefInfo->typeToken = targetTypeDef;
}
else
@@ -4347,19 +4347,19 @@ void DacDbiInterfaceImpl::GetSymbolsBuffer(VMPTR_Module vmModule, TargetBuffer *
-void DacDbiInterfaceImpl::GetModuleForDomainAssembly(VMPTR_DomainAssembly vmDomainAssembly, OUT VMPTR_Module * pModule)
+void DacDbiInterfaceImpl::GetModuleForDomainFile(VMPTR_DomainFile vmDomainFile, OUT VMPTR_Module * pModule)
{
DD_ENTER_MAY_THROW;
_ASSERTE(pModule != NULL);
- DomainAssembly * pDomainAssembly = vmDomainAssembly.GetDacPtr();
- pModule->SetHostPtr(pDomainAssembly->GetModule());
+ DomainFile * pDomainFile = vmDomainFile.GetDacPtr();
+ pModule->SetHostPtr(pDomainFile->GetModule());
}
-// Implement IDacDbiInterface::GetDomainAssemblyData
-void DacDbiInterfaceImpl::GetDomainAssemblyData(VMPTR_DomainAssembly vmDomainAssembly, DomainAssemblyInfo * pData)
+// Implement IDacDbiInterface::GetDomainFileData
+void DacDbiInterfaceImpl::GetDomainFileData(VMPTR_DomainFile vmDomainFile, DomainFileInfo * pData)
{
DD_ENTER_MAY_THROW;
@@ -4367,11 +4367,12 @@ void DacDbiInterfaceImpl::GetDomainAssemblyData(VMPTR_DomainAssembly vmDomainAss
ZeroMemory(pData, sizeof(*pData));
- DomainAssembly * pDomainAssembly = vmDomainAssembly.GetDacPtr();
- AppDomain * pAppDomain = pDomainAssembly->GetAppDomain();
+ DomainFile * pDomainFile = vmDomainFile.GetDacPtr();
+ AppDomain * pAppDomain = pDomainFile->GetAppDomain();
// @dbgtodo - is this efficient DAC usage (perhaps a dac-cop rule)? Are we round-tripping the pointer?
- pData->vmDomainAssembly.SetHostPtr(pDomainAssembly);
+ // Should we have a GetDomainAssembly() that returns a PTR_DomainAssembly?
+ pData->vmDomainAssembly.SetHostPtr(pDomainFile->GetDomainAssembly());
pData->vmAppDomain.SetHostPtr(pAppDomain);
}
@@ -4493,30 +4494,41 @@ void DacDbiInterfaceImpl::EnumerateModulesInAssembly(
DomainAssembly * pDomainAssembly = vmAssembly.GetDacPtr();
- // Debugger isn't notified of Resource / Inspection-only modules.
- if (pDomainAssembly->GetModule()->IsVisibleToDebugger())
+ // If the domain is not yet fully-loaded, don't advertise it yet.
+ // It's not ready to be inspected.
+ DomainModuleIterator iterator = pDomainAssembly->IterateModules(kModIterIncludeLoaded);
+
+ while (iterator.Next())
{
- _ASSERTE(pDomainAssembly->IsLoaded());
+ DomainFile * pDomainFile = iterator.GetDomainFile();
- VMPTR_DomainAssembly vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
- vmDomainAssembly.SetHostPtr(pDomainAssembly);
+ // Debugger isn't notified of Resource / Inspection-only modules.
+ if (!pDomainFile->GetModule()->IsVisibleToDebugger())
+ {
+ continue;
+ }
- fpCallback(vmDomainAssembly, pUserData);
+ _ASSERTE(pDomainFile->IsLoaded());
+
+ VMPTR_DomainFile vmDomainFile = VMPTR_DomainFile::NullPtr();
+ vmDomainFile.SetHostPtr(pDomainFile);
+
+ fpCallback(vmDomainFile, pUserData);
}
}
// Implementation of IDacDbiInterface::ResolveAssembly
// Returns NULL if not found.
VMPTR_DomainAssembly DacDbiInterfaceImpl::ResolveAssembly(
- VMPTR_DomainAssembly vmScope,
+ VMPTR_DomainFile vmScope,
mdToken tkAssemblyRef)
{
DD_ENTER_MAY_THROW;
- DomainAssembly * pDomainAssembly = vmScope.GetDacPtr();
- AppDomain * pAppDomain = pDomainAssembly->GetAppDomain();
- Module * pModule = pDomainAssembly->GetModule();
+ DomainFile * pDomainFile = vmScope.GetDacPtr();
+ AppDomain * pAppDomain = pDomainFile->GetAppDomain();
+ Module * pModule = pDomainFile->GetCurrentModule();
VMPTR_DomainAssembly vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
@@ -5416,16 +5428,6 @@ GENERICS_TYPE_TOKEN DacDbiInterfaceImpl::ResolveExactGenericArgsToken(DWORD
if (dwExactGenericArgsTokenIndex == 0)
{
- // In a rare case of VS4Mac debugging VS4Mac ARM64 optimized code we get a null generics argument token. We aren't sure
- // why the token is null, it may be a bug or it may be by design in the runtime. In the interest of time we are working
- // around the issue rather than investigating the root cause. This workaround should only cause us to degrade generic
- // types from exact type parameters to approximate or canonical type parameters. In the future if we discover this issue
- // is happening more frequently than we expect or the workaround is more impactful than we expect we may need to remove
- // this workaround and resolve the underlying issue.
- if (rawToken == 0)
- {
- return rawToken;
- }
// In this case the real generics type token is the MethodTable of the "this" object.
// Note that we want the target address here.
@@ -6056,7 +6058,7 @@ void DacDbiInterfaceImpl::GetTypedByRefInfo(CORDB_ADDRESS pTypedByRe
"ref=0x%08x, cls=0x%08x, mod=0x%p\n",
pObjectData->objRef,
pObjectData->typedByrefType.metadataToken,
- pObjectData->typedByrefType.vmDomainAssembly.GetDacPtr()));
+ pObjectData->typedByrefType.vmDomainFile.GetDacPtr()));
} // DacDbiInterfaceImpl::GetTypedByRefInfo
// Get the string data associated withn obj and put it into the pointers
@@ -7013,7 +7015,7 @@ bool DacDbiInterfaceImpl::IsValidObject(CORDB_ADDRESS addr)
}
bool DacDbiInterfaceImpl::GetAppDomainForObject(CORDB_ADDRESS addr, OUT VMPTR_AppDomain * pAppDomain,
- OUT VMPTR_Module *pModule, OUT VMPTR_DomainAssembly *pDomainAssembly)
+ OUT VMPTR_Module *pModule, OUT VMPTR_DomainFile *pDomainFile)
{
DD_ENTER_MAY_THROW;
@@ -7033,7 +7035,7 @@ bool DacDbiInterfaceImpl::GetAppDomainForObject(CORDB_ADDRESS addr, OUT VMPTR_Ap
{
pAppDomain->SetDacTargetPtr(PTR_HOST_TO_TADDR(baseDomain->AsAppDomain()));
pModule->SetDacTargetPtr(PTR_HOST_TO_TADDR(module));
- pDomainAssembly->SetDacTargetPtr(PTR_HOST_TO_TADDR(module->GetDomainAssembly()));
+ pDomainFile->SetDacTargetPtr(PTR_HOST_TO_TADDR(module->GetDomainFile()));
}
else
{
diff --git a/src/coreclr/debug/daccess/dacdbiimpl.h b/src/coreclr/debug/daccess/dacdbiimpl.h
index e885703113197..e484a28008b0c 100644
--- a/src/coreclr/debug/daccess/dacdbiimpl.h
+++ b/src/coreclr/debug/daccess/dacdbiimpl.h
@@ -96,7 +96,7 @@ class DacDbiInterfaceImpl :
IStringHolder * pStrName);
// Get the values of the JIT Optimization and EnC flags.
- void GetCompilerFlags (VMPTR_DomainAssembly vmDomainAssembly,
+ void GetCompilerFlags (VMPTR_DomainFile vmDomainFile,
BOOL * pfAllowJITOpts,
BOOL * pfEnableEnC);
@@ -104,7 +104,7 @@ class DacDbiInterfaceImpl :
bool CanSetEnCBits(Module * pModule);
// Set the values of the JIT optimization and EnC flags.
- HRESULT SetCompilerFlags(VMPTR_DomainAssembly vmDomainAssembly,
+ HRESULT SetCompilerFlags(VMPTR_DomainFile vmDomainFile,
BOOL fAllowJitOpts,
BOOL fEnableEnC);
@@ -133,7 +133,7 @@ class DacDbiInterfaceImpl :
bool IsValidObject(CORDB_ADDRESS obj);
- bool GetAppDomainForObject(CORDB_ADDRESS obj, OUT VMPTR_AppDomain * pApp, OUT VMPTR_Module *pModule, OUT VMPTR_DomainAssembly *mod);
+ bool GetAppDomainForObject(CORDB_ADDRESS obj, OUT VMPTR_AppDomain * pApp, OUT VMPTR_Module *pModule, OUT VMPTR_DomainFile *mod);
@@ -218,7 +218,7 @@ class DacDbiInterfaceImpl :
// a module and a token. The info will come from a MethodDesc, if
// one exists or from metadata.
//
- void GetILCodeAndSig(VMPTR_DomainAssembly vmDomainAssembly,
+ void GetILCodeAndSig(VMPTR_DomainFile vmDomainFile,
mdToken functionToken,
TargetBuffer * pCodeInfo,
mdToken * pLocalSigToken);
@@ -229,7 +229,7 @@ class DacDbiInterfaceImpl :
// whether it's an instantiated generic
// its EnC version number
// hot and cold region information.
- void GetNativeCodeInfo(VMPTR_DomainAssembly vmDomainAssembly,
+ void GetNativeCodeInfo(VMPTR_DomainFile vmDomainFile,
mdToken functionToken,
NativeCodeFunctionData * pCodeInfo);
@@ -260,7 +260,7 @@ class DacDbiInterfaceImpl :
ClassInfo * pData);
// get field information and object size for an instantiated generic type
- void GetInstantiationFieldInfo (VMPTR_DomainAssembly vmDomainAssembly,
+ void GetInstantiationFieldInfo (VMPTR_DomainFile vmDomainFile,
VMPTR_TypeHandle vmThExact,
VMPTR_TypeHandle vmThApprox,
DacDbiArrayList * pFieldList,
@@ -336,7 +336,7 @@ class DacDbiInterfaceImpl :
CorElementType simpleType,
mdTypeDef * pMetadataToken,
VMPTR_Module * pVmModule,
- VMPTR_DomainAssembly * pVmDomainAssembly);
+ VMPTR_DomainFile * pVmDomainFile);
BOOL IsExceptionObject(VMPTR_Object vmObject);
@@ -352,7 +352,7 @@ class DacDbiInterfaceImpl :
HRESULT GetDelegateFunctionData(
DelegateType delegateType,
VMPTR_Object delegateObject,
- OUT VMPTR_DomainAssembly *ppFunctionDomainAssembly,
+ OUT VMPTR_DomainFile *ppFunctionDomainFile,
OUT mdMethodDef *pMethodDef);
HRESULT GetDelegateTargetObject(
@@ -730,10 +730,10 @@ class DacDbiInterfaceImpl :
// Gets properties for a module
void GetModuleData(VMPTR_Module vmModule, ModuleInfo * pData);
- // Gets properties for a domain assembly
- void GetDomainAssemblyData(VMPTR_DomainAssembly vmDomainAssembly, DomainAssemblyInfo * pData);
+ // Gets properties for a domainfile
+ void GetDomainFileData(VMPTR_DomainFile vmDomainFile, DomainFileInfo * pData);
- void GetModuleForDomainAssembly(VMPTR_DomainAssembly vmDomainAssembly, OUT VMPTR_Module * pModule);
+ void GetModuleForDomainFile(VMPTR_DomainFile vmDomainFile, OUT VMPTR_Module * pModule);
// Yields true if the address is a CLR stub.
BOOL IsTransitionStub(CORDB_ADDRESS address);
@@ -829,8 +829,8 @@ class DacDbiInterfaceImpl :
// Return the current appdomain the specified thread is in.
VMPTR_AppDomain GetCurrentAppDomain(VMPTR_Thread vmThread);
- // Given an assembly ref token and metadata scope (via the DomainAssembly), resolve the assembly.
- VMPTR_DomainAssembly ResolveAssembly(VMPTR_DomainAssembly vmScope, mdToken tkAssemblyRef);
+ // Given an assembly ref token and metadata scope (via the DomainFile), resolve the assembly.
+ VMPTR_DomainAssembly ResolveAssembly(VMPTR_DomainFile vmScope, mdToken tkAssemblyRef);
// Hijack the thread
diff --git a/src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp b/src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp
index b8a84043b396f..251b5dde74fdf 100644
--- a/src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp
+++ b/src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp
@@ -514,7 +514,7 @@ void DacDbiInterfaceImpl::EnumerateInternalFrames(VMPTR_Thread
#endif // FEATURE_COMINTEROP
Module * pModule = (pMD ? pMD->GetModule() : NULL);
- DomainAssembly * pDomainAssembly = (pModule ? pModule->GetDomainAssembly() : NULL);
+ DomainFile * pDomainFile = (pModule ? pModule->GetDomainFile() : NULL);
if (frameData.stubFrame.frameType == STUBFRAME_FUNC_EVAL)
{
@@ -522,14 +522,14 @@ void DacDbiInterfaceImpl::EnumerateInternalFrames(VMPTR_Thread
DebuggerEval * pDE = pFEF->GetDebuggerEval();
frameData.stubFrame.funcMetadataToken = pDE->m_methodToken;
- frameData.stubFrame.vmDomainAssembly.SetHostPtr(
- pDE->m_debuggerModule ? pDE->m_debuggerModule->GetDomainAssembly() : NULL);
+ frameData.stubFrame.vmDomainFile.SetHostPtr(
+ pDE->m_debuggerModule ? pDE->m_debuggerModule->GetDomainFile() : NULL);
frameData.stubFrame.vmMethodDesc = VMPTR_MethodDesc::NullPtr();
}
else
{
frameData.stubFrame.funcMetadataToken = (pMD == NULL ? NULL : pMD->GetMemberDef());
- frameData.stubFrame.vmDomainAssembly.SetHostPtr(pDomainAssembly);
+ frameData.stubFrame.vmDomainFile.SetHostPtr(pDomainFile);
frameData.stubFrame.vmMethodDesc.SetHostPtr(pMD);
}
@@ -702,11 +702,11 @@ void DacDbiInterfaceImpl::InitFrameData(StackFrameIterator * pIter,
// Although MiniDumpNormal tries to dump all AppDomains, it's possible
// target corruption will keep one from being present. This should mean
// we'll just fail later, but struggle on for now.
- DomainAssembly *pDomainAssembly = NULL;
+ DomainFile *pDomainFile = NULL;
EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY
{
- pDomainAssembly = (pModule ? pModule->GetDomainAssembly() : NULL);
- _ASSERTE(pDomainAssembly != NULL);
+ pDomainFile = (pModule ? pModule->GetDomainFile() : NULL);
+ _ASSERTE(pDomainFile != NULL);
}
EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY
@@ -783,7 +783,7 @@ void DacDbiInterfaceImpl::InitFrameData(StackFrameIterator * pIter,
//
pFuncData->funcMetadataToken = pMD->GetMemberDef();
- pFuncData->vmDomainAssembly.SetHostPtr(pDomainAssembly);
+ pFuncData->vmDomainFile.SetHostPtr(pDomainFile);
// PERF: this is expensive to get so I stopped fetching it eagerly
// It is only needed if we haven't already got a cached copy
diff --git a/src/coreclr/debug/daccess/dacimpl.h b/src/coreclr/debug/daccess/dacimpl.h
index 7a03d984e3ac7..57a4dc1bbab8f 100644
--- a/src/coreclr/debug/daccess/dacimpl.h
+++ b/src/coreclr/debug/daccess/dacimpl.h
@@ -14,11 +14,14 @@
#define __DACIMPL_H__
#include "gcinterface.dac.h"
+
+#if defined(TARGET_ARM) || defined(FEATURE_CORESYSTEM) // @ARMTODO: STL breaks the build with current VC headers
//---------------------------------------------------------------------------------------
// Setting DAC_HASHTABLE tells the DAC to use the hand rolled hashtable for
// storing code:DAC_INSTANCE . Otherwise, the DAC uses the STL unordered_map to.
#define DAC_HASHTABLE
+#endif // TARGET_ARM|| FEATURE_CORESYSTEM
#ifndef DAC_HASHTABLE
#pragma push_macro("return")
@@ -506,6 +509,7 @@ struct ProcessModIter
bool m_nextDomain;
AppDomain::AssemblyIterator m_assemIter;
Assembly* m_curAssem;
+ Assembly::ModuleIterator m_modIter;
ProcessModIter(void)
: m_domainIter(FALSE)
@@ -541,7 +545,7 @@ struct ProcessModIter
}
// Note: DAC doesn't need to keep the assembly alive - see code:CollectibleAssemblyHolder#CAH_DAC
- CollectibleAssemblyHolder pAssembly = pDomainAssembly->GetAssembly();
+ CollectibleAssemblyHolder pAssembly = pDomainAssembly->GetLoadedAssembly();
return pAssembly;
}
return NULL;
@@ -550,13 +554,27 @@ struct ProcessModIter
Module* NextModule(void)
{
SUPPORTS_DAC;
- m_curAssem = NextAssem();
- if (!m_curAssem)
+ for (;;)
{
- return NULL;
- }
+ if (!m_curAssem)
+ {
+ m_curAssem = NextAssem();
+ if (!m_curAssem)
+ {
+ return NULL;
+ }
- return m_curAssem->GetModule();
+ m_modIter = m_curAssem->IterateModules();
+ }
+
+ if (!m_modIter.Next())
+ {
+ m_curAssem = NULL;
+ continue;
+ }
+
+ return m_modIter.GetModule();
+ }
}
};
@@ -1502,6 +1520,11 @@ class ClrDataAccess
DWORD &dwSize,
_Out_writes_(cchPath) LPWSTR wszPath,
const DWORD cchPath);
+#if defined(FEATURE_CORESYSTEM)
+ static bool GetILImageNameFromNgenImage(LPCWSTR ilExtension,
+ _Out_writes_(cchFilePath) LPWSTR wszFilePath,
+ const DWORD cchFilePath);
+#endif // FEATURE_CORESYSTEM
};
extern ClrDataAccess* g_dacImpl;
diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp
index cd81cde5ac69e..1e327721f4a92 100644
--- a/src/coreclr/debug/daccess/request.cpp
+++ b/src/coreclr/debug/daccess/request.cpp
@@ -2607,7 +2607,10 @@ ClrDataAccess::GetAssemblyData(CLRDATA_ADDRESS cdBaseDomainPtr, CLRDATA_ADDRESS
assemblyData->ModuleCount = 0;
assemblyData->isDomainNeutral = FALSE;
- if (pAssembly->GetModule())
+ pAssembly->GetManifestFile();
+
+ ModuleIterator mi = pAssembly->IterateModules();
+ while (mi.Next())
{
assemblyData->ModuleCount++;
}
@@ -2625,17 +2628,17 @@ ClrDataAccess::GetAssemblyName(CLRDATA_ADDRESS assembly, unsigned int count, _In
if (name)
name[0] = 0;
- if (!pAssembly->GetPEAssembly()->GetPath().IsEmpty())
+ if (!pAssembly->GetManifestFile()->GetPath().IsEmpty())
{
- if (!pAssembly->GetPEAssembly()->GetPath().DacGetUnicode(count, name, pNeeded))
+ if (!pAssembly->GetManifestFile()->GetPath().DacGetUnicode(count, name, pNeeded))
hr = E_FAIL;
else if (name)
name[count-1] = 0;
}
- else if (!pAssembly->GetPEAssembly()->IsDynamic())
+ else if (!pAssembly->GetManifestFile()->IsDynamic())
{
StackSString displayName;
- pAssembly->GetPEAssembly()->GetDisplayName(displayName, 0);
+ pAssembly->GetManifestFile()->GetDisplayName(displayName, 0);
const WCHAR *val = displayName.GetUnicode();
@@ -2670,9 +2673,9 @@ ClrDataAccess::GetAssemblyLocation(CLRDATA_ADDRESS assembly, int count, _Inout_u
Assembly* pAssembly = PTR_Assembly(TO_TADDR(assembly));
// Turn from bytes to wide characters
- if (!pAssembly->GetPEAssembly()->GetPath().IsEmpty())
+ if (!pAssembly->GetManifestFile()->GetPath().IsEmpty())
{
- if (!pAssembly->GetPEAssembly()->GetPath().
+ if (!pAssembly->GetManifestFile()->GetPath().
DacGetUnicode(count, location, pNeeded))
{
hr = E_FAIL;
@@ -2700,14 +2703,21 @@ ClrDataAccess::GetAssemblyModuleList(CLRDATA_ADDRESS assembly, unsigned int coun
SOSDacEnter();
Assembly* pAssembly = PTR_Assembly(TO_TADDR(assembly));
+ ModuleIterator mi = pAssembly->IterateModules();
+ unsigned int n = 0;
if (modules)
{
- if (pAssembly->GetModule() && count > 0)
- modules[0] = HOST_CDADDR(pAssembly->GetModule());
+ while (mi.Next() && n < count)
+ modules[n++] = HOST_CDADDR(mi.GetModule());
+ }
+ else
+ {
+ while (mi.Next())
+ n++;
}
if (pNeeded)
- *pNeeded = 1;
+ *pNeeded = n;
SOSDacLeave();
return hr;
diff --git a/src/coreclr/debug/daccess/task.cpp b/src/coreclr/debug/daccess/task.cpp
index 319d3506b9b88..30abc5e090cc9 100644
--- a/src/coreclr/debug/daccess/task.cpp
+++ b/src/coreclr/debug/daccess/task.cpp
@@ -948,11 +948,6 @@ ClrDataAssembly::Release(THIS)
return newRefs;
}
-struct TrivialModuleIterator
-{
- Module* m_module;
-};
-
HRESULT STDMETHODCALLTYPE
ClrDataAssembly::StartEnumModules(
/* [out] */ CLRDATA_ENUM* handle)
@@ -963,10 +958,11 @@ ClrDataAssembly::StartEnumModules(
EX_TRY
{
- TrivialModuleIterator* iter = new (nothrow) TrivialModuleIterator;
+ Assembly::ModuleIterator* iter = new (nothrow)
+ Assembly::ModuleIterator;
if (iter)
{
- iter->m_module = m_assembly->GetModule();
+ *iter = m_assembly->IterateModules();
*handle = TO_CDENUM(iter);
status = S_OK;
}
@@ -999,13 +995,12 @@ ClrDataAssembly::EnumModule(
EX_TRY
{
- TrivialModuleIterator* iter = FROM_CDENUM(TrivialModuleIterator, *handle);
- if (iter->m_module)
+ Assembly::ModuleIterator* iter =
+ FROM_CDENUM(Assembly::ModuleIterator, *handle);
+ if (iter->Next())
{
*mod = new (nothrow)
- ClrDataModule(m_dac, iter->m_module);
-
- iter->m_module = NULL;
+ ClrDataModule(m_dac, iter->GetModule());
status = *mod ? S_OK : E_OUTOFMEMORY;
}
else
@@ -1036,7 +1031,8 @@ ClrDataAssembly::EndEnumModules(
EX_TRY
{
- TrivialModuleIterator* iter = FROM_CDENUM(TrivialModuleIterator, handle);
+ Assembly::ModuleIterator* iter =
+ FROM_CDENUM(Assembly::ModuleIterator, handle);
delete iter;
status = S_OK;
}
@@ -1174,7 +1170,7 @@ ClrDataAssembly::GetFileName(
{
COUNT_T _nameLen;
- if (m_assembly->GetPEAssembly()->GetPath().
+ if (m_assembly->GetManifestFile()->GetPath().
DacGetUnicode(bufLen, name, &_nameLen))
{
if (nameLen)
diff --git a/src/coreclr/debug/di/breakpoint.cpp b/src/coreclr/debug/di/breakpoint.cpp
index ad45df5c618ac..eb156c49e04d9 100644
--- a/src/coreclr/debug/di/breakpoint.cpp
+++ b/src/coreclr/debug/di/breakpoint.cpp
@@ -201,7 +201,7 @@ HRESULT CordbFunctionBreakpoint::Activate(BOOL fActivate)
pProcess->InitIPCEvent(pEvent, DB_IPCE_BREAKPOINT_ADD, true, pAppDomain->GetADToken());
pEvent->BreakpointData.funcMetadataToken = m_code->GetMetadataToken();
- pEvent->BreakpointData.vmDomainAssembly = m_code->GetModule()->GetRuntimeDomainAssembly();
+ pEvent->BreakpointData.vmDomainFile = m_code->GetModule()->GetRuntimeDomainFile();
pEvent->BreakpointData.encVersion = m_code->GetVersion();
BOOL codeIsIL = m_code->IsIL();
diff --git a/src/coreclr/debug/di/cordb.cpp b/src/coreclr/debug/di/cordb.cpp
index 2f014d1fa587c..e195f3731a9e6 100644
--- a/src/coreclr/debug/di/cordb.cpp
+++ b/src/coreclr/debug/di/cordb.cpp
@@ -84,6 +84,16 @@
//*****************************************************************************
STDAPI CreateCordbObject(int iDebuggerVersion, IUnknown ** ppCordb)
{
+#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) && !defined(FEATURE_CORESYSTEM)
+ // This API should not be called for Windows CoreCLR unless we are doing interop-debugging
+ // (which is only supported internally). Use code:CoreCLRCreateCordbObject instead.
+ if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgEnableMixedModeDebugging) == 0)
+ {
+ _ASSERTE(!"Deprecated entry point CreateCordbObject() is called on Windows CoreCLR\n");
+ return E_NOTIMPL;
+ }
+#endif // !defined(FEATURE_DBGIPC_TRANSPORT_DI) && !defined(FEATURE_CORESYSTEM)
+
if (ppCordb == NULL)
{
return E_INVALIDARG;
diff --git a/src/coreclr/debug/di/divalue.cpp b/src/coreclr/debug/di/divalue.cpp
index 5e79a5ee1c92b..b8c9e745260db 100644
--- a/src/coreclr/debug/di/divalue.cpp
+++ b/src/coreclr/debug/di/divalue.cpp
@@ -2464,7 +2464,7 @@ HRESULT CordbObjectValue::EnumerateExceptionCallStack(ICorDebugExceptionObjectCa
CorDebugExceptionObjectStackFrame& currentStackFrame = pStackFrames[index];
CordbAppDomain* pAppDomain = GetProcess()->LookupOrCreateAppDomain(currentDacFrame.vmAppDomain);
- CordbModule* pModule = pAppDomain->LookupOrCreateModule(currentDacFrame.vmDomainAssembly);
+ CordbModule* pModule = pAppDomain->LookupOrCreateModule(currentDacFrame.vmDomainFile);
hr = pModule->QueryInterface(IID_ICorDebugModule, reinterpret_cast(¤tStackFrame.pModule));
_ASSERTE(SUCCEEDED(hr));
@@ -2653,18 +2653,18 @@ HRESULT CordbObjectValue::GetFunctionHelper(ICorDebugFunction **ppFunction)
return hr;
mdMethodDef functionMethodDef = 0;
- VMPTR_DomainAssembly functionDomainAssembly;
+ VMPTR_DomainFile functionDomainFile;
NativeCodeFunctionData nativeCodeForDelFunc;
- hr = pDAC->GetDelegateFunctionData(delType, pDelegateObj, &functionDomainAssembly, &functionMethodDef);
+ hr = pDAC->GetDelegateFunctionData(delType, pDelegateObj, &functionDomainFile, &functionMethodDef);
if (hr != S_OK)
return hr;
// TODO: How to ensure results are sanitized?
// Also, this is expensive. Do we really care that much about this?
- pDAC->GetNativeCodeInfo(functionDomainAssembly, functionMethodDef, &nativeCodeForDelFunc);
+ pDAC->GetNativeCodeInfo(functionDomainFile, functionMethodDef, &nativeCodeForDelFunc);
- RSSmartPtr funcModule(GetProcess()->LookupOrCreateModule(functionDomainAssembly));
+ RSSmartPtr funcModule(GetProcess()->LookupOrCreateModule(functionDomainFile));
RSSmartPtr func;
{
RSLockHolder lockHolder(GetProcess()->GetProcessLock());
diff --git a/src/coreclr/debug/di/module.cpp b/src/coreclr/debug/di/module.cpp
index 55f9e8a29c87d..6d6a7a55befa2 100644
--- a/src/coreclr/debug/di/module.cpp
+++ b/src/coreclr/debug/di/module.cpp
@@ -48,17 +48,17 @@ STDAPI ReOpenMetaDataWithMemoryEx(
//
// Arguments:
// pProcess - process that this module lives in
-// vmDomainAssembly - CLR cookie for module.
+// vmDomainFile - CLR cookie for module.
CordbModule::CordbModule(
CordbProcess * pProcess,
VMPTR_Module vmModule,
- VMPTR_DomainAssembly vmDomainAssembly)
-: CordbBase(pProcess, vmDomainAssembly.IsNull() ? VmPtrToCookie(vmModule) : VmPtrToCookie(vmDomainAssembly), enumCordbModule),
+ VMPTR_DomainFile vmDomainFile)
+: CordbBase(pProcess, vmDomainFile.IsNull() ? VmPtrToCookie(vmModule) : VmPtrToCookie(vmDomainFile), enumCordbModule),
m_pAssembly(0),
m_pAppDomain(0),
m_classes(11),
m_functions(101),
- m_vmDomainAssembly(vmDomainAssembly),
+ m_vmDomainFile(vmDomainFile),
m_vmModule(vmModule),
m_EnCCount(0),
m_fForceMetaDataSerialize(FALSE),
@@ -84,11 +84,11 @@ CordbModule::CordbModule(
m_fInMemory = modInfo.fInMemory;
m_vmPEFile = modInfo.vmPEAssembly;
- if (!vmDomainAssembly.IsNull())
+ if (!vmDomainFile.IsNull())
{
- DomainAssemblyInfo dfInfo;
+ DomainFileInfo dfInfo;
- pProcess->GetDAC()->GetDomainAssemblyData(vmDomainAssembly, &dfInfo); // throws
+ pProcess->GetDAC()->GetDomainFileData(vmDomainFile, &dfInfo); // throws
m_pAppDomain = pProcess->LookupOrCreateAppDomain(dfInfo.vmAppDomain);
m_pAssembly = m_pAppDomain->LookupOrCreateAssembly(dfInfo.vmDomainAssembly);
@@ -115,21 +115,21 @@ CordbModule::CordbModule(
// Callback helper for code:CordbModule::DbgAssertModuleDeleted
//
// Arguments
-// vmDomainAssembly - domain file in the enumeration
+// vmDomainFile - domain file in the enumeration
// pUserData - pointer to the CordbModule that we just got an exit event for.
//
-void DbgAssertModuleDeletedCallback(VMPTR_DomainAssembly vmDomainAssembly, void * pUserData)
+void DbgAssertModuleDeletedCallback(VMPTR_DomainFile vmDomainFile, void * pUserData)
{
CordbModule * pThis = reinterpret_cast(pUserData);
INTERNAL_DAC_CALLBACK(pThis->GetProcess());
- if (!pThis->m_vmDomainAssembly.IsNull())
+ if (!pThis->m_vmDomainFile.IsNull())
{
- VMPTR_DomainAssembly vmDomainAssemblyDeleted = pThis->m_vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFileDeleted = pThis->m_vmDomainFile;
- CONSISTENCY_CHECK_MSGF((vmDomainAssemblyDeleted != vmDomainAssembly),
- ("A Module Unload event was sent for a module, but it still shows up in the enumeration.\n vmDomainAssemblyDeleted=%p\n",
- VmPtrToCookie(vmDomainAssemblyDeleted)));
+ CONSISTENCY_CHECK_MSGF((vmDomainFileDeleted != vmDomainFile),
+ ("A Module Unload event was sent for a module, but it still shows up in the enumeration.\n vmDomainFileDeleted=%p\n",
+ VmPtrToCookie(vmDomainFileDeleted)));
}
}
@@ -1499,7 +1499,7 @@ HRESULT CordbModule::EnableClassLoadCallbacks(BOOL bClassLoadCallbacks)
if (m_fDynamic && !bClassLoadCallbacks)
return E_INVALIDARG;
- if (m_vmDomainAssembly.IsNull())
+ if (m_vmDomainFile.IsNull())
return E_UNEXPECTED;
// Send a Set Class Load Flag event to the left side. There is no need to wait for a response, and this can be
@@ -1511,7 +1511,7 @@ HRESULT CordbModule::EnableClassLoadCallbacks(BOOL bClassLoadCallbacks)
DB_IPCE_SET_CLASS_LOAD_FLAG,
false,
(GetAppDomain()->GetADToken()));
- event.SetClassLoad.vmDomainAssembly = this->m_vmDomainAssembly;
+ event.SetClassLoad.vmDomainFile = this->m_vmDomainFile;
event.SetClassLoad.flag = (bClassLoadCallbacks == TRUE);
HRESULT hr = pProcess->m_cordb->SendIPCEvent(pProcess, &event,
@@ -2041,7 +2041,7 @@ HRESULT CordbModule::ResolveTypeRef(mdTypeRef token, CordbClass **ppClass)
return E_INVALIDARG;
}
- if (m_vmDomainAssembly.IsNull() || m_pAppDomain == NULL)
+ if (m_vmDomainFile.IsNull() || m_pAppDomain == NULL)
{
return E_UNEXPECTED;
}
@@ -2050,7 +2050,7 @@ HRESULT CordbModule::ResolveTypeRef(mdTypeRef token, CordbClass **ppClass)
*ppClass = NULL;
EX_TRY
{
- TypeRefData inData = {m_vmDomainAssembly, token};
+ TypeRefData inData = {m_vmDomainFile, token};
TypeRefData outData;
{
@@ -2058,7 +2058,7 @@ HRESULT CordbModule::ResolveTypeRef(mdTypeRef token, CordbClass **ppClass)
pProcess->GetDAC()->ResolveTypeReference(&inData, &outData);
}
- CordbModule * pModule = m_pAppDomain->LookupOrCreateModule(outData.vmDomainAssembly);
+ CordbModule * pModule = m_pAppDomain->LookupOrCreateModule(outData.vmDomainFile);
IfFailThrow(pModule->LookupClassByToken(outData.typeToken, ppClass));
}
EX_CATCH_HRESULT(hr);
@@ -2271,7 +2271,7 @@ HRESULT CordbModule::ApplyChangesInternal(ULONG cbMetaData,
FAIL_IF_NEUTERED(this);
INTERNAL_SYNC_API_ENTRY(this->GetProcess()); //
- if (m_vmDomainAssembly.IsNull())
+ if (m_vmDomainFile.IsNull())
return E_UNEXPECTED;
#ifdef FEATURE_ENC_SUPPORTED
@@ -2288,7 +2288,7 @@ HRESULT CordbModule::ApplyChangesInternal(ULONG cbMetaData,
DebuggerIPCEvent event;
GetProcess()->InitIPCEvent(&event, DB_IPCE_APPLY_CHANGES, false, VMPTR_AppDomain::NullPtr());
- event.ApplyChanges.vmDomainAssembly = this->m_vmDomainAssembly;
+ event.ApplyChanges.vmDomainFile = this->m_vmDomainFile;
// Have the left-side create a buffer for us to store the delta into
ULONG cbSize = cbMetaData+cbIL;
@@ -2354,7 +2354,7 @@ HRESULT CordbModule::ApplyChangesInternal(ULONG cbMetaData,
CordbModule* pModule = NULL;
- pModule = pAppDomain->LookupOrCreateModule(retEvent->EnCUpdate.vmDomainAssembly); // throws
+ pModule = pAppDomain->LookupOrCreateModule(retEvent->EnCUpdate.vmDomainFile); // throws
_ASSERTE(pModule != NULL);
// update to the newest version
@@ -2412,7 +2412,7 @@ HRESULT CordbModule::SetJMCStatus(
FAIL_IF_NEUTERED(this);
ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
- if (m_vmDomainAssembly.IsNull())
+ if (m_vmDomainFile.IsNull())
return E_UNEXPECTED;
// @todo -allow the other parameters. These are functions that have default status
@@ -2431,7 +2431,7 @@ HRESULT CordbModule::SetJMCStatus(
// Tell the LS that this module is/is not user code
DebuggerIPCEvent event;
pProcess->InitIPCEvent(&event, DB_IPCE_SET_MODULE_JMC_STATUS, true, this->GetAppDomain()->GetADToken());
- event.SetJMCFunctionStatus.vmDomainAssembly = m_vmDomainAssembly;
+ event.SetJMCFunctionStatus.vmDomainFile = m_vmDomainFile;
event.SetJMCFunctionStatus.dwStatus = fIsUserCode;
@@ -2520,10 +2520,10 @@ CordbAssembly * CordbModule::ResolveAssemblyInternal(mdToken tkAssemblyRef)
CordbAssembly * pAssembly = NULL;
- if (!m_vmDomainAssembly.IsNull())
+ if (!m_vmDomainFile.IsNull())
{
// Get DAC to do the real work to resolve the assembly
- VMPTR_DomainAssembly vmDomainAssembly = GetProcess()->GetDAC()->ResolveAssembly(m_vmDomainAssembly, tkAssemblyRef);
+ VMPTR_DomainAssembly vmDomainAssembly = GetProcess()->GetDAC()->ResolveAssembly(m_vmDomainFile, tkAssemblyRef);
// now find the ICorDebugAssembly corresponding to it
if (!vmDomainAssembly.IsNull() && m_pAppDomain != NULL)
@@ -2694,7 +2694,7 @@ HRESULT CordbModule::SetJITCompilerFlags(DWORD dwFlags)
if (SUCCEEDED(hr))
{
// DD interface will check if it's a valid time to change the flags.
- hr = pProcess->GetDAC()->SetCompilerFlags(GetRuntimeDomainAssembly(), fAllowJitOpts, fEnableEnC);
+ hr = pProcess->GetDAC()->SetCompilerFlags(GetRuntimeDomainFile(), fAllowJitOpts, fEnableEnC);
}
}
}
@@ -2730,7 +2730,7 @@ HRESULT CordbModule::GetJITCompilerFlags(DWORD *pdwFlags )
BOOL fEnableEnC;
pProcess->GetDAC()->GetCompilerFlags (
- GetRuntimeDomainAssembly(),
+ GetRuntimeDomainFile(),
&fAllowJitOpts,
&fEnableEnC);
@@ -5169,8 +5169,8 @@ HRESULT CordbNativeCode::GetReturnValueLiveOffsetImpl(Instantiation *currentInst
int skipBytes = 0;
-#if defined(PSEUDORANDOM_NOP_INSERTION)
- // Skip nop sleds the JIT adds. These instructions as a security measure,
+#if defined(TARGET_X86) && defined(FEATURE_CORESYSTEM)
+ // Skip nop sleds on x86 coresystem. The JIT adds these instructions as a security measure,
// and incorrectly reports to us the wrong offset of the call instruction.
const BYTE nop_opcode = 0x90;
while (fetched && nativeBuffer[0] == nop_opcode)
diff --git a/src/coreclr/debug/di/nativepipeline.h b/src/coreclr/debug/di/nativepipeline.h
index fc03b27772474..f1b973ea5967c 100644
--- a/src/coreclr/debug/di/nativepipeline.h
+++ b/src/coreclr/debug/di/nativepipeline.h
@@ -146,6 +146,28 @@ class INativeEventPipeline
virtual BOOL TerminateProcess(UINT32 exitCode) = 0;
+ //
+ // Resume any suspended threads in the currend process.
+ // This decreases the suspend count of each thread by at most 1.
+ // Call multiple times until it returns S_FALSE if you want to really ensure
+ // all threads are running.
+ //
+ // Notes:
+ // On Windows the OS may suspend threads when continuing a 2nd-chance exception.
+ // Call this to get them resumed again. On other platforms this
+ // will typically be a no-op, so I provide a default implementation to avoid
+ // everyone having to override this.
+ //
+ // Return Value:
+ // S_OK if at least one thread was resumed from a suspended state
+ // S_FALSE if nothing was done
+ // An error code indicating why we were not able to attempt this
+
+ virtual HRESULT EnsureThreadsRunning()
+ {
+ return S_FALSE;
+ }
+
#ifdef TARGET_UNIX
// Used by debugger side (RS) to cleanup the target (LS) named pipes
// and semaphores when the debugger detects the debuggee process exited.
diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp
index 1abed121f3e5a..59af4cc8d9c64 100644
--- a/src/coreclr/debug/di/process.cpp
+++ b/src/coreclr/debug/di/process.cpp
@@ -414,6 +414,7 @@ IMDInternalImport * CordbProcess::LookupMetaDataFromDebugger(
WCHAR *mutableFilePath = (WCHAR *)filePath;
+#if defined(FEATURE_CORESYSTEM)
size_t pathLen = wcslen(mutableFilePath);
const WCHAR *nidll = W(".ni.dll");
@@ -428,6 +429,7 @@ IMDInternalImport * CordbProcess::LookupMetaDataFromDebugger(
{
wcscpy_s(mutableFilePath+pathLen-dllLen, dllLen, W(".exe"));
}
+#endif//FEATURE_CORESYSTEM
ALLOW_DATATARGET_MISSING_MEMORY(
pMDII = LookupMetaDataFromDebuggerForSingleFile(pModule, mutableFilePath, dwImageTimeStamp, dwImageSize);
@@ -2562,10 +2564,10 @@ HRESULT CordbProcess::GetTypeForObject(CORDB_ADDRESS addr, CordbAppDomain* pAppD
{
VMPTR_AppDomain appDomain;
VMPTR_Module mod;
- VMPTR_DomainAssembly domainAssembly;
+ VMPTR_DomainFile domainFile;
HRESULT hr = E_FAIL;
- if (GetDAC()->GetAppDomainForObject(addr, &appDomain, &mod, &domainAssembly))
+ if (GetDAC()->GetAppDomainForObject(addr, &appDomain, &mod, &domainFile))
{
if (pAppDomainOverride)
{
@@ -4429,15 +4431,15 @@ class ShimModuleCallbackData
// Callback invoked from DAC enumeration.
//
// arguments:
- // vmDomainAssembly - VMPTR for Module
+ // vmDomainFile - VMPTR for Module
// pData - a 'this' pointer
//
- static void Callback(VMPTR_DomainAssembly vmDomainAssembly, void * pData)
+ static void Callback(VMPTR_DomainFile vmDomainFile, void * pData)
{
ShimModuleCallbackData * pThis = static_cast (pData);
INTERNAL_DAC_CALLBACK(pThis->m_pProcess);
- CordbModule * pModule = pThis->m_pAssembly->GetAppDomain()->LookupOrCreateModule(vmDomainAssembly);
+ CordbModule * pModule = pThis->m_pAssembly->GetAppDomain()->LookupOrCreateModule(vmDomainFile);
pThis->SetAndMoveNext(pModule);
}
@@ -5063,7 +5065,7 @@ void CordbProcess::RawDispatchEvent(
case DB_IPCE_METADATA_UPDATE:
{
- CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->MetadataUpdateData.vmDomainAssembly);
+ CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->MetadataUpdateData.vmDomainFile);
pModule->RefreshMetaData();
}
break;
@@ -5071,7 +5073,7 @@ void CordbProcess::RawDispatchEvent(
case DB_IPCE_LOAD_MODULE:
{
_ASSERTE (pAppDomain != NULL);
- CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadModuleData.vmDomainAssembly);
+ CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadModuleData.vmDomainFile);
{
pModule->SetLoadEventContinueMarker();
@@ -5123,12 +5125,12 @@ void CordbProcess::RawDispatchEvent(
{
STRESS_LOG3(LF_CORDB, LL_INFO100, "RCET::HRCE: unload module on thread %#x Mod:0x%x AD:0x%08x\n",
dwVolatileThreadId,
- VmPtrToCookie(pEvent->UnloadModuleData.vmDomainAssembly),
+ VmPtrToCookie(pEvent->UnloadModuleData.vmDomainFile),
VmPtrToCookie(pEvent->vmAppDomain));
PREFIX_ASSUME (pAppDomain != NULL);
- CordbModule *module = pAppDomain->LookupOrCreateModule(pEvent->UnloadModuleData.vmDomainAssembly);
+ CordbModule *module = pAppDomain->LookupOrCreateModule(pEvent->UnloadModuleData.vmDomainFile);
if (module == NULL)
{
@@ -5149,7 +5151,7 @@ void CordbProcess::RawDispatchEvent(
pCallback1->UnloadModule(pAppDomain, module);
}
- pAppDomain->m_modules.RemoveBase(VmPtrToCookie(pEvent->UnloadModuleData.vmDomainAssembly));
+ pAppDomain->m_modules.RemoveBase(VmPtrToCookie(pEvent->UnloadModuleData.vmDomainFile));
}
break;
@@ -5161,13 +5163,13 @@ void CordbProcess::RawDispatchEvent(
"RCET::HRCE: load class on thread %#x Tok:0x%08x Mod:0x%08x Asm:0x%08x AD:0x%08x\n",
dwVolatileThreadId,
pEvent->LoadClass.classMetadataToken,
- VmPtrToCookie(pEvent->LoadClass.vmDomainAssembly),
+ VmPtrToCookie(pEvent->LoadClass.vmDomainFile),
LsPtrToCookie(pEvent->LoadClass.classDebuggerAssemblyToken),
VmPtrToCookie(pEvent->vmAppDomain)));
_ASSERTE (pAppDomain != NULL);
- CordbModule* pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadClass.vmDomainAssembly);
+ CordbModule* pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadClass.vmDomainFile);
if (pModule == NULL)
{
LOG((LF_CORDB, LL_INFO100, "Load Class on not-loaded Module - continue()ing!" ));
@@ -5219,13 +5221,13 @@ void CordbProcess::RawDispatchEvent(
"RCET::HRCE: unload class on thread %#x Tok:0x%08x Mod:0x%08x AD:0x%08x\n",
dwVolatileThreadId,
pEvent->UnloadClass.classMetadataToken,
- VmPtrToCookie(pEvent->UnloadClass.vmDomainAssembly),
+ VmPtrToCookie(pEvent->UnloadClass.vmDomainFile),
VmPtrToCookie(pEvent->vmAppDomain)));
// get the appdomain object
_ASSERTE (pAppDomain != NULL);
- CordbModule *pModule = pAppDomain->LookupOrCreateModule(pEvent->UnloadClass.vmDomainAssembly);
+ CordbModule *pModule = pAppDomain->LookupOrCreateModule(pEvent->UnloadClass.vmDomainFile);
if (pModule == NULL)
{
LOG((LF_CORDB, LL_INFO100, "Unload Class on not-loaded Module - continue()ing!" ));
@@ -5302,7 +5304,7 @@ void CordbProcess::RawDispatchEvent(
// determine first whether custom notifications for this type are enabled -- if not
// we just return without doing anything.
CordbClass * pNotificationClass = LookupClass(pAppDomain,
- pEvent->CustomNotification.vmDomainAssembly,
+ pEvent->CustomNotification.vmDomainFile,
pEvent->CustomNotification.classToken);
// if the class is NULL, that means the debugger never enabled notifications for it. Otherwise,
@@ -5578,7 +5580,7 @@ void CordbProcess::RawDispatchEvent(
_ASSERTE (pAppDomain != NULL);
// Find the Right Side module for this module.
- CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->UpdateModuleSymsData.vmDomainAssembly);
+ CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->UpdateModuleSymsData.vmDomainFile);
_ASSERTE(pModule != NULL);
// This is a legacy event notification for updated PDBs.
@@ -5652,7 +5654,7 @@ void CordbProcess::RawDispatchEvent(
_ASSERTE(NULL != pAppDomain);
- CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->EnCRemap.vmDomainAssembly);
+ CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->EnCRemap.vmDomainFile);
PREFIX_ASSUME(pModule != NULL);
CordbFunction * pCurFunction = NULL;
@@ -5708,7 +5710,7 @@ void CordbProcess::RawDispatchEvent(
_ASSERTE(NULL != pAppDomain);
- CordbModule* pModule = pAppDomain->LookupOrCreateModule(pEvent->EnCRemap.vmDomainAssembly);
+ CordbModule* pModule = pAppDomain->LookupOrCreateModule(pEvent->EnCRemap.vmDomainFile);
PREFIX_ASSUME(pModule != NULL);
// Find the function we're remapping to, which must be the latest version
@@ -7624,7 +7626,27 @@ HRESULT CordbProcess::GetRuntimeOffsets()
{
-#if TARGET_UNIX
+#if !defined FEATURE_CORESYSTEM
+ // kernel32!OpenThread does not exist on all platforms (missing on Win98).
+ // So we need to delay load it.
+ typedef HANDLE (WINAPI *FPOPENTHREAD)(DWORD dwDesiredAccess,
+ BOOL bInheritHandle,
+ DWORD dwThreadId);
+
+
+
+ HMODULE mod = WszGetModuleHandle(W("kernel32.dll"));
+
+ _ASSERTE(mod != NULL); // can't fail since Kernel32.dll is already loaded.
+
+ const FPOPENTHREAD pfnOpenThread = (FPOPENTHREAD)GetProcAddress(mod, "OpenThread");
+
+ if (pfnOpenThread != NULL)
+ {
+ m_hHelperThread = pfnOpenThread(SYNCHRONIZE, FALSE, dwHelperTid);
+ CONSISTENCY_CHECK_MSGF(m_hHelperThread != NULL, ("Failed to get helper-thread handle. tid=0x%x\n", dwHelperTid));
+ }
+#elif TARGET_UNIX
m_hHelperThread = NULL; //RS is supposed to be able to live without a helper thread handle.
#else
m_hHelperThread = OpenThread(SYNCHRONIZE, FALSE, dwHelperTid);
@@ -7651,6 +7673,8 @@ HRESULT CordbProcess::GetRuntimeOffsets()
m_runtimeOffsets.m_excepNotForRuntimeBPAddr));
LOG((LF_CORDB, LL_INFO10000, " m_notifyRSOfSyncCompleteBPAddr= 0x%p\n",
m_runtimeOffsets.m_notifyRSOfSyncCompleteBPAddr));
+ LOG((LF_CORDB, LL_INFO10000, " m_raiseException= 0x%p\n",
+ m_runtimeOffsets.m_raiseExceptionAddr));
LOG((LF_CORDB, LL_INFO10000, " m_debuggerWordTLSIndex= 0x%08x\n",
m_runtimeOffsets.m_debuggerWordTLSIndex));
#endif // FEATURE_INTEROP_DEBUGGING
@@ -9795,22 +9819,27 @@ HRESULT CordbProcess::EnsureClrInstanceIdSet()
// If we didn't expect a specific CLR, then attempt to attach to any.
if (m_clrInstanceId == 0)
{
- // The only case in which we were allowed to request the "default" CLR instance
- // ID is when we're running in V2 mode. In V3, the client is required to pass
- // a non-zero value to OpenVirtualProcess. Since V2 is no longer supported we
- // no longer attempt to find it.
+
+#ifdef FEATURE_CORESYSTEM
if(m_cordb->GetTargetCLR() != 0)
{
m_clrInstanceId = PTR_TO_CORDB_ADDRESS(m_cordb->GetTargetCLR());
return S_OK;
}
+#endif
- // In V3, the client is required to pass a non-zero value to OpenVirtualProcess.
- // In V2 mode we should be setting target CLR up front but return an error
- // if we haven't.
+ // The only case in which we're allowed to request the "default" CLR instance
+ // ID is when we're running in V2 mode. In V3, the client is required to pass
+ // a non-zero value to OpenVirtualProcess.
_ASSERTE(m_pShim != NULL);
- return E_UNEXPECTED;
+ HRESULT hr = m_pShim->FindLoadedCLR(&m_clrInstanceId);
+ if (FAILED(hr))
+ {
+ // Couldn't find a loaded clr - no CLR instance ID yet
+ _ASSERTE(m_clrInstanceId == 0);
+ return hr;
+ }
}
// We've (now) got a valid CLR instance id
@@ -14881,6 +14910,26 @@ HRESULT CordbProcess::IsReadyForDetach()
pAppDomain = m_appDomains.FindNext(&foundAppDomain);
}
+ // If we're using the shim, give a chance to early-out if the OS doesn't support detach
+ // so that the user can continue to debug in that case.
+ // Ideally we'd just rely on the failure from DebugActiveProcessStop, but by then it's too late
+ // to recover. This function is our only chance to distinguish between graceful detach failures
+ // and hard detach failures (after which the process object is neutered).
+ if (m_pShim != NULL)
+ {
+#if !defined(FEATURE_CORESYSTEM) // CORESYSTEM TODO
+ HModuleHolder hKernel32;
+ hKernel32 = WszLoadLibrary(W("kernel32"));
+ if (hKernel32 == NULL)
+ return HRESULT_FROM_GetLastError();
+ typedef BOOL (*DebugActiveProcessStopSig) (DWORD);
+ DebugActiveProcessStopSig pDebugActiveProcessStop =
+ reinterpret_cast(GetProcAddress(hKernel32, "DebugActiveProcessStop"));
+ if (pDebugActiveProcessStop == NULL)
+ return COR_E_PLATFORMNOTSUPPORTED;
+#endif
+ }
+
return S_OK;
}
@@ -14927,16 +14976,16 @@ void CordbProcess::UpdateThreadsForAdUnload(CordbAppDomain * pAppDomain)
// CordbProcess::LookupClass
// Looks up a previously constructed CordbClass instance without creating. May return NULL if the
// CordbClass instance doesn't exist.
-// Argument: (in) vmDomainAssembly - pointer to the domain assembly for the module
+// Argument: (in) vmDomainFile - pointer to the domainfile for the module
// (in) mdTypeDef - metadata token for the class
// Return value: pointer to a previously created CordbClass instance or NULL in none exists
-CordbClass * CordbProcess::LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_DomainAssembly vmDomainAssembly, mdTypeDef classToken)
+CordbClass * CordbProcess::LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_DomainFile vmDomainFile, mdTypeDef classToken)
{
_ASSERTE(ThreadHoldsProcessLock());
if (pAppDomain != NULL)
{
- CordbModule * pModule = ((CordbAppDomain *)pAppDomain)->m_modules.GetBase(VmPtrToCookie(vmDomainAssembly));
+ CordbModule * pModule = ((CordbAppDomain *)pAppDomain)->m_modules.GetBase(VmPtrToCookie(vmDomainFile));
if (pModule != NULL)
{
return pModule->LookupClass(classToken);
@@ -14949,7 +14998,7 @@ CordbClass * CordbProcess::LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_Do
// Look for a specific module in the process.
//
// Arguments:
-// vmDomainAssembly - non-null module to lookup
+// vmDomainFile - non-null module to lookup
//
// Returns:
// a CordbModule object for the given cookie. Object may be from the cache, or created
@@ -14957,23 +15006,23 @@ CordbClass * CordbProcess::LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_Do
// Never returns null. Throws on error.
//
// Notes:
-// A VMPTR_DomainAssembly has appdomain affinity, but is ultimately scoped to a process.
-// So if we get a raw VMPTR_DomainAssembly (eg, from the stackwalker or from some other
+// A VMPTR_DomainFile has appdomain affinity, but is ultimately scoped to a process.
+// So if we get a raw VMPTR_DomainFile (eg, from the stackwalker or from some other
// lookup function), then we need to do a process wide lookup since we don't know which
// appdomain it's in. If you know the appdomain, you can use code:CordbAppDomain::LookupOrCreateModule.
//
-CordbModule * CordbProcess::LookupOrCreateModule(VMPTR_DomainAssembly vmDomainAssembly)
+CordbModule * CordbProcess::LookupOrCreateModule(VMPTR_DomainFile vmDomainFile)
{
INTERNAL_API_ENTRY(this);
RSLockHolder lockHolder(GetProcess()->GetProcessLock());
- _ASSERTE(!vmDomainAssembly.IsNull());
+ _ASSERTE(!vmDomainFile.IsNull());
- DomainAssemblyInfo data;
- GetDAC()->GetDomainAssemblyData(vmDomainAssembly, &data); // throws
+ DomainFileInfo data;
+ GetDAC()->GetDomainFileData(vmDomainFile, &data); // throws
CordbAppDomain * pAppDomain = LookupOrCreateAppDomain(data.vmAppDomain);
- return pAppDomain->LookupOrCreateModule(vmDomainAssembly);
+ return pAppDomain->LookupOrCreateModule(vmDomainFile);
}
//---------------------------------------------------------------------------------------
diff --git a/src/coreclr/debug/di/publish.cpp b/src/coreclr/debug/di/publish.cpp
index d27e28a4abc37..1d7741fb9ea75 100644
--- a/src/coreclr/debug/di/publish.cpp
+++ b/src/coreclr/debug/di/publish.cpp
@@ -43,8 +43,54 @@ BOOL GetAllProcessesInSystem(DWORD *ProcessId,
{
HandleHolder hSnapshotHolder;
+#if !defined(FEATURE_CORESYSTEM)
+ // Load the dll "kernel32.dll".
+ HModuleHolder hDll = WszLoadLibrary(W("kernel32"));
+ _ASSERTE(hDll != NULL);
+
+ if (hDll == NULL)
+ {
+ LOG((LF_CORDB, LL_INFO1000,
+ "Unable to load the dll for enumerating processes. "
+ "LoadLibrary (kernel32.dll) failed.\n"));
+ return FALSE;
+ }
+#else
+ // Load the dll "api-ms-win-obsolete-kernel32-l1-1-0.dll".
+ HModuleHolder hDll = WszLoadLibrary(W("api-ms-win-obsolete-kernel32-l1-1-0.dll"));
+ _ASSERTE(hDll != NULL);
+
+ if (hDll == NULL)
+ {
+ LOG((LF_CORDB, LL_INFO1000,
+ "Unable to load the dll for enumerating processes. "
+ "LoadLibrary (api-ms-win-obsolete-kernel32-l1-1-0.dll) failed.\n"));
+ return FALSE;
+ }
+#endif
+
+
// Create the Process' Snapshot
- HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
+ // Get the pointer to the requested function
+ FARPROC pProcAddr = GetProcAddress(hDll, "CreateToolhelp32Snapshot");
+
+ // If the proc address was not found, return error
+ if (pProcAddr == NULL)
+ {
+ LOG((LF_CORDB, LL_INFO1000,
+ "Unable to enumerate processes in the system. "
+ "GetProcAddr (CreateToolhelp32Snapshot) failed.\n"));
+ return FALSE;
+ }
+
+
+
+ // Handle from CreateToolHelp32Snapshot must be freed via CloseHandle().
+ typedef HANDLE CREATETOOLHELP32SNAPSHOT(DWORD, DWORD);
+
+ HANDLE hSnapshot =
+ ((CREATETOOLHELP32SNAPSHOT *)pProcAddr)(TH32CS_SNAPPROCESS, NULL);
+
if (hSnapshot == INVALID_HANDLE_VALUE)
{
LOG((LF_CORDB, LL_INFO1000,
@@ -55,13 +101,29 @@ BOOL GetAllProcessesInSystem(DWORD *ProcessId,
// HandleHolder doesn't deal with INVALID_HANDLE_VALUE, so we only assign if we have a legal value.
hSnapshotHolder.Assign(hSnapshot);
+ // Get the first process in the process list
+ // Get the pointer to the requested function
+ pProcAddr = GetProcAddress(hDll, "Process32First");
+
+ // If the proc address was not found, return error
+ if (pProcAddr == NULL)
+ {
+ LOG((LF_CORDB, LL_INFO1000,
+ "Unable to enumerate processes in the system. "
+ "GetProcAddr (Process32First) failed.\n"));
+ return FALSE;
+ }
+
PROCESSENTRY32 PE32;
// need to initialize the dwSize field before calling Process32First
PE32.dwSize = sizeof (PROCESSENTRY32);
- // Get the first process in the process list
- BOOL succ = Process32First(hSnapshot, &PE32);
+ typedef BOOL PROCESS32FIRST(HANDLE, LPPROCESSENTRY32);
+
+ BOOL succ =
+ ((PROCESS32FIRST *)pProcAddr)(hSnapshot, &PE32);
+
if (succ != TRUE)
{
LOG((LF_CORDB, LL_INFO1000,
@@ -70,14 +132,29 @@ BOOL GetAllProcessesInSystem(DWORD *ProcessId,
return FALSE;
}
+
// Loop over and get all the remaining processes
+ // Get the pointer to the requested function
+ pProcAddr = GetProcAddress(hDll, "Process32Next");
+
+ // If the proc address was not found, return error
+ if (pProcAddr == NULL)
+ {
+ LOG((LF_CORDB, LL_INFO1000,
+ "Unable to enumerate processes in the system. "
+ "GetProcAddr (Process32Next) failed.\n"));
+ return FALSE;
+ }
+
+ typedef BOOL PROCESS32NEXT(HANDLE, LPPROCESSENTRY32);
+
int iIndex = 0;
do
{
ProcessId [iIndex++] = PE32.th32ProcessID;
- succ = Process32Next(hSnapshot, &PE32);
+ succ = ((PROCESS32NEXT *)pProcAddr)(hSnapshot, &PE32);
} while ((succ == TRUE) && (iIndex < (int)dwArraySize));
@@ -100,12 +177,16 @@ const DWORD SAFETY_TIMEOUT = 2000;
// ******************************************
CorpubPublish::CorpubPublish()
- : CordbCommonBase(0)
- , m_fpGetModuleFileNameEx(NULL)
+ : CordbCommonBase(0),
+ m_fpGetModuleFileNameEx(NULL)
{
// Try to get psapi!GetModuleFileNameExW once, and then every process object can use it.
// If we can't get it, then we'll fallback to getting information from the IPC block.
+#if !defined(FEATURE_CORESYSTEM)
+ m_hPSAPIdll = WszLoadLibrary(W("psapi.dll"));
+#else
m_hPSAPIdll = WszLoadLibrary(W("api-ms-win-obsolete-psapi-l1-1-0.dll"));
+#endif
if (m_hPSAPIdll != NULL)
{
diff --git a/src/coreclr/debug/di/rsappdomain.cpp b/src/coreclr/debug/di/rsappdomain.cpp
index e140b8a77f13f..081baa95216d5 100644
--- a/src/coreclr/debug/di/rsappdomain.cpp
+++ b/src/coreclr/debug/di/rsappdomain.cpp
@@ -829,7 +829,7 @@ CordbAssembly * CordbAppDomain::LookupOrCreateAssembly(VMPTR_Assembly vmAssembly
// Lookup or create a module within the appdomain
//
// Arguments:
-// vmDomainAssembly - non-null module to lookup
+// vmDomainFile - non-null module to lookup
//
// Returns:
// a CordbModule object for the given cookie. Object may be from the cache, or created
@@ -839,26 +839,26 @@ CordbAssembly * CordbAppDomain::LookupOrCreateAssembly(VMPTR_Assembly vmAssembly
// Notes:
// If you don't know which appdomain the module is in, use code:CordbProcess::LookupOrCreateModule.
//
-CordbModule* CordbAppDomain::LookupOrCreateModule(VMPTR_Module vmModule, VMPTR_DomainAssembly vmDomainAssembly)
+CordbModule* CordbAppDomain::LookupOrCreateModule(VMPTR_Module vmModule, VMPTR_DomainFile vmDomainFile)
{
INTERNAL_API_ENTRY(this);
CordbModule * pModule;
RSLockHolder lockHolder(GetProcess()->GetProcessLock()); // @dbgtodo locking: push this up.
- _ASSERTE(!vmDomainAssembly.IsNull() || !vmModule.IsNull());
+ _ASSERTE(!vmDomainFile.IsNull() || !vmModule.IsNull());
// check to see if the module is present in this app domain
- pModule = m_modules.GetBase(vmDomainAssembly.IsNull() ? VmPtrToCookie(vmModule) : VmPtrToCookie(vmDomainAssembly));
+ pModule = m_modules.GetBase(vmDomainFile.IsNull() ? VmPtrToCookie(vmModule) : VmPtrToCookie(vmDomainFile));
if (pModule != NULL)
{
return pModule;
}
if (vmModule.IsNull())
- GetProcess()->GetDAC()->GetModuleForDomainAssembly(vmDomainAssembly, &vmModule);
+ GetProcess()->GetDAC()->GetModuleForDomainFile(vmDomainFile, &vmModule);
- RSInitHolder pModuleInit(new CordbModule(GetProcess(), vmModule, vmDomainAssembly));
+ RSInitHolder pModuleInit(new CordbModule(GetProcess(), vmModule, vmDomainFile));
pModule = pModuleInit.TransferOwnershipToHash(&m_modules);
// The appdomains should match.
@@ -868,12 +868,12 @@ CordbModule* CordbAppDomain::LookupOrCreateModule(VMPTR_Module vmModule, VMPTR_D
}
-CordbModule* CordbAppDomain::LookupOrCreateModule(VMPTR_DomainAssembly vmDomainAssembly)
+CordbModule* CordbAppDomain::LookupOrCreateModule(VMPTR_DomainFile vmDomainFile)
{
INTERNAL_API_ENTRY(this);
- _ASSERTE(!vmDomainAssembly.IsNull());
- return LookupOrCreateModule(VMPTR_Module::NullPtr(), vmDomainAssembly);
+ _ASSERTE(!vmDomainFile.IsNull());
+ return LookupOrCreateModule(VMPTR_Module::NullPtr(), vmDomainFile);
}
@@ -890,7 +890,7 @@ CordbModule* CordbAppDomain::LookupOrCreateModule(VMPTR_DomainAssembly vmDomainA
// invokes this callback.
// static
-void CordbAppDomain::ModuleEnumerationCallback(VMPTR_DomainAssembly vmModule, void * pUserData)
+void CordbAppDomain::ModuleEnumerationCallback(VMPTR_DomainFile vmModule, void * pUserData)
{
CONTRACTL
{
diff --git a/src/coreclr/debug/di/rsclass.cpp b/src/coreclr/debug/di/rsclass.cpp
index 4fe8930712a4e..40d886de9935e 100644
--- a/src/coreclr/debug/di/rsclass.cpp
+++ b/src/coreclr/debug/di/rsclass.cpp
@@ -781,11 +781,11 @@ void CordbClass::Init(ClassLoadLevel desiredLoadLevel)
if(desiredLoadLevel == FullInfo)
{
VMPTR_AppDomain vmAppDomain = VMPTR_AppDomain::NullPtr();
- VMPTR_DomainAssembly vmDomainAssembly = m_pModule->GetRuntimeDomainAssembly();
- if (!vmDomainAssembly.IsNull())
+ VMPTR_DomainFile vmDomainFile = m_pModule->GetRuntimeDomainFile();
+ if (!vmDomainFile.IsNull())
{
- DomainAssemblyInfo info;
- pDac->GetDomainAssemblyData(vmDomainAssembly, &info);
+ DomainFileInfo info;
+ pDac->GetDomainFileData(vmDomainFile, &info);
vmAppDomain = info.vmAppDomain;
}
pDac->GetClassInfo(vmAppDomain, vmTypeHandle, &m_classInfo);
@@ -941,7 +941,7 @@ void CordbClass::InitEnCFieldInfo(EnCHangingFieldInfo * pEncField,
fieldToken,
ELEMENT_TYPE_MAX,
classToken,
- m_pModule->GetRuntimeDomainAssembly());
+ m_pModule->GetRuntimeDomainFile());
}
else
{
@@ -966,7 +966,7 @@ void CordbClass::InitEnCFieldInfo(EnCHangingFieldInfo * pEncField,
// This is used only for log messages, and could
// be removed.
classToken, // metadata token for the class
- m_pModule->GetRuntimeDomainAssembly()); // Domain file for the class
+ m_pModule->GetRuntimeDomainFile()); // Domain file for the class
}
} // CordbClass::InitFieldData
diff --git a/src/coreclr/debug/di/rsfunction.cpp b/src/coreclr/debug/di/rsfunction.cpp
index f2384411bc0f2..b901a1ded88fe 100644
--- a/src/coreclr/debug/di/rsfunction.cpp
+++ b/src/coreclr/debug/di/rsfunction.cpp
@@ -705,7 +705,7 @@ HRESULT CordbFunction::GetILCodeAndSigToken()
// and we also fallback on creating an empty ILCode object.
// See issue DD 273199 for cases where IL and NGEN metadata mismatch (different RVAs).
ALLOW_DATATARGET_MISSING_OR_INCONSISTENT_MEMORY(
- pProcess->GetDAC()->GetILCodeAndSig(m_pModule->GetRuntimeDomainAssembly(),
+ pProcess->GetDAC()->GetILCodeAndSig(m_pModule->GetRuntimeDomainFile(),
m_MDToken,
&codeInfo,
&localVarSigToken);
@@ -782,7 +782,7 @@ HRESULT CordbFunction::InitParentClassOfFunction()
}
mdTypeDef classMetadataToken;
- VMPTR_DomainAssembly vmDomainAssembly = m_pModule->GetRuntimeDomainAssembly();
+ VMPTR_DomainFile vmDomainFile = m_pModule->GetRuntimeDomainFile();
classMetadataToken = InitParentClassOfFunctionHelper(m_MDToken);
@@ -795,7 +795,7 @@ HRESULT CordbFunction::InitParentClassOfFunction()
CordbAssembly *pAssembly = m_pModule->GetCordbAssembly();
PREFIX_ASSUME(pAssembly != NULL);
- CordbModule* pClassModule = pAssembly->GetAppDomain()->LookupOrCreateModule(vmDomainAssembly);
+ CordbModule* pClassModule = pAssembly->GetAppDomain()->LookupOrCreateModule(vmDomainFile);
PREFIX_ASSUME(pClassModule != NULL);
CordbClass *pClass;
@@ -850,7 +850,7 @@ HRESULT CordbFunction::InitNativeCodeInfo()
// All we actually need is the start address and method desc which are cheap to get relative
// to some of the other members. So far this doesn't appear to be a perf hotspot, but if it
// shows up in some scenario it wouldn't be too hard to improve it
- pProcess->GetDAC()->GetNativeCodeInfo(m_pModule->GetRuntimeDomainAssembly(), m_MDToken, &codeInfo);
+ pProcess->GetDAC()->GetNativeCodeInfo(m_pModule->GetRuntimeDomainFile(), m_MDToken, &codeInfo);
}
// populate the m_nativeCode pointer with the code info we found
@@ -904,7 +904,7 @@ HRESULT CordbFunction::SetJMCStatus(BOOL fIsUserCode)
DebuggerIPCEvent event;
pProcess->InitIPCEvent(&event, DB_IPCE_SET_METHOD_JMC_STATUS, true, m_pModule->GetAppDomain()->GetADToken());
- event.SetJMCFunctionStatus.vmDomainAssembly = m_pModule->GetRuntimeDomainAssembly();
+ event.SetJMCFunctionStatus.vmDomainFile = m_pModule->GetRuntimeDomainFile();
event.SetJMCFunctionStatus.funcMetadataToken = m_MDToken;
event.SetJMCFunctionStatus.dwStatus = fIsUserCode;
@@ -956,7 +956,7 @@ HRESULT CordbFunction::GetJMCStatus(BOOL * pfIsUserCode)
// Ask the left-side if a method is user code or not.
DebuggerIPCEvent event;
pProcess->InitIPCEvent(&event, DB_IPCE_GET_METHOD_JMC_STATUS, true, m_pModule->GetAppDomain()->GetADToken());
- event.SetJMCFunctionStatus.vmDomainAssembly = m_pModule->GetRuntimeDomainAssembly();
+ event.SetJMCFunctionStatus.vmDomainFile = m_pModule->GetRuntimeDomainFile();
event.SetJMCFunctionStatus.funcMetadataToken = m_MDToken;
diff --git a/src/coreclr/debug/di/rsmain.cpp b/src/coreclr/debug/di/rsmain.cpp
index cc30e2c84136e..5594b299e2d12 100644
--- a/src/coreclr/debug/di/rsmain.cpp
+++ b/src/coreclr/debug/di/rsmain.cpp
@@ -961,12 +961,15 @@ Cordb::Cordb(CorDebugInterfaceVersion iDebuggerVersion)
}
Cordb::Cordb(CorDebugInterfaceVersion iDebuggerVersion, const ProcessDescriptor& pd)
- : CordbBase(NULL, 0, enumCordb)
- , m_processes(11)
- , m_initialized(false)
- , m_debuggerSpecifiedVersion(iDebuggerVersion)
- , m_pd(pd)
- , m_targetCLR(0)
+ : CordbBase(NULL, 0, enumCordb),
+ m_processes(11),
+ m_initialized(false),
+ m_debuggerSpecifiedVersion(iDebuggerVersion),
+ m_pd(pd)
+#ifdef FEATURE_CORESYSTEM
+ ,
+ m_targetCLR(0)
+#endif
{
g_pRSDebuggingInfo->m_Cordb = this;
@@ -1417,7 +1420,10 @@ HRESULT Cordb::SetTargetCLR(HMODULE hmodTargetCLR)
if (m_initialized)
return E_FAIL;
+#ifdef FEATURE_CORESYSTEM
m_targetCLR = hmodTargetCLR;
+#endif
+
return S_OK;
}
@@ -1522,6 +1528,16 @@ bool Cordb::IsInteropDebuggingSupported()
// We explicitly refrain from checking the unmanaged callback. See comment in
// ICorDebug::SetUnmanagedHandler for details.
#ifdef FEATURE_INTEROP_DEBUGGING
+
+#if !defined(FEATURE_CORESYSTEM)
+ // Interop debugging is only supported internally on CoreCLR.
+ // Check if the special reg key is set. If not, then we don't allow interop debugging.
+ if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgEnableMixedModeDebugging) == 0)
+ {
+ return false;
+ }
+#endif // FEATURE_CORESYSTEM
+
return true;
#else
return false;
diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h
index acb8d4c32473c..690917c2795a9 100644
--- a/src/coreclr/debug/di/rspriv.h
+++ b/src/coreclr/debug/di/rspriv.h
@@ -2324,7 +2324,9 @@ class Cordb : public CordbBase, public ICorDebug, public ICorDebugRemote
CorDebugInterfaceVersion GetDebuggerVersion() const;
+#ifdef FEATURE_CORESYSTEM
HMODULE GetTargetCLR() { return m_targetCLR; }
+#endif
private:
bool IsCreateProcessSupported();
@@ -2345,7 +2347,11 @@ class Cordb : public CordbBase, public ICorDebug, public ICorDebugRemote
// Store information about the process to be debugged
ProcessDescriptor m_pd;
+//Note - this code could be useful outside coresystem, but keeping the change localized
+// because we are late in the win8 release
+#ifdef FEATURE_CORESYSTEM
HMODULE m_targetCLR;
+#endif
};
@@ -2505,13 +2511,13 @@ class CordbAppDomain : public CordbBase,
CordbModule * GetModuleFromMetaDataInterface(IUnknown *pIMetaData);
// Lookup a module from the cache. Create and to the cache if needed.
- CordbModule * LookupOrCreateModule(VMPTR_Module vmModuleToken, VMPTR_DomainAssembly vmDomainAssemblyToken);
+ CordbModule * LookupOrCreateModule(VMPTR_Module vmModuleToken, VMPTR_DomainFile vmDomainFileToken);
// Lookup a module from the cache. Create and to the cache if needed.
- CordbModule * LookupOrCreateModule(VMPTR_DomainAssembly vmDomainAssemblyToken);
+ CordbModule * LookupOrCreateModule(VMPTR_DomainFile vmDomainFileToken);
// Callback from DAC for module enumeration
- static void ModuleEnumerationCallback(VMPTR_DomainAssembly vmModule, void * pUserData);
+ static void ModuleEnumerationCallback(VMPTR_DomainFile vmModule, void * pUserData);
// Use DAC to add any modules for this assembly.
void PrepopulateModules();
@@ -2543,7 +2549,7 @@ class CordbAppDomain : public CordbBase,
// Cache of modules in this appdomain. In the VM, modules live in an assembly.
// This cache lives on the appdomain because we generally want to do appdomain (or process)
// wide lookup.
- // This is indexed by VMPTR_DomainAssembly, which has appdomain affinity.
+ // This is indexed by VMPTR_DomainFile, which has appdomain affinity.
// This is populated by code:CordbAppDomain::LookupOrCreateModule (which may be invoked
// anytime the RS gets hold of a VMPTR), and are removed at the unload event.
CordbSafeHashTable m_modules;
@@ -3454,9 +3460,9 @@ class CordbProcess :
// Looks up a previously constructed CordbClass instance without creating. May return NULL if the
// CordbClass instance doesn't exist.
- CordbClass * LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_DomainAssembly vmDomainAssembly, mdTypeDef classToken);
+ CordbClass * LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_DomainFile vmDomainFile, mdTypeDef classToken);
- CordbModule * LookupOrCreateModule(VMPTR_DomainAssembly vmDomainAssembly);
+ CordbModule * LookupOrCreateModule(VMPTR_DomainFile vmDomainFile);
#ifdef FEATURE_INTEROP_DEBUGGING
CordbUnmanagedThread *GetUnmanagedThread(DWORD dwThreadId)
@@ -4141,7 +4147,7 @@ class CordbModule : public CordbBase,
public:
CordbModule(CordbProcess * process,
VMPTR_Module vmModule,
- VMPTR_DomainAssembly vmDomainAssembly);
+ VMPTR_DomainFile vmDomainFile);
virtual ~CordbModule();
virtual void Neuter();
@@ -4348,9 +4354,9 @@ class CordbModule : public CordbBase,
const WCHAR * GetNGenImagePath();
- const VMPTR_DomainAssembly GetRuntimeDomainAssembly ()
+ const VMPTR_DomainFile GetRuntimeDomainFile ()
{
- return m_vmDomainAssembly;
+ return m_vmDomainFile;
}
const VMPTR_Module GetRuntimeModule()
@@ -4385,7 +4391,7 @@ class CordbModule : public CordbBase,
// The real handle into the VM for a module. This is appdomain aware.
// This is the primary VM counterpart for the CordbModule.
- VMPTR_DomainAssembly m_vmDomainAssembly;
+ VMPTR_DomainFile m_vmDomainFile;
VMPTR_Module m_vmModule;
@@ -4800,7 +4806,7 @@ class CordbType : public CordbBase, public ICorDebugType, public ICorDebugType2
void DestNaryType(Instantiation *pInst);
CorElementType GetElementType() { return m_elementType; }
- VMPTR_DomainAssembly GetDomainAssembly();
+ VMPTR_DomainFile GetDomainFile();
VMPTR_Module GetModule();
// If this is a ptr type, get the CordbType that it points to.
@@ -6260,6 +6266,10 @@ class CordbThread : public CordbBase, public ICorDebugThread,
BOOL ConvertFrameForILMethodWithoutMetadata(ICorDebugFrame * pFrame,
ICorDebugInternalFrame2 ** ppInternalFrame2);
+ // Gets/sets m_fCreationEventQueued
+ bool CreateEventWasQueued();
+ void SetCreateEventQueued();
+
//-----------------------------------------------------------
// Data members
//-----------------------------------------------------------
@@ -6317,6 +6327,11 @@ class CordbThread : public CordbBase, public ICorDebugThread,
// Both events will set this bit high. Be careful not to reset this bit inbetween them.
bool m_fException;
+ // True if a creation event has been queued for this thread
+ // The event may or may not have been dispatched yet
+ // Bugfix DevDiv2\DevDiv 77523 - this is only being set from ShimProcess::QueueFakeThreadAttachEventsNativeOrder
+ bool m_fCreationEventQueued;
+
// Object handle for Exception object in debuggee.
VMPTR_OBJECTHANDLE m_vmExcepObjHandle;
diff --git a/src/coreclr/debug/di/rsstackwalk.cpp b/src/coreclr/debug/di/rsstackwalk.cpp
index b115349593fc2..42732435db409 100644
--- a/src/coreclr/debug/di/rsstackwalk.cpp
+++ b/src/coreclr/debug/di/rsstackwalk.cpp
@@ -634,7 +634,7 @@ HRESULT CordbStackWalk::GetFrameWorker(ICorDebugFrame ** ppFrame)
_ASSERTE(pCurrentAppDomain != NULL);
// Lookup the module
- CordbModule* pModule = pCurrentAppDomain->LookupOrCreateModule(pFuncData->vmDomainAssembly);
+ CordbModule* pModule = pCurrentAppDomain->LookupOrCreateModule(pFuncData->vmDomainFile);
PREFIX_ASSUME(pModule != NULL);
// Create or look up a CordbNativeCode. There is one for each jitted instance of a method,
diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp
index 38a498752771a..577574b796019 100644
--- a/src/coreclr/debug/di/rsthread.cpp
+++ b/src/coreclr/debug/di/rsthread.cpp
@@ -81,6 +81,7 @@ CordbThread::CordbThread(CordbProcess * pProcess, VMPTR_Thread vmThread) :
m_fFloatStateValid(false),
m_floatStackTop(0),
m_fException(false),
+ m_fCreationEventQueued(false),
m_EnCRemapFunctionIP(NULL),
m_userState(kInvalidUserState),
m_hCachedThread(INVALID_HANDLE_VALUE),
@@ -1629,8 +1630,8 @@ HRESULT CordbThread::SetIP(bool fCanSetIPOnly,
ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
- VMPTR_DomainAssembly vmDomainAssembly = pNativeCode->GetModule()->m_vmDomainAssembly;
- _ASSERTE(!vmDomainAssembly.IsNull());
+ VMPTR_DomainFile vmDomainFile = pNativeCode->GetModule()->m_vmDomainFile;
+ _ASSERTE(!vmDomainFile.IsNull());
// If this thread is stopped due to an exception, never allow SetIP
if (HasException())
@@ -1642,7 +1643,7 @@ HRESULT CordbThread::SetIP(bool fCanSetIPOnly,
GetProcess()->InitIPCEvent(&event, DB_IPCE_SET_IP, true, GetAppDomain()->GetADToken());
event.SetIP.fCanSetIPOnly = fCanSetIPOnly;
event.SetIP.vmThreadToken = m_vmThreadToken;
- event.SetIP.vmDomainAssembly = vmDomainAssembly;
+ event.SetIP.vmDomainFile = vmDomainFile;
event.SetIP.mdMethod = pNativeCode->GetMetadataToken();
event.SetIP.vmMethodDesc = pNativeCode->GetVMNativeCodeMethodDescToken();
event.SetIP.startAddress = pNativeCode->GetAddress();
@@ -1654,7 +1655,7 @@ HRESULT CordbThread::SetIP(bool fCanSetIPOnly,
"mod:0x%x MethodDef:0x%x offset:0x%x il?:0x%x\n",
GetCurrentThreadId(),
VmPtrToCookie(m_vmThreadToken),
- VmPtrToCookie(vmDomainAssembly),
+ VmPtrToCookie(vmDomainFile),
pNativeCode->GetMetadataToken(),
offset,
fIsIL));
@@ -2789,6 +2790,21 @@ HRESULT CordbThread::GetBlockingObjects(ICorDebugBlockingObjectEnum **ppBlocking
return hr;
}
+// ----------------------------------------------------------------------------
+// CordbThread::SetCreateEventQueued
+void CordbThread::SetCreateEventQueued()
+{
+ m_fCreationEventQueued = true;
+}
+
+// ----------------------------------------------------------------------------
+// CordbThread::CreateEventWasQueued
+bool CordbThread::CreateEventWasQueued()
+{
+ return m_fCreationEventQueued;
+}
+
+
#ifdef FEATURE_INTEROP_DEBUGGING
/* ------------------------------------------------------------------------- *
* Unmanaged Thread classes
@@ -5249,7 +5265,7 @@ CordbInternalFrame::CordbInternalFrame(CordbThread * pThread,
// Find the module of the function. Note that this module isn't necessarily in the same domain as our frame.
// FuncEval frames can point to methods they are going to invoke in another domain.
CordbModule * pModule = NULL;
- pModule = GetProcess()->LookupOrCreateModule(pData->stubFrame.vmDomainAssembly);
+ pModule = GetProcess()->LookupOrCreateModule(pData->stubFrame.vmDomainFile);
_ASSERTE(pModule != NULL);
//
@@ -9645,7 +9661,7 @@ HRESULT CordbEval::CallParameterizedFunction(ICorDebugFunction *pFunction,
event.FuncEval.vmThreadToken = m_thread->m_vmThreadToken;
event.FuncEval.funcEvalType = m_evalType;
event.FuncEval.funcMetadataToken = m_function->GetMetadataToken();
- event.FuncEval.vmDomainAssembly = m_function->GetModule()->GetRuntimeDomainAssembly();
+ event.FuncEval.vmDomainFile = m_function->GetModule()->GetRuntimeDomainFile();
event.FuncEval.funcEvalKey = hFuncEval.Ptr();
event.FuncEval.argCount = nArgs;
event.FuncEval.genericArgsCount = nTypeArgs;
@@ -9828,7 +9844,7 @@ HRESULT CordbEval::NewParameterizedObject(ICorDebugFunction * pConstructor,
event.FuncEval.vmThreadToken = m_thread->m_vmThreadToken;
event.FuncEval.funcEvalType = m_evalType;
event.FuncEval.funcMetadataToken = m_function->GetMetadataToken();
- event.FuncEval.vmDomainAssembly = m_function->GetModule()->GetRuntimeDomainAssembly();
+ event.FuncEval.vmDomainFile = m_function->GetModule()->GetRuntimeDomainFile();
event.FuncEval.funcEvalKey = hFuncEval.Ptr();
event.FuncEval.argCount = nArgs;
event.FuncEval.genericArgsCount = nTypeArgs;
@@ -9929,7 +9945,7 @@ HRESULT CordbEval::NewParameterizedObjectNoConstructor(ICorDebugClass * pClass,
event.FuncEval.funcEvalType = m_evalType;
event.FuncEval.funcMetadataToken = mdMethodDefNil;
event.FuncEval.funcClassMetadataToken = (mdTypeDef)m_class->m_id;
- event.FuncEval.vmDomainAssembly = m_class->GetModule()->GetRuntimeDomainAssembly();
+ event.FuncEval.vmDomainFile = m_class->GetModule()->GetRuntimeDomainFile();
event.FuncEval.funcEvalKey = hFuncEval.Ptr();
event.FuncEval.argCount = 0;
event.FuncEval.genericArgsCount = nTypeArgs;
@@ -10024,7 +10040,7 @@ HRESULT CordbEval::NewStringWithLength(LPCWSTR wszString, UINT iLength)
// Note: no function or module here...
event.FuncEval.funcMetadataToken = mdMethodDefNil;
event.FuncEval.funcClassMetadataToken = mdTypeDefNil;
- event.FuncEval.vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ event.FuncEval.vmDomainFile = VMPTR_DomainFile::NullPtr();
event.FuncEval.argCount = 0;
event.FuncEval.genericArgsCount = 0;
event.FuncEval.genericArgsNodeCount = 0;
@@ -10141,7 +10157,7 @@ HRESULT CordbEval::NewParameterizedArray(ICorDebugType * pElementType,
// Note: no function or module here...
event.FuncEval.funcMetadataToken = mdMethodDefNil;
event.FuncEval.funcClassMetadataToken = mdTypeDefNil;
- event.FuncEval.vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ event.FuncEval.vmDomainFile = VMPTR_DomainFile::NullPtr();
event.FuncEval.argCount = 0;
event.FuncEval.genericArgsCount = 1;
diff --git a/src/coreclr/debug/di/rstype.cpp b/src/coreclr/debug/di/rstype.cpp
index af6a8f5e14a58..3d807bb2434f5 100644
--- a/src/coreclr/debug/di/rstype.cpp
+++ b/src/coreclr/debug/di/rstype.cpp
@@ -1191,7 +1191,7 @@ HRESULT CordbType::TypeDataToType(CordbAppDomain *pAppDomain, DebuggerIPCE_Basic
DebuggerIPCE_ExpandedTypeData e;
e.elementType = et;
e.ClassTypeData.metadataToken = data->metadataToken;
- e.ClassTypeData.vmDomainAssembly = data->vmDomainAssembly;
+ e.ClassTypeData.vmDomainFile = data->vmDomainFile;
e.ClassTypeData.vmModule = data->vmModule;
e.ClassTypeData.typeHandle = data->vmTypeHandle;
return CordbType::TypeDataToType(pAppDomain, &e, pRes);
@@ -1254,7 +1254,7 @@ HRESULT CordbType::TypeDataToType(CordbAppDomain *pAppDomain, DebuggerIPCE_Expan
CordbModule * pClassModule = NULL;
EX_TRY
{
- pClassModule = pAppDomain->LookupOrCreateModule(data->ClassTypeData.vmModule, data->ClassTypeData.vmDomainAssembly);
+ pClassModule = pAppDomain->LookupOrCreateModule(data->ClassTypeData.vmModule, data->ClassTypeData.vmDomainFile);
}
EX_CATCH_HRESULT(hr);
if( pClassModule == NULL )
@@ -1611,7 +1611,7 @@ HRESULT CordbType::InitStringOrObjectClass(BOOL fForceInit)
//
CordbProcess *pProcess = GetProcess();
mdTypeDef metadataToken;
- VMPTR_DomainAssembly vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ VMPTR_DomainFile vmDomainFile = VMPTR_DomainFile::NullPtr();
VMPTR_Module vmModule = VMPTR_Module::NullPtr();
{
@@ -1620,13 +1620,13 @@ HRESULT CordbType::InitStringOrObjectClass(BOOL fForceInit)
m_elementType,
&metadataToken,
&vmModule,
- &vmDomainAssembly);
+ &vmDomainFile);
}
//
// Step 2) Lookup CordbClass based off token + Module.
//
- CordbModule * pTypeModule = m_appdomain->LookupOrCreateModule(vmModule, vmDomainAssembly);
+ CordbModule * pTypeModule = m_appdomain->LookupOrCreateModule(vmModule, vmDomainFile);
_ASSERTE(pTypeModule != NULL);
IfFailThrow(pTypeModule->LookupOrCreateClass(metadataToken, &m_pClass));
@@ -1704,7 +1704,7 @@ HRESULT CordbType::InitInstantiationFieldInfo(BOOL fForceInit)
// this may be called multiple times. Each call will discard previous values in m_fieldList and reinitialize
// the list with updated information
RSLockHolder lockHolder(pProcess->GetProcessLock());
- pProcess->GetDAC()->GetInstantiationFieldInfo(m_pClass->GetModule()->GetRuntimeDomainAssembly(),
+ pProcess->GetDAC()->GetInstantiationFieldInfo(m_pClass->GetModule()->GetRuntimeDomainFile(),
m_typeHandleExact,
typeHandleApprox,
&m_fieldList,
@@ -1876,23 +1876,23 @@ CordbType::GetUnboxedObjectSize(ULONG32 *pObjectSize)
}
}
-VMPTR_DomainAssembly CordbType::GetDomainAssembly()
+VMPTR_DomainFile CordbType::GetDomainFile()
{
if (m_pClass != NULL)
{
CordbModule * pModule = m_pClass->GetModule();
if (pModule)
{
- return pModule->m_vmDomainAssembly;
+ return pModule->m_vmDomainFile;
}
else
{
- return VMPTR_DomainAssembly::NullPtr();
+ return VMPTR_DomainFile::NullPtr();
}
}
else
{
- return VMPTR_DomainAssembly::NullPtr();
+ return VMPTR_DomainFile::NullPtr();
}
}
@@ -1937,7 +1937,7 @@ HRESULT CordbType::TypeToBasicTypeData(DebuggerIPCE_BasicTypeData *data)
case ELEMENT_TYPE_PTR:
data->elementType = m_elementType;
data->metadataToken = mdTokenNil;
- data->vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ data->vmDomainFile = VMPTR_DomainFile::NullPtr();
data->vmTypeHandle = m_typeHandleExact;
if (data->vmTypeHandle.IsNull())
{
@@ -1950,7 +1950,7 @@ HRESULT CordbType::TypeToBasicTypeData(DebuggerIPCE_BasicTypeData *data)
_ASSERTE(m_pClass != NULL);
data->elementType = m_pClass->IsValueClassNoInit() ? ELEMENT_TYPE_VALUETYPE : ELEMENT_TYPE_CLASS;
data->metadataToken = m_pClass->MDToken();
- data->vmDomainAssembly = GetDomainAssembly();
+ data->vmDomainFile = GetDomainFile();
data->vmTypeHandle = m_typeHandleExact;
if (m_pClass->HasTypeParams() && data->vmTypeHandle.IsNull())
{
@@ -1961,7 +1961,7 @@ HRESULT CordbType::TypeToBasicTypeData(DebuggerIPCE_BasicTypeData *data)
// This includes all the "primitive" types, in which CorElementType is a sufficient description.
data->elementType = m_elementType;
data->metadataToken = mdTokenNil;
- data->vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ data->vmDomainFile = VMPTR_DomainFile::NullPtr();
data->vmTypeHandle = VMPTR_TypeHandle::NullPtr();
break;
}
@@ -2001,7 +2001,7 @@ void CordbType::TypeToExpandedTypeData(DebuggerIPCE_ExpandedTypeData *data)
{
data->elementType = m_pClass->IsValueClassNoInit() ? ELEMENT_TYPE_VALUETYPE : ELEMENT_TYPE_CLASS;
data->ClassTypeData.metadataToken = m_pClass->GetToken();
- data->ClassTypeData.vmDomainAssembly = GetDomainAssembly();
+ data->ClassTypeData.vmDomainFile = GetDomainFile();
data->ClassTypeData.vmModule = GetModule();
data->ClassTypeData.typeHandle = VMPTR_TypeHandle::NullPtr();
@@ -2339,14 +2339,14 @@ HRESULT CordbType::GetTypeID(COR_TYPEID *pId)
{
mdTypeDef mdToken;
VMPTR_Module vmModule = VMPTR_Module::NullPtr();
- VMPTR_DomainAssembly vmDomainAssembly = VMPTR_DomainAssembly::NullPtr();
+ VMPTR_DomainFile vmDomainFile = VMPTR_DomainFile::NullPtr();
// get module and token of the simple type
GetProcess()->GetDAC()->GetSimpleType(GetAppDomain()->GetADToken(),
et,
&mdToken,
&vmModule,
- &vmDomainAssembly);
+ &vmDomainFile);
vmTypeHandle = GetProcess()->GetDAC()->GetTypeHandle(vmModule, mdToken);
}
diff --git a/src/coreclr/debug/di/shimpriv.h b/src/coreclr/debug/di/shimpriv.h
index 15efec5647349..26a939ee8a3a8 100644
--- a/src/coreclr/debug/di/shimpriv.h
+++ b/src/coreclr/debug/di/shimpriv.h
@@ -426,6 +426,9 @@ class ShimProcess
// Helper to queue fake assembly and mdule events
void QueueFakeAssemblyAndModuleEvent(ICorDebugAssembly * pAssembly);
+ // Queue fake thread-create events on attach. Order via native threads.
+ HRESULT QueueFakeThreadAttachEventsNativeOrder();
+
// Queue fake thread-create events on attach. No ordering.
HRESULT QueueFakeThreadAttachEventsNoOrder();
@@ -488,6 +491,9 @@ class ShimProcess
// dispatching an event.
void PreDispatchEvent(bool fRealCreateProcessEvent = false);
+ // Look for a CLR in the process and if found, return it's instance ID
+ HRESULT FindLoadedCLR(CORDB_ADDRESS * pClrInstanceId);
+
// Retrieve the IP address and the port number of the debugger proxy.
MachineInfo GetMachineInfo();
@@ -520,6 +526,9 @@ class ShimProcess
HANDLE m_markAttachPendingEvent;
HANDLE m_terminatingEvent;
+ // Finds the base address of [core]clr.dll
+ CORDB_ADDRESS GetCLRInstanceBaseAddress();
+
//
// Event Queues
//
diff --git a/src/coreclr/debug/di/shimprocess.cpp b/src/coreclr/debug/di/shimprocess.cpp
index 8d60f954b4a71..72da6068e8235 100644
--- a/src/coreclr/debug/di/shimprocess.cpp
+++ b/src/coreclr/debug/di/shimprocess.cpp
@@ -17,6 +17,10 @@
#include
#include "shimpriv.h"
+#if !defined(FEATURE_CORESYSTEM)
+#include
+#endif
+
//---------------------------------------------------------------------------------------
//
// Ctor for a ShimProcess
@@ -867,6 +871,8 @@ HRESULT ShimProcess::HandleWin32DebugEvent(const DEBUG_EVENT * pEvent)
if (!fSkipResume)
{
::Sleep(500);
+ hrIgnore = GetNativePipeline()->EnsureThreadsRunning();
+ SIMPLIFYING_ASSUMPTION_SUCCEEDED(hrIgnore);
}
}
}
@@ -1014,6 +1020,9 @@ void ShimProcess::QueueFakeAttachEventsIfNeeded(bool fRealCreateProcessEvent)
// same order that V2 used. So without using platform-specific thread-enumeration,
// we can't get the V2 ordering.
//
+// Compare to code:ShimProcess::QueueFakeThreadAttachEventsNativeOrder,
+// which sends threads in the OS native thread create order.
+//
HRESULT ShimProcess::QueueFakeThreadAttachEventsNoOrder()
{
ICorDebugProcess * pProcess = GetProcess();
@@ -1052,6 +1061,136 @@ HRESULT ShimProcess::QueueFakeThreadAttachEventsNoOrder()
return S_OK;
}
+//---------------------------------------------------------------------------------------
+// Send fake Thread-create events for attach, using the order of the OS native
+// thread list.
+//
+// Returns:
+// S_OK on success, else error.
+//
+// Notes:
+// This sends fake thread-create events, ala V2 attach.
+// See code:ShimProcess::QueueFakeAttachEvents for details
+// The order of the thread creates matches the OS's native thread list.
+// This is important because the debugger can use the order of thread-create
+// callbacks to associate logical thread-ids (0,1,2...) with threads. Users
+// may rely on thread 0 always being the main thread.
+// In contrast, the order from ICorDebugProcess::EnumerateThreads is random.
+//
+// Compare to code:ShimProcess::QueueFakeThreadAttachEventsNoOrder, which
+// sends the threads in an arbitrary order.
+HRESULT ShimProcess::QueueFakeThreadAttachEventsNativeOrder()
+{
+#ifdef FEATURE_CORESYSTEM
+ _ASSERTE("NYI");
+ return E_FAIL;
+#else
+ ICorDebugProcess * pProcess = GetProcess();
+
+ DWORD dwProcessId;
+ HRESULT hr = pProcess->GetID(&dwProcessId);
+ SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
+ THREADENTRY32 te32;
+
+ // Take a snapshot of all running threads
+ hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+ if (hThreadSnap == INVALID_HANDLE_VALUE)
+ {
+ hr = HRESULT_FROM_GetLastError();
+ SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr);
+ return hr;
+ }
+ // HandleHolder doesn't deal with INVALID_HANDLE_VALUE, so we only assign if we have a legal value.
+ HandleHolder hSnapshotHolder(hThreadSnap);
+
+ // Fill in the size of the structure before using it.
+ te32.dwSize = sizeof(THREADENTRY32);
+
+ // Retrieve information about the first thread, and exit if unsuccessful
+ if (!Thread32First(hThreadSnap, &te32))
+ {
+ hr = HRESULT_FROM_GetLastError();
+ return hr;
+ }
+
+ // Now walk the thread list of the system,
+ // and display information about each thread
+ // associated with the specified process
+ do
+ {
+ if (te32.th32OwnerProcessID == dwProcessId)
+ {
+ RSExtSmartPtr pThread;
+ pProcess->GetThread(te32.th32ThreadID, &pThread);
+ if (pThread != NULL)
+ {
+ // If we fail to get the appdomain for some reason, then then
+ // we can't dispatch this thread callback. But we can still
+ // finish enumerating.
+ RSExtSmartPtr pAppDomain;
+ HRESULT hrGetAppDomain = pThread->GetAppDomain(&pAppDomain);
+ SIMPLIFYING_ASSUMPTION_SUCCEEDED(hrGetAppDomain);
+ if (pAppDomain != NULL)
+ {
+ GetShimCallback()->CreateThread(pAppDomain, pThread);
+ AddDuplicateCreationEvent(pThread);
+
+ //fix for issue DevDiv2\DevDiv 77523 - threads are switched out in SQL don't get thread create notifications
+ // mark that this thread has queued a create event
+ CordbThread* pThreadInternal = static_cast(pThread.GetValue());
+ pThreadInternal->SetCreateEventQueued();
+ }
+ }
+ }
+ } while(Thread32Next(hThreadSnap, &te32));
+
+
+ //fix for issue DevDiv2\DevDiv 77523 - threads are switched out in SQL don't get thread create notifications
+ //
+
+
+ // Threads which were switched out won't be present in the native thread order enumeration above.
+ // In order to not miss them we will enumerate all the managed thread objects and for any that we haven't
+ // already queued a notification for, we will queue a notification now.
+ RSExtSmartPtr pThreadEnum;
+ RSExtSmartPtr pThread;
+ hr = pProcess->EnumerateThreads(&pThreadEnum);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ ULONG cDummy;
+
+ while(SUCCEEDED(pThreadEnum->Next(1, &pThread, &cDummy)) && (pThread != NULL))
+ {
+ RSExtSmartPtr pAppDomain;
+ hr = pThread->GetAppDomain(&pAppDomain);
+ CordbThread* pThreadInternal = static_cast(pThread.GetValue());
+
+ // Getting the appdomain shouldn't fail. If it does, we can't dispatch
+ // this callback, but we can still dispatch the other thread creates.
+ SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr);
+ if (pAppDomain != NULL && !pThreadInternal->CreateEventWasQueued())
+ {
+ GetShimCallback()->CreateThread(pAppDomain, pThread);
+ AddDuplicateCreationEvent(pThread);
+ pThreadInternal->SetCreateEventQueued();
+ }
+ pThread.Clear();
+ }
+
+
+ return S_OK;
+#endif
+}
+
//---------------------------------------------------------------------------------------
// Queues the fake Assembly and Module load events
//
@@ -1337,9 +1476,15 @@ void ShimProcess::QueueFakeAttachEvents()
//
// Third, Queue all Threads
//
+#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) && !defined(FEATURE_CORESYSTEM)
+ // Use OS thread enumeration facilities to ensure that the managed thread
+ // thread order is the same as the corresponding native thread order.
+ QueueFakeThreadAttachEventsNativeOrder();
+#else
// Use ICorDebug to enumerate threads. The order of managed threads may
// not match the order the threads were created in.
QueueFakeThreadAttachEventsNoOrder();
+#endif
// Forth, Queue all Connections.
// Enumerate connections is not exposed through ICorDebug, so we need to go use a private hook on CordbProcess.
@@ -1585,6 +1730,86 @@ void ShimProcess::PreDispatchEvent(bool fRealCreateProcessEvent /*= false*/)
}
+// ----------------------------------------------------------------------------
+// ShimProcess::GetCLRInstanceBaseAddress
+// Finds the base address of [core]clr.dll
+// Arguments: none
+// Return value: returns the base address of [core]clr.dll if possible or NULL otherwise
+//
+CORDB_ADDRESS ShimProcess::GetCLRInstanceBaseAddress()
+{
+ CORDB_ADDRESS baseAddress = CORDB_ADDRESS(NULL);
+ DWORD dwPid = m_pLiveDataTarget->GetPid();
+
+#if defined(FEATURE_CORESYSTEM)
+ // Debugger attaching to CoreCLR via CoreCLRCreateCordbObject should have already specified CLR module address.
+ // Code that help to find it now lives in dbgshim.
+#else
+ // get a "snapshot" of all modules in the target
+ HandleHolder hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPid);
+ MODULEENTRY32 moduleEntry = { 0 };
+
+ if (hSnapshot == INVALID_HANDLE_VALUE)
+ {
+ // we haven't got a loaded CLR yet
+ baseAddress = CORDB_ADDRESS(NULL);
+ }
+ else
+ {
+ // we need to loop through the modules until we find mscorwks.dll
+ moduleEntry.dwSize = sizeof(MODULEENTRY32);
+
+ if (!Module32First(hSnapshot, &moduleEntry))
+ {
+ baseAddress = CORDB_ADDRESS(NULL);
+ }
+ else
+ {
+
+ do
+ {
+ if (!_wcsicmp(moduleEntry.szModule, MAKEDLLNAME_W(MAIN_CLR_MODULE_NAME_W)))
+ {
+ // we found it, so save the base address
+ baseAddress = PTR_TO_CORDB_ADDRESS(moduleEntry.modBaseAddr);
+ }
+ } while (Module32Next(hSnapshot, &moduleEntry));
+ }
+ }
+#endif
+ return baseAddress;
+} // ShimProcess::GetCLRInstanceBaseAddress
+
+// ----------------------------------------------------------------------------
+// ShimProcess::FindLoadedCLR
+//
+// Description:
+// Look for any CLR loaded into the process. If found, return the instance ID for it.
+//
+// Arguments:
+// * pClrInstanceId - out parameter for the instance ID of the CLR
+//
+// Return Value:
+// Returns S_OK if a CLR was found, and stores its instance ID in pClrInstanceId.
+// Otherwise returns an error code.
+//
+// Notes:
+// If there are multiple CLRs loaded in the process, the one chosen for the returned
+// instance ID is unspecified.
+//
+HRESULT ShimProcess::FindLoadedCLR(CORDB_ADDRESS * pClrInstanceId)
+{
+ *pClrInstanceId = GetCLRInstanceBaseAddress();
+
+ if (*pClrInstanceId == 0)
+ {
+ return E_UNEXPECTED;
+ }
+
+ return S_OK;
+}
+
+
//---------------------------------------------------------------------------------------
//
// Locates DAC by finding mscordac{wks|core} next to DBI
diff --git a/src/coreclr/debug/di/windowspipeline.cpp b/src/coreclr/debug/di/windowspipeline.cpp
index 68ac4a216c660..cea89e7387400 100644
--- a/src/coreclr/debug/di/windowspipeline.cpp
+++ b/src/coreclr/debug/di/windowspipeline.cpp
@@ -92,7 +92,14 @@ class WindowsNativePipeline :
// Terminate the debuggee process.
virtual BOOL TerminateProcess(UINT32 exitCode);
+ // Resume any suspended threads
+ virtual HRESULT EnsureThreadsRunning();
+
protected:
+ void UpdateDebugSetProcessKillOnExit();
+
+ HRESULT IsRemoteDebuggerPresent(DWORD processId, BOOL* pfDebuggerPresent);
+
// Cached value from DebugSetProcessKillOnExit.
// This is thread-local, and impacts all debuggees on the thread.
bool m_fKillOnExit;
@@ -118,10 +125,46 @@ BOOL WindowsNativePipeline::DebugSetProcessKillOnExit(bool fKillOnExit)
{
// Can't call kernel32!DebugSetProcessKillOnExit until after the event thread
// has spawned a debuggee. So cache the value now and call it later.
+ // This bit is enforced in code:WindowsNativePipeline::UpdateDebugSetProcessKillOnExit
m_fKillOnExit = fKillOnExit;
return TRUE;
}
+// Enforces the bit set in code:WindowsNativePipeline::DebugSetProcessKillOnExit
+void WindowsNativePipeline::UpdateDebugSetProcessKillOnExit()
+{
+#if !defined(FEATURE_CORESYSTEM)
+ // Late bind to DebugSetProcessKillOnExit - WinXP and above only
+ HModuleHolder hKernel32;
+ hKernel32 = WszLoadLibrary(W("kernel32"));
+ SIMPLIFYING_ASSUMPTION(hKernel32 != NULL);
+ if (hKernel32 == NULL)
+ return;
+
+ typedef BOOL (*DebugSetProcessKillOnExitSig) (BOOL);
+ DebugSetProcessKillOnExitSig pDebugSetProcessKillOnExit =
+ reinterpret_cast(GetProcAddress(hKernel32, "DebugSetProcessKillOnExit"));
+
+ // If the API doesn't exist (eg. Win2k) - there isn't anything we can do, just
+ // silently ignore the request.
+ if (pDebugSetProcessKillOnExit == NULL)
+ return;
+
+ BOOL ret = pDebugSetProcessKillOnExit(m_fKillOnExit);
+
+ // Not a good failure path here.
+ // 1) This shouldn't fail.
+ // 2) Even if it does, this is likely called after the debuggee
+ // has already been created, and if this API fails, most scenarios will
+ // be unaffected, so we don't want to fail the overall debugging session.
+ SIMPLIFYING_ASSUMPTION(ret);
+
+#else
+ // The API doesn't exit on CoreSystem, just return
+ return;
+#endif
+}
+
// Create an process under the debugger.
HRESULT WindowsNativePipeline::CreateProcessUnderDebugger(
MachineInfo machineInfo,
@@ -156,6 +199,7 @@ HRESULT WindowsNativePipeline::CreateProcessUnderDebugger(
}
m_dwProcessId = lpProcessInformation->dwProcessId;
+ UpdateDebugSetProcessKillOnExit();
return S_OK;
}
@@ -169,23 +213,104 @@ HRESULT WindowsNativePipeline::DebugActiveProcess(MachineInfo machineInfo, const
{
hr = S_OK;
m_dwProcessId = processDescriptor.m_Pid;
+ UpdateDebugSetProcessKillOnExit();
}
else
{
hr = HRESULT_FROM_GetLastError();
+
+ // There are at least two scenarios in which DebugActiveProcess() returns E_INVALIDARG:
+ // 1) if the specified process doesn't exist, or
+ // 2) if the specified process already has a debugger atttached
+ // We need to distinguish these two cases in order to return the correct HR.
+ if (hr == E_INVALIDARG)
+ {
+ // Check whether a debugger is known to be already attached.
+ // Note that this API won't work on some OSes, in which case we err on the side of returning E_INVALIDARG
+ // even though a debugger may be attached. Another approach could be to assume that if
+ // OpenProcess succeeded, then DebugActiveProcess must only have failed because a debugger is
+ // attached. But I think it's better to only return the specific error code if we know for sure
+ // the case is true.
+ BOOL fIsDebuggerPresent = FALSE;
+ if (SUCCEEDED(IsRemoteDebuggerPresent(processDescriptor.m_Pid, &fIsDebuggerPresent)))
+ {
+ if (fIsDebuggerPresent)
+ {
+ hr = CORDBG_E_DEBUGGER_ALREADY_ATTACHED;
+ }
+ }
+ }
}
return hr;
}
+// Determine (if possible) whether a debugger is attached to the target process
+HRESULT WindowsNativePipeline::IsRemoteDebuggerPresent(DWORD processId, BOOL* pfDebuggerPresent)
+{
+#if !defined(FEATURE_CORESYSTEM)
+
+ // Get a process handle for the process ID.
+ HandleHolder hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId);
+ if (hProc == NULL)
+ return HRESULT_FROM_GetLastError();
+
+ // Delay-bind to CheckRemoteDebuggerPresent - WinXP SP1 and above only
+ HModuleHolder hKernel32;
+ hKernel32 = WszLoadLibrary(W("kernel32"));
+ if (hKernel32 == NULL)
+ return HRESULT_FROM_GetLastError();
+
+ typedef BOOL (*CheckRemoteDebuggerPresentSig) (HANDLE, PBOOL);
+ CheckRemoteDebuggerPresentSig pCheckRemoteDebuggerPresent =
+ reinterpret_cast(GetProcAddress(hKernel32, "CheckRemoteDebuggerPresent"));
+ if (pCheckRemoteDebuggerPresent == NULL)
+ return HRESULT_FROM_GetLastError();
+
+ // API exists - call it
+ if (!pCheckRemoteDebuggerPresent(hProc, pfDebuggerPresent))
+ return HRESULT_FROM_GetLastError();
+
+ return S_OK;
+#else
+
+ //CoreSystem doesn't have this API
+ return E_FAIL;
+#endif
+}
+
// Detach
HRESULT WindowsNativePipeline::DebugActiveProcessStop(DWORD processId)
{
+#if !defined(FEATURE_CORESYSTEM)
+ // Late-bind to DebugActiveProcessStop since it's WinXP and above only
+ HModuleHolder hKernel32;
+ hKernel32 = WszLoadLibrary(W("kernel32"));
+ if (hKernel32 == NULL)
+ return HRESULT_FROM_GetLastError();
+
+ typedef BOOL (*DebugActiveProcessStopSig) (DWORD);
+ DebugActiveProcessStopSig pDebugActiveProcessStop =
+ reinterpret_cast(GetProcAddress(hKernel32, "DebugActiveProcessStop"));
+
+ // Win2K will fail here - can't find DebugActiveProcessStop
+ if (pDebugActiveProcessStop == NULL)
+ return HRESULT_FROM_GetLastError();
+
+ // Ok, the API exists, call it
+ if (!pDebugActiveProcessStop(processId))
+ {
+ // Detach itself failed
+ return HRESULT_FROM_GetLastError();
+ }
+#else
+ // The API exists, call it
if (!::DebugActiveProcessStop(processId))
{
// Detach itself failed
return HRESULT_FROM_GetLastError();
}
+#endif
return S_OK;
}
@@ -234,3 +359,60 @@ BOOL WindowsNativePipeline::TerminateProcess(UINT32 exitCode)
return ::TerminateProcess(hProc, exitCode);
}
+
+// Resume any suspended threads (but just once)
+HRESULT WindowsNativePipeline::EnsureThreadsRunning()
+{
+#ifdef FEATURE_CORESYSTEM
+ _ASSERTE("NYI");
+ return E_FAIL;
+#else
+ _ASSERTE(m_dwProcessId != 0);
+
+ // Take a snapshot of all running threads (similar to ShimProcess::QueueFakeThreadAttachEventsNativeOrder)
+ // Alternately we could return thread creation/exit in WaitForDebugEvent. But we expect this to be used
+ // very rarely, so no need to complicate more common codepaths.
+ HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
+ THREADENTRY32 te32;
+
+ hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+ if (hThreadSnap == INVALID_HANDLE_VALUE)
+ return HRESULT_FROM_GetLastError();
+
+ // HandleHolder doesn't deal with INVALID_HANDLE_VALUE, so we only assign if we have a legal value.
+ HandleHolder hSnapshotHolder(hThreadSnap);
+
+ // Fill in the size of the structure before using it.
+ te32.dwSize = sizeof(THREADENTRY32);
+
+ // Retrieve information about the first thread, and exit if unsuccessful
+ if (!Thread32First(hThreadSnap, &te32))
+ return HRESULT_FROM_GetLastError();
+
+ // Now walk the thread list of the system and attempt to resume any that are part of this process
+ // Ignore errors - this is a best effort (but ASSERT in CHK builds since we don't expect errors
+ // in practice - we expect the process to be frozen at a debug event, so no races etc.)
+
+ HRESULT hr = S_FALSE; // no thread was resumed
+ do
+ {
+ if (te32.th32OwnerProcessID == m_dwProcessId)
+ {
+ HandleHolder hThread = ::OpenThread(THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID);
+ _ASSERTE(hThread != NULL);
+ if (hThread != NULL)
+ {
+ // Resume each thread exactly once (if they were suspended multiple times,
+ // then EnsureThreadsRunning would need to be called multiple times until it
+ // returned S_FALSE.
+ DWORD prevCount = ::ResumeThread(hThread);
+ _ASSERTE(prevCount >= 0);
+ if (prevCount >= 1)
+ hr = S_OK; // some thread was resumed
+ }
+ }
+ } while(Thread32Next(hThreadSnap, &te32));
+
+ return hr;
+#endif
+}
diff --git a/src/coreclr/debug/ee/debugger.cpp b/src/coreclr/debug/ee/debugger.cpp
index bd96c50fc59d3..1e326e724250b 100644
--- a/src/coreclr/debug/ee/debugger.cpp
+++ b/src/coreclr/debug/ee/debugger.cpp
@@ -1347,7 +1347,7 @@ DebuggerEval::DebuggerEval(CONTEXT * pContext, DebuggerIPCE_FuncEvalInfo * pEval
// could get unloaded between now and when the funceval actually starts. So we stash an
// AppDomain ID which is safe to use after the AD is unloaded. It's only safe to
// use the DebuggerModule* after we've verified the ADID is still valid (i.e. by entering that domain).
- m_debuggerModule = g_pDebugger->LookupOrCreateModule(pEvalInfo->vmDomainAssembly);
+ m_debuggerModule = g_pDebugger->LookupOrCreateModule(pEvalInfo->vmDomainFile);
m_funcEvalKey = pEvalInfo->funcEvalKey;
m_argCount = pEvalInfo->argCount;
m_targetCodeAddr = NULL;
@@ -5187,10 +5187,10 @@ void Debugger::SendSyncCompleteIPCEvent(bool isEESuspendedForGC)
}
//
-// Lookup or create a DebuggerModule for the given pDomainAssembly.
+// Lookup or create a DebuggerModule for the given pDomainFile.
//
// Arguments:
-// pDomainAssembly - non-null domain file.
+// pDomainFile - non-null domain file.
//
// Returns:
// DebuggerModule instance for the given domain file. May be lazily created.
@@ -5199,36 +5199,36 @@ void Debugger::SendSyncCompleteIPCEvent(bool isEESuspendedForGC)
// @dbgtodo JMC - this should go away when we get rid of DebuggerModule.
//
-DebuggerModule * Debugger::LookupOrCreateModule(DomainAssembly * pDomainAssembly)
+DebuggerModule * Debugger::LookupOrCreateModule(DomainFile * pDomainFile)
{
- _ASSERTE(pDomainAssembly != NULL);
- LOG((LF_CORDB, LL_INFO1000, "D::LOCM df=0x%x\n", pDomainAssembly));
- DebuggerModule * pDModule = LookupOrCreateModule(pDomainAssembly->GetModule(), pDomainAssembly->GetAppDomain());
- LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=0x%x ad=0x%x -> dm=0x%x\n", pDomainAssembly->GetModule(), pDomainAssembly->GetAppDomain(), pDModule));
+ _ASSERTE(pDomainFile != NULL);
+ LOG((LF_CORDB, LL_INFO1000, "D::LOCM df=0x%x\n", pDomainFile));
+ DebuggerModule * pDModule = LookupOrCreateModule(pDomainFile->GetModule(), pDomainFile->GetAppDomain());
+ LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=0x%x ad=0x%x -> dm=0x%x\n", pDomainFile->GetModule(), pDomainFile->GetAppDomain(), pDModule));
_ASSERTE(pDModule != NULL);
- _ASSERTE(pDModule->GetDomainAssembly() == pDomainAssembly);
+ _ASSERTE(pDModule->GetDomainFile() == pDomainFile);
return pDModule;
}
-// Overloaded Wrapper around for VMPTR_DomainAssembly-->DomainAssembly*
+// Overloaded Wrapper around for VMPTR_DomainFile-->DomainFile*
//
// Arguments:
-// vmDomainAssembly - VMPTR cookie for a domain file. This can be NullPtr().
+// vmDomainFile - VMPTR cookie for a domain file. This can be NullPtr().
//
// Returns:
// Debugger Module instance for the given domain file. May be lazily created.
//
// Notes:
// VMPTR comes from IPC events
-DebuggerModule * Debugger::LookupOrCreateModule(VMPTR_DomainAssembly vmDomainAssembly)
+DebuggerModule * Debugger::LookupOrCreateModule(VMPTR_DomainFile vmDomainFile)
{
- DomainAssembly * pDomainAssembly = vmDomainAssembly.GetRawPtr();
- if (pDomainAssembly == NULL)
+ DomainFile * pDomainFile = vmDomainFile.GetRawPtr();
+ if (pDomainFile == NULL)
{
return NULL;
}
- return LookupOrCreateModule(pDomainAssembly);
+ return LookupOrCreateModule(pDomainFile);
}
// Lookup or create a DebuggerModule for the given (Module, AppDomain) pair.
@@ -5281,9 +5281,9 @@ DebuggerModule* Debugger::LookupOrCreateModule(Module* pModule, AppDomain *pAppD
HRESULT hr = S_OK;
EX_TRY
{
- DomainAssembly * pDomainAssembly = pModule->GetDomainAssembly();
- SIMPLIFYING_ASSUMPTION(pDomainAssembly != NULL);
- dmod = AddDebuggerModule(pDomainAssembly); // throws
+ DomainFile * pDomainFile = pModule->GetDomainFile();
+ SIMPLIFYING_ASSUMPTION(pDomainFile != NULL);
+ dmod = AddDebuggerModule(pDomainFile); // throws
}
EX_CATCH_HRESULT(hr);
SIMPLIFYING_ASSUMPTION(dmod != NULL); // may not be true in OOM cases; but LS doesn't handle OOM.
@@ -5293,19 +5293,19 @@ DebuggerModule* Debugger::LookupOrCreateModule(Module* pModule, AppDomain *pAppD
_ASSERTE( (dmod == NULL) || (dmod->GetAppDomain() == pAppDomain) );
LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=0x%x ad=0x%x -> dm=0x%x(Mod=0x%x, DomFile=0x%x, AD=0x%x)\n",
- pModule, pAppDomain, dmod, dmod->GetRuntimeModule(), dmod->GetDomainAssembly(), dmod->GetAppDomain()));
+ pModule, pAppDomain, dmod, dmod->GetRuntimeModule(), dmod->GetDomainFile(), dmod->GetAppDomain()));
return dmod;
}
// Create a new DebuggerModule object
//
// Arguments:
-// pDomainAssembly- runtime domain file to create debugger module object around
+// pDomainFile- runtime domain file to create debugger module object around
//
// Returns:
// New instnace of a DebuggerModule. Throws on failure.
//
-DebuggerModule* Debugger::AddDebuggerModule(DomainAssembly * pDomainAssembly)
+DebuggerModule* Debugger::AddDebuggerModule(DomainFile * pDomainFile)
{
CONTRACTL
{
@@ -5314,16 +5314,16 @@ DebuggerModule* Debugger::AddDebuggerModule(DomainAssembly * pDomainAssembly)
}
CONTRACTL_END;
- LOG((LF_CORDB, LL_INFO1000, "D::ADM df=0x%x\n", pDomainAssembly));
+ LOG((LF_CORDB, LL_INFO1000, "D::ADM df=0x%x\n", pDomainFile));
DebuggerDataLockHolder chInfo(this);
- Module * pRuntimeModule = pDomainAssembly->GetModule();
- AppDomain * pAppDomain = pDomainAssembly->GetAppDomain();
+ Module * pRuntimeModule = pDomainFile->GetCurrentModule();
+ AppDomain * pAppDomain = pDomainFile->GetAppDomain();
HRESULT hr = CheckInitModuleTable();
IfFailThrow(hr);
- DebuggerModule* pModule = new (interopsafe) DebuggerModule(pRuntimeModule, pDomainAssembly, pAppDomain);
+ DebuggerModule* pModule = new (interopsafe) DebuggerModule(pRuntimeModule, pDomainFile, pAppDomain);
_ASSERTE(pModule != NULL); // throws on oom
TRACE_ALLOC(pModule);
@@ -5332,7 +5332,7 @@ DebuggerModule* Debugger::AddDebuggerModule(DomainAssembly * pDomainAssembly)
// @dbgtodo inspection/exceptions - this may leak module in OOM case. LS is not OOM resilient; and we
// expect to get rid of DebuggerModule anyways.
- LOG((LF_CORDB, LL_INFO1000, "D::ADM df=0x%x -> dm=0x%x\n", pDomainAssembly, pModule));
+ LOG((LF_CORDB, LL_INFO1000, "D::ADM df=0x%x -> dm=0x%x\n", pDomainFile, pModule));
return pModule;
}
@@ -6246,7 +6246,7 @@ void Debugger::LockAndSendEnCRemapEvent(DebuggerJitInfo * dji, SIZE_T currentIP,
Module *pRuntimeModule = pFD->GetModule();
DebuggerModule * pDModule = LookupOrCreateModule(pRuntimeModule, thread->GetDomain());
- ipce->EnCRemap.vmDomainAssembly.SetRawPtr((pDModule ? pDModule->GetDomainAssembly() : NULL));
+ ipce->EnCRemap.vmDomainFile.SetRawPtr((pDModule ? pDModule->GetDomainFile() : NULL));
LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRE: %s::%s "
"dmod:0x%x, methodDef:0x%x \n",
@@ -6315,7 +6315,7 @@ void Debugger::LockAndSendEnCRemapCompleteEvent(MethodDesc *pFD)
Module *pRuntimeModule = pFD->GetModule();
DebuggerModule * pDModule = LookupOrCreateModule(pRuntimeModule, thread->GetDomain());
- ipce->EnCRemapComplete.vmDomainAssembly.SetRawPtr((pDModule ? pDModule->GetDomainAssembly() : NULL));
+ ipce->EnCRemapComplete.vmDomainFile.SetRawPtr((pDModule ? pDModule->GetDomainFile() : NULL));
LOG((LF_CORDB, LL_INFO10000, "D::LASEnCRC: %s::%s "
@@ -6381,7 +6381,7 @@ void Debugger::SendEnCUpdateEvent(DebuggerIPCEventType eventType,
_ASSERTE(pModule->GetDomain()->IsAppDomain());
DebuggerModule * pDModule = LookupOrCreateModule(pModule, pModule->GetDomain()->AsAppDomain());
- event->EnCUpdate.vmDomainAssembly.SetRawPtr((pDModule ? pDModule->GetDomainAssembly() : NULL));
+ event->EnCUpdate.vmDomainFile.SetRawPtr((pDModule ? pDModule->GetDomainFile() : NULL));
m_pRCThread->SendIPCEvent();
@@ -9426,7 +9426,7 @@ void Debugger::LoadModule(Module* pRuntimeModule,
DWORD dwModuleName, // length of pszModuleName in chars, not including null.
Assembly *pAssembly,
AppDomain *pAppDomain,
- DomainAssembly * pDomainAssembly,
+ DomainFile * pDomainFile,
BOOL fAttaching)
{
@@ -9461,13 +9461,13 @@ void Debugger::LoadModule(Module* pRuntimeModule,
{
// The loader lookups may throw or togggle GC mode, so do them inside a TRY/Catch and
// outside any debugger locks.
- Module * pManifestModule = pRuntimeModule->GetAssembly()->GetModule();
+ Module * pManifestModule = pRuntimeModule->GetAssembly()->GetManifestModule();
_ASSERTE(pManifestModule != pRuntimeModule);
_ASSERTE(pManifestModule->IsManifest());
_ASSERTE(pManifestModule->GetAssembly() == pRuntimeModule->GetAssembly());
- DomainAssembly * pManifestDomainAssembly = pManifestModule->GetDomainAssembly();
+ DomainFile * pManifestDomainFile = pManifestModule->GetDomainFile();
DebuggerLockHolder dbgLockHolder(this);
@@ -9477,7 +9477,7 @@ void Debugger::LoadModule(Module* pRuntimeModule,
DebuggerIPCEvent eventMetadataUpdate;
InitIPCEvent(&eventMetadataUpdate, DB_IPCE_METADATA_UPDATE, NULL, pAppDomain);
- eventMetadataUpdate.MetadataUpdateData.vmDomainAssembly.SetRawPtr(pManifestDomainAssembly);
+ eventMetadataUpdate.MetadataUpdateData.vmDomainFile.SetRawPtr(pManifestDomainFile);
SendRawEvent(&eventMetadataUpdate);
}
@@ -9499,7 +9499,7 @@ void Debugger::LoadModule(Module* pRuntimeModule,
// The RS has logic to ignore duplicate ModuleLoad events. We have to send what could possibly be a dup, though,
// due to some really nasty issues with getting proper assembly and module load events from the loader when dealing
// with shared assemblies.
- module = LookupOrCreateModule(pDomainAssembly);
+ module = LookupOrCreateModule(pDomainFile);
_ASSERTE(module != NULL);
@@ -9509,18 +9509,18 @@ void Debugger::LoadModule(Module* pRuntimeModule,
module->SetCanChangeJitFlags(true);
- // @dbgtodo inspection - Check whether the DomainAssembly we get is consistent with the Module and AppDomain we get.
+ // @dbgtodo inspection - Check whether the DomainFile we get is consistent with the Module and AppDomain we get.
// We should simply things when we actually get rid of DebuggerModule, possibly by just passing the
- // DomainAssembly around.
- _ASSERTE(module->GetDomainAssembly() == pDomainAssembly);
- _ASSERTE(module->GetAppDomain() == pDomainAssembly->GetAppDomain());
- _ASSERTE(module->GetRuntimeModule() == pDomainAssembly->GetModule());
+ // DomainFile around.
+ _ASSERTE(module->GetDomainFile() == pDomainFile);
+ _ASSERTE(module->GetAppDomain() == pDomainFile->GetAppDomain());
+ _ASSERTE(module->GetRuntimeModule() == pDomainFile->GetModule());
// Send a load module event to the Right Side.
ipce = m_pRCThread->GetIPCEventSendBuffer();
InitIPCEvent(ipce,DB_IPCE_LOAD_MODULE, pThread, pAppDomain);
- ipce->LoadModuleData.vmDomainAssembly.SetRawPtr(pDomainAssembly);
+ ipce->LoadModuleData.vmDomainFile.SetRawPtr(pDomainFile);
m_pRCThread->SendIPCEvent();
@@ -9588,7 +9588,7 @@ void Debugger::SendRawUpdateModuleSymsEvent(Module *pRuntimeModule, AppDomain *p
g_pEEInterface->GetThread(),
pAppDomain);
- ipce->UpdateModuleSymsData.vmDomainAssembly.SetRawPtr((module ? module->GetDomainAssembly() : NULL));
+ ipce->UpdateModuleSymsData.vmDomainFile.SetRawPtr((module ? module->GetDomainFile() : NULL));
m_pRCThread->SendIPCEvent();
}
@@ -9695,8 +9695,8 @@ void Debugger::UnloadModule(Module* pRuntimeModule,
STRESS_LOG6(LF_CORDB, LL_INFO10000,
"D::UM: Unloading RTMod:%#08x (DomFile: %#08x, IsISStream:%#08x); DMod:%#08x(RTMod:%#08x DomFile: %#08x)\n",
- pRuntimeModule, pRuntimeModule->GetDomainAssembly(), false,
- module, module->GetRuntimeModule(), module->GetDomainAssembly());
+ pRuntimeModule, pRuntimeModule->GetDomainFile(), false,
+ module, module->GetRuntimeModule(), module->GetDomainFile());
// Note: the appdomain the module was loaded in must match the appdomain we're unloading it from. If it doesn't,
// then we've either found the wrong DebuggerModule in LookupModule or we were passed bad data.
@@ -9705,7 +9705,7 @@ void Debugger::UnloadModule(Module* pRuntimeModule,
// Send the unload module event to the Right Side.
DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
InitIPCEvent(ipce, DB_IPCE_UNLOAD_MODULE, thread, pAppDomain);
- ipce->UnloadModuleData.vmDomainAssembly.SetRawPtr((module ? module->GetDomainAssembly() : NULL));
+ ipce->UnloadModuleData.vmDomainFile.SetRawPtr((module ? module->GetDomainFile() : NULL));
ipce->UnloadModuleData.debuggerAssemblyToken.Set(pRuntimeModule->GetClassLoader()->GetAssembly());
m_pRCThread->SendIPCEvent();
@@ -9877,7 +9877,7 @@ void Debugger::SendClassLoadUnloadEvent (mdTypeDef classMetadataToken,
InitIPCEvent(pEvent, DB_IPCE_LOAD_CLASS, g_pEEInterface->GetThread(), pAppDomain);
pEvent->LoadClass.classMetadataToken = classMetadataToken;
- pEvent->LoadClass.vmDomainAssembly.SetRawPtr((pClassDebuggerModule ? pClassDebuggerModule->GetDomainAssembly() : NULL));
+ pEvent->LoadClass.vmDomainFile.SetRawPtr((pClassDebuggerModule ? pClassDebuggerModule->GetDomainFile() : NULL));
pEvent->LoadClass.classDebuggerAssemblyToken.Set(pAssembly);
@@ -9889,7 +9889,7 @@ void Debugger::SendClassLoadUnloadEvent (mdTypeDef classMetadataToken,
InitIPCEvent(pEvent, DB_IPCE_UNLOAD_CLASS, g_pEEInterface->GetThread(), pAppDomain);
pEvent->UnloadClass.classMetadataToken = classMetadataToken;
- pEvent->UnloadClass.vmDomainAssembly.SetRawPtr((pClassDebuggerModule ? pClassDebuggerModule->GetDomainAssembly() : NULL));
+ pEvent->UnloadClass.vmDomainFile.SetRawPtr((pClassDebuggerModule ? pClassDebuggerModule->GetDomainFile() : NULL));
pEvent->UnloadClass.classDebuggerAssemblyToken.Set(pAssembly);
}
@@ -9940,10 +9940,10 @@ BOOL Debugger::SendSystemClassLoadUnloadEvent(mdTypeDef classMetadataToken,
// Only notify for app domains where the module has been fully loaded already
// We used to make a different check here domain->ContainsAssembly() but that
- // triggers too early in the loading process. FindDomainAssembly will not become
+ // triggers too early in the loading process. FindDomainFile will not become
// non-NULL until the module is fully loaded into the domain which is what we
// want.
- if (classModule->GetDomainAssembly() != NULL )
+ if (classModule->GetDomainFile() != NULL )
{
// Find the Left Side module that this class belongs in.
DebuggerModule* pModule = LookupOrCreateModule(classModule, pAppDomain);
@@ -10528,7 +10528,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent)
_ASSERTE(hr == S_OK);
DebuggerBreakpoint * pDebuggerBP = NULL;
- DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->BreakpointData.vmDomainAssembly);
+ DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->BreakpointData.vmDomainFile);
Module * pModule = pDebuggerModule->GetRuntimeModule();
DebuggerMethodInfo * pDMI = GetOrCreateMethodInfo(pModule, pEvent->BreakpointData.funcMetadataToken);
MethodDesc * pMethodDesc = pEvent->BreakpointData.nativeCodeMethodDescToken.UnWrap();
@@ -10847,7 +10847,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent)
{
LOG((LF_ENC, LL_INFO100, "D::HIPCE: DB_IPCE_APPLY_CHANGES 1\n"));
- DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->ApplyChanges.vmDomainAssembly);
+ DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->ApplyChanges.vmDomainFile);
//
// @todo handle error.
//
@@ -10864,7 +10864,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent)
case DB_IPCE_SET_CLASS_LOAD_FLAG:
{
- DebuggerModule *pDebuggerModule = LookupOrCreateModule(pEvent->SetClassLoad.vmDomainAssembly);
+ DebuggerModule *pDebuggerModule = LookupOrCreateModule(pEvent->SetClassLoad.vmDomainFile);
_ASSERTE(pDebuggerModule != NULL);
@@ -10914,7 +10914,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent)
// unexpected in an OOM situation. Quickly just sanity check them.
//
Thread * pThread = pEvent->SetIP.vmThreadToken.GetRawPtr();
- Module * pModule = pEvent->SetIP.vmDomainAssembly.GetRawPtr()->GetModule();
+ Module * pModule = pEvent->SetIP.vmDomainFile.GetRawPtr()->GetModule();
// Get the DJI for this function
DebuggerMethodInfo * pDMI = GetOrCreateMethodInfo(pModule, pEvent->SetIP.mdMethod);
@@ -11244,7 +11244,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent)
case DB_IPCE_SET_METHOD_JMC_STATUS:
{
// Get the info out of the event
- DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmDomainAssembly);
+ DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmDomainFile);
Module * pModule = pDebuggerModule->GetRuntimeModule();
bool fStatus = (pEvent->SetJMCFunctionStatus.dwStatus != 0);
@@ -11292,7 +11292,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent)
case DB_IPCE_GET_METHOD_JMC_STATUS:
{
// Get the method
- DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmDomainAssembly);
+ DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmDomainFile);
Module * pModule = pDebuggerModule->GetRuntimeModule();
@@ -11326,7 +11326,7 @@ bool Debugger::HandleIPCEvent(DebuggerIPCEvent * pEvent)
case DB_IPCE_SET_MODULE_JMC_STATUS:
{
// Get data out of event
- DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmDomainAssembly);
+ DebuggerModule * pDebuggerModule = LookupOrCreateModule(pEvent->SetJMCFunctionStatus.vmDomainFile);
bool fStatus = (pEvent->SetJMCFunctionStatus.dwStatus != 0);
@@ -11818,7 +11818,7 @@ void Debugger::TypeHandleToBasicTypeInfo(AppDomain *pAppDomain, TypeHandle th, D
case ELEMENT_TYPE_BYREF:
res->vmTypeHandle = WrapTypeHandle(th);
res->metadataToken = mdTokenNil;
- res->vmDomainAssembly.SetRawPtr(NULL);
+ res->vmDomainFile.SetRawPtr(NULL);
break;
case ELEMENT_TYPE_CLASS:
@@ -11828,14 +11828,14 @@ void Debugger::TypeHandleToBasicTypeInfo(AppDomain *pAppDomain, TypeHandle th, D
// only set if instantiated
res->metadataToken = th.GetCl();
DebuggerModule * pDModule = LookupOrCreateModule(th.GetModule(), pAppDomain);
- res->vmDomainAssembly.SetRawPtr((pDModule ? pDModule->GetDomainAssembly() : NULL));
+ res->vmDomainFile.SetRawPtr((pDModule ? pDModule->GetDomainFile() : NULL));
break;
}
default:
res->vmTypeHandle = VMPTR_TypeHandle::NullPtr();
res->metadataToken = mdTokenNil;
- res->vmDomainAssembly.SetRawPtr(NULL);
+ res->vmDomainFile.SetRawPtr(NULL);
break;
}
return;
@@ -11907,8 +11907,8 @@ void Debugger::TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed,
res->ClassTypeData.typeHandle = th.HasInstantiation() ? WrapTypeHandle(th) : VMPTR_TypeHandle::NullPtr(); // only set if instantiated
res->ClassTypeData.metadataToken = th.GetCl();
DebuggerModule * pModule = LookupOrCreateModule(th.GetModule(), pAppDomain);
- res->ClassTypeData.vmDomainAssembly.SetRawPtr((pModule ? pModule->GetDomainAssembly() : NULL));
- _ASSERTE(!res->ClassTypeData.vmDomainAssembly.IsNull());
+ res->ClassTypeData.vmDomainFile.SetRawPtr((pModule ? pModule->GetDomainFile() : NULL));
+ _ASSERTE(!res->ClassTypeData.vmDomainFile.IsNull());
break;
}
@@ -11968,7 +11968,7 @@ HRESULT Debugger::BasicTypeInfoToTypeHandle(DebuggerIPCE_BasicTypeData *data, Ty
}
else
{
- DebuggerModule *pDebuggerModule = g_pDebugger->LookupOrCreateModule(data->vmDomainAssembly);
+ DebuggerModule *pDebuggerModule = g_pDebugger->LookupOrCreateModule(data->vmDomainFile);
th = g_pEEInterface->FindLoadedClass(pDebuggerModule->GetRuntimeModule(), data->metadataToken);
if (th.IsNull())
@@ -12070,7 +12070,7 @@ TypeHandle Debugger::TypeDataWalk::ReadTypeHandle()
case ELEMENT_TYPE_CLASS:
case ELEMENT_TYPE_VALUETYPE:
{
- DebuggerModule *pDebuggerModule = g_pDebugger->LookupOrCreateModule(data->data.ClassTypeData.vmDomainAssembly);
+ DebuggerModule *pDebuggerModule = g_pDebugger->LookupOrCreateModule(data->data.ClassTypeData.vmDomainFile);
th = ReadInstantiation(pDebuggerModule->GetRuntimeModule(), data->data.ClassTypeData.metadataToken, data->numTypeArgs);
break;
}
@@ -14403,7 +14403,7 @@ void Debugger::SendLogSwitchSetting(int iLevel,
// pDomain - domain file for the domain in which the notification occurred
// classToken - metadata token for the type of the notification object
void Debugger::SendCustomDebuggerNotification(Thread * pThread,
- DomainAssembly * pDomain,
+ DomainFile * pDomain,
mdTypeDef classToken)
{
CONTRACTL
@@ -14434,10 +14434,10 @@ void Debugger::SendCustomDebuggerNotification(Thread * pThread,
curThread,
curThread->GetDomain());
- VMPTR_DomainAssembly vmDomainAssembly = VMPTR_DomainAssembly::MakePtr(pDomain);
+ VMPTR_DomainFile vmDomainFile = VMPTR_DomainFile::MakePtr(pDomain);
ipce->CustomNotification.classToken = classToken;
- ipce->CustomNotification.vmDomainAssembly = vmDomainAssembly;
+ ipce->CustomNotification.vmDomainFile = vmDomainFile;
m_pRCThread->SendIPCEvent();
@@ -14725,6 +14725,16 @@ HRESULT Debugger::IterateAppDomainsForPdbs()
if (!pDomainAssembly->IsVisibleToDebugger())
continue;
+ DomainAssembly::ModuleIterator j = pDomainAssembly->IterateModules(kModIterIncludeLoading);
+ while (j.Next())
+ {
+ DomainFile * pDomainFile = j.GetDomainFile();
+ if (!pDomainFile->ShouldNotifyDebugger())
+ continue;
+
+ Module* pRuntimeModule = pDomainFile->GetModule();
+ CopyModulePdb(pRuntimeModule);
+ }
if (pDomainAssembly->ShouldNotifyDebugger())
{
CopyModulePdb(pDomainAssembly->GetModule());
diff --git a/src/coreclr/debug/ee/debugger.h b/src/coreclr/debug/ee/debugger.h
index 9703354ec4235..084f1da6a5c93 100644
--- a/src/coreclr/debug/ee/debugger.h
+++ b/src/coreclr/debug/ee/debugger.h
@@ -472,7 +472,7 @@ typedef DPTR(class DebuggerModule) PTR_DebuggerModule;
class DebuggerModule
{
public:
- DebuggerModule(Module * pRuntimeModule, DomainAssembly * pDomainAssembly, AppDomain * pAppDomain);
+ DebuggerModule(Module * pRuntimeModule, DomainFile * pDomainFile, AppDomain * pAppDomain);
// Do we have any optimized code in the module?
// JMC-probes aren't emitted in optimized code,
@@ -504,16 +504,16 @@ class DebuggerModule
// If the Runtime module is shared, then this gives a common DM.
// If the runtime module is not shared, then this is an identity function.
//
- // The runtime has the notion of "DomainAssembly", which is 1:1 with DebuggerModule
+ // The runtime has the notion of "DomainFile", which is 1:1 with DebuggerModule
// and thus 1:1 with CordbModule. The CordbModule hash table on the RS now uses
- // the DomainAssembly as the key instead of DebuggerModule. This is a temporary
+ // the DomainFile as the key instead of DebuggerModule. This is a temporary
// workaround to facilitate the removal of DebuggerModule.
//
DebuggerModule * GetPrimaryModule();
- DomainAssembly * GetDomainAssembly()
+ DomainFile * GetDomainFile()
{
LIMITED_METHOD_DAC_CONTRACT;
- return m_pRuntimeDomainAssembly;
+ return m_pRuntimeDomainFile;
}
// Called by DebuggerModuleTable to set our primary module
@@ -528,7 +528,7 @@ class DebuggerModule
DebuggerModule* m_pPrimaryModule;
PTR_Module m_pRuntimeModule;
- PTR_DomainAssembly m_pRuntimeDomainAssembly;
+ PTR_DomainFile m_pRuntimeDomainFile;
AppDomain* m_pAppDomain;
@@ -1893,9 +1893,9 @@ class Debugger : public DebugInterface
DWORD dwModuleName,
Assembly *pAssembly,
AppDomain *pAppDomain,
- DomainAssembly * pDomainAssembly,
+ DomainFile * pDomainFile,
BOOL fAttaching);
- DebuggerModule * AddDebuggerModule(DomainAssembly * pDomainAssembly);
+ DebuggerModule * AddDebuggerModule(DomainFile * pDomainFile);
void UnloadModule(Module* pRuntimeModule,
@@ -2068,8 +2068,8 @@ class Debugger : public DebugInterface
bool HandleIPCEvent(DebuggerIPCEvent* event);
- DebuggerModule * LookupOrCreateModule(VMPTR_DomainAssembly vmDomainAssembly);
- DebuggerModule * LookupOrCreateModule(DomainAssembly * pDomainAssembly);
+ DebuggerModule * LookupOrCreateModule(VMPTR_DomainFile vmDomainFile);
+ DebuggerModule * LookupOrCreateModule(DomainFile * pDomainFile);
DebuggerModule * LookupOrCreateModule(Module * pModule, AppDomain * pAppDomain);
HRESULT GetAndSendInterceptCommand(DebuggerIPCEvent *event);
@@ -2437,7 +2437,7 @@ class Debugger : public DebugInterface
}
// send a custom debugger notification to the RS
- void SendCustomDebuggerNotification(Thread * pThread, DomainAssembly * pDomain, mdTypeDef classToken);
+ void SendCustomDebuggerNotification(Thread * pThread, DomainFile * pDomain, mdTypeDef classToken);
// Send an MDA notification. This ultimately translates to an ICorDebugMDA object on the Right-Side.
void SendMDANotification(
diff --git a/src/coreclr/debug/ee/debugger.inl b/src/coreclr/debug/ee/debugger.inl
index be4e3f67c4daf..0eba7edccf87d 100644
--- a/src/coreclr/debug/ee/debugger.inl
+++ b/src/coreclr/debug/ee/debugger.inl
@@ -52,16 +52,16 @@ inline DebuggerModuleTable * Debugger::GetModuleTable()
// @dbgtodo inspection - get rid of this entire class as we move things out-of-proc.
//-----------------------------------------------------------------------------
inline DebuggerModule::DebuggerModule(Module * pRuntimeModule,
- DomainAssembly * pDomainAssembly,
+ DomainFile * pDomainFile,
AppDomain * pAppDomain) :
m_enableClassLoadCallbacks(FALSE),
m_pPrimaryModule(NULL),
m_pRuntimeModule(pRuntimeModule),
- m_pRuntimeDomainAssembly(pDomainAssembly),
+ m_pRuntimeDomainFile(pDomainFile),
m_pAppDomain(pAppDomain)
{
LOG((LF_CORDB,LL_INFO10000, "DM::DM this:0x%x Module:0x%x DF:0x%x AD:0x%x\n",
- this, pRuntimeModule, pDomainAssembly, pAppDomain));
+ this, pRuntimeModule, pDomainFile, pAppDomain));
// Pick a primary module.
// Arguably, this could be in DebuggerModuleTable::AddModule
diff --git a/src/coreclr/debug/ee/debuggermodule.cpp b/src/coreclr/debug/ee/debuggermodule.cpp
index 633567f0dd85f..fb6fa53652fbe 100644
--- a/src/coreclr/debug/ee/debuggermodule.cpp
+++ b/src/coreclr/debug/ee/debuggermodule.cpp
@@ -253,7 +253,7 @@ void DebuggerModuleTable::RemoveModule(Module* pModule, AppDomain *pAppDomain)
if ((pRuntimeModule == pModule) && (pDM->GetAppDomain() == pAppDomain))
{
LOG((LF_CORDB, LL_INFO1000, "DMT::RM Removing DebuggerMod:0x%x - Module:0x%x DF:0x%x AD:0x%x\n",
- pDM, pModule, pDM->GetDomainAssembly(), pAppDomain));
+ pDM, pModule, pDM->GetDomainFile(), pAppDomain));
TRACE_FREE(pDM);
DeleteInteropSafe(pDM);
Delete(HASH(pRuntimeModule), (HASHENTRY *) pDME);
diff --git a/src/coreclr/debug/ee/rcthread.cpp b/src/coreclr/debug/ee/rcthread.cpp
index 961b06c879f95..0f48eb2c95e18 100644
--- a/src/coreclr/debug/ee/rcthread.cpp
+++ b/src/coreclr/debug/ee/rcthread.cpp
@@ -513,6 +513,19 @@ HRESULT DebuggerRCThread::SetupRuntimeOffsets(DebuggerIPCControlBlock * pDebugge
pDebuggerRuntimeOffsets->m_excepNotForRuntimeBPAddr = (void*) ExceptionNotForRuntimeFlare;
pDebuggerRuntimeOffsets->m_notifyRSOfSyncCompleteBPAddr = (void*) NotifyRightSideOfSyncCompleteFlare;
pDebuggerRuntimeOffsets->m_debuggerWordTLSIndex = g_debuggerWordTLSIndex;
+
+#if !defined(FEATURE_CORESYSTEM)
+ // Grab the address of RaiseException in kernel32 because we have to play some games with exceptions
+ // that are generated there (just another reason why mixed mode debugging is shady). See bug 476768.
+ HMODULE hModule = WszGetModuleHandle(W("kernel32.dll"));
+ _ASSERTE(hModule != NULL);
+ PREFAST_ASSUME(hModule != NULL);
+ pDebuggerRuntimeOffsets->m_raiseExceptionAddr = GetProcAddress(hModule, "RaiseException");
+ _ASSERTE(pDebuggerRuntimeOffsets->m_raiseExceptionAddr != NULL);
+ hModule = NULL;
+#else
+ pDebuggerRuntimeOffsets->m_raiseExceptionAddr = NULL;
+#endif
#endif // FEATURE_INTEROP_DEBUGGING
pDebuggerRuntimeOffsets->m_pPatches = DebuggerController::GetPatchTable();
@@ -562,14 +575,14 @@ static LONG _debugFilter(LPEXCEPTION_POINTERS ep, PVOID pv)
SUPPRESS_ALLOCATION_ASSERTS_IN_THIS_SCOPE;
-#if defined(_DEBUG)
+#if defined(_DEBUG) || !defined(FEATURE_CORESYSTEM)
DebuggerIPCEvent *event = ((DebugFilterParam *)pv)->event;
DWORD pid = GetCurrentProcessId();
DWORD tid = GetCurrentThreadId();
DebuggerIPCEventType type = (DebuggerIPCEventType) (event->type & DB_IPCE_TYPE_MASK);
-#endif // _DEBUG
+#endif // _DEBUG || !FEATURE_CORESYSTEM
// We should never AV here. In a debug build, throw up an assert w/ lots of useful (private) info.
#ifdef _DEBUG
@@ -600,6 +613,18 @@ static LONG _debugFilter(LPEXCEPTION_POINTERS ep, PVOID pv)
}
#endif
+// this message box doesn't work well on coresystem... we actually get in a recursive exception handling loop
+#ifndef FEATURE_CORESYSTEM
+ // We took an AV on the helper thread. This is a catastrophic situation so we can
+ // simply call the EE's catastrophic message box to display the error.
+ EEMessageBoxCatastrophic(
+ IDS_DEBUG_UNHANDLEDEXCEPTION_IPC, IDS_DEBUG_SERVICE_CAPTION,
+ type,
+ ep->ExceptionRecord->ExceptionCode,
+ GetIP(ep->ContextRecord),
+ pid, pid, tid, tid);
+#endif
+
// For debugging, we can change the behavior by manually setting eax.
// EXCEPTION_EXECUTE_HANDLER=1, EXCEPTION_CONTINUE_SEARCH=0, EXCEPTION_CONTINUE_EXECUTION=-1
return EXCEPTION_CONTINUE_SEARCH;
diff --git a/src/coreclr/debug/inc/dacdbiinterface.h b/src/coreclr/debug/inc/dacdbiinterface.h
index 82d5c4d1e465a..0bda865bd0f59 100644
--- a/src/coreclr/debug/inc/dacdbiinterface.h
+++ b/src/coreclr/debug/inc/dacdbiinterface.h
@@ -588,27 +588,27 @@ class IDacDbiInterface
// pData - required out parameter which will be filled out with module properties
//
// Notes:
- // See definition of DomainAssemblyInfo for more details about what properties
+ // See definition of DomainFileInfo for more details about what properties
// this gives back.
virtual
void GetModuleData(VMPTR_Module vmModule, OUT ModuleInfo * pData) = 0;
//
- // Get properties for a DomainAssembly
+ // Get properties for a DomainFile
//
// Arguments:
- // vmDomainAssembly - vm handle to a DomainAssembly
+ // vmDomainFile - vm handle to a DomainFile
// pData - required out parameter which will be filled out with module properties
//
// Notes:
- // See definition of DomainAssemblyInfo for more details about what properties
+ // See definition of DomainFileInfo for more details about what properties
// this gives back.
virtual
- void GetDomainAssemblyData(VMPTR_DomainAssembly vmDomainAssembly, OUT DomainAssemblyInfo * pData) = 0;
+ void GetDomainFileData(VMPTR_DomainFile vmDomainFile, OUT DomainFileInfo * pData) = 0;
virtual
- void GetModuleForDomainAssembly(VMPTR_DomainAssembly vmDomainAssembly, OUT VMPTR_Module * pModule) = 0;
+ void GetModuleForDomainFile(VMPTR_DomainFile vmDomainFile, OUT VMPTR_Module * pModule) = 0;
//.........................................................................
// These methods were the methods that DBI was calling from IXClrData in V2.
@@ -672,7 +672,7 @@ class IDacDbiInterface
// Get the values of the JIT Optimization and EnC flags.
//
// Arguments:
- // vmDomainAssembly - (input) VM DomainAssembly (module) for which we are retrieving flags
+ // vmDomainFile - (input) VM DomainFile (module) for which we are retrieving flags
// pfAllowJITOpts - (mandatory output) true iff this is not compiled for debug,
// i.e., without optimization
// pfEnableEnc - (mandatory output) true iff this module has EnC enabled
@@ -687,7 +687,7 @@ class IDacDbiInterface
virtual
void GetCompilerFlags(
- VMPTR_DomainAssembly vmDomainAssembly,
+ VMPTR_DomainFile vmDomainFile,
OUT BOOL * pfAllowJITOpts,
OUT BOOL * pfEnableEnC) = 0;
@@ -695,7 +695,7 @@ class IDacDbiInterface
// Set the values of the JIT optimization and EnC flags.
//
// Arguments:
- // vmDomainAssembly - (input) VM DomainAssembly (module) for which we are retrieving flags
+ // vmDomainFile - (input) VM DomainFile (module) for which we are retrieving flags
// pfAllowJITOpts - (input) true iff this should not be compiled for debug,
// i.e., without optimization
// pfEnableEnc - (input) true iff this module should have EnC enabled. If this is
@@ -717,7 +717,7 @@ class IDacDbiInterface
//.........................................................................
virtual
- HRESULT SetCompilerFlags(VMPTR_DomainAssembly vmDomainAssembly,
+ HRESULT SetCompilerFlags(VMPTR_DomainFile vmDomainFile,
BOOL fAllowJitOpts,
BOOL fEnableEnC) = 0;
@@ -784,7 +784,7 @@ class IDacDbiInterface
// Arguments:
// vmModule - new module from the enumeration
// pUserData - user data passed to EnumerateModulesInAssembly
- typedef void (*FP_MODULE_ENUMERATION_CALLBACK)(VMPTR_DomainAssembly vmModule, CALLBACK_DATA pUserData);
+ typedef void (*FP_MODULE_ENUMERATION_CALLBACK)(VMPTR_DomainFile vmModule, CALLBACK_DATA pUserData);
//
// Enumerates all the code Modules in an assembly.
@@ -1277,7 +1277,7 @@ class IDacDbiInterface
// The debugger can't duplicate this policy with 100% accuracy, and
// so we need DAC to lookup the assembly that was actually loaded.
virtual
- VMPTR_DomainAssembly ResolveAssembly(VMPTR_DomainAssembly vmScope, mdToken tkAssemblyRef) = 0;
+ VMPTR_DomainAssembly ResolveAssembly(VMPTR_DomainFile vmScope, mdToken tkAssemblyRef) = 0;
//-----------------------------------------------------------------------------
// Interface for initializing the native/IL sequence points and native var info
@@ -1707,13 +1707,13 @@ class IDacDbiInterface
//
// Arguments:
// Input:
- // vmDomainAssembly - module containing metadata for the method
+ // vmDomainFile - module containing metadata for the method
// functionToken - metadata token for the function
// Output (required):
// codeInfo - start address and size of the IL
// pLocalSigToken - signature token for the method
virtual
- void GetILCodeAndSig(VMPTR_DomainAssembly vmDomainAssembly,
+ void GetILCodeAndSig(VMPTR_DomainFile vmDomainFile,
mdToken functionToken,
OUT TargetBuffer * pCodeInfo,
OUT mdToken * pLocalSigToken) = 0;
@@ -1723,7 +1723,7 @@ class IDacDbiInterface
// and hot and cold region information.
// Arguments:
// Input:
- // vmDomainAssembly - module containing metadata for the method
+ // vmDomainFile - module containing metadata for the method
// functionToken - token for the function for which we need code info
// Output (required):
// pCodeInfo - data structure describing the native code regions.
@@ -1733,7 +1733,7 @@ class IDacDbiInterface
// invalid (i.e., pCodeInfo->IsValid is false).
virtual
- void GetNativeCodeInfo(VMPTR_DomainAssembly vmDomainAssembly,
+ void GetNativeCodeInfo(VMPTR_DomainFile vmDomainFile,
mdToken functionToken,
OUT NativeCodeFunctionData * pCodeInfo) = 0;
@@ -1798,7 +1798,7 @@ class IDacDbiInterface
// get field information and object size for an instantiated generic
//
// Arguments:
- // input: vmDomainAssembly - module containing metadata for the type
+ // input: vmDomainFile - module containing metadata for the type
// thExact - exact type handle for type (may be NULL)
// thApprox - approximate type handle for the type
// output:
@@ -1807,7 +1807,7 @@ class IDacDbiInterface
// pObjectSize - size of the instantiated object
//
virtual
- void GetInstantiationFieldInfo (VMPTR_DomainAssembly vmDomainAssembly,
+ void GetInstantiationFieldInfo (VMPTR_DomainFile vmDomainFile,
VMPTR_TypeHandle vmThExact,
VMPTR_TypeHandle vmThApprox,
OUT DacDbiArrayList * pFieldList,
@@ -1992,12 +1992,12 @@ class IDacDbiInterface
// input: vmAppDomain - Appdomain in which simpleType resides
// simpleType - CorElementType value corresponding to a simple type
// output: pMetadataToken - the metadata token corresponding to simpleType,
- // in the scope of vmDomainAssembly.
- // vmDomainAssembly - the domainAssembly for simpleType
+ // in the scope of vmDomainFile.
+ // vmDomainFile - the domainFile for simpleType
// Notes:
// This is inspection-only. If the type is not yet loaded, it will throw CORDBG_E_CLASS_NOT_LOADED.
// It will not try to load a type.
- // If the type has been loaded, vmDomainAssembly will be non-null unless the target is somehow corrupted.
+ // If the type has been loaded, vmDomainFile will be non-null unless the target is somehow corrupted.
// In that case, we will throw CORDBG_E_TARGET_INCONSISTENT.
virtual
@@ -2005,7 +2005,7 @@ class IDacDbiInterface
CorElementType simpleType,
OUT mdTypeDef * pMetadataToken,
OUT VMPTR_Module * pVmModule,
- OUT VMPTR_DomainAssembly * pVmDomainAssembly) = 0;
+ OUT VMPTR_DomainFile * pVmDomainFile) = 0;
// for the specified object returns TRUE if the object derives from System.Exception
virtual
@@ -2459,7 +2459,7 @@ class IDacDbiInterface
virtual
bool GetAppDomainForObject(CORDB_ADDRESS obj, OUT VMPTR_AppDomain * pApp,
OUT VMPTR_Module * pModule,
- OUT VMPTR_DomainAssembly * pDomainAssembly) = 0;
+ OUT VMPTR_DomainFile * pDomainFile) = 0;
// Reference Walking.
@@ -2731,7 +2731,7 @@ class IDacDbiInterface
HRESULT GetDelegateFunctionData(
DelegateType delegateType,
VMPTR_Object delegateObject,
- OUT VMPTR_DomainAssembly *ppFunctionDomainAssembly,
+ OUT VMPTR_DomainFile *ppFunctionDomainFile,
OUT mdMethodDef *pMethodDef) = 0;
virtual
diff --git a/src/coreclr/debug/inc/dacdbistructures.h b/src/coreclr/debug/inc/dacdbistructures.h
index aca5c668de42b..5e02a68a792c9 100644
--- a/src/coreclr/debug/inc/dacdbistructures.h
+++ b/src/coreclr/debug/inc/dacdbistructures.h
@@ -162,15 +162,15 @@ struct MSLAYOUT TargetBuffer
//===================================================================================
// Module properties, retrieved by DAC.
-// Describes a VMPTR_DomainAssembly representing a module.
+// Describes a VMPTR_DomainFile representing a module.
// In the VM, a raw Module may be domain neutral and shared by many appdomains.
-// Whereas a DomainAssembly is like a { AppDomain, Module} pair. DomainAssembly corresponds
+// Whereas a DomainFile is like a { AppDomain, Module} pair. DomainFile corresponds
// much more to ICorDebugModule (which also has appdomain affinity).
//===================================================================================
-struct MSLAYOUT DomainAssemblyInfo
+struct MSLAYOUT DomainFileInfo
{
- // The appdomain that the DomainAssembly is associated with.
- // Although VMPTR_Module may be shared across multiple domains, a DomainAssembly has appdomain affinity.
+ // The appdomain that the DomainFile is associated with.
+ // Although VMPTR_Module may be shared across multiple domains, a DomainFile has appdomain affinity.
VMPTR_AppDomain vmAppDomain;
// The assembly this module belongs to. All modules live in an assembly.
@@ -624,7 +624,7 @@ class MSLAYOUT EnCHangingFieldInfo
mdFieldDef fieldToken,
CorElementType elementType,
mdTypeDef metadataToken,
- VMPTR_DomainAssembly vmDomainAssembly);
+ VMPTR_DomainFile vmDomainFile);
DebuggerIPCE_BasicTypeData GetObjectTypeData() const { return m_objectTypeData; };
mdFieldDef GetFieldToken() const { return m_fldToken; };
@@ -660,7 +660,7 @@ enum AreValueTypesBoxed { NoValueTypeBoxing, OnlyPrimitivesUnboxed, AllBoxed };
typedef struct MSLAYOUT
{
// domain file for the type
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
// metadata token for the type. This may be a typeRef (for requests) or a typeDef (for responses).
mdToken typeToken;
} TypeRefData;
@@ -746,7 +746,7 @@ struct MSLAYOUT DacGcReference
struct MSLAYOUT DacExceptionCallStackData
{
VMPTR_AppDomain vmAppDomain;
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
CORDB_ADDRESS ip;
mdMethodDef methodDef;
BOOL isLastForeignExceptionFrame;
diff --git a/src/coreclr/debug/inc/dacdbistructures.inl b/src/coreclr/debug/inc/dacdbistructures.inl
index 84dd234319863..f9c0404b659c4 100644
--- a/src/coreclr/debug/inc/dacdbistructures.inl
+++ b/src/coreclr/debug/inc/dacdbistructures.inl
@@ -712,14 +712,14 @@ void EnCHangingFieldInfo::Init(VMPTR_Object pObject,
mdFieldDef fieldToken,
CorElementType elementType,
mdTypeDef metadataToken,
- VMPTR_DomainAssembly vmDomainAssembly)
+ VMPTR_DomainFile vmDomainFile)
{
m_vmObject = pObject;
m_offsetToVars = offset;
m_fldToken = fieldToken;
m_objectTypeData.elementType = elementType;
m_objectTypeData.metadataToken = metadataToken;
- m_objectTypeData.vmDomainAssembly = vmDomainAssembly;
+ m_objectTypeData.vmDomainFile = vmDomainFile;
}
diff --git a/src/coreclr/debug/inc/dbgipcevents.h b/src/coreclr/debug/inc/dbgipcevents.h
index e433532c29a16..ddef09554cf80 100644
--- a/src/coreclr/debug/inc/dbgipcevents.h
+++ b/src/coreclr/debug/inc/dbgipcevents.h
@@ -126,6 +126,7 @@ struct MSLAYOUT DebuggerIPCRuntimeOffsets
void *m_signalHijackCompleteBPAddr;
void *m_excepNotForRuntimeBPAddr;
void *m_notifyRSOfSyncCompleteBPAddr;
+ void *m_raiseExceptionAddr; // The address of kernel32!RaiseException in the debuggee
DWORD m_debuggerWordTLSIndex; // The TLS slot for the debugger word used in the debugger hijack functions
#endif // FEATURE_INTEROP_DEBUGGING
SIZE_T m_TLSIndex; // The TLS index of the thread-local storage for coreclr.dll
@@ -363,6 +364,30 @@ struct MSLAYOUT DebuggerIPCControlBlockTransport
#include "dbgtransportsession.h"
#endif // defined(FEATURE_DBGIPC_TRANSPORT_VM) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
+#if defined(TARGET_X86) && !defined(FEATURE_CORESYSTEM)
+// We have an versioning requirement.
+// Certain portions of the v1.0 and v1.1 IPC block are shared. This is b/c a v1.1 debugger needs to be able
+// to look at a v2.0 app enough to recognize the version mismatch.
+// This check is only necessary for platforms that ran on v1.1 (Win32-x86)
+
+// Just to catch any potential illegal change in the IPC block, we assert the offsets against the offsets from v1.1.
+// The constants here are pulled from v1.1.
+// The RS will look at these versioning fields, so they absolutely must line up.
+static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_leftSideProtocolCurrent) == 0x10);
+static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_leftSideProtocolMinSupported) == 0x14);
+static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_rightSideProtocolCurrent) == 0x18);
+static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_rightSideProtocolMinSupported) == 0x1c);
+
+// Unfortunately, on detecting such failure, v1.1 will also null out LSEA, LSER and RSPH.
+// If these get adjusted, a version-mismatch attach will effectively null out random fields.
+static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_paddingObsoleteLSEA) == 0x30);
+static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_paddingObsoleteLSER) == 0x34);
+static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_rightSideProcessHandle) == 0x38);
+
+
+
+#endif
+
#define INITIAL_APP_DOMAIN_INFO_LIST_SIZE 16
@@ -822,13 +847,15 @@ typedef VMPTR_Base VMPTR_CONTEXT;
typedef VMPTR_Base VMPTR_CONTEXT;
#endif
-// DomainAssembly is a base-class for a CLR module, with app-domain affinity.
-// For domain-neutral modules (like CoreLib), there is a DomainAssembly instance
+// DomainFile is a base-class for a CLR module, with app-domain affinity.
+// For domain-neutral modules (like CoreLib), there is a DomainFile instance
// for each appdomain the module lives in.
// This is the canonical handle ICorDebug uses to a CLR module.
-DEFINE_VMPTR(class DomainAssembly, PTR_DomainAssembly, VMPTR_DomainAssembly);
+DEFINE_VMPTR(class DomainFile, PTR_DomainFile, VMPTR_DomainFile);
DEFINE_VMPTR(class Module, PTR_Module, VMPTR_Module);
+// DomainAssembly derives from DomainFile and represents a manifest module.
+DEFINE_VMPTR(class DomainAssembly, PTR_DomainAssembly, VMPTR_DomainAssembly);
DEFINE_VMPTR(class Assembly, PTR_Assembly, VMPTR_Assembly);
DEFINE_VMPTR(class PEAssembly, PTR_PEAssembly, VMPTR_PEAssembly);
@@ -1258,7 +1285,7 @@ inline bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2)
struct MSLAYOUT DebuggerIPCE_FuncData
{
mdMethodDef funcMetadataToken;
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
mdTypeDef classMetadataToken;
@@ -1398,7 +1425,7 @@ struct MSLAYOUT DebuggerIPCE_STRData
struct MSLAYOUT
{
mdMethodDef funcMetadataToken;
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
VMPTR_MethodDesc vmMethodDesc;
CorDebugInternalFrameType frameType;
} stubFrame;
@@ -1442,7 +1469,7 @@ struct MSLAYOUT DebuggerIPCE_BasicTypeData
CorElementType elementType;
mdTypeDef metadataToken;
VMPTR_Module vmModule;
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
VMPTR_TypeHandle vmTypeHandle;
};
@@ -1478,7 +1505,7 @@ struct MSLAYOUT DebuggerIPCE_ExpandedTypeData
{
mdTypeDef metadataToken;
VMPTR_Module vmModule;
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
VMPTR_TypeHandle typeHandle; // if non-null then further fetches will be needed to get type arguments
} ClassTypeData;
@@ -1652,7 +1679,7 @@ struct MSLAYOUT DebuggerIPCE_FuncEvalInfo
DebuggerIPCE_FuncEvalType funcEvalType;
mdMethodDef funcMetadataToken;
mdTypeDef funcClassMetadataToken;
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
RSPTR_CORDBEVAL funcEvalKey;
bool evalDuringException;
@@ -1890,7 +1917,7 @@ struct MSLAYOUT DebuggerIPCEvent
{
// Module whos metadata is being updated
// This tells the RS that the metadata for that module has become invalid.
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
} MetadataUpdateData;
@@ -1933,13 +1960,13 @@ struct MSLAYOUT DebuggerIPCEvent
struct MSLAYOUT
{
// Module that was just loaded.
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
}LoadModuleData;
struct MSLAYOUT
{
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
LSPTR_ASSEMBLY debuggerAssemblyToken;
} UnloadModuleData;
@@ -1948,7 +1975,7 @@ struct MSLAYOUT DebuggerIPCEvent
// Queury PDB from OOP
struct MSLAYOUT
{
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
} UpdateModuleSymsData;
DebuggerMDANotification MDANotification;
@@ -1957,7 +1984,7 @@ struct MSLAYOUT DebuggerIPCEvent
{
LSPTR_BREAKPOINT breakpointToken;
mdMethodDef funcMetadataToken;
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
bool isIL;
SIZE_T offset;
SIZE_T encVersion;
@@ -2037,7 +2064,7 @@ struct MSLAYOUT DebuggerIPCEvent
// Apply an EnC edit
struct MSLAYOUT
{
- VMPTR_DomainAssembly vmDomainAssembly; // Module to edit
+ VMPTR_DomainFile vmDomainFile; // Module to edit
DWORD cbDeltaMetadata; // size of blob pointed to by pDeltaMetadata
CORDB_ADDRESS pDeltaMetadata; // pointer to delta metadata in debuggee
// it's the RS's responsibility to allocate and free
@@ -2054,20 +2081,20 @@ struct MSLAYOUT DebuggerIPCEvent
struct MSLAYOUT
{
mdTypeDef classMetadataToken;
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
LSPTR_ASSEMBLY classDebuggerAssemblyToken;
} LoadClass;
struct MSLAYOUT
{
mdTypeDef classMetadataToken;
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
LSPTR_ASSEMBLY classDebuggerAssemblyToken;
} UnloadClass;
struct MSLAYOUT
{
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
bool flag;
} SetClassLoad;
@@ -2098,7 +2125,7 @@ struct MSLAYOUT DebuggerIPCEvent
CORDB_ADDRESS startAddress;
bool fCanSetIPOnly;
VMPTR_Thread vmThreadToken;
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
mdMethodDef mdMethod;
VMPTR_MethodDesc vmMethodDesc;
SIZE_T offset;
@@ -2127,7 +2154,7 @@ struct MSLAYOUT DebuggerIPCEvent
struct MSLAYOUT
{
// Domain file for the domain in which the notification occurred
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
// metadata token for the type of the CustomNotification object's type
mdTypeDef classToken;
@@ -2192,7 +2219,7 @@ struct MSLAYOUT DebuggerIPCEvent
struct MSLAYOUT
{
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
BOOL fAllowJitOpts;
BOOL fEnableEnC;
} JitDebugInfo;
@@ -2200,7 +2227,7 @@ struct MSLAYOUT DebuggerIPCEvent
// EnC Remap opportunity
struct MSLAYOUT
{
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
mdMethodDef funcMetadataToken ; // methodDef of function with remap opportunity
SIZE_T currentVersionNumber; // version currently executing
SIZE_T resumeVersionNumber; // latest version
@@ -2212,7 +2239,7 @@ struct MSLAYOUT DebuggerIPCEvent
// EnC Remap has taken place
struct MSLAYOUT
{
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
mdMethodDef funcMetadataToken; // methodDef of function that was remapped
} EnCRemapComplete;
@@ -2220,7 +2247,7 @@ struct MSLAYOUT DebuggerIPCEvent
// specific edit made by EnC (function add/update or field add).
struct MSLAYOUT
{
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
mdToken memberMetadataToken; // Either a methodDef token indicating the function that
// was updated/added, or a fieldDef token indicating the
// field which was added.
@@ -2241,7 +2268,7 @@ struct MSLAYOUT DebuggerIPCEvent
// @todo - Perhaps we can bundle these up so we can set multiple funcs w/ 1 event?
struct MSLAYOUT
{
- VMPTR_DomainAssembly vmDomainAssembly;
+ VMPTR_DomainFile vmDomainFile;
mdMethodDef funcMetadataToken;
DWORD dwStatus;
} SetJMCFunctionStatus;
diff --git a/src/coreclr/debug/shared/dbgtransportsession.cpp b/src/coreclr/debug/shared/dbgtransportsession.cpp
index 3ff580717e72a..6d3ed5b345cf7 100644
--- a/src/coreclr/debug/shared/dbgtransportsession.cpp
+++ b/src/coreclr/debug/shared/dbgtransportsession.cpp
@@ -2696,6 +2696,11 @@ bool DbgTransportSession::DbgTransportShouldInjectFault(DbgTransportFaultOp eOp,
if (dwChance < (s_dwFaultInjection & DBG_TRANSPORT_FAULT_RATE_MASK))
{
DbgTransportLog(LC_FaultInject, "Injected fault for %s operation", szOpName);
+#if defined(FEATURE_CORESYSTEM)
+ // not supported
+#else
+ WSASetLastError(WSAEFAULT);
+#endif // defined(FEATURE_CORESYSTEM)
return true;
}
}
diff --git a/src/coreclr/dlls/dbgshim/dbgshim.cpp b/src/coreclr/dlls/dbgshim/dbgshim.cpp
index c82625487cfe8..40e4d7dea4bf2 100644
--- a/src/coreclr/dlls/dbgshim/dbgshim.cpp
+++ b/src/coreclr/dlls/dbgshim/dbgshim.cpp
@@ -1956,7 +1956,9 @@ GetContinueStartupEvent(
#endif // !TARGET_UNIX
+#if defined(FEATURE_CORESYSTEM)
#include "debugshim.h"
+#endif
//-----------------------------------------------------------------------------
// Public API.
@@ -1978,17 +1980,26 @@ CLRCreateInstance(
{
PUBLIC_CONTRACT;
+#if defined(FEATURE_CORESYSTEM)
+
if (ppInterface == NULL)
return E_POINTER;
if (clsid != CLSID_CLRDebugging || riid != IID_ICLRDebugging)
return E_NOINTERFACE;
+#if defined(FEATURE_CORESYSTEM)
GUID skuId = CLR_ID_ONECORE_CLR;
+#else
+ GUID skuId = CLR_ID_CORECLR;
+#endif
CLRDebuggingImpl *pDebuggingImpl = new (nothrow) CLRDebuggingImpl(skuId);
if (NULL == pDebuggingImpl)
return E_OUTOFMEMORY;
return pDebuggingImpl->QueryInterface(riid, ppInterface);
+#else
+ return E_NOTIMPL;
+#endif
}
diff --git a/src/coreclr/dlls/mscordac/mscordac_unixexports.src b/src/coreclr/dlls/mscordac/mscordac_unixexports.src
index 334d1b90c9308..2a529b2f4a779 100644
--- a/src/coreclr/dlls/mscordac/mscordac_unixexports.src
+++ b/src/coreclr/dlls/mscordac/mscordac_unixexports.src
@@ -65,6 +65,7 @@ nativeStringResourceTable_mscorrc
#PAL_wcsrchr
#PAL_wcscmp
#PAL_wcschr
+#PAL_wcscspn
#PAL_wcscat
#PAL_wcsstr
#PAL__open
@@ -139,6 +140,8 @@ nativeStringResourceTable_mscorrc
#LoadLibraryA
#LoadLibraryW
#LoadLibraryExW
+#LocalAlloc
+#LocalFree
#MapViewOfFile
#MapViewOfFileEx
#MoveFileExW
diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc
index d2c7bff988cc8..0e78c99f38d5d 100644
--- a/src/coreclr/dlls/mscorrc/mscorrc.rc
+++ b/src/coreclr/dlls/mscorrc/mscorrc.rc
@@ -194,10 +194,6 @@ BEGIN
IDS_EE_NDIRECT_GETPROCADDR_WIN_DLL "Unable to find an entry point named '%1' in DLL."
IDS_EE_NDIRECT_GETPROCADDR_UNIX_SO "Unable to find an entry point named '%1' in shared library."
IDS_EE_NDIRECT_GETPROCADDRESS_NONAME "A library name must be specified in a DllImport attribute applied to non-IJW methods."
- IDS_EE_NDIRECT_DISABLEDMARSHAL_SETLASTERROR "Setting SetLastError to 'true' is not supported when runtime marshalling is disabled."
- IDS_EE_NDIRECT_DISABLEDMARSHAL_LCID "The LCIDConversionAttribute is not supported when runtime marshalling is disabled."
- IDS_EE_NDIRECT_DISABLEDMARSHAL_PRESERVESIG "Setting PreserveSig to false for a P/Invoke is not supported when runtime marshalling is disabled."
- IDS_EE_NDIRECT_DISABLEDMARSHAL_VARARGS "Using a variable argument list in a P/Invoke is not supported when runtime marshalling is disabled."
IDS_EE_CLASS_CONSTRAINTS_VIOLATION "GenericArguments[%1], '%2', on '%3' violates the constraint of type parameter '%4'."
IDS_EE_METHOD_CONSTRAINTS_VIOLATION "Method %1.%2: type argument '%3' violates the constraint of type parameter '%4'."
IDS_EE_NOSYNCHRONIZED "Synchronized attribute cannot be used with this method type."
@@ -301,7 +297,6 @@ BEGIN
IDS_EE_BADMARSHAL_GENERICS_RESTRICTION "Non-blittable generic types cannot be marshaled."
IDS_EE_BADMARSHAL_AUTOLAYOUT "Structures marked with [StructLayout(LayoutKind.Auto)] cannot be marshaled."
IDS_EE_BADMARSHAL_STRING_OUT "Cannot marshal a string by-value with the [Out] attribute."
- IDS_EE_BADMARSHAL_MARSHAL_DISABLED "Cannot marshal managed types when the runtime marshalling system is disabled."
IDS_EE_BADMARSHALPARAM_STRINGBUILDER "Invalid managed/unmanaged type combination (StringBuilders must be paired with LPStr, LPWStr, or LPTStr)."
IDS_EE_BADMARSHALPARAM_NO_LPTSTR "Invalid managed/unmanaged type combination (Strings cannot be paired with LPTStr for parameters and return types of methods in interfaces exposed to COM)."
diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h
index 7a8f148456a83..05b31799ec5c4 100644
--- a/src/coreclr/dlls/mscorrc/resource.h
+++ b/src/coreclr/dlls/mscorrc/resource.h
@@ -588,8 +588,3 @@
#define IDS_EE_BADMARSHAL_DELEGATE_TLB_INTERFACE 0x2649
#define IDS_EE_THREAD_APARTMENT_NOT_SUPPORTED 0x264A
#define IDS_EE_NO_IINSPECTABLE 0x264B
-#define IDS_EE_BADMARSHAL_MARSHAL_DISABLED 0x264C
-#define IDS_EE_NDIRECT_DISABLEDMARSHAL_SETLASTERROR 0x264D
-#define IDS_EE_NDIRECT_DISABLEDMARSHAL_LCID 0x264E
-#define IDS_EE_NDIRECT_DISABLEDMARSHAL_PRESERVESIG 0x264F
-#define IDS_EE_NDIRECT_DISABLEDMARSHAL_VARARGS 0x2650
diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp
index c15f926fa756b..5a2a9c2c2c20e 100644
--- a/src/coreclr/gc/gc.cpp
+++ b/src/coreclr/gc/gc.cpp
@@ -2444,6 +2444,8 @@ heap_segment* gc_heap::reserved_free_regions_sip[max_generation];
int gc_heap::num_sip_regions = 0;
+size_t gc_heap::committed_in_free = 0;
+
size_t gc_heap::end_gen0_region_space = 0;
size_t gc_heap::gen0_pinned_free_space = 0;
@@ -9402,7 +9404,7 @@ void gc_heap::remove_ro_segment (heap_segment* seg)
enter_spin_lock (&gc_heap::gc_lock);
- seg_table->remove (heap_segment_mem (seg));
+ seg_table->remove ((uint8_t*)seg);
seg_mapping_table_remove_ro_segment (seg);
// Locate segment (and previous segment) in the list.
@@ -10890,7 +10892,7 @@ void gc_heap::seg_clear_mark_array_bits_soh (heap_segment* seg)
}
}
-void gc_heap::bgc_clear_batch_mark_array_bits (uint8_t* start, uint8_t* end)
+void gc_heap::clear_batch_mark_array_bits (uint8_t* start, uint8_t* end)
{
if ((start < background_saved_highest_address) &&
(end > background_saved_lowest_address))
@@ -10914,15 +10916,8 @@ void gc_heap::bgc_clear_batch_mark_array_bits (uint8_t* start, uint8_t* end)
if (startwrd == endwrd)
{
- if (startbit != endbit)
- {
- unsigned int wrd = firstwrd | lastwrd;
- mark_array[startwrd] &= wrd;
- }
- else
- {
- assert (start == end);
- }
+ unsigned int wrd = firstwrd | lastwrd;
+ mark_array[startwrd] &= wrd;
return;
}
@@ -10945,6 +10940,18 @@ void gc_heap::bgc_clear_batch_mark_array_bits (uint8_t* start, uint8_t* end)
}
}
}
+
+void gc_heap::bgc_clear_batch_mark_array_bits (uint8_t* start, uint8_t* end)
+{
+ if ((start < background_saved_highest_address) &&
+ (end > background_saved_lowest_address))
+ {
+ start = max (start, background_saved_lowest_address);
+ end = min (end, background_saved_highest_address);
+
+ clear_batch_mark_array_bits (start, end);
+ }
+}
#endif //BACKGROUND_GC
inline
@@ -11137,6 +11144,9 @@ heap_segment* gc_heap::get_free_region (int gen_number, size_t size)
{
heap_segment* region = 0;
+ // TODO: the update to committed_in_free is incorrect - we'd need synchorization 'cause a thread
+ // could be getting a small and another one could be getting a large region at the same time.
+ // This is only used for recording.
if (gen_number <= max_generation)
{
assert (size == 0);
@@ -11538,8 +11548,6 @@ void gc_heap::decommit_heap_segment_pages (heap_segment* seg,
if (use_large_pages_p)
return;
uint8_t* page_start = align_on_page (heap_segment_allocated(seg));
- assert (heap_segment_committed (seg) >= page_start);
-
size_t size = heap_segment_committed (seg) - page_start;
extra_space = align_on_page (extra_space);
if (size >= max ((extra_space + 2*OS_PAGE_SIZE), MIN_DECOMMIT_SIZE))
@@ -11560,10 +11568,10 @@ size_t gc_heap::decommit_heap_segment_pages_worker (heap_segment* seg,
#endif
assert (!use_large_pages_p);
uint8_t* page_start = align_on_page (new_committed);
- ptrdiff_t size = heap_segment_committed (seg) - page_start;
+ size_t size = heap_segment_committed (seg) - page_start;
if (size > 0)
{
- bool decommit_succeeded_p = virtual_decommit (page_start, (size_t)size, heap_segment_oh (seg), heap_number);
+ bool decommit_succeeded_p = virtual_decommit (page_start, size, heap_segment_oh (seg), heap_number);
if (decommit_succeeded_p)
{
dprintf (3, ("Decommitting heap segment [%Ix, %Ix[(%d)",
@@ -11598,11 +11606,10 @@ void gc_heap::decommit_heap_segment (heap_segment* seg)
dprintf (3, ("Decommitting heap segment %Ix(%Ix)", (size_t)seg, heap_segment_mem (seg)));
-#if defined(BACKGROUND_GC) && !defined(USE_REGIONS)
+#ifdef BACKGROUND_GC
page_start += OS_PAGE_SIZE;
-#endif //BACKGROUND_GC && !USE_REGIONS
+#endif //BACKGROUND_GC
- assert (heap_segment_committed (seg) >= page_start);
size_t size = heap_segment_committed (seg) - page_start;
bool decommit_succeeded_p = virtual_decommit (page_start, size, heap_segment_oh (seg), heap_number);
@@ -13561,6 +13568,7 @@ gc_heap::init_gc_heap (int h_number)
sip_seg_maxgen_interval = 3;
num_condemned_regions = 0;
#endif //STRESS_REGIONS
+ committed_in_free = 0;
end_gen0_region_space = 0;
gen0_pinned_free_space = 0;
gen0_large_chunk_found = false;
@@ -20420,33 +20428,23 @@ void gc_heap::gc1()
if (n < max_generation)
{
- int highest_gen_number =
-#ifdef USE_REGIONS
- max_generation;
-#else //USE_REGIONS
- 1 + n;
-#endif //USE_REGIONS
-
- for (int older_gen_idx = (1 + n); older_gen_idx <= highest_gen_number; older_gen_idx++)
- {
- compute_promoted_allocation (older_gen_idx);
+ compute_promoted_allocation (1 + n);
- dynamic_data* dd = dynamic_data_of (older_gen_idx);
- size_t new_fragmentation = generation_free_list_space (generation_of (older_gen_idx)) +
- generation_free_obj_space (generation_of (older_gen_idx));
+ dynamic_data* dd = dynamic_data_of (1 + n);
+ size_t new_fragmentation = generation_free_list_space (generation_of (1 + n)) +
+ generation_free_obj_space (generation_of (1 + n));
#ifdef BACKGROUND_GC
- if (current_c_gc_state != c_gc_state_planning)
+ if (current_c_gc_state != c_gc_state_planning)
#endif //BACKGROUND_GC
+ {
+ if (settings.promotion)
{
- if (settings.promotion)
- {
- dd_fragmentation (dd) = new_fragmentation;
- }
- else
- {
- //assert (dd_fragmentation (dd) == new_fragmentation);
- }
+ dd_fragmentation (dd) = new_fragmentation;
+ }
+ else
+ {
+ //assert (dd_fragmentation (dd) == new_fragmentation);
}
}
}
@@ -24366,17 +24364,8 @@ size_t gc_heap::committed_size()
}
#ifdef USE_REGIONS
- size_t committed_in_free = 0;
-
- for (int kind = basic_free_region; kind < count_free_region_kinds; kind++)
- {
- committed_in_free += free_regions[kind].get_size_committed_in_free();
- }
-
- dprintf (3, ("h%d committed in free %Id", heap_number, committed_in_free));
-
total_committed += committed_in_free;
-#endif //USE_REGIONS
+#endif //USE_REGIO
return total_committed;
}
@@ -27464,7 +27453,7 @@ void gc_heap::plan_phase (int condemned_gen_number)
_sort (&mark_list[0], mark_list_index - 1, 0);
#endif //USE_VXSORT
- dprintf (3, ("using mark list at GC #%Id", (size_t)settings.gc_index));
+ dprintf (3, ("using mark list at GC #%d", settings.gc_index));
//verify_qsort_array (&mark_list[0], mark_list_index-1);
#endif //!MULTIPLE_HEAPS
use_mark_list = TRUE;
@@ -29752,7 +29741,7 @@ void gc_heap::thread_final_regions (bool compact_p)
}
}
- verify_regions (true, false);
+ verify_regions (true);
}
void gc_heap::thread_start_region (generation* gen, heap_segment* region)
@@ -29803,7 +29792,7 @@ heap_segment* gc_heap::get_new_region (int gen_number, size_t size)
heap_segment_next (generation_tail_region (gen)) = new_region;
generation_tail_region (gen) = new_region;
- verify_regions (gen_number, false, settings.concurrent);
+ verify_regions (gen_number, false);
}
return new_region;
@@ -29872,7 +29861,7 @@ void gc_heap::update_start_tail_regions (generation* gen,
(size_t)prev_region, heap_segment_mem (prev_region)));
}
- verify_regions (false, settings.concurrent);
+ verify_regions (false);
}
// There's one complication with deciding whether we can make a region SIP or not - if the plan_gen_num of
@@ -30141,19 +30130,12 @@ void gc_heap::sweep_region_in_plan (heap_segment* region,
heap_segment_saved_allocated (region) = heap_segment_allocated (region);
heap_segment_allocated (region) = last_marked_obj_end;
heap_segment_plan_allocated (region) = heap_segment_allocated (region);
-
- int plan_gen_num = heap_segment_plan_gen_num (region);
- generation_allocation_size (generation_of (plan_gen_num)) += heap_segment_survived (region);
- dprintf (REGIONS_LOG, ("sip: g%d alloc size is now %Id", plan_gen_num,
- generation_allocation_size (generation_of (plan_gen_num))));
}
inline
void gc_heap::check_demotion_helper_sip (uint8_t** pval, int parent_gen_num, uint8_t* parent_loc)
{
uint8_t* child_object = *pval;
- if (!is_in_heap_range (child_object))
- return;
if (!child_object) return;
int child_object_plan_gen = get_region_plan_gen_num (child_object);
@@ -36671,7 +36653,7 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating CARD_
hpt->heap_number, heap_number, n_eph, n_gen, n_card_set, total_cards_cleared,
(n_eph ? (int)(((float)n_gen / (float)n_eph) * 100) : 0)));
dprintf (3, ("h%d marking h%d Msoh: total cross %Id, useful: %Id, running ratio: %d",
- hpt->heap_number, heap_number, (size_t)n_eph_soh, (size_t)n_gen_soh,
+ hpt->heap_number, heap_number, n_eph_soh, n_gen_soh,
(n_eph_soh ? (int)(((float)n_gen_soh / (float)n_eph_soh) * 100) : 0)));
#else
generation_skip_ratio = ((n_eph > MIN_SOH_CROSS_GEN_REFS) ? (int)(((float)n_gen / (float)n_eph) * 100) : 100);
@@ -41419,7 +41401,7 @@ void gc_heap::mark_through_cards_for_uoh_objects (card_fn fn,
hpt->heap_number, heap_number, n_eph, n_gen, n_card_set, total_cards_cleared,
(n_eph ? (int)(((float)n_gen / (float)n_eph) * 100) : 0)));
dprintf (3, ("h%d marking h%d Mloh: total cross %Id, useful: %Id, running ratio: %d",
- hpt->heap_number, heap_number, (size_t)n_eph_loh, (size_t)n_gen_loh,
+ hpt->heap_number, heap_number, n_eph_loh, n_gen_loh,
(n_eph_loh ? (int)(((float)n_gen_loh / (float)n_eph_loh) * 100) : 0)));
#else
generation_skip_ratio = min (((n_eph > MIN_LOH_CROSS_GEN_REFS) ?
@@ -42175,7 +42157,7 @@ gc_heap::verify_free_lists ()
}
}
-void gc_heap::verify_regions (int gen_number, bool can_verify_gen_num, bool can_verify_tail)
+void gc_heap::verify_regions (int gen_number, bool can_verify_gen_num)
{
#ifdef USE_REGIONS
// For the given generation, verify that
@@ -42238,7 +42220,7 @@ void gc_heap::verify_regions (int gen_number, bool can_verify_gen_num, bool can_
FATAL_GC_ERROR();
}
- if (can_verify_tail && (tail_region != prev_region_in_gen))
+ if (tail_region != prev_region_in_gen)
{
dprintf (REGIONS_LOG, ("h%d gen%d tail region is %Ix(%Ix), diff from last region %Ix(%Ix)!!",
heap_number, gen_number,
@@ -42249,18 +42231,12 @@ void gc_heap::verify_regions (int gen_number, bool can_verify_gen_num, bool can_
#endif //USE_REGIONS
}
-inline bool is_user_alloc_gen (int gen_number)
-{
- return ((gen_number == soh_gen0) || (gen_number == loh_generation) || (gen_number == poh_generation));
-}
-
-void gc_heap::verify_regions (bool can_verify_gen_num, bool concurrent_p)
+void gc_heap::verify_regions (bool can_verify_gen_num)
{
#ifdef USE_REGIONS
for (int i = 0; i < total_generation_count; i++)
{
- bool can_verify_tail = (concurrent_p ? !is_user_alloc_gen (i) : true);
- verify_regions (i, can_verify_gen_num, can_verify_tail);
+ verify_regions (i, can_verify_gen_num);
}
#endif //USE_REGIONS
}
@@ -42391,7 +42367,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p)
//verify that the generation structures makes sense
{
#ifdef USE_REGIONS
- verify_regions (true, settings.concurrent);
+ verify_regions (true);
#else //USE_REGIONS
generation* gen = generation_of (max_generation);
@@ -43452,15 +43428,8 @@ void GCHeap::SetYieldProcessorScalingFactor (float scalingFactor)
unsigned int GCHeap::WhichGeneration (Object* object)
{
- uint8_t* o = (uint8_t*)object;
-#ifdef FEATURE_BASICFREEZE
- if (!((o < g_gc_highest_address) && (o >= g_gc_lowest_address)))
- {
- return max_generation;
- }
-#endif //FEATURE_BASICFREEZE
- gc_heap* hp = gc_heap::heap_of (o);
- unsigned int g = hp->object_gennum (o);
+ gc_heap* hp = gc_heap::heap_of ((uint8_t*)object);
+ unsigned int g = hp->object_gennum ((uint8_t*)object);
dprintf (3, ("%Ix is in gen %d", (size_t)object, g));
return g;
}
@@ -44102,8 +44071,12 @@ GCHeap::Alloc(gc_alloc_context* context, size_t size, uint32_t flags REQD_ALIGN_
}
CHECK_ALLOC_AND_POSSIBLY_REGISTER_FOR_FINALIZATION(newAlloc, size, flags & GC_ALLOC_FINALIZE);
+
#ifdef USE_REGIONS
- assert (IsHeapPointer (newAlloc));
+ if (!IsHeapPointer (newAlloc))
+ {
+ GCToOSInterface::DebugBreak();
+ }
#endif //USE_REGIONS
return newAlloc;
diff --git a/src/coreclr/gc/gcconfig.h b/src/coreclr/gc/gcconfig.h
index d727a4685c527..886ea17743880 100644
--- a/src/coreclr/gc/gcconfig.h
+++ b/src/coreclr/gc/gcconfig.h
@@ -87,8 +87,8 @@ class GCConfigStringHolder
INT_CONFIG (SegmentSize, "GCSegmentSize", NULL, 0, "Specifies the managed heap segment size") \
INT_CONFIG (LatencyMode, "GCLatencyMode", NULL, -1, "Specifies the GC latency mode - batch, interactive or low latency (note that the same " \
"thing can be specified via API which is the supported way") \
- INT_CONFIG (LatencyLevel, "GCLatencyLevel", NULL, 1, "Specifies the GC latency level that you want to optimize for. Must be a number from 0 " \
- "to 3. See documentation for more details on each level.") \
+ INT_CONFIG (LatencyLevel, "GCLatencyLevel", NULL, 1, "Specifies the GC latency level that you want to optimize for. Must be a number from 0" \
+ "3. See documentation for more details on each level.") \
INT_CONFIG (LogFileSize, "GCLogFileSize", NULL, 0, "Specifies the GC log file size") \
INT_CONFIG (CompactRatio, "GCCompactRatio", NULL, 0, "Specifies the ratio compacting GCs vs sweeping") \
INT_CONFIG (GCHeapAffinitizeMask, "GCHeapAffinitizeMask", "System.GC.HeapAffinitizeMask", 0, "Specifies processor mask for Server GC threads") \
@@ -117,7 +117,7 @@ class GCConfigStringHolder
INT_CONFIG (BGCFLkd, "BGCFLkd", NULL, 11, "Specifies kd for above goal tuning") \
INT_CONFIG (BGCFLff, "BGCFLff", NULL, 100, "Specifies ff ratio") \
INT_CONFIG (BGCFLSmoothFactor, "BGCFLSmoothFactor", NULL, 150, "Smoothing over these") \
- INT_CONFIG (BGCFLGradualD, "BGCFLGradualD", NULL, 0, "Enable gradual D instead of cutting off at the value") \
+ INT_CONFIG (BGCFLGradualD, "BGCFLGradualD", NULL, 0, "Enable gradual D instead of cutting of at the value") \
INT_CONFIG (BGCMLkp, "BGCMLkp", NULL, 1000, "Specifies kp for ML tuning") \
INT_CONFIG (BGCMLki, "BGCMLki", NULL, 16, "Specifies ki for ML tuning") \
INT_CONFIG (BGCFLEnableKi, "BGCFLEnableKi", NULL, 1, "Enables ki for above goal tuning") \
diff --git a/src/coreclr/gc/gcinterface.dac.h b/src/coreclr/gc/gcinterface.dac.h
index c7d72c7145baf..cfffcf1221a81 100644
--- a/src/coreclr/gc/gcinterface.dac.h
+++ b/src/coreclr/gc/gcinterface.dac.h
@@ -111,7 +111,7 @@ enum oom_reason
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/* If you modify failure_get_memory and */
/* oom_reason be sure to make the corresponding */
-/* changes in tools\sos\strike\strike.cpp. */
+/* changes in toolbox\sos\strike\strike.cpp. */
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
enum failure_get_memory
{
diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h
index 567e7c1bd69ca..14bf3ef290889 100644
--- a/src/coreclr/gc/gcpriv.h
+++ b/src/coreclr/gc/gcpriv.h
@@ -51,8 +51,8 @@ inline void FATAL_GC_ERROR()
//
// This means any empty regions can be freely used for any generation. For
// Server GC we will balance regions between heaps.
-// For now disable regions outside of StandAlone GC builds
-#if defined (HOST_64BIT) && defined (BUILD_AS_STANDALONE)
+// For now disable regions StandAlone GC builds
+#if defined (HOST_64BIT) && !defined (BUILD_AS_STANDALONE)
#define USE_REGIONS
#endif //HOST_64BIT && BUILD_AS_STANDALONE
@@ -1175,7 +1175,6 @@ class region_free_list
heap_segment* unlink_region_front();
heap_segment* unlink_smallest_region (size_t size);
size_t get_num_free_regions();
- size_t get_size_committed_in_free() { return size_committed_in_free_regions; }
size_t get_size_free_regions() { return size_free_regions; }
heap_segment* get_first_free_region() { return head_free_region; }
static void unlink_region (heap_segment* region);
@@ -1287,9 +1286,9 @@ class gc_heap
PER_HEAP
void verify_free_lists();
PER_HEAP
- void verify_regions (int gen_number, bool can_verify_gen_num, bool can_verify_tail);
+ void verify_regions (int gen_number, bool can_verify_gen_num);
PER_HEAP
- void verify_regions (bool can_verify_gen_num, bool concurrent_p);
+ void verify_regions (bool can_verify_gen_num);
PER_HEAP_ISOLATED
void enter_gc_lock_for_verify_heap();
PER_HEAP_ISOLATED
@@ -2157,6 +2156,8 @@ class gc_heap
PER_HEAP
void seg_clear_mark_array_bits_soh (heap_segment* seg);
PER_HEAP
+ void clear_batch_mark_array_bits (uint8_t* start, uint8_t* end);
+ PER_HEAP
void bgc_clear_batch_mark_array_bits (uint8_t* start, uint8_t* end);
#ifdef VERIFY_HEAP
PER_HEAP
@@ -3595,6 +3596,9 @@ class gc_heap
PER_HEAP
int num_sip_regions;
+ PER_HEAP
+ size_t committed_in_free;
+
PER_HEAP
// After plan we calculate this as the planned end gen0 space;
// but if we end up sweeping, we recalculate it at the end of
diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp
index 2d979c395610e..431421afc87e4 100644
--- a/src/coreclr/gc/unix/gcenv.unix.cpp
+++ b/src/coreclr/gc/unix/gcenv.unix.cpp
@@ -28,10 +28,6 @@
#undef min
#undef max
-#ifndef __has_cpp_attribute
-#define __has_cpp_attribute(x) (0)
-#endif
-
#if __has_cpp_attribute(fallthrough)
#define FALLTHROUGH [[fallthrough]]
#else
diff --git a/src/coreclr/hosts/corerun/corerun.cpp b/src/coreclr/hosts/corerun/corerun.cpp
index 67a43e28b20d1..345a18ef6bc62 100644
--- a/src/coreclr/hosts/corerun/corerun.cpp
+++ b/src/coreclr/hosts/corerun/corerun.cpp
@@ -291,9 +291,9 @@ static int run(const configuration& config)
}
// Construct CoreCLR properties.
- pal::string_utf8_t tpa_list_utf8 = pal::convert_to_utf8(tpa_list.c_str());
- pal::string_utf8_t app_path_utf8 = pal::convert_to_utf8(app_path.c_str());
- pal::string_utf8_t native_search_dirs_utf8 = pal::convert_to_utf8(native_search_dirs.str().c_str());
+ pal::string_utf8_t tpa_list_utf8 = pal::convert_to_utf8(std::move(tpa_list));
+ pal::string_utf8_t app_path_utf8 = pal::convert_to_utf8(std::move(app_path));
+ pal::string_utf8_t native_search_dirs_utf8 = pal::convert_to_utf8(native_search_dirs.str());
std::vector user_defined_keys_utf8;
std::vector user_defined_values_utf8;
@@ -334,7 +334,7 @@ static int run(const configuration& config)
int propertyCount = (int)propertyKeys.size();
// Construct arguments
- pal::string_utf8_t exe_path_utf8 = pal::convert_to_utf8(exe_path.c_str());
+ pal::string_utf8_t exe_path_utf8 = pal::convert_to_utf8(std::move(exe_path));
std::vector argv_lifetime;
pal::malloc_ptr argv_utf8{ pal::convert_argv_to_utf8(config.entry_assembly_argc, config.entry_assembly_argv, argv_lifetime) };
pal::string_utf8_t entry_assembly_utf8 = pal::convert_to_utf8(config.entry_assembly_fullpath.c_str());
diff --git a/src/coreclr/hosts/corerun/corerun.hpp b/src/coreclr/hosts/corerun/corerun.hpp
index 14cb9ec6580e1..9781299c8049e 100644
--- a/src/coreclr/hosts/corerun/corerun.hpp
+++ b/src/coreclr/hosts/corerun/corerun.hpp
@@ -88,28 +88,11 @@ namespace pal
assert(wrote < needed);
return { buffer.get() };
}
- inline string_utf8_t getenvA(const char* var)
- {
- DWORD needed = ::GetEnvironmentVariableA(var, nullptr, 0);
- if (needed == 0)
- return {};
-
- malloc_ptr buffer{ (char*)::malloc(needed * sizeof(char)) };
- assert(buffer != nullptr);
- DWORD wrote = ::GetEnvironmentVariableA(var, buffer.get(), needed);
- assert(wrote < needed);
- return { buffer.get() };
- }
inline void setenv(const char_t* var, string_t value)
{
BOOL success = ::SetEnvironmentVariableW(var, value.c_str());
assert(success);
}
- inline void setenvA(const char* var, string_utf8_t value)
- {
- BOOL success = ::SetEnvironmentVariableA(var, value.c_str());
- assert(success);
- }
inline string_t get_exe_path()
{
char_t file_name[1024];
@@ -194,17 +177,31 @@ namespace pal
inline string_utf8_t convert_to_utf8(const char_t* str)
{
- int bytes_req = ::WideCharToMultiByte(CP_UTF8, 0, str, -1, nullptr, 0, nullptr, nullptr);
+ // Compute the needed buffer
+ int bytes_req = ::WideCharToMultiByte(
+ CP_UTF8, 0, // Conversion args
+ str, -1, // Input string
+ nullptr, 0, // Null to request side
+ nullptr, nullptr);
malloc_ptr buffer{ (char*)::malloc(bytes_req) };
assert(buffer != nullptr);
- int written = ::WideCharToMultiByte(CP_UTF8, 0, str, -1, buffer.get(), bytes_req, nullptr, nullptr);
+ int written = ::WideCharToMultiByte(
+ CP_UTF8, 0, // Conversion args
+ str, -1, // Input string
+ buffer.get(), bytes_req, // Output buffer
+ nullptr, nullptr);
assert(bytes_req == written);
return { buffer.get() };
}
+ inline string_utf8_t convert_to_utf8(string_t&& str)
+ {
+ return convert_to_utf8(str.c_str());
+ }
+
inline bool try_load_hostpolicy(pal::string_t mock_hostpolicy_value)
{
const char_t* hostpolicyName = W("hostpolicy.dll");
@@ -363,19 +360,11 @@ namespace pal
return {};
return { val };
}
- inline string_utf8_t getenvA(const char* var)
- {
- return getenv(var);
- }
inline void setenv(const char_t* var, string_t value)
{
int error = ::setenv(var, value.c_str(), /* overwrite */ 1);
assert(error == 0);
}
- inline void setenvA(const char* var, string_utf8_t value)
- {
- setenv(var, value.c_str());
- }
inline string_t get_exe_path() { return minipal_getexepath(); }
@@ -578,6 +567,11 @@ namespace pal
return { str };
}
+ inline string_utf8_t convert_to_utf8(string_t&& str)
+ {
+ return std::move(str);
+ }
+
inline bool try_load_hostpolicy(pal::string_t mock_hostpolicy_value)
{
if (!string_ends_with(mock_hostpolicy_value, pal::nativelib_ext))
diff --git a/src/coreclr/hosts/corerun/dotenv.cpp b/src/coreclr/hosts/corerun/dotenv.cpp
index 8792d63151f56..0e0e37c7919b0 100644
--- a/src/coreclr/hosts/corerun/dotenv.cpp
+++ b/src/coreclr/hosts/corerun/dotenv.cpp
@@ -7,8 +7,22 @@
#include
#include
+#ifdef TARGET_WINDOWS
+#include
+#endif
+
namespace
{
+ pal::string_t convert_to_string_t(std::string str)
+ {
+#ifdef TARGET_WINDOWS
+ std::wstring_convert> converter;
+ return converter.from_bytes(str);
+#else
+ return str;
+#endif
+ }
+
bool read_var_name(std::istream& file, std::string& var_name_out)
{
std::string var_name;
@@ -312,7 +326,8 @@ dotenv::dotenv(pal::string_t dotEnvFilePath, std::istream& contents)
{
return dot_env_entry->second;
}
- return pal::getenvA(name.c_str());
+ pal::string_t env_var_name = convert_to_string_t(name);
+ return pal::convert_to_utf8(pal::getenv(env_var_name.c_str()));
}, temp_value))
{
_environmentVariables = {};
@@ -326,9 +341,9 @@ void dotenv::load_into_current_process() const
{
for (std::pair env_vars : _environmentVariables)
{
- pal::string_utf8_t name_string = env_vars.first;
- pal::string_utf8_t value_string = env_vars.second;
- pal::setenvA(name_string.c_str(), std::move(value_string));
+ pal::string_t name_string = convert_to_string_t(env_vars.first);
+ pal::string_t value_string = convert_to_string_t(env_vars.second);
+ pal::setenv(name_string.c_str(), std::move(value_string));
}
}
diff --git a/src/coreclr/inc/bbsweep.h b/src/coreclr/inc/bbsweep.h
index 64855ed939ddd..eda1e11d2f2e1 100644
--- a/src/coreclr/inc/bbsweep.h
+++ b/src/coreclr/inc/bbsweep.h
@@ -31,9 +31,11 @@
#pragma push_macro("SetEvent")
#pragma push_macro("ResetEvent")
#pragma push_macro("ReleaseSemaphore")
+#pragma push_macro("LocalFree")
#undef SetEvent
#undef ResetEvent
#undef ReleaseSemaphore
+#undef LocalFree
// MAX_COUNT is the maximal number of runtime processes that can run at a given time
#define MAX_COUNT 20
@@ -182,6 +184,97 @@ class BBSweep
if (!bInitialized)
{
SECURITY_ATTRIBUTES * pSecurityAttributes = NULL;
+
+#ifndef FEATURE_CORESYSTEM // @CORESYSTEMTODO
+ PSECURITY_DESCRIPTOR pSD = NULL;
+ PSID pAdminSid = NULL;
+ HANDLE hToken = NULL;
+ PACL pACL = NULL;
+ LPVOID buffer = NULL;
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
+ goto cleanup;
+
+ // don't set pSecurityAttributes for AppContainer processes
+ if(!IsAppContainerProcess(hToken))
+ {
+ SECURITY_ATTRIBUTES securityAttributes;
+ PSID pUserSid = NULL;
+ SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
+ DWORD retLength;
+
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:6211) // PREfast warning: Leaking memory 'pSD' due to an exception.
+#endif /*_PREFAST_ */
+ pSD = (PSECURITY_DESCRIPTOR) new char[SECURITY_DESCRIPTOR_MIN_LENGTH];
+ if (!pSD)
+ goto cleanup;
+
+ if (GetTokenInformation(hToken, TokenOwner, NULL, 0, &retLength))
+ goto cleanup;
+
+ buffer = (LPVOID) new char[retLength];
+ if (!buffer)
+ goto cleanup;
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif /*_PREFAST_*/
+
+ // Get the SID for the current user
+ if (!GetTokenInformation(hToken, TokenOwner, (LPVOID) buffer, retLength, &retLength))
+ goto cleanup;
+
+ pUserSid = ((TOKEN_OWNER *) buffer)->Owner;
+
+ // Get the SID for the admin group
+ // Create a SID for the BUILTIN\Administrators group.
+ if(! AllocateAndInitializeSid(&SIDAuthNT, 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &pAdminSid))
+ goto cleanup;
+
+ EXPLICIT_ACCESS ea[2];
+ ZeroMemory(ea, 2 * sizeof(EXPLICIT_ACCESS));
+
+ // Initialize an EXPLICIT_ACCESS structure for an ACE.
+ // The ACE will allow the current user full access
+ ea[0].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; // KEY_ALL_ACCESS;
+ ea[0].grfAccessMode = SET_ACCESS;
+ ea[0].grfInheritance= NO_INHERITANCE;
+ ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
+ ea[0].Trustee.ptstrName = (LPTSTR) pUserSid;
+
+ // Initialize an EXPLICIT_ACCESS structure for an ACE.
+ // The ACE will allow admins full access
+ ea[1].grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL; //KEY_ALL_ACCESS;
+ ea[1].grfAccessMode = SET_ACCESS;
+ ea[1].grfInheritance= NO_INHERITANCE;
+ ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
+ ea[1].Trustee.ptstrName = (LPTSTR) pAdminSid;
+
+ if (SetEntriesInAcl(2, ea, NULL, &pACL) != ERROR_SUCCESS)
+ goto cleanup;
+
+ if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
+ goto cleanup;
+
+ if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE))
+ goto cleanup;
+
+ memset((void *) &securityAttributes, 0, sizeof(SECURITY_ATTRIBUTES));
+ securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ securityAttributes.lpSecurityDescriptor = pSD;
+ securityAttributes.bInheritHandle = FALSE;
+
+ pSecurityAttributes = &securityAttributes;
+ }
+#endif // !FEATURE_CORESYSTEM
+
WCHAR objectName[MAX_LONGPATH] = {0};
WCHAR objectNamePrefix[MAX_LONGPATH] = {0};
GetObjectNamePrefix(processID, fromRuntime, objectNamePrefix);
@@ -200,6 +293,15 @@ class BBSweep
hTerminationEvent = ::WszCreateEvent(pSecurityAttributes, true, false, NULL);
swprintf_s(objectName, MAX_LONGPATH, W("%sBBSweep_hProfWriterSemaphore"), objectNamePrefix);
hProfWriterSemaphore = ::WszCreateSemaphore(pSecurityAttributes, MAX_COUNT, MAX_COUNT, objectName);
+
+#ifndef FEATURE_CORESYSTEM // @CORESYSTEMTODO
+cleanup:
+ if (pSD) delete [] ((char *) pSD);
+ if (pAdminSid) FreeSid(pAdminSid);
+ if (hToken) CloseHandle(hToken);
+ if (pACL) LocalFree(pACL);
+ if (buffer) delete [] ((char *) buffer);
+#endif
}
bInitialized = hSweepMutex &&
@@ -279,7 +381,7 @@ class BBSweep
}
else
{
-#if !defined(DACCESS_COMPILE)
+#if defined (FEATURE_CORESYSTEM) && !defined(DACCESS_COMPILE)
#define MODULE_NAME W("api-ms-win-security-appcontainer-l1-1-0.dll")
#else
#define MODULE_NAME W("kernel32.dll")
@@ -314,6 +416,7 @@ class BBSweep
HANDLE hBBSweepThread; // a handle to the CLR sweeper thread (that calls watch for sweep events)
};
+#pragma pop_macro("LocalFree")
#pragma pop_macro("ReleaseSemaphore")
#pragma pop_macro("ResetEvent")
#pragma pop_macro("SetEvent")
diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h
index e544430fa587b..28b1010666369 100644
--- a/src/coreclr/inc/clrconfigvalues.h
+++ b/src/coreclr/inc/clrconfigvalues.h
@@ -176,6 +176,7 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_DbgDACSkipVerifyDlls, W("DbgDACSkipVerifyDlls"
CONFIG_DWORD_INFO(INTERNAL_DbgDelayHelper, W("DbgDelayHelper"), 0, "Varies the wait in the helper thread startup for testing race between threads")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_DbgDisableDynamicSymsCompat, W("DbgDisableDynamicSymsCompat"), 0, "")
CONFIG_DWORD_INFO(INTERNAL_DbgDisableTargetConsistencyAsserts, W("DbgDisableTargetConsistencyAsserts"), 0, "Allows explicitly testing with corrupt targets")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_DbgEnableMixedModeDebugging, W("DbgEnableMixedModeDebuggingInternalOnly"), 0, "")
CONFIG_DWORD_INFO(INTERNAL_DbgExtraThreads, W("DbgExtraThreads"), 0, "Allows extra unmanaged threads to run and throw debug events for stress testing")
CONFIG_DWORD_INFO(INTERNAL_DbgExtraThreadsCantStop, W("DbgExtraThreadsCantStop"), 0, "Allows extra unmanaged threads in can't stop region to run and throw debug events for stress testing")
CONFIG_DWORD_INFO(INTERNAL_DbgExtraThreadsIB, W("DbgExtraThreadsIB"), 0, "Allows extra in-band unmanaged threads to run and throw debug events for stress testing")
@@ -561,36 +562,21 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_GainExponent,
/// Tiered Compilation
///
#ifdef FEATURE_TIERED_COMPILATION
-#ifdef _DEBUG
-// Use lower values to exercise more paths sooner
-#define TC_BackgroundWorkerTimeoutMs (100)
-#define TC_CallCountThreshold (2)
-#define TC_CallCountingDelayMs (1)
-#define TC_DelaySingleProcMultiplier (2)
-#define TC_DeleteCallCountingStubsAfter (1)
-#else // !_DEBUG
-#define TC_BackgroundWorkerTimeoutMs (4000)
-#define TC_CallCountThreshold (30)
-#define TC_CallCountingDelayMs (100)
-#define TC_DelaySingleProcMultiplier (10)
-#define TC_DeleteCallCountingStubsAfter (4096)
-#endif // _DEBUG
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TieredCompilation, W("TieredCompilation"), 1, "Enables tiered compilation")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TC_QuickJit, W("TC_QuickJit"), 1, "For methods that would be jitted, enable using quick JIT when appropriate.")
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_QuickJitForLoops, W("TC_QuickJitForLoops"), 0, "When quick JIT is enabled, quick JIT may also be used for methods that contain loops.")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TC_AggressiveTiering, W("TC_AggressiveTiering"), 0, "Transition through tiers aggressively.")
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_BackgroundWorkerTimeoutMs, W("TC_BackgroundWorkerTimeoutMs"), TC_BackgroundWorkerTimeoutMs, "How long in milliseconds the background worker thread may remain idle before exiting.")
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCountThreshold, W("TC_CallCountThreshold"), TC_CallCountThreshold, "Number of times a method must be called in tier 0 after which it is promoted to the next tier.")
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCountingDelayMs, W("TC_CallCountingDelayMs"), TC_CallCountingDelayMs, "A perpetual delay in milliseconds that is applied call counting in tier 0 and jitting at higher tiers, while there is startup-like activity.")
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_DelaySingleProcMultiplier, W("TC_DelaySingleProcMultiplier"), TC_DelaySingleProcMultiplier, "Multiplier for TC_CallCountingDelayMs that is applied on a single-processor machine or when the process is affinitized to a single processor.")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_BackgroundWorkerTimeoutMs, W("TC_BackgroundWorkerTimeoutMs"), 4000, "How long in milliseconds the background worker thread may remain idle before exiting.")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCountThreshold, W("TC_CallCountThreshold"), 30, "Number of times a method must be called in tier 0 after which it is promoted to the next tier.")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCountingDelayMs, W("TC_CallCountingDelayMs"), 100, "A perpetual delay in milliseconds that is applied call counting in tier 0 and jitting at higher tiers, while there is startup-like activity.")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_DelaySingleProcMultiplier, W("TC_DelaySingleProcMultiplier"), 10, "Multiplier for TC_CallCountingDelayMs that is applied on a single-processor machine or when the process is affinitized to a single processor.")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCounting, W("TC_CallCounting"), 1, "Enabled by default (only activates when TieredCompilation is also enabled). If disabled immediately backpatches prestub, and likely prevents any promotion to higher tiers")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_UseCallCountingStubs, W("TC_UseCallCountingStubs"), 1, "Uses call counting stubs for faster call counting.")
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_DeleteCallCountingStubsAfter, W("TC_DeleteCallCountingStubsAfter"), TC_DeleteCallCountingStubsAfter, "Deletes call counting stubs after this many have completed. Zero to disable deleting.")
-#undef TC_BackgroundWorkerTimeoutMs
-#undef TC_CallCountThreshold
-#undef TC_CallCountingDelayMs
-#undef TC_DelaySingleProcMultiplier
-#undef TC_DeleteCallCountingStubsAfter
+#ifdef _DEBUG
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_DeleteCallCountingStubsAfter, W("TC_DeleteCallCountingStubsAfter"), 1, "Deletes call counting stubs after this many have completed. Zero to disable deleting.")
+#else
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_DeleteCallCountingStubsAfter, W("TC_DeleteCallCountingStubsAfter"), 4096, "Deletes call counting stubs after this many have completed. Zero to disable deleting.")
+#endif
#endif // FEATURE_TIERED_COMPILATION
///
diff --git a/src/coreclr/inc/clrtypes.h b/src/coreclr/inc/clrtypes.h
index 5e83573e7aa94..6050936814e6f 100644
--- a/src/coreclr/inc/clrtypes.h
+++ b/src/coreclr/inc/clrtypes.h
@@ -11,7 +11,7 @@
#ifndef CLRTYPES_H_
#define CLRTYPES_H_
-#if defined(_MSC_VER) && !defined(SOURCE_FORMATTING)
+#if defined(_MSC_VER) && !defined(SOURCE_FORMATTING) && defined(FEATURE_CORESYSTEM)
// Prefer intsafe.h when available, which defines many of the MAX/MIN
// values below (which is why they are in #ifndef blocks).
#include
diff --git a/src/coreclr/inc/dacvars.h b/src/coreclr/inc/dacvars.h
index 686c77217395e..fdae380a90cb4 100644
--- a/src/coreclr/inc/dacvars.h
+++ b/src/coreclr/inc/dacvars.h
@@ -5,7 +5,7 @@
// 1. in daccess.h to build the table of DAC globals
// 2. in enummem.cpp to dump out the related memory of static and globals
// in a mini dump or heap dump
-// 3. in DacUpdateDll and tools\DacTablenGen\main.cs
+// 3. in DacUpdateDll and toolbox\DacTablenGen\main.cs
//
// To use this functionality for other tools or purposes, define the
// DEFINE_DACVAR macro & include dacvars.h like so (see enummem.cpp and/or
diff --git a/src/coreclr/inc/holder.h b/src/coreclr/inc/holder.h
index 4ec7b106cc0e8..448610634a612 100644
--- a/src/coreclr/inc/holder.h
+++ b/src/coreclr/inc/holder.h
@@ -1152,14 +1152,7 @@ FORCEINLINE void HolderFreeLibrary(HMODULE h) { FreeLibrary(h); }
typedef Wrapper, HolderFreeLibrary, NULL> HModuleHolder;
template FORCEINLINE
-void DoLocalFree(T* pMem)
-{
-#ifdef HOST_WINDOWS
- (LocalFree)((void*)pMem);
-#else
- (free)((void*)pMem);
-#endif
-}
+void DoLocalFree(T* pMem) { (LocalFree)((HLOCAL)pMem); }
template
using LocalAllocHolder = SpecializedWrapper<_TYPE, DoLocalFree<_TYPE>>;
diff --git a/src/coreclr/inc/ostype.h b/src/coreclr/inc/ostype.h
index 78494c71c2b66..ddb0ec5d01b8e 100644
--- a/src/coreclr/inc/ostype.h
+++ b/src/coreclr/inc/ostype.h
@@ -31,6 +31,20 @@ extern RunningOnStatusEnum gRunningOnStatus;
void InitRunningOnVersionStatus();
+#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORESYSTEM)
+typedef enum
+{
+ WINRT_STATUS_UNINITED = 0,
+ WINRT_STATUS_UNSUPPORTED,
+ WINRT_STATUS_SUPPORTED
+}
+WinRTStatusEnum;
+
+extern WinRTStatusEnum gWinRTStatus;
+
+void InitWinRTStatus();
+#endif // FEATURE_COMINTEROP && !FEATURE_CORESYSTEM
+
//*****************************************************************************
// Returns true if you are running on Windows 8 or newer.
//*****************************************************************************
@@ -51,10 +65,28 @@ inline BOOL RunningOnWin8()
#ifdef FEATURE_COMINTEROP
+#ifdef FEATURE_CORESYSTEM
+
inline BOOL WinRTSupported()
{
return RunningOnWin8();
}
+#else
+inline BOOL WinRTSupported()
+{
+ STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_GC_NOTRIGGER;
+ STATIC_CONTRACT_CANNOT_TAKE_LOCK;
+
+
+ if (gWinRTStatus == WINRT_STATUS_UNINITED)
+ {
+ InitWinRTStatus();
+ }
+
+ return gWinRTStatus == WINRT_STATUS_SUPPORTED;
+}
+#endif // FEATURE_CORESYSTEM
#endif // FEATURE_COMINTEROP
diff --git a/src/coreclr/inc/sigparser.h b/src/coreclr/inc/sigparser.h
index b9b79e951e40b..1e861c4cd3edf 100644
--- a/src/coreclr/inc/sigparser.h
+++ b/src/coreclr/inc/sigparser.h
@@ -864,21 +864,6 @@ class CorTypeInfo
return (GetGCType_NoThrow(type) == TYPE_GC_REF);
}
- static BOOL IsByRef(CorElementType type)
- {
- WRAPPER_NO_CONTRACT;
- SUPPORTS_DAC;
-
- return (GetGCType(type) == TYPE_GC_BYREF);
- }
- static BOOL IsByRef_NoThrow(CorElementType type)
- {
- WRAPPER_NO_CONTRACT;
- SUPPORTS_DAC;
-
- return (GetGCType_NoThrow(type) == TYPE_GC_BYREF);
- }
-
FORCEINLINE static BOOL IsGenericVariable(CorElementType type)
{
WRAPPER_NO_CONTRACT;
diff --git a/src/coreclr/inc/switches.h b/src/coreclr/inc/switches.h
index 081299e7bfdbc..65cda94ed9900 100644
--- a/src/coreclr/inc/switches.h
+++ b/src/coreclr/inc/switches.h
@@ -165,7 +165,9 @@
#define FEATURE_DOUBLE_ALIGNMENT_HINT
#endif
+#if defined(FEATURE_CORESYSTEM)
#define FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
+#endif // defined(FEATURE_CORESYSTEM)
// If defined, support interpretation.
diff --git a/src/coreclr/inc/volatile.h b/src/coreclr/inc/volatile.h
index e127fe25f99b1..610a408f39fb6 100644
--- a/src/coreclr/inc/volatile.h
+++ b/src/coreclr/inc/volatile.h
@@ -73,10 +73,7 @@
#endif
#if defined(__GNUC__)
-#if defined(HOST_ARMV6)
-// DMB ISH not valid on ARMv6
-#define VOLATILE_MEMORY_BARRIER() asm volatile ("mcr p15, 0, r0, c7, c10, 5" : : : "memory")
-#elif defined(HOST_ARM) || defined(HOST_ARM64)
+#if defined(HOST_ARM) || defined(HOST_ARM64)
// This is functionally equivalent to the MemoryBarrier() macro used on ARM on Windows.
#define VOLATILE_MEMORY_BARRIER() asm volatile ("dmb ish" : : : "memory")
#else
diff --git a/src/coreclr/inc/vptr_list.h b/src/coreclr/inc/vptr_list.h
index d8e6cd42bd7c3..0fde8090d0699 100644
--- a/src/coreclr/inc/vptr_list.h
+++ b/src/coreclr/inc/vptr_list.h
@@ -23,6 +23,7 @@ VPTR_CLASS(ReflectionModule)
VPTR_CLASS(AppDomain)
VPTR_CLASS(SystemDomain)
+VPTR_CLASS(DomainAssembly)
VPTR_CLASS(PrecodeStubManager)
VPTR_CLASS(StubLinkStubManager)
VPTR_CLASS(ThePreStubManager)
@@ -38,6 +39,7 @@ VPTR_CLASS(DelegateInvokeStubManager)
VPTR_CLASS(TailCallStubManager)
#endif
VPTR_CLASS(CallCountingStubManager)
+VPTR_CLASS(PEAssembly)
VPTR_CLASS(PEImageLayout)
VPTR_CLASS(ConvertedImageLayout)
@@ -83,6 +85,9 @@ VPTR_CLASS(ExternalMethodFrame)
#ifdef FEATURE_READYTORUN
VPTR_CLASS(DynamicHelperFrame)
#endif
+#if defined(TARGET_X86)
+VPTR_CLASS(UMThkCallFrame)
+#endif
#if defined(TARGET_X86) && !defined(UNIX_X86_ABI)
VPTR_CLASS(TailCallFrame)
#endif
diff --git a/src/coreclr/inc/winwrap.h b/src/coreclr/inc/winwrap.h
index 0c1b7c22459ce..3bf11baea318b 100644
--- a/src/coreclr/inc/winwrap.h
+++ b/src/coreclr/inc/winwrap.h
@@ -188,11 +188,16 @@
#define WszWideCharToMultiByte WideCharToMultiByte
#define WszCreateSemaphore(_secattr, _count, _maxcount, _name) CreateSemaphoreExW((_secattr), (_count), (_maxcount), (_name), 0, MAXIMUM_ALLOWED | SYNCHRONIZE | SEMAPHORE_MODIFY_STATE)
+#ifdef FEATURE_CORESYSTEM
+
+// CoreSystem has GetFileVersionInfo{Size}Ex but not GetFileVersionInfoSize{Size}
#undef GetFileVersionInfo
#define GetFileVersionInfo(_filename, _handle, _len, _data) GetFileVersionInfoEx(0, (_filename), (_handle), (_len), (_data))
#undef GetFileVersionInfoSize
#define GetFileVersionInfoSize(_filename, _handle) GetFileVersionInfoSizeEx(0, (_filename), (_handle))
+#endif // FEATURE_CORESYSTEM
+
#ifndef _T
#define _T(str) W(str)
#endif
@@ -254,6 +259,12 @@ inline DWORD GetMaxDBCSCharByteSize()
#endif // HOST_UNIX
}
+#ifndef HOST_UNIX
+BOOL RunningInteractive();
+#else // !HOST_UNIX
+#define RunningInteractive() FALSE
+#endif // !HOST_UNIX
+
#ifndef Wsz_mbstowcs
#define Wsz_mbstowcs(szOut, szIn, iSize) WszMultiByteToWideChar(CP_ACP, 0, szIn, -1, szOut, iSize)
#endif
@@ -470,7 +481,11 @@ inline int LateboundMessageBoxA(HWND hWnd,
return LateboundMessageBoxW(hWnd, wszText, wszCaption, uType);
}
+#if defined(FEATURE_CORESYSTEM)
+
#define MessageBoxW LateboundMessageBoxW
#define MessageBoxA LateboundMessageBoxA
+#endif // FEATURE_CORESYSTEM
+
#endif // __WIN_WRAP_H__
diff --git a/src/coreclr/jit/CMakeLists.txt b/src/coreclr/jit/CMakeLists.txt
index ebca7e65daaac..c46cdd18a164e 100644
--- a/src/coreclr/jit/CMakeLists.txt
+++ b/src/coreclr/jit/CMakeLists.txt
@@ -32,9 +32,6 @@ function(create_standalone_jit)
elseif((TARGETDETAILS_ARCH STREQUAL "arm") OR (TARGETDETAILS_ARCH STREQUAL "armel"))
set(JIT_ARCH_SOURCES ${JIT_ARM_SOURCES})
set(JIT_ARCH_HEADERS ${JIT_ARM_HEADERS})
- elseif((TARGETDETAILS_ARCH STREQUAL "armv6") OR (TARGETDETAILS_ARCH STREQUAL "armv6l"))
- set(JIT_ARCH_SOURCES ${JIT_ARMV6_SOURCES})
- set(JIT_ARCH_HEADERS ${JIT_ARMV6_HEADERS})
elseif(TARGETDETAILS_ARCH STREQUAL "x86")
set(JIT_ARCH_SOURCES ${JIT_I386_SOURCES})
set(JIT_ARCH_HEADERS ${JIT_I386_HEADERS})
@@ -223,10 +220,6 @@ set( JIT_ARM64_SOURCES
hwintrinsiccodegenarm64.cpp
)
-set( JIT_ARMV6_SOURCES
- # Not supported as JIT target
-)
-
set( JIT_S390X_SOURCES
# Not supported as JIT target
)
@@ -369,10 +362,6 @@ set( JIT_ARM_HEADERS
registerarm.h
)
-set ( JIT_ARMV6_HEADERS
- # Not supported as JIT target
-)
-
set ( JIT_S390X_HEADERS
# Not supported as JIT target
)
@@ -391,8 +380,6 @@ convert_to_absolute_path(JIT_I386_SOURCES ${JIT_I386_SOURCES})
convert_to_absolute_path(JIT_I386_HEADERS ${JIT_I386_HEADERS})
convert_to_absolute_path(JIT_ARM64_SOURCES ${JIT_ARM64_SOURCES})
convert_to_absolute_path(JIT_ARM64_HEADERS ${JIT_ARM64_HEADERS})
-convert_to_absolute_path(JIT_ARMV6_SOURCES ${JIT_ARMV6_SOURCES})
-convert_to_absolute_path(JIT_ARMV6_HEADERS ${JIT_ARMV6_HEADERS})
convert_to_absolute_path(JIT_S390X_SOURCES ${JIT_S390X_SOURCES})
convert_to_absolute_path(JIT_S390X_HEADERS ${JIT_S390X_HEADERS})
@@ -402,9 +389,6 @@ if(CLR_CMAKE_TARGET_ARCH_AMD64)
elseif(CLR_CMAKE_TARGET_ARCH_ARM)
set(JIT_ARCH_SOURCES ${JIT_ARM_SOURCES})
set(JIT_ARCH_HEADERS ${JIT_ARM_HEADERS})
-elseif(CLR_CMAKE_TARGET_ARCH_ARMV6)
- set(JIT_ARCH_SOURCES ${JIT_ARMV6_SOURCES})
- set(JIT_ARCH_HEADERS ${JIT_ARMV6_HEADERS})
elseif(CLR_CMAKE_TARGET_ARCH_I386)
set(JIT_ARCH_SOURCES ${JIT_I386_SOURCES})
set(JIT_ARCH_HEADERS ${JIT_I386_HEADERS})
@@ -566,13 +550,13 @@ if (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX)
endif (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX)
if (CLR_CMAKE_TARGET_UNIX)
- if (NOT ARCH_TARGET_NAME STREQUAL s390x AND NOT ARCH_TARGET_NAME STREQUAL armv6)
+ if (NOT ARCH_TARGET_NAME STREQUAL s390x)
if(CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)
install_clr(TARGETS clrjit_universal_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} DESTINATIONS . COMPONENT jit)
else()
install_clr(TARGETS clrjit_unix_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} DESTINATIONS . COMPONENT jit)
endif()
- endif(NOT ARCH_TARGET_NAME STREQUAL s390x AND NOT ARCH_TARGET_NAME STREQUAL armv6)
+ endif(NOT ARCH_TARGET_NAME STREQUAL s390x)
endif()
if (CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_PGO_INSTRUMENT)
diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp
index 4e0e708be326c..51fad24772b47 100644
--- a/src/coreclr/jit/assertionprop.cpp
+++ b/src/coreclr/jit/assertionprop.cpp
@@ -2576,6 +2576,7 @@ void Compiler::optAssertionGen(GenTree* tree)
case GT_OBJ:
case GT_BLK:
+ case GT_DYN_BLK:
case GT_IND:
// R-value indirections create non-null assertions, but not all indirections are R-values.
// Those under ADDR nodes or on the LHS of ASGs are "locations", and will not end up
@@ -4625,9 +4626,9 @@ GenTree* Compiler::optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree,
case GT_OBJ:
case GT_BLK:
+ case GT_DYN_BLK:
case GT_IND:
case GT_NULLCHECK:
- case GT_STORE_DYN_BLK:
return optAssertionProp_Ind(assertions, tree, stmt);
case GT_BOUNDS_CHECK:
diff --git a/src/coreclr/jit/block.h b/src/coreclr/jit/block.h
index 81a511f4bceed..c5996ac8239d7 100644
--- a/src/coreclr/jit/block.h
+++ b/src/coreclr/jit/block.h
@@ -825,17 +825,6 @@ struct BasicBlock : private LIR::Range
BBswtDesc* bbJumpSwt; // switch descriptor
};
- bool KindIs(BBjumpKinds kind) const
- {
- return bbJumpKind == kind;
- }
-
- template
- bool KindIs(BBjumpKinds kind, T... rest) const
- {
- return KindIs(kind) || KindIs(rest...);
- }
-
// NumSucc() gives the number of successors, and GetSucc() returns a given numbered successor.
//
// There are two versions of these functions: ones that take a Compiler* and ones that don't. You must
diff --git a/src/coreclr/jit/codegenarm.cpp b/src/coreclr/jit/codegenarm.cpp
index 18cb59068bab3..9dd13cdc12533 100644
--- a/src/coreclr/jit/codegenarm.cpp
+++ b/src/coreclr/jit/codegenarm.cpp
@@ -82,7 +82,7 @@ bool CodeGen::genInstrWithConstant(
// generate two or more instructions
// first we load the immediate into tmpReg
- instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, imm);
+ instGen_Set_Reg_To_Imm(attr, tmpReg, imm);
// generate the instruction using a three register encoding with the immediate in tmpReg
GetEmitter()->emitIns_R_R_R(ins, attr, reg1, reg2, tmpReg);
diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp
index 595e2a232e541..250a23904944a 100644
--- a/src/coreclr/jit/codegenarm64.cpp
+++ b/src/coreclr/jit/codegenarm64.cpp
@@ -120,7 +120,7 @@ bool CodeGen::genInstrWithConstant(instruction ins,
// generate two or more instructions
// first we load the immediate into tmpReg
- instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, imm);
+ instGen_Set_Reg_To_Imm(size, tmpReg, imm);
regSet.verifyRegUsed(tmpReg);
// when we are in an unwind code region
@@ -6922,12 +6922,9 @@ void CodeGen::genArm64EmitterUnitTests()
#ifdef ALL_ARM64_EMITTER_UNIT_TESTS
//
- // R_R cmeq/fmov/fcmp/fcvt
+ // R_R fmov/fcmp/fcvt
//
- // cmeq scalar
- theEmitter->emitIns_R_R(INS_cmeq, EA_8BYTE, REG_V0, REG_V1);
-
// fmov to vector to vector
theEmitter->emitIns_Mov(INS_fmov, EA_8BYTE, REG_V0, REG_V2, /* canSkip */ false);
theEmitter->emitIns_Mov(INS_fmov, EA_4BYTE, REG_V1, REG_V3, /* canSkip */ false);
diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp
index 24c57d110b7ba..227de58aedc97 100644
--- a/src/coreclr/jit/codegenarmarch.cpp
+++ b/src/coreclr/jit/codegenarmarch.cpp
@@ -2416,7 +2416,7 @@ class CopyBlockUnrollHelper
const int dstOffsetAligned = AlignUp((UINT)dstOffset, storePairRegsAlignment);
- if (byteCount >= (unsigned)storePairRegsWritesBytes)
+ if (endDstOffset - dstOffsetAligned >= storePairRegsWritesBytes)
{
const int dstBytesToAlign = dstOffsetAligned - dstOffset;
@@ -2840,8 +2840,8 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
// When both addresses are not 16-byte aligned the CopyBlock instruction sequence starts with padding
// str instruction. For example, when both addresses are 8-byte aligned the instruction sequence looks like
//
- // ldr X_intReg1, [srcReg, #srcOffset]
- // str X_intReg1, [dstReg, #dstOffset]
+ // ldr D_simdReg1, [srcReg, #srcOffset]
+ // str D_simdReg1, [dstReg, #dstOffset]
// ldp Q_simdReg1, Q_simdReg2, [srcReg, #srcOffset+8]
// stp Q_simdReg1, Q_simdReg2, [dstReg, #dstOffset+8]
// ldp Q_simdReg1, Q_simdReg2, [srcReg, #srcOffset+40]
@@ -2853,7 +2853,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
// be profitable).
const bool canUse16ByteWideInstrs = isSrcRegAddrAlignmentKnown && isDstRegAddrAlignmentKnown &&
- (size >= 2 * FP_REGSIZE_BYTES) && (srcRegAddrAlignment == dstRegAddrAlignment);
+ (size >= FP_REGSIZE_BYTES) && (srcRegAddrAlignment == dstRegAddrAlignment);
bool shouldUse16ByteWideInstrs = false;
@@ -2876,7 +2876,8 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
{
// In order to use 16-byte instructions the JIT needs to adjust either srcOffset or dstOffset.
// The JIT should use 16-byte loads and stores when the resulting sequence (incl. an additional add
- // instruction) has fewer number of instructions.
+ // instruction)
+ // has fewer number of instructions.
if (helper.InstructionCount(FP_REGSIZE_BYTES) + 1 < helper.InstructionCount(REGSIZE_BYTES))
{
@@ -2936,31 +2937,51 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
const unsigned intRegCount = node->AvailableTempRegCount(RBM_ALLINT);
- if (intRegCount >= 2)
+ switch (intRegCount)
{
- intReg1 = node->ExtractTempReg(RBM_ALLINT);
- intReg2 = node->ExtractTempReg(RBM_ALLINT);
- }
- else if (intRegCount == 1)
- {
- intReg1 = node->GetSingleTempReg(RBM_ALLINT);
- intReg2 = rsGetRsvdReg();
+ case 1:
+ intReg1 = node->GetSingleTempReg(RBM_ALLINT);
+ break;
+ case 2:
+ intReg1 = node->ExtractTempReg(RBM_ALLINT);
+ intReg2 = node->GetSingleTempReg(RBM_ALLINT);
+ break;
+ default:
+ break;
}
- else
+
+ regNumber simdReg1 = REG_NA;
+ regNumber simdReg2 = REG_NA;
+
+ const unsigned simdRegCount = node->AvailableTempRegCount(RBM_ALLFLOAT);
+
+ switch (simdRegCount)
{
- intReg1 = rsGetRsvdReg();
+ case 1:
+ simdReg1 = node->GetSingleTempReg(RBM_ALLFLOAT);
+ break;
+ case 2:
+ simdReg1 = node->ExtractTempReg(RBM_ALLFLOAT);
+ simdReg2 = node->GetSingleTempReg(RBM_ALLFLOAT);
+ break;
+ default:
+ break;
}
if (shouldUse16ByteWideInstrs)
{
- const regNumber simdReg1 = node->ExtractTempReg(RBM_ALLFLOAT);
- const regNumber simdReg2 = node->GetSingleTempReg(RBM_ALLFLOAT);
-
helper.Unroll(FP_REGSIZE_BYTES, intReg1, simdReg1, simdReg2, srcReg, dstReg, GetEmitter());
}
else
{
- helper.UnrollBaseInstrs(intReg1, intReg2, srcReg, dstReg, GetEmitter());
+ if (intReg2 == REG_NA)
+ {
+ helper.Unroll(REGSIZE_BYTES, intReg1, simdReg1, simdReg2, srcReg, dstReg, GetEmitter());
+ }
+ else
+ {
+ helper.UnrollBaseInstrs(intReg1, intReg2, srcReg, dstReg, GetEmitter());
+ }
}
#endif // TARGET_ARM64
diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp
index fe8b2d82dcaec..7072e4fd66b0a 100644
--- a/src/coreclr/jit/codegencommon.cpp
+++ b/src/coreclr/jit/codegencommon.cpp
@@ -6236,9 +6236,15 @@ void CodeGen::genEnregisterOSRArgsAndLocals()
// This local was part of the live tier0 state and is enregistered in the
// OSR method. Initialize the register from the right frame slot.
//
+ // We currently don't expect to see enregistered multi-reg args in OSR methods,
+ // as struct promotion is disabled. So any struct arg just uses the location
+ // on the tier0 frame.
+ //
// If we ever enable promotion we'll need to generalize what follows to copy each
// field from the tier0 frame to its OSR home.
//
+ assert(!varDsc->lvIsMultiRegArg);
+
if (!VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex))
{
// This arg or local is not live at entry to the OSR method.
@@ -6385,31 +6391,16 @@ void CodeGen::genEnregisterOSRArgsAndLocals()
void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed)
{
- assert(compiler->compGeneratingProlog);
-
- const bool reportArg = compiler->lvaReportParamTypeArg();
-
+ // For OSR the original method has set this up for us.
if (compiler->opts.IsOSR())
{
- PatchpointInfo* const ppInfo = compiler->info.compPatchpointInfo;
- if (reportArg)
- {
- // OSR method will use Tier0 slot to report context arg.
- //
- assert(ppInfo->HasGenericContextArgOffset());
- JITDUMP("OSR method will use Tier0 frame slot for generics context arg.\n");
- }
- else if (compiler->lvaKeepAliveAndReportThis())
- {
- // OSR method will use Tier0 slot to report `this` as context.
- //
- assert(ppInfo->HasKeptAliveThis());
- JITDUMP("OSR method will use Tier0 frame slot for generics context `this`.\n");
- }
-
return;
}
+ assert(compiler->compGeneratingProlog);
+
+ bool reportArg = compiler->lvaReportParamTypeArg();
+
// We should report either generic context arg or "this" when used so.
if (!reportArg)
{
@@ -7552,16 +7543,6 @@ void CodeGen::genFnProlog()
#endif // PROFILING_SUPPORTED
- // For OSR we may have a zero-length prolog. That's not supported
- // when the method must report a generics context,/ so add a nop if so.
- //
- if (compiler->opts.IsOSR() && (GetEmitter()->emitGetPrologOffsetEstimate() == 0) &&
- (compiler->lvaReportParamTypeArg() || compiler->lvaKeepAliveAndReportThis()))
- {
- JITDUMP("OSR: prolog was zero length and has generic context to report: adding nop to pad prolog.\n");
- instGen(INS_nop);
- }
-
if (!GetInterruptible())
{
// The 'real' prolog ends here for non-interruptible methods.
diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp
index 009c0d9ad41dd..51e9afc074398 100644
--- a/src/coreclr/jit/codegenlinear.cpp
+++ b/src/coreclr/jit/codegenlinear.cpp
@@ -1657,7 +1657,7 @@ void CodeGen::genConsumeRegs(GenTree* tree)
#ifdef FEATURE_SIMD
// (In)Equality operation that produces bool result, when compared
// against Vector zero, marks its Vector Zero operand as contained.
- assert(tree->OperIsLeaf() || tree->IsSIMDZero() || tree->IsVectorZero());
+ assert(tree->OperIsLeaf() || tree->IsSIMDZero());
#else
assert(tree->OperIsLeaf());
#endif
@@ -1912,7 +1912,7 @@ void CodeGen::genSetBlockSize(GenTreeBlk* blkNode, regNumber sizeReg)
}
else
{
- GenTree* sizeNode = blkNode->AsStoreDynBlk()->gtDynamicSize;
+ GenTree* sizeNode = blkNode->AsDynBlk()->gtDynamicSize;
inst_Mov(sizeNode->TypeGet(), sizeReg, sizeNode->GetRegNum(), /* canSkip */ true);
}
}
@@ -2022,7 +2022,7 @@ void CodeGen::genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber
// in the case where the size is a constant (i.e. it is not GT_STORE_DYN_BLK).
if (blkNode->OperGet() == GT_STORE_DYN_BLK)
{
- genConsumeReg(blkNode->AsStoreDynBlk()->gtDynamicSize);
+ genConsumeReg(blkNode->AsDynBlk()->gtDynamicSize);
}
// Next, perform any necessary moves.
diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp
index cfc97dc6b1370..7da0bd7285625 100644
--- a/src/coreclr/jit/codegenxarch.cpp
+++ b/src/coreclr/jit/codegenxarch.cpp
@@ -1972,7 +1972,6 @@ void CodeGen::genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode)
inst_Mov(TYP_FLOAT, tempXmm, reg1, /* canSkip */ false);
GetEmitter()->emitIns_SIMD_R_R_R(INS_punpckldq, size, targetReg, targetReg, tempXmm);
}
- genProduceReg(lclNode);
}
#elif defined(TARGET_AMD64)
assert(!TargetOS::IsWindows || !"Multireg store to SIMD reg not supported on Windows x64");
diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp
index cf87223f71760..b8775857bb659 100644
--- a/src/coreclr/jit/compiler.cpp
+++ b/src/coreclr/jit/compiler.cpp
@@ -2644,19 +2644,15 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
verboseDump = (JitConfig.JitDumpTier0() > 0);
}
- // Optionally suppress dumping except for a specific OSR jit request.
+ // Optionally suppress dumping some OSR jit requests.
//
- const int dumpAtOSROffset = JitConfig.JitDumpAtOSROffset();
-
- if (verboseDump && (dumpAtOSROffset != -1))
+ if (verboseDump && jitFlags->IsSet(JitFlags::JIT_FLAG_OSR))
{
- if (jitFlags->IsSet(JitFlags::JIT_FLAG_OSR))
- {
- verboseDump = (((IL_OFFSET)dumpAtOSROffset) == info.compILEntry);
- }
- else
+ const int desiredOffset = JitConfig.JitDumpAtOSROffset();
+
+ if (desiredOffset != -1)
{
- verboseDump = false;
+ verboseDump = (((IL_OFFSET)desiredOffset) == info.compILEntry);
}
}
@@ -4636,7 +4632,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
// Run an early flow graph simplification pass
//
auto earlyUpdateFlowGraphPhase = [this]() {
- constexpr bool doTailDup = false;
+ const bool doTailDup = false;
fgUpdateFlowGraph(doTailDup);
};
DoPhase(this, PHASE_EARLY_UPDATE_FLOW_GRAPH, earlyUpdateFlowGraphPhase);
@@ -4776,10 +4772,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
// Unroll loops
//
DoPhase(this, PHASE_UNROLL_LOOPS, &Compiler::optUnrollLoops);
-
- // Clear loop table info that is not used after this point, and might become invalid.
- //
- DoPhase(this, PHASE_CLEAR_LOOP_INFO, &Compiler::optClearLoopIterInfo);
}
#ifdef DEBUG
@@ -4913,7 +4905,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
// update the flowgraph if we modified it during the optimization phase
//
auto optUpdateFlowGraphPhase = [this]() {
- constexpr bool doTailDup = false;
+ const bool doTailDup = false;
fgUpdateFlowGraph(doTailDup);
};
DoPhase(this, PHASE_OPT_UPDATE_FLOW_GRAPH, optUpdateFlowGraphPhase);
@@ -4970,6 +4962,11 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
//
DoPhase(this, PHASE_SIMPLE_LOWERING, &Compiler::fgSimpleLowering);
+#ifdef DEBUG
+ fgDebugCheckBBlist();
+ fgDebugCheckLinks();
+#endif
+
// Enable this to gather statistical data such as
// call and register argument info, flowgraph and loop info, etc.
compJitStats();
@@ -5020,6 +5017,10 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
// Copied from rpPredictRegUse()
SetFullPtrRegMapRequired(codeGen->GetInterruptible() || !codeGen->isFramePointerUsed());
+#ifdef DEBUG
+ fgDebugCheckLinks();
+#endif
+
#if FEATURE_LOOP_ALIGN
// Place loop alignment instructions
DoPhase(this, PHASE_ALIGN_LOOPS, &Compiler::placeLoopAlignInstructions);
@@ -5625,8 +5626,11 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr,
// Set this before the first 'BADCODE'
// Skip verification where possible
+ //.tiVerificationNeeded = !compileFlags->IsSet(JitFlags::JIT_FLAG_SKIP_VERIFICATION);
assert(compileFlags->IsSet(JitFlags::JIT_FLAG_SKIP_VERIFICATION));
+ assert(!compIsForInlining() || !tiVerificationNeeded); // Inlinees must have been verified.
+
/* Setup an error trap */
struct Param
@@ -6153,9 +6157,17 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
eeGetMethodFullName(info.compMethodHnd), dspPtr(impTokenLookupContextHandle)));
}
+ if (tiVerificationNeeded)
+ {
+ JITLOG((LL_INFO10000, "tiVerificationNeeded initially set to true for %s\n", info.compFullName));
+ }
#endif // DEBUG
- impCanReimport = compStressCompile(STRESS_CHK_REIMPORT, 15);
+ /* Since tiVerificationNeeded can be turned off in the middle of
+ compiling a method, and it might have caused blocks to be queued up
+ for reimporting, impCanReimport can be used to check for reimporting. */
+
+ impCanReimport = (tiVerificationNeeded || compStressCompile(STRESS_CHK_REIMPORT, 15));
/* Initialize set a bunch of global values */
@@ -6385,10 +6397,9 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
// Honor the config setting that tells the jit to
// always optimize methods with loops.
//
- // If neither of those apply, and OSR is enabled, the jit may still
+ // If that's not set, and OSR is enabled, the jit may still
// decide to optimize, if there's something in the method that
- // OSR currently cannot handle, or we're optionally suppressing
- // OSR by method hash.
+ // OSR currently cannot handle.
//
const char* reason = nullptr;
@@ -6396,42 +6407,35 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
{
reason = "tail.call and not BBINSTR";
}
- else if (compHasBackwardJump && ((info.compFlags & CORINFO_FLG_DISABLE_TIER0_FOR_LOOPS) != 0))
+ else if ((info.compFlags & CORINFO_FLG_DISABLE_TIER0_FOR_LOOPS) != 0)
{
- reason = "loop";
+ if (compHasBackwardJump)
+ {
+ reason = "loop";
+ }
}
-
- if (compHasBackwardJump && (reason == nullptr) && (JitConfig.TC_OnStackReplacement() > 0))
+ else if (JitConfig.TC_OnStackReplacement() > 0)
{
- const char* noPatchpointReason = nullptr;
- bool canEscapeViaOSR = compCanHavePatchpoints(&reason);
+ const bool patchpointsOK = compCanHavePatchpoints(&reason);
+ assert(patchpointsOK || (reason != nullptr));
#ifdef DEBUG
- if (canEscapeViaOSR)
+ // Optionally disable OSR by method hash.
+ //
+ if (patchpointsOK && compHasBackwardJump)
{
- // Optionally disable OSR by method hash. This will force any
- // method that might otherwise get trapped in Tier0 to be optimized.
- //
static ConfigMethodRange JitEnableOsrRange;
JitEnableOsrRange.EnsureInit(JitConfig.JitEnableOsrRange());
const unsigned hash = impInlineRoot()->info.compMethodHash();
if (!JitEnableOsrRange.Contains(hash))
{
- canEscapeViaOSR = false;
- reason = "OSR disabled by JitEnableOsrRange";
+ JITDUMP("Disabling OSR -- Method hash 0x%08x not within range ", hash);
+ JITDUMPEXEC(JitEnableOsrRange.Dump());
+ JITDUMP("\n");
+ reason = "OSR disabled by JitEnableOsrRange";
}
}
#endif
-
- if (canEscapeViaOSR)
- {
- JITDUMP("\nOSR enabled for this method\n");
- }
- else
- {
- JITDUMP("\nOSR disabled for this method: %s\n", noPatchpointReason);
- assert(reason != nullptr);
- }
}
if (reason != nullptr)
@@ -9381,6 +9385,7 @@ void cTreeFlags(Compiler* comp, GenTree* tree)
FALLTHROUGH;
case GT_BLK:
+ case GT_DYN_BLK:
case GT_STORE_BLK:
case GT_STORE_DYN_BLK:
@@ -9733,7 +9738,7 @@ bool Compiler::lvaIsOSRLocal(unsigned varNum)
//
void Compiler::gtChangeOperToNullCheck(GenTree* tree, BasicBlock* block)
{
- assert(tree->OperIs(GT_FIELD, GT_IND, GT_OBJ, GT_BLK));
+ assert(tree->OperIs(GT_FIELD, GT_IND, GT_OBJ, GT_BLK, GT_DYN_BLK));
tree->ChangeOper(GT_NULLCHECK);
tree->ChangeType(TYP_INT);
block->bbFlags |= BBF_HAS_NULLCHECK;
diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h
index 967d27eac4703..5a16ac8a58bf8 100644
--- a/src/coreclr/jit/compiler.h
+++ b/src/coreclr/jit/compiler.h
@@ -1735,7 +1735,7 @@ struct fgArgTabEntry
// In this case, it must be removed by GenTreeCall::ResetArgInfo.
bool isNonStandardArgAddedLate() const
{
- switch (static_cast(nonStandardArgKind))
+ switch (nonStandardArgKind)
{
case NonStandardArgKind::None:
case NonStandardArgKind::PInvokeFrame:
@@ -4844,7 +4844,7 @@ class Compiler
static LONG jitNestingLevel;
#endif // DEBUG
- static bool impIsAddressInLocal(const GenTree* tree, GenTree** lclVarTreeOut = nullptr);
+ static bool impIsAddressInLocal(const GenTree* tree, GenTree** lclVarTreeOut);
void impMakeDiscretionaryInlineObservations(InlineInfo* pInlineInfo, InlineResult* inlineResult);
@@ -5432,7 +5432,7 @@ class Compiler
// Requires that "tree" is a GT_IND marked as an array index, and that its address argument
// has been parsed to yield the other input arguments. If evaluation of the address
- // can raise exceptions, those should be captured in the exception set "addrXvnp".
+ // can raise exceptions, those should be captured in the exception set "excVN."
// Assumes that "elemTypeEq" is the (equivalence class rep) of the array element type.
// Marks "tree" with the VN for H[elemTypeEq][arrVN][inx][fldSeq] (for the liberal VN; a new unique
// VN for the conservative VN.) Also marks the tree's argument as the address of an array element.
@@ -5443,14 +5443,14 @@ class Compiler
CORINFO_CLASS_HANDLE elemTypeEq,
ValueNum arrVN,
ValueNum inxVN,
- ValueNumPair addrXvnp,
+ ValueNum excVN,
FieldSeqNode* fldSeq);
- // Requires "funcApp" to be a VNF_PtrToArrElem, and "addrXvnp" to represent the exception set thrown
+ // Requires "funcApp" to be a VNF_PtrToArrElem, and "addrXvn" to represent the exception set thrown
// by evaluating the array index expression "tree". Returns the value number resulting from
// dereferencing the array in the current GcHeap state. If "tree" is non-null, it must be the
// "GT_IND" that does the dereference, and it is given the returned value number.
- ValueNum fgValueNumberArrIndexVal(GenTree* tree, VNFuncApp* funcApp, ValueNumPair addrXvnp);
+ ValueNum fgValueNumberArrIndexVal(GenTree* tree, struct VNFuncApp* funcApp, ValueNum addrXvn);
// Compute the value number for a byref-exposed load of the given type via the given pointerVN.
ValueNum fgValueNumberByrefExposedLoad(var_types type, ValueNum pointerVN);
@@ -5560,10 +5560,6 @@ class Compiler
// Adds the exception sets for the current tree node
void fgValueNumberAddExceptionSet(GenTree* tree);
-#ifdef DEBUG
- void fgDebugCheckExceptionSets();
-#endif
-
// These are the current value number for the memory implicit variables while
// doing value numbering. These are the value numbers under the "liberal" interpretation
// of memory values; the "conservative" interpretation needs no VN, since every access of
@@ -5945,7 +5941,7 @@ class Compiler
bool fgReorderBlocks();
- PhaseStatus fgDetermineFirstColdBlock();
+ void fgDetermineFirstColdBlock();
bool fgIsForwardBranch(BasicBlock* bJump, BasicBlock* bSrc = nullptr);
@@ -6404,16 +6400,11 @@ class Compiler
GenTree* fgMorphGetStructAddr(GenTree** pTree, CORINFO_CLASS_HANDLE clsHnd, bool isRValue = false);
GenTree* fgMorphBlockOperand(GenTree* tree, var_types asgType, unsigned blockWidth, bool isBlkReqd);
GenTree* fgMorphCopyBlock(GenTree* tree);
- GenTree* fgMorphStoreDynBlock(GenTreeStoreDynBlk* tree);
GenTree* fgMorphForRegisterFP(GenTree* tree);
GenTree* fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac = nullptr);
GenTree* fgOptimizeCast(GenTreeCast* cast);
GenTree* fgOptimizeEqualityComparisonWithConst(GenTreeOp* cmp);
GenTree* fgOptimizeRelationalComparisonWithConst(GenTreeOp* cmp);
- GenTree* fgOptimizeCommutativeArithmetic(GenTreeOp* tree);
- GenTree* fgOptimizeAddition(GenTreeOp* add);
- GenTree* fgOptimizeMultiply(GenTreeOp* mul);
- GenTree* fgOptimizeBitwiseAnd(GenTreeOp* andOp);
GenTree* fgPropagateCommaThrow(GenTree* parent, GenTreeOp* commaThrow, GenTreeFlags precedingSideEffects);
GenTree* fgMorphRetInd(GenTreeUnOp* tree);
GenTree* fgMorphModToSubMulDiv(GenTreeOp* tree);
@@ -6424,7 +6415,7 @@ class Compiler
bool fgMorphCanUseLclFldForCopy(unsigned lclNum1, unsigned lclNum2);
GenTreeLclVar* fgMorphTryFoldObjAsLclVar(GenTreeObj* obj);
- GenTreeOp* fgMorphCommutative(GenTreeOp* tree);
+ GenTree* fgMorphCommutative(GenTreeOp* tree);
GenTree* fgMorphCastedBitwiseOp(GenTreeOp* tree);
GenTree* fgMorphReduceAddOps(GenTree* tree);
@@ -6740,12 +6731,6 @@ class Compiler
CALLINT_ALL, // kills everything (normal method call)
};
- enum class FieldKindForVN
- {
- SimpleStatic,
- WithBaseAddr
- };
-
public:
// A "LoopDsc" describes a ("natural") loop. We (currently) require the body of a loop to be a contiguous (in
// bbNext order) sequence of basic blocks. (At times, we may require the blocks in a loop to be "properly numbered"
@@ -6800,9 +6785,9 @@ class Compiler
int lpLoopVarFPCount; // The register count for the FP LclVars that are read/written inside this loop
int lpVarInOutFPCount; // The register count for the FP LclVars that are alive inside or across this loop
- typedef JitHashTable, FieldKindForVN>
- FieldHandleSet;
- FieldHandleSet* lpFieldsModified; // This has entries for all static field and object instance fields modified
+ typedef JitHashTable, bool> FieldHandleSet;
+ FieldHandleSet* lpFieldsModified; // This has entries (mappings to "true") for all static field and object
+ // instance fields modified
// in the loop.
typedef JitHashTable, bool> ClassHandleSet;
@@ -6813,7 +6798,7 @@ class Compiler
// Adds the variable liveness information for 'blk' to 'this' LoopDsc
void AddVariableLiveness(Compiler* comp, BasicBlock* blk);
- inline void AddModifiedField(Compiler* comp, CORINFO_FIELD_HANDLE fldHnd, FieldKindForVN fieldKind);
+ inline void AddModifiedField(Compiler* comp, CORINFO_FIELD_HANDLE fldHnd);
// This doesn't *always* take a class handle -- it can also take primitive types, encoded as class handles
// (shifted left, with a low-order bit set to distinguish.)
// Use the {Encode/Decode}ElemType methods to construct/destruct these.
@@ -6931,7 +6916,7 @@ class Compiler
}
#ifdef DEBUG
- void lpValidatePreHeader() const
+ void lpValidatePreHeader()
{
// If this is called, we expect there to be a pre-header.
assert(lpFlags & LPFLG_HAS_PREHEAD);
@@ -6992,8 +6977,6 @@ class Compiler
BasicBlock* exit,
unsigned char exitCnt);
- void optClearLoopIterInfo();
-
#ifdef DEBUG
void optPrintLoopInfo(unsigned lnum, bool printVerbose = false);
void optPrintLoopInfo(const LoopDsc* loop, bool printVerbose = false);
@@ -7062,7 +7045,7 @@ class Compiler
void AddVariableLivenessAllContainingLoops(unsigned lnum, BasicBlock* blk);
// Adds "fldHnd" to the set of modified fields of "lnum" and any parent loops.
- void AddModifiedFieldAllContainingLoops(unsigned lnum, CORINFO_FIELD_HANDLE fldHnd, FieldKindForVN fieldKind);
+ void AddModifiedFieldAllContainingLoops(unsigned lnum, CORINFO_FIELD_HANDLE fldHnd);
// Adds "elemType" to the set of modified array element types of "lnum" and any parent loops.
void AddModifiedElemTypeAllContainingLoops(unsigned lnum, CORINFO_CLASS_HANDLE elemType);
@@ -7122,6 +7105,12 @@ class Compiler
bool optNarrowTree(GenTree* tree, var_types srct, var_types dstt, ValueNumPair vnpNarrow, bool doit);
+ /**************************************************************************
+ * Optimization conditions
+ *************************************************************************/
+
+ bool optAvoidIntMult(void);
+
protected:
// The following is the upper limit on how many expressions we'll keep track
// of for the CSE analysis.
@@ -7381,11 +7370,14 @@ class Compiler
typedef ArrayStack GenTreePtrStack;
typedef JitHashTable, GenTreePtrStack*> LclNumToGenTreePtrStack;
+ // Kill set to track variables with intervening definitions.
+ VARSET_TP optCopyPropKillSet;
+
// Copy propagation functions.
- void optCopyProp(Statement* stmt, GenTreeLclVarCommon* tree, unsigned lclNum, LclNumToGenTreePtrStack* curSsaName);
+ void optCopyProp(BasicBlock* block, Statement* stmt, GenTree* tree, LclNumToGenTreePtrStack* curSsaName);
void optBlockCopyPropPopStacks(BasicBlock* block, LclNumToGenTreePtrStack* curSsaName);
void optBlockCopyProp(BasicBlock* block, LclNumToGenTreePtrStack* curSsaName);
- unsigned optIsSsaLocal(GenTreeLclVarCommon* lclNode);
+ unsigned optIsSsaLocal(GenTree* tree);
int optCopyProp_LclVarScore(LclVarDsc* lclVarDsc, LclVarDsc* copyVarDsc, bool preferOp2);
void optVnCopyProp();
INDEBUG(void optDumpCopyPropStack(LclNumToGenTreePtrStack* curSsaName));
@@ -8078,6 +8070,7 @@ class Compiler
CORINFO_RESOLVED_TOKEN* pConstrainedToken,
CORINFO_CALLINFO_FLAGS flags,
CORINFO_CALL_INFO* pResult);
+ inline CORINFO_CALLINFO_FLAGS addVerifyFlag(CORINFO_CALLINFO_FLAGS flags);
void eeGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_ACCESS_FLAGS flags,
@@ -10708,6 +10701,12 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
public:
+ // Set to true if verification cannot be skipped for this method
+ // CoreCLR does not ever run IL verification. Compile out the verifier from the JIT by making this a constant.
+ // TODO: Delete the verifier from the JIT? (https://github.com/dotnet/runtime/issues/32648)
+ // bool tiVerificationNeeded;
+ static const bool tiVerificationNeeded = false;
+
// Returns true if child is equal to or a subtype of parent for merge purposes
// This support is necessary to suport attributes that are not described in
// for example, signatures. For example, the permanent home byref (byref that
@@ -11491,14 +11490,42 @@ class GenTreeVisitor
break;
}
+ case GT_DYN_BLK:
+ {
+ GenTreeDynBlk* const dynBlock = node->AsDynBlk();
+
+ GenTree** op1Use = &dynBlock->gtOp1;
+ GenTree** op2Use = &dynBlock->gtDynamicSize;
+
+ result = WalkTree(op1Use, dynBlock);
+ if (result == fgWalkResult::WALK_ABORT)
+ {
+ return result;
+ }
+ result = WalkTree(op2Use, dynBlock);
+ if (result == fgWalkResult::WALK_ABORT)
+ {
+ return result;
+ }
+ break;
+ }
+
case GT_STORE_DYN_BLK:
{
- GenTreeStoreDynBlk* const dynBlock = node->AsStoreDynBlk();
+ GenTreeDynBlk* const dynBlock = node->AsDynBlk();
GenTree** op1Use = &dynBlock->gtOp1;
GenTree** op2Use = &dynBlock->gtOp2;
GenTree** op3Use = &dynBlock->gtDynamicSize;
+ if (TVisitor::UseExecutionOrder)
+ {
+ if (dynBlock->IsReverseOp())
+ {
+ std::swap(op1Use, op2Use);
+ }
+ }
+
result = WalkTree(op1Use, dynBlock);
if (result == fgWalkResult::WALK_ABORT)
{
diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp
index f03ecd43f7702..b75828d4cc68a 100644
--- a/src/coreclr/jit/compiler.hpp
+++ b/src/coreclr/jit/compiler.hpp
@@ -1986,18 +1986,13 @@ inline bool Compiler::lvaKeepAliveAndReportThis()
// the VM requires us to keep the generics context alive or it is used in a look-up.
// We keep it alive in the lookup scenario, even when the VM didn't ask us to,
// because collectible types need the generics context when gc-ing.
- //
- // Methoods that can inspire OSR methods must always report context as live
- //
if (genericsContextIsThis)
{
- const bool mustKeep = (info.compMethodInfo->options & CORINFO_GENERICS_CTXT_KEEP_ALIVE) != 0;
- const bool hasPatchpoint = doesMethodHavePatchpoints() || doesMethodHavePartialCompilationPatchpoints();
+ const bool mustKeep = (info.compMethodInfo->options & CORINFO_GENERICS_CTXT_KEEP_ALIVE) != 0;
- if (lvaGenericsContextInUse || mustKeep || hasPatchpoint)
+ if (lvaGenericsContextInUse || mustKeep)
{
- JITDUMP("Reporting this as generic context: %s\n",
- mustKeep ? "must keep" : (hasPatchpoint ? "patchpoints" : "referenced"));
+ JITDUMP("Reporting this as generic context: %s\n", mustKeep ? "must keep" : "referenced");
return true;
}
}
@@ -2029,13 +2024,6 @@ inline bool Compiler::lvaReportParamTypeArg()
{
return true;
}
-
- // Methoods that have patchpoints always report context as live
- //
- if (doesMethodHavePatchpoints() || doesMethodHavePartialCompilationPatchpoints())
- {
- return true;
- }
}
// Otherwise, we don't need to report it -- the generics context parameter is unused.
@@ -2355,29 +2343,29 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
inline unsigned Compiler::compMapILargNum(unsigned ILargNum)
{
- assert(ILargNum < info.compILargsCount);
+ assert(ILargNum < info.compILargsCount || tiVerificationNeeded);
// Note that this works because if compRetBuffArg/compTypeCtxtArg/lvVarargsHandleArg are not present
// they will be BAD_VAR_NUM (MAX_UINT), which is larger than any variable number.
if (ILargNum >= info.compRetBuffArg)
{
ILargNum++;
- assert(ILargNum < info.compLocalsCount); // compLocals count already adjusted.
+ assert(ILargNum < info.compLocalsCount || tiVerificationNeeded); // compLocals count already adjusted.
}
if (ILargNum >= (unsigned)info.compTypeCtxtArg)
{
ILargNum++;
- assert(ILargNum < info.compLocalsCount); // compLocals count already adjusted.
+ assert(ILargNum < info.compLocalsCount || tiVerificationNeeded); // compLocals count already adjusted.
}
if (ILargNum >= (unsigned)lvaVarargsHandleArg)
{
ILargNum++;
- assert(ILargNum < info.compLocalsCount); // compLocals count already adjusted.
+ assert(ILargNum < info.compLocalsCount || tiVerificationNeeded); // compLocals count already adjusted.
}
- assert(ILargNum < info.compArgsCount);
+ assert(ILargNum < info.compArgsCount || tiVerificationNeeded);
return (ILargNum);
}
@@ -3358,14 +3346,14 @@ inline void Compiler::optAssertionRemove(AssertionIndex index)
}
}
-inline void Compiler::LoopDsc::AddModifiedField(Compiler* comp, CORINFO_FIELD_HANDLE fldHnd, FieldKindForVN fieldKind)
+inline void Compiler::LoopDsc::AddModifiedField(Compiler* comp, CORINFO_FIELD_HANDLE fldHnd)
{
if (lpFieldsModified == nullptr)
{
lpFieldsModified =
new (comp->getAllocatorLoopHoist()) Compiler::LoopDsc::FieldHandleSet(comp->getAllocatorLoopHoist());
}
- lpFieldsModified->Set(fldHnd, fieldKind, FieldHandleSet::Overwrite);
+ lpFieldsModified->Set(fldHnd, true, FieldHandleSet::Overwrite);
}
inline void Compiler::LoopDsc::AddModifiedElemType(Compiler* comp, CORINFO_CLASS_HANDLE structHnd)
@@ -3578,6 +3566,22 @@ inline bool Compiler::LoopDsc::lpArrLenLimit(Compiler* comp, ArrIndex* index) co
return false;
}
+/*
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XX XX
+XX Optimization activation rules XX
+XX XX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+*/
+
+// should we try to replace integer multiplication with lea/add/shift sequences?
+inline bool Compiler::optAvoidIntMult(void)
+{
+ return (compCodeOpt() != SMALL_CODE);
+}
+
/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -4343,9 +4347,20 @@ void GenTree::VisitOperands(TVisitor visitor)
return;
}
+ case GT_DYN_BLK:
+ {
+ GenTreeDynBlk* const dynBlock = this->AsDynBlk();
+ if (visitor(dynBlock->gtOp1) == VisitResult::Abort)
+ {
+ return;
+ }
+ visitor(dynBlock->gtDynamicSize);
+ return;
+ }
+
case GT_STORE_DYN_BLK:
{
- GenTreeStoreDynBlk* const dynBlock = this->AsStoreDynBlk();
+ GenTreeDynBlk* const dynBlock = this->AsDynBlk();
if (visitor(dynBlock->gtOp1) == VisitResult::Abort)
{
return;
@@ -4501,12 +4516,11 @@ inline static bool StructHasNoPromotionFlagSet(DWORD attribs)
return ((attribs & CORINFO_FLG_DONT_PROMOTE) != 0);
}
-//------------------------------------------------------------------------------
-// DEBUG_DESTROY_NODE: sets value of tree to garbage to catch extra references
-//
-// Arguments:
-// tree: This node should not be referenced by anyone now
-//
+/*****************************************************************************
+ * This node should not be referenced by anyone now. Set its values to garbage
+ * to catch extra references
+ */
+
inline void DEBUG_DESTROY_NODE(GenTree* tree)
{
#ifdef DEBUG
@@ -4527,19 +4541,6 @@ inline void DEBUG_DESTROY_NODE(GenTree* tree)
#endif
}
-//------------------------------------------------------------------------------
-// DEBUG_DESTROY_NODE: sets value of trees to garbage to catch extra references
-//
-// Arguments:
-// tree, ...rest: These nodes should not be referenced by anyone now
-//
-template
-void DEBUG_DESTROY_NODE(GenTree* tree, T... rest)
-{
- DEBUG_DESTROY_NODE(tree);
- DEBUG_DESTROY_NODE(rest...);
-}
-
//------------------------------------------------------------------------------
// lvRefCnt: access reference count for this local var
//
diff --git a/src/coreclr/jit/compphases.h b/src/coreclr/jit/compphases.h
index 8f72dcce2360c..e5c15c1d438a6 100644
--- a/src/coreclr/jit/compphases.h
+++ b/src/coreclr/jit/compphases.h
@@ -5,7 +5,7 @@
//
//
-// Names of JIT phases, in order. Assumes that the caller defines CompPhaseNameMacro
+// Names of x86 JIT phases, in order. Assumes that the caller defines CompPhaseNameMacro
// in a useful way before including this file, e.g., to define the phase enumeration and the
// corresponding array of string names of those phases. This include file undefines CompPhaseNameMacro
// after the last use.
@@ -61,7 +61,6 @@ CompPhaseNameMacro(PHASE_ZERO_INITS, "Redundant zero Inits",
CompPhaseNameMacro(PHASE_FIND_LOOPS, "Find loops", "LOOP-FND", false, -1, false)
CompPhaseNameMacro(PHASE_CLONE_LOOPS, "Clone loops", "LP-CLONE", false, -1, false)
CompPhaseNameMacro(PHASE_UNROLL_LOOPS, "Unroll loops", "UNROLL", false, -1, false)
-CompPhaseNameMacro(PHASE_CLEAR_LOOP_INFO, "Clear loop info", "LP-CLEAR", false, -1, false)
CompPhaseNameMacro(PHASE_HOIST_LOOP_CODE, "Hoist loop code", "LP-HOIST", false, -1, false)
CompPhaseNameMacro(PHASE_MARK_LOCAL_VARS, "Mark local vars", "MARK-LCL", false, -1, false)
CompPhaseNameMacro(PHASE_OPTIMIZE_BOOLS, "Optimize bools", "OPT-BOOL", false, -1, false)
@@ -87,6 +86,7 @@ CompPhaseNameMacro(PHASE_INSERT_GC_POLLS, "Insert GC Polls",
CompPhaseNameMacro(PHASE_DETERMINE_FIRST_COLD_BLOCK, "Determine first cold block", "COLD-BLK", false, -1, true)
CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR", "RAT", false, -1, false)
CompPhaseNameMacro(PHASE_SIMPLE_LOWERING, "Do 'simple' lowering", "SMP-LWR", false, -1, false)
+CompPhaseNameMacro(PHASE_ALIGN_LOOPS, "Place 'align' instructions", "LOOP-ALIGN", false, -1, false)
CompPhaseNameMacro(PHASE_LCLVARLIVENESS, "Local var liveness", "LIVENESS", true, -1, false)
CompPhaseNameMacro(PHASE_LCLVARLIVENESS_INIT, "Local var liveness init", "LIV-INIT", false, PHASE_LCLVARLIVENESS, false)
@@ -100,7 +100,6 @@ CompPhaseNameMacro(PHASE_LINEAR_SCAN, "Linear scan register alloc",
CompPhaseNameMacro(PHASE_LINEAR_SCAN_BUILD, "LSRA build intervals", "LSRA-BLD", false, PHASE_LINEAR_SCAN, false)
CompPhaseNameMacro(PHASE_LINEAR_SCAN_ALLOC, "LSRA allocate", "LSRA-ALL", false, PHASE_LINEAR_SCAN, false)
CompPhaseNameMacro(PHASE_LINEAR_SCAN_RESOLVE, "LSRA resolve", "LSRA-RES", false, PHASE_LINEAR_SCAN, false)
-CompPhaseNameMacro(PHASE_ALIGN_LOOPS, "Place 'align' instructions", "LOOP-ALIGN", false, -1, false)
CompPhaseNameMacro(PHASE_GENERATE_CODE, "Generate code", "CODEGEN", false, -1, false)
CompPhaseNameMacro(PHASE_EMIT_CODE, "Emit code", "EMIT", false, -1, false)
CompPhaseNameMacro(PHASE_EMIT_GCEH, "Emit GC+EH tables", "EMT-GCEH", false, -1, false)
diff --git a/src/coreclr/jit/copyprop.cpp b/src/coreclr/jit/copyprop.cpp
index 52c765a12dc41..1c80436902f90 100644
--- a/src/coreclr/jit/copyprop.cpp
+++ b/src/coreclr/jit/copyprop.cpp
@@ -32,16 +32,17 @@ void Compiler::optBlockCopyPropPopStacks(BasicBlock* block, LclNumToGenTreePtrSt
{
for (GenTree* const tree : stmt->TreeList())
{
- GenTreeLclVarCommon* lclDefNode = nullptr;
- if (tree->OperIs(GT_ASG) && tree->DefinesLocal(this, &lclDefNode))
+ if (!tree->IsLocal())
+ {
+ continue;
+ }
+ const unsigned lclNum = optIsSsaLocal(tree);
+ if (lclNum == BAD_VAR_NUM)
+ {
+ continue;
+ }
+ if (tree->gtFlags & GTF_VAR_DEF)
{
- const unsigned lclNum = optIsSsaLocal(lclDefNode);
-
- if (lclNum == BAD_VAR_NUM)
- {
- continue;
- }
-
GenTreePtrStack* stack = nullptr;
curSsaName->Lookup(lclNum, &stack);
stack->Pop();
@@ -122,67 +123,97 @@ int Compiler::optCopyProp_LclVarScore(LclVarDsc* lclVarDsc, LclVarDsc* copyVarDs
// definitions share the same value number. If so, then we can make the replacement.
//
// Arguments:
+// block - Block the tree belongs to
// stmt - Statement the tree belongs to
-// tree - The local tree to perform copy propagation on
-// lclNum - The local number of said tree
+// tree - The tree to perform copy propagation on
// curSsaName - The map from lclNum to its recently live definitions as a stack
-void Compiler::optCopyProp(Statement* stmt,
- GenTreeLclVarCommon* tree,
- unsigned lclNum,
- LclNumToGenTreePtrStack* curSsaName)
+void Compiler::optCopyProp(BasicBlock* block, Statement* stmt, GenTree* tree, LclNumToGenTreePtrStack* curSsaName)
{
- assert((lclNum != BAD_VAR_NUM) && (optIsSsaLocal(tree) == lclNum) && ((tree->gtFlags & GTF_VAR_DEF) == 0));
+ // TODO-Review: EH successor/predecessor iteration seems broken.
+ if (block->bbCatchTyp == BBCT_FINALLY || block->bbCatchTyp == BBCT_FAULT)
+ {
+ return;
+ }
+
+ // If not local nothing to do.
+ if (!tree->IsLocal())
+ {
+ return;
+ }
+ if (tree->OperGet() == GT_PHI_ARG || tree->OperGet() == GT_LCL_FLD)
+ {
+ return;
+ }
+
+ // Propagate only on uses.
+ if (tree->gtFlags & GTF_VAR_DEF)
+ {
+ return;
+ }
+ const unsigned lclNum = optIsSsaLocal(tree);
+
+ // Skip non-SSA variables.
+ if (lclNum == BAD_VAR_NUM)
+ {
+ return;
+ }
+
assert(tree->gtVNPair.GetConservative() != ValueNumStore::NoVN);
for (LclNumToGenTreePtrStack::KeyIterator iter = curSsaName->Begin(); !iter.Equal(curSsaName->End()); ++iter)
{
unsigned newLclNum = iter.Get();
+ GenTree* op = iter.GetValue()->Top();
+
// Nothing to do if same.
if (lclNum == newLclNum)
{
continue;
}
- LclVarDsc* varDsc = lvaGetDesc(lclNum);
- LclVarDsc* newLclVarDsc = lvaGetDesc(newLclNum);
- GenTree* newLclDefNode = iter.GetValue()->Top(); // Note that this "def" node can actually be a use (for
- // parameters and other use-before-def locals).
+ // Skip variables with assignments embedded in the statement (i.e., with a comma). Because we
+ // are not currently updating their SSA names as live in the copy-prop pass of the stmt.
+ if (VarSetOps::IsMember(this, optCopyPropKillSet, lvaTable[newLclNum].lvVarIndex))
+ {
+ continue;
+ }
// Do not copy propagate if the old and new lclVar have different 'doNotEnregister' settings.
// This is primarily to avoid copy propagating to IND(ADDR(LCL_VAR)) where the replacement lclVar
// is not marked 'lvDoNotEnregister'.
// However, in addition, it may not be profitable to propagate a 'doNotEnregister' lclVar to an
// existing use of an enregisterable lclVar.
- if (varDsc->lvDoNotEnregister != newLclVarDsc->lvDoNotEnregister)
+
+ if (lvaTable[lclNum].lvDoNotEnregister != lvaTable[newLclNum].lvDoNotEnregister)
{
continue;
}
- if ((gsShadowVarInfo != nullptr) && newLclVarDsc->lvIsParam &&
- (gsShadowVarInfo[newLclNum].shadowCopy == lclNum))
+ if (op->gtFlags & GTF_VAR_CAST)
{
continue;
}
-
- ValueNum newLclDefVN = GetUseAsgDefVNOrTreeVN(newLclDefNode);
- if (newLclDefVN == ValueNumStore::NoVN)
+ if (gsShadowVarInfo != nullptr && lvaTable[newLclNum].lvIsParam &&
+ gsShadowVarInfo[newLclNum].shadowCopy == lclNum)
{
continue;
}
-
- if (newLclDefNode->TypeGet() != tree->TypeGet())
+ ValueNum opVN = GetUseAsgDefVNOrTreeVN(op);
+ if (opVN == ValueNumStore::NoVN)
{
continue;
}
-
- if (newLclDefVN != tree->gtVNPair.GetConservative())
+ if (op->TypeGet() != tree->TypeGet())
{
continue;
}
-
- if (optCopyProp_LclVarScore(varDsc, newLclVarDsc, true) <= 0)
+ if (opVN != tree->gtVNPair.GetConservative())
+ {
+ continue;
+ }
+ if (optCopyProp_LclVarScore(lvaGetDesc(lclNum), lvaGetDesc(newLclNum), true) <= 0)
{
continue;
}
@@ -199,25 +230,34 @@ void Compiler::optCopyProp(Statement* stmt,
// node x2 = phi(x0, x1) which can then be used to substitute 'c' with. But because of pruning
// there would be no such phi node. To solve this we'll check if 'x' is live, before replacing
// 'c' with 'x.'
+ if (!lvaTable[newLclNum].lvVerTypeInfo.IsThisPtr())
+ {
+ if (lvaTable[newLclNum].IsAddressExposed())
+ {
+ continue;
+ }
- // We compute liveness only on tracked variables. And all SSA locals are tracked.
- assert(lvaGetDesc(newLclNum)->lvTracked);
+ // We compute liveness only on tracked variables. So skip untracked locals.
+ if (!lvaTable[newLclNum].lvTracked)
+ {
+ continue;
+ }
- // Because of this dependence on live variable analysis, CopyProp phase is immediately
- // after Liveness, SSA and VN.
- if ((newLclNum != info.compThisArg) && !VarSetOps::IsMember(this, compCurLife, newLclVarDsc->lvVarIndex))
- {
- continue;
+ // Because of this dependence on live variable analysis, CopyProp phase is immediately
+ // after Liveness, SSA and VN.
+ if (!VarSetOps::IsMember(this, compCurLife, lvaTable[newLclNum].lvVarIndex))
+ {
+ continue;
+ }
}
-
unsigned newSsaNum = SsaConfig::RESERVED_SSA_NUM;
- if (newLclDefNode->gtFlags & GTF_VAR_DEF)
+ if (op->gtFlags & GTF_VAR_DEF)
{
- newSsaNum = GetSsaNumForLocalVarDef(newLclDefNode);
+ newSsaNum = GetSsaNumForLocalVarDef(op);
}
else // parameters, this pointer etc.
{
- newSsaNum = newLclDefNode->AsLclVarCommon()->GetSsaNum();
+ newSsaNum = op->AsLclVarCommon()->GetSsaNum();
}
if (newSsaNum == SsaConfig::RESERVED_SSA_NUM)
@@ -231,42 +271,48 @@ void Compiler::optCopyProp(Statement* stmt,
JITDUMP("VN based copy assertion for ");
printTreeID(tree);
printf(" V%02d " FMT_VN " by ", lclNum, tree->GetVN(VNK_Conservative));
- printTreeID(newLclDefNode);
- printf(" V%02d " FMT_VN ".\n", newLclNum, newLclDefNode->GetVN(VNK_Conservative));
- DISPNODE(tree);
+ printTreeID(op);
+ printf(" V%02d " FMT_VN ".\n", newLclNum, op->GetVN(VNK_Conservative));
+ gtDispTree(tree, nullptr, nullptr, true);
}
#endif
tree->AsLclVarCommon()->SetLclNum(newLclNum);
tree->AsLclVarCommon()->SetSsaNum(newSsaNum);
gtUpdateSideEffects(stmt, tree);
-
#ifdef DEBUG
if (verbose)
{
printf("copy propagated to:\n");
- DISPNODE(tree);
+ gtDispTree(tree, nullptr, nullptr, true);
}
#endif
break;
}
+ return;
}
//------------------------------------------------------------------------------
// optIsSsaLocal : helper to check if the tree is a local that participates in SSA numbering.
//
// Arguments:
-// lclNode - The local tree to perform the check on;
+// tree - The tree to perform the check on;
//
// Returns:
// - lclNum if the local is participating in SSA;
// - fieldLclNum if the parent local can be replaced by its only field;
// - BAD_VAR_NUM otherwise.
//
-unsigned Compiler::optIsSsaLocal(GenTreeLclVarCommon* lclNode)
+unsigned Compiler::optIsSsaLocal(GenTree* tree)
{
- unsigned lclNum = lclNode->GetLclNum();
- LclVarDsc* varDsc = lvaGetDesc(lclNum);
+ if (!tree->IsLocal())
+ {
+ return BAD_VAR_NUM;
+ }
+
+ GenTreeLclVarCommon* lclNode = tree->AsLclVarCommon();
+ unsigned lclNum = lclNode->GetLclNum();
+ LclVarDsc* varDsc = lvaGetDesc(lclNum);
if (!lvaInSsa(lclNum) && varDsc->CanBeReplacedWithItsField(this))
{
@@ -309,63 +355,68 @@ void Compiler::optBlockCopyProp(BasicBlock* block, LclNumToGenTreePtrStack* curS
VarSetOps::Assign(this, compCurLife, block->bbLiveIn);
for (Statement* const stmt : block->Statements())
{
+ VarSetOps::ClearD(this, optCopyPropKillSet);
+
// Walk the tree to find if any local variable can be replaced with current live definitions.
- // Simultaneously, push live definitions on the stack - that logic must be in sync with the
- // SSA renaming process.
for (GenTree* const tree : stmt->TreeList())
{
treeLifeUpdater.UpdateLife(tree);
- GenTreeLclVarCommon* lclDefNode = nullptr;
- if (tree->OperIs(GT_ASG) && tree->DefinesLocal(this, &lclDefNode))
+ optCopyProp(block, stmt, tree, curSsaName);
+
+ // TODO-Review: Merge this loop with the following loop to correctly update the
+ // live SSA num while also propagating copies.
+ //
+ // 1. This loop performs copy prop with currently live (on-top-of-stack) SSA num.
+ // 2. The subsequent loop maintains a stack for each lclNum with
+ // currently active SSA numbers when definitions are encountered.
+ //
+ // If there is an embedded definition using a "comma" in a stmt, then the currently
+ // live SSA number will get updated only in the next loop (2). However, this new
+ // definition is now supposed to be live (on tos). If we did not update the stacks
+ // using (2), copy prop (1) will use a SSA num defined outside the stmt ignoring the
+ // embedded update. Killing the variable is a simplification to produce 0 ASM diffs
+ // for an update release.
+ //
+ const unsigned lclNum = optIsSsaLocal(tree);
+ if ((lclNum != BAD_VAR_NUM) && (tree->gtFlags & GTF_VAR_DEF))
{
- const unsigned lclNum = optIsSsaLocal(lclDefNode);
+ VarSetOps::AddElemD(this, optCopyPropKillSet, lvaTable[lclNum].lvVarIndex);
+ }
+ }
- if (lclNum == BAD_VAR_NUM)
- {
- continue;
- }
+ // This logic must be in sync with SSA renaming process.
+ for (GenTree* const tree : stmt->TreeList())
+ {
+ const unsigned lclNum = optIsSsaLocal(tree);
+ if (lclNum == BAD_VAR_NUM)
+ {
+ continue;
+ }
+ // As we encounter a definition add it to the stack as a live definition.
+ if (tree->gtFlags & GTF_VAR_DEF)
+ {
GenTreePtrStack* stack;
if (!curSsaName->Lookup(lclNum, &stack))
{
stack = new (curSsaName->GetAllocator()) GenTreePtrStack(curSsaName->GetAllocator());
}
- stack->Push(lclDefNode);
+ stack->Push(tree);
curSsaName->Set(lclNum, stack, LclNumToGenTreePtrStack::Overwrite);
}
- // TODO-CQ: propagate on LCL_FLDs too.
- else if (tree->OperIs(GT_LCL_VAR) && ((tree->gtFlags & GTF_VAR_DEF) == 0))
+ // If we encounter first use of a param or this pointer add it as a live definition.
+ // Since they are always live, do it only once.
+ else if ((tree->gtOper == GT_LCL_VAR) && !(tree->gtFlags & GTF_VAR_USEASG) &&
+ (lvaTable[lclNum].lvIsParam || lvaTable[lclNum].lvVerTypeInfo.IsThisPtr()))
{
- const unsigned lclNum = optIsSsaLocal(tree->AsLclVarCommon());
-
- if (lclNum == BAD_VAR_NUM)
- {
- continue;
- }
-
- // If we encounter first use of a param or this pointer add it as a live definition.
- // Since they are always live, we'll do it only once.
- if (lvaGetDesc(lclNum)->lvIsParam || (lclNum == info.compThisArg))
- {
- GenTreePtrStack* stack;
- if (!curSsaName->Lookup(lclNum, &stack))
- {
- assert(tree->AsLclVarCommon()->GetSsaNum() == SsaConfig::FIRST_SSA_NUM);
-
- stack = new (curSsaName->GetAllocator()) GenTreePtrStack(curSsaName->GetAllocator());
- stack->Push(tree);
- curSsaName->Set(lclNum, stack);
- }
- }
-
- // TODO-Review: EH successor/predecessor iteration seems broken.
- if ((block->bbCatchTyp == BBCT_FINALLY) || (block->bbCatchTyp == BBCT_FAULT))
+ GenTreePtrStack* stack;
+ if (!curSsaName->Lookup(lclNum, &stack))
{
- continue;
+ stack = new (curSsaName->GetAllocator()) GenTreePtrStack(curSsaName->GetAllocator());
+ stack->Push(tree);
+ curSsaName->Set(lclNum, stack);
}
-
- optCopyProp(stmt, tree->AsLclVarCommon(), lclNum, curSsaName);
}
}
}
@@ -411,6 +462,7 @@ void Compiler::optVnCopyProp()
}
VarSetOps::AssignNoCopy(this, compCurLife, VarSetOps::MakeEmpty(this));
+ VarSetOps::AssignNoCopy(this, optCopyPropKillSet, VarSetOps::MakeEmpty(this));
class CopyPropDomTreeVisitor : public DomTreeVisitor
{
diff --git a/src/coreclr/jit/earlyprop.cpp b/src/coreclr/jit/earlyprop.cpp
index 283c9c8901ae7..f00b3f6e3ad6e 100644
--- a/src/coreclr/jit/earlyprop.cpp
+++ b/src/coreclr/jit/earlyprop.cpp
@@ -110,7 +110,7 @@ void Compiler::optCheckFlagsAreSet(unsigned methodFlag,
if ((basicBlock->bbFlags & bbFlag) == 0)
{
printf("%s is not set on " FMT_BB " but is required because of the following tree \n", bbFlagStr,
- basicBlock->bbNum);
+ compCurBB->bbNum);
gtDispTree(tree);
assert(false);
}
diff --git a/src/coreclr/jit/ee_il_dll.hpp b/src/coreclr/jit/ee_il_dll.hpp
index 337ca8f147977..33d5fab12ac5b 100644
--- a/src/coreclr/jit/ee_il_dll.hpp
+++ b/src/coreclr/jit/ee_il_dll.hpp
@@ -294,3 +294,11 @@ inline CORINFO_CALLINFO_FLAGS combine(CORINFO_CALLINFO_FLAGS flag1, CORINFO_CALL
{
return (CORINFO_CALLINFO_FLAGS)(flag1 | flag2);
}
+inline CORINFO_CALLINFO_FLAGS Compiler::addVerifyFlag(CORINFO_CALLINFO_FLAGS flags)
+{
+ if (tiVerificationNeeded)
+ {
+ flags = combine(flags, CORINFO_CALLINFO_VERIFICATION);
+ }
+ return flags;
+}
diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h
index 66706ecaf488e..47daad7798fc2 100644
--- a/src/coreclr/jit/emit.h
+++ b/src/coreclr/jit/emit.h
@@ -614,15 +614,6 @@ class emitter
assert((ins != INS_invalid) && (ins < INS_count));
_idIns = ins;
}
- bool idInsIs(instruction ins) const
- {
- return idIns() == ins;
- }
- template
- bool idInsIs(instruction ins, T... rest) const
- {
- return idInsIs(ins) || idInsIs(rest...);
- }
insFormat idInsFmt() const
{
@@ -2883,12 +2874,19 @@ inline unsigned emitter::emitGetInsCIargs(instrDesc* id)
/* static */ emitAttr emitter::emitGetMemOpSize(instrDesc* id)
{
emitAttr defaultSize = id->idOpSize();
-
+ emitAttr newSize = defaultSize;
switch (id->idIns())
{
+ case INS_vextractf128:
+ case INS_vextracti128:
+ case INS_vinsertf128:
+ case INS_vinserti128:
+ {
+ return EA_16BYTE;
+ }
+
case INS_pextrb:
case INS_pinsrb:
- case INS_vpbroadcastb:
{
return EA_1BYTE;
}
@@ -2896,142 +2894,27 @@ inline unsigned emitter::emitGetInsCIargs(instrDesc* id)
case INS_pextrw:
case INS_pextrw_sse41:
case INS_pinsrw:
- case INS_pmovsxbq:
- case INS_pmovzxbq:
- case INS_vpbroadcastw:
{
return EA_2BYTE;
}
- case INS_addss:
- case INS_cmpss:
- case INS_comiss:
- case INS_cvtss2sd:
- case INS_cvtss2si:
- case INS_cvttss2si:
- case INS_divss:
case INS_extractps:
case INS_insertps:
- case INS_maxss:
- case INS_minss:
- case INS_movss:
- case INS_mulss:
case INS_pextrd:
case INS_pinsrd:
- case INS_pmovsxbd:
- case INS_pmovsxwq:
- case INS_pmovzxbd:
- case INS_pmovzxwq:
- case INS_rcpss:
- case INS_roundss:
- case INS_rsqrtss:
- case INS_sqrtss:
- case INS_subss:
- case INS_ucomiss:
- case INS_vbroadcastss:
- case INS_vfmadd132ss:
- case INS_vfmadd213ss:
- case INS_vfmadd231ss:
- case INS_vfmsub132ss:
- case INS_vfmsub213ss:
- case INS_vfmsub231ss:
- case INS_vfnmadd132ss:
- case INS_vfnmadd213ss:
- case INS_vfnmadd231ss:
- case INS_vfnmsub132ss:
- case INS_vfnmsub213ss:
- case INS_vfnmsub231ss:
- case INS_vpbroadcastd:
{
return EA_4BYTE;
}
- case INS_addsd:
- case INS_cmpsd:
- case INS_comisd:
- case INS_cvtsd2si:
- case INS_cvtsd2ss:
- case INS_cvttsd2si:
- case INS_divsd:
- case INS_maxsd:
- case INS_minsd:
- case INS_movhpd:
- case INS_movhps:
- case INS_movlpd:
- case INS_movlps:
- case INS_movq:
- case INS_movsd:
- case INS_mulsd:
case INS_pextrq:
case INS_pinsrq:
- case INS_pmovsxbw:
- case INS_pmovsxdq:
- case INS_pmovsxwd:
- case INS_pmovzxbw:
- case INS_pmovzxdq:
- case INS_pmovzxwd:
- case INS_roundsd:
- case INS_sqrtsd:
- case INS_subsd:
- case INS_ucomisd:
- case INS_vbroadcastsd:
- case INS_vfmadd132sd:
- case INS_vfmadd213sd:
- case INS_vfmadd231sd:
- case INS_vfmsub132sd:
- case INS_vfmsub213sd:
- case INS_vfmsub231sd:
- case INS_vfnmadd132sd:
- case INS_vfnmadd213sd:
- case INS_vfnmadd231sd:
- case INS_vfnmsub132sd:
- case INS_vfnmsub213sd:
- case INS_vfnmsub231sd:
- case INS_vpbroadcastq:
{
return EA_8BYTE;
}
- case INS_cvtdq2pd:
- case INS_cvtps2pd:
- {
- if (defaultSize == 32)
- {
- return EA_16BYTE;
- }
- else
- {
- assert(defaultSize == 16);
- return EA_8BYTE;
- }
- }
-
- case INS_vbroadcastf128:
- case INS_vbroadcasti128:
- case INS_vextractf128:
- case INS_vextracti128:
- case INS_vinsertf128:
- case INS_vinserti128:
- {
- return EA_16BYTE;
- }
-
- case INS_movddup:
- {
- if (defaultSize == 32)
- {
- return EA_32BYTE;
- }
- else
- {
- assert(defaultSize == 16);
- return EA_8BYTE;
- }
- }
-
default:
{
- return defaultSize;
+ return id->idOpSize();
}
}
}
diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp
index 52f24d4524279..51e02c5c26895 100644
--- a/src/coreclr/jit/emitarm64.cpp
+++ b/src/coreclr/jit/emitarm64.cpp
@@ -4732,19 +4732,19 @@ void emitter::emitIns_R_R(
assert(isVectorRegister(reg1));
assert(isVectorRegister(reg2));
- if (insOptsAnyArrangement(opt))
+ if (isValidVectorDatasize(size))
{
// Vector operation
- assert(isValidVectorDatasize(size));
+ assert(insOptsAnyArrangement(opt));
assert(isValidArrangement(size, opt));
elemsize = optGetElemsize(opt);
fmt = IF_DV_2M;
}
else
{
+ NYI("Untested");
// Scalar operation
- assert(size == EA_8BYTE);
- assert(insOptsNone(opt));
+ assert(size == EA_8BYTE); // Only Double supported
fmt = IF_DV_2L;
}
break;
@@ -12971,11 +12971,6 @@ void emitter::emitDispIns(
emitDispVectorReg(id->idReg1(), id->idInsOpt(), true);
emitDispVectorReg(id->idReg2(), id->idInsOpt(), false);
}
- if (ins == INS_fcmeq)
- {
- printf(", ");
- emitDispImm(0, false);
- }
break;
case IF_DV_2P: // DV_2P ................ ......nnnnnddddd Vd Vn (aes*, sha1su1)
@@ -12995,11 +12990,6 @@ void emitter::emitDispIns(
emitDispVectorReg(id->idReg1(), id->idInsOpt(), true);
emitDispVectorReg(id->idReg2(), id->idInsOpt(), false);
}
- if (ins == INS_cmeq)
- {
- printf(", ");
- emitDispImm(0, false);
- }
break;
case IF_DV_2N: // DV_2N .........iiiiiii ......nnnnnddddd Vd Vn imm (shift - scalar)
@@ -13136,11 +13126,6 @@ void emitter::emitDispIns(
emitDispReg(id->idReg1(), size, true);
emitDispReg(id->idReg2(), size, false);
}
- if (fmt == IF_DV_2L && ins == INS_cmeq)
- {
- printf(", ");
- emitDispImm(0, false);
- }
break;
case IF_DV_2H: // DV_2H X........X...... ......nnnnnddddd Rd Vn (fmov, fcvtXX - to general)
@@ -15629,11 +15614,6 @@ bool emitter::IsMovInstruction(instruction ins)
// mov Rx, Ry # <-- last instruction
// mov Ry, Rx # <-- current instruction can be omitted.
//
-// 4. Move that does zero extension while previous instruction already did it
-//
-// ldr Wx, [Ry] # <-- ldr will clear upper 4 byte of Wx
-// mov Wx, Wx # <-- clears upper 4 byte in Wx
-//
// Arguments:
// ins - The current instruction
// size - Operand size of current instruction
@@ -15660,8 +15640,6 @@ bool emitter::IsRedundantMov(instruction ins, emitAttr size, regNumber dst, regN
return false;
}
- const bool isFirstInstrInBlock = (emitCurIGinsCnt == 0) && ((emitCurIG->igFlags & IGF_EXTEND) == 0);
-
if (dst == src)
{
// A mov with a EA_4BYTE has the side-effect of clearing the upper bits
@@ -15677,18 +15655,10 @@ bool emitter::IsRedundantMov(instruction ins, emitAttr size, regNumber dst, regN
JITDUMP("\n -- suppressing mov because src and dst is same 16-byte register.\n");
return true;
}
- else if (isGeneralRegisterOrSP(dst) && (size == EA_4BYTE))
- {
- // See if the previous instruction already cleared upper 4 bytes for us unintentionally
- if (!isFirstInstrInBlock && (emitLastIns != nullptr) && (emitLastIns->idReg1() == dst) &&
- (emitLastIns->idOpSize() == size) && emitLastIns->idInsIs(INS_ldr, INS_ldrh, INS_ldrb))
- {
- JITDUMP("\n -- suppressing mov because ldr already cleared upper 4 bytes\n");
- return true;
- }
- }
}
+ bool isFirstInstrInBlock = (emitCurIGinsCnt == 0) && ((emitCurIG->igFlags & IGF_EXTEND) == 0);
+
if (!isFirstInstrInBlock && // Don't optimize if instruction is not the first instruction in IG.
(emitLastIns != nullptr) &&
(emitLastIns->idIns() == INS_mov) && // Don't optimize if last instruction was not 'mov'.
diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp
index d90c5771ce1a9..1075c4ccd97d0 100644
--- a/src/coreclr/jit/emitxarch.cpp
+++ b/src/coreclr/jit/emitxarch.cpp
@@ -8965,8 +8965,9 @@ void emitter::emitDispIns(
}
else
{
- attr = id->idOpSize();
- sstr = codeGen->genSizeStr(emitGetMemOpSize(id));
+ attr = emitGetMemOpSize(id);
+
+ sstr = codeGen->genSizeStr(attr);
if (ins == INS_lea)
{
@@ -11742,6 +11743,17 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
#ifdef DEBUG
int byteSize = EA_SIZE_IN_BYTES(emitGetMemOpSize(id));
+ // this instruction has a fixed size (4) src.
+ if (ins == INS_cvttss2si || ins == INS_cvtss2sd || ins == INS_vbroadcastss)
+ {
+ byteSize = 4;
+ }
+ // This has a fixed size (8) source.
+ if (ins == INS_vbroadcastsd)
+ {
+ byteSize = 8;
+ }
+
// Check that the offset is properly aligned (i.e. the ddd in [ddd])
// When SMALL_CODE is set, we only expect 4-byte alignment, otherwise
// we expect the same alignment as the size of the constant.
diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h
index 5cef7d5aa12f2..d6ed324deb242 100644
--- a/src/coreclr/jit/emitxarch.h
+++ b/src/coreclr/jit/emitxarch.h
@@ -193,7 +193,7 @@ bool IsDstDstSrcAVXInstruction(instruction ins);
bool IsDstSrcSrcAVXInstruction(instruction ins);
bool HasRegularWideForm(instruction ins);
bool HasRegularWideImmediateForm(instruction ins);
-static bool DoesWriteZeroFlag(instruction ins);
+bool DoesWriteZeroFlag(instruction ins);
bool DoesWriteSignFlag(instruction ins);
bool DoesResetOverflowAndCarryFlags(instruction ins);
bool IsFlagsAlwaysModified(instrDesc* id);
diff --git a/src/coreclr/jit/error.cpp b/src/coreclr/jit/error.cpp
index dfb5a859b4300..1845af97b5731 100644
--- a/src/coreclr/jit/error.cpp
+++ b/src/coreclr/jit/error.cpp
@@ -258,7 +258,11 @@ void debugError(const char* msg, const char* file, unsigned line)
// If ComPlus_JitRequired is 0 or is not set, we will not assert.
if (JitConfig.JitRequired() == 1 || getBreakOnBadCode())
{
- assertAbort(msg, file, line);
+ // Don't assert if verification is done.
+ if (!env->compiler->tiVerificationNeeded || getBreakOnBadCode())
+ {
+ assertAbort(msg, file, line);
+ }
}
BreakIfDebuggerPresent();
diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp
index 7f8bd7b01c6d0..73695932cb543 100644
--- a/src/coreclr/jit/fgbasic.cpp
+++ b/src/coreclr/jit/fgbasic.cpp
@@ -321,7 +321,7 @@ bool Compiler::fgFirstBBisScratch()
// Normally, the first scratch block is a fall-through block. However, if the block after it was an empty
// BBJ_ALWAYS block, it might get removed, and the code that removes it will make the first scratch block
// a BBJ_ALWAYS block.
- assert(fgFirstBBScratch->KindIs(BBJ_NONE, BBJ_ALWAYS));
+ assert((fgFirstBBScratch->bbJumpKind == BBJ_NONE) || (fgFirstBBScratch->bbJumpKind == BBJ_ALWAYS));
return true;
}
@@ -1113,12 +1113,12 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
{
ni = lookupNamedIntrinsic(methodHnd);
- bool foldableIntrinsic = false;
+ bool foldableIntrinsc = false;
if (IsMathIntrinsic(ni))
{
// Most Math(F) intrinsics have single arguments
- foldableIntrinsic = FgStack::IsConstantOrConstArg(pushedStack.Top(), impInlineInfo);
+ foldableIntrinsc = FgStack::IsConstantOrConstArg(pushedStack.Top(), impInlineInfo);
}
else
{
@@ -1131,7 +1131,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
case NI_System_GC_KeepAlive:
{
pushedStack.PushUnknown();
- foldableIntrinsic = true;
+ foldableIntrinsc = true;
break;
}
@@ -1145,20 +1145,6 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
break;
}
- case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant:
- if (FgStack::IsConstArgument(pushedStack.Top(), impInlineInfo))
- {
- compInlineResult->Note(InlineObservation::CALLEE_CONST_ARG_FEEDS_ISCONST);
- }
- else
- {
- compInlineResult->Note(InlineObservation::CALLEE_ARG_FEEDS_ISCONST);
- }
- // RuntimeHelpers.IsKnownConstant is always folded into a const
- pushedStack.PushConstant();
- foldableIntrinsic = true;
- break;
-
// These are foldable if the first argument is a constant
case NI_System_Type_get_IsValueType:
case NI_System_Type_GetTypeFromHandle:
@@ -1173,10 +1159,10 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
case NI_Vector128_Create:
#endif
{
- // Top() in order to keep it as is in case of foldableIntrinsic
+ // Top() in order to keep it as is in case of foldableIntrinsc
if (FgStack::IsConstantOrConstArg(pushedStack.Top(), impInlineInfo))
{
- foldableIntrinsic = true;
+ foldableIntrinsc = true;
}
break;
}
@@ -1191,7 +1177,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
if (FgStack::IsConstantOrConstArg(pushedStack.Top(0), impInlineInfo) &&
FgStack::IsConstantOrConstArg(pushedStack.Top(1), impInlineInfo))
{
- foldableIntrinsic = true;
+ foldableIntrinsc = true;
pushedStack.PushConstant();
}
break;
@@ -1200,31 +1186,31 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
case NI_IsSupported_True:
case NI_IsSupported_False:
{
- foldableIntrinsic = true;
+ foldableIntrinsc = true;
pushedStack.PushConstant();
break;
}
#if defined(TARGET_XARCH) && defined(FEATURE_HW_INTRINSICS)
case NI_Vector128_get_Count:
case NI_Vector256_get_Count:
- foldableIntrinsic = true;
+ foldableIntrinsc = true;
pushedStack.PushConstant();
// TODO: check if it's a loop condition - we unroll such loops.
break;
case NI_Vector256_get_Zero:
case NI_Vector256_get_AllBitsSet:
- foldableIntrinsic = true;
+ foldableIntrinsc = true;
pushedStack.PushUnknown();
break;
#elif defined(TARGET_ARM64) && defined(FEATURE_HW_INTRINSICS)
case NI_Vector64_get_Count:
case NI_Vector128_get_Count:
- foldableIntrinsic = true;
+ foldableIntrinsc = true;
pushedStack.PushConstant();
break;
case NI_Vector128_get_Zero:
case NI_Vector128_get_AllBitsSet:
- foldableIntrinsic = true;
+ foldableIntrinsc = true;
pushedStack.PushUnknown();
break;
#endif
@@ -1236,7 +1222,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed
}
}
- if (foldableIntrinsic)
+ if (foldableIntrinsc)
{
compInlineResult->Note(InlineObservation::CALLSITE_FOLDABLE_INTRINSIC);
handled = true;
@@ -2229,7 +2215,7 @@ void Compiler::fgAdjustForAddressExposedOrWrittenThis()
LclVarDsc* thisVarDsc = lvaGetDesc(info.compThisArg);
// Optionally enable adjustment during stress.
- if (compStressCompile(STRESS_GENERIC_VARN, 15))
+ if (!tiVerificationNeeded && compStressCompile(STRESS_GENERIC_VARN, 15))
{
thisVarDsc->lvHasILStoreOp = true;
}
@@ -2421,7 +2407,7 @@ void Compiler::fgLinkBasicBlocks()
/* Is the next block reachable? */
- if (curBBdesc->KindIs(BBJ_ALWAYS, BBJ_LEAVE))
+ if (curBBdesc->bbJumpKind == BBJ_ALWAYS || curBBdesc->bbJumpKind == BBJ_LEAVE)
{
break;
}
@@ -3516,6 +3502,9 @@ void Compiler::fgFindBasicBlocks()
#endif // !FEATURE_EH_FUNCLETS
+#ifndef DEBUG
+ if (tiVerificationNeeded)
+#endif
{
// always run these checks for a debug build
verCheckNestingLevel(initRoot);
@@ -3524,7 +3513,7 @@ void Compiler::fgFindBasicBlocks()
#ifndef DEBUG
// fgNormalizeEH assumes that this test has been passed. And Ssa assumes that fgNormalizeEHTable
// has been run. So do this unless we're in minOpts mode (and always in debug).
- if (!opts.MinOpts())
+ if (tiVerificationNeeded || !opts.MinOpts())
#endif
{
fgCheckBasicBlockControlFlow();
@@ -4380,7 +4369,7 @@ BasicBlock* Compiler::fgSplitBlockAtBeginning(BasicBlock* curr)
BasicBlock* Compiler::fgSplitEdge(BasicBlock* curr, BasicBlock* succ)
{
- assert(curr->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_ALWAYS));
+ assert(curr->bbJumpKind == BBJ_COND || curr->bbJumpKind == BBJ_SWITCH || curr->bbJumpKind == BBJ_ALWAYS);
if (fgComputePredsDone)
{
@@ -4549,7 +4538,7 @@ void Compiler::fgRemoveBlock(BasicBlock* block, bool unreachable)
BasicBlock* bPrev = block->bbPrev;
- JITDUMP("fgRemoveBlock " FMT_BB ", unreachable=%s\n", block->bbNum, dspBool(unreachable));
+ JITDUMP("fgRemoveBlock " FMT_BB "\n", block->bbNum);
// If we've cached any mappings from switch blocks to SwitchDesc's (which contain only the
// *unique* successors of the switch block), invalidate that cache, since an entry in one of
@@ -4573,6 +4562,12 @@ void Compiler::fgRemoveBlock(BasicBlock* block, bool unreachable)
fgUnreachableBlock(block);
+ /* If this is the last basic block update fgLastBB */
+ if (block == fgLastBB)
+ {
+ fgLastBB = bPrev;
+ }
+
#if defined(FEATURE_EH_FUNCLETS)
// If block was the fgFirstFuncletBB then set fgFirstFuncletBB to block->bbNext
if (block == fgFirstFuncletBB)
@@ -4625,7 +4620,7 @@ void Compiler::fgRemoveBlock(BasicBlock* block, bool unreachable)
leaveBlk->bbRefs = 0;
leaveBlk->bbPreds = nullptr;
- fgRemoveBlock(leaveBlk, /* unreachable */ true);
+ fgRemoveBlock(leaveBlk, true);
#if defined(FEATURE_EH_FUNCLETS) && defined(TARGET_ARM)
fgClearFinallyTargetBit(leaveBlk->bbJumpDest);
@@ -4675,7 +4670,7 @@ void Compiler::fgRemoveBlock(BasicBlock* block, bool unreachable)
}
#endif // DEBUG
- noway_assert(block->KindIs(BBJ_NONE, BBJ_ALWAYS));
+ noway_assert(block->bbJumpKind == BBJ_NONE || block->bbJumpKind == BBJ_ALWAYS);
/* Who is the "real" successor of this block? */
@@ -5187,7 +5182,7 @@ bool Compiler::fgIsForwardBranch(BasicBlock* bJump, BasicBlock* bSrc /* = NULL *
{
bool result = false;
- if (bJump->KindIs(BBJ_COND, BBJ_ALWAYS))
+ if ((bJump->bbJumpKind == BBJ_COND) || (bJump->bbJumpKind == BBJ_ALWAYS))
{
BasicBlock* bDest = bJump->bbJumpDest;
BasicBlock* bTemp = (bSrc == nullptr) ? bJump : bSrc;
@@ -5804,7 +5799,7 @@ bool Compiler::fgIsBetterFallThrough(BasicBlock* bCur, BasicBlock* bAlt)
noway_assert(bAlt != nullptr);
// We only handle the cases when bAlt is a BBJ_ALWAYS or a BBJ_COND
- if (!bAlt->KindIs(BBJ_ALWAYS, BBJ_COND))
+ if ((bAlt->bbJumpKind != BBJ_ALWAYS) && (bAlt->bbJumpKind != BBJ_COND))
{
return false;
}
diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp
index 2df6d000419b9..7fd7b5d562563 100644
--- a/src/coreclr/jit/fgdiagnostic.cpp
+++ b/src/coreclr/jit/fgdiagnostic.cpp
@@ -2151,11 +2151,11 @@ void Compiler::fgTableDispBasicBlock(BasicBlock* block, int ibcColWidth /* = 0 *
{
if (block == fgEntryBB)
{
- printf(" original-entry");
+ printf("original-entry");
}
if (block == fgOSREntryBB)
{
- printf(" osr-entry");
+ printf("osr-entry");
}
}
@@ -2503,7 +2503,7 @@ bool BBPredsChecker::CheckEhTryDsc(BasicBlock* block, BasicBlock* blockPred, EHb
bool BBPredsChecker::CheckEhHndDsc(BasicBlock* block, BasicBlock* blockPred, EHblkDsc* ehHndlDsc)
{
// You can do a BBJ_EHFINALLYRET or BBJ_EHFILTERRET into a handler region
- if (blockPred->KindIs(BBJ_EHFINALLYRET, BBJ_EHFILTERRET))
+ if ((blockPred->bbJumpKind == BBJ_EHFINALLYRET) || (blockPred->bbJumpKind == BBJ_EHFILTERRET))
{
return true;
}
@@ -3534,22 +3534,12 @@ void Compiler::fgDebugCheckNodesUniqueness()
// - If the method has natural loops, the loop table is not null
// - Loop `top` must come before `bottom`.
// - Loop `entry` must be between `top` and `bottom`.
-// - Children loops of a loop are disjoint.
// - All basic blocks with loop numbers set have a corresponding loop in the table
// - All basic blocks without a loop number are not in a loop
// - All parents of the loop with the block contain that block
-// - If the loop has a pre-header, it is valid
-// - The loop flags are valid
//
void Compiler::fgDebugCheckLoopTable()
{
-#ifdef DEBUG
- if (verbose)
- {
- printf("*************** In fgDebugCheckLoopTable\n");
- }
-#endif // DEBUG
-
if (optLoopCount > 0)
{
assert(optLoopTable != nullptr);
@@ -3665,38 +3655,8 @@ void Compiler::fgDebugCheckLoopTable()
assert(loop.lpExit == nullptr);
}
- if (loop.lpParent == BasicBlock::NOT_IN_LOOP)
+ if (loop.lpParent != BasicBlock::NOT_IN_LOOP)
{
- // This is a top-level loop.
-
- // Verify all top-level loops are disjoint. We don't have a list of just these (such as a
- // top-level pseudo-loop entry with a list of all top-level lists), so we have to iterate
- // over the entire loop table.
- for (unsigned j = 0; j < optLoopCount; j++)
- {
- if (i == j)
- {
- // Don't compare against ourselves.
- continue;
- }
- const LoopDsc& otherLoop = optLoopTable[j];
- if (otherLoop.lpFlags & LPFLG_REMOVED)
- {
- continue;
- }
- if (otherLoop.lpParent != BasicBlock::NOT_IN_LOOP)
- {
- // Only consider top-level loops
- continue;
- }
- assert(MappedChecks::lpDisjoint(blockNumMap, &loop, otherLoop));
- }
- }
- else
- {
- // This is not a top-level loop
-
- assert(loop.lpParent != BasicBlock::NOT_IN_LOOP);
assert(loop.lpParent < optLoopCount);
assert(loop.lpParent < i); // outer loops come before inner loops in the table
const LoopDsc& parentLoop = optLoopTable[loop.lpParent];
@@ -3714,12 +3674,10 @@ void Compiler::fgDebugCheckLoopTable()
assert(child < optLoopCount);
assert(i < child); // outer loops come before inner loops in the table
const LoopDsc& childLoop = optLoopTable[child];
- if (childLoop.lpFlags & LPFLG_REMOVED) // removed child loop might still be in table
+ if ((childLoop.lpFlags & LPFLG_REMOVED) == 0) // removed child loop might still be in table
{
- continue;
+ assert(MappedChecks::lpContains(blockNumMap, &loop, childLoop));
}
- assert(MappedChecks::lpContains(blockNumMap, &loop, childLoop));
- assert(childLoop.lpParent == i);
}
// Verify all child loops are disjoint.
@@ -3776,43 +3734,6 @@ void Compiler::fgDebugCheckLoopTable()
assert(MappedChecks::lpContains(blockNumMap, &loop, predBlock));
}
}
-
- loop.lpValidatePreHeader();
- }
-
- // Check the flags.
- // Note that the various init/limit flags are only used when LPFLG_ITER is set, but they are set first,
- // separately, and only if everything works out is LPFLG_ITER set. If LPFLG_ITER is NOT set, the
- // individual flags are not un-set (arguably, they should be).
-
- // Only one of the `init` flags can be set.
- assert(genCountBits((unsigned)(loop.lpFlags & (LPFLG_VAR_INIT | LPFLG_CONST_INIT))) <= 1);
-
- // Only one of the `limit` flags can be set. (Note that LPFLG_SIMD_LIMIT is a "sub-flag" that can be
- // set when LPFLG_CONST_LIMIT is set.)
- assert(genCountBits((unsigned)(loop.lpFlags & (LPFLG_VAR_LIMIT | LPFLG_CONST_LIMIT | LPFLG_ARRLEN_LIMIT))) <=
- 1);
-
- // LPFLG_SIMD_LIMIT can only be set if LPFLG_CONST_LIMIT is set.
- if (loop.lpFlags & LPFLG_SIMD_LIMIT)
- {
- assert(loop.lpFlags & LPFLG_CONST_LIMIT);
- }
-
- if (loop.lpFlags & (LPFLG_CONST_INIT | LPFLG_VAR_INIT))
- {
- assert(loop.lpInitBlock != nullptr);
-
- if (loop.lpFlags & LPFLG_VAR_INIT)
- {
- assert(loop.lpVarInit < lvaCount);
- }
- }
-
- if (loop.lpFlags & LPFLG_ITER)
- {
- loop.VERIFY_lpIterTree();
- loop.VERIFY_lpTestTree();
}
}
diff --git a/src/coreclr/jit/fgehopt.cpp b/src/coreclr/jit/fgehopt.cpp
index 514b6879a9f6b..4fa511f63dbdd 100644
--- a/src/coreclr/jit/fgehopt.cpp
+++ b/src/coreclr/jit/fgehopt.cpp
@@ -175,7 +175,7 @@ PhaseStatus Compiler::fgRemoveEmptyFinally()
nextBlock = leaveBlock->bbNext;
leaveBlock->bbFlags &= ~BBF_KEEP_BBJ_ALWAYS;
- fgRemoveBlock(leaveBlock, /* unreachable */ true);
+ fgRemoveBlock(leaveBlock, true);
// Cleanup the postTryFinallyBlock
fgCleanupContinuation(postTryFinallyBlock);
@@ -194,8 +194,8 @@ PhaseStatus Compiler::fgRemoveEmptyFinally()
firstBlock->bbRefs = 0;
// Remove the handler block.
+ const bool unreachable = true;
firstBlock->bbFlags &= ~BBF_DONT_REMOVE;
- constexpr bool unreachable = true;
fgRemoveBlock(firstBlock, unreachable);
// Find enclosing try region for the try, if any, and update
@@ -1181,7 +1181,7 @@ PhaseStatus Compiler::fgCloneFinally()
nextBlock = leaveBlock->bbNext;
leaveBlock->bbFlags &= ~BBF_KEEP_BBJ_ALWAYS;
- fgRemoveBlock(leaveBlock, /* unreachable */ true);
+ fgRemoveBlock(leaveBlock, true);
// Make sure iteration isn't going off the deep end.
assert(leaveBlock != endCallFinallyRangeBlock);
diff --git a/src/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp
index 53566eb17de7b..aaf40cefbfd13 100644
--- a/src/coreclr/jit/fginline.cpp
+++ b/src/coreclr/jit/fginline.cpp
@@ -47,9 +47,7 @@ unsigned Compiler::fgCheckInlineDepthAndRecursion(InlineInfo* inlineInfo)
// This inline candidate has the same IL code buffer as an already
// inlined method does.
inlineResult->NoteFatal(InlineObservation::CALLSITE_IS_RECURSIVE);
-
- // No need to note CALLSITE_DEPTH we're already rejecting this candidate
- return depth;
+ break;
}
if (depth > InlineStrategy::IMPLEMENTATION_MAX_INLINE_DEPTH)
diff --git a/src/coreclr/jit/fgopt.cpp b/src/coreclr/jit/fgopt.cpp
index eebe8a8e8eff5..361ff92ee8099 100644
--- a/src/coreclr/jit/fgopt.cpp
+++ b/src/coreclr/jit/fgopt.cpp
@@ -145,16 +145,16 @@ bool Compiler::fgReachable(BasicBlock* b1, BasicBlock* b2)
if (b1->bbNum > fgDomBBcount)
{
- noway_assert(b1->KindIs(BBJ_NONE, BBJ_ALWAYS, BBJ_COND));
+ noway_assert(b1->bbJumpKind == BBJ_NONE || b1->bbJumpKind == BBJ_ALWAYS || b1->bbJumpKind == BBJ_COND);
- if (b1->KindIs(BBJ_NONE, BBJ_COND) && fgReachable(b1->bbNext, b2))
+ if (b1->bbFallsThrough() && fgReachable(b1->bbNext, b2))
{
return true;
}
- if (b1->KindIs(BBJ_ALWAYS, BBJ_COND) && fgReachable(b1->bbJumpDest, b2))
+ if (b1->bbJumpKind == BBJ_ALWAYS || b1->bbJumpKind == BBJ_COND)
{
- return true;
+ return fgReachable(b1->bbJumpDest, b2);
}
return false;
@@ -445,7 +445,8 @@ bool Compiler::fgRemoveUnreachableBlocks()
else if (block == genReturnBB)
{
// Don't remove statements for the genReturnBB block, as we might have special hookups there.
- // For example, the profiler hookup needs to have the "void GT_RETURN" statement
+ // For example, in VSW 364383,
+ // the profiler hookup needs to have the "void GT_RETURN" statement
// to properly set the info.compProfilerCallback flag.
continue;
}
@@ -477,9 +478,10 @@ bool Compiler::fgRemoveUnreachableBlocks()
if (block->bbFlags & BBF_DONT_REMOVE)
{
- const bool bIsBBCallAlwaysPair = block->isBBCallAlwaysPair();
+ bool bIsBBCallAlwaysPair = block->isBBCallAlwaysPair();
- // Unmark the block as removed, clear BBF_INTERNAL, and set BBJ_IMPORTED
+ /* Unmark the block as removed, */
+ /* clear BBF_INTERNAL as well and set BBJ_IMPORTED */
// The successors may be unreachable after this change.
changed |= block->NumSucc() > 0;
@@ -516,7 +518,7 @@ bool Compiler::fgRemoveUnreachableBlocks()
if (block->bbFlags & BBF_REMOVED)
{
- fgRemoveBlock(block, /* unreachable */ true);
+ fgRemoveBlock(block, true);
// TODO: couldn't we have fgRemoveBlock() return the block after the (last)one removed
// so we don't need the code below?
@@ -2283,7 +2285,8 @@ void Compiler::fgUnreachableBlock(BasicBlock* block)
{
// genReturnBB should never be removed, as we might have special hookups there.
// Therefore, we should never come here to remove the statements in the genReturnBB block.
- // For example, the profiler hookup needs to have the "void GT_RETURN" statement
+ // For example, in VSW 364383,
+ // the profiler hookup needs to have the "void GT_RETURN" statement
// to properly set the info.compProfilerCallback flag.
noway_assert(block != genReturnBB);
@@ -2305,7 +2308,10 @@ void Compiler::fgUnreachableBlock(BasicBlock* block)
assert(!block->isBBCallAlwaysPairTail()); // can't remove the BBJ_ALWAYS of a BBJ_CALLFINALLY / BBJ_ALWAYS pair
#endif
- // First, delete all the code in the block.
+ /* First walk the statement trees in this basic block and delete each stmt */
+
+ /* Make the block publicly available */
+ compCurBB = block;
if (block->IsLIR())
{
@@ -2337,13 +2343,13 @@ void Compiler::fgUnreachableBlock(BasicBlock* block)
noway_assert(block->bbStmtList == nullptr);
}
- // Next update the loop table and bbWeights
+ /* Next update the loop table and bbWeights */
optUpdateLoopsBeforeRemoveBlock(block);
- // Mark the block as removed
+ /* Mark the block as removed */
block->bbFlags |= BBF_REMOVED;
- // Update bbRefs and bbPreds for the blocks reached by this block
+ /* update bbRefs and bbPreds for the blocks reached by this block */
fgRemoveBlockAsPred(block);
}
@@ -2819,7 +2825,7 @@ bool Compiler::fgOptimizeEmptyBlock(BasicBlock* block)
/* Remove the block */
compCurBB = block;
- fgRemoveBlock(block, /* unreachable */ false);
+ fgRemoveBlock(block, false);
return true;
default:
@@ -3543,7 +3549,7 @@ bool Compiler::fgOptimizeUncondBranchToSimpleCond(BasicBlock* block, BasicBlock*
//
bool Compiler::fgOptimizeBranchToNext(BasicBlock* block, BasicBlock* bNext, BasicBlock* bPrev)
{
- assert(block->KindIs(BBJ_COND, BBJ_ALWAYS));
+ assert(block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_ALWAYS);
assert(block->bbJumpDest == bNext);
assert(block->bbNext == bNext);
assert(block->bbPrev == bPrev);
@@ -4598,7 +4604,7 @@ bool Compiler::fgReorderBlocks()
bool backwardBranch = false;
// Setup bDest
- if (bPrev->KindIs(BBJ_COND, BBJ_ALWAYS))
+ if ((bPrev->bbJumpKind == BBJ_COND) || (bPrev->bbJumpKind == BBJ_ALWAYS))
{
bDest = bPrev->bbJumpDest;
forwardBranch = fgIsForwardBranch(bPrev);
@@ -4848,7 +4854,8 @@ bool Compiler::fgReorderBlocks()
// to bTmp (which is a higher weighted block) then it is better to keep out current
// candidateBlock and have it fall into bTmp
//
- if ((candidateBlock == nullptr) || !candidateBlock->KindIs(BBJ_COND, BBJ_ALWAYS) ||
+ if ((candidateBlock == nullptr) ||
+ ((candidateBlock->bbJumpKind != BBJ_COND) && (candidateBlock->bbJumpKind != BBJ_ALWAYS)) ||
(candidateBlock->bbJumpDest != bTmp))
{
// otherwise we have a new candidateBlock
@@ -5789,7 +5796,7 @@ bool Compiler::fgUpdateFlowGraph(bool doTailDuplication)
// Remove JUMPS to the following block
// and optimize any JUMPS to JUMPS
- if (block->KindIs(BBJ_COND, BBJ_ALWAYS))
+ if (block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_ALWAYS)
{
bDest = block->bbJumpDest;
if (bDest == bNext)
@@ -5928,7 +5935,7 @@ bool Compiler::fgUpdateFlowGraph(bool doTailDuplication)
// Add fall through fixup block, if needed.
//
- if (bDest->KindIs(BBJ_NONE, BBJ_COND))
+ if ((bDest->bbJumpKind == BBJ_NONE) || (bDest->bbJumpKind == BBJ_COND))
{
BasicBlock* const bFixup = fgNewBBafter(BBJ_ALWAYS, bDest, true);
bFixup->inheritWeight(bDestNext);
@@ -6102,7 +6109,7 @@ bool Compiler::fgUpdateFlowGraph(bool doTailDuplication)
/* no references -> unreachable - remove it */
/* For now do not update the bbNum, do it at the end */
- fgRemoveBlock(block, /* unreachable */ true);
+ fgRemoveBlock(block, true);
change = true;
modified = true;
@@ -6120,7 +6127,7 @@ bool Compiler::fgUpdateFlowGraph(bool doTailDuplication)
case BBJ_ALWAYS:
if (block->bbJumpDest == block)
{
- fgRemoveBlock(block, /* unreachable */ true);
+ fgRemoveBlock(block, true);
change = true;
modified = true;
diff --git a/src/coreclr/jit/fgprofile.cpp b/src/coreclr/jit/fgprofile.cpp
index 34ab390a9b899..f94cb8615be40 100644
--- a/src/coreclr/jit/fgprofile.cpp
+++ b/src/coreclr/jit/fgprofile.cpp
@@ -1721,23 +1721,12 @@ PhaseStatus Compiler::fgPrepareToInstrumentMethod()
// jitting on PGO. If we ever implement a broader pattern of deferral -- say deferring
// based on static PGO -- we will need to reconsider.
//
- // Under OSR stress we may add patchpoints even without backedges. So we also
- // need to change the PGO instrumetation approach if OSR stress is enabled.
- //
CLANG_FORMAT_COMMENT_ANCHOR;
-#if defined(DEBUG)
- const bool mayHaveStressPatchpoints =
- (JitConfig.JitOffsetOnStackReplacement() >= 0) || (JitConfig.JitRandomOnStackReplacement() > 0);
-#else
- const bool mayHaveStressPatchpoints = false;
-#endif
-
- const bool mayHavePatchpoints =
- (JitConfig.TC_OnStackReplacement() > 0) && (compHasBackwardJump || mayHaveStressPatchpoints);
const bool prejit = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT);
- const bool tier0WithPatchpoints = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_TIER0) && mayHavePatchpoints;
- const bool osrMethod = opts.IsOSR();
+ const bool tier0WithPatchpoints = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_TIER0) &&
+ (JitConfig.TC_OnStackReplacement() > 0) && compHasBackwardJump;
+ const bool osrMethod = opts.IsOSR();
const bool useEdgeProfiles = (JitConfig.JitEdgeProfiling() > 0) && !prejit && !tier0WithPatchpoints && !osrMethod;
if (useEdgeProfiles)
@@ -3428,7 +3417,7 @@ weight_t Compiler::fgComputeMissingBlockWeights()
// Sum up the weights of all of the return blocks and throw blocks
// This is used when we have a back-edge into block 1
//
- if (bDst->hasProfileWeight() && bDst->KindIs(BBJ_RETURN, BBJ_THROW))
+ if (bDst->hasProfileWeight() && ((bDst->bbJumpKind == BBJ_RETURN) || (bDst->bbJumpKind == BBJ_THROW)))
{
returnWeight += bDst->bbWeight;
}
@@ -3999,7 +3988,7 @@ void Compiler::fgDebugCheckProfileData()
// Exit blocks
//
- if (block->KindIs(BBJ_RETURN, BBJ_THROW))
+ if ((block->bbJumpKind == BBJ_RETURN) || (block->bbJumpKind == BBJ_THROW))
{
exitWeight += blockWeight;
exitProfiled = true;
@@ -4168,7 +4157,7 @@ bool Compiler::fgDebugCheckOutgoingProfileData(BasicBlock* block)
// We won't check finally or filter returns (for now).
//
- if (block->KindIs(BBJ_EHFINALLYRET, BBJ_EHFILTERRET))
+ if ((block->bbJumpKind == BBJ_EHFINALLYRET) || (block->bbJumpKind == BBJ_EHFILTERRET))
{
return true;
}
diff --git a/src/coreclr/jit/fgstmt.cpp b/src/coreclr/jit/fgstmt.cpp
index f5f07399a1d37..24140b3fc52b9 100644
--- a/src/coreclr/jit/fgstmt.cpp
+++ b/src/coreclr/jit/fgstmt.cpp
@@ -182,7 +182,7 @@ void Compiler::fgInsertStmtNearEnd(BasicBlock* block, Statement* stmt)
// This routine can only be used when in tree order.
assert(fgOrder == FGOrderTree);
- if (block->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_RETURN))
+ if ((block->bbJumpKind == BBJ_COND) || (block->bbJumpKind == BBJ_SWITCH) || (block->bbJumpKind == BBJ_RETURN))
{
Statement* firstStmt = block->firstStmt();
noway_assert(firstStmt != nullptr);
diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp
index e2786ce57d820..188e44ab7f7f6 100644
--- a/src/coreclr/jit/flowgraph.cpp
+++ b/src/coreclr/jit/flowgraph.cpp
@@ -67,6 +67,7 @@ static bool blockNeedsGCPoll(BasicBlock* block)
// Returns:
// PhaseStatus indicating what, if anything, was changed.
//
+
PhaseStatus Compiler::fgInsertGCPolls()
{
PhaseStatus result = PhaseStatus::MODIFIED_NOTHING;
@@ -107,8 +108,23 @@ PhaseStatus Compiler::fgInsertGCPolls()
// the test.
// If we're doing GCPOLL_CALL, just insert a GT_CALL node before the last node in the block.
+ CLANG_FORMAT_COMMENT_ANCHOR;
- assert(block->KindIs(BBJ_RETURN, BBJ_ALWAYS, BBJ_COND, BBJ_SWITCH, BBJ_NONE, BBJ_THROW, BBJ_CALLFINALLY));
+#ifdef DEBUG
+ switch (block->bbJumpKind)
+ {
+ case BBJ_RETURN:
+ case BBJ_ALWAYS:
+ case BBJ_COND:
+ case BBJ_SWITCH:
+ case BBJ_NONE:
+ case BBJ_THROW:
+ case BBJ_CALLFINALLY:
+ break;
+ default:
+ assert(!"Unexpected block kind");
+ }
+#endif // DEBUG
GCPollType pollType = GCPOLL_INLINE;
@@ -180,6 +196,13 @@ PhaseStatus Compiler::fgInsertGCPolls()
constexpr bool computeDoms = false;
fgUpdateChangedFlowGraph(computePreds, computeDoms);
}
+#ifdef DEBUG
+ if (verbose)
+ {
+ printf("*************** After fgInsertGCPolls()\n");
+ fgDispBasicBlocks(true);
+ }
+#endif // DEBUG
return result;
}
@@ -222,9 +245,10 @@ BasicBlock* Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block)
createdPollBlocks = false;
Statement* newStmt = nullptr;
- if (block->KindIs(BBJ_ALWAYS, BBJ_CALLFINALLY, BBJ_NONE))
+ if ((block->bbJumpKind == BBJ_ALWAYS) || (block->bbJumpKind == BBJ_CALLFINALLY) ||
+ (block->bbJumpKind == BBJ_NONE))
{
- // For BBJ_ALWAYS, BBJ_CALLFINALLY, and BBJ_NONE we don't need to insert it before the condition.
+ // For BBJ_ALWAYS, BBJ_CALLFINALLY, and BBJ_NONE and we don't need to insert it before the condition.
// Just append it.
newStmt = fgNewStmtAtEnd(block, call);
}
@@ -3085,9 +3109,6 @@ void Compiler::fgSimpleLowering()
fgDispHandlerTab();
printf("\n");
}
-
- fgDebugCheckBBlist();
- fgDebugCheckLinks();
#endif
}
@@ -3369,7 +3390,7 @@ void Compiler::fgCreateFunclets()
* or are rarely executed.
*/
-PhaseStatus Compiler::fgDetermineFirstColdBlock()
+void Compiler::fgDetermineFirstColdBlock()
{
#ifdef DEBUG
if (verbose)
@@ -3383,19 +3404,19 @@ PhaseStatus Compiler::fgDetermineFirstColdBlock()
//
assert(fgSafeBasicBlockCreation);
- assert(fgFirstColdBlock == nullptr);
+ fgFirstColdBlock = nullptr;
if (!opts.compProcedureSplitting)
{
JITDUMP("No procedure splitting will be done for this method\n");
- return PhaseStatus::MODIFIED_NOTHING;
+ return;
}
#ifdef DEBUG
if ((compHndBBtabCount > 0) && !opts.compProcedureSplittingEH)
{
JITDUMP("No procedure splitting will be done for this method with EH (by request)\n");
- return PhaseStatus::MODIFIED_NOTHING;
+ return;
}
#endif // DEBUG
@@ -3406,7 +3427,7 @@ PhaseStatus Compiler::fgDetermineFirstColdBlock()
if (compHndBBtabCount > 0)
{
JITDUMP("No procedure splitting will be done for this method with EH (implementation limitation)\n");
- return PhaseStatus::MODIFIED_NOTHING;
+ return;
}
#endif // FEATURE_EH_FUNCLETS
@@ -3477,7 +3498,7 @@ PhaseStatus Compiler::fgDetermineFirstColdBlock()
if (prevToFirstColdBlock == nullptr)
{
- return PhaseStatus::MODIFIED_EVERYTHING; // To keep Prefast happy
+ return; // To keep Prefast happy
}
// If we only have one cold block
@@ -3573,12 +3594,14 @@ EXIT:;
{
printf("fgFirstColdBlock is NULL.\n");
}
+
+ fgDispBasicBlocks();
}
+
+ fgVerifyHandlerTab();
#endif // DEBUG
fgFirstColdBlock = firstColdBlock;
-
- return PhaseStatus::MODIFIED_EVERYTHING;
}
/* static */
@@ -3903,6 +3926,33 @@ void Compiler::fgSetTreeSeqHelper(GenTree* tree, bool isLIR)
return;
}
+ // Special handling for dynamic block ops.
+ if (tree->OperIs(GT_DYN_BLK, GT_STORE_DYN_BLK))
+ {
+ GenTreeDynBlk* dynBlk = tree->AsDynBlk();
+ GenTree* sizeNode = dynBlk->gtDynamicSize;
+ GenTree* dstAddr = dynBlk->Addr();
+ GenTree* src = dynBlk->Data();
+ bool isReverse = dynBlk->IsReverseOp();
+
+ // We either have a DYN_BLK or a STORE_DYN_BLK. If the latter, we have a
+ // src (the Data to be stored), and isReverse tells us whether to evaluate
+ // that before dstAddr.
+ if (isReverse && (src != nullptr))
+ {
+ fgSetTreeSeqHelper(src, isLIR);
+ }
+ fgSetTreeSeqHelper(dstAddr, isLIR);
+ if (!isReverse && (src != nullptr))
+ {
+ fgSetTreeSeqHelper(src, isLIR);
+ }
+ fgSetTreeSeqHelper(sizeNode, isLIR);
+
+ fgSetTreeSeqFinish(dynBlk, isLIR);
+ return;
+ }
+
/* Is it a 'simple' unary/binary operator? */
if (kind & GTK_SMPOP)
@@ -4074,9 +4124,8 @@ void Compiler::fgSetTreeSeqHelper(GenTree* tree, bool isLIR)
break;
case GT_STORE_DYN_BLK:
- fgSetTreeSeqHelper(tree->AsStoreDynBlk()->Addr(), isLIR);
- fgSetTreeSeqHelper(tree->AsStoreDynBlk()->Data(), isLIR);
- fgSetTreeSeqHelper(tree->AsStoreDynBlk()->gtDynamicSize, isLIR);
+ case GT_DYN_BLK:
+ noway_assert(!"DYN_BLK nodes should be sequenced as a special case");
break;
default:
diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp
index 35b9d2d829ca4..280c2f7087590 100644
--- a/src/coreclr/jit/gentree.cpp
+++ b/src/coreclr/jit/gentree.cpp
@@ -258,6 +258,7 @@ void GenTree::InitNodeSize()
GenTree::s_gtNodeSizes[GT_FIELD] = TREE_NODE_SZ_LARGE;
GenTree::s_gtNodeSizes[GT_CMPXCHG] = TREE_NODE_SZ_LARGE;
GenTree::s_gtNodeSizes[GT_QMARK] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_DYN_BLK] = TREE_NODE_SZ_LARGE;
GenTree::s_gtNodeSizes[GT_STORE_DYN_BLK] = TREE_NODE_SZ_LARGE;
GenTree::s_gtNodeSizes[GT_INTRINSIC] = TREE_NODE_SZ_LARGE;
GenTree::s_gtNodeSizes[GT_ALLOCOBJ] = TREE_NODE_SZ_LARGE;
@@ -319,7 +320,7 @@ void GenTree::InitNodeSize()
static_assert_no_msg(sizeof(GenTreeAddrMode) <= TREE_NODE_SZ_SMALL);
static_assert_no_msg(sizeof(GenTreeObj) <= TREE_NODE_SZ_SMALL);
static_assert_no_msg(sizeof(GenTreeBlk) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeStoreDynBlk) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeDynBlk) <= TREE_NODE_SZ_LARGE); // *** large node
static_assert_no_msg(sizeof(GenTreeRetExpr) <= TREE_NODE_SZ_LARGE); // *** large node
static_assert_no_msg(sizeof(GenTreeILOffset) <= TREE_NODE_SZ_SMALL);
static_assert_no_msg(sizeof(GenTreeClsVar) <= TREE_NODE_SZ_SMALL);
@@ -1608,9 +1609,10 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK)
Compare(op1->AsCmpXchg()->gtOpComparand, op2->AsCmpXchg()->gtOpComparand);
case GT_STORE_DYN_BLK:
- return Compare(op1->AsStoreDynBlk()->Addr(), op2->AsStoreDynBlk()->Addr()) &&
- Compare(op1->AsStoreDynBlk()->Data(), op2->AsStoreDynBlk()->Data()) &&
- Compare(op1->AsStoreDynBlk()->gtDynamicSize, op2->AsStoreDynBlk()->gtDynamicSize);
+ case GT_DYN_BLK:
+ return Compare(op1->AsDynBlk()->Addr(), op2->AsDynBlk()->Addr()) &&
+ Compare(op1->AsDynBlk()->Data(), op2->AsDynBlk()->Data()) &&
+ Compare(op1->AsDynBlk()->gtDynamicSize, op2->AsDynBlk()->gtDynamicSize);
default:
assert(!"unexpected operator");
@@ -2071,9 +2073,11 @@ unsigned Compiler::gtHashValue(GenTree* tree)
break;
case GT_STORE_DYN_BLK:
- hash = genTreeHashAdd(hash, gtHashValue(tree->AsStoreDynBlk()->Data()));
- hash = genTreeHashAdd(hash, gtHashValue(tree->AsStoreDynBlk()->Addr()));
- hash = genTreeHashAdd(hash, gtHashValue(tree->AsStoreDynBlk()->gtDynamicSize));
+ hash = genTreeHashAdd(hash, gtHashValue(tree->AsDynBlk()->Data()));
+ FALLTHROUGH;
+ case GT_DYN_BLK:
+ hash = genTreeHashAdd(hash, gtHashValue(tree->AsDynBlk()->Addr()));
+ hash = genTreeHashAdd(hash, gtHashValue(tree->AsDynBlk()->gtDynamicSize));
break;
default:
@@ -4132,6 +4136,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
case GT_IND:
case GT_BLK:
case GT_OBJ:
+ case GT_DYN_BLK:
// In an indirection, the destination address is evaluated prior to the source.
// If we have any side effects on the target indirection,
@@ -4176,7 +4181,6 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
case GT_LCL_VAR:
case GT_LCL_FLD:
- case GT_CLS_VAR:
// We evaluate op2 before op1
bReverseInAssignment = true;
@@ -4641,19 +4645,23 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
break;
case GT_STORE_DYN_BLK:
- level = gtSetEvalOrder(tree->AsStoreDynBlk()->Addr());
- costEx = tree->AsStoreDynBlk()->Addr()->GetCostEx();
- costSz = tree->AsStoreDynBlk()->Addr()->GetCostSz();
+ case GT_DYN_BLK:
+ level = gtSetEvalOrder(tree->AsDynBlk()->Addr());
+ costEx = tree->AsDynBlk()->Addr()->GetCostEx();
+ costSz = tree->AsDynBlk()->Addr()->GetCostSz();
- lvl2 = gtSetEvalOrder(tree->AsStoreDynBlk()->Data());
- level = max(level, lvl2);
- costEx += tree->AsStoreDynBlk()->Data()->GetCostEx();
- costSz += tree->AsStoreDynBlk()->Data()->GetCostSz();
+ if (oper == GT_STORE_DYN_BLK)
+ {
+ lvl2 = gtSetEvalOrder(tree->AsDynBlk()->Data());
+ level = max(level, lvl2);
+ costEx += tree->AsDynBlk()->Data()->GetCostEx();
+ costSz += tree->AsDynBlk()->Data()->GetCostSz();
+ }
- lvl2 = gtSetEvalOrder(tree->AsStoreDynBlk()->gtDynamicSize);
+ lvl2 = gtSetEvalOrder(tree->AsDynBlk()->gtDynamicSize);
level = max(level, lvl2);
- costEx += tree->AsStoreDynBlk()->gtDynamicSize->GetCostEx();
- costSz += tree->AsStoreDynBlk()->gtDynamicSize->GetCostSz();
+ costEx += tree->AsDynBlk()->gtDynamicSize->GetCostEx();
+ costSz += tree->AsDynBlk()->gtDynamicSize->GetCostSz();
break;
default:
@@ -4957,9 +4965,25 @@ bool GenTree::TryGetUse(GenTree* operand, GenTree*** pUse)
return false;
}
+ case GT_DYN_BLK:
+ {
+ GenTreeDynBlk* const dynBlock = this->AsDynBlk();
+ if (operand == dynBlock->gtOp1)
+ {
+ *pUse = &dynBlock->gtOp1;
+ return true;
+ }
+ if (operand == dynBlock->gtDynamicSize)
+ {
+ *pUse = &dynBlock->gtDynamicSize;
+ return true;
+ }
+ return false;
+ }
+
case GT_STORE_DYN_BLK:
{
- GenTreeStoreDynBlk* const dynBlock = this->AsStoreDynBlk();
+ GenTreeDynBlk* const dynBlock = this->AsDynBlk();
if (operand == dynBlock->gtOp1)
{
*pUse = &dynBlock->gtOp1;
@@ -5160,8 +5184,7 @@ GenTree* GenTree::gtRetExprVal(BasicBlockFlags* pbbFlags /* = nullptr */)
bool GenTree::OperRequiresAsgFlag()
{
- if (OperIs(GT_ASG, GT_STORE_DYN_BLK) ||
- OperIs(GT_XADD, GT_XORR, GT_XAND, GT_XCHG, GT_LOCKADD, GT_CMPXCHG, GT_MEMORYBARRIER))
+ if (OperIs(GT_ASG) || OperIs(GT_XADD, GT_XORR, GT_XAND, GT_XCHG, GT_LOCKADD, GT_CMPXCHG, GT_MEMORYBARRIER))
{
return true;
}
@@ -5227,7 +5250,7 @@ bool GenTree::OperRequiresCallFlag(Compiler* comp)
// Return Value:
// True if the given node contains an implicit indirection
//
-// Note that for the [HW]INTRINSIC nodes we have to examine the
+// Note that for the GT_HWINTRINSIC node we have to examine the
// details of the node to determine its result.
//
@@ -5243,6 +5266,7 @@ bool GenTree::OperIsImplicitIndir() const
case GT_CMPXCHG:
case GT_BLK:
case GT_OBJ:
+ case GT_DYN_BLK:
case GT_STORE_BLK:
case GT_STORE_OBJ:
case GT_STORE_DYN_BLK:
@@ -5251,8 +5275,6 @@ bool GenTree::OperIsImplicitIndir() const
case GT_ARR_ELEM:
case GT_ARR_OFFSET:
return true;
- case GT_INTRINSIC:
- return AsIntrinsic()->gtIntrinsicName == NI_System_Object_GetType;
#ifdef FEATURE_SIMD
case GT_SIMD:
{
@@ -5309,8 +5331,18 @@ bool GenTree::OperMayThrow(Compiler* comp)
case GT_INTRINSIC:
// If this is an intrinsic that represents the object.GetType(), it can throw an NullReferenceException.
- // Currently, this is the only intrinsic that can throw an exception.
- return AsIntrinsic()->gtIntrinsicName == NI_System_Object_GetType;
+ // Report it as may throw.
+ // Note: Some of the rest of the existing intrinsics could potentially throw an exception (for example
+ // the array and string element access ones). They are handled differently than the GetType intrinsic
+ // and are not marked with GTF_EXCEPT. If these are revisited at some point to be marked as
+ // GTF_EXCEPT,
+ // the code below might need to be specialized to handle them properly.
+ if ((this->gtFlags & GTF_EXCEPT) != 0)
+ {
+ return true;
+ }
+
+ break;
case GT_CALL:
@@ -5321,9 +5353,9 @@ bool GenTree::OperMayThrow(Compiler* comp)
case GT_IND:
case GT_BLK:
case GT_OBJ:
- case GT_NULLCHECK:
+ case GT_DYN_BLK:
case GT_STORE_BLK:
- case GT_STORE_DYN_BLK:
+ case GT_NULLCHECK:
return (((this->gtFlags & GTF_IND_NONFAULTING) == 0) && comp->fgAddrCouldBeNull(this->AsIndir()->Addr()));
case GT_ARR_LENGTH:
@@ -6795,19 +6827,24 @@ void Compiler::gtBlockOpInit(GenTree* result, GenTree* dst, GenTree* srcOrFillVa
// gtNewBlkOpNode: Creates a GenTree for a block (struct) assignment.
//
// Arguments:
-// dst - The destination node: local var / block node.
-// srcOrFillVall - The value to assign for CopyBlk, the integer "fill" for InitBlk
+// dst - Destination or target to copy to / initialize the buffer.
+// srcOrFillVall - the size of the buffer to copy/initialize or zero, in the case of CpObj.
// isVolatile - Whether this is a volatile memory operation or not.
// isCopyBlock - True if this is a block copy (rather than a block init).
//
// Return Value:
// Returns the newly constructed and initialized block operation.
//
+// Notes:
+// If size is zero, the dst must be a GT_OBJ with the class handle.
+// 'dst' must be a block node or lclVar.
+//
GenTree* Compiler::gtNewBlkOpNode(GenTree* dst, GenTree* srcOrFillVal, bool isVolatile, bool isCopyBlock)
{
assert(dst->OperIsBlk() || dst->OperIsLocal());
if (isCopyBlock)
{
+ srcOrFillVal->gtFlags |= GTF_DONT_CSE;
if (srcOrFillVal->OperIsIndir() && (srcOrFillVal->gtGetOp1()->gtOper == GT_ADDR))
{
srcOrFillVal = srcOrFillVal->gtGetOp1()->gtGetOp1();
@@ -7398,6 +7435,10 @@ GenTree* Compiler::gtCloneExpr(
GenTreeBlk(GT_BLK, tree->TypeGet(), tree->AsBlk()->Addr(), tree->AsBlk()->GetLayout());
break;
+ case GT_DYN_BLK:
+ copy = new (this, GT_DYN_BLK) GenTreeDynBlk(tree->AsOp()->gtGetOp1(), tree->AsDynBlk()->gtDynamicSize);
+ break;
+
case GT_FIELD:
copy = new (this, GT_FIELD) GenTreeField(tree->TypeGet(), tree->AsField()->GetFldObj(),
tree->AsField()->gtFldHnd, tree->AsField()->gtFldOffset);
@@ -7625,10 +7666,10 @@ GenTree* Compiler::gtCloneExpr(
break;
case GT_STORE_DYN_BLK:
+ case GT_DYN_BLK:
copy = new (this, oper)
- GenTreeStoreDynBlk(gtCloneExpr(tree->AsStoreDynBlk()->Addr(), addFlags, deepVarNum, deepVarVal),
- gtCloneExpr(tree->AsStoreDynBlk()->Data(), addFlags, deepVarNum, deepVarVal),
- gtCloneExpr(tree->AsStoreDynBlk()->gtDynamicSize, addFlags, deepVarNum, deepVarVal));
+ GenTreeDynBlk(gtCloneExpr(tree->AsDynBlk()->Addr(), addFlags, deepVarNum, deepVarVal),
+ gtCloneExpr(tree->AsDynBlk()->gtDynamicSize, addFlags, deepVarNum, deepVarVal));
break;
default:
@@ -8312,10 +8353,20 @@ GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node)
m_advance = &GenTreeUseEdgeIterator::AdvanceArrOffset;
return;
+ case GT_DYN_BLK:
+ m_edge = &m_node->AsDynBlk()->Addr();
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::AdvanceDynBlk;
+ return;
+
case GT_STORE_DYN_BLK:
- m_edge = &m_node->AsStoreDynBlk()->Addr();
+ {
+ GenTreeDynBlk* const dynBlock = m_node->AsDynBlk();
+ m_edge = dynBlock->IsReverseOp() ? &dynBlock->gtOp2 : &dynBlock->gtOp1;
assert(*m_edge != nullptr);
+
m_advance = &GenTreeUseEdgeIterator::AdvanceStoreDynBlk;
+ }
return;
case GT_CALL:
@@ -8393,16 +8444,28 @@ void GenTreeUseEdgeIterator::AdvanceArrOffset()
assert(*m_edge != nullptr);
}
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::AdvanceDynBlk: produces the next operand of a DynBlk node and advances the state.
+//
+void GenTreeUseEdgeIterator::AdvanceDynBlk()
+{
+ GenTreeDynBlk* const dynBlock = m_node->AsDynBlk();
+
+ m_edge = &dynBlock->gtDynamicSize;
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
+}
+
//------------------------------------------------------------------------
// GenTreeUseEdgeIterator::AdvanceStoreDynBlk: produces the next operand of a StoreDynBlk node and advances the state.
//
void GenTreeUseEdgeIterator::AdvanceStoreDynBlk()
{
- GenTreeStoreDynBlk* const dynBlock = m_node->AsStoreDynBlk();
+ GenTreeDynBlk* const dynBlock = m_node->AsDynBlk();
switch (m_state)
{
case 0:
- m_edge = &dynBlock->Data();
+ m_edge = dynBlock->IsReverseOp() ? &dynBlock->gtOp1 : &dynBlock->gtOp2;
m_state = 1;
break;
case 1:
@@ -9194,6 +9257,7 @@ void Compiler::gtDispNode(GenTree* tree, IndentStack* indentStack, _In_ _In_opt_
case GT_LEA:
case GT_BLK:
case GT_OBJ:
+ case GT_DYN_BLK:
case GT_STORE_BLK:
case GT_STORE_OBJ:
case GT_STORE_DYN_BLK:
@@ -10760,9 +10824,6 @@ void Compiler::gtDispTree(GenTree* tree,
case NI_System_Object_GetType:
printf(" objGetType");
break;
- case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant:
- printf(" isKnownConst");
- break;
default:
unreached();
@@ -11012,6 +11073,7 @@ void Compiler::gtDispTree(GenTree* tree,
break;
case GT_STORE_DYN_BLK:
+ case GT_DYN_BLK:
if (tree->OperIsCopyBlkOp())
{
printf(" (copy)");
@@ -11024,12 +11086,12 @@ void Compiler::gtDispTree(GenTree* tree,
if (!topOnly)
{
- gtDispChild(tree->AsStoreDynBlk()->Addr(), indentStack, IIArc, nullptr, topOnly);
- if (tree->AsStoreDynBlk()->Data() != nullptr)
+ if (tree->AsDynBlk()->Data() != nullptr)
{
- gtDispChild(tree->AsStoreDynBlk()->Data(), indentStack, IIArc, nullptr, topOnly);
+ gtDispChild(tree->AsDynBlk()->Data(), indentStack, IIArc, nullptr, topOnly);
}
- gtDispChild(tree->AsStoreDynBlk()->gtDynamicSize, indentStack, IIArcBottom, nullptr, topOnly);
+ gtDispChild(tree->AsDynBlk()->Addr(), indentStack, IIArc, nullptr, topOnly);
+ gtDispChild(tree->AsDynBlk()->gtDynamicSize, indentStack, IIArcBottom, nullptr, topOnly);
}
break;
@@ -11422,7 +11484,7 @@ void Compiler::gtDispLIRNode(GenTree* node, const char* prefixMsg /* = nullptr *
displayOperand(operand, buf, operandArc, indentStack, prefixIndent);
}
}
- else if (node->OperIs(GT_STORE_DYN_BLK))
+ else if (node->OperIsDynBlkOp())
{
if (operand == node->AsBlk()->Addr())
{
@@ -11434,7 +11496,19 @@ void Compiler::gtDispLIRNode(GenTree* node, const char* prefixMsg /* = nullptr *
}
else
{
- assert(operand == node->AsStoreDynBlk()->gtDynamicSize);
+ assert(operand == node->AsDynBlk()->gtDynamicSize);
+ displayOperand(operand, "size", operandArc, indentStack, prefixIndent);
+ }
+ }
+ else if (node->OperGet() == GT_DYN_BLK)
+ {
+ if (operand == node->AsBlk()->Addr())
+ {
+ displayOperand(operand, "lhs", operandArc, indentStack, prefixIndent);
+ }
+ else
+ {
+ assert(operand == node->AsDynBlk()->gtDynamicSize);
displayOperand(operand, "size", operandArc, indentStack, prefixIndent);
}
}
@@ -14467,14 +14541,14 @@ bool Compiler::gtNodeHasSideEffects(GenTree* tree, GenTreeFlags flags)
{
if (flags & GTF_ASG)
{
- // TODO-Bug: This only checks for GT_ASG/GT_STORE_DYN_BLK but according to OperRequiresAsgFlag
- // there are many more opers that are considered to have an assignment side effect: atomic ops
+ // TODO-Cleanup: This only checks for GT_ASG but according to OperRequiresAsgFlag there
+ // are many more opers that are considered to have an assignment side effect: atomic ops
// (GT_CMPXCHG & co.), GT_MEMORYBARRIER (not classified as an atomic op) and HW intrinsic
// memory stores. Atomic ops have special handling in gtExtractSideEffList but the others
// will simply be dropped is they are ever subject to an "extract side effects" operation.
// It is possible that the reason no bugs have yet been observed in this area is that the
// other nodes are likely to always be tree roots.
- if (tree->OperIs(GT_ASG, GT_STORE_DYN_BLK))
+ if (tree->OperIs(GT_ASG))
{
return true;
}
@@ -15200,21 +15274,33 @@ bool GenTree::DefinesLocal(Compiler* comp, GenTreeLclVarCommon** pLclVarTree, bo
GenTree* destAddr = blkNode->Addr();
unsigned width = blkNode->Size();
// Do we care about whether this assigns the entire variable?
- if (pIsEntire != nullptr && blkNode->OperIs(GT_STORE_DYN_BLK))
+ if (pIsEntire != nullptr && blkNode->OperIs(GT_DYN_BLK))
{
- GenTree* blockWidth = blkNode->AsStoreDynBlk()->gtDynamicSize;
+ GenTree* blockWidth = blkNode->AsDynBlk()->gtDynamicSize;
if (blockWidth->IsCnsIntOrI())
{
- assert(blockWidth->AsIntConCommon()->FitsInI32());
- width = static_cast(blockWidth->AsIntConCommon()->IconValue());
-
- if (width == 0)
+ if (blockWidth->IsIconHandle())
{
- return false;
+ // If it's a handle, it must be a class handle. We only create such block operations
+ // for initialization of struct types, so the type of the argument(s) will match this
+ // type, by construction, and be "entire".
+ assert(blockWidth->IsIconHandle(GTF_ICON_CLASS_HDL));
+ width = comp->info.compCompHnd->getClassSize(
+ CORINFO_CLASS_HANDLE(blockWidth->AsIntConCommon()->IconValue()));
+ }
+ else
+ {
+ ssize_t swidth = blockWidth->AsIntConCommon()->IconValue();
+ assert(swidth >= 0);
+ // cpblk of size zero exists in the wild (in yacc-generated code in SQL) and is valid IL.
+ if (swidth == 0)
+ {
+ return false;
+ }
+ width = unsigned(swidth);
}
}
}
-
return destAddr->DefinesLocalAddr(comp, width, pLclVarTree, pIsEntire);
}
// Otherwise...
@@ -15844,26 +15930,26 @@ bool GenTreeIntConCommon::AddrNeedsReloc(Compiler* comp)
// this: ADD(CONST FldSeq, baseAddr)
//
// Arguments:
-// comp - the Compiler object
-// pBaseAddr - [out] parameter for "the base address"
-// pFldSeq - [out] parameter for the field sequence
+// comp - the Compiler object
+// pObj - [out] parameter for instance fields, the object reference
+// pStatic - [out] parameter for static fields, the base address
+// pFldSeq - [out] parameter for the field sequence
//
// Return Value:
// If "this" matches patterns denoted above, and the FldSeq found is "full",
// i. e. starts with a class field or a static field, and includes all the
// struct fields that this tree represents the address of, this method will
-// return "true" and set either "pBaseAddr" to some value, which must be used
-// by the caller as the key into the "first field map" to obtain the actual
-// value for the field. For instance fields, "base address" will be the object
-// reference, for statics - the address to which the field offset with the
-// field sequence is added, see "impImportStaticFieldAccess" and "fgMorphField".
+// return "true" and set either "pObj" or "pStatic" to some value, which must
+// be used by the caller as the key into the "first field map" to obtain the
+// actual value for the field.
//
-bool GenTree::IsFieldAddr(Compiler* comp, GenTree** pBaseAddr, FieldSeqNode** pFldSeq)
+bool GenTree::IsFieldAddr(Compiler* comp, GenTree** pObj, GenTree** pStatic, FieldSeqNode** pFldSeq)
{
assert(TypeIs(TYP_I_IMPL, TYP_BYREF, TYP_REF));
- *pBaseAddr = nullptr;
- *pFldSeq = FieldSeqStore::NotAField();
+ *pObj = nullptr;
+ *pStatic = nullptr;
+ *pFldSeq = FieldSeqStore::NotAField();
GenTree* baseAddr = nullptr;
FieldSeqNode* fldSeq = nullptr;
@@ -15920,8 +16006,8 @@ bool GenTree::IsFieldAddr(Compiler* comp, GenTree** pBaseAddr, FieldSeqNode** pF
// TODO-VNTypes: we will always return the "baseAddr" here for now, but strictly speaking,
// we only need to do that if we have a shared field, to encode the logical "instantiation"
// argument. In all other cases, this serves no purpose and just leads to redundant maps.
- *pBaseAddr = baseAddr;
- *pFldSeq = fldSeq;
+ *pStatic = baseAddr;
+ *pFldSeq = fldSeq;
return true;
}
@@ -15929,8 +16015,8 @@ bool GenTree::IsFieldAddr(Compiler* comp, GenTree** pBaseAddr, FieldSeqNode** pF
{
assert(!comp->eeIsValueClass(comp->info.compCompHnd->getFieldClass(fldSeq->GetFieldHandle())));
- *pBaseAddr = baseAddr;
- *pFldSeq = fldSeq;
+ *pObj = baseAddr;
+ *pFldSeq = fldSeq;
return true;
}
@@ -17646,20 +17732,6 @@ bool GenTree::isContainableHWIntrinsic() const
return true;
}
- default:
- {
- return false;
- }
- }
-#elif TARGET_ARM64
- switch (AsHWIntrinsic()->GetHWIntrinsicId())
- {
- case NI_Vector64_get_Zero:
- case NI_Vector128_get_Zero:
- {
- return true;
- }
-
default:
{
return false;
@@ -17859,7 +17931,7 @@ GenTree* Compiler::gtNewSimdAbsNode(
if ((simdBaseType != TYP_LONG) && ((simdSize == 32) || compOpportunisticallyDependsOn(InstructionSet_SSSE3)))
{
NamedIntrinsic intrinsic = (simdSize == 32) ? NI_AVX2_Abs : NI_SSSE3_Abs;
- return gtNewSimdHWIntrinsicNode(type, op1, intrinsic, simdBaseJitType, simdSize, isSimdAsHWIntrinsic);
+ return gtNewSimdAsHWIntrinsicNode(type, op1, intrinsic, simdBaseJitType, simdSize);
}
else
{
@@ -19287,22 +19359,20 @@ GenTree* Compiler::gtNewSimdCmpOpAllNode(genTreeOps op,
NamedIntrinsic intrinsic = NI_Illegal;
+#if defined(TARGET_XARCH)
+ if (simdSize == 32)
+ {
+ assert(compIsaSupportedDebugOnly(InstructionSet_AVX));
+ assert(varTypeIsFloating(simdBaseType) || compIsaSupportedDebugOnly(InstructionSet_AVX2));
+ }
+#endif // TARGET_XARCH
+
switch (op)
{
#if defined(TARGET_XARCH)
case GT_EQ:
{
- if (simdSize == 32)
- {
- assert(compIsaSupportedDebugOnly(InstructionSet_AVX));
- assert(varTypeIsFloating(simdBaseType) || compIsaSupportedDebugOnly(InstructionSet_AVX2));
-
- intrinsic = NI_Vector256_op_Equality;
- }
- else
- {
- intrinsic = NI_Vector128_op_Equality;
- }
+ intrinsic = (simdSize == 32) ? NI_Vector256_op_Equality : NI_Vector128_op_Equality;
break;
}
@@ -19318,12 +19388,6 @@ GenTree* Compiler::gtNewSimdCmpOpAllNode(genTreeOps op,
if (simdSize == 32)
{
- // TODO-XArch-CQ: It's a non-trivial amount of work to support these
- // for floating-point while only utilizing AVX. It would require, among
- // other things, inverting the comparison and potentially support for a
- // new Avx.TestNotZ intrinsic to ensure the codegen remains efficient.
- assert(compIsaSupportedDebugOnly(InstructionSet_AVX2));
-
intrinsic = NI_Vector256_op_Equality;
getAllBitsSet = NI_Vector256_get_AllBitsSet;
}
@@ -19333,7 +19397,7 @@ GenTree* Compiler::gtNewSimdCmpOpAllNode(genTreeOps op,
getAllBitsSet = NI_Vector128_get_AllBitsSet;
}
- op1 = gtNewSimdCmpOpNode(op, simdType, op1, op2, simdBaseJitType, simdSize,
+ op1 = gtNewSimdCmpOpNode(op, simdBaseType, op1, op2, simdBaseJitType, simdSize,
/* isSimdAsHWIntrinsic */ false);
if (simdBaseType == TYP_FLOAT)
@@ -19347,7 +19411,7 @@ GenTree* Compiler::gtNewSimdCmpOpAllNode(genTreeOps op,
simdBaseJitType = CORINFO_TYPE_LONG;
}
- op2 = gtNewSimdHWIntrinsicNode(simdType, getAllBitsSet, simdBaseJitType, simdSize);
+ op2 = gtNewSimdHWIntrinsicNode(simdBaseType, getAllBitsSet, simdBaseJitType, simdSize);
break;
}
#elif defined(TARGET_ARM64)
@@ -19378,7 +19442,7 @@ GenTree* Compiler::gtNewSimdCmpOpAllNode(genTreeOps op,
getAllBitsSet = NI_Vector128_get_AllBitsSet;
}
- op1 = gtNewSimdCmpOpNode(op, simdType, op1, op2, simdBaseJitType, simdSize,
+ op1 = gtNewSimdCmpOpNode(op, simdBaseType, op1, op2, simdBaseJitType, simdSize,
/* isSimdAsHWIntrinsic */ false);
if (simdBaseType == TYP_FLOAT)
@@ -19392,7 +19456,7 @@ GenTree* Compiler::gtNewSimdCmpOpAllNode(genTreeOps op,
simdBaseJitType = CORINFO_TYPE_LONG;
}
- op2 = gtNewSimdHWIntrinsicNode(simdType, getAllBitsSet, simdBaseJitType, simdSize);
+ op2 = gtNewSimdHWIntrinsicNode(simdBaseType, getAllBitsSet, simdBaseJitType, simdSize);
break;
}
#else
@@ -19434,6 +19498,14 @@ GenTree* Compiler::gtNewSimdCmpOpAnyNode(genTreeOps op,
NamedIntrinsic intrinsic = NI_Illegal;
+#if defined(TARGET_XARCH)
+ if (simdSize == 32)
+ {
+ assert(compIsaSupportedDebugOnly(InstructionSet_AVX));
+ assert(varTypeIsFloating(simdBaseType) || compIsaSupportedDebugOnly(InstructionSet_AVX2));
+ }
+#endif // TARGET_XARCH
+
switch (op)
{
#if defined(TARGET_XARCH)
@@ -19446,22 +19518,9 @@ GenTree* Compiler::gtNewSimdCmpOpAnyNode(genTreeOps op,
// We want to generate a comparison along the lines of
// GT_XX(op1, op2).As() != Vector128.Zero
- if (simdSize == 32)
- {
- // TODO-XArch-CQ: It's a non-trivial amount of work to support these
- // for floating-point while only utilizing AVX. It would require, among
- // other things, inverting the comparison and potentially support for a
- // new Avx.TestNotZ intrinsic to ensure the codegen remains efficient.
- assert(compIsaSupportedDebugOnly(InstructionSet_AVX2));
-
- intrinsic = NI_Vector256_op_Inequality;
- }
- else
- {
- intrinsic = NI_Vector128_op_Inequality;
- }
+ intrinsic = (simdSize == 32) ? NI_Vector256_op_Inequality : NI_Vector128_op_Inequality;
- op1 = gtNewSimdCmpOpNode(op, simdType, op1, op2, simdBaseJitType, simdSize,
+ op1 = gtNewSimdCmpOpNode(op, simdBaseType, op1, op2, simdBaseJitType, simdSize,
/* isSimdAsHWIntrinsic */ false);
if (simdBaseType == TYP_FLOAT)
@@ -19475,23 +19534,13 @@ GenTree* Compiler::gtNewSimdCmpOpAnyNode(genTreeOps op,
simdBaseJitType = CORINFO_TYPE_LONG;
}
- op2 = gtNewSimdZeroNode(simdType, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
+ op2 = gtNewSimdZeroNode(simdBaseType, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
break;
}
case GT_NE:
{
- if (simdSize == 32)
- {
- assert(compIsaSupportedDebugOnly(InstructionSet_AVX));
- assert(varTypeIsFloating(simdBaseType) || compIsaSupportedDebugOnly(InstructionSet_AVX2));
-
- intrinsic = NI_Vector256_op_Inequality;
- }
- else
- {
- intrinsic = NI_Vector128_op_Inequality;
- }
+ intrinsic = (simdSize == 32) ? NI_Vector256_op_Inequality : NI_Vector128_op_Inequality;
break;
}
#elif defined(TARGET_ARM64)
@@ -19506,7 +19555,7 @@ GenTree* Compiler::gtNewSimdCmpOpAnyNode(genTreeOps op,
intrinsic = (simdSize == 8) ? NI_Vector64_op_Inequality : NI_Vector128_op_Inequality;
- op1 = gtNewSimdCmpOpNode(op, simdType, op1, op2, simdBaseJitType, simdSize,
+ op1 = gtNewSimdCmpOpNode(op, simdBaseType, op1, op2, simdBaseJitType, simdSize,
/* isSimdAsHWIntrinsic */ false);
if (simdBaseType == TYP_FLOAT)
@@ -19520,7 +19569,7 @@ GenTree* Compiler::gtNewSimdCmpOpAnyNode(genTreeOps op,
simdBaseJitType = CORINFO_TYPE_LONG;
}
- op2 = gtNewSimdZeroNode(simdType, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
+ op2 = gtNewSimdZeroNode(simdBaseType, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
break;
}
@@ -19593,8 +19642,7 @@ GenTree* Compiler::gtNewSimdCndSelNode(var_types type,
// result = op2 | op3
return gtNewSimdBinOpNode(GT_OR, type, op2, op3, simdBaseJitType, simdSize, isSimdAsHWIntrinsic);
#elif defined(TARGET_ARM64)
- return gtNewSimdHWIntrinsicNode(type, op1, op2, op3, NI_AdvSimd_BitwiseSelect, simdBaseJitType, simdSize,
- isSimdAsHWIntrinsic);
+ return gtNewSimdAsHWIntrinsicNode(type, op1, op2, op3, NI_AdvSimd_BitwiseSelect, simdBaseJitType, simdSize);
#else
#error Unsupported platform
#endif // !TARGET_XARCH && !TARGET_ARM64
@@ -19653,7 +19701,7 @@ GenTree* Compiler::gtNewSimdDotProdNode(var_types type,
assert(op2->TypeIs(simdType));
var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType);
- assert(JITtype2varType(simdBaseJitType) == type);
+ assert(genActualType(simdBaseType) == type);
NamedIntrinsic intrinsic = NI_Illegal;
@@ -20686,7 +20734,7 @@ GenTree* Compiler::gtNewSimdSumNode(
for (int i = 0; i < haddCount; i++)
{
op1 = impCloneExpr(op1, &tmp, clsHnd, (unsigned)CHECK_SPILL_ALL, nullptr DEBUGARG("Clone op1 for vector sum"));
- op1 = gtNewSimdHWIntrinsicNode(simdType, op1, tmp, intrinsic, simdBaseJitType, simdSize, isSimdAsHWIntrinsic);
+ op1 = gtNewSimdAsHWIntrinsicNode(simdType, op1, tmp, intrinsic, simdBaseJitType, simdSize);
}
if (simdSize == 32)
@@ -20694,15 +20742,14 @@ GenTree* Compiler::gtNewSimdSumNode(
intrinsic = (simdBaseType == TYP_FLOAT) ? NI_SSE_Add : NI_SSE2_Add;
op1 = impCloneExpr(op1, &tmp, clsHnd, (unsigned)CHECK_SPILL_ALL, nullptr DEBUGARG("Clone op1 for vector sum"));
- op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, gtNewIconNode(0x01, TYP_INT), NI_AVX_ExtractVector128,
- simdBaseJitType, simdSize, isSimdAsHWIntrinsic);
+ op1 = gtNewSimdAsHWIntrinsicNode(TYP_SIMD16, op1, gtNewIconNode(0x01, TYP_INT), NI_AVX_ExtractVector128,
+ simdBaseJitType, simdSize);
- tmp = gtNewSimdHWIntrinsicNode(simdType, tmp, NI_Vector256_GetLower, simdBaseJitType, simdSize,
- isSimdAsHWIntrinsic);
- op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, tmp, intrinsic, simdBaseJitType, 16, isSimdAsHWIntrinsic);
+ tmp = gtNewSimdAsHWIntrinsicNode(simdType, tmp, NI_Vector256_GetLower, simdBaseJitType, simdSize);
+ op1 = gtNewSimdAsHWIntrinsicNode(TYP_SIMD16, op1, tmp, intrinsic, simdBaseJitType, 16);
}
- return gtNewSimdHWIntrinsicNode(type, op1, NI_Vector128_ToScalar, simdBaseJitType, simdSize, isSimdAsHWIntrinsic);
+ return gtNewSimdAsHWIntrinsicNode(type, op1, NI_Vector128_ToScalar, simdBaseJitType, simdSize);
#elif defined(TARGET_ARM64)
switch (simdBaseType)
{
@@ -20710,64 +20757,34 @@ GenTree* Compiler::gtNewSimdSumNode(
case TYP_UBYTE:
case TYP_SHORT:
case TYP_USHORT:
- {
- tmp = gtNewSimdHWIntrinsicNode(simdType, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, simdSize,
- isSimdAsHWIntrinsic);
- return gtNewSimdHWIntrinsicNode(type, tmp, NI_Vector64_ToScalar, simdBaseJitType, 8, isSimdAsHWIntrinsic);
- }
-
case TYP_INT:
case TYP_UINT:
{
- if (simdSize == 8)
- {
- op1 = impCloneExpr(op1, &tmp, clsHnd, (unsigned)CHECK_SPILL_ALL,
- nullptr DEBUGARG("Clone op1 for vector sum"));
- tmp = gtNewSimdHWIntrinsicNode(simdType, op1, tmp, NI_AdvSimd_AddPairwise, simdBaseJitType, simdSize,
- isSimdAsHWIntrinsic);
- }
- else
- {
- tmp = gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, 16,
- isSimdAsHWIntrinsic);
- }
- return gtNewSimdHWIntrinsicNode(type, tmp, NI_Vector64_ToScalar, simdBaseJitType, 8, isSimdAsHWIntrinsic);
+ tmp = gtNewSimdAsHWIntrinsicNode(simdType, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, simdSize);
+ return gtNewSimdAsHWIntrinsicNode(type, tmp, NI_Vector64_ToScalar, simdBaseJitType, 8);
}
-
case TYP_FLOAT:
{
- if (simdSize == 8)
+ unsigned vectorLength = getSIMDVectorLength(simdSize, simdBaseType);
+ int haddCount = genLog2(vectorLength);
+
+ for (int i = 0; i < haddCount; i++)
{
- op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddPairwiseScalar, simdBaseJitType,
- simdSize, isSimdAsHWIntrinsic);
+ op1 = impCloneExpr(op1, &tmp, clsHnd, (unsigned)CHECK_SPILL_ALL,
+ nullptr DEBUGARG("Clone op1 for vector sum"));
+ op1 = gtNewSimdAsHWIntrinsicNode(simdType, op1, tmp, NI_AdvSimd_Arm64_AddPairwise, simdBaseJitType,
+ simdSize);
}
- else
- {
- unsigned vectorLength = getSIMDVectorLength(simdSize, simdBaseType);
- int haddCount = genLog2(vectorLength);
- for (int i = 0; i < haddCount; i++)
- {
- op1 = impCloneExpr(op1, &tmp, clsHnd, (unsigned)CHECK_SPILL_ALL,
- nullptr DEBUGARG("Clone op1 for vector sum"));
- op1 = gtNewSimdHWIntrinsicNode(simdType, op1, tmp, NI_AdvSimd_Arm64_AddPairwise, simdBaseJitType,
- simdSize, isSimdAsHWIntrinsic);
- }
- }
- return gtNewSimdHWIntrinsicNode(type, op1, NI_Vector128_ToScalar, simdBaseJitType, simdSize,
- isSimdAsHWIntrinsic);
+ return gtNewSimdAsHWIntrinsicNode(type, op1, NI_Vector128_ToScalar, simdBaseJitType, simdSize);
}
-
case TYP_DOUBLE:
case TYP_LONG:
case TYP_ULONG:
{
- if (simdSize == 16)
- {
- op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddPairwiseScalar, simdBaseJitType,
- simdSize, isSimdAsHWIntrinsic);
- }
- return gtNewSimdHWIntrinsicNode(type, op1, NI_Vector64_ToScalar, simdBaseJitType, 8, isSimdAsHWIntrinsic);
+ op1 = gtNewSimdAsHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddPairwiseScalar, simdBaseJitType,
+ simdSize);
+ return gtNewSimdAsHWIntrinsicNode(type, op1, NI_Vector64_ToScalar, simdBaseJitType, 8);
}
default:
{
@@ -21380,9 +21397,7 @@ GenTreeHWIntrinsic* Compiler::gtNewScalarHWIntrinsicNode(
bool GenTreeHWIntrinsic::OperIsMemoryLoad() const
{
#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
- NamedIntrinsic intrinsicId = GetHWIntrinsicId();
- HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId);
-
+ HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(GetHWIntrinsicId());
if (category == HW_Category_MemoryLoad)
{
return true;
@@ -21391,42 +21406,17 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad() const
else if (HWIntrinsicInfo::MaybeMemoryLoad(GetHWIntrinsicId()))
{
// Some intrinsics (without HW_Category_MemoryLoad) also have MemoryLoad semantics
- // This is generally because they have both vector and pointer overloads, e.g.,
- // * Vector128 BroadcastScalarToVector128(Vector128 value)
- // * Vector128 BroadcastScalarToVector128(byte* source)
- // So, we need to check the argument's type is memory-reference or Vector128
- if ((category == HW_Category_SimpleSIMD) || (category == HW_Category_SIMDScalar))
+ if (category == HW_Category_SIMDScalar)
{
+ // Avx2.BroadcastScalarToVector128/256 have vector and pointer overloads both, e.g.,
+ // Vector128 BroadcastScalarToVector128(Vector128 value)
+ // Vector128 BroadcastScalarToVector128(byte* source)
+ // So, we need to check the argument's type is memory-reference or Vector128
assert(GetOperandCount() == 1);
-
- switch (intrinsicId)
- {
- case NI_SSE41_ConvertToVector128Int16:
- case NI_SSE41_ConvertToVector128Int32:
- case NI_SSE41_ConvertToVector128Int64:
- case NI_AVX2_BroadcastScalarToVector128:
- case NI_AVX2_BroadcastScalarToVector256:
- case NI_AVX2_ConvertToVector256Int16:
- case NI_AVX2_ConvertToVector256Int32:
- case NI_AVX2_ConvertToVector256Int64:
- {
- CorInfoType auxiliaryType = GetAuxiliaryJitType();
-
- if (auxiliaryType == CORINFO_TYPE_PTR)
- {
- return true;
- }
-
- assert(auxiliaryType == CORINFO_TYPE_UNDEF);
- return false;
- }
-
- default:
- {
- unreached();
- }
- }
+ return (GetHWIntrinsicId() == NI_AVX2_BroadcastScalarToVector128 ||
+ GetHWIntrinsicId() == NI_AVX2_BroadcastScalarToVector256) &&
+ !Op(1)->TypeIs(TYP_SIMD16);
}
else if (category == HW_Category_IMM)
{
@@ -22025,7 +22015,8 @@ bool GenTreeLclFld::IsOffsetMisaligned() const
bool GenTree::IsInvariant() const
{
- return OperIsConst() || Compiler::impIsAddressInLocal(this);
+ GenTree* lclVarTree = nullptr;
+ return OperIsConst() || Compiler::impIsAddressInLocal(this, &lclVarTree);
}
//------------------------------------------------------------------------
diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h
index 085bc17a1e510..3c5fff088cef1 100644
--- a/src/coreclr/jit/gentree.h
+++ b/src/coreclr/jit/gentree.h
@@ -1235,10 +1235,12 @@ struct GenTree
bool OperIsBlkOp();
bool OperIsCopyBlkOp();
bool OperIsInitBlkOp();
+ bool OperIsDynBlkOp();
static bool OperIsBlk(genTreeOps gtOper)
{
- return (gtOper == GT_BLK) || (gtOper == GT_OBJ) || OperIsStoreBlk(gtOper);
+ return ((gtOper == GT_BLK) || (gtOper == GT_OBJ) || (gtOper == GT_DYN_BLK) || (gtOper == GT_STORE_BLK) ||
+ (gtOper == GT_STORE_OBJ) || (gtOper == GT_STORE_DYN_BLK));
}
bool OperIsBlk() const
@@ -1246,9 +1248,19 @@ struct GenTree
return OperIsBlk(OperGet());
}
+ static bool OperIsDynBlk(genTreeOps gtOper)
+ {
+ return ((gtOper == GT_DYN_BLK) || (gtOper == GT_STORE_DYN_BLK));
+ }
+
+ bool OperIsDynBlk() const
+ {
+ return OperIsDynBlk(OperGet());
+ }
+
static bool OperIsStoreBlk(genTreeOps gtOper)
{
- return StaticOperIs(gtOper, GT_STORE_BLK, GT_STORE_OBJ, GT_STORE_DYN_BLK);
+ return ((gtOper == GT_STORE_BLK) || (gtOper == GT_STORE_OBJ) || (gtOper == GT_STORE_DYN_BLK));
}
bool OperIsStoreBlk() const
@@ -1692,8 +1704,6 @@ struct GenTree
inline bool IsIntegralConst(ssize_t constVal) const;
inline bool IsIntegralConstVector(ssize_t constVal) const;
inline bool IsSIMDZero() const;
- inline bool IsFloatPositiveZero() const;
- inline bool IsVectorZero() const;
inline bool IsBoxedValue();
@@ -1907,7 +1917,7 @@ struct GenTree
// where Y is an arbitrary tree, and X is a lclVar.
unsigned IsLclVarUpdateTree(GenTree** otherTree, genTreeOps* updateOper);
- bool IsFieldAddr(Compiler* comp, GenTree** pBaseAddr, FieldSeqNode** pFldSeq);
+ bool IsFieldAddr(Compiler* comp, GenTree** pObj, GenTree** pStatic, FieldSeqNode** pFldSeq);
// Requires "this" to be the address of an array (the child of a GT_IND labeled with GTF_IND_ARR_INDEX).
// Sets "pArr" to the node representing the array (either an array object pointer, or perhaps a byref to the some
@@ -2066,14 +2076,9 @@ struct GenTree
SetAllEffectsFlags(source->gtFlags & GTF_ALL_EFFECT);
}
- void SetAllEffectsFlags(GenTree* firstSource, GenTree* secondSource)
- {
- SetAllEffectsFlags((firstSource->gtFlags | secondSource->gtFlags) & GTF_ALL_EFFECT);
- }
-
- void SetAllEffectsFlags(GenTree* firstSource, GenTree* secondSource, GenTree* thirdSouce)
+ void SetAllEffectsFlags(GenTree* source, GenTree* otherSource)
{
- SetAllEffectsFlags((firstSource->gtFlags | secondSource->gtFlags | thirdSouce->gtFlags) & GTF_ALL_EFFECT);
+ SetAllEffectsFlags((source->gtFlags | otherSource->gtFlags) & GTF_ALL_EFFECT);
}
void SetAllEffectsFlags(GenTreeFlags sourceFlags)
@@ -2092,7 +2097,7 @@ struct GenTree
inline bool IsCnsFltOrDbl() const;
- inline bool IsCnsNonZeroFltOrDbl() const;
+ inline bool IsCnsNonZeroFltOrDbl();
bool IsIconHandle() const
{
@@ -2738,6 +2743,7 @@ class GenTreeUseEdgeIterator final
void AdvanceCmpXchg();
void AdvanceArrElem();
void AdvanceArrOffset();
+ void AdvanceDynBlk();
void AdvanceStoreDynBlk();
void AdvanceFieldList();
void AdvancePhi();
@@ -5977,6 +5983,8 @@ struct GenTreeAddrMode : public GenTreeOp
struct GenTreeIndir : public GenTreeOp
{
// The address for the indirection.
+ // Since GenTreeDynBlk derives from this, but is an "EXOP" (i.e. it has extra fields),
+ // we can't access Op1 and Op2 in the normal manner if we may have a DynBlk.
GenTree*& Addr()
{
return gtOp1;
@@ -6043,7 +6051,7 @@ struct GenTreeBlk : public GenTreeIndir
void SetLayout(ClassLayout* layout)
{
- assert((layout != nullptr) || OperIs(GT_STORE_DYN_BLK));
+ assert((layout != nullptr) || OperIs(GT_DYN_BLK, GT_STORE_DYN_BLK));
m_layout = layout;
}
@@ -6060,7 +6068,7 @@ struct GenTreeBlk : public GenTreeIndir
// The size of the buffer to be copied.
unsigned Size() const
{
- assert((m_layout != nullptr) || OperIs(GT_STORE_DYN_BLK));
+ assert((m_layout != nullptr) || OperIs(GT_DYN_BLK, GT_STORE_DYN_BLK));
return (m_layout != nullptr) ? m_layout->GetSize() : 0;
}
@@ -6098,7 +6106,7 @@ struct GenTreeBlk : public GenTreeIndir
#endif
{
assert(OperIsBlk(oper));
- assert((layout != nullptr) || OperIs(GT_STORE_DYN_BLK));
+ assert((layout != nullptr) || OperIs(GT_DYN_BLK, GT_STORE_DYN_BLK));
gtFlags |= (addr->gtFlags & GTF_ALL_EFFECT);
}
@@ -6111,7 +6119,7 @@ struct GenTreeBlk : public GenTreeIndir
#endif
{
assert(OperIsBlk(oper));
- assert((layout != nullptr) || OperIs(GT_STORE_DYN_BLK));
+ assert((layout != nullptr) || OperIs(GT_DYN_BLK, GT_STORE_DYN_BLK));
gtFlags |= (addr->gtFlags & GTF_ALL_EFFECT);
gtFlags |= (data->gtFlags & GTF_ALL_EFFECT);
}
@@ -6160,33 +6168,28 @@ struct GenTreeObj : public GenTreeBlk
#endif
};
-// GenTreeStoreDynBlk -- 'dynamic block store' (GT_STORE_DYN_BLK).
+// gtDynBlk -- 'dynamic block' (GT_DYN_BLK).
//
-// This node is used to represent stores that have a dynamic size - the "cpblk" and "initblk"
-// IL instructions are implemented with it. Note that such stores assume the input has no GC
-// pointers in it, and as such do not ever use write barriers.
-//
-// The "Data()" member of this node will either be a "dummy" IND(struct) node, for "cpblk", or
-// the zero constant/INIT_VAL for "initblk".
-//
-struct GenTreeStoreDynBlk : public GenTreeBlk
+// This node is used for block values that have a dynamic size.
+// Note that such a value can never have GC pointers.
+
+struct GenTreeDynBlk : public GenTreeBlk
{
public:
GenTree* gtDynamicSize;
- GenTreeStoreDynBlk(GenTree* dstAddr, GenTree* data, GenTree* dynamicSize)
- : GenTreeBlk(GT_STORE_DYN_BLK, TYP_VOID, dstAddr, data, nullptr), gtDynamicSize(dynamicSize)
+ GenTreeDynBlk(GenTree* addr, GenTree* dynamicSize)
+ : GenTreeBlk(GT_DYN_BLK, TYP_STRUCT, addr, nullptr), gtDynamicSize(dynamicSize)
{
- // Conservatively the 'dstAddr' could be null or point into the global heap.
- // Likewise, this is a store and so must be marked with the GTF_ASG flag.
- gtFlags |= (GTF_ASG | GTF_EXCEPT | GTF_GLOB_REF);
+ // Conservatively the 'addr' could be null or point into the global heap.
+ gtFlags |= GTF_EXCEPT | GTF_GLOB_REF;
gtFlags |= (dynamicSize->gtFlags & GTF_ALL_EFFECT);
}
#if DEBUGGABLE_GENTREE
protected:
friend GenTree;
- GenTreeStoreDynBlk() : GenTreeBlk()
+ GenTreeDynBlk() : GenTreeBlk()
{
}
#endif // DEBUGGABLE_GENTREE
@@ -7485,7 +7488,20 @@ struct GenTreeCC final : public GenTree
inline bool GenTree::OperIsBlkOp()
{
- return ((gtOper == GT_ASG) && varTypeIsStruct(AsOp()->gtOp1)) || OperIsStoreBlk();
+ return ((gtOper == GT_ASG) && varTypeIsStruct(AsOp()->gtOp1)) || (OperIsBlk() && (AsBlk()->Data() != nullptr));
+}
+
+inline bool GenTree::OperIsDynBlkOp()
+{
+ if (gtOper == GT_ASG)
+ {
+ return gtGetOp1()->OperGet() == GT_DYN_BLK;
+ }
+ else if (gtOper == GT_STORE_DYN_BLK)
+ {
+ return true;
+ }
+ return false;
}
inline bool GenTree::OperIsInitBlkOp()
@@ -7634,79 +7650,6 @@ inline bool GenTree::IsSIMDZero() const
return false;
}
-//-------------------------------------------------------------------
-// IsFloatPositiveZero: returns true if this is exactly a const float value of postive zero (+0.0)
-//
-// Returns:
-// True if this represents a const floating-point value of exactly positive zero (+0.0).
-// Will return false if the value is negative zero (-0.0).
-//
-inline bool GenTree::IsFloatPositiveZero() const
-{
- return IsCnsFltOrDbl() && !IsCnsNonZeroFltOrDbl();
-}
-
-//-------------------------------------------------------------------
-// IsVectorZero: returns true if this is an integral or floating-point (SIMD or HW intrinsic) vector
-// with all its elements equal to zero.
-//
-// Returns:
-// True if this represents an integral or floating-point const (SIMD or HW intrinsic) vector with all its elements
-// equal to zero.
-//
-// TODO: We already have IsSIMDZero() and IsIntegralConstVector(0),
-// however, IsSIMDZero() does not cover hardware intrinsics, and IsIntegralConstVector(0) does not cover floating
-// point. In order to not risk adverse behaviour by modifying those, this function 'IsVectorZero' was introduced.
-// At some point, it makes sense to normalize this logic to be a single function call rather than have several
-// separate ones; preferably this one.
-inline bool GenTree::IsVectorZero() const
-{
-#ifdef FEATURE_SIMD
- if (gtOper == GT_SIMD)
- {
- const GenTreeSIMD* node = AsSIMD();
-
- if (node->GetSIMDIntrinsicId() == SIMDIntrinsicInit)
- {
- return (node->Op(1)->IsIntegralConst(0) || node->Op(1)->IsFloatPositiveZero());
- }
- }
-#endif
-
-#ifdef FEATURE_HW_INTRINSICS
- if (gtOper == GT_HWINTRINSIC)
- {
- const GenTreeHWIntrinsic* node = AsHWIntrinsic();
- const var_types simdBaseType = node->GetSimdBaseType();
-
- if (varTypeIsIntegral(simdBaseType) || varTypeIsFloating(simdBaseType))
- {
- const NamedIntrinsic intrinsicId = node->GetHWIntrinsicId();
-
- if (node->GetOperandCount() == 0)
- {
-#if defined(TARGET_XARCH)
- return (intrinsicId == NI_Vector128_get_Zero) || (intrinsicId == NI_Vector256_get_Zero);
-#elif defined(TARGET_ARM64)
- return (intrinsicId == NI_Vector64_get_Zero) || (intrinsicId == NI_Vector128_get_Zero);
-#endif // !TARGET_XARCH && !TARGET_ARM64
- }
- else if ((node->GetOperandCount() == 1) &&
- (node->Op(1)->IsIntegralConst(0) || node->Op(1)->IsFloatPositiveZero()))
- {
-#if defined(TARGET_XARCH)
- return (intrinsicId == NI_Vector128_Create) || (intrinsicId == NI_Vector256_Create);
-#elif defined(TARGET_ARM64)
- return (intrinsicId == NI_Vector64_Create) || (intrinsicId == NI_Vector128_Create);
-#endif // !TARGET_XARCH && !TARGET_ARM64
- }
- }
- }
-#endif // FEATURE_HW_INTRINSICS
-
- return false;
-}
-
inline bool GenTree::IsBoxedValue()
{
assert(gtOper != GT_BOX || AsBox()->BoxOp() != nullptr);
@@ -8385,7 +8328,7 @@ inline bool GenTree::IsCnsFltOrDbl() const
return OperGet() == GT_CNS_DBL;
}
-inline bool GenTree::IsCnsNonZeroFltOrDbl() const
+inline bool GenTree::IsCnsNonZeroFltOrDbl()
{
if (OperGet() == GT_CNS_DBL)
{
diff --git a/src/coreclr/jit/gtlist.h b/src/coreclr/jit/gtlist.h
index 9b40861fef0fd..5a5afe6aad050 100644
--- a/src/coreclr/jit/gtlist.h
+++ b/src/coreclr/jit/gtlist.h
@@ -90,7 +90,8 @@ GTNODE(OBJ , GenTreeObj ,0,(GTK_UNOP|GTK_EXOP))
GTNODE(STORE_OBJ , GenTreeObj ,0,(GTK_BINOP|GTK_EXOP|GTK_NOVALUE)) // Object that MAY have gc pointers, and thus includes the relevant gc layout info.
GTNODE(BLK , GenTreeBlk ,0,(GTK_UNOP|GTK_EXOP)) // Block/object with no gc pointers, and with a known size (e.g. a struct with no gc fields)
GTNODE(STORE_BLK , GenTreeBlk ,0,(GTK_BINOP|GTK_EXOP|GTK_NOVALUE)) // Block/object with no gc pointers, and with a known size (e.g. a struct with no gc fields)
-GTNODE(STORE_DYN_BLK , GenTreeStoreDynBlk ,0,(GTK_SPECIAL|GTK_NOVALUE)) // Dynamically sized block store
+GTNODE(DYN_BLK , GenTreeDynBlk ,0,GTK_SPECIAL) // Dynamically sized block object
+GTNODE(STORE_DYN_BLK , GenTreeDynBlk ,0,(GTK_SPECIAL|GTK_NOVALUE)) // Dynamically sized block object
GTNODE(BOX , GenTreeBox ,0,(GTK_UNOP|GTK_EXOP|GTK_NOTLIR))
GTNODE(FIELD , GenTreeField ,0,(GTK_UNOP|GTK_EXOP)) // Member-field
diff --git a/src/coreclr/jit/gtstructs.h b/src/coreclr/jit/gtstructs.h
index 6373011779020..591753837fe89 100644
--- a/src/coreclr/jit/gtstructs.h
+++ b/src/coreclr/jit/gtstructs.h
@@ -92,14 +92,14 @@ GTSTRUCT_2(ClsVar , GT_CLS_VAR, GT_CLS_VAR_ADDR)
GTSTRUCT_1(ArgPlace , GT_ARGPLACE)
GTSTRUCT_1(CmpXchg , GT_CMPXCHG)
GTSTRUCT_1(AddrMode , GT_LEA)
-GTSTRUCT_N(Blk , GT_BLK, GT_STORE_BLK, GT_OBJ, GT_STORE_OBJ, GT_STORE_DYN_BLK)
+GTSTRUCT_N(Blk , GT_BLK, GT_STORE_BLK, GT_OBJ, GT_STORE_OBJ, GT_DYN_BLK, GT_STORE_DYN_BLK)
GTSTRUCT_2(Obj , GT_OBJ, GT_STORE_OBJ)
-GTSTRUCT_1(StoreDynBlk , GT_STORE_DYN_BLK)
+GTSTRUCT_2(DynBlk , GT_DYN_BLK, GT_STORE_DYN_BLK)
GTSTRUCT_1(Qmark , GT_QMARK)
GTSTRUCT_1(PhiArg , GT_PHI_ARG)
GTSTRUCT_1(Phi , GT_PHI)
GTSTRUCT_1(StoreInd , GT_STOREIND)
-GTSTRUCT_N(Indir , GT_STOREIND, GT_IND, GT_NULLCHECK, GT_BLK, GT_STORE_BLK, GT_OBJ, GT_STORE_OBJ, GT_STORE_DYN_BLK)
+GTSTRUCT_N(Indir , GT_STOREIND, GT_IND, GT_NULLCHECK, GT_BLK, GT_STORE_BLK, GT_OBJ, GT_STORE_OBJ, GT_DYN_BLK, GT_STORE_DYN_BLK)
#if FEATURE_ARG_SPLIT
GTSTRUCT_2_SPECIAL(PutArgStk, GT_PUTARG_STK, GT_PUTARG_SPLIT)
GTSTRUCT_1(PutArgSplit , GT_PUTARG_SPLIT)
diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp
index fe9729ee7a9f1..dfde343fe52cb 100644
--- a/src/coreclr/jit/hwintrinsic.cpp
+++ b/src/coreclr/jit/hwintrinsic.cpp
@@ -285,26 +285,7 @@ NamedIntrinsic HWIntrinsicInfo::lookupId(Compiler* comp,
bool isIsaSupported = comp->compSupportsHWIntrinsic(isa);
- bool isHardwareAcceleratedProp = (strcmp(methodName, "get_IsHardwareAccelerated") == 0);
-#ifdef TARGET_XARCH
- if (isHardwareAcceleratedProp)
- {
- // Special case: Some of Vector128/256 APIs are hardware accelerated with Sse1 and Avx1,
- // but we want IsHardwareAccelerated to return true only when all of them are (there are
- // still can be cases where e.g. Sse41 might give an additional boost for Vector128, but it's
- // not important enough to bump the minimal Sse version here)
- if (strcmp(className, "Vector128") == 0)
- {
- isa = InstructionSet_SSE2;
- }
- else if (strcmp(className, "Vector256") == 0)
- {
- isa = InstructionSet_AVX2;
- }
- }
-#endif
-
- if ((strcmp(methodName, "get_IsSupported") == 0) || isHardwareAcceleratedProp)
+ if ((strcmp(methodName, "get_IsSupported") == 0) || (strcmp(methodName, "get_IsHardwareAccelerated") == 0))
{
return isIsaSupported ? (comp->compExactlyDependsOn(isa) ? NI_IsSupported_True : NI_IsSupported_Dynamic)
: NI_IsSupported_False;
@@ -1026,41 +1007,6 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
retNode = isScalar ? gtNewScalarHWIntrinsicNode(retType, op1, intrinsic)
: gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, simdBaseJitType, simdSize);
-
-#if defined(TARGET_XARCH)
- switch (intrinsic)
- {
- case NI_SSE41_ConvertToVector128Int16:
- case NI_SSE41_ConvertToVector128Int32:
- case NI_SSE41_ConvertToVector128Int64:
- case NI_AVX2_BroadcastScalarToVector128:
- case NI_AVX2_BroadcastScalarToVector256:
- case NI_AVX2_ConvertToVector256Int16:
- case NI_AVX2_ConvertToVector256Int32:
- case NI_AVX2_ConvertToVector256Int64:
- {
- // These intrinsics have both pointer and vector overloads
- // We want to be able to differentiate between them so lets
- // just track the aux type as a ptr or undefined, depending
-
- CorInfoType auxiliaryType = CORINFO_TYPE_UNDEF;
-
- if (!varTypeIsSIMD(op1->TypeGet()))
- {
- auxiliaryType = CORINFO_TYPE_PTR;
- }
-
- retNode->AsHWIntrinsic()->SetAuxiliaryJitType(auxiliaryType);
- break;
- }
-
- default:
- {
- break;
- }
- }
-#endif // TARGET_XARCH
-
break;
case 2:
diff --git a/src/coreclr/jit/hwintrinsic.h b/src/coreclr/jit/hwintrinsic.h
index 4551ed9e4e1ce..43bd543c599f1 100644
--- a/src/coreclr/jit/hwintrinsic.h
+++ b/src/coreclr/jit/hwintrinsic.h
@@ -577,25 +577,6 @@ struct HWIntrinsicInfo
return lookup(id).ins[type - TYP_BYTE];
}
- static instruction lookupIns(GenTreeHWIntrinsic* intrinsicNode)
- {
- assert(intrinsicNode != nullptr);
-
- NamedIntrinsic intrinsic = intrinsicNode->GetHWIntrinsicId();
- var_types type = TYP_UNKNOWN;
-
- if (lookupCategory(intrinsic) == HW_Category_Scalar)
- {
- type = intrinsicNode->TypeGet();
- }
- else
- {
- type = intrinsicNode->GetSimdBaseType();
- }
-
- return lookupIns(intrinsic, type);
- }
-
static HWIntrinsicCategory lookupCategory(NamedIntrinsic id)
{
return lookup(id).category;
diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp
index 3e5c612236050..0c1b01e64ed93 100644
--- a/src/coreclr/jit/hwintrinsicarm64.cpp
+++ b/src/coreclr/jit/hwintrinsicarm64.cpp
@@ -339,7 +339,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
GenTree* op1 = nullptr;
GenTree* op2 = nullptr;
GenTree* op3 = nullptr;
- GenTree* op4 = nullptr;
switch (intrinsic)
{
@@ -602,16 +601,11 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 2);
- if (!varTypeIsLong(simdBaseType))
- {
- var_types simdType = getSIMDTypeForSize(simdSize);
-
- op2 = impSIMDPopStack(simdType);
- op1 = impSIMDPopStack(simdType);
+ op2 = impSIMDPopStack(retType);
+ op1 = impSIMDPopStack(retType);
- retNode = gtNewSimdDotProdNode(retType, op1, op2, simdBaseJitType, simdSize,
- /* isSimdAsHWIntrinsic */ false);
- }
+ retNode =
+ gtNewSimdDotProdNode(retType, op1, op2, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
break;
}
@@ -687,8 +681,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
case TYP_UBYTE:
{
op2 = gtNewIconNode(0x80);
- simdBaseType = TYP_UBYTE;
- simdBaseJitType = CORINFO_TYPE_UBYTE;
vectorCreateOp1 = gtNewLconNode(0x00FFFEFDFCFBFAF9);
if (simdSize == 16)
@@ -713,6 +705,30 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
case TYP_INT:
case TYP_UINT:
+ {
+ op2 = gtNewIconNode(0x80000000);
+ vectorCreateOp1 = gtNewLconNode(0xFFFFFFE2FFFFFFE1);
+
+ if (simdSize == 16)
+ {
+ vectorCreateOp2 = gtNewLconNode(0xFFFFFFE4FFFFFFE3);
+ }
+ break;
+ }
+
+ case TYP_LONG:
+ case TYP_ULONG:
+ {
+ op2 = gtNewLconNode(0x8000000000000000);
+ vectorCreateOp1 = gtNewLconNode(0xFFFFFFFFFFFFFFC1);
+
+ if (simdSize == 16)
+ {
+ vectorCreateOp2 = gtNewLconNode(0xFFFFFFFFFFFFFFC2);
+ }
+ break;
+ }
+
case TYP_FLOAT:
{
op2 = gtNewIconNode(0x80000000);
@@ -727,8 +743,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case TYP_LONG:
- case TYP_ULONG:
case TYP_DOUBLE:
{
op2 = gtNewLconNode(0x8000000000000000);
@@ -760,27 +774,17 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
gtNewSimdHWIntrinsicNode(simdType, vectorCreateOp1, NI_Vector64_Create, vectorCreateType, simdSize);
}
- op2 =
- gtNewSimdCreateBroadcastNode(simdType, op2, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
-
op1 = gtNewSimdHWIntrinsicNode(simdType, op1, op2, NI_AdvSimd_And, simdBaseJitType, simdSize,
/* isSimdAsHWIntrinsic */ false);
- NamedIntrinsic shiftIntrinsic = NI_AdvSimd_ShiftLogical;
-
- if ((simdSize == 8) && varTypeIsLong(simdBaseType))
- {
- shiftIntrinsic = NI_AdvSimd_ShiftLogicalScalar;
- }
-
- op1 = gtNewSimdHWIntrinsicNode(simdType, op1, op3, shiftIntrinsic, simdBaseJitType, simdSize,
+ op1 = gtNewSimdHWIntrinsicNode(simdType, op1, op3, NI_AdvSimd_ShiftLogical, simdBaseJitType, simdSize,
/* isSimdAsHWIntrinsic */ false);
if (varTypeIsByte(simdBaseType) && (simdSize == 16))
{
- CORINFO_CLASS_HANDLE simdClsHnd = gtGetStructHandleForSIMD(simdType, simdBaseJitType);
+ CORINFO_CLASS_HANDLE clsHnd = gtGetStructHandleForSIMD(simdType, simdBaseJitType);
- op1 = impCloneExpr(op1, &op2, simdClsHnd, (unsigned)CHECK_SPILL_ALL,
+ op1 = impCloneExpr(op1, &op2, clsHnd, (unsigned)CHECK_SPILL_ALL,
nullptr DEBUGARG("Clone op1 for vector extractmostsignificantbits"));
op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_Vector128_GetLower, simdBaseJitType, simdSize,
@@ -789,9 +793,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
/* isSimdAsHWIntrinsic */ false);
op1 = gtNewSimdHWIntrinsicNode(simdBaseType, op1, NI_Vector64_ToScalar, simdBaseJitType, 8,
/* isSimdAsHWIntrinsic */ false);
- op1 = gtNewCastNode(TYP_INT, op1, /* isUnsigned */ true, TYP_INT);
+ op1 = gtNewCastNode(TYP_INT, op1, /* isUnsigned */ true, simdBaseType);
- GenTree* zero = gtNewSimdZeroNode(simdType, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
+ GenTree* zero = gtNewSimdHWIntrinsicNode(retType, NI_Vector128_get_Zero, simdBaseJitType, simdSize);
ssize_t index = 8 / genTypeSize(simdBaseType);
op2 = gtNewSimdHWIntrinsicNode(simdType, op2, zero, gtNewIconNode(index), NI_AdvSimd_ExtractVector128,
@@ -802,7 +806,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
/* isSimdAsHWIntrinsic */ false);
op2 = gtNewSimdHWIntrinsicNode(simdBaseType, op2, NI_Vector64_ToScalar, simdBaseJitType, 8,
/* isSimdAsHWIntrinsic */ false);
- op2 = gtNewCastNode(TYP_INT, op2, /* isUnsigned */ true, TYP_INT);
+ op2 = gtNewCastNode(TYP_INT, op2, /* isUnsigned */ true, simdBaseType);
op2 = gtNewOperNode(GT_LSH, TYP_INT, op2, gtNewIconNode(8));
retNode = gtNewOperNode(GT_OR, TYP_INT, op1, op2);
@@ -811,20 +815,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
{
if (!varTypeIsLong(simdBaseType))
{
- if ((simdSize == 8) && ((simdBaseType == TYP_INT) || (simdBaseType == TYP_UINT)))
- {
- CORINFO_CLASS_HANDLE simdClsHnd = gtGetStructHandleForSIMD(simdType, simdBaseJitType);
-
- op1 = impCloneExpr(op1, &op2, simdClsHnd, (unsigned)CHECK_SPILL_ALL,
- nullptr DEBUGARG("Clone op1 for vector extractmostsignificantbits"));
- op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, op2, NI_AdvSimd_AddPairwise, simdBaseJitType,
- simdSize, /* isSimdAsHWIntrinsic */ false);
- }
- else
- {
- op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType,
- simdSize, /* isSimdAsHWIntrinsic */ false);
- }
+ op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType,
+ simdSize, /* isSimdAsHWIntrinsic */ false);
}
else if (simdSize == 16)
{
@@ -837,7 +829,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
if ((simdBaseType != TYP_INT) && (simdBaseType != TYP_UINT))
{
- retNode = gtNewCastNode(TYP_INT, retNode, /* isUnsigned */ true, TYP_INT);
+ retNode = gtNewCastNode(TYP_INT, retNode, /* isUnsigned */ true, simdBaseType);
}
}
break;
@@ -1406,10 +1398,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector128_Store:
{
assert(sig->numArgs == 2);
- var_types simdType = getSIMDTypeForSize(simdSize);
op2 = impPopStack().val;
- op1 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(retType);
retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, NI_AdvSimd_Store, simdBaseJitType, simdSize);
break;
@@ -1419,7 +1410,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector128_StoreAligned:
{
assert(sig->numArgs == 2);
- var_types simdType = getSIMDTypeForSize(simdSize);
if (!opts.MinOpts())
{
@@ -1429,7 +1419,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
}
op2 = impPopStack().val;
- op1 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(retType);
retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, NI_AdvSimd_Store, simdBaseJitType, simdSize);
break;
@@ -1439,7 +1429,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector128_StoreAlignedNonTemporal:
{
assert(sig->numArgs == 2);
- var_types simdType = getSIMDTypeForSize(simdSize);
if (!opts.MinOpts())
{
@@ -1449,7 +1438,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
}
op2 = impPopStack().val;
- op1 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(retType);
// ARM64 has non-temporal stores (STNP) but we don't currently support them
@@ -1460,8 +1449,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector64_StoreUnsafe:
case NI_Vector128_StoreUnsafe:
{
- var_types simdType = getSIMDTypeForSize(simdSize);
-
if (sig->numArgs == 3)
{
op3 = impPopStack().val;
@@ -1472,13 +1459,13 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
}
op2 = impPopStack().val;
- op1 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(retType);
if (sig->numArgs == 3)
{
- op4 = gtNewIconNode(genTypeSize(simdBaseType), op3->TypeGet());
- op3 = gtNewOperNode(GT_MUL, op3->TypeGet(), op3, op4);
- op2 = gtNewOperNode(GT_ADD, op2->TypeGet(), op2, op3);
+ op3 = gtNewIconNode(genTypeSize(simdBaseType), op2->TypeGet());
+ op2 = gtNewOperNode(GT_MUL, op2->TypeGet(), op2, op3);
+ op2 = gtNewOperNode(GT_ADD, op1->TypeGet(), op1, op2);
}
retNode = gtNewSimdHWIntrinsicNode(retType, op2, op1, NI_AdvSimd_Store, simdBaseJitType, simdSize);
@@ -1489,9 +1476,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector128_Sum:
{
assert(sig->numArgs == 1);
- var_types simdType = getSIMDTypeForSize(simdSize);
- op1 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(retType);
retNode = gtNewSimdSumNode(retType, op1, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
break;
}
diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp
index 6dfe48047c094..706b988f049e5 100644
--- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp
+++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp
@@ -206,9 +206,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
{
const HWIntrinsic intrin(node);
- // We need to validate that other phases of the compiler haven't introduced unsupported intrinsics
- assert(compiler->compIsaSupportedDebugOnly(HWIntrinsicInfo::lookupIsa(intrin.id)));
-
regNumber targetReg = node->GetRegNum();
regNumber op1Reg = REG_NA;
@@ -499,29 +496,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt);
break;
- case NI_AdvSimd_CompareEqual:
- case NI_AdvSimd_Arm64_CompareEqual:
- case NI_AdvSimd_Arm64_CompareEqualScalar:
- if (intrin.op1->isContained())
- {
- assert(HWIntrinsicInfo::SupportsContainment(intrin.id));
- assert(intrin.op1->IsVectorZero());
-
- GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt);
- }
- else if (intrin.op2->isContained())
- {
- assert(HWIntrinsicInfo::SupportsContainment(intrin.id));
- assert(intrin.op2->IsVectorZero());
-
- GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op1Reg, opt);
- }
- else
- {
- GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt);
- }
- break;
-
case NI_AdvSimd_AbsoluteCompareLessThan:
case NI_AdvSimd_AbsoluteCompareLessThanOrEqual:
case NI_AdvSimd_CompareLessThan:
diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp
index 10c8dcaedb197..cd9e0f8f8fc3d 100644
--- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp
+++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp
@@ -27,13 +27,11 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// assertIsContainableHWIntrinsicOp: Asserts that op is containable by node
//
// Arguments:
-// lowering - The lowering phase from the compiler
-// containingNode - The HWIntrinsic node that has the contained node
-// containedNode - The node that is contained
+// lowering - The lowering phase from the compiler
+// node - The HWIntrinsic node that has the contained node
+// op - The op that is contained
//
-static void assertIsContainableHWIntrinsicOp(Lowering* lowering,
- GenTreeHWIntrinsic* containingNode,
- GenTree* containedNode)
+static void assertIsContainableHWIntrinsicOp(Lowering* lowering, GenTreeHWIntrinsic* node, GenTree* op)
{
#if DEBUG
// The Lowering::IsContainableHWIntrinsicOp call is not quite right, since it follows pre-register allocation
@@ -41,15 +39,14 @@ static void assertIsContainableHWIntrinsicOp(Lowering* lowering,
//
// We use isContainable to track the special HWIntrinsic node containment rules (for things like LoadAligned and
// LoadUnaligned) and we use the supportsRegOptional check to support general-purpose loads (both from stack
- // spillage and for isUsedFromMemory contained nodes, in the case where the register allocator decided to not
- // allocate a register in the first place).
-
- GenTree* node = containedNode;
- bool supportsRegOptional = false;
- bool isContainable = lowering->TryGetContainableHWIntrinsicOp(containingNode, &node, &supportsRegOptional);
+ // spillage
+ // and for isUsedFromMemory contained nodes, in the case where the register allocator decided to not allocate a
+ // register
+ // in the first place).
+ bool supportsRegOptional = false;
+ bool isContainable = lowering->IsContainableHWIntrinsicOp(node, op, &supportsRegOptional);
assert(isContainable || supportsRegOptional);
- assert(node == containedNode);
#endif // DEBUG
}
@@ -86,9 +83,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId);
size_t numArgs = node->GetOperandCount();
- // We need to validate that other phases of the compiler haven't introduced unsupported intrinsics
- assert(compiler->compIsaSupportedDebugOnly(isa));
-
int ival = HWIntrinsicInfo::lookupIval(intrinsicId, compiler->compOpportunisticallyDependsOn(InstructionSet_AVX));
assert(HWIntrinsicInfo::RequiresCodegen(intrinsicId));
@@ -527,14 +521,6 @@ void CodeGen::genHWIntrinsic_R_RM(
break;
}
- case GT_CNS_DBL:
- {
- GenTreeDblCon* cns = rmOp->AsDblCon();
- CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(cns->gtDconVal, emitTypeSize(cns));
- emit->emitIns_R_C(ins, attr, reg, hnd, 0);
- return;
- }
-
default:
{
unreached();
@@ -751,14 +737,6 @@ void CodeGen::genHWIntrinsic_R_R_RM_I(GenTreeHWIntrinsic* node, instruction ins,
break;
}
- case GT_CNS_DBL:
- {
- GenTreeDblCon* cns = op2->AsDblCon();
- CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(cns->gtDconVal, emitTypeSize(cns));
- emit->emitIns_SIMD_R_R_C_I(ins, simdSize, targetReg, op1Reg, hnd, 0, ival);
- return;
- }
-
default:
unreached();
break;
@@ -908,14 +886,6 @@ void CodeGen::genHWIntrinsic_R_R_RM_R(GenTreeHWIntrinsic* node, instruction ins,
break;
}
- case GT_CNS_DBL:
- {
- GenTreeDblCon* cns = op2->AsDblCon();
- CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(cns->gtDconVal, emitTypeSize(cns));
- emit->emitIns_SIMD_R_R_C_R(ins, simdSize, targetReg, op1Reg, op3Reg, hnd, 0);
- return;
- }
-
default:
unreached();
break;
@@ -1042,14 +1012,6 @@ void CodeGen::genHWIntrinsic_R_R_R_RM(
break;
}
- case GT_CNS_DBL:
- {
- GenTreeDblCon* cns = op3->AsDblCon();
- CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(cns->gtDconVal, emitTypeSize(cns));
- emit->emitIns_SIMD_R_R_R_C(ins, attr, targetReg, op1Reg, op2Reg, hnd, 0);
- return;
- }
-
default:
unreached();
break;
diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h
index 7d4582db97616..4b2e3fa132ad7 100644
--- a/src/coreclr/jit/hwintrinsiclistarm64.h
+++ b/src/coreclr/jit/hwintrinsiclistarm64.h
@@ -42,28 +42,28 @@ HARDWARE_INTRINSIC(Vector64, ConvertToUInt64,
HARDWARE_INTRINSIC(Vector64, Create, 8, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mov, INS_mov, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport)
HARDWARE_INTRINSIC(Vector64, CreateScalarUnsafe, 8, 1, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_invalid, INS_invalid, INS_fmov, INS_invalid}, HW_Category_SIMD, HW_Flag_SpecialCodeGen|HW_Flag_SupportsContainment)
HARDWARE_INTRINSIC(Vector64, Divide, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, Dot, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, Dot, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, Equals, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, EqualsAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, EqualsAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, ExtractMostSignificantBits, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, EqualsAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, EqualsAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, ExtractMostSignificantBits, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, Floor, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, get_AllBitsSet, 8, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport)
HARDWARE_INTRINSIC(Vector64, get_Count, 8, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport)
HARDWARE_INTRINSIC(Vector64, get_Zero, 8, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport)
HARDWARE_INTRINSIC(Vector64, GetElement, 8, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(Vector64, GreaterThan, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, GreaterThanAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, GreaterThanAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, GreaterThanAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, GreaterThanAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, GreaterThanOrEqual, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, GreaterThanOrEqualAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, GreaterThanOrEqualAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, GreaterThanOrEqualAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, GreaterThanOrEqualAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, LessThan, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, LessThanAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, LessThanAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, LessThanAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, LessThanAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, LessThanOrEqual, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, LessThanOrEqualAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, LessThanOrEqualAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, LessThanOrEqualAll, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, LessThanOrEqualAny, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, Load, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, LoadAligned, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, LoadAlignedNonTemporal, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
@@ -90,12 +90,12 @@ HARDWARE_INTRINSIC(Vector64, ShiftLeft,
HARDWARE_INTRINSIC(Vector64, ShiftRightArithmetic, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, ShiftRightLogical, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, Sqrt, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, Store, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, StoreAligned, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, StoreAlignedNonTemporal, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, StoreUnsafe, 8, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, Store, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, StoreAligned, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, StoreAlignedNonTemporal, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, StoreUnsafe, 8, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, Subtract, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector64, Sum, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector64, Sum, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector64, ToScalar, 8, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector64, ToVector128, 8, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SIMD, HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector64, ToVector128Unsafe, 8, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SIMD, HW_Flag_SpecialCodeGen)
@@ -140,11 +140,11 @@ HARDWARE_INTRINSIC(Vector128, ConvertToUInt64,
HARDWARE_INTRINSIC(Vector128, Create, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport)
HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, {INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_ins, INS_fmov, INS_fmov}, HW_Category_SIMD, HW_Flag_SpecialCodeGen|HW_Flag_SupportsContainment)
HARDWARE_INTRINSIC(Vector128, Divide, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, Dot, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, Dot, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, Equals, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, EqualsAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, EqualsAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, EqualsAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, EqualsAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, Floor, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport)
HARDWARE_INTRINSIC(Vector128, get_Count, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport)
@@ -153,17 +153,17 @@ HARDWARE_INTRINSIC(Vector128, GetElement,
HARDWARE_INTRINSIC(Vector128, GetLower, 16, 1, {INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov, INS_mov}, HW_Category_SIMD, HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector128, GetUpper, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialImport)
HARDWARE_INTRINSIC(Vector128, GreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, GreaterThanAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, GreaterThanAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, GreaterThanAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, GreaterThanAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, LessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, LessThanAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, LessThanAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, LessThanAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, LessThanAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, LessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, LessThanOrEqualAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, LessThanOrEqualAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, LessThanOrEqualAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, LessThanOrEqualAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, Load, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, LoadAligned, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, LoadAlignedNonTemporal, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
@@ -190,12 +190,12 @@ HARDWARE_INTRINSIC(Vector128, ShiftLeft,
HARDWARE_INTRINSIC(Vector128, ShiftRightArithmetic, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, ShiftRightLogical, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, Sqrt, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, Store, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, StoreAligned, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, StoreAlignedNonTemporal, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, StoreUnsafe, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, Store, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, StoreAligned, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, StoreAlignedNonTemporal, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, StoreUnsafe, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, Subtract, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, Sum, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, Sum, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, ToScalar, 16, 1, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(Vector128, WidenLower, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(Vector128, WidenUpper, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg)
@@ -240,7 +240,7 @@ HARDWARE_INTRINSIC(AdvSimd, BitwiseClear,
HARDWARE_INTRINSIC(AdvSimd, BitwiseSelect, -1, 3, {INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl, INS_bsl}, HW_Category_SIMD, HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(AdvSimd, Ceiling, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frintp, INS_invalid}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd, CeilingScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frintp, INS_frintp}, HW_Category_SIMD, HW_Flag_SIMDScalar)
-HARDWARE_INTRINSIC(AdvSimd, CompareEqual, -1, 2, {INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_invalid, INS_invalid, INS_fcmeq, INS_invalid}, HW_Category_SIMD, HW_Flag_Commutative|HW_Flag_SpecialCodeGen|HW_Flag_SupportsContainment)
+HARDWARE_INTRINSIC(AdvSimd, CompareEqual, -1, 2, {INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_cmeq, INS_invalid, INS_invalid, INS_fcmeq, INS_invalid}, HW_Category_SIMD, HW_Flag_Commutative)
HARDWARE_INTRINSIC(AdvSimd, CompareGreaterThan, -1, 2, {INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_invalid, INS_invalid, INS_fcmgt, INS_invalid}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd, CompareGreaterThanOrEqual, -1, 2, {INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_cmge, INS_cmhs, INS_invalid, INS_invalid, INS_fcmge, INS_invalid}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd, CompareLessThan, -1, 2, {INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_cmgt, INS_cmhi, INS_invalid, INS_invalid, INS_fcmgt, INS_invalid}, HW_Category_SIMD, HW_Flag_SpecialCodeGen)
@@ -492,8 +492,8 @@ HARDWARE_INTRINSIC(AdvSimd_Arm64, AddPairwiseScalar,
HARDWARE_INTRINSIC(AdvSimd_Arm64, AddSaturate, -1, 2, {INS_suqadd, INS_usqadd, INS_suqadd, INS_usqadd, INS_suqadd, INS_usqadd, INS_suqadd, INS_usqadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasRMWSemantics)
HARDWARE_INTRINSIC(AdvSimd_Arm64, AddSaturateScalar, 8, 2, {INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_sqadd, INS_uqadd, INS_suqadd, INS_usqadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(AdvSimd_Arm64, Ceiling, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_frintp}, HW_Category_SIMD, HW_Flag_NoFlag)
-HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmeq, INS_cmeq, INS_invalid, INS_fcmeq}, HW_Category_SIMD, HW_Flag_Commutative|HW_Flag_SpecialCodeGen|HW_Flag_SupportsContainment)
-HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmeq, INS_cmeq, INS_fcmeq, INS_fcmeq}, HW_Category_SIMD, HW_Flag_Commutative|HW_Flag_SIMDScalar|HW_Flag_SpecialCodeGen|HW_Flag_SupportsContainment)
+HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmeq, INS_cmeq, INS_invalid, INS_fcmeq}, HW_Category_SIMD, HW_Flag_Commutative)
+HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmeq, INS_cmeq, INS_fcmeq, INS_fcmeq}, HW_Category_SIMD, HW_Flag_Commutative|HW_Flag_SIMDScalar)
HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmgt, INS_cmhi, INS_invalid, INS_fcmgt}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmge, INS_cmhs, INS_invalid, INS_fcmge}, HW_Category_SIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, CompareGreaterThanOrEqualScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_cmge, INS_cmhs, INS_fcmge, INS_fcmge}, HW_Category_SIMD, HW_Flag_SIMDScalar)
diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h
index 7c80de358cf4e..95ab714ae6334 100644
--- a/src/coreclr/jit/hwintrinsiclistxarch.h
+++ b/src/coreclr/jit/hwintrinsiclistxarch.h
@@ -59,28 +59,28 @@ HARDWARE_INTRINSIC(Vector128, ConvertToUInt64,
HARDWARE_INTRINSIC(Vector128, Create, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, CreateScalarUnsafe, 16, 1, {INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movss, INS_movsdsse2}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector128, Divide, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, Dot, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, Dot, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, Equals, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, EqualsAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, EqualsAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, EqualsAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, EqualsAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, Floor, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, {INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_cmpps, INS_cmpps}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector128, get_Count, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, get_Zero, 16, 0, {INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(Vector128, GreaterThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, GreaterThanAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, GreaterThanAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, GreaterThanAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, GreaterThanAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, GreaterThanOrEqualAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, LessThan, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, LessThanAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, LessThanAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, LessThanAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, LessThanAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, LessThanOrEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, LessThanOrEqualAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, LessThanOrEqualAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, LessThanOrEqualAll, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, LessThanOrEqualAny, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, Load, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, LoadAligned, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, LoadAlignedNonTemporal, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
@@ -107,12 +107,12 @@ HARDWARE_INTRINSIC(Vector128, ShiftLeft,
HARDWARE_INTRINSIC(Vector128, ShiftRightArithmetic, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, ShiftRightLogical, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, Sqrt, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, Store, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, StoreAligned, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, StoreAlignedNonTemporal, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, StoreUnsafe, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, Store, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, StoreAligned, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, StoreAlignedNonTemporal, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, StoreUnsafe, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, Subtract, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector128, Sum, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector128, Sum, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector128, ToScalar, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movss, INS_movsdsse2}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector128, ToVector256, 16, 1, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector128, ToVector256Unsafe, 16, 1, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics)
@@ -155,11 +155,11 @@ HARDWARE_INTRINSIC(Vector256, ConvertToUInt64,
HARDWARE_INTRINSIC(Vector256, Create, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, CreateScalarUnsafe, 32, 1, {INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movd, INS_movss, INS_movsdsse2}, HW_Category_SIMDScalar, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector256, Divide, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, Dot, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, Dot, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, Equals, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, EqualsAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, EqualsAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, ExtractMostSignificantBits, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, EqualsAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, EqualsAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, ExtractMostSignificantBits, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, Floor, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, get_AllBitsSet, 32, 0, {INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_cmpps, INS_cmpps}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector256, get_Count, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
@@ -167,17 +167,17 @@ HARDWARE_INTRINSIC(Vector256, get_Zero,
HARDWARE_INTRINSIC(Vector256, GetElement, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(Vector256, GetLower, 32, 1, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movups, INS_movupd}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector256, GreaterThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, GreaterThanAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, GreaterThanAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, GreaterThanAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, GreaterThanAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, GreaterThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, GreaterThanOrEqualAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, GreaterThanOrEqualAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, GreaterThanOrEqualAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, GreaterThanOrEqualAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, LessThan, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, LessThanAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, LessThanAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, LessThanAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, LessThanAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, LessThanOrEqual, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, LessThanOrEqualAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, LessThanOrEqualAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, LessThanOrEqualAll, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, LessThanOrEqualAny, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, Load, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, LoadAligned, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, LoadAlignedNonTemporal, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
@@ -204,12 +204,12 @@ HARDWARE_INTRINSIC(Vector256, ShiftLeft,
HARDWARE_INTRINSIC(Vector256, ShiftRightArithmetic, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, ShiftRightLogical, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, Sqrt, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, Store, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, StoreAligned, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, StoreAlignedNonTemporal, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, StoreUnsafe, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, Store, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, StoreAligned, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, StoreAlignedNonTemporal, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, StoreUnsafe, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, Subtract, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
-HARDWARE_INTRINSIC(Vector256, Sum, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen)
+HARDWARE_INTRINSIC(Vector256, Sum, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen)
HARDWARE_INTRINSIC(Vector256, ToScalar, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movss, INS_movsdsse2}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(Vector256, WidenLower, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(Vector256, WidenUpper, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg)
@@ -494,9 +494,9 @@ HARDWARE_INTRINSIC(SSE41, BlendVariable,
HARDWARE_INTRINSIC(SSE41, Ceiling, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundps, INS_roundpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(SSE41, CeilingScalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundss, INS_roundsd}, HW_Category_SIMDScalar, HW_Flag_CopyUpperBits)
HARDWARE_INTRINSIC(SSE41, CompareEqual, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pcmpeqq, INS_pcmpeqq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative)
-HARDWARE_INTRINSIC(SSE41, ConvertToVector128Int16, 16, 1, {INS_pmovsxbw, INS_pmovzxbw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics|HW_Flag_MaybeMemoryLoad)
-HARDWARE_INTRINSIC(SSE41, ConvertToVector128Int32, 16, 1, {INS_pmovsxbd, INS_pmovzxbd, INS_pmovsxwd, INS_pmovzxwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics|HW_Flag_MaybeMemoryLoad)
-HARDWARE_INTRINSIC(SSE41, ConvertToVector128Int64, 16, 1, {INS_pmovsxbq, INS_pmovzxbq, INS_pmovsxwq, INS_pmovzxwq, INS_pmovsxdq, INS_pmovzxdq, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics|HW_Flag_MaybeMemoryLoad)
+HARDWARE_INTRINSIC(SSE41, ConvertToVector128Int16, 16, 1, {INS_pmovsxbw, INS_pmovzxbw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(SSE41, ConvertToVector128Int32, 16, 1, {INS_pmovsxbd, INS_pmovzxbd, INS_pmovsxwd, INS_pmovzxwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(SSE41, ConvertToVector128Int64, 16, 1, {INS_pmovsxbq, INS_pmovzxbq, INS_pmovsxwq, INS_pmovzxwq, INS_pmovsxdq, INS_pmovzxdq, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(SSE41, DotProduct, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_dpps, INS_dppd}, HW_Category_IMM, HW_Flag_FullRangeIMM)
HARDWARE_INTRINSIC(SSE41, Extract, 16, 2, {INS_pextrb, INS_pextrb, INS_invalid, INS_invalid, INS_pextrd, INS_pextrd, INS_invalid, INS_invalid, INS_extractps, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_BaseTypeFromFirstArg|HW_Flag_MultiIns|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(SSE41, Floor, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundps, INS_roundpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics)
@@ -649,9 +649,9 @@ HARDWARE_INTRINSIC(AVX2, CompareLessThan,
HARDWARE_INTRINSIC(AVX2, ExtractVector128, 32, 2, {INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM)
HARDWARE_INTRINSIC(AVX2, ConvertToInt32, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(AVX2, ConvertToUInt32, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_NoRMWSemantics)
-HARDWARE_INTRINSIC(AVX2, ConvertToVector256Int16, 32, 1, {INS_pmovsxbw, INS_pmovzxbw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_MaybeMemoryLoad)
-HARDWARE_INTRINSIC(AVX2, ConvertToVector256Int32, 32, 1, {INS_pmovsxbd, INS_pmovzxbd, INS_pmovsxwd, INS_pmovzxwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_MaybeMemoryLoad)
-HARDWARE_INTRINSIC(AVX2, ConvertToVector256Int64, 32, 1, {INS_pmovsxbq, INS_pmovzxbq, INS_pmovsxwq, INS_pmovzxwq, INS_pmovsxdq, INS_pmovzxdq, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_MaybeMemoryLoad)
+HARDWARE_INTRINSIC(AVX2, ConvertToVector256Int16, 32, 1, {INS_pmovsxbw, INS_pmovzxbw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg)
+HARDWARE_INTRINSIC(AVX2, ConvertToVector256Int32, 32, 1, {INS_pmovsxbd, INS_pmovzxbd, INS_pmovsxwd, INS_pmovzxwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg)
+HARDWARE_INTRINSIC(AVX2, ConvertToVector256Int64, 32, 1, {INS_pmovsxbq, INS_pmovzxbq, INS_pmovsxwq, INS_pmovzxwq, INS_pmovsxdq, INS_pmovzxdq, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(AVX2, GatherVector128, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpgatherdd, INS_vpgatherdd, INS_vpgatherdq, INS_vpgatherdq, INS_vgatherdps, INS_vgatherdpd}, HW_Category_IMM, HW_Flag_MaybeMemoryLoad|HW_Flag_SpecialCodeGen|HW_Flag_NoContainment)
HARDWARE_INTRINSIC(AVX2, GatherVector256, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpgatherdd, INS_vpgatherdd, INS_vpgatherdq, INS_vpgatherdq, INS_vgatherdps, INS_vgatherdpd}, HW_Category_IMM, HW_Flag_MaybeMemoryLoad|HW_Flag_SpecialCodeGen|HW_Flag_NoContainment)
HARDWARE_INTRINSIC(AVX2, GatherMaskVector128, 16, 5, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpgatherdd, INS_vpgatherdd, INS_vpgatherdq, INS_vpgatherdq, INS_vgatherdps, INS_vgatherdpd}, HW_Category_IMM, HW_Flag_MaybeMemoryLoad|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport|HW_Flag_NoContainment)
diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp
index aec1be705f3db..e6f499588c528 100644
--- a/src/coreclr/jit/hwintrinsicxarch.cpp
+++ b/src/coreclr/jit/hwintrinsicxarch.cpp
@@ -535,7 +535,6 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
GenTree* op1 = nullptr;
GenTree* op2 = nullptr;
GenTree* op3 = nullptr;
- GenTree* op4 = nullptr;
if (!featureSIMD || !IsBaselineSimdIsaSupported())
{
@@ -948,7 +947,6 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector256_Dot:
{
assert(sig->numArgs == 2);
- var_types simdType = getSIMDTypeForSize(simdSize);
if (varTypeIsByte(simdBaseType) || varTypeIsLong(simdBaseType))
{
@@ -975,8 +973,8 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
}
}
- op2 = impSIMDPopStack(simdType);
- op1 = impSIMDPopStack(simdType);
+ op2 = impSIMDPopStack(retType);
+ op1 = impSIMDPopStack(retType);
retNode =
gtNewSimdDotProdNode(retType, op1, op2, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
@@ -1024,7 +1022,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 2);
- if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2))
+ if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
{
var_types simdType = getSIMDTypeForSize(simdSize);
@@ -1046,136 +1044,23 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
{
var_types simdType = getSIMDTypeForSize(simdSize);
+ op1 = impSIMDPopStack(simdType);
+
NamedIntrinsic moveMaskIntrinsic = NI_Illegal;
- NamedIntrinsic shuffleIntrinsic = NI_Illegal;
- NamedIntrinsic createIntrinsic = NI_Illegal;
- switch (simdBaseType)
+ if (simdBaseType == TYP_FLOAT)
{
- case TYP_BYTE:
- case TYP_UBYTE:
- {
- op1 = impSIMDPopStack(simdType);
- moveMaskIntrinsic = (simdSize == 32) ? NI_AVX2_MoveMask : NI_SSE2_MoveMask;
- break;
- }
-
- case TYP_SHORT:
- case TYP_USHORT:
- {
- simdBaseJitType = varTypeIsUnsigned(simdBaseType) ? CORINFO_TYPE_UBYTE : CORINFO_TYPE_BYTE;
-
- assert((simdSize == 16) || (simdSize == 32));
- IntrinsicNodeBuilder nodeBuilder(getAllocator(CMK_ASTNode), simdSize);
-
- // We want to tightly pack the most significant byte of each short/ushort
- // and then zero the tightly packed least significant bytes
-
- nodeBuilder.AddOperand(0x00, gtNewIconNode(0x01));
- nodeBuilder.AddOperand(0x01, gtNewIconNode(0x03));
- nodeBuilder.AddOperand(0x02, gtNewIconNode(0x05));
- nodeBuilder.AddOperand(0x03, gtNewIconNode(0x07));
- nodeBuilder.AddOperand(0x04, gtNewIconNode(0x09));
- nodeBuilder.AddOperand(0x05, gtNewIconNode(0x0B));
- nodeBuilder.AddOperand(0x06, gtNewIconNode(0x0D));
- nodeBuilder.AddOperand(0x07, gtNewIconNode(0x0F));
-
- for (unsigned i = 0x08; i < 0x10; i++)
- {
- // The most significant bit being set means zero the value
- nodeBuilder.AddOperand(i, gtNewIconNode(0x80));
- }
-
- if (simdSize == 32)
- {
- // Vector256 works on 2x128-bit lanes, so repeat the same indices for the upper lane
-
- nodeBuilder.AddOperand(0x10, gtNewIconNode(0x01));
- nodeBuilder.AddOperand(0x11, gtNewIconNode(0x03));
- nodeBuilder.AddOperand(0x12, gtNewIconNode(0x05));
- nodeBuilder.AddOperand(0x13, gtNewIconNode(0x07));
- nodeBuilder.AddOperand(0x14, gtNewIconNode(0x09));
- nodeBuilder.AddOperand(0x15, gtNewIconNode(0x0B));
- nodeBuilder.AddOperand(0x16, gtNewIconNode(0x0D));
- nodeBuilder.AddOperand(0x17, gtNewIconNode(0x0F));
-
- for (unsigned i = 0x18; i < 0x20; i++)
- {
- // The most significant bit being set means zero the value
- nodeBuilder.AddOperand(i, gtNewIconNode(0x80));
- }
-
- createIntrinsic = NI_Vector256_Create;
- shuffleIntrinsic = NI_AVX2_Shuffle;
- moveMaskIntrinsic = NI_AVX2_MoveMask;
- }
- else if (compOpportunisticallyDependsOn(InstructionSet_SSSE3))
- {
- createIntrinsic = NI_Vector128_Create;
- shuffleIntrinsic = NI_SSSE3_Shuffle;
- moveMaskIntrinsic = NI_SSE2_MoveMask;
- }
- else
- {
- return nullptr;
- }
-
- op2 = gtNewSimdHWIntrinsicNode(simdType, std::move(nodeBuilder), createIntrinsic,
- simdBaseJitType, simdSize);
-
- op1 = impSIMDPopStack(simdType);
- op1 = gtNewSimdHWIntrinsicNode(simdType, op1, op2, shuffleIntrinsic, simdBaseJitType, simdSize);
-
- if (simdSize == 32)
- {
- CorInfoType simdOtherJitType;
-
- // Since Vector256 is 2x128-bit lanes we need a full width permutation so we get the lower
- // 64-bits of each lane next to eachother. The upper bits should be zero, but also don't
- // matter so we can also then simplify down to a 128-bit move mask.
-
- simdOtherJitType = (simdBaseType == TYP_UBYTE) ? CORINFO_TYPE_ULONG : CORINFO_TYPE_LONG;
-
- op1 = gtNewSimdHWIntrinsicNode(simdType, op1, gtNewIconNode(0xD8), NI_AVX2_Permute4x64,
- simdOtherJitType, simdSize);
-
- simdSize = 16;
- simdType = TYP_SIMD16;
-
- op1 = gtNewSimdHWIntrinsicNode(simdType, op1, NI_Vector256_GetLower, simdBaseJitType,
- simdSize);
- }
- break;
- }
-
- case TYP_INT:
- case TYP_UINT:
- case TYP_FLOAT:
- {
- simdBaseJitType = CORINFO_TYPE_FLOAT;
- op1 = impSIMDPopStack(simdType);
- moveMaskIntrinsic = (simdSize == 32) ? NI_AVX_MoveMask : NI_SSE_MoveMask;
- break;
- }
-
- case TYP_LONG:
- case TYP_ULONG:
- case TYP_DOUBLE:
- {
- simdBaseJitType = CORINFO_TYPE_DOUBLE;
- op1 = impSIMDPopStack(simdType);
- moveMaskIntrinsic = (simdSize == 32) ? NI_AVX_MoveMask : NI_SSE2_MoveMask;
- break;
- }
-
- default:
- {
- unreached();
- }
+ moveMaskIntrinsic = (simdSize == 32) ? NI_AVX_MoveMask : NI_SSE_MoveMask;
+ }
+ else if (simdBaseType == TYP_DOUBLE)
+ {
+ moveMaskIntrinsic = (simdSize == 32) ? NI_AVX_MoveMask : NI_SSE2_MoveMask;
+ }
+ else
+ {
+ moveMaskIntrinsic = (simdSize == 32) ? NI_AVX2_MoveMask : NI_SSE2_MoveMask;
+ simdBaseJitType = varTypeIsUnsigned(simdBaseType) ? CORINFO_TYPE_UBYTE : CORINFO_TYPE_BYTE;
}
-
- assert(moveMaskIntrinsic != NI_Illegal);
- assert(op1 != nullptr);
retNode = gtNewSimdHWIntrinsicNode(retType, op1, moveMaskIntrinsic, simdBaseJitType, simdSize,
/* isSimdAsHWIntrinsic */ false);
@@ -1287,7 +1172,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 2);
- if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2))
+ if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
{
var_types simdType = getSIMDTypeForSize(simdSize);
@@ -1305,7 +1190,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 2);
- if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2))
+ if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
{
var_types simdType = getSIMDTypeForSize(simdSize);
@@ -1339,7 +1224,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 2);
- if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2))
+ if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
{
var_types simdType = getSIMDTypeForSize(simdSize);
@@ -1357,7 +1242,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 2);
- if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2))
+ if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
{
var_types simdType = getSIMDTypeForSize(simdSize);
@@ -1391,7 +1276,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 2);
- if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2))
+ if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
{
var_types simdType = getSIMDTypeForSize(simdSize);
@@ -1409,7 +1294,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 2);
- if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2))
+ if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
{
var_types simdType = getSIMDTypeForSize(simdSize);
@@ -1443,7 +1328,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 2);
- if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2))
+ if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
{
var_types simdType = getSIMDTypeForSize(simdSize);
@@ -1461,7 +1346,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
{
assert(sig->numArgs == 2);
- if ((simdSize != 32) || compExactlyDependsOn(InstructionSet_AVX2))
+ if ((simdSize != 32) || varTypeIsFloating(simdBaseType) || compExactlyDependsOn(InstructionSet_AVX2))
{
var_types simdType = getSIMDTypeForSize(simdSize);
@@ -1895,10 +1780,9 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector256_Store:
{
assert(sig->numArgs == 2);
- var_types simdType = getSIMDTypeForSize(simdSize);
op2 = impPopStack().val;
- op1 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(retType);
NamedIntrinsic storeIntrinsic = NI_Illegal;
@@ -1923,10 +1807,9 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector256_StoreAligned:
{
assert(sig->numArgs == 2);
- var_types simdType = getSIMDTypeForSize(simdSize);
op2 = impPopStack().val;
- op1 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(retType);
NamedIntrinsic storeIntrinsic = NI_Illegal;
@@ -1951,10 +1834,9 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector256_StoreAlignedNonTemporal:
{
assert(sig->numArgs == 2);
- var_types simdType = getSIMDTypeForSize(simdSize);
op2 = impPopStack().val;
- op1 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(retType);
NamedIntrinsic storeIntrinsic = NI_Illegal;
@@ -1978,8 +1860,6 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector128_StoreUnsafe:
case NI_Vector256_StoreUnsafe:
{
- var_types simdType = getSIMDTypeForSize(simdSize);
-
if (sig->numArgs == 3)
{
op3 = impPopStack().val;
@@ -1990,13 +1870,13 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
}
op2 = impPopStack().val;
- op1 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(retType);
if (sig->numArgs == 3)
{
- op4 = gtNewIconNode(genTypeSize(simdBaseType), op3->TypeGet());
- op3 = gtNewOperNode(GT_MUL, op3->TypeGet(), op3, op4);
- op2 = gtNewOperNode(GT_ADD, op2->TypeGet(), op2, op3);
+ op3 = gtNewIconNode(genTypeSize(simdBaseType), op2->TypeGet());
+ op2 = gtNewOperNode(GT_MUL, op2->TypeGet(), op2, op3);
+ op2 = gtNewOperNode(GT_ADD, op1->TypeGet(), op1, op2);
}
NamedIntrinsic storeIntrinsic = NI_Illegal;
@@ -2022,14 +1902,8 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
case NI_Vector256_Sum:
{
assert(sig->numArgs == 1);
- var_types simdType = getSIMDTypeForSize(simdSize);
- if ((simdSize == 32) && !compOpportunisticallyDependsOn(InstructionSet_AVX2))
- {
- // Vector256 for integer types requires AVX2
- break;
- }
- else if (varTypeIsFloating(simdBaseType))
+ if (varTypeIsFloating(simdBaseType))
{
if (!compOpportunisticallyDependsOn(InstructionSet_SSE3))
{
@@ -2048,7 +1922,7 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
break;
}
- op1 = impSIMDPopStack(simdType);
+ op1 = impSIMDPopStack(retType);
retNode = gtNewSimdSumNode(retType, op1, simdBaseJitType, simdSize, /* isSimdAsHWIntrinsic */ false);
break;
}
diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp
index b9cc2ff883d64..aab024d3ac30d 100644
--- a/src/coreclr/jit/importer.cpp
+++ b/src/coreclr/jit/importer.cpp
@@ -91,6 +91,42 @@ void Compiler::impPushOnStack(GenTree* tree, typeInfo ti)
CORINFO_CLASS_HANDLE clsHnd = ti.GetClassHandle();
assert(clsHnd != NO_CLASS_HANDLE);
}
+
+ if (tiVerificationNeeded && !ti.IsDead())
+ {
+ assert(typeInfo::AreEquivalent(NormaliseForStack(ti), ti)); // types are normalized
+
+ // The ti type is consistent with the tree type.
+ //
+
+ // On 64-bit systems, nodes whose "proper" type is "native int" get labeled TYP_LONG.
+ // In the verification type system, we always transform "native int" to "TI_INT".
+ // Ideally, we would keep track of which nodes labeled "TYP_LONG" are really "native int", but
+ // attempts to do that have proved too difficult. Instead, we'll assume that in checks like this,
+ // when there's a mismatch, it's because of this reason -- the typeInfo::AreEquivalentModuloNativeInt
+ // method used in the last disjunct allows exactly this mismatch.
+ assert(ti.IsDead() || (ti.IsByRef() && ((tree->TypeGet() == TYP_I_IMPL) || (tree->TypeGet() == TYP_BYREF))) ||
+ (ti.IsUnboxedGenericTypeVar() && tree->TypeGet() == TYP_REF) ||
+ (ti.IsObjRef() && tree->TypeGet() == TYP_REF) || (ti.IsMethod() && tree->TypeGet() == TYP_I_IMPL) ||
+ (ti.IsType(TI_STRUCT) && tree->TypeGet() != TYP_REF) ||
+ typeInfo::AreEquivalentModuloNativeInt(NormaliseForStack(ti),
+ NormaliseForStack(typeInfo(tree->TypeGet()))));
+
+ // If it is a struct type, make certain we normalized the primitive types
+ assert(!ti.IsType(TI_STRUCT) ||
+ info.compCompHnd->getTypeForPrimitiveValueClass(ti.GetClassHandle()) == CORINFO_TYPE_UNDEF);
+ }
+
+#if VERBOSE_VERIFY
+ if (VERBOSE && tiVerificationNeeded)
+ {
+ printf("\n");
+ printf(TI_DUMP_PADDING);
+ printf("About to push to stack: ");
+ ti.Dump();
+ }
+#endif // VERBOSE_VERIFY
+
#endif // DEBUG
verCurrentState.esStack[verCurrentState.esStackDepth].seTypeInfo = ti;
@@ -221,7 +257,14 @@ void Compiler::impResolveToken(const BYTE* addr, CORINFO_RESOLVED_TOKEN* pResolv
pResolvedToken->token = getU4LittleEndian(addr);
pResolvedToken->tokenType = kind;
- info.compCompHnd->resolveToken(pResolvedToken);
+ if (!tiVerificationNeeded)
+ {
+ info.compCompHnd->resolveToken(pResolvedToken);
+ }
+ else
+ {
+ Verify(eeTryResolveToken(pResolvedToken), "Token resolution failed");
+ }
}
/*****************************************************************************
@@ -236,6 +279,19 @@ StackEntry Compiler::impPopStack()
BADCODE("stack underflow");
}
+#ifdef DEBUG
+#if VERBOSE_VERIFY
+ if (VERBOSE && tiVerificationNeeded)
+ {
+ JITDUMP("\n");
+ printf(TI_DUMP_PADDING);
+ printf("About to pop from the stack: ");
+ const typeInfo& ti = verCurrentState.esStack[verCurrentState.esStackDepth - 1].seTypeInfo;
+ ti.Dump();
+ }
+#endif // VERBOSE_VERIFY
+#endif // DEBUG
+
return verCurrentState.esStack[--verCurrentState.esStackDepth];
}
@@ -768,7 +824,7 @@ void Compiler::impAssignTempGen(unsigned tmpNum,
// so at least ignore it in the case when verification is turned on
// since any block that tries to use the temp would have failed verification.
var_types varType = lvaTable[tmpNum].lvType;
- assert(varType == TYP_UNDEF || varTypeIsStruct(varType));
+ assert(tiVerificationNeeded || varType == TYP_UNDEF || varTypeIsStruct(varType));
lvaSetStruct(tmpNum, structType, false);
varType = lvaTable[tmpNum].lvType;
@@ -1808,6 +1864,7 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal,
case GT_OBJ:
case GT_BLK:
+ case GT_DYN_BLK:
case GT_ASG:
// These should already have the appropriate type.
assert(structVal->gtType == structType);
@@ -2431,9 +2488,21 @@ bool Compiler::impSpillStackEntry(unsigned level,
/* Allocate a temp if we haven't been asked to use a particular one */
- if (tnum != BAD_VAR_NUM && (tnum >= lvaCount))
+ if (tiVerificationNeeded)
{
- return false;
+ // Ignore bad temp requests (they will happen with bad code and will be
+ // catched when importing the destblock)
+ if (tnum != BAD_VAR_NUM && tnum >= lvaCount)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (tnum != BAD_VAR_NUM && (tnum >= lvaCount))
+ {
+ return false;
+ }
}
bool isNewTemp = false;
@@ -2443,6 +2512,27 @@ bool Compiler::impSpillStackEntry(unsigned level,
tnum = lvaGrabTemp(true DEBUGARG(reason));
isNewTemp = true;
}
+ else if (tiVerificationNeeded && lvaTable[tnum].TypeGet() != TYP_UNDEF)
+ {
+ // if verification is needed and tnum's type is incompatible with
+ // type on that stack, we grab a new temp. This is safe since
+ // we will throw a verification exception in the dest block.
+
+ var_types valTyp = tree->TypeGet();
+ var_types dstTyp = lvaTable[tnum].TypeGet();
+
+ // if the two types are different, we return. This will only happen with bad code and will
+ // be catched when importing the destblock. We still allow int/byrefs and float/double differences.
+ if ((genActualType(valTyp) != genActualType(dstTyp)) &&
+ !(
+#ifndef TARGET_64BIT
+ (valTyp == TYP_I_IMPL && dstTyp == TYP_BYREF) || (valTyp == TYP_BYREF && dstTyp == TYP_I_IMPL) ||
+#endif // !TARGET_64BIT
+ (varTypeIsFloating(dstTyp) && varTypeIsFloating(valTyp))))
+ {
+ return false;
+ }
+ }
/* Assign the spilled entry to the temp */
impAssignTempGen(tnum, tree, verCurrentState.esStack[level].seTypeInfo.GetClassHandle(), level);
@@ -2557,9 +2647,11 @@ inline void Compiler::impSpillSideEffects(bool spillGlobEffects, unsigned chkLev
{
GenTree* tree = verCurrentState.esStack[i].val;
+ GenTree* lclVarTree;
+
if ((tree->gtFlags & spillFlags) != 0 ||
- (spillGlobEffects && // Only consider the following when spillGlobEffects == true
- !impIsAddressInLocal(tree) && // No need to spill the GT_ADDR node on a local.
+ (spillGlobEffects && // Only consider the following when spillGlobEffects == true
+ !impIsAddressInLocal(tree, &lclVarTree) && // No need to spill the GT_ADDR node on a local.
gtHasLocalsWithAddrOp(tree))) // Spill if we still see GT_LCL_VAR that contains lvHasLdAddrOp or
// lvAddrTaken flag.
{
@@ -3787,25 +3879,19 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
return new (this, GT_LABEL) GenTree(GT_LABEL, TYP_I_IMPL);
}
- switch (ni)
+ if (((ni == NI_System_Runtime_CompilerServices_RuntimeHelpers_CreateSpan) ||
+ (ni == NI_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray)) &&
+ IsTargetAbi(CORINFO_CORERT_ABI))
{
// CreateSpan must be expanded for NativeAOT
- case NI_System_Runtime_CompilerServices_RuntimeHelpers_CreateSpan:
- case NI_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray:
- mustExpand |= IsTargetAbi(CORINFO_CORERT_ABI);
- break;
-
- case NI_System_ByReference_ctor:
- case NI_System_ByReference_get_Value:
- case NI_System_Activator_AllocatorOf:
- case NI_System_Activator_DefaultConstructorOf:
- case NI_System_Object_MethodTableOf:
- case NI_System_EETypePtr_EETypePtrOf:
- mustExpand = true;
- break;
+ mustExpand = true;
+ }
- default:
- break;
+ if ((ni == NI_System_ByReference_ctor) || (ni == NI_System_ByReference_get_Value) ||
+ (ni == NI_System_Activator_AllocatorOf) || (ni == NI_System_Activator_DefaultConstructorOf) ||
+ (ni == NI_System_Object_MethodTableOf) || (ni == NI_System_EETypePtr_EETypePtrOf))
+ {
+ mustExpand = true;
}
GenTree* retNode = nullptr;
@@ -3849,19 +3935,29 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
case NI_System_String_get_Length:
{
GenTree* op1 = impPopStack().val;
- if (op1->OperIs(GT_CNS_STR))
+ if (opts.OptimizationEnabled())
{
- // Optimize `ldstr + String::get_Length()` to CNS_INT
- // e.g. "Hello".Length => 5
- GenTreeIntCon* iconNode = gtNewStringLiteralLength(op1->AsStrCon());
- if (iconNode != nullptr)
+ if (op1->OperIs(GT_CNS_STR))
{
- retNode = iconNode;
- break;
+ // Optimize `ldstr + String::get_Length()` to CNS_INT
+ // e.g. "Hello".Length => 5
+ GenTreeIntCon* iconNode = gtNewStringLiteralLength(op1->AsStrCon());
+ if (iconNode != nullptr)
+ {
+ retNode = iconNode;
+ break;
+ }
}
+ GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, op1, OFFSETOF__CORINFO_String__stringLen, compCurBB);
+ op1 = arrLen;
+ }
+ else
+ {
+ /* Create the expression "*(str_addr + stringLengthOffset)" */
+ op1 = gtNewOperNode(GT_ADD, TYP_BYREF, op1,
+ gtNewIconNode(OFFSETOF__CORINFO_String__stringLen, TYP_I_IMPL));
+ op1 = gtNewOperNode(GT_IND, TYP_INT, op1);
}
- GenTreeArrLen* arrLen = gtNewArrLen(TYP_INT, op1, OFFSETOF__CORINFO_String__stringLen, compCurBB);
- op1 = arrLen;
// Getting the length of a null string should throw
op1->gtFlags |= GTF_EXCEPT;
@@ -3911,26 +4007,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
break;
}
- case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant:
- {
- GenTree* op1 = impPopStack().val;
- if (op1->OperIsConst())
- {
- // op1 is a known constant, replace with 'true'.
- retNode = gtNewIconNode(1);
- JITDUMP("\nExpanding RuntimeHelpers.IsKnownConstant to true early\n");
- // We can also consider FTN_ADDR and typeof(T) here
- }
- else
- {
- // op1 is not a known constant, we'll do the expansion in morph
- retNode = new (this, GT_INTRINSIC) GenTreeIntrinsic(TYP_INT, op1, ni, method);
- JITDUMP("\nConverting RuntimeHelpers.IsKnownConstant to:\n");
- DISPTREE(retNode);
- }
- break;
- }
-
case NI_System_Activator_AllocatorOf:
case NI_System_Activator_DefaultConstructorOf:
case NI_System_Object_MethodTableOf:
@@ -4207,7 +4283,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
case NI_System_Threading_Thread_get_ManagedThreadId:
{
- if (impStackTop().val->OperIs(GT_RET_EXPR))
+ if (opts.OptimizationEnabled() && impStackTop().val->OperIs(GT_RET_EXPR))
{
GenTreeCall* call = impStackTop().val->AsRetExpr()->gtInlineCandidate->AsCall();
if (call->gtCallMoreFlags & GTF_CALL_M_SPECIAL_INTRINSIC)
@@ -4230,7 +4306,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
case NI_System_Threading_Interlocked_Or:
case NI_System_Threading_Interlocked_And:
{
- if (compOpportunisticallyDependsOn(InstructionSet_Atomics))
+ if (opts.OptimizationEnabled() && compOpportunisticallyDependsOn(InstructionSet_Atomics))
{
assert(sig->numArgs == 2);
GenTree* op2 = impPopStack().val;
@@ -5276,10 +5352,6 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
{
result = NI_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray;
}
- else if (strcmp(methodName, "IsKnownConstant") == 0)
- {
- result = NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant;
- }
}
else if (strncmp(namespaceName, "System.Runtime.Intrinsics", 25) == 0)
{
@@ -6269,8 +6341,8 @@ void Compiler::verVerifyCall(OPCODE opcode,
info.compCompHnd->resolveToken(&delegateResolvedToken);
CORINFO_CALL_INFO delegateCallInfo;
- eeGetCallInfo(&delegateResolvedToken, nullptr /* constraint typeRef */, CORINFO_CALLINFO_SECURITYCHECKS,
- &delegateCallInfo);
+ eeGetCallInfo(&delegateResolvedToken, nullptr /* constraint typeRef */,
+ addVerifyFlag(CORINFO_CALLINFO_SECURITYCHECKS), &delegateCallInfo);
bool isOpenDelegate = false;
VerifyOrReturn(info.compCompHnd->isCompatibleDelegate(objTypeHandle, delegateResolvedToken.hClass,
@@ -9451,10 +9523,6 @@ var_types Compiler::impImportCall(OPCODE opcode,
// Take care to pass raw IL offset here as the 'debug info' might be different for
// inlinees.
rawILOffset);
-
- // Devirtualization may change which method gets invoked. Update our local cache.
- //
- methHnd = callInfo->hMethod;
}
if (impIsThis(obj))
@@ -9526,6 +9594,9 @@ var_types Compiler::impImportCall(OPCODE opcode,
{
if (newobjThis->gtOper == GT_COMMA)
{
+ // In coreclr the callout can be inserted even if verification is disabled
+ // so we cannot rely on tiVerificationNeeded alone
+
// We must have inserted the callout. Get the real newobj.
newobjThis = newobjThis->AsOp()->gtOp2;
}
@@ -9834,6 +9905,14 @@ var_types Compiler::impImportCall(OPCODE opcode,
eeGetCallSiteSig(pResolvedToken->token, pResolvedToken->tokenScope, pResolvedToken->tokenContext, sig);
}
+ // Find the return type used for verification by interpreting the method signature.
+ // NB: we are clobbering the already established sig.
+ if (tiVerificationNeeded)
+ {
+ // Actually, we never get the sig for the original method.
+ sig = &(callInfo->verSig);
+ }
+
typeInfo tiRetVal = verMakeTypeInfo(sig->retType, sig->retTypeClass);
tiRetVal.NormaliseForStack();
@@ -9844,6 +9923,17 @@ var_types Compiler::impImportCall(OPCODE opcode,
tiRetVal.SetIsReadonlyByRef();
}
+ if (tiVerificationNeeded)
+ {
+ // We assume all calls return permanent home byrefs. If they
+ // didn't they wouldn't be verifiable. This is also covering
+ // the Address() helper for multidimensional arrays.
+ if (tiRetVal.IsByRef())
+ {
+ tiRetVal.SetIsPermanentHomeByRef();
+ }
+ }
+
if (call->IsCall())
{
// Sometimes "call" is not a GT_CALL (if we imported an intrinsic that didn't turn into a call)
@@ -10676,7 +10766,7 @@ void Compiler::impImportLeave(BasicBlock* block)
* scope */
exitBlock = fgNewBBinRegion(BBJ_EHCATCHRET, 0, XTnum + 1, step);
- assert(step->KindIs(BBJ_ALWAYS, BBJ_EHCATCHRET));
+ assert(step->bbJumpKind == BBJ_ALWAYS || step->bbJumpKind == BBJ_EHCATCHRET);
step->bbJumpDest = exitBlock; // the previous step (maybe a call to a nested finally, or a nested catch
// exit) returns to this block
step->bbJumpDest->bbRefs++;
@@ -10784,7 +10874,7 @@ void Compiler::impImportLeave(BasicBlock* block)
// never returns to the call-to-finally call, and the finally-protected 'try' region doesn't appear on
// stack walks.)
- assert(step->KindIs(BBJ_ALWAYS, BBJ_EHCATCHRET));
+ assert(step->bbJumpKind == BBJ_ALWAYS || step->bbJumpKind == BBJ_EHCATCHRET);
#if FEATURE_EH_CALLFINALLY_THUNKS
if (step->bbJumpKind == BBJ_EHCATCHRET)
@@ -11683,48 +11773,41 @@ void Compiler::impImportBlockCode(BasicBlock* block)
CORINFO_HELPER_DESC calloutHelper;
const BYTE* lastLoadToken = nullptr;
+ // reject cyclic constraints
+ if (tiVerificationNeeded)
+ {
+ Verify(!info.hasCircularClassConstraints, "Method parent has circular class type parameter constraints.");
+ Verify(!info.hasCircularMethodConstraints, "Method has circular method type parameter constraints.");
+ }
+
/* Get the tree list started */
impBeginTreeList();
#ifdef FEATURE_ON_STACK_REPLACEMENT
- bool enablePatchpoints = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_TIER0) && (JitConfig.TC_OnStackReplacement() > 0);
-
-#ifdef DEBUG
-
- // Optionally suppress patchpoints by method hash
+ // Are there any places in the method where we might add a patchpoint?
//
- static ConfigMethodRange JitEnablePatchpointRange;
- JitEnablePatchpointRange.EnsureInit(JitConfig.JitEnablePatchpointRange());
- const unsigned hash = impInlineRoot()->info.compMethodHash();
- const bool inRange = JitEnablePatchpointRange.Contains(hash);
- enablePatchpoints &= inRange;
-
-#endif // DEBUG
-
- if (enablePatchpoints)
+ if (compHasBackwardJump)
{
- // We don't inline at Tier0, if we do, we may need rethink our approach.
- // Could probably support inlines that don't introduce flow.
- //
- assert(!compIsForInlining());
-
- // OSR is not yet supported for methods with explicit tail calls.
+ // Is OSR enabled?
//
- // But we also do not have to switch these methods to be optimized as we should be
- // able to avoid getting trapped in Tier0 code by normal call counting.
- // So instead, just suppress adding patchpoints.
- //
- if (!compTailPrefixSeen)
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_TIER0) && (JitConfig.TC_OnStackReplacement() > 0))
{
- // The normaly policy is only to add patchpoints to the targets of lexically
- // backwards branches.
+ // OSR is not yet supported for methods with explicit tail calls.
+ //
+ // But we also may not switch methods to be optimized as we should be
+ // able to avoid getting trapped in Tier0 code by normal call counting.
+ // So instead, just suppress adding patchpoints.
//
- if (compHasBackwardJump)
+ if (!compTailPrefixSeen)
{
assert(compCanHavePatchpoints());
+ // We don't inline at Tier0, if we do, we may need rethink our approach.
+ // Could probably support inlines that don't introduce flow.
+ assert(!compIsForInlining());
+
// Is the start of this block a suitable patchpoint?
//
if (((block->bbFlags & BBF_BACKWARD_JUMP_TARGET) != 0) && (verCurrentState.esStackDepth == 0))
@@ -11737,64 +11820,12 @@ void Compiler::impImportBlockCode(BasicBlock* block)
setMethodHasPatchpoint();
}
}
- else
- {
- // Should not see backward branch targets w/o backwards branches
- assert((block->bbFlags & BBF_BACKWARD_JUMP_TARGET) == 0);
- }
- }
-
-#ifdef DEBUG
- // As a stress test, we can place patchpoints at the start of any block
- // that is a stack empty point and is not within a handler.
- //
- // Todo: enable for mid-block stack empty points too.
- //
- const int offsetOSR = JitConfig.JitOffsetOnStackReplacement();
- const int randomOSR = JitConfig.JitRandomOnStackReplacement();
- const bool tryOffsetOSR = offsetOSR >= 0;
- const bool tryRandomOSR = randomOSR > 0;
-
- if (compCanHavePatchpoints() && (tryOffsetOSR || tryRandomOSR) && (verCurrentState.esStackDepth == 0) &&
- !block->hasHndIndex() && ((block->bbFlags & BBF_PATCHPOINT) == 0))
- {
- // Block start can have a patchpoint. See if we should add one.
- //
- bool addPatchpoint = false;
-
- // Specific offset?
- //
- if (tryOffsetOSR)
- {
- if (impCurOpcOffs == (unsigned)offsetOSR)
- {
- addPatchpoint = true;
- }
- }
- // Random?
- //
- else
- {
- // Reuse the random inliner's random state.
- // Note m_inlineStrategy is always created, even if we're not inlining.
- //
- CLRRandom* const random = impInlineRoot()->m_inlineStrategy->GetRandom(randomOSR);
- const int randomValue = (int)random->Next(100);
-
- addPatchpoint = (randomValue < randomOSR);
- }
-
- if (addPatchpoint)
- {
- block->bbFlags |= BBF_PATCHPOINT;
- setMethodHasPatchpoint();
- }
-
- JITDUMP("\n** %s patchpoint%s added to " FMT_BB " (il offset %u)\n", tryOffsetOSR ? "offset" : "random",
- addPatchpoint ? "" : " not", block->bbNum, impCurOpcOffs);
}
-
-#endif // DEBUG
+ }
+ else
+ {
+ // Should not see backward branch targets w/o backwards branches
+ assert((block->bbFlags & BBF_BACKWARD_JUMP_TARGET) == 0);
}
// Mark stack-empty rare blocks to be considered for partial compilation.
@@ -12228,6 +12259,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
val = getU4LittleEndian(codeAddr);
JITDUMP(" %08X", val);
+ if (tiVerificationNeeded)
+ {
+ Verify(info.compCompHnd->isValidStringRef(info.compScopeHnd, val), "bad string");
+ tiRetVal = typeInfo(TI_REF, impGetStringClass());
+ }
impPushOnStack(gtNewSconNode(val, info.compScopeHnd), tiRetVal);
break;
@@ -12283,6 +12319,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
STARG:
JITDUMP(" %u", lclNum);
+ if (tiVerificationNeeded)
+ {
+ Verify(lclNum < info.compILargsCount, "bad arg num");
+ }
+
if (compIsForInlining())
{
op1 = impInlineFetchArg(lclNum, impInlineInfo->inlArgInfo, impInlineInfo->lclVarInfo);
@@ -12303,6 +12344,18 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// We should have seen this arg write in the prescan
assert(lvaTable[lclNum].lvHasILStoreOp);
+ if (tiVerificationNeeded)
+ {
+ typeInfo& tiLclVar = lvaTable[lclNum].lvVerTypeInfo;
+ Verify(tiCompatibleWith(impStackTop().seTypeInfo, NormaliseForStack(tiLclVar), true),
+ "type mismatch");
+
+ if (verTrackObjCtorInitState && (verCurrentState.thisInitialized != TIS_Init))
+ {
+ Verify(!tiLclVar.IsThisPtr(), "storing to uninit this ptr");
+ }
+ }
+
goto VAR_ST;
case CEE_STLOC:
@@ -12326,6 +12379,14 @@ void Compiler::impImportBlockCode(BasicBlock* block)
assert(lclNum >= 0 && lclNum < 4);
LOC_ST:
+ if (tiVerificationNeeded)
+ {
+ Verify(lclNum < info.compMethodInfo->locals.numArgs, "bad local num");
+ Verify(tiCompatibleWith(impStackTop().seTypeInfo,
+ NormaliseForStack(lvaTable[lclNum + numArgs].lvVerTypeInfo), true),
+ "type mismatch");
+ }
+
if (compIsForInlining())
{
lclTyp = impInlineInfo->lclVarInfo[lclNum + impInlineInfo->argCnt].lclTypeInfo;
@@ -12343,6 +12404,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
if (lclNum >= info.compLocalsCount && lclNum != lvaArg0Var)
{
+ assert(!tiVerificationNeeded); // We should have thrown the VerificationException before.
BADCODE("Bad IL");
}
@@ -12384,6 +12446,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// Downcast the TYP_I_IMPL into a 32-bit Int for x86 JIT compatiblity
if (varTypeIsI(op1->TypeGet()) && (genActualType(lclTyp) == TYP_INT))
{
+ assert(!tiVerificationNeeded); // We should have thrown the VerificationException before.
op1 = gtNewCastNode(TYP_INT, op1, false, TYP_INT);
}
#endif // TARGET_64BIT
@@ -12497,6 +12560,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
lclNum = getU1LittleEndian(codeAddr);
LDLOCA:
JITDUMP(" %u", lclNum);
+ if (tiVerificationNeeded)
+ {
+ Verify(lclNum < info.compMethodInfo->locals.numArgs, "bad local num");
+ Verify(info.compInitMem, "initLocals not set");
+ }
if (compIsForInlining())
{
@@ -12573,6 +12641,23 @@ void Compiler::impImportBlockCode(BasicBlock* block)
assert((op1->gtFlags & GTF_GLOB_REF) == 0);
tiRetVal = lvaTable[lclNum].lvVerTypeInfo;
+ if (tiVerificationNeeded)
+ {
+ // Don't allow taking address of uninit this ptr.
+ if (verTrackObjCtorInitState && (verCurrentState.thisInitialized != TIS_Init))
+ {
+ Verify(!tiRetVal.IsThisPtr(), "address of uninit this ptr");
+ }
+
+ if (!tiRetVal.IsByRef())
+ {
+ tiRetVal.MakeByRef();
+ }
+ else
+ {
+ Verify(false, "byref to byref");
+ }
+ }
impPushOnStack(op1, tiRetVal);
break;
@@ -12584,6 +12669,10 @@ void Compiler::impImportBlockCode(BasicBlock* block)
BADCODE("arglist in non-vararg method");
}
+ if (tiVerificationNeeded)
+ {
+ tiRetVal = typeInfo(TI_STRUCT, impGetRuntimeArgumentHandle());
+ }
assertImp((info.compMethodInfo->args.callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG);
/* The ARGLIST cookie is a hidden 'last' parameter, we have already
@@ -12635,6 +12724,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
BADCODE("endfilter outside filter");
}
+ if (tiVerificationNeeded)
+ {
+ Verify(impStackTop().seTypeInfo.IsType(TI_INT), "bad endfilt arg");
+ }
+
op1 = impPopStack().val;
assertImp(op1->gtType == TYP_INT);
if (!bbInFilterILRange(block))
@@ -12673,6 +12767,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
assert(!compIsForInlining());
+ if (tiVerificationNeeded)
+ {
+ Verify(false, "Invalid opcode: CEE_JMP");
+ }
+
if ((info.compFlags & CORINFO_FLG_SYNCH) || block->hasTryIndex() || block->hasHndIndex())
{
/* CEE_JMP does not make sense in some "protected" regions. */
@@ -12729,6 +12828,30 @@ void Compiler::impImportBlockCode(BasicBlock* block)
ldelemClsHnd = resolvedToken.hClass;
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiArray = impStackTop(1).seTypeInfo;
+ typeInfo tiIndex = impStackTop().seTypeInfo;
+
+ // As per ECMA 'index' specified can be either int32 or native int.
+ Verify(tiIndex.IsIntOrNativeIntType(), "bad index");
+
+ typeInfo arrayElemType = verMakeTypeInfo(ldelemClsHnd);
+ Verify(tiArray.IsNullObjRef() ||
+ typeInfo::AreEquivalent(verGetArrayElemType(tiArray), arrayElemType),
+ "bad array");
+
+ tiRetVal = arrayElemType;
+ tiRetVal.MakeByRef();
+ if (prefixFlags & PREFIX_READONLY)
+ {
+ tiRetVal.SetIsReadonlyByRef();
+ }
+
+ // an array interior pointer is always in the heap
+ tiRetVal.SetIsPermanentHomeByRef();
+ }
+
// If it's a value class array we just do a simple address-of
if (eeIsValueClass(ldelemClsHnd))
{
@@ -12779,6 +12902,20 @@ void Compiler::impImportBlockCode(BasicBlock* block)
ldelemClsHnd = resolvedToken.hClass;
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiArray = impStackTop(1).seTypeInfo;
+ typeInfo tiIndex = impStackTop().seTypeInfo;
+
+ // As per ECMA 'index' specified can be either int32 or native int.
+ Verify(tiIndex.IsIntOrNativeIntType(), "bad index");
+ tiRetVal = verMakeTypeInfo(ldelemClsHnd);
+
+ Verify(tiArray.IsNullObjRef() || tiCompatibleWith(verGetArrayElemType(tiArray), tiRetVal, false),
+ "type of array incompatible with type operand");
+ tiRetVal.NormaliseForStack();
+ }
+
// If it's a reference type or generic variable type
// then just generate code as though it's a ldelem.ref instruction
if (!eeIsValueClass(ldelemClsHnd))
@@ -12834,6 +12971,47 @@ void Compiler::impImportBlockCode(BasicBlock* block)
goto ARR_LD;
ARR_LD:
+
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiArray = impStackTop(1).seTypeInfo;
+ typeInfo tiIndex = impStackTop().seTypeInfo;
+
+ // As per ECMA 'index' specified can be either int32 or native int.
+ Verify(tiIndex.IsIntOrNativeIntType(), "bad index");
+ if (tiArray.IsNullObjRef())
+ {
+ if (lclTyp == TYP_REF)
+ { // we will say a deref of a null array yields a null ref
+ tiRetVal = typeInfo(TI_NULL);
+ }
+ else
+ {
+ tiRetVal = typeInfo(lclTyp);
+ }
+ }
+ else
+ {
+ tiRetVal = verGetArrayElemType(tiArray);
+ typeInfo arrayElemTi = typeInfo(lclTyp);
+#ifdef TARGET_64BIT
+ if (opcode == CEE_LDELEM_I)
+ {
+ arrayElemTi = typeInfo::nativeInt();
+ }
+
+ if (lclTyp != TYP_REF && lclTyp != TYP_STRUCT)
+ {
+ Verify(typeInfo::AreEquivalent(tiRetVal, arrayElemTi), "bad array");
+ }
+ else
+#endif // TARGET_64BIT
+ {
+ Verify(tiRetVal.IsType(arrayElemTi.GetType()), "bad array");
+ }
+ }
+ tiRetVal.NormaliseForStack();
+ }
ARR_LD_POST_VERIFY:
/* Pull the index value and array address */
@@ -12928,6 +13106,22 @@ void Compiler::impImportBlockCode(BasicBlock* block)
stelemClsHnd = resolvedToken.hClass;
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiArray = impStackTop(2).seTypeInfo;
+ typeInfo tiIndex = impStackTop(1).seTypeInfo;
+ typeInfo tiValue = impStackTop().seTypeInfo;
+
+ // As per ECMA 'index' specified can be either int32 or native int.
+ Verify(tiIndex.IsIntOrNativeIntType(), "bad index");
+ typeInfo arrayElem = verMakeTypeInfo(stelemClsHnd);
+
+ Verify(tiArray.IsNullObjRef() || tiCompatibleWith(arrayElem, verGetArrayElemType(tiArray), false),
+ "type operand incompatible with array element type");
+ arrayElem.NormaliseForStack();
+ Verify(tiCompatibleWith(tiValue, arrayElem, true), "value incompatible with type operand");
+ }
+
// If it's a reference type just behave as though it's a stelem.ref instruction
if (!eeIsValueClass(stelemClsHnd))
{
@@ -12942,6 +13136,21 @@ void Compiler::impImportBlockCode(BasicBlock* block)
}
case CEE_STELEM_REF:
+
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiArray = impStackTop(2).seTypeInfo;
+ typeInfo tiIndex = impStackTop(1).seTypeInfo;
+ typeInfo tiValue = impStackTop().seTypeInfo;
+
+ // As per ECMA 'index' specified can be either int32 or native int.
+ Verify(tiIndex.IsIntOrNativeIntType(), "bad index");
+ Verify(tiValue.IsObjRef(), "bad value");
+
+ // we only check that it is an object referece, The helper does additional checks
+ Verify(tiArray.IsNullObjRef() || verGetArrayElemType(tiArray).IsType(TI_REF), "bad array");
+ }
+
STELEM_REF_POST_VERIFY:
if (opts.OptimizationEnabled())
@@ -12984,6 +13193,29 @@ void Compiler::impImportBlockCode(BasicBlock* block)
goto ARR_ST;
ARR_ST:
+
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiArray = impStackTop(2).seTypeInfo;
+ typeInfo tiIndex = impStackTop(1).seTypeInfo;
+ typeInfo tiValue = impStackTop().seTypeInfo;
+
+ // As per ECMA 'index' specified can be either int32 or native int.
+ Verify(tiIndex.IsIntOrNativeIntType(), "bad index");
+ typeInfo arrayElem = typeInfo(lclTyp);
+#ifdef TARGET_64BIT
+ if (opcode == CEE_STELEM_I)
+ {
+ arrayElem = typeInfo::nativeInt();
+ }
+#endif // TARGET_64BIT
+ Verify(tiArray.IsNullObjRef() || typeInfo::AreEquivalent(verGetArrayElemType(tiArray), arrayElem),
+ "bad array");
+
+ Verify(tiCompatibleWith(NormaliseForStack(tiValue), arrayElem.NormaliseForStack(), true),
+ "bad value");
+ }
+
ARR_ST_POST_VERIFY:
/* The strict order of evaluation is LHS-operands, RHS-operands,
range-check, and then assignment. However, codegen currently
@@ -13150,6 +13382,33 @@ void Compiler::impImportBlockCode(BasicBlock* block)
/* Pull two values and push back the result */
+ if (tiVerificationNeeded)
+ {
+ const typeInfo& tiOp1 = impStackTop(1).seTypeInfo;
+ const typeInfo& tiOp2 = impStackTop().seTypeInfo;
+
+ Verify(tiCompatibleWith(tiOp1, tiOp2, true), "different arg type");
+ if (oper == GT_ADD || oper == GT_DIV || oper == GT_SUB || oper == GT_MUL || oper == GT_MOD)
+ {
+ Verify(tiOp1.IsNumberType(), "not number");
+ }
+ else
+ {
+ Verify(tiOp1.IsIntegerType(), "not integer");
+ }
+
+ Verify(!ovfl || tiOp1.IsIntegerType(), "not integer");
+
+ tiRetVal = tiOp1;
+
+#ifdef TARGET_64BIT
+ if (tiOp2.IsNativeIntType())
+ {
+ tiRetVal = tiOp2;
+ }
+#endif // TARGET_64BIT
+ }
+
op2 = impPopStack().val;
op1 = impPopStack().val;
@@ -13254,6 +13513,13 @@ void Compiler::impImportBlockCode(BasicBlock* block)
goto CEE_SH_OP2;
CEE_SH_OP2:
+ if (tiVerificationNeeded)
+ {
+ const typeInfo& tiVal = impStackTop(1).seTypeInfo;
+ const typeInfo& tiShift = impStackTop(0).seTypeInfo;
+ Verify(tiVal.IsIntegerType() && tiShift.IsType(TI_INT), "Bad shift args");
+ tiRetVal = tiVal;
+ }
op2 = impPopStack().val;
op1 = impPopStack().val; // operand to be shifted
impBashVarAddrsToI(op1, op2);
@@ -13265,6 +13531,12 @@ void Compiler::impImportBlockCode(BasicBlock* block)
break;
case CEE_NOT:
+ if (tiVerificationNeeded)
+ {
+ tiRetVal = impStackTop().seTypeInfo;
+ Verify(tiRetVal.IsIntegerType(), "bad int value");
+ }
+
op1 = impPopStack().val;
impBashVarAddrsToI(op1, nullptr);
type = genActualType(op1->TypeGet());
@@ -13272,6 +13544,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
break;
case CEE_CKFINITE:
+ if (tiVerificationNeeded)
+ {
+ tiRetVal = impStackTop().seTypeInfo;
+ Verify(tiRetVal.IsType(TI_DOUBLE), "bad R value");
+ }
op1 = impPopStack().val;
type = op1->TypeGet();
op1 = gtNewOperNode(GT_CKFINITE, type, op1);
@@ -13328,6 +13605,12 @@ void Compiler::impImportBlockCode(BasicBlock* block)
case CEE_BRFALSE_S:
/* Pop the comparand (now there's a neat term) from the stack */
+ if (tiVerificationNeeded)
+ {
+ typeInfo& tiVal = impStackTop().seTypeInfo;
+ Verify(tiVal.IsObjRef() || tiVal.IsByRef() || tiVal.IsIntegerType() || tiVal.IsMethod(),
+ "bad value");
+ }
op1 = impPopStack().val;
type = op1->TypeGet();
@@ -13450,6 +13733,12 @@ void Compiler::impImportBlockCode(BasicBlock* block)
goto CMP_2_OPs;
CMP_2_OPs:
+ if (tiVerificationNeeded)
+ {
+ verVerifyCond(impStackTop(1).seTypeInfo, impStackTop().seTypeInfo, opcode);
+ tiRetVal = typeInfo(TI_INT);
+ }
+
op2 = impPopStack().val;
op1 = impPopStack().val;
@@ -13552,9 +13841,15 @@ void Compiler::impImportBlockCode(BasicBlock* block)
unordered = false;
goto CMP_2_OPs_AND_BR_ALL;
CMP_2_OPs_AND_BR_ALL:
- /* Pull two values */
- op2 = impPopStack().val;
- op1 = impPopStack().val;
+
+ if (tiVerificationNeeded)
+ {
+ verVerifyCond(impStackTop(1).seTypeInfo, impStackTop().seTypeInfo, opcode);
+ }
+
+ /* Pull two values */
+ op2 = impPopStack().val;
+ op1 = impPopStack().val;
#ifdef TARGET_64BIT
if ((op1->TypeGet() == TYP_I_IMPL) && (genActualType(op2->TypeGet()) == TYP_INT))
@@ -13639,6 +13934,10 @@ void Compiler::impImportBlockCode(BasicBlock* block)
goto COND_JUMP;
case CEE_SWITCH:
+ if (tiVerificationNeeded)
+ {
+ Verify(impStackTop().seTypeInfo.IsType(TI_INT), "Bad switch val");
+ }
/* Pop the switch value off the stack */
op1 = impPopStack().val;
assertImp(genActualTypeIsIntOrI(op1->TypeGet()));
@@ -13789,6 +14088,40 @@ void Compiler::impImportBlockCode(BasicBlock* block)
goto _CONV;
_CONV:
+ // just check that we have a number on the stack
+ if (tiVerificationNeeded)
+ {
+ const typeInfo& tiVal = impStackTop().seTypeInfo;
+ Verify(tiVal.IsNumberType(), "bad arg");
+
+#ifdef TARGET_64BIT
+ bool isNative = false;
+
+ switch (opcode)
+ {
+ case CEE_CONV_OVF_I:
+ case CEE_CONV_OVF_I_UN:
+ case CEE_CONV_I:
+ case CEE_CONV_OVF_U:
+ case CEE_CONV_OVF_U_UN:
+ case CEE_CONV_U:
+ isNative = true;
+ break;
+ default:
+ // leave 'isNative' = false;
+ break;
+ }
+ if (isNative)
+ {
+ tiRetVal = typeInfo::nativeInt();
+ }
+ else
+#endif // TARGET_64BIT
+ {
+ tiRetVal = typeInfo(lclTyp).NormaliseForStack();
+ }
+ }
+
// only converts from FLOAT or DOUBLE to an integer type
// and converts from ULONG (or LONG on ARM) to DOUBLE are morphed to calls
@@ -13904,6 +14237,12 @@ void Compiler::impImportBlockCode(BasicBlock* block)
break;
case CEE_NEG:
+ if (tiVerificationNeeded)
+ {
+ tiRetVal = impStackTop().seTypeInfo;
+ Verify(tiRetVal.IsNumberType(), "Bad arg");
+ }
+
op1 = impPopStack().val;
impBashVarAddrsToI(op1, nullptr);
impPushOnStack(gtNewOperNode(GT_NEG, genActualType(op1->gtType), op1), tiRetVal);
@@ -13992,40 +14331,22 @@ void Compiler::impImportBlockCode(BasicBlock* block)
case CEE_DUP:
{
+ if (tiVerificationNeeded)
+ {
+ // Dup could start the beginning of delegate creation sequence, remember that
+ delegateCreateStart = codeAddr - 1;
+ impStackTop(0);
+ }
+
+ // If the expression to dup is simple, just clone it.
+ // Otherwise spill it to a temp, and reload the temp
+ // twice.
StackEntry se = impPopStack();
GenTree* tree = se.val;
tiRetVal = se.seTypeInfo;
op1 = tree;
- // If the expression to dup is simple, just clone it.
- // Otherwise spill it to a temp, and reload the temp twice.
- bool cloneExpr = false;
-
- if (!opts.compDbgCode)
- {
- // Duplicate 0 and +0.0
- if (op1->IsIntegralConst(0) || op1->IsFloatPositiveZero())
- {
- cloneExpr = true;
- }
- // Duplicate locals and addresses of them
- else if (op1->IsLocal())
- {
- cloneExpr = true;
- }
- else if (op1->TypeIs(TYP_BYREF) && op1->OperIs(GT_ADDR) && op1->gtGetOp1()->IsLocal() &&
- (OPCODE)impGetNonPrefixOpcode(codeAddr + sz, codeEndp) != CEE_INITOBJ)
- {
- cloneExpr = true;
- }
- }
- else
- {
- // Always clone for debug mode
- cloneExpr = true;
- }
-
- if (!cloneExpr)
+ if (!opts.compDbgCode && !op1->IsIntegralConst(0) && !op1->IsFPZero() && !op1->IsLocal())
{
const unsigned tmpNum = lvaGrabTemp(true DEBUGARG("dup spill"));
impAssignTempGen(tmpNum, op1, tiRetVal.GetClassHandle(), (unsigned)CHECK_SPILL_ALL);
@@ -14076,7 +14397,22 @@ void Compiler::impImportBlockCode(BasicBlock* block)
lclTyp = TYP_DOUBLE;
goto STIND;
STIND:
- compUnsafeCastUsed = true; // Have to go conservative
+
+ if (tiVerificationNeeded)
+ {
+ typeInfo instrType(lclTyp);
+#ifdef TARGET_64BIT
+ if (opcode == CEE_STIND_I)
+ {
+ instrType = typeInfo::nativeInt();
+ }
+#endif // TARGET_64BIT
+ verVerifySTIND(impStackTop(1).seTypeInfo, impStackTop(0).seTypeInfo, instrType);
+ }
+ else
+ {
+ compUnsafeCastUsed = true; // Have to go conservative
+ }
STIND_POST_VERIFY:
@@ -14102,12 +14438,14 @@ void Compiler::impImportBlockCode(BasicBlock* block)
//
if (varTypeIsI(op2->gtType) && (genActualType(lclTyp) == TYP_INT))
{
+ assert(!tiVerificationNeeded); // We should have thrown the VerificationException before.
op2 = gtNewCastNode(TYP_INT, op2, false, TYP_INT);
}
// Allow an upcast of op2 from a 32-bit Int into TYP_I_IMPL for x86 JIT compatiblity
//
if (varTypeIsI(lclTyp) && (genActualType(op2->gtType) == TYP_INT))
{
+ assert(!tiVerificationNeeded); // We should have thrown the VerificationException before.
op2 = gtNewCastNode(TYP_I_IMPL, op2, false, TYP_I_IMPL);
}
}
@@ -14202,7 +14540,23 @@ void Compiler::impImportBlockCode(BasicBlock* block)
lclTyp = TYP_USHORT;
goto LDIND;
LDIND:
- compUnsafeCastUsed = true; // Have to go conservative
+
+ if (tiVerificationNeeded)
+ {
+ typeInfo lclTiType(lclTyp);
+#ifdef TARGET_64BIT
+ if (opcode == CEE_LDIND_I)
+ {
+ lclTiType = typeInfo::nativeInt();
+ }
+#endif // TARGET_64BIT
+ tiRetVal = verVerifyLDIND(impStackTop().seTypeInfo, lclTiType);
+ tiRetVal.NormaliseForStack();
+ }
+ else
+ {
+ compUnsafeCastUsed = true; // Have to go conservative
+ }
LDIND_POST_VERIFY:
@@ -14214,6 +14568,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
//
if (genActualType(op1->gtType) == TYP_INT)
{
+ assert(!tiVerificationNeeded); // We should have thrown the VerificationException before.
op1 = gtNewCastNode(TYP_I_IMPL, op1, false, TYP_I_IMPL);
}
#endif
@@ -14283,7 +14638,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
JITDUMP(" %08X", resolvedToken.token);
eeGetCallInfo(&resolvedToken, (prefixFlags & PREFIX_CONSTRAINED) ? &constrainedResolvedToken : nullptr,
- combine(CORINFO_CALLINFO_SECURITYCHECKS, CORINFO_CALLINFO_LDFTN), &callInfo);
+ addVerifyFlag(combine(CORINFO_CALLINFO_SECURITYCHECKS, CORINFO_CALLINFO_LDFTN)),
+ &callInfo);
// This check really only applies to intrinsic Array.Address methods
if (callInfo.sig.callConv & CORINFO_CALLCONV_PARAMTYPE)
@@ -14294,6 +14650,22 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// Do this before DO_LDFTN since CEE_LDVIRTFN does it on its own.
impHandleAccessAllowed(callInfo.accessAllowed, &callInfo.callsiteCalloutHelper);
+ if (tiVerificationNeeded)
+ {
+ // LDFTN could start the beginning of delegate creation sequence, remember that
+ delegateCreateStart = codeAddr - 2;
+
+ // check any constraints on the callee's class and type parameters
+ VerifyOrReturn(info.compCompHnd->satisfiesClassConstraints(resolvedToken.hClass),
+ "method has unsatisfied class constraints");
+ VerifyOrReturn(info.compCompHnd->satisfiesMethodConstraints(resolvedToken.hClass,
+ resolvedToken.hMethod),
+ "method has unsatisfied method constraints");
+
+ mflags = callInfo.verMethodFlags;
+ Verify(!(mflags & CORINFO_FLG_CONSTRUCTOR), "LDFTN on a constructor");
+ }
+
DO_LDFTN:
op1 = impMethodPointer(&resolvedToken, &callInfo);
@@ -14321,8 +14693,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
JITDUMP(" %08X", resolvedToken.token);
eeGetCallInfo(&resolvedToken, nullptr /* constraint typeRef */,
- combine(combine(CORINFO_CALLINFO_SECURITYCHECKS, CORINFO_CALLINFO_LDFTN),
- CORINFO_CALLINFO_CALLVIRT),
+ addVerifyFlag(combine(combine(CORINFO_CALLINFO_SECURITYCHECKS, CORINFO_CALLINFO_LDFTN),
+ CORINFO_CALLINFO_CALLVIRT)),
&callInfo);
// This check really only applies to intrinsic Array.Address methods
@@ -14346,6 +14718,40 @@ void Compiler::impImportBlockCode(BasicBlock* block)
CORINFO_SIG_INFO& ftnSig = callInfo.sig;
+ if (tiVerificationNeeded)
+ {
+
+ Verify(ftnSig.hasThis(), "ldvirtftn on a static method");
+ Verify(!(mflags & CORINFO_FLG_CONSTRUCTOR), "LDVIRTFTN on a constructor");
+
+ // JIT32 verifier rejects verifiable ldvirtftn pattern
+ typeInfo declType =
+ verMakeTypeInfo(resolvedToken.hClass, true); // Change TI_STRUCT to TI_REF when necessary
+
+ typeInfo arg = impStackTop().seTypeInfo;
+ Verify((arg.IsType(TI_REF) || arg.IsType(TI_NULL)) && tiCompatibleWith(arg, declType, true),
+ "bad ldvirtftn");
+
+ CORINFO_CLASS_HANDLE instanceClassHnd = info.compClassHnd;
+ if (!(arg.IsType(TI_NULL) || (mflags & CORINFO_FLG_STATIC)))
+ {
+ instanceClassHnd = arg.GetClassHandleForObjRef();
+ }
+
+ // check any constraints on the method's class and type parameters
+ VerifyOrReturn(info.compCompHnd->satisfiesClassConstraints(resolvedToken.hClass),
+ "method has unsatisfied class constraints");
+ VerifyOrReturn(info.compCompHnd->satisfiesMethodConstraints(resolvedToken.hClass,
+ resolvedToken.hMethod),
+ "method has unsatisfied method constraints");
+
+ if (mflags & CORINFO_FLG_PROTECTED)
+ {
+ Verify(info.compCompHnd->canAccessFamily(info.compMethodHnd, instanceClassHnd),
+ "Accessing protected method through wrong type.");
+ }
+ }
+
/* Get the object-ref */
op1 = impPopStack().val;
assertImp(op1->gtType == TYP_REF);
@@ -14458,7 +14864,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
_impResolveToken(CORINFO_TOKENKIND_NewObj);
eeGetCallInfo(&resolvedToken, nullptr /* constraint typeRef*/,
- combine(CORINFO_CALLINFO_SECURITYCHECKS, CORINFO_CALLINFO_ALLOWINSTPARAM), &callInfo);
+ addVerifyFlag(combine(CORINFO_CALLINFO_SECURITYCHECKS, CORINFO_CALLINFO_ALLOWINSTPARAM)),
+ &callInfo);
if (compIsForInlining())
{
@@ -14492,6 +14899,19 @@ void Compiler::impImportBlockCode(BasicBlock* block)
clsFlags = callInfo.classFlags;
if (clsFlags & CORINFO_FLG_ARRAY)
{
+ if (tiVerificationNeeded)
+ {
+ CORINFO_CLASS_HANDLE elemTypeHnd;
+ INDEBUG(CorInfoType corType =)
+ info.compCompHnd->getChildType(resolvedToken.hClass, &elemTypeHnd);
+ assert(!(elemTypeHnd == nullptr && corType == CORINFO_TYPE_VALUECLASS));
+ Verify(elemTypeHnd == nullptr ||
+ !(info.compCompHnd->getClassAttribs(elemTypeHnd) & CORINFO_FLG_BYREF_LIKE),
+ "newarr of byref-like objects");
+ verVerifyCall(opcode, &resolvedToken, nullptr, ((prefixFlags & PREFIX_TAILCALL_EXPLICIT) != 0),
+ ((prefixFlags & PREFIX_READONLY) != 0), delegateCreateStart, codeAddr - 1,
+ &callInfo DEBUGARG(info.compFullName));
+ }
// Arrays need to call the NEWOBJ helper.
assertImp(clsFlags & CORINFO_FLG_VAROBJSIZE);
@@ -14683,8 +15103,10 @@ void Compiler::impImportBlockCode(BasicBlock* block)
eeGetCallInfo(&resolvedToken,
(prefixFlags & PREFIX_CONSTRAINED) ? &constrainedResolvedToken : nullptr,
// this is how impImportCall invokes getCallInfo
- combine(combine(CORINFO_CALLINFO_ALLOWINSTPARAM, CORINFO_CALLINFO_SECURITYCHECKS),
- (opcode == CEE_CALLVIRT) ? CORINFO_CALLINFO_CALLVIRT : CORINFO_CALLINFO_NONE),
+ addVerifyFlag(
+ combine(combine(CORINFO_CALLINFO_ALLOWINSTPARAM, CORINFO_CALLINFO_SECURITYCHECKS),
+ (opcode == CEE_CALLVIRT) ? CORINFO_CALLINFO_CALLVIRT
+ : CORINFO_CALLINFO_NONE)),
&callInfo);
}
else
@@ -14825,6 +15247,13 @@ void Compiler::impImportBlockCode(BasicBlock* block)
impHandleAccessAllowed(callInfo.accessAllowed, &callInfo.callsiteCalloutHelper);
}
+ if (tiVerificationNeeded)
+ {
+ verVerifyCall(opcode, &resolvedToken, constraintCall ? &constrainedResolvedToken : nullptr,
+ explicitTailCall, readonlyCall, delegateCreateStart, codeAddr - 1,
+ &callInfo DEBUGARG(info.compFullName));
+ }
+
callTyp = impImportCall(opcode, &resolvedToken, constraintCall ? &constrainedResolvedToken : nullptr,
newObjThisPtr, prefixFlags, &callInfo, opcodeOffs);
if (compDonotInline())
@@ -14944,10 +15373,45 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// SkipVerification.
impHandleAccessAllowed(fieldInfo.accessAllowed, &fieldInfo.accessCalloutHelper);
- // Raise InvalidProgramException if static load accesses non-static field
- if (isLoadStatic && ((fieldInfo.fieldFlags & CORINFO_FLG_FIELD_STATIC) == 0))
+ if (tiVerificationNeeded)
{
- BADCODE("static access on an instance field");
+ // You can also pass the unboxed struct to LDFLD
+ bool bAllowPlainValueTypeAsThis = false;
+ if (opcode == CEE_LDFLD && impIsValueType(tiObj))
+ {
+ bAllowPlainValueTypeAsThis = true;
+ }
+
+ verVerifyField(&resolvedToken, fieldInfo, tiObj, isLoadAddress, bAllowPlainValueTypeAsThis);
+
+ // If we're doing this on a heap object or from a 'safe' byref
+ // then the result is a safe byref too
+ if (isLoadAddress) // load address
+ {
+ if (fieldInfo.fieldFlags &
+ CORINFO_FLG_FIELD_STATIC) // statics marked as safe will have permanent home
+ {
+ if (fieldInfo.fieldFlags & CORINFO_FLG_FIELD_SAFESTATIC_BYREF_RETURN)
+ {
+ tiRetVal.SetIsPermanentHomeByRef();
+ }
+ }
+ else if (tiObj->IsObjRef() || tiObj->IsPermanentHomeByRef())
+ {
+ // ldflda of byref is safe if done on a gc object or on a
+ // safe byref
+ tiRetVal.SetIsPermanentHomeByRef();
+ }
+ }
+ }
+ else
+ {
+ // tiVerificationNeeded is false.
+ // Raise InvalidProgramException if static load accesses non-static field
+ if (isLoadStatic && ((fieldInfo.fieldFlags & CORINFO_FLG_FIELD_STATIC) == 0))
+ {
+ BADCODE("static access on an instance field");
+ }
}
// We are using ldfld/a on a static field. We allow it, but need to get side-effect from obj.
@@ -15262,10 +15726,20 @@ void Compiler::impImportBlockCode(BasicBlock* block)
impHandleAccessAllowed(fieldInfo.accessAllowed, &fieldInfo.accessCalloutHelper);
- // Raise InvalidProgramException if static store accesses non-static field
- if (isStoreStatic && ((fieldInfo.fieldFlags & CORINFO_FLG_FIELD_STATIC) == 0))
+ if (tiVerificationNeeded)
{
- BADCODE("static access on an instance field");
+ verVerifyField(&resolvedToken, fieldInfo, tiObj, true);
+ typeInfo fieldType = verMakeTypeInfo(ciType, fieldClsHnd);
+ Verify(tiCompatibleWith(tiVal, fieldType.NormaliseForStack(), true), "type mismatch");
+ }
+ else
+ {
+ // tiVerificationNeed is false.
+ // Raise InvalidProgramException if static store accesses non-static field
+ if (isStoreStatic && ((fieldInfo.fieldFlags & CORINFO_FLG_FIELD_STATIC) == 0))
+ {
+ BADCODE("static access on an instance field");
+ }
}
// We are using stfld on a static field.
@@ -15530,6 +16004,18 @@ void Compiler::impImportBlockCode(BasicBlock* block)
}
}
+ if (tiVerificationNeeded)
+ {
+ // As per ECMA 'numElems' specified can be either int32 or native int.
+ Verify(impStackTop().seTypeInfo.IsIntOrNativeIntType(), "bad bound");
+
+ CORINFO_CLASS_HANDLE elemTypeHnd;
+ info.compCompHnd->getChildType(resolvedToken.hClass, &elemTypeHnd);
+ Verify(elemTypeHnd == nullptr ||
+ !(info.compCompHnd->getClassAttribs(elemTypeHnd) & CORINFO_FLG_BYREF_LIKE),
+ "array of byref-like type");
+ }
+
tiRetVal = verMakeTypeInfo(resolvedToken.hClass);
accessAllowedResult =
@@ -15610,6 +16096,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
break;
case CEE_LOCALLOC:
+ if (tiVerificationNeeded)
+ {
+ Verify(false, "bad opcode");
+ }
+
// We don't allow locallocs inside handlers
if (block->hasHndIndex())
{
@@ -15735,6 +16226,12 @@ void Compiler::impImportBlockCode(BasicBlock* block)
}
}
+ if (tiVerificationNeeded)
+ {
+ Verify(impStackTop().seTypeInfo.IsObjRef(), "obj reference needed");
+ // Even if this is a value class, we know it is boxed.
+ tiRetVal = typeInfo(TI_REF, resolvedToken.hClass);
+ }
accessAllowedResult =
info.compCompHnd->canAccessClass(&resolvedToken, info.compMethodHnd, &calloutHelper);
impHandleAccessAllowed(accessAllowedResult, &calloutHelper);
@@ -15806,6 +16303,13 @@ void Compiler::impImportBlockCode(BasicBlock* block)
return;
}
+ if (tiVerificationNeeded)
+ {
+ Verify(typeInfo::AreEquivalent(impStackTop().seTypeInfo, verMakeTypeInfo(impGetRefAnyClass())),
+ "need refany");
+ tiRetVal = verMakeTypeInfo(resolvedToken.hClass).MakeByRef();
+ }
+
op1 = impPopStack().val;
// make certain it is normalized;
op1 = impNormStructVal(op1, impGetRefAnyClass(), (unsigned)CHECK_SPILL_ALL);
@@ -15818,6 +16322,12 @@ void Compiler::impImportBlockCode(BasicBlock* block)
case CEE_REFANYTYPE:
+ if (tiVerificationNeeded)
+ {
+ Verify(typeInfo::AreEquivalent(impStackTop().seTypeInfo, verMakeTypeInfo(impGetRefAnyClass())),
+ "need refany");
+ }
+
op1 = impPopStack().val;
// make certain it is normalized;
@@ -15941,6 +16451,13 @@ void Compiler::impImportBlockCode(BasicBlock* block)
if (opcode == CEE_UNBOX_ANY && !eeIsValueClass(resolvedToken.hClass))
{
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiUnbox = impStackTop().seTypeInfo;
+ Verify(tiUnbox.IsObjRef(), "bad unbox.any arg");
+ tiRetVal = verMakeTypeInfo(resolvedToken.hClass);
+ tiRetVal.NormaliseForStack();
+ }
JITDUMP("\n Importing UNBOX.ANY(refClass) as CASTCLASS\n");
op1 = impPopStack().val;
goto CASTCLASS;
@@ -15951,6 +16468,19 @@ void Compiler::impImportBlockCode(BasicBlock* block)
/* (non-byref) type, but here we're making the tiRetVal that is used */
/* for the intermediate pointer which we then transfer onto the OBJ */
/* instruction. OBJ then creates the appropriate tiRetVal. */
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiUnbox = impStackTop().seTypeInfo;
+ Verify(tiUnbox.IsObjRef(), "Bad unbox arg");
+
+ tiRetVal = verMakeTypeInfo(resolvedToken.hClass);
+ Verify(tiRetVal.IsValueClass(), "not value class");
+ tiRetVal.MakeByRef();
+
+ // We always come from an objref, so this is safe byref
+ tiRetVal.SetIsPermanentHomeByRef();
+ tiRetVal.SetIsReadonlyByRef();
+ }
op1 = impPopStack().val;
assertImp(op1->gtType == TYP_REF);
@@ -16119,6 +16649,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
}
assert(op1->gtType == TYP_BYREF);
+ assert(!tiVerificationNeeded || tiRetVal.IsByRef());
}
else
{
@@ -16163,6 +16694,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
oper = GT_OBJ;
assert(op1->gtType == TYP_BYREF);
+ assert(!tiVerificationNeeded || tiRetVal.IsByRef());
goto OBJ;
}
@@ -16191,6 +16723,29 @@ void Compiler::impImportBlockCode(BasicBlock* block)
JITDUMP(" %08X", resolvedToken.token);
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiActual = impStackTop().seTypeInfo;
+ typeInfo tiBox = verMakeTypeInfo(resolvedToken.hClass);
+
+ Verify(verIsBoxable(tiBox), "boxable type expected");
+
+ // check the class constraints of the boxed type in case we are boxing an uninitialized value
+ Verify(info.compCompHnd->satisfiesClassConstraints(resolvedToken.hClass),
+ "boxed type has unsatisfied class constraints");
+
+ Verify(tiCompatibleWith(tiActual, tiBox.NormaliseForStack(), true), "type mismatch");
+
+ // Observation: the following code introduces a boxed value class on the stack, but,
+ // according to the ECMA spec, one would simply expect: tiRetVal =
+ // typeInfo(TI_REF,impGetObjectClass());
+
+ // Push the result back on the stack,
+ // even if clsHnd is a value class we want the TI_REF
+ // we call back to the EE to get find out what hte type we should push (for nullable we push T)
+ tiRetVal = typeInfo(TI_REF, info.compCompHnd->getTypeForBox(resolvedToken.hClass));
+ }
+
accessAllowedResult =
info.compCompHnd->canAccessClass(&resolvedToken, info.compMethodHnd, &calloutHelper);
impHandleAccessAllowed(accessAllowedResult, &calloutHelper);
@@ -16231,6 +16786,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
JITDUMP(" %08X", resolvedToken.token);
+ if (tiVerificationNeeded)
+ {
+ tiRetVal = typeInfo(TI_INT);
+ }
+
op1 = gtNewIconNode(info.compCompHnd->getClassSize(resolvedToken.hClass));
impPushOnStack(op1, tiRetVal);
break;
@@ -16254,6 +16814,13 @@ void Compiler::impImportBlockCode(BasicBlock* block)
}
}
+ if (tiVerificationNeeded)
+ {
+ Verify(impStackTop().seTypeInfo.IsObjRef(), "object ref expected");
+ // box it
+ tiRetVal = typeInfo(TI_REF, resolvedToken.hClass);
+ }
+
accessAllowedResult =
info.compCompHnd->canAccessClass(&resolvedToken, info.compMethodHnd, &calloutHelper);
impHandleAccessAllowed(accessAllowedResult, &calloutHelper);
@@ -16320,6 +16887,16 @@ void Compiler::impImportBlockCode(BasicBlock* block)
case CEE_THROW:
+ if (tiVerificationNeeded)
+ {
+ tiRetVal = impStackTop().seTypeInfo;
+ Verify(tiRetVal.IsObjRef(), "object ref expected");
+ if (verTrackObjCtorInitState && (verCurrentState.thisInitialized != TIS_Init))
+ {
+ Verify(!tiRetVal.IsThisPtr(), "throw uninitialized this");
+ }
+ }
+
// Any block with a throw is rarely executed.
block->bbSetRunRarely();
@@ -16347,6 +16924,22 @@ void Compiler::impImportBlockCode(BasicBlock* block)
BADCODE("rethrow outside catch");
}
+ if (tiVerificationNeeded)
+ {
+ Verify(block->hasHndIndex(), "rethrow outside catch");
+ if (block->hasHndIndex())
+ {
+ EHblkDsc* HBtab = ehGetDsc(block->getHndIndex());
+ Verify(!HBtab->HasFinallyOrFaultHandler(), "rethrow in finally or fault");
+ if (HBtab->HasFilter())
+ {
+ // we better be in the handler clause part, not the filter part
+ Verify(jitIsBetween(compCurBB->bbCodeOffs, HBtab->ebdHndBegOffs(), HBtab->ebdHndEndOffs()),
+ "rethrow in filter");
+ }
+ }
+ }
+
/* Create the 'rethrow' helper call */
op1 = gtNewHelperCallNode(CORINFO_HELP_RETHROW, TYP_VOID);
@@ -16361,6 +16954,18 @@ void Compiler::impImportBlockCode(BasicBlock* block)
JITDUMP(" %08X", resolvedToken.token);
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiTo = impStackTop().seTypeInfo;
+ typeInfo tiInstr = verMakeTypeInfo(resolvedToken.hClass);
+
+ Verify(tiTo.IsByRef(), "byref expected");
+ Verify(!tiTo.IsReadonlyByRef(), "write to readonly byref");
+
+ Verify(tiCompatibleWith(tiInstr, tiTo.DereferenceByRef(), false),
+ "type operand incompatible with type of address");
+ }
+
op2 = gtNewIconNode(0); // Value
op1 = impPopStack().val; // Dest
@@ -16384,66 +16989,59 @@ void Compiler::impImportBlockCode(BasicBlock* block)
case CEE_INITBLK:
+ if (tiVerificationNeeded)
+ {
+ Verify(false, "bad opcode");
+ }
+
op3 = impPopStack().val; // Size
op2 = impPopStack().val; // Value
- op1 = impPopStack().val; // Dst addr
+ op1 = impPopStack().val; // Dest
if (op3->IsCnsIntOrI())
{
size = (unsigned)op3->AsIntConCommon()->IconValue();
op1 = new (this, GT_BLK) GenTreeBlk(GT_BLK, TYP_STRUCT, op1, typGetBlkLayout(size));
- op1 = gtNewBlkOpNode(op1, op2, (prefixFlags & PREFIX_VOLATILE) != 0, false);
}
else
{
- if (!op2->IsIntegralConst(0))
- {
- op2 = gtNewOperNode(GT_INIT_VAL, TYP_INT, op2);
- }
-
- op1 = new (this, GT_STORE_DYN_BLK) GenTreeStoreDynBlk(op1, op2, op3);
+ op1 = new (this, GT_DYN_BLK) GenTreeDynBlk(op1, op3);
size = 0;
-
- if ((prefixFlags & PREFIX_VOLATILE) != 0)
- {
- op1->gtFlags |= GTF_BLK_VOLATILE;
- }
}
+ op1 = gtNewBlkOpNode(op1, op2, (prefixFlags & PREFIX_VOLATILE) != 0, false);
goto SPILL_APPEND;
case CEE_CPBLK:
- op3 = impPopStack().val; // Size
- op2 = impPopStack().val; // Src addr
- op1 = impPopStack().val; // Dst addr
-
- if (op2->OperGet() == GT_ADDR)
+ if (tiVerificationNeeded)
{
- op2 = op2->AsOp()->gtOp1;
- }
- else
- {
- op2 = gtNewOperNode(GT_IND, TYP_STRUCT, op2);
+ Verify(false, "bad opcode");
}
+ op3 = impPopStack().val; // Size
+ op2 = impPopStack().val; // Src
+ op1 = impPopStack().val; // Dest
if (op3->IsCnsIntOrI())
{
size = (unsigned)op3->AsIntConCommon()->IconValue();
op1 = new (this, GT_BLK) GenTreeBlk(GT_BLK, TYP_STRUCT, op1, typGetBlkLayout(size));
- op1 = gtNewBlkOpNode(op1, op2, (prefixFlags & PREFIX_VOLATILE) != 0, true);
}
else
{
- op1 = new (this, GT_STORE_DYN_BLK) GenTreeStoreDynBlk(op1, op2, op3);
+ op1 = new (this, GT_DYN_BLK) GenTreeDynBlk(op1, op3);
size = 0;
-
- if ((prefixFlags & PREFIX_VOLATILE) != 0)
- {
- op1->gtFlags |= GTF_BLK_VOLATILE;
- }
+ }
+ if (op2->OperGet() == GT_ADDR)
+ {
+ op2 = op2->AsOp()->gtOp1;
+ }
+ else
+ {
+ op2 = gtNewOperNode(GT_IND, TYP_STRUCT, op2);
}
+ op1 = gtNewBlkOpNode(op1, op2, (prefixFlags & PREFIX_VOLATILE) != 0, true);
goto SPILL_APPEND;
case CEE_CPOBJ:
@@ -16454,6 +17052,22 @@ void Compiler::impImportBlockCode(BasicBlock* block)
JITDUMP(" %08X", resolvedToken.token);
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiFrom = impStackTop().seTypeInfo;
+ typeInfo tiTo = impStackTop(1).seTypeInfo;
+ typeInfo tiInstr = verMakeTypeInfo(resolvedToken.hClass);
+
+ Verify(tiFrom.IsByRef(), "expected byref source");
+ Verify(tiTo.IsByRef(), "expected byref destination");
+
+ Verify(tiCompatibleWith(tiFrom.DereferenceByRef(), tiInstr, false),
+ "type of source address incompatible with type operand");
+ Verify(!tiTo.IsReadonlyByRef(), "write to readonly byref");
+ Verify(tiCompatibleWith(tiInstr, tiTo.DereferenceByRef(), false),
+ "type operand incompatible with type of destination address");
+ }
+
if (!eeIsValueClass(resolvedToken.hClass))
{
op1 = impPopStack().val; // address to load from
@@ -16493,7 +17107,38 @@ void Compiler::impImportBlockCode(BasicBlock* block)
lclTyp = TYP_REF;
}
- compUnsafeCastUsed = true;
+ if (tiVerificationNeeded)
+ {
+
+ typeInfo tiPtr = impStackTop(1).seTypeInfo;
+
+ // Make sure we have a good looking byref
+ Verify(tiPtr.IsByRef(), "pointer not byref");
+ Verify(!tiPtr.IsReadonlyByRef(), "write to readonly byref");
+ if (!tiPtr.IsByRef() || tiPtr.IsReadonlyByRef())
+ {
+ compUnsafeCastUsed = true;
+ }
+
+ typeInfo ptrVal = DereferenceByRef(tiPtr);
+ typeInfo argVal = verMakeTypeInfo(resolvedToken.hClass);
+
+ if (!tiCompatibleWith(impStackTop(0).seTypeInfo, NormaliseForStack(argVal), true))
+ {
+ Verify(false, "type of value incompatible with type operand");
+ compUnsafeCastUsed = true;
+ }
+
+ if (!tiCompatibleWith(argVal, ptrVal, false))
+ {
+ Verify(false, "type operand incompatible with type of address");
+ compUnsafeCastUsed = true;
+ }
+ }
+ else
+ {
+ compUnsafeCastUsed = true;
+ }
if (lclTyp == TYP_REF)
{
@@ -16545,6 +17190,16 @@ void Compiler::impImportBlockCode(BasicBlock* block)
return;
}
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiPtr = impStackTop().seTypeInfo;
+ typeInfo tiInstr = verMakeTypeInfo(resolvedToken.hClass);
+
+ Verify(!verIsByRefLike(tiInstr), "mkrefany of byref-like class");
+ Verify(!tiPtr.IsReadonlyByRef(), "readonly byref used with mkrefany");
+ Verify(typeInfo::AreEquivalent(tiPtr.DereferenceByRef(), tiInstr), "type mismatch");
+ }
+
accessAllowedResult =
info.compCompHnd->canAccessClass(&resolvedToken, info.compMethodHnd, &calloutHelper);
impHandleAccessAllowed(accessAllowedResult, &calloutHelper);
@@ -16574,7 +17229,29 @@ void Compiler::impImportBlockCode(BasicBlock* block)
tiRetVal = verMakeTypeInfo(resolvedToken.hClass);
- compUnsafeCastUsed = true;
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiPtr = impStackTop().seTypeInfo;
+
+ // Make sure we have a byref
+ if (!tiPtr.IsByRef())
+ {
+ Verify(false, "pointer not byref");
+ compUnsafeCastUsed = true;
+ }
+ typeInfo tiPtrVal = DereferenceByRef(tiPtr);
+
+ if (!tiCompatibleWith(tiPtrVal, tiRetVal, false))
+ {
+ Verify(false, "type of address incompatible with type operand");
+ compUnsafeCastUsed = true;
+ }
+ tiRetVal.NormaliseForStack();
+ }
+ else
+ {
+ compUnsafeCastUsed = true;
+ }
if (eeIsValueClass(resolvedToken.hClass))
{
@@ -16618,6 +17295,13 @@ void Compiler::impImportBlockCode(BasicBlock* block)
}
case CEE_LDLEN:
+ if (tiVerificationNeeded)
+ {
+ typeInfo tiArray = impStackTop().seTypeInfo;
+ Verify(verIsSDArray(tiArray), "bad array");
+ tiRetVal = typeInfo(TI_INT);
+ }
+
op1 = impPopStack().val;
if (opts.OptimizationEnabled())
{
@@ -16771,6 +17455,12 @@ void Compiler::impLoadArg(unsigned ilArgNum, IL_OFFSET offset)
// It will be mapped to the correct lvaTable index
void Compiler::impLoadLoc(unsigned ilLclNum, IL_OFFSET offset)
{
+ if (tiVerificationNeeded)
+ {
+ Verify(ilLclNum < info.compMethodInfo->locals.numArgs, "bad loc num");
+ Verify(info.compInitMem, "initLocals not set");
+ }
+
if (compIsForInlining())
{
if (ilLclNum >= info.compMethodInfo->locals.numArgs)
@@ -16893,6 +17583,25 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode)
{
const bool isTailCall = (prefixFlags & PREFIX_TAILCALL) != 0;
+ if (tiVerificationNeeded)
+ {
+ verVerifyThisPtrInitialised();
+
+ unsigned expectedStack = 0;
+ if (info.compRetType != TYP_VOID)
+ {
+ typeInfo tiVal = impStackTop().seTypeInfo;
+ typeInfo tiDeclared =
+ verMakeTypeInfo(info.compMethodInfo->args.retType, info.compMethodInfo->args.retTypeClass);
+
+ Verify(!verIsByRefLike(tiDeclared) || verIsSafeToReturnByRef(tiVal), "byref return");
+
+ Verify(tiCompatibleWith(tiVal, tiDeclared.NormaliseForStack(), true), "type mismatch");
+ expectedStack = 1;
+ }
+ Verify(verCurrentState.esStackDepth == expectedStack, "stack non-empty on return");
+ }
+
#ifdef DEBUG
// If we are importing an inlinee and have GC ref locals we always
// need to have a spill temp for the return value. This temp
@@ -17761,6 +18470,27 @@ void Compiler::impImportBlock(BasicBlock* block)
#ifdef TARGET_64BIT
if (genActualType(tree->gtType) == TYP_I_IMPL && lvaTable[tempNum].lvType == TYP_INT)
{
+ if (tiVerificationNeeded && tgtBlock->bbEntryState != nullptr &&
+ (tgtBlock->bbFlags & BBF_FAILED_VERIFICATION) == 0)
+ {
+ // Merge the current state into the entry state of block;
+ // the call to verMergeEntryStates must have changed
+ // the entry state of the block by merging the int local var
+ // and the native-int stack entry.
+ bool changed = false;
+ if (verMergeEntryStates(tgtBlock, &changed))
+ {
+ impRetypeEntryStateTemps(tgtBlock);
+ impReimportBlockPending(tgtBlock);
+ assert(changed);
+ }
+ else
+ {
+ tgtBlock->bbFlags |= BBF_FAILED_VERIFICATION;
+ break;
+ }
+ }
+
// Some other block in the spill clique set this to "int", but now we have "native int".
// Change the type and go back to re-import any blocks that used the wrong type.
lvaTable[tempNum].lvType = TYP_I_IMPL;
@@ -17781,20 +18511,22 @@ void Compiler::impImportBlock(BasicBlock* block)
// imported already, we need to change the type of the local and reimport the spill clique.
// If the 'byref' side has imported, we insert a cast from int to 'native int' to match
// the 'byref' size.
- if (genActualType(tree->gtType) == TYP_BYREF && lvaTable[tempNum].lvType == TYP_INT)
- {
- // Some other block in the spill clique set this to "int", but now we have "byref".
- // Change the type and go back to re-import any blocks that used the wrong type.
- lvaTable[tempNum].lvType = TYP_BYREF;
- reimportSpillClique = true;
- }
- else if (genActualType(tree->gtType) == TYP_INT && lvaTable[tempNum].lvType == TYP_BYREF)
+ if (!tiVerificationNeeded)
{
- // Spill clique has decided this should be "byref", but this block only pushes an "int".
- // Insert a sign-extension to "native int" so we match the clique size.
- verCurrentState.esStack[level].val = gtNewCastNode(TYP_I_IMPL, tree, false, TYP_I_IMPL);
+ if (genActualType(tree->gtType) == TYP_BYREF && lvaTable[tempNum].lvType == TYP_INT)
+ {
+ // Some other block in the spill clique set this to "int", but now we have "byref".
+ // Change the type and go back to re-import any blocks that used the wrong type.
+ lvaTable[tempNum].lvType = TYP_BYREF;
+ reimportSpillClique = true;
+ }
+ else if (genActualType(tree->gtType) == TYP_INT && lvaTable[tempNum].lvType == TYP_BYREF)
+ {
+ // Spill clique has decided this should be "byref", but this block only pushes an "int".
+ // Insert a sign-extension to "native int" so we match the clique size.
+ verCurrentState.esStack[level].val = gtNewCastNode(TYP_I_IMPL, tree, false, TYP_I_IMPL);
+ }
}
-
#endif // TARGET_64BIT
if (tree->gtType == TYP_DOUBLE && lvaTable[tempNum].lvType == TYP_FLOAT)
@@ -17978,6 +18710,25 @@ void Compiler::impImportBlockPending(BasicBlock* block)
#endif
}
+ // Additionally, if we need to verify, merge the verification state.
+ if (tiVerificationNeeded)
+ {
+ // Merge the current state into the entry state of block; if this does not change the entry state
+ // by merging, do not add the block to the pending-list.
+ bool changed = false;
+ if (!verMergeEntryStates(block, &changed))
+ {
+ block->bbFlags |= BBF_FAILED_VERIFICATION;
+ addToPending = true; // We will pop it off, and check the flag set above.
+ }
+ else if (changed)
+ {
+ addToPending = true;
+
+ JITDUMP("Adding " FMT_BB " to pending set due to new merge result\n", block->bbNum);
+ }
+ }
+
if (!addToPending)
{
return;
@@ -18429,6 +19180,16 @@ void Compiler::verInitCurrentState()
verTrackObjCtorInitState = false;
verCurrentState.thisInitialized = TIS_Bottom;
+ if (tiVerificationNeeded)
+ {
+ // Track this ptr initialization
+ if (!info.compIsStatic && (info.compFlags & CORINFO_FLG_CONSTRUCTOR) && lvaTable[0].lvVerTypeInfo.IsObjRef())
+ {
+ verTrackObjCtorInitState = true;
+ verCurrentState.thisInitialized = TIS_Uninit;
+ }
+ }
+
// initialize stack info
verCurrentState.esStackDepth = 0;
@@ -18609,8 +19370,22 @@ void Compiler::impImport()
if (dsc->pdBB->bbFlags & BBF_FAILED_VERIFICATION)
{
- verConvertBBToThrowVerificationException(dsc->pdBB DEBUGARG(true));
- impEndTreeList(dsc->pdBB);
+
+#ifdef TARGET_64BIT
+ // On AMD64, during verification we have to match JIT64 behavior since the VM is very tighly
+ // coupled with the JIT64 IL Verification logic. Look inside verHandleVerificationFailure
+ // method for further explanation on why we raise this exception instead of making the jitted
+ // code throw the verification exception during execution.
+ if (tiVerificationNeeded && opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IMPORT_ONLY))
+ {
+ BADCODE("Basic block marked as not verifiable");
+ }
+ else
+#endif // TARGET_64BIT
+ {
+ verConvertBBToThrowVerificationException(dsc->pdBB DEBUGARG(true));
+ impEndTreeList(dsc->pdBB);
+ }
}
else
{
@@ -18620,7 +19395,7 @@ void Compiler::impImport()
{
return;
}
- if (compIsForImportOnly())
+ if (compIsForImportOnly() && !tiVerificationNeeded)
{
return;
}
@@ -18641,6 +19416,8 @@ void Compiler::impImport()
block->bbFlags &= ~BBF_VISITED;
}
#endif
+
+ assert(!compIsForInlining() || !tiVerificationNeeded);
}
// Checks if a typeinfo (usually stored in the type stack) is a struct.
@@ -18689,10 +19466,7 @@ bool Compiler::impIsAddressInLocal(const GenTree* tree, GenTree** lclVarTreeOut)
if (op->gtOper == GT_LCL_VAR)
{
- if (lclVarTreeOut != nullptr)
- {
- *lclVarTreeOut = op;
- }
+ *lclVarTreeOut = op;
return true;
}
else
@@ -21360,7 +22134,7 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
// Look up the new call info.
CORINFO_CALL_INFO derivedCallInfo;
- eeGetCallInfo(pDerivedResolvedToken, nullptr, CORINFO_CALLINFO_ALLOWINSTPARAM, &derivedCallInfo);
+ eeGetCallInfo(pDerivedResolvedToken, nullptr, addVerifyFlag(CORINFO_CALLINFO_ALLOWINSTPARAM), &derivedCallInfo);
// Update the call.
call->gtCallMoreFlags &= ~GTF_CALL_M_VIRTSTUB_REL_INDIRECT;
diff --git a/src/coreclr/jit/inline.def b/src/coreclr/jit/inline.def
index a519471a3caec..a28daf4e980fd 100644
--- a/src/coreclr/jit/inline.def
+++ b/src/coreclr/jit/inline.def
@@ -70,8 +70,6 @@ INLINE_OBSERVATION(ARG_FEEDS_CONSTANT_TEST, bool, "argument feeds constant t
INLINE_OBSERVATION(ARG_FEEDS_TEST, bool, "argument feeds test", INFORMATION, CALLEE)
INLINE_OBSERVATION(ARG_FEEDS_CAST, int, "argument feeds castclass or isinst", INFORMATION, CALLEE)
INLINE_OBSERVATION(ARG_FEEDS_RANGE_CHECK, bool, "argument feeds range check", INFORMATION, CALLEE)
-INLINE_OBSERVATION(ARG_FEEDS_ISCONST, bool, "argument feeds IsKnownConstant", INFORMATION, CALLEE)
-INLINE_OBSERVATION(CONST_ARG_FEEDS_ISCONST, bool, "const argument feeds IsKnownConstant", INFORMATION, CALLEE)
INLINE_OBSERVATION(ARG_STRUCT, int, "arg is a struct passed by value", INFORMATION, CALLEE)
INLINE_OBSERVATION(RETURNS_STRUCT, bool, "returns a struct by value", INFORMATION, CALLEE)
INLINE_OBSERVATION(ARG_STRUCT_FIELD_ACCESS, int, "ldfld/stfld over arg (struct)", INFORMATION, CALLEE)
diff --git a/src/coreclr/jit/inlinepolicy.cpp b/src/coreclr/jit/inlinepolicy.cpp
index 0ea9135b82c24..1ec47378872d5 100644
--- a/src/coreclr/jit/inlinepolicy.cpp
+++ b/src/coreclr/jit/inlinepolicy.cpp
@@ -326,14 +326,6 @@ void DefaultPolicy::NoteBool(InlineObservation obs, bool value)
m_ArgFeedsRangeCheck++;
break;
- case InlineObservation::CALLEE_CONST_ARG_FEEDS_ISCONST:
- m_ConstArgFeedsIsKnownConst = true;
- break;
-
- case InlineObservation::CALLEE_ARG_FEEDS_ISCONST:
- m_ArgFeedsIsKnownConst = true;
- break;
-
case InlineObservation::CALLEE_UNSUPPORTED_OPCODE:
propagate = true;
break;
@@ -735,15 +727,6 @@ double DefaultPolicy::DetermineMultiplier()
JITDUMP("\nInline candidate has arg that feeds range check. Multiplier increased to %g.", multiplier);
}
- if (m_ConstArgFeedsIsKnownConst || (m_ArgFeedsIsKnownConst && m_IsPrejitRoot))
- {
- // if we use RuntimeHelpers.IsKnownConstant we most likely expect our function to be always inlined
- // at least in the case of constant arguments. In IsPrejitRoot we don't have callsite info so let's
- // assume we have a constant here in order to avoid "baked" noinline
- multiplier += 20;
- JITDUMP("\nConstant argument feeds RuntimeHelpers.IsKnownConstant. Multiplier increased to %g.", multiplier);
- }
-
if (m_ConstantArgFeedsConstantTest > 0)
{
multiplier += 3.0;
@@ -1388,7 +1371,7 @@ void ExtendedDefaultPolicy::NoteInt(InlineObservation obs, int value)
{
SetNever(InlineObservation::CALLEE_DOES_NOT_RETURN);
}
- else if (!m_IsForceInline && !m_HasProfile && !m_ConstArgFeedsIsKnownConst && !m_ArgFeedsIsKnownConst)
+ else if (!m_IsForceInline && !m_HasProfile)
{
unsigned bbLimit = (unsigned)JitConfig.JitExtDefaultPolicyMaxBB();
if (m_IsPrejitRoot)
@@ -1398,7 +1381,6 @@ void ExtendedDefaultPolicy::NoteInt(InlineObservation obs, int value)
bbLimit += 5 + m_Switch * 10;
}
bbLimit += m_FoldableBranch + m_FoldableSwitch * 10;
-
if ((unsigned)value > bbLimit)
{
SetNever(InlineObservation::CALLEE_TOO_MANY_BASIC_BLOCKS);
@@ -2656,8 +2638,6 @@ void DiscretionaryPolicy::DumpData(FILE* file) const
fprintf(file, ",%u", m_ArgFeedsConstantTest);
fprintf(file, ",%u", m_MethodIsMostlyLoadStore ? 1 : 0);
fprintf(file, ",%u", m_ArgFeedsRangeCheck);
- fprintf(file, ",%u", m_ConstArgFeedsIsKnownConst ? 1 : 0);
- fprintf(file, ",%u", m_ArgFeedsIsKnownConst ? 1 : 0);
fprintf(file, ",%u", m_ConstantArgFeedsConstantTest);
fprintf(file, ",%d", m_CalleeNativeSizeEstimate);
fprintf(file, ",%d", m_CallsiteNativeSizeEstimate);
diff --git a/src/coreclr/jit/inlinepolicy.h b/src/coreclr/jit/inlinepolicy.h
index 05e8539982ee8..f5f200e9f5bd7 100644
--- a/src/coreclr/jit/inlinepolicy.h
+++ b/src/coreclr/jit/inlinepolicy.h
@@ -110,8 +110,6 @@ class DefaultPolicy : public LegalPolicy
, m_CallsiteIsInLoop(false)
, m_IsNoReturn(false)
, m_IsNoReturnKnown(false)
- , m_ConstArgFeedsIsKnownConst(false)
- , m_ArgFeedsIsKnownConst(false)
{
// empty
}
@@ -180,8 +178,6 @@ class DefaultPolicy : public LegalPolicy
bool m_CallsiteIsInLoop : 1;
bool m_IsNoReturn : 1;
bool m_IsNoReturnKnown : 1;
- bool m_ConstArgFeedsIsKnownConst : 1;
- bool m_ArgFeedsIsKnownConst : 1;
};
// ExtendedDefaultPolicy is a slightly more aggressive variant of
diff --git a/src/coreclr/jit/instr.cpp b/src/coreclr/jit/instr.cpp
index 1cbe07cb69b1c..bbf204c74caa8 100644
--- a/src/coreclr/jit/instr.cpp
+++ b/src/coreclr/jit/instr.cpp
@@ -1017,8 +1017,7 @@ void CodeGen::inst_RV_RV_IV(instruction ins, emitAttr size, regNumber reg1, regN
//
void CodeGen::inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenTree* rmOp, int ival)
{
- emitter* emit = GetEmitter();
- noway_assert(emit->emitVerifyEncodable(ins, EA_SIZE(attr), reg1));
+ noway_assert(GetEmitter()->emitVerifyEncodable(ins, EA_SIZE(attr), reg1));
if (rmOp->isContained() || rmOp->isUsedFromSpillTemp())
{
@@ -1070,7 +1069,7 @@ void CodeGen::inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenT
case GT_CLS_VAR_ADDR:
{
- emit->emitIns_R_C_I(ins, attr, reg1, addr->AsClsVar()->gtClsVarHnd, 0, ival);
+ GetEmitter()->emitIns_R_C_I(ins, attr, reg1, addr->AsClsVar()->gtClsVarHnd, 0, ival);
return;
}
@@ -1085,7 +1084,7 @@ void CodeGen::inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenT
// temporary GT_IND to generate code with.
memIndir = &load;
}
- emit->emitIns_R_A_I(ins, attr, reg1, memIndir, ival);
+ GetEmitter()->emitIns_R_A_I(ins, attr, reg1, memIndir, ival);
return;
}
}
@@ -1107,14 +1106,6 @@ void CodeGen::inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenT
break;
}
- case GT_CNS_DBL:
- {
- GenTreeDblCon* cns = rmOp->AsDblCon();
- CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(cns->gtDconVal, emitTypeSize(cns));
- emit->emitIns_R_C_I(ins, attr, reg1, hnd, 0, ival);
- return;
- }
-
default:
unreached();
}
@@ -1126,12 +1117,12 @@ void CodeGen::inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenT
assert((varNum != BAD_VAR_NUM) || (tmpDsc != nullptr));
assert(offset != (unsigned)-1);
- emit->emitIns_R_S_I(ins, attr, reg1, varNum, offset, ival);
+ GetEmitter()->emitIns_R_S_I(ins, attr, reg1, varNum, offset, ival);
}
else
{
regNumber rmOpReg = rmOp->GetRegNum();
- emit->emitIns_SIMD_R_R_I(ins, attr, reg1, rmOpReg, ival);
+ GetEmitter()->emitIns_SIMD_R_R_I(ins, attr, reg1, rmOpReg, ival);
}
}
@@ -1151,8 +1142,7 @@ void CodeGen::inst_RV_TT_IV(instruction ins, emitAttr attr, regNumber reg1, GenT
void CodeGen::inst_RV_RV_TT(
instruction ins, emitAttr size, regNumber targetReg, regNumber op1Reg, GenTree* op2, bool isRMW)
{
- emitter* emit = GetEmitter();
- noway_assert(emit->emitVerifyEncodable(ins, EA_SIZE(size), targetReg));
+ noway_assert(GetEmitter()->emitVerifyEncodable(ins, EA_SIZE(size), targetReg));
// TODO-XArch-CQ: Commutative operations can have op1 be contained
// TODO-XArch-CQ: Non-VEX encoded instructions can have both ops contained
@@ -1207,7 +1197,7 @@ void CodeGen::inst_RV_RV_TT(
case GT_CLS_VAR_ADDR:
{
- emit->emitIns_SIMD_R_R_C(ins, size, targetReg, op1Reg, addr->AsClsVar()->gtClsVarHnd, 0);
+ GetEmitter()->emitIns_SIMD_R_R_C(ins, size, targetReg, op1Reg, addr->AsClsVar()->gtClsVarHnd, 0);
return;
}
@@ -1222,7 +1212,7 @@ void CodeGen::inst_RV_RV_TT(
// temporary GT_IND to generate code with.
memIndir = &load;
}
- emit->emitIns_SIMD_R_R_A(ins, size, targetReg, op1Reg, memIndir);
+ GetEmitter()->emitIns_SIMD_R_R_A(ins, size, targetReg, op1Reg, memIndir);
return;
}
}
@@ -1248,9 +1238,10 @@ void CodeGen::inst_RV_RV_TT(
case GT_CNS_DBL:
{
- GenTreeDblCon* cns = op2->AsDblCon();
- CORINFO_FIELD_HANDLE hnd = emit->emitFltOrDblConst(cns->gtDconVal, emitTypeSize(cns));
- emit->emitIns_SIMD_R_R_C(ins, size, targetReg, op1Reg, hnd, 0);
+ GenTreeDblCon* dblCns = op2->AsDblCon();
+ CORINFO_FIELD_HANDLE cnsDblHnd =
+ GetEmitter()->emitFltOrDblConst(dblCns->gtDconVal, emitTypeSize(dblCns));
+ GetEmitter()->emitIns_SIMD_R_R_C(ins, size, targetReg, op1Reg, cnsDblHnd, 0);
return;
}
@@ -1267,7 +1258,7 @@ void CodeGen::inst_RV_RV_TT(
assert((varNum != BAD_VAR_NUM) || (tmpDsc != nullptr));
assert(offset != (unsigned)-1);
- emit->emitIns_SIMD_R_R_S(ins, size, targetReg, op1Reg, varNum, offset);
+ GetEmitter()->emitIns_SIMD_R_R_S(ins, size, targetReg, op1Reg, varNum, offset);
}
else
{
@@ -1286,7 +1277,7 @@ void CodeGen::inst_RV_RV_TT(
op1Reg = targetReg;
}
- emit->emitIns_SIMD_R_R_R(ins, size, targetReg, op1Reg, op2Reg);
+ GetEmitter()->emitIns_SIMD_R_R_R(ins, size, targetReg, op1Reg, op2Reg);
}
}
#endif // TARGET_XARCH
diff --git a/src/coreclr/jit/instrsarm64.h b/src/coreclr/jit/instrsarm64.h
index d4e7ef5b10c8d..c89b006a41897 100644
--- a/src/coreclr/jit/instrsarm64.h
+++ b/src/coreclr/jit/instrsarm64.h
@@ -312,8 +312,8 @@ INST4(neg, "neg", 0, IF_EN4G, 0x4B0003E0, 0x4B0003E0,
INST4(cmeq, "cmeq", 0, IF_EN4H, 0x7EE08C00, 0x2E208C00, 0x5E209800, 0x0E209800)
// cmeq Vd,Vn,Vm DV_3E 01111110111mmmmm 100011nnnnnddddd 7EE0 8C00 Vd,Vn,Vm (scalar)
// cmeq Vd,Vn,Vm DV_3A 0Q101110XX1mmmmm 100011nnnnnddddd 2E20 8C00 Vd,Vn,Vm (vector)
- // cmeq Vd,Vn,#0 DV_2L 01011110XX100000 100110nnnnnddddd 5E20 9800 Vd,Vn,#0 (scalar - with zero)
- // cmeq Vd,Vn,#0 DV_2M 0Q001110XX100000 100110nnnnnddddd 0E20 9800 Vd,Vn,#0 (vector - with zero)
+ // cmeq Vd,Vn DV_2L 01011110XX100000 100110nnnnnddddd 5E20 9800 Vd,Vn (scalar)
+ // cmeq Vd,Vn DV_2M 0Q001110XX100000 100110nnnnnddddd 0E20 9800 Vd,Vn (vector)
INST4(cmge, "cmge", 0, IF_EN4H, 0x5EE03C00, 0x0E203C00, 0x7E208800, 0x2E208800)
// cmge Vd,Vn,Vm DV_3E 01011110111mmmmm 001111nnnnnddddd 5EE0 3C00 Vd,Vn,Vm (scalar)
@@ -331,8 +331,8 @@ INST4(cmgt, "cmgt", 0, IF_EN4H, 0x5EE03400, 0x0E203400,
INST4(fcmeq, "fcmeq", 0, IF_EN4I, 0x5E20E400, 0x0E20E400, 0x5EA0D800, 0x0EA0D800)
// fcmeq Vd,Vn,Vm DV_3D 010111100X1mmmmm 111001nnnnnddddd 5E20 E400 Vd Vn Vm (scalar)
// fcmeq Vd,Vn,Vm DV_3B 0Q0011100X1mmmmm 111001nnnnnddddd 0E20 E400 Vd,Vn,Vm (vector)
- // fcmeq Vd,Vn,#0 DV_2G 010111101X100000 110110nnnnnddddd 5EA0 D800 Vd Vn,#0 (scalar - with zero)
- // fcmeq Vd,Vn,#0 DV_2A 0Q0011101X100000 110110nnnnnddddd 0EA0 D800 Vd Vn,#0 (vector - with zero)
+ // fcmeq Vd,Vn DV_2G 010111101X100000 110110nnnnnddddd 5EA0 D800 Vd Vn (scalar)
+ // fcmeq Vd,Vn DV_2A 0Q0011101X100000 110110nnnnnddddd 0EA0 D800 Vd Vn (vector)
INST4(fcmge, "fcmge", 0, IF_EN4I, 0x7E20E400, 0x2E20E400, 0x7EA0C800, 0x2EA0C800)
// fcmge Vd,Vn,Vm DV_3D 011111100X1mmmmm 111001nnnnnddddd 7E20 E400 Vd Vn Vm (scalar)
diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h
index 08d4c4a8c8675..458f919fe2793 100644
--- a/src/coreclr/jit/instrsxarch.h
+++ b/src/coreclr/jit/instrsxarch.h
@@ -595,7 +595,7 @@ INST3(FIRST_BMI_INSTRUCTION, "FIRST_BMI_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE
INST3(andn, "andn", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF2), INS_Flags_IsDstDstSrcAVXInstruction) // Logical AND NOT
INST3(blsi, "blsi", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), INS_Flags_IsDstDstSrcAVXInstruction) // Extract Lowest Set Isolated Bit
INST3(blsmsk, "blsmsk", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), INS_Flags_IsDstDstSrcAVXInstruction) // Get Mask Up to Lowest Set Bit
-INST3(blsr, "blsr", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_IsDstDstSrcAVXInstruction) // Reset Lowest Set Bit
+INST3(blsr, "blsr", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), INS_Flags_IsDstDstSrcAVXInstruction) // Reset Lowest Set Bit
INST3(bextr, "bextr", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF7), INS_Flags_IsDstDstSrcAVXInstruction) // Bit Field Extract
// BMI2
diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h
index 1346c2069da17..1c8da276c3dc5 100644
--- a/src/coreclr/jit/jitconfigvalues.h
+++ b/src/coreclr/jit/jitconfigvalues.h
@@ -463,24 +463,10 @@ CONFIG_INTEGER(TC_OnStackReplacement, W("TC_OnStackReplacement"), 0)
CONFIG_INTEGER(TC_OnStackReplacement_InitialCounter, W("TC_OnStackReplacement_InitialCounter"), 1000)
// Enable partial compilation for Tier0 methods
CONFIG_INTEGER(TC_PartialCompilation, W("TC_PartialCompilation"), 0)
-#if defined(DEBUG)
-// Randomly sprinkle patchpoints. Value is the likelyhood any given stack-empty point becomes a patchpoint.
-CONFIG_INTEGER(JitRandomOnStackReplacement, W("JitRandomOnStackReplacement"), 0)
-// Place patchpoint at the specified IL offset, if possible. Overrides random placement.
-CONFIG_INTEGER(JitOffsetOnStackReplacement, W("JitOffsetOnStackReplacement"), -1)
-#endif // debug
#if defined(DEBUG)
-// EnableOsrRange allows you to limit the set of methods that will rely on OSR to escape
-// from Tier0 code. Methods outside the range that would normally be jitted at Tier0
-// and have patchpoints will instead be switched to optimized.
-CONFIG_STRING(JitEnableOsrRange, W("JitEnableOsrRange"))
-// EnablePatchpointRange allows you to limit the set of Tier0 methods that
-// will have patchpoints, and hence control which methods will create OSR methods.
-// Unlike EnableOsrRange, it will not alter the optimization setting for methods
-// outside the enabled range.
-CONFIG_STRING(JitEnablePatchpointRange, W("JitEnablePatchpointRange"))
-#endif
+CONFIG_STRING(JitEnableOsrRange, W("JitEnableOsrRange")) // Enable osr for only some methods
+#endif // debug
// Profile instrumentation options
CONFIG_INTEGER(JitMinimalJitProfiling, W("JitMinimalJitProfiling"), 1)
diff --git a/src/coreclr/jit/lclmorph.cpp b/src/coreclr/jit/lclmorph.cpp
index 66684e38e1a3b..84d7965d395bf 100644
--- a/src/coreclr/jit/lclmorph.cpp
+++ b/src/coreclr/jit/lclmorph.cpp
@@ -567,6 +567,26 @@ class LocalAddressVisitor final : public GenTreeVisitor
PopValue();
break;
+ case GT_DYN_BLK:
+ assert(TopValue(2).Node() == node);
+ assert(TopValue(1).Node() == node->AsDynBlk()->Addr());
+ assert(TopValue(0).Node() == node->AsDynBlk()->gtDynamicSize);
+
+ // The block size may be the result of an indirection so we need
+ // to escape the location that may be associated with it.
+ EscapeValue(TopValue(0), node);
+
+ if (!TopValue(2).Indir(TopValue(1)))
+ {
+ // If the address comes from another indirection (e.g. DYN_BLK(IND(...))
+ // then we need to escape the location.
+ EscapeLocation(TopValue(1), node);
+ }
+
+ PopValue();
+ PopValue();
+ break;
+
case GT_RETURN:
if (TopValue(0).Node() != node)
{
@@ -809,13 +829,14 @@ class LocalAddressVisitor final : public GenTreeVisitor
// user - the node that uses the indirection
//
// Notes:
- // This returns 0 for indirection of unknown size. GT_IND nodes that have type
- // TYP_STRUCT are expected to only appears on the RHS of an assignment, in which
- // case the LHS size will be used instead. Otherwise 0 is returned as well.
+ // This returns 0 for indirection of unknown size, typically GT_DYN_BLK.
+ // GT_IND nodes that have type TYP_STRUCT are expected to only appears
+ // on the RHS of an assignment, in which case the LHS size will be used instead.
+ // Otherwise 0 is returned as well.
//
unsigned GetIndirSize(GenTree* indir, GenTree* user)
{
- assert(indir->OperIs(GT_IND, GT_OBJ, GT_BLK, GT_FIELD));
+ assert(indir->OperIs(GT_IND, GT_OBJ, GT_BLK, GT_DYN_BLK, GT_FIELD));
if (indir->TypeGet() != TYP_STRUCT)
{
@@ -862,7 +883,7 @@ class LocalAddressVisitor final : public GenTreeVisitor
case GT_OBJ:
return indir->AsBlk()->GetLayout()->GetSize();
default:
- assert(indir->OperIs(GT_IND));
+ assert(indir->OperIs(GT_IND, GT_DYN_BLK));
return 0;
}
}
diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp
index a1cfc61822216..7b329e0a86a46 100644
--- a/src/coreclr/jit/lclvars.cpp
+++ b/src/coreclr/jit/lclvars.cpp
@@ -305,9 +305,7 @@ void Compiler::lvaInitTypeRef()
JITDUMP("-- V%02u is OSR exposed\n", varNum);
varDsc->lvHasLdAddrOp = 1;
- // todo: Why does it apply only to non-structs?
- //
- if (!varTypeIsStruct(varDsc) && !varTypeIsSIMD(varDsc))
+ if (varDsc->lvType != TYP_STRUCT) // Why does it apply only to non-structs?
{
lvaSetVarAddrExposed(varNum DEBUGARG(AddressExposedReason::OSR_EXPOSED));
}
@@ -487,7 +485,19 @@ void Compiler::lvaInitThisPtr(InitVarDscInfo* varDscInfo)
lvaSetClass(varDscInfo->varNum, info.compClassHnd);
}
- varDsc->lvVerTypeInfo = typeInfo();
+ if (tiVerificationNeeded)
+ {
+ varDsc->lvVerTypeInfo = verMakeTypeInfo(info.compClassHnd);
+
+ if (varDsc->lvVerTypeInfo.IsValueClass())
+ {
+ varDsc->lvVerTypeInfo.MakeByRef();
+ }
+ }
+ else
+ {
+ varDsc->lvVerTypeInfo = typeInfo();
+ }
// Mark the 'this' pointer for the method
varDsc->lvVerTypeInfo.SetIsThisPtr();
@@ -1311,6 +1321,48 @@ void Compiler::lvaInitVarDsc(LclVarDsc* varDsc,
compFloatingPointUsed = true;
}
+ if (tiVerificationNeeded)
+ {
+ varDsc->lvVerTypeInfo = verParseArgSigToTypeInfo(varSig, varList);
+ }
+
+ if (tiVerificationNeeded)
+ {
+ if (varDsc->lvIsParam)
+ {
+ // For an incoming ValueType we better be able to have the full type information
+ // so that we can layout the parameter offsets correctly
+
+ if (varTypeIsStruct(type) && varDsc->lvVerTypeInfo.IsDead())
+ {
+ BADCODE("invalid ValueType parameter");
+ }
+
+ // For an incoming reference type we need to verify that the actual type is
+ // a reference type and not a valuetype.
+
+ if (type == TYP_REF &&
+ !(varDsc->lvVerTypeInfo.IsType(TI_REF) || varDsc->lvVerTypeInfo.IsUnboxedGenericTypeVar()))
+ {
+ BADCODE("parameter type mismatch");
+ }
+ }
+
+ // Disallow byrefs to byref like objects (ArgTypeHandle)
+ // techncally we could get away with just not setting them
+ if (varDsc->lvVerTypeInfo.IsByRef() && verIsByRefLike(DereferenceByRef(varDsc->lvVerTypeInfo)))
+ {
+ varDsc->lvVerTypeInfo = typeInfo();
+ }
+
+ // we don't want the EE to assert in lvaSetStruct on bad sigs, so change
+ // the JIT type to avoid even trying to call back
+ if (varTypeIsStruct(type) && varDsc->lvVerTypeInfo.IsDead())
+ {
+ type = TYP_VOID;
+ }
+ }
+
if (typeHnd)
{
unsigned cFlags = info.compCompHnd->getClassAttribs(typeHnd);
@@ -1319,8 +1371,11 @@ void Compiler::lvaInitVarDsc(LclVarDsc* varDsc,
// a primitive. We will need the typeHnd to distinguish them, so we store it here.
if ((cFlags & CORINFO_FLG_VALUECLASS) && !varTypeIsStruct(type))
{
- // printf("This is a struct that the JIT will treat as a primitive\n");
- varDsc->lvVerTypeInfo = verMakeTypeInfo(typeHnd);
+ if (tiVerificationNeeded == false)
+ {
+ // printf("This is a struct that the JIT will treat as a primitive\n");
+ varDsc->lvVerTypeInfo = verMakeTypeInfo(typeHnd);
+ }
}
varDsc->lvOverlappingFields = StructHasOverlappingFields(cFlags);
@@ -1338,7 +1393,7 @@ void Compiler::lvaInitVarDsc(LclVarDsc* varDsc,
}
if ((varTypeIsStruct(type)))
{
- lvaSetStruct(varNum, typeHnd, typeHnd != nullptr, true);
+ lvaSetStruct(varNum, typeHnd, typeHnd != nullptr, !tiVerificationNeeded);
if (info.compIsVarArgs)
{
lvaSetStructUsedAsVarArg(varNum);
@@ -4056,8 +4111,8 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt,
#endif // UNIX_AMD64_ABI
/* Variables must be used as the same type throughout the method */
- noway_assert(varDsc->lvType == TYP_UNDEF || tree->gtType == TYP_UNKNOWN || allowStructs ||
- genActualType(varDsc->TypeGet()) == genActualType(tree->gtType) ||
+ noway_assert(tiVerificationNeeded || varDsc->lvType == TYP_UNDEF || tree->gtType == TYP_UNKNOWN ||
+ allowStructs || genActualType(varDsc->TypeGet()) == genActualType(tree->gtType) ||
(tree->gtType == TYP_BYREF && varDsc->TypeGet() == TYP_I_IMPL) ||
(tree->gtType == TYP_I_IMPL && varDsc->TypeGet() == TYP_BYREF) || (tree->gtFlags & GTF_VAR_CAST) ||
(varTypeIsFloating(varDsc) && varTypeIsFloating(tree)) ||
diff --git a/src/coreclr/jit/lir.cpp b/src/coreclr/jit/lir.cpp
index 81d03b93f7b34..97f9e4f4807d2 100644
--- a/src/coreclr/jit/lir.cpp
+++ b/src/coreclr/jit/lir.cpp
@@ -1636,7 +1636,7 @@ void LIR::InsertBeforeTerminator(BasicBlock* block, LIR::Range&& range)
LIR::Range& blockRange = LIR::AsRange(block);
GenTree* insertionPoint = nullptr;
- if (block->KindIs(BBJ_COND, BBJ_SWITCH, BBJ_RETURN))
+ if ((block->bbJumpKind == BBJ_COND) || (block->bbJumpKind == BBJ_SWITCH) || (block->bbJumpKind == BBJ_RETURN))
{
insertionPoint = blockRange.LastNode();
assert(insertionPoint != nullptr);
diff --git a/src/coreclr/jit/liveness.cpp b/src/coreclr/jit/liveness.cpp
index d9592683db798..4f8d9334249cf 100644
--- a/src/coreclr/jit/liveness.cpp
+++ b/src/coreclr/jit/liveness.cpp
@@ -2090,6 +2090,7 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR
case GT_BLK:
case GT_OBJ:
+ case GT_DYN_BLK:
{
bool removed = fgTryRemoveNonLocal(node, &blockRange);
if (!removed && node->IsUnusedValue())
diff --git a/src/coreclr/jit/loopcloning.cpp b/src/coreclr/jit/loopcloning.cpp
index bdd8d763aa4c7..c206249a43740 100644
--- a/src/coreclr/jit/loopcloning.cpp
+++ b/src/coreclr/jit/loopcloning.cpp
@@ -767,7 +767,7 @@ BasicBlock* LoopCloneContext::CondToStmtInBlock(Compiler*
{
noway_assert(conds.Size() > 0);
assert(slowHead != nullptr);
- assert(insertAfter->KindIs(BBJ_NONE, BBJ_COND));
+ assert((insertAfter->bbJumpKind == BBJ_NONE) || (insertAfter->bbJumpKind == BBJ_COND));
// Choose how to generate the conditions
const bool generateOneConditionPerBlock = true;
@@ -1847,7 +1847,7 @@ void Compiler::optCloneLoop(unsigned loopInd, LoopCloneContext* context)
// X
BasicBlock* h = loop.lpHead;
- if (!h->KindIs(BBJ_NONE, BBJ_ALWAYS))
+ if (h->bbJumpKind != BBJ_NONE && h->bbJumpKind != BBJ_ALWAYS)
{
// Make a new block to be the unique entry to the loop.
JITDUMP("Create new unique single-successor entry to loop\n");
diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp
index b111d73db6a99..06d42a37f986f 100644
--- a/src/coreclr/jit/lower.cpp
+++ b/src/coreclr/jit/lower.cpp
@@ -139,7 +139,7 @@ GenTree* Lowering::LowerNode(GenTree* node)
case GT_AND:
case GT_OR:
case GT_XOR:
- return LowerBinaryArithmeticCommon(node->AsOp());
+ return LowerBinaryArithmetic(node->AsOp());
case GT_MUL:
case GT_MULHI:
@@ -2708,16 +2708,10 @@ GenTree* Lowering::OptimizeConstCompare(GenTree* cmp)
if (op2->IsIntegralConst(0) && (op1->gtNext == op2) && (op2->gtNext == cmp) &&
#ifdef TARGET_XARCH
- (op1->OperIs(GT_AND, GT_OR, GT_XOR, GT_ADD, GT_SUB, GT_NEG)
-#ifdef FEATURE_HW_INTRINSICS
- || (op1->OperIs(GT_HWINTRINSIC) &&
- emitter::DoesWriteZeroFlag(HWIntrinsicInfo::lookupIns(op1->AsHWIntrinsic())))
-#endif // FEATURE_HW_INTRINSICS
- )
+ op1->OperIs(GT_AND, GT_OR, GT_XOR, GT_ADD, GT_SUB, GT_NEG))
#else // TARGET_ARM64
- op1->OperIs(GT_AND, GT_ADD, GT_SUB)
+ op1->OperIs(GT_AND, GT_ADD, GT_SUB))
#endif
- )
{
op1->gtFlags |= GTF_SET_FLAGS;
op1->SetUnusedValue();
@@ -3798,29 +3792,32 @@ GenTree* Lowering::LowerDelegateInvoke(GenTreeCall* call)
assert(thisArgNode != nullptr);
assert(thisArgNode->gtOper == GT_PUTARG_REG);
- GenTree* thisExpr = thisArgNode->AsOp()->gtOp1;
+ GenTree* originalThisExpr = thisArgNode->AsOp()->gtOp1;
+ GenTree* thisExpr = originalThisExpr;
// We're going to use the 'this' expression multiple times, so make a local to copy it.
- GenTree* base;
- if (thisExpr->OperIs(GT_LCL_VAR))
- {
- base = comp->gtNewLclvNode(thisExpr->AsLclVar()->GetLclNum(), thisExpr->TypeGet());
- }
- else if (thisExpr->OperIs(GT_LCL_FLD))
+ unsigned lclNum;
+
+ if (call->IsTailCallViaJitHelper() && originalThisExpr->IsLocal())
{
- base = comp->gtNewLclFldNode(thisExpr->AsLclFld()->GetLclNum(), thisExpr->TypeGet(),
- thisExpr->AsLclFld()->GetLclOffs());
+ // For ordering purposes for the special tailcall arguments on x86, we forced the
+ // 'this' pointer in this case to a local in Compiler::fgMorphTailCall().
+ // We could possibly use this case to remove copies for all architectures and non-tailcall
+ // calls by creating a new lcl var or lcl field reference, as is done in the
+ // LowerVirtualVtableCall() code.
+ assert(originalThisExpr->OperGet() == GT_LCL_VAR);
+ lclNum = originalThisExpr->AsLclVarCommon()->GetLclNum();
}
else
{
unsigned delegateInvokeTmp = comp->lvaGrabTemp(true DEBUGARG("delegate invoke call"));
- base = comp->gtNewLclvNode(delegateInvokeTmp, thisExpr->TypeGet());
LIR::Use thisExprUse(BlockRange(), &thisArgNode->AsOp()->gtOp1, thisArgNode);
ReplaceWithLclVar(thisExprUse, delegateInvokeTmp);
thisExpr = thisExprUse.Def(); // it's changed; reload it.
+ lclNum = delegateInvokeTmp;
}
// replace original expression feeding into thisPtr with
@@ -3839,6 +3836,8 @@ GenTree* Lowering::LowerDelegateInvoke(GenTreeCall* call)
// the control target is
// [originalThis + firstTgtOffs]
+ GenTree* base = new (comp, GT_LCL_VAR) GenTreeLclVar(GT_LCL_VAR, originalThisExpr->TypeGet(), lclNum);
+
unsigned targetOffs = comp->eeGetEEInfo()->offsetOfDelegateFirstTarget;
GenTree* result = new (comp, GT_LEA) GenTreeAddrMode(TYP_REF, base, nullptr, 0, targetOffs);
GenTree* callTarget = Ind(result);
@@ -4607,7 +4606,7 @@ GenTree* Lowering::LowerVirtualVtableCall(GenTreeCall* call)
// If what we are passing as the thisptr is not already a local, make a new local to place it in
// because we will be creating expressions based on it.
unsigned lclNum;
- if (thisPtr->OperIsLocal())
+ if (thisPtr->IsLocal())
{
lclNum = thisPtr->AsLclVarCommon()->GetLclNum();
}
@@ -4891,29 +4890,20 @@ bool Lowering::AreSourcesPossiblyModifiedLocals(GenTree* addr, GenTree* base, Ge
// addressing mode and transform them to a GT_LEA
//
// Arguments:
-// addr - the use of the address we want to transform
+// use - the use of the address we want to transform
// isContainable - true if this addressing mode can be contained
-// parent - the node that consumes the given addr (most likely it's an IND)
+// targetType - on arm we can use "scale" only for appropriate target type
//
// Returns:
// true if the address node was changed to a LEA, false otherwise.
//
-bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* parent)
+bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, var_types targetType)
{
if (!addr->OperIs(GT_ADD) || addr->gtOverflow())
{
return false;
}
-#ifdef TARGET_ARM64
- if (parent->OperIsIndir() && parent->AsIndir()->IsVolatile() && !varTypeIsGC(addr))
- {
- // For Arm64 we avoid using LEA for volatile INDs
- // because we won't be able to use ldar/star
- return false;
- }
-#endif
-
GenTree* base = nullptr;
GenTree* index = nullptr;
unsigned scale = 0;
@@ -4929,8 +4919,6 @@ bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* par
&scale, // scaling
&offset); // displacement
- var_types targetType = parent->OperIsIndir() ? parent->TypeGet() : TYP_UNDEF;
-
#ifdef TARGET_ARMARCH
// Multiplier should be a "natural-scale" power of two number which is equal to target's width.
//
@@ -5120,7 +5108,7 @@ GenTree* Lowering::LowerAdd(GenTreeOp* node)
GenTree* parent = use.User();
if (!parent->OperIsIndir() && !parent->OperIs(GT_ADD))
{
- TryCreateAddrMode(node, false, parent);
+ TryCreateAddrMode(node, false);
}
}
#endif // !TARGET_ARMARCH
@@ -5134,7 +5122,7 @@ GenTree* Lowering::LowerAdd(GenTreeOp* node)
}
//------------------------------------------------------------------------
-// LowerBinaryArithmeticCommon: lowers the given binary arithmetic node.
+// LowerBinaryArithmetic: lowers the given binary arithmetic node.
//
// Recognizes opportunities for using target-independent "combined" nodes
// (currently AND_NOT on ARMArch). Performs containment checks.
@@ -5145,39 +5133,41 @@ GenTree* Lowering::LowerAdd(GenTreeOp* node)
// Returns:
// The next node to lower.
//
-GenTree* Lowering::LowerBinaryArithmeticCommon(GenTreeOp* binOp)
+GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* node)
{
// TODO-CQ-XArch: support BMI2 "andn" in codegen and condition
// this logic on the support for the instruction set on XArch.
CLANG_FORMAT_COMMENT_ANCHOR;
#ifdef TARGET_ARMARCH
- if (comp->opts.OptimizationEnabled() && binOp->OperIs(GT_AND))
+ if (comp->opts.OptimizationEnabled() && node->OperIs(GT_AND))
{
GenTree* opNode = nullptr;
GenTree* notNode = nullptr;
- if (binOp->gtGetOp1()->OperIs(GT_NOT))
+ if (node->gtGetOp1()->OperIs(GT_NOT))
{
- notNode = binOp->gtGetOp1();
- opNode = binOp->gtGetOp2();
+ notNode = node->gtGetOp1();
+ opNode = node->gtGetOp2();
}
- else if (binOp->gtGetOp2()->OperIs(GT_NOT))
+ else if (node->gtGetOp2()->OperIs(GT_NOT))
{
- notNode = binOp->gtGetOp2();
- opNode = binOp->gtGetOp1();
+ notNode = node->gtGetOp2();
+ opNode = node->gtGetOp1();
}
if (notNode != nullptr)
{
- binOp->gtOp1 = opNode;
- binOp->gtOp2 = notNode->AsUnOp()->gtGetOp1();
- binOp->ChangeOper(GT_AND_NOT);
+ node->gtOp1 = opNode;
+ node->gtOp2 = notNode->AsUnOp()->gtGetOp1();
+ node->ChangeOper(GT_AND_NOT);
BlockRange().Remove(notNode);
}
}
-#endif
+#endif // TARGET_ARMARCH
+
+ ContainCheckBinary(node);
- return LowerBinaryArithmetic(binOp);
+ return node->gtNext;
}
//------------------------------------------------------------------------
@@ -6789,7 +6779,7 @@ void Lowering::ContainCheckBitCast(GenTree* node)
void Lowering::LowerStoreIndirCommon(GenTreeStoreInd* ind)
{
assert(ind->TypeGet() != TYP_STRUCT);
- TryCreateAddrMode(ind->Addr(), true, ind);
+ TryCreateAddrMode(ind->Addr(), true, ind->TypeGet());
if (!comp->codeGen->gcInfo.gcIsWriteBarrierStoreIndNode(ind))
{
if (varTypeIsFloating(ind) && ind->Data()->IsCnsFltOrDbl())
@@ -6857,7 +6847,7 @@ void Lowering::LowerIndir(GenTreeIndir* ind)
// TODO-Cleanup: We're passing isContainable = true but ContainCheckIndir rejects
// address containment in some cases so we end up creating trivial (reg + offfset)
// or (reg + reg) LEAs that are not necessary.
- TryCreateAddrMode(ind->Addr(), true, ind);
+ TryCreateAddrMode(ind->Addr(), true, ind->TypeGet());
ContainCheckIndir(ind);
if (ind->OperIs(GT_NULLCHECK) || ind->IsUnusedValue())
@@ -6870,7 +6860,7 @@ void Lowering::LowerIndir(GenTreeIndir* ind)
// If the `ADDR` node under `STORE_OBJ(dstAddr, IND(struct(ADDR))`
// is a complex one it could benefit from an `LEA` that is not contained.
const bool isContainable = false;
- TryCreateAddrMode(ind->Addr(), isContainable, ind);
+ TryCreateAddrMode(ind->Addr(), isContainable, ind->TypeGet());
}
}
@@ -6932,14 +6922,6 @@ void Lowering::TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, Bas
void Lowering::LowerBlockStoreCommon(GenTreeBlk* blkNode)
{
assert(blkNode->OperIs(GT_STORE_BLK, GT_STORE_DYN_BLK, GT_STORE_OBJ));
-
- // Lose the type information stored in the source - we no longer need it.
- if (blkNode->Data()->OperIs(GT_OBJ, GT_BLK))
- {
- blkNode->Data()->SetOper(GT_IND);
- LowerIndir(blkNode->Data()->AsIndir());
- }
-
if (TryTransformStoreObjAsStoreInd(blkNode))
{
return;
@@ -7014,7 +6996,7 @@ bool Lowering::TryTransformStoreObjAsStoreInd(GenTreeBlk* blkNode)
return false;
}
- JITDUMP("Replacing STORE_OBJ with STOREIND for [%06u]\n", blkNode->gtTreeID);
+ JITDUMP("Replacing STORE_OBJ with STOREIND for [06%u]", blkNode->gtTreeID);
blkNode->ChangeOper(GT_STOREIND);
blkNode->ChangeType(regType);
diff --git a/src/coreclr/jit/lower.h b/src/coreclr/jit/lower.h
index 95843b6bded47..ed0ecc5661970 100644
--- a/src/coreclr/jit/lower.h
+++ b/src/coreclr/jit/lower.h
@@ -297,8 +297,7 @@ class Lowering final : public Phase
void LowerStoreIndir(GenTreeStoreInd* node);
GenTree* LowerAdd(GenTreeOp* node);
GenTree* LowerMul(GenTreeOp* mul);
- GenTree* LowerBinaryArithmeticCommon(GenTreeOp* binOp);
- GenTree* LowerBinaryArithmetic(GenTreeOp* binOp);
+ GenTree* LowerBinaryArithmetic(GenTreeOp* node);
bool LowerUnsignedDivOrMod(GenTreeOp* divMod);
GenTree* LowerConstIntDivOrMod(GenTree* node);
GenTree* LowerSignedDivOrMod(GenTree* node);
@@ -307,7 +306,7 @@ class Lowering final : public Phase
void ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenTree* addr);
void LowerPutArgStk(GenTreePutArgStk* tree);
- bool TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* parent);
+ bool TryCreateAddrMode(GenTree* addr, bool isContainable, var_types targetType = TYP_UNDEF);
bool TryTransformStoreObjAsStoreInd(GenTreeBlk* blkNode);
@@ -344,7 +343,6 @@ class Lowering final : public Phase
void LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node);
void LowerHWIntrinsicGetElement(GenTreeHWIntrinsic* node);
void LowerHWIntrinsicWithElement(GenTreeHWIntrinsic* node);
- GenTree* TryLowerAndOpToResetLowestSetBit(GenTreeOp* binOp);
#elif defined(TARGET_ARM64)
bool IsValidConstForMovImm(GenTreeHWIntrinsic* node);
void LowerHWIntrinsicFusedMultiplyAddScalar(GenTreeHWIntrinsic* node);
@@ -566,8 +564,8 @@ class Lowering final : public Phase
}
#ifdef FEATURE_HW_INTRINSICS
- // Tries to get a containable node for a given HWIntrinsic
- bool TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode, GenTree** pNode, bool* supportsRegOptional);
+ // Return true if 'node' is a containable HWIntrinsic op.
+ bool IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode, GenTree* node, bool* supportsRegOptional);
#endif // FEATURE_HW_INTRINSICS
static void TransformUnusedIndirection(GenTreeIndir* ind, Compiler* comp, BasicBlock* block);
diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp
index 67e1269dfd429..e4ba37cffb1d5 100644
--- a/src/coreclr/jit/lowerarmarch.cpp
+++ b/src/coreclr/jit/lowerarmarch.cpp
@@ -281,22 +281,6 @@ GenTree* Lowering::LowerMul(GenTreeOp* mul)
return mul->gtNext;
}
-//------------------------------------------------------------------------
-// LowerBinaryArithmetic: lowers the given binary arithmetic node.
-//
-// Arguments:
-// node - the arithmetic node to lower
-//
-// Returns:
-// The next node to lower.
-//
-GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp)
-{
- ContainCheckBinary(binOp);
-
- return binOp->gtNext;
-}
-
//------------------------------------------------------------------------
// LowerBlockStore: Lower a block store node
//
@@ -309,8 +293,6 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
GenTree* src = blkNode->Data();
unsigned size = blkNode->Size();
- const bool isDstAddrLocal = dstAddr->OperIsLocalAddr();
-
if (blkNode->OperIsInitBlkOp())
{
if (src->OperIs(GT_INIT_VAL))
@@ -324,18 +306,7 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
blkNode->SetOper(GT_STORE_BLK);
}
- unsigned initBlockUnrollLimit = INITBLK_UNROLL_LIMIT;
-
-#ifdef TARGET_ARM64
- if (isDstAddrLocal)
- {
- // Since dstAddr points to the stack CodeGen can use more optimal
- // quad-word store SIMD instructions for InitBlock.
- initBlockUnrollLimit = INITBLK_LCL_UNROLL_LIMIT;
- }
-#endif
-
- if (!blkNode->OperIs(GT_STORE_DYN_BLK) && (size <= initBlockUnrollLimit) && src->OperIs(GT_CNS_INT))
+ if (!blkNode->OperIs(GT_STORE_DYN_BLK) && (size <= INITBLK_UNROLL_LIMIT) && src->OperIs(GT_CNS_INT))
{
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindUnroll;
@@ -382,39 +353,19 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
assert(src->OperIs(GT_IND, GT_LCL_VAR, GT_LCL_FLD));
src->SetContained();
- bool isSrcAddrLocal = false;
-
if (src->OperIs(GT_IND))
{
- GenTree* srcAddr = src->AsIndir()->Addr();
// TODO-Cleanup: Make sure that GT_IND lowering didn't mark the source address as contained.
// Sometimes the GT_IND type is a non-struct type and then GT_IND lowering may contain the
// address, not knowing that GT_IND is part of a block op that has containment restrictions.
- srcAddr->ClearContained();
- isSrcAddrLocal = srcAddr->OperIsLocalAddr();
- }
- else
- {
- isSrcAddrLocal = true;
-
- if (src->OperIs(GT_LCL_VAR))
- {
- // TODO-1stClassStructs: for now we can't work with STORE_BLOCK source in register.
- const unsigned srcLclNum = src->AsLclVar()->GetLclNum();
- comp->lvaSetVarDoNotEnregister(srcLclNum DEBUGARG(DoNotEnregisterReason::BlockOp));
- }
+ src->AsIndir()->Addr()->ClearContained();
}
-
- unsigned copyBlockUnrollLimit = CPBLK_UNROLL_LIMIT;
-
-#ifdef TARGET_ARM64
- if (isSrcAddrLocal && isDstAddrLocal)
+ else if (src->OperIs(GT_LCL_VAR))
{
- // Since both srcAddr and dstAddr point to the stack CodeGen can use more optimal
- // quad-word load and store SIMD instructions for CopyBlock.
- copyBlockUnrollLimit = CPBLK_LCL_UNROLL_LIMIT;
+ // TODO-1stClassStructs: for now we can't work with STORE_BLOCK source in register.
+ const unsigned srcLclNum = src->AsLclVar()->GetLclNum();
+ comp->lvaSetVarDoNotEnregister(srcLclNum DEBUGARG(DoNotEnregisterReason::BlockOp));
}
-#endif
if (blkNode->OperIs(GT_STORE_OBJ))
{
@@ -422,7 +373,7 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
{
blkNode->SetOper(GT_STORE_BLK);
}
- else if (isDstAddrLocal && (size <= copyBlockUnrollLimit))
+ else if (dstAddr->OperIsLocalAddr() && (size <= CPBLK_UNROLL_LIMIT))
{
// If the size is small enough to unroll then we need to mark the block as non-interruptible
// to actually allow unrolling. The generated code does not report GC references loaded in the
@@ -438,7 +389,7 @@ void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindUnroll;
}
- else if (blkNode->OperIs(GT_STORE_BLK) && (size <= copyBlockUnrollLimit))
+ else if (blkNode->OperIs(GT_STORE_BLK) && (size <= CPBLK_UNROLL_LIMIT))
{
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindUnroll;
@@ -539,6 +490,7 @@ void Lowering::LowerCast(GenTree* tree)
GenTree* op1 = tree->AsOp()->gtOp1;
var_types dstType = tree->CastToType();
var_types srcType = genActualType(op1->TypeGet());
+ var_types tmpType = TYP_UNDEF;
if (varTypeIsFloating(srcType))
{
@@ -549,6 +501,16 @@ void Lowering::LowerCast(GenTree* tree)
assert(!varTypeIsSmall(srcType));
+ if (tmpType != TYP_UNDEF)
+ {
+ GenTree* tmp = comp->gtNewCastNode(tmpType, op1, tree->IsUnsigned(), tmpType);
+ tmp->gtFlags |= (tree->gtFlags & (GTF_OVERFLOW | GTF_EXCEPT));
+
+ tree->gtFlags &= ~GTF_UNSIGNED;
+ tree->AsOp()->gtOp1 = tmp;
+ BlockRange().InsertAfter(op1, tmp);
+ }
+
// Now determine if we have operands that should be contained.
ContainCheckCast(tree->AsCast());
}
@@ -890,8 +852,8 @@ void Lowering::LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cmpOp)
GenTree* insCns = comp->gtNewIconNode(-1, TYP_INT);
BlockRange().InsertAfter(idxCns, insCns);
- GenTree* tmp = comp->gtNewSimdHWIntrinsicNode(simdType, cmp, idxCns, insCns, NI_AdvSimd_Insert,
- CORINFO_TYPE_INT, simdSize);
+ GenTree* tmp = comp->gtNewSimdAsHWIntrinsicNode(simdType, cmp, idxCns, insCns, NI_AdvSimd_Insert,
+ CORINFO_TYPE_INT, simdSize);
BlockRange().InsertAfter(insCns, tmp);
LowerNode(tmp);
@@ -907,7 +869,7 @@ void Lowering::LowerHWIntrinsicCmpOp(GenTreeHWIntrinsic* node, genTreeOps cmpOp)
BlockRange().InsertAfter(msk, zroCns);
GenTree* val =
- comp->gtNewSimdHWIntrinsicNode(TYP_UBYTE, msk, zroCns, NI_AdvSimd_Extract, CORINFO_TYPE_UBYTE, simdSize);
+ comp->gtNewSimdAsHWIntrinsicNode(TYP_UBYTE, msk, zroCns, NI_AdvSimd_Extract, CORINFO_TYPE_UBYTE, simdSize);
BlockRange().InsertAfter(zroCns, val);
LowerNode(val);
@@ -1185,7 +1147,7 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
BlockRange().InsertAfter(idx, tmp1);
LowerNode(tmp1);
- op1 = comp->gtNewSimdHWIntrinsicNode(simdType, op1, idx, tmp1, NI_AdvSimd_Insert, simdBaseJitType, simdSize);
+ op1 = comp->gtNewSimdAsHWIntrinsicNode(simdType, op1, idx, tmp1, NI_AdvSimd_Insert, simdBaseJitType, simdSize);
BlockRange().InsertAfter(tmp1, op1);
LowerNode(op1);
@@ -1196,7 +1158,7 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
BlockRange().InsertAfter(idx, tmp2);
LowerNode(tmp2);
- op2 = comp->gtNewSimdHWIntrinsicNode(simdType, op2, idx, tmp2, NI_AdvSimd_Insert, simdBaseJitType, simdSize);
+ op2 = comp->gtNewSimdAsHWIntrinsicNode(simdType, op2, idx, tmp2, NI_AdvSimd_Insert, simdBaseJitType, simdSize);
BlockRange().InsertAfter(tmp2, op2);
LowerNode(op2);
}
@@ -1221,35 +1183,32 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
}
assert(!varTypeIsLong(simdBaseType));
- tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, op1, op2, multiply, simdBaseJitType, simdSize);
+ tmp1 = comp->gtNewSimdAsHWIntrinsicNode(simdType, op1, op2, multiply, simdBaseJitType, simdSize);
BlockRange().InsertBefore(node, tmp1);
LowerNode(tmp1);
if (varTypeIsFloating(simdBaseType))
{
- if ((simdSize != 8) || (simdBaseType == TYP_FLOAT))
- {
- // We will be constructing the following parts:
- // ...
- // /--* tmp1 simd16
- // * STORE_LCL_VAR simd16
- // tmp1 = LCL_VAR simd16
- // tmp2 = LCL_VAR simd16
- // ...
+ // We will be constructing the following parts:
+ // ...
+ // /--* tmp1 simd16
+ // * STORE_LCL_VAR simd16
+ // tmp1 = LCL_VAR simd16
+ // tmp2 = LCL_VAR simd16
+ // ...
- // This is roughly the following managed code:
- // ...
- // var tmp2 = tmp1;
- // ...
+ // This is roughly the following managed code:
+ // ...
+ // var tmp2 = tmp1;
+ // ...
- node->Op(1) = tmp1;
- LIR::Use tmp1Use(BlockRange(), &node->Op(1), node);
- ReplaceWithLclVar(tmp1Use);
- tmp1 = node->Op(1);
+ node->Op(1) = tmp1;
+ LIR::Use tmp1Use(BlockRange(), &node->Op(1), node);
+ ReplaceWithLclVar(tmp1Use);
+ tmp1 = node->Op(1);
- tmp2 = comp->gtClone(tmp1);
- BlockRange().InsertAfter(tmp1, tmp2);
- }
+ tmp2 = comp->gtClone(tmp1);
+ BlockRange().InsertAfter(tmp1, tmp2);
if (simdSize == 8)
{
@@ -1267,8 +1226,8 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
// var tmp1 = AdvSimd.AddPairwise(tmp1, tmp2);
// ...
- tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, tmp2, NI_AdvSimd_AddPairwise, simdBaseJitType,
- simdSize);
+ tmp1 = comp->gtNewSimdAsHWIntrinsicNode(simdType, tmp1, tmp2, NI_AdvSimd_AddPairwise, simdBaseJitType,
+ simdSize);
BlockRange().InsertAfter(tmp2, tmp1);
LowerNode(tmp1);
}
@@ -1293,8 +1252,8 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
// var tmp1 = AdvSimd.Arm64.AddPairwise(tmp1, tmp2);
// ...
- tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, tmp2, NI_AdvSimd_Arm64_AddPairwise, simdBaseJitType,
- simdSize);
+ tmp1 = comp->gtNewSimdAsHWIntrinsicNode(simdType, tmp1, tmp2, NI_AdvSimd_Arm64_AddPairwise, simdBaseJitType,
+ simdSize);
BlockRange().InsertAfter(tmp2, tmp1);
LowerNode(tmp1);
@@ -1332,8 +1291,8 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
tmp2 = comp->gtClone(tmp1);
BlockRange().InsertAfter(tmp1, tmp2);
- tmp1 = comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, tmp2, NI_AdvSimd_Arm64_AddPairwise,
- simdBaseJitType, simdSize);
+ tmp1 = comp->gtNewSimdAsHWIntrinsicNode(simdType, tmp1, tmp2, NI_AdvSimd_Arm64_AddPairwise,
+ simdBaseJitType, simdSize);
BlockRange().InsertAfter(tmp2, tmp1);
LowerNode(tmp1);
}
@@ -1345,66 +1304,20 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
{
assert(varTypeIsIntegral(simdBaseType));
- if ((simdSize == 8) && ((simdBaseType == TYP_INT) || (simdBaseType == TYP_UINT)))
- {
- // We will be constructing the following parts:
- // ...
- // /--* tmp1 simd16
- // * STORE_LCL_VAR simd16
- // tmp1 = LCL_VAR simd16
- // tmp2 = LCL_VAR simd16
- // ...
-
- // This is roughly the following managed code:
- // ...
- // var tmp2 = tmp1;
- // ...
-
- node->Op(1) = tmp1;
- LIR::Use tmp1Use(BlockRange(), &node->Op(1), node);
- ReplaceWithLclVar(tmp1Use);
- tmp1 = node->Op(1);
-
- tmp2 = comp->gtClone(tmp1);
- BlockRange().InsertAfter(tmp1, tmp2);
-
- // We will be constructing the following parts:
- // ...
- // /--* tmp1 simd16
- // /--* tmp2 simd16
- // tmp2 = * HWINTRINSIC simd8 T AddPairwise
- // ...
-
- // This is roughly the following managed code:
- // ...
- // var tmp2 = AdvSimd.AddPairwise(tmp1, tmp2);
- // ...
-
- tmp1 =
- comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, tmp2, NI_AdvSimd_AddPairwise, simdBaseJitType, simdSize);
- BlockRange().InsertAfter(tmp2, tmp1);
- LowerNode(tmp1);
-
- tmp2 = tmp1;
- }
- else
- {
- // We will be constructing the following parts:
- // ...
- // /--* tmp1 simd16
- // tmp2 = * HWINTRINSIC simd16 T AddAcross
- // ...
+ // We will be constructing the following parts:
+ // ...
+ // /--* tmp1 simd16
+ // tmp2 = * HWINTRINSIC simd16 T AddAcross
+ // ...
- // This is roughly the following managed code:
- // ...
- // var tmp2 = AdvSimd.Arm64.AddAcross(tmp1);
- // ...
+ // This is roughly the following managed code:
+ // ...
+ // var tmp2 = AdvSimd.Arm64.AddAcross(tmp1);
+ // ...
- tmp2 =
- comp->gtNewSimdHWIntrinsicNode(simdType, tmp1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, simdSize);
- BlockRange().InsertAfter(tmp1, tmp2);
- LowerNode(tmp2);
- }
+ tmp2 = comp->gtNewSimdAsHWIntrinsicNode(simdType, tmp1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, simdSize);
+ BlockRange().InsertAfter(tmp1, tmp2);
+ LowerNode(tmp2);
}
// We will be constructing the following parts:
@@ -1940,21 +1853,6 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
MakeSrcContained(node, intrin.op4);
break;
- case NI_AdvSimd_CompareEqual:
- case NI_AdvSimd_Arm64_CompareEqual:
- case NI_AdvSimd_Arm64_CompareEqualScalar:
- {
- if (intrin.op1->IsVectorZero())
- {
- MakeSrcContained(node, intrin.op1);
- }
- else if (intrin.op2->IsVectorZero())
- {
- MakeSrcContained(node, intrin.op2);
- }
- break;
- }
-
case NI_Vector64_CreateScalarUnsafe:
case NI_Vector128_CreateScalarUnsafe:
case NI_AdvSimd_DuplicateToVector64:
diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp
index 37459907558a0..c8076c4525f2d 100644
--- a/src/coreclr/jit/lowerxarch.cpp
+++ b/src/coreclr/jit/lowerxarch.cpp
@@ -159,33 +159,6 @@ GenTree* Lowering::LowerMul(GenTreeOp* mul)
return mul->gtNext;
}
-//------------------------------------------------------------------------
-// LowerBinaryArithmetic: lowers the given binary arithmetic node.
-//
-// Arguments:
-// node - the arithmetic node to lower
-//
-// Returns:
-// The next node to lower.
-//
-GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp)
-{
-#ifdef FEATURE_HW_INTRINSICS
- if (comp->opts.OptimizationEnabled() && binOp->OperIs(GT_AND) && varTypeIsIntegral(binOp))
- {
- GenTree* blsrNode = TryLowerAndOpToResetLowestSetBit(binOp);
- if (blsrNode != nullptr)
- {
- return blsrNode->gtNext;
- }
- }
-#endif
-
- ContainCheckBinary(binOp);
-
- return binOp->gtNext;
-}
-
//------------------------------------------------------------------------
// LowerBlockStore: Lower a block store node
//
@@ -194,7 +167,7 @@ GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp)
//
void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
{
- TryCreateAddrMode(blkNode->Addr(), false, blkNode);
+ TryCreateAddrMode(blkNode->Addr(), false);
GenTree* dstAddr = blkNode->Addr();
GenTree* src = blkNode->Data();
@@ -408,7 +381,7 @@ void Lowering::ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenT
return;
}
- if (!addr->OperIsAddrMode() && !TryCreateAddrMode(addr, true, blkNode))
+ if (!addr->OperIsAddrMode() && !TryCreateAddrMode(addr, true))
{
return;
}
@@ -859,8 +832,8 @@ void Lowering::LowerHWIntrinsicCC(GenTreeHWIntrinsic* node, NamedIntrinsic newIn
bool op1SupportsRegOptional = false;
bool op2SupportsRegOptional = false;
- if (!TryGetContainableHWIntrinsicOp(node, &node->Op(2), &op2SupportsRegOptional) &&
- TryGetContainableHWIntrinsicOp(node, &node->Op(1), &op1SupportsRegOptional))
+ if (!IsContainableHWIntrinsicOp(node, node->Op(2), &op2SupportsRegOptional) &&
+ IsContainableHWIntrinsicOp(node, node->Op(1), &op1SupportsRegOptional))
{
// Swap operands if op2 cannot be contained but op1 can.
swapOperands = true;
@@ -3074,6 +3047,8 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
if (simdSize == 32)
{
+ assert(comp->compIsaSupportedDebugOnly(InstructionSet_AVX2));
+
switch (simdBaseType)
{
case TYP_SHORT:
@@ -3081,8 +3056,6 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
case TYP_INT:
case TYP_UINT:
{
- assert(comp->compIsaSupportedDebugOnly(InstructionSet_AVX2));
-
multiply = NI_AVX2_MultiplyLow;
horizontalAdd = NI_AVX2_HorizontalAdd;
add = NI_AVX2_Add;
@@ -3091,8 +3064,6 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
case TYP_FLOAT:
{
- assert(comp->compIsaSupportedDebugOnly(InstructionSet_AVX));
-
// We will be constructing the following parts:
// idx = CNS_INT int 0xF1
// /--* op1 simd16
@@ -3156,8 +3127,6 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
case TYP_DOUBLE:
{
- assert(comp->compIsaSupportedDebugOnly(InstructionSet_AVX));
-
multiply = NI_AVX_Multiply;
horizontalAdd = NI_AVX_HorizontalAdd;
add = NI_AVX_Add;
@@ -3456,7 +3425,7 @@ void Lowering::LowerHWIntrinsicDot(GenTreeHWIntrinsic* node)
// e6, e7, e4, e5 | e2, e3, e0, e1
// e7, e6, e5, e4 | e3, e2, e1, e0
- shuffleConst = 0x4E;
+ shuffleConst = 0x4D;
break;
}
@@ -3724,84 +3693,6 @@ void Lowering::LowerHWIntrinsicToScalar(GenTreeHWIntrinsic* node)
LowerNode(cast);
}
}
-
-//----------------------------------------------------------------------------------------------
-// Lowering::TryLowerAndOpToResetLowestSetBit: Lowers a tree AND(X, ADD(X, -1) to HWIntrinsic::ResetLowestSetBit
-//
-// Arguments:
-// andNode - GT_AND node of integral type
-//
-// Return Value:
-// Returns the replacement node if one is created else nullptr indicating no replacement
-//
-GenTree* Lowering::TryLowerAndOpToResetLowestSetBit(GenTreeOp* andNode)
-{
- assert(andNode->OperIs(GT_AND) && varTypeIsIntegral(andNode));
-
- GenTree* op1 = andNode->gtGetOp1();
- if (!op1->OperIs(GT_LCL_VAR) || comp->lvaGetDesc(op1->AsLclVar())->IsAddressExposed())
- {
- return nullptr;
- }
-
- GenTree* op2 = andNode->gtGetOp2();
- if (!op2->OperIs(GT_ADD))
- {
- return nullptr;
- }
-
- GenTree* addOp2 = op2->gtGetOp2();
- if (!addOp2->IsIntegralConst(-1))
- {
- return nullptr;
- }
-
- GenTree* addOp1 = op2->gtGetOp1();
- if (!addOp1->OperIs(GT_LCL_VAR) || (addOp1->AsLclVar()->GetLclNum() != op1->AsLclVar()->GetLclNum()))
- {
- return nullptr;
- }
-
- NamedIntrinsic intrinsic;
- if (op1->TypeIs(TYP_LONG) && comp->compOpportunisticallyDependsOn(InstructionSet_BMI1_X64))
- {
- intrinsic = NamedIntrinsic::NI_BMI1_X64_ResetLowestSetBit;
- }
- else if (comp->compOpportunisticallyDependsOn(InstructionSet_BMI1))
- {
- intrinsic = NamedIntrinsic::NI_BMI1_ResetLowestSetBit;
- }
- else
- {
- return nullptr;
- }
-
- LIR::Use use;
- if (!BlockRange().TryGetUse(andNode, &use))
- {
- return nullptr;
- }
-
- GenTreeHWIntrinsic* blsrNode = comp->gtNewScalarHWIntrinsicNode(andNode->TypeGet(), op1, intrinsic);
-
- JITDUMP("Lower: optimize AND(X, ADD(X, -1))\n");
- DISPNODE(andNode);
- JITDUMP("to:\n");
- DISPNODE(blsrNode);
-
- use.ReplaceWith(blsrNode);
-
- BlockRange().InsertBefore(andNode, blsrNode);
- BlockRange().Remove(andNode);
- BlockRange().Remove(op2);
- BlockRange().Remove(addOp1);
- BlockRange().Remove(addOp2);
-
- ContainCheckHWIntrinsic(blsrNode);
-
- return blsrNode;
-}
-
#endif // FEATURE_HW_INTRINSICS
//----------------------------------------------------------------------------------------------
@@ -5267,34 +5158,21 @@ void Lowering::ContainCheckSIMD(GenTreeSIMD* simdNode)
#ifdef FEATURE_HW_INTRINSICS
//----------------------------------------------------------------------------------------------
-// TryGetContainableHWIntrinsicOp: Tries to get a containable node for a given HWIntrinsic
+// IsContainableHWIntrinsicOp: Return true if 'node' is a containable HWIntrinsic op.
//
// Arguments:
-// [In] containingNode - The hardware intrinsic node which contains 'node'
-// [In/Out] pNode - The node to check and potentially replace with the containable node
-// [Out] supportsRegOptional - On return, this will be true if 'containingNode' supports regOptional operands
+// containingNode - The hardware intrinsic node which contains 'node'
+// node - The node to check
+// [Out] supportsRegOptional - On return, this will be true if 'containingNode' supports regOptional operands;
// otherwise, false.
//
// Return Value:
-// true if 'node' is a containable by containingNode; otherwise, false.
-//
-// When true is returned 'node' (and by extension the relevant op of 'containingNode') may be modified
-// to handle special scenarios such as CreateScalarUnsafe which exist to bridge the type system with
-// the actual registers.
+// true if 'node' is a containable hardware intrinsic node; otherwise, false.
//
-// When false is returned 'node' is not modified.
-//
-bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode,
- GenTree** pNode,
- bool* supportsRegOptional)
+bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode, GenTree* node, bool* supportsRegOptional)
{
- assert(containingNode != nullptr);
- assert((pNode != nullptr) && (*pNode != nullptr));
- assert(supportsRegOptional != nullptr);
-
NamedIntrinsic containingIntrinsicId = containingNode->GetHWIntrinsicId();
HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(containingIntrinsicId);
- GenTree*& node = *pNode;
// We shouldn't have called in here if containingNode doesn't support containment
assert(HWIntrinsicInfo::SupportsContainment(containingIntrinsicId));
@@ -5335,10 +5213,8 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
switch (category)
{
case HW_Category_MemoryLoad:
- {
- supportsGeneralLoads = !node->OperIsHWIntrinsic();
+ supportsGeneralLoads = (!node->OperIsHWIntrinsic());
break;
- }
case HW_Category_SimpleSIMD:
{
@@ -5351,90 +5227,26 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
case NI_AVX2_ConvertToVector256Int32:
case NI_AVX2_ConvertToVector256Int64:
{
- assert(!supportsSIMDScalarLoads);
-
- if (!containingNode->OperIsMemoryLoad())
- {
- // The containable form is the one that takes a SIMD value, that may be in memory.
-
- if (!comp->canUseVexEncoding())
- {
- supportsAlignedSIMDLoads = true;
- supportsUnalignedSIMDLoads = !supportsAlignedSIMDLoads;
- }
- else
- {
- supportsAlignedSIMDLoads = !comp->opts.MinOpts();
- supportsUnalignedSIMDLoads = true;
- }
-
- // General loads are a bit special where we need at least `sizeof(simdType) / (sizeof(baseType)
- // * 2)` elements
- // For example:
- // * ConvertToVector128Int16 - sizeof(simdType) = 16; sizeof(baseType) = 1; expectedSize = 8
- // * ConvertToVector128Int32 - sizeof(simdType) = 16; sizeof(baseType) = 1 | 2;
- // expectedSize = 8 | 4
- // * ConvertToVector128Int64 - sizeof(simdType) = 16; sizeof(baseType) = 1 | 2 | 4;
- // expectedSize = 8 | 4 | 2
- // * ConvertToVector256Int16 - sizeof(simdType) = 32; sizeof(baseType) = 1; expectedSize = 16
- // * ConvertToVector256Int32 - sizeof(simdType) = 32; sizeof(baseType) = 1 | 2;
- // expectedSize = 16 | 8
- // * ConvertToVector256Int64 - sizeof(simdType) = 32; sizeof(baseType) = 1 | 2 | 4;
- // expectedSize = 16 | 8 | 4
-
- const unsigned sizeof_simdType = genTypeSize(containingNode->TypeGet());
- const unsigned sizeof_baseType = genTypeSize(containingNode->GetSimdBaseType());
-
- assert((sizeof_simdType == 16) || (sizeof_simdType == 32));
- assert((sizeof_baseType == 1) || (sizeof_baseType == 2) || (sizeof_baseType == 4));
-
- const unsigned expectedSize = sizeof_simdType / (sizeof_baseType * 2);
- const unsigned operandSize = genTypeSize(node->TypeGet());
-
- assert((sizeof_simdType != 16) || (expectedSize == 8) || (expectedSize == 4) ||
- (expectedSize == 2));
- assert((sizeof_simdType != 32) || (expectedSize == 16) || (expectedSize == 8) ||
- (expectedSize == 4));
-
- supportsGeneralLoads = (operandSize >= expectedSize);
- }
- else
- {
- // The memory form of this already takes a pointer and should be treated like a MemoryLoad
- supportsGeneralLoads = !node->OperIsHWIntrinsic();
- }
- break;
- }
-
- case NI_SSE2_ConvertToVector128Double:
- case NI_SSE3_MoveAndDuplicate:
- case NI_AVX_ConvertToVector256Double:
- {
- assert(!supportsSIMDScalarLoads);
-
- // Most instructions under the non-VEX encoding require aligned operands.
- // Those used for Sse2.ConvertToVector128Double (CVTDQ2PD and CVTPS2PD)
- // and Sse3.MoveAndDuplicate (MOVDDUP) are exceptions and don't fail for
- // unaligned inputs as they read mem64 (half the vector width) instead
-
- supportsAlignedSIMDLoads = !comp->opts.MinOpts();
- supportsUnalignedSIMDLoads = true;
-
- const unsigned expectedSize = genTypeSize(containingNode->TypeGet()) / 2;
- const unsigned operandSize = genTypeSize(node->TypeGet());
-
- supportsGeneralLoads = supportsUnalignedSIMDLoads && (operandSize >= expectedSize);
+ supportsGeneralLoads = (!node->OperIsHWIntrinsic());
break;
}
default:
{
- assert(!supportsSIMDScalarLoads);
+ if ((genTypeSize(node->TypeGet()) != 16) && (genTypeSize(node->TypeGet()) != 32))
+ {
+ // These intrinsics only expect 16 or 32-byte nodes for containment
+ break;
+ }
if (!comp->canUseVexEncoding())
{
- assert(!supportsUnalignedSIMDLoads);
- supportsAlignedSIMDLoads = true;
+ // Most instructions under the non-VEX encoding require aligned operands.
+ // Those used for Sse2.ConvertToVector128Double (CVTDQ2PD and CVTPS2PD)
+ // are exceptions and don't fail for unaligned inputs.
+
+ supportsAlignedSIMDLoads = (containingIntrinsicId != NI_SSE2_ConvertToVector128Double);
+ supportsUnalignedSIMDLoads = !supportsAlignedSIMDLoads;
}
else
{
@@ -5442,10 +5254,7 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
supportsUnalignedSIMDLoads = true;
}
- const unsigned expectedSize = genTypeSize(containingNode->TypeGet());
- const unsigned operandSize = genTypeSize(node->TypeGet());
-
- supportsGeneralLoads = supportsUnalignedSIMDLoads && (operandSize >= expectedSize);
+ supportsGeneralLoads = supportsUnalignedSIMDLoads;
break;
}
}
@@ -5474,9 +5283,11 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
case NI_AVX_Blend:
case NI_AVX_Compare:
case NI_AVX_DotProduct:
+ case NI_AVX_InsertVector128:
case NI_AVX_Permute:
case NI_AVX_Permute2x128:
case NI_AVX2_Blend:
+ case NI_AVX2_InsertVector128:
case NI_AVX2_MultipleSumAbsoluteDifferences:
case NI_AVX2_Permute2x128:
case NI_AVX2_Permute4x64:
@@ -5486,29 +5297,17 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
case NI_AVX2_ShuffleHigh:
case NI_AVX2_ShuffleLow:
{
+ if ((genTypeSize(node->TypeGet()) != 16) && (genTypeSize(node->TypeGet()) != 32))
+ {
+ // These intrinsics only expect 16 or 32-byte nodes for containment
+ break;
+ }
assert(!supportsSIMDScalarLoads);
- const unsigned expectedSize = genTypeSize(containingNode->GetSimdBaseType());
- const unsigned operandSize = genTypeSize(node->TypeGet());
-
supportsAlignedSIMDLoads = !comp->canUseVexEncoding() || !comp->opts.MinOpts();
supportsUnalignedSIMDLoads = comp->canUseVexEncoding();
- supportsGeneralLoads = supportsUnalignedSIMDLoads && (operandSize >= expectedSize);
- break;
- }
+ supportsGeneralLoads = supportsUnalignedSIMDLoads;
- case NI_AVX_InsertVector128:
- case NI_AVX2_InsertVector128:
- {
- // InsertVector128 is special in that that it returns a TYP_SIMD32 but takes a TYP_SIMD16
- assert(!supportsSIMDScalarLoads);
-
- const unsigned expectedSize = 16;
- const unsigned operandSize = genTypeSize(node->TypeGet());
-
- supportsAlignedSIMDLoads = !comp->canUseVexEncoding() || !comp->opts.MinOpts();
- supportsUnalignedSIMDLoads = comp->canUseVexEncoding();
- supportsGeneralLoads = supportsUnalignedSIMDLoads && (operandSize >= expectedSize);
break;
}
@@ -5516,13 +5315,16 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
case NI_SSE41_Insert:
case NI_SSE41_X64_Insert:
{
- assert(supportsAlignedSIMDLoads == false);
- assert(supportsUnalignedSIMDLoads == false);
-
if (containingNode->GetSimdBaseType() == TYP_FLOAT)
{
assert(containingIntrinsicId == NI_SSE41_Insert);
+ if (genTypeSize(node->TypeGet()) != 16)
+ {
+ // These intrinsics only expect 16-byte nodes for containment
+ break;
+ }
+
// Sse41.Insert(V128, V128, byte) is a bit special
// in that it has different behavior depending on whether the
// second operand is coming from a register or memory. When coming
@@ -5531,6 +5333,8 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
// from memory, it only works with the lowest element and is effectively
// a `SIMDScalar`.
+ assert(supportsAlignedSIMDLoads == false);
+ assert(supportsUnalignedSIMDLoads == false);
assert(supportsGeneralLoads == false);
assert(supportsSIMDScalarLoads == false);
@@ -5538,6 +5342,8 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
GenTree* op2 = containingNode->Op(2);
GenTree* op3 = containingNode->Op(3);
+ assert(node == op2);
+
// The upper two bits of the immediate value are ignored if
// op2 comes from memory. In order to support using the upper
// bits, we need to disable containment support if op3 is not
@@ -5557,6 +5363,9 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
// We should only get here for integral nodes.
assert(varTypeIsIntegral(node->TypeGet()));
+
+ assert(supportsAlignedSIMDLoads == false);
+ assert(supportsUnalignedSIMDLoads == false);
assert(supportsSIMDScalarLoads == false);
const unsigned expectedSize = genTypeSize(containingNode->GetSimdBaseType());
@@ -5568,6 +5377,12 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
case NI_AVX_CompareScalar:
{
+ if ((genTypeSize(node->TypeGet()) != 16) && (genTypeSize(node->TypeGet()) != 32))
+ {
+ // These intrinsics only expect 16 or 32-byte nodes for containment
+ break;
+ }
+
assert(supportsAlignedSIMDLoads == false);
assert(supportsUnalignedSIMDLoads == false);
@@ -5598,38 +5413,21 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
case NI_Vector128_CreateScalarUnsafe:
case NI_Vector256_CreateScalarUnsafe:
{
- if (!varTypeIsIntegral(node->TypeGet()))
- {
- // The floating-point overload doesn't require any special semantics
- supportsSIMDScalarLoads = true;
- supportsGeneralLoads = supportsSIMDScalarLoads;
- break;
- }
-
- // The integral overloads only take GPR/mem
assert(supportsSIMDScalarLoads == false);
const unsigned expectedSize = genTypeSize(genActualType(containingNode->GetSimdBaseType()));
const unsigned operandSize = genTypeSize(node->TypeGet());
- supportsGeneralLoads = (operandSize >= expectedSize);
+ supportsGeneralLoads = (operandSize == expectedSize);
break;
}
case NI_AVX2_BroadcastScalarToVector128:
case NI_AVX2_BroadcastScalarToVector256:
{
- if (!containingNode->OperIsMemoryLoad())
- {
- // The containable form is the one that takes a SIMD value, that may be in memory.
- supportsSIMDScalarLoads = true;
- supportsGeneralLoads = supportsSIMDScalarLoads;
- }
- else
- {
- // The memory form of this already takes a pointer and should be treated like a MemoryLoad
- supportsGeneralLoads = !node->OperIsHWIntrinsic();
- }
+ // The memory form of this already takes a pointer, and cannot be further contained.
+ // The containable form is the one that takes a SIMD value, that may be in memory.
+ supportsGeneralLoads = (node->TypeGet() == TYP_SIMD16);
break;
}
@@ -5651,18 +5449,23 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
break;
}
- // The integral overloads only take GPR/mem
assert(supportsSIMDScalarLoads == false);
const unsigned expectedSize = genTypeSize(genActualType(containingNode->GetSimdBaseType()));
const unsigned operandSize = genTypeSize(node->TypeGet());
- supportsGeneralLoads = (operandSize >= expectedSize);
+ supportsGeneralLoads = (operandSize == expectedSize);
break;
}
default:
{
+ if ((genTypeSize(node->TypeGet()) != 16) && (genTypeSize(node->TypeGet()) != 32))
+ {
+ // These intrinsics only expect 16 or 32-byte nodes for containment
+ break;
+ }
+
supportsSIMDScalarLoads = true;
supportsGeneralLoads = supportsSIMDScalarLoads;
break;
@@ -5705,55 +5508,20 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
}
}
+ noway_assert(supportsRegOptional != nullptr);
*supportsRegOptional = supportsGeneralLoads;
if (!node->OperIsHWIntrinsic())
{
- return supportsGeneralLoads && (IsContainableMemoryOp(node) || node->IsCnsNonZeroFltOrDbl());
+ return supportsGeneralLoads && IsContainableMemoryOp(node);
}
// TODO-XArch: Update this to be table driven, if possible.
- GenTreeHWIntrinsic* hwintrinsic = node->AsHWIntrinsic();
- NamedIntrinsic intrinsicId = hwintrinsic->GetHWIntrinsicId();
+ NamedIntrinsic intrinsicId = node->AsHWIntrinsic()->GetHWIntrinsicId();
switch (intrinsicId)
{
- case NI_Vector128_CreateScalarUnsafe:
- case NI_Vector256_CreateScalarUnsafe:
- {
- if (!supportsSIMDScalarLoads)
- {
- return false;
- }
-
- GenTree* op1 = hwintrinsic->Op(1);
- bool op1SupportsRegOptional = false;
-
- if (!TryGetContainableHWIntrinsicOp(containingNode, &op1, &op1SupportsRegOptional))
- {
- return false;
- }
-
- LIR::Use use;
- if (!BlockRange().TryGetUse(node, &use) || (use.User() != containingNode))
- {
- return false;
- }
-
- // We have CreateScalarUnsafe where the underlying scalar is directly containable
- // by containingNode. As such, we'll just remove CreateScalarUnsafe and consume
- // the value directly.
-
- use.ReplaceWith(op1);
- BlockRange().Remove(node);
-
- node = op1;
- node->ClearContained();
-
- return true;
- }
-
case NI_SSE_LoadAlignedVector128:
case NI_SSE2_LoadAlignedVector128:
case NI_AVX_LoadAlignedVector256:
@@ -5799,7 +5567,7 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
void Lowering::ContainCheckHWIntrinsicAddr(GenTreeHWIntrinsic* node, GenTree* addr)
{
assert((addr->TypeGet() == TYP_I_IMPL) || (addr->TypeGet() == TYP_BYREF));
- TryCreateAddrMode(addr, true, node);
+ TryCreateAddrMode(addr, true);
if ((addr->OperIs(GT_CLS_VAR_ADDR, GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR, GT_LEA) ||
(addr->IsCnsIntOrI() && addr->AsIntConCommon()->FitsInAddrBase(comp))) &&
IsSafeToContainMem(node, addr))
@@ -5941,22 +5709,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
bool supportsRegOptional = false;
- if (node->OperIsMemoryLoad())
- {
- // We have a few cases that can be potential memory loads
-
- assert((intrinsicId == NI_SSE41_ConvertToVector128Int16) ||
- (intrinsicId == NI_SSE41_ConvertToVector128Int32) ||
- (intrinsicId == NI_SSE41_ConvertToVector128Int64) ||
- (intrinsicId == NI_AVX2_BroadcastScalarToVector128) ||
- (intrinsicId == NI_AVX2_BroadcastScalarToVector256) ||
- (intrinsicId == NI_AVX2_ConvertToVector256Int16) ||
- (intrinsicId == NI_AVX2_ConvertToVector256Int32) ||
- (intrinsicId == NI_AVX2_ConvertToVector256Int64));
-
- ContainCheckHWIntrinsicAddr(node, op1);
- }
- else if (TryGetContainableHWIntrinsicOp(node, &op1, &supportsRegOptional))
+ if (IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional))
{
MakeSrcContained(node, op1);
}
@@ -6012,13 +5765,13 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
{
bool supportsRegOptional = false;
- if (TryGetContainableHWIntrinsicOp(node, &op2, &supportsRegOptional))
+ if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
{
MakeSrcContained(node, op2);
}
else if ((isCommutative || (intrinsicId == NI_BMI2_MultiplyNoFlags) ||
(intrinsicId == NI_BMI2_X64_MultiplyNoFlags)) &&
- TryGetContainableHWIntrinsicOp(node, &op1, &supportsRegOptional))
+ IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional))
{
MakeSrcContained(node, op1);
@@ -6064,7 +5817,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
if (!HWIntrinsicInfo::isImmOp(intrinsicId, op2))
{
- if (TryGetContainableHWIntrinsicOp(node, &op2, &supportsRegOptional))
+ if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
{
MakeSrcContained(node, op2);
}
@@ -6086,7 +5839,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
{
// These intrinsics have op2 as an imm and op1 as a reg/mem
- if (TryGetContainableHWIntrinsicOp(node, &op1, &supportsRegOptional))
+ if (IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional))
{
MakeSrcContained(node, op1);
}
@@ -6113,7 +5866,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
if (HWIntrinsicInfo::isImmOp(intrinsicId, op2))
{
- if (TryGetContainableHWIntrinsicOp(node, &op1, &supportsRegOptional))
+ if (IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional))
{
MakeSrcContained(node, op1);
}
@@ -6122,7 +5875,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
op1->SetRegOptional();
}
}
- else if (TryGetContainableHWIntrinsicOp(node, &op2, &supportsRegOptional))
+ else if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
{
MakeSrcContained(node, op2);
}
@@ -6135,7 +5888,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
case NI_AES_KeygenAssist:
{
- if (TryGetContainableHWIntrinsicOp(node, &op1, &supportsRegOptional))
+ if (IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional))
{
MakeSrcContained(node, op1);
}
@@ -6263,19 +6016,18 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
// Set op regOptional only if none of them is containable.
// Prefer to make op3 contained,
- if (resultOpNum != 3 && TryGetContainableHWIntrinsicOp(node, &op3, &supportsOp3RegOptional))
+ if (resultOpNum != 3 && IsContainableHWIntrinsicOp(node, op3, &supportsOp3RegOptional))
{
// result = (op1 * op2) + [op3]
MakeSrcContained(node, op3);
}
- else if (resultOpNum != 2 &&
- TryGetContainableHWIntrinsicOp(node, &op2, &supportsOp2RegOptional))
+ else if (resultOpNum != 2 && IsContainableHWIntrinsicOp(node, op2, &supportsOp2RegOptional))
{
// result = (op1 * [op2]) + op3
MakeSrcContained(node, op2);
}
else if (resultOpNum != 1 && !HWIntrinsicInfo::CopiesUpperBits(intrinsicId) &&
- TryGetContainableHWIntrinsicOp(node, &op1, &supportsOp1RegOptional))
+ IsContainableHWIntrinsicOp(node, op1, &supportsOp1RegOptional))
{
// result = ([op1] * op2) + op3
MakeSrcContained(node, op1);
@@ -6305,7 +6057,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
case NI_AVX_BlendVariable:
case NI_AVX2_BlendVariable:
{
- if (TryGetContainableHWIntrinsicOp(node, &op2, &supportsRegOptional))
+ if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
{
MakeSrcContained(node, op2);
}
@@ -6318,7 +6070,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
case NI_AVXVNNI_MultiplyWideningAndAdd:
case NI_AVXVNNI_MultiplyWideningAndAddSaturate:
{
- if (TryGetContainableHWIntrinsicOp(node, &op3, &supportsRegOptional))
+ if (IsContainableHWIntrinsicOp(node, op3, &supportsRegOptional))
{
MakeSrcContained(node, op3);
}
@@ -6331,11 +6083,11 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
case NI_BMI2_MultiplyNoFlags:
case NI_BMI2_X64_MultiplyNoFlags:
{
- if (TryGetContainableHWIntrinsicOp(node, &op2, &supportsRegOptional))
+ if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
{
MakeSrcContained(node, op2);
}
- else if (TryGetContainableHWIntrinsicOp(node, &op1, &supportsRegOptional))
+ else if (IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional))
{
MakeSrcContained(node, op1);
// MultiplyNoFlags is a Commutative operation, so swap the first two operands here
@@ -6389,7 +6141,7 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
case NI_AVX2_Permute2x128:
case NI_PCLMULQDQ_CarrylessMultiply:
{
- if (TryGetContainableHWIntrinsicOp(node, &op2, &supportsRegOptional))
+ if (IsContainableHWIntrinsicOp(node, op2, &supportsRegOptional))
{
MakeSrcContained(node, op2);
}
diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp
index 88f137ab65764..9308836ff78fc 100644
--- a/src/coreclr/jit/lsra.cpp
+++ b/src/coreclr/jit/lsra.cpp
@@ -1299,10 +1299,6 @@ void LinearScan::doLinearScan()
DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_POST));
-#ifdef DEBUG
- compiler->fgDebugCheckLinks();
-#endif
-
compiler->compLSRADone = true;
}
@@ -2812,7 +2808,7 @@ regNumber LinearScan::allocateReg(Interval* currentInterval,
bool wasAssigned = regSelector->foundUnassignedReg() && (assignedInterval != nullptr) &&
(assignedInterval->physReg == foundReg);
unassignPhysReg(availablePhysRegRecord ARM_ARG(currentInterval->registerType));
- if (regSelector->isMatchingConstant() && compiler->opts.OptimizationEnabled())
+ if (regSelector->isMatchingConstant())
{
assert(assignedInterval->isConstant);
refPosition->treeNode->SetReuseRegVal();
@@ -6419,7 +6415,7 @@ void LinearScan::insertUpperVectorRestore(GenTree* tree,
else
{
JITDUMP("at end of " FMT_BB ":\n", block->bbNum);
- if (block->KindIs(BBJ_COND, BBJ_SWITCH))
+ if (block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_SWITCH)
{
noway_assert(!blockRange.IsEmpty());
@@ -6431,7 +6427,7 @@ void LinearScan::insertUpperVectorRestore(GenTree* tree,
}
else
{
- assert(block->KindIs(BBJ_NONE, BBJ_ALWAYS));
+ assert(block->bbJumpKind == BBJ_NONE || block->bbJumpKind == BBJ_ALWAYS);
blockRange.InsertAtEnd(LIR::SeqTree(compiler, simdNode));
}
}
@@ -7295,7 +7291,7 @@ void LinearScan::insertMove(
{
// Put the copy at the bottom
GenTree* lastNode = blockRange.LastNode();
- if (block->KindIs(BBJ_COND, BBJ_SWITCH))
+ if (block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_SWITCH)
{
noway_assert(!blockRange.IsEmpty());
@@ -7363,7 +7359,7 @@ void LinearScan::insertSwap(
{
// Put the copy at the bottom
// If there's a branch, make an embedded statement that executes just prior to the branch
- if (block->KindIs(BBJ_COND, BBJ_SWITCH))
+ if (block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_SWITCH)
{
noway_assert(!blockRange.IsEmpty());
@@ -7375,7 +7371,7 @@ void LinearScan::insertSwap(
}
else
{
- assert(block->KindIs(BBJ_NONE, BBJ_ALWAYS));
+ assert(block->bbJumpKind == BBJ_NONE || block->bbJumpKind == BBJ_ALWAYS);
blockRange.InsertAtEnd(std::move(swapRange));
}
}
diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h
index 052c3f93999a3..1b549424f0fc4 100644
--- a/src/coreclr/jit/lsra.h
+++ b/src/coreclr/jit/lsra.h
@@ -1772,7 +1772,7 @@ class LinearScan : public LinearScanInterface
// The following keep track of information about internal (temporary register) intervals
// during the building of a single node.
- static const int MaxInternalCount = 5;
+ static const int MaxInternalCount = 4;
RefPosition* internalDefs[MaxInternalCount];
int internalCount = 0;
bool setInternalRegsDelayFree;
diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp
index f18099f4f573e..73b971ec5932f 100644
--- a/src/coreclr/jit/lsraarm64.cpp
+++ b/src/coreclr/jit/lsraarm64.cpp
@@ -522,6 +522,7 @@ int LinearScan::BuildNode(GenTree* tree)
break;
case GT_BLK:
+ case GT_DYN_BLK:
// These should all be eliminated prior to Lowering.
assert(!"Non-store block node in Lowering");
srcCount = 0;
@@ -1090,52 +1091,55 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
}
}
}
- else if (intrin.op2 != nullptr)
+ else
{
- // RMW intrinsic operands doesn't have to be delayFree when they can be assigned the same register as op1Reg
- // (i.e. a register that corresponds to read-modify-write operand) and one of them is the last use.
+ if (intrin.op2 != nullptr)
+ {
+ // RMW intrinsic operands doesn't have to be delayFree when they can be assigned the same register as op1Reg
+ // (i.e. a register that corresponds to read-modify-write operand) and one of them is the last use.
- assert(intrin.op1 != nullptr);
+ assert(intrin.op1 != nullptr);
- bool forceOp2DelayFree = false;
- if ((intrin.id == NI_Vector64_GetElement) || (intrin.id == NI_Vector128_GetElement))
- {
- if (!intrin.op2->IsCnsIntOrI() && (!intrin.op1->isContained() || intrin.op1->OperIsLocal()))
+ bool forceOp2DelayFree = false;
+ if ((intrin.id == NI_Vector64_GetElement) || (intrin.id == NI_Vector128_GetElement))
{
- // If the index is not a constant and the object is not contained or is a local
- // we will need a general purpose register to calculate the address
- // internal register must not clobber input index
- // TODO-Cleanup: An internal register will never clobber a source; this code actually
- // ensures that the index (op2) doesn't interfere with the target.
- buildInternalIntRegisterDefForNode(intrinsicTree);
- forceOp2DelayFree = true;
+ if (!intrin.op2->IsCnsIntOrI() && (!intrin.op1->isContained() || intrin.op1->OperIsLocal()))
+ {
+ // If the index is not a constant and the object is not contained or is a local
+ // we will need a general purpose register to calculate the address
+ // internal register must not clobber input index
+ // TODO-Cleanup: An internal register will never clobber a source; this code actually
+ // ensures that the index (op2) doesn't interfere with the target.
+ buildInternalIntRegisterDefForNode(intrinsicTree);
+ forceOp2DelayFree = true;
+ }
+
+ if (!intrin.op2->IsCnsIntOrI() && !intrin.op1->isContained())
+ {
+ // If the index is not a constant or op1 is in register,
+ // we will use the SIMD temp location to store the vector.
+ var_types requiredSimdTempType = (intrin.id == NI_Vector64_GetElement) ? TYP_SIMD8 : TYP_SIMD16;
+ compiler->getSIMDInitTempVarNum(requiredSimdTempType);
+ }
}
- if (!intrin.op2->IsCnsIntOrI() && !intrin.op1->isContained())
+ if (forceOp2DelayFree)
{
- // If the index is not a constant or op1 is in register,
- // we will use the SIMD temp location to store the vector.
- var_types requiredSimdTempType = (intrin.id == NI_Vector64_GetElement) ? TYP_SIMD8 : TYP_SIMD16;
- compiler->getSIMDInitTempVarNum(requiredSimdTempType);
+ srcCount += BuildDelayFreeUses(intrin.op2);
+ }
+ else
+ {
+ srcCount += isRMW ? BuildDelayFreeUses(intrin.op2, intrin.op1) : BuildOperandUses(intrin.op2);
}
- }
-
- if (forceOp2DelayFree)
- {
- srcCount += BuildDelayFreeUses(intrin.op2);
- }
- else
- {
- srcCount += isRMW ? BuildDelayFreeUses(intrin.op2, intrin.op1) : BuildOperandUses(intrin.op2);
- }
-
- if (intrin.op3 != nullptr)
- {
- srcCount += isRMW ? BuildDelayFreeUses(intrin.op3, intrin.op1) : BuildOperandUses(intrin.op3);
- if (intrin.op4 != nullptr)
+ if (intrin.op3 != nullptr)
{
- srcCount += isRMW ? BuildDelayFreeUses(intrin.op4, intrin.op1) : BuildOperandUses(intrin.op4);
+ srcCount += isRMW ? BuildDelayFreeUses(intrin.op3, intrin.op1) : BuildOperandUses(intrin.op3);
+
+ if (intrin.op4 != nullptr)
+ {
+ srcCount += isRMW ? BuildDelayFreeUses(intrin.op4, intrin.op1) : BuildOperandUses(intrin.op4);
+ }
}
}
}
diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp
index a8db1264b64af..ef7a2d0440aa4 100644
--- a/src/coreclr/jit/lsraarmarch.cpp
+++ b/src/coreclr/jit/lsraarmarch.cpp
@@ -694,40 +694,36 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode)
{
buildInternalIntRegisterDefForNode(blkNode);
#ifdef TARGET_ARM64
- const bool canUseLoadStorePairIntRegsInstrs = (size >= 2 * REGSIZE_BYTES);
+ const bool dstAddrMayNeedReg = dstAddr->isContained();
+ const bool srcAddrMayNeedReg = src->OperIs(GT_LCL_VAR, GT_LCL_FLD) ||
+ ((srcAddrOrFill != nullptr) && srcAddrOrFill->isContained());
- if (canUseLoadStorePairIntRegsInstrs)
+ if (srcAddrMayNeedReg && dstAddrMayNeedReg)
{
- // CodeGen can use ldp/stp instructions sequence.
+ // The following allocates an additional integer register in a case
+ // when a load instruction and a store instruction cannot be encoded.
buildInternalIntRegisterDefForNode(blkNode);
+ // In this case, CodeGen will use a SIMD register for copying.
+ buildInternalFloatRegisterDefForNode(blkNode, internalFloatRegCandidates());
+ // And in case of a larger block size, two SIMD registers.
+ if (size >= 2 * REGSIZE_BYTES)
+ {
+ buildInternalFloatRegisterDefForNode(blkNode, internalFloatRegCandidates());
+ }
}
-
- const bool isSrcAddrLocal = src->OperIs(GT_LCL_VAR, GT_LCL_FLD) ||
- ((srcAddrOrFill != nullptr) && srcAddrOrFill->OperIsLocalAddr());
- const bool isDstAddrLocal = dstAddr->OperIsLocalAddr();
-
- // CodeGen can use 16-byte SIMD ldp/stp for larger block sizes
- // only when both source and destination base address registers have known alignment.
- // This is the case, when both registers are either sp or fp.
- bool canUse16ByteWideInstrs = isSrcAddrLocal && isDstAddrLocal && (size >= 2 * FP_REGSIZE_BYTES);
-
- // Note that the SIMD registers allocation is speculative - LSRA doesn't know at this point
- // whether CodeGen will use SIMD registers (i.e. if such instruction sequence will be more optimal).
- // Therefore, it must allocate an additional integer register anyway.
- if (canUse16ByteWideInstrs)
+ else if (srcAddrMayNeedReg || dstAddrMayNeedReg)
{
- buildInternalFloatRegisterDefForNode(blkNode, internalFloatRegCandidates());
- buildInternalFloatRegisterDefForNode(blkNode, internalFloatRegCandidates());
+ if (size >= 2 * REGSIZE_BYTES)
+ {
+ buildInternalFloatRegisterDefForNode(blkNode, internalFloatRegCandidates());
+ buildInternalFloatRegisterDefForNode(blkNode, internalFloatRegCandidates());
+ }
+ else
+ {
+ buildInternalIntRegisterDefForNode(blkNode);
+ }
}
-
- const bool srcAddrMayNeedReg =
- isSrcAddrLocal || ((srcAddrOrFill != nullptr) && srcAddrOrFill->isContained());
- const bool dstAddrMayNeedReg = isDstAddrLocal || dstAddr->isContained();
-
- // The following allocates an additional integer register in a case
- // when a load instruction and a store instruction cannot be encoded using offset
- // from a corresponding base register.
- if (srcAddrMayNeedReg && dstAddrMayNeedReg)
+ else if (size >= 2 * REGSIZE_BYTES)
{
buildInternalIntRegisterDefForNode(blkNode);
}
@@ -785,7 +781,7 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode)
if (blkNode->OperIs(GT_STORE_DYN_BLK))
{
useCount++;
- BuildUse(blkNode->AsStoreDynBlk()->gtDynamicSize, sizeRegMask);
+ BuildUse(blkNode->AsDynBlk()->gtDynamicSize, sizeRegMask);
}
buildInternalRegisterUses();
diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp
index d58f1996091fa..a48d7e7bdee57 100644
--- a/src/coreclr/jit/lsrabuild.cpp
+++ b/src/coreclr/jit/lsrabuild.cpp
@@ -3078,15 +3078,6 @@ int LinearScan::BuildOperandUses(GenTree* node, regMaskTP candidates)
return 1;
}
-#ifdef TARGET_ARM64
- // Must happen before OperIsHWIntrinsic case,
- // but this occurs when a vector zero node is marked as contained.
- if (node->IsVectorZero())
- {
- return 0;
- }
-#endif
-
#if !defined(TARGET_64BIT)
if (node->OperIs(GT_LONG))
{
@@ -3173,14 +3164,6 @@ int LinearScan::BuildDelayFreeUses(GenTree* node, GenTree* rmwNode, regMaskTP ca
{
use = BuildUse(node, candidates);
}
-#ifdef TARGET_ARM64
- // Must happen before OperIsHWIntrinsic case,
- // but this occurs when a vector zero node is marked as contained.
- else if (node->IsVectorZero())
- {
- return 0;
- }
-#endif
#ifdef FEATURE_HW_INTRINSICS
else if (node->OperIsHWIntrinsic())
{
diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp
index e679f00b3bca3..ce1de0b6f4fde 100644
--- a/src/coreclr/jit/lsraxarch.cpp
+++ b/src/coreclr/jit/lsraxarch.cpp
@@ -496,6 +496,7 @@ int LinearScan::BuildNode(GenTree* tree)
case GT_OBJ:
#endif
case GT_BLK:
+ case GT_DYN_BLK:
// These should all be eliminated prior to Lowering.
assert(!"Non-store block node in Lowering");
srcCount = 0;
@@ -1437,7 +1438,7 @@ int LinearScan::BuildBlockStore(GenTreeBlk* blkNode)
if (blkNode->OperIs(GT_STORE_DYN_BLK))
{
useCount++;
- BuildUse(blkNode->AsStoreDynBlk()->gtDynamicSize, sizeRegMask);
+ BuildUse(blkNode->AsDynBlk()->gtDynamicSize, sizeRegMask);
}
#ifdef TARGET_X86
diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp
index f07fe3ca9ed02..972cecf7cd2ee 100644
--- a/src/coreclr/jit/morph.cpp
+++ b/src/coreclr/jit/morph.cpp
@@ -4866,6 +4866,10 @@ void Compiler::fgMakeOutgoingStructArgCopy(GenTreeCall* call, GenTreeCall::Use*
argx->gtFlags &= ~(GTF_ALL_EFFECT) | (argx->AsBlk()->Addr()->gtFlags & GTF_ALL_EFFECT);
argx->SetIndirExceptionFlags(this);
}
+ else
+ {
+ argx->gtFlags |= GTF_DONT_CSE;
+ }
// Copy the valuetype to the temp
GenTree* copyBlk = gtNewBlkOpNode(dest, argx, false /* not volatile */, true /* copyBlock */);
@@ -5194,7 +5198,7 @@ GenTree* Compiler::fgMorphArrayIndex(GenTree* tree)
asIndex->Arr()->AsStrCon()->gtSconCPX, &length);
if ((cnsIndex < length) && (str != nullptr))
{
- GenTree* cnsCharNode = gtNewIconNode(str[cnsIndex], TYP_INT);
+ GenTree* cnsCharNode = gtNewIconNode(str[cnsIndex], elemTyp);
INDEBUG(cnsCharNode->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
return cnsCharNode;
}
@@ -10427,8 +10431,15 @@ GenTree* Compiler::fgMorphBlockOperand(GenTree* tree, var_types asgType, unsigne
{
if (indirTree != nullptr)
{
- // If we have an indirection and a block is required, it should already be a block.
- assert(indirTree->OperIsBlk() || !isBlkReqd);
+ if (indirTree->OperIsBlk() && !isBlkReqd)
+ {
+ effectiveVal->SetOper(GT_IND);
+ }
+ else
+ {
+ // If we have an indirection and a block is required, it should already be a block.
+ assert(indirTree->OperIsBlk() || !isBlkReqd);
+ }
effectiveVal->gtType = asgType;
}
else
@@ -10767,7 +10778,7 @@ GenTree* Compiler::fgMorphFieldAssignToSimdSetElement(GenTree* tree)
// A folded GenTree* instance or nullptr if something prevents folding.
//
-GenTreeOp* Compiler::fgMorphCommutative(GenTreeOp* tree)
+GenTree* Compiler::fgMorphCommutative(GenTreeOp* tree)
{
assert(varTypeIsIntegralOrI(tree->TypeGet()));
assert(tree->OperIs(GT_ADD, GT_MUL, GT_OR, GT_AND, GT_XOR));
@@ -10839,7 +10850,7 @@ GenTreeOp* Compiler::fgMorphCommutative(GenTreeOp* tree)
DEBUG_DESTROY_NODE(foldedCns);
INDEBUG(cns1->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
- return op1->AsOp();
+ return op1;
}
//------------------------------------------------------------------------------
@@ -10852,8 +10863,6 @@ GenTreeOp* Compiler::fgMorphCommutative(GenTreeOp* tree)
// A folded GenTree* instance, or nullptr if it couldn't be folded
GenTree* Compiler::fgMorphCastedBitwiseOp(GenTreeOp* tree)
{
- // This transform does not preserve VNs and deletes a node.
- assert(fgGlobalMorph);
assert(varTypeIsIntegralOrI(tree));
assert(tree->OperIs(GT_OR, GT_AND, GT_XOR));
@@ -11601,6 +11610,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
break;
case GT_OBJ:
case GT_BLK:
+ case GT_DYN_BLK:
case GT_IND:
// A non-null mac here implies this node is part of an address computation (the tree parent is
// GT_ADDR).
@@ -11839,9 +11849,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
}
} // if (op2)
-#ifndef TARGET_64BIT
DONE_MORPHING_CHILDREN:
-#endif // !TARGET_64BIT
if (tree->OperIsIndirOrArrLength())
{
@@ -11976,6 +11984,8 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
*/
GenTree* temp;
+ GenTree* cns1;
+ GenTree* cns2;
size_t ival1;
GenTree* lclVarTree;
GenTree* effectiveOp1;
@@ -12226,15 +12236,335 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
case GT_OR:
case GT_XOR:
case GT_AND:
- tree = fgOptimizeCommutativeArithmetic(tree->AsOp());
- if (!tree->OperIsSimple())
+
+ /* Commute any non-REF constants to the right */
+
+ noway_assert(op1);
+ if (op1->OperIsConst() && (op1->gtType != TYP_REF))
{
- return tree;
+ // TODO-Review: We used to assert here that
+ // noway_assert(!op2->OperIsConst() || !opts.OptEnabled(CLFLG_CONSTANTFOLD));
+ // With modifications to AddrTaken==>AddrExposed, we did more assertion propagation,
+ // and would sometimes hit this assertion. This may indicate a missed "remorph".
+ // Task is to re-enable this assertion and investigate.
+
+ /* Swap the operands */
+ tree->AsOp()->gtOp1 = op2;
+ tree->AsOp()->gtOp2 = op1;
+
+ op1 = op2;
+ op2 = tree->AsOp()->gtOp2;
}
- typ = tree->TypeGet();
- oper = tree->OperGet();
- op1 = tree->gtGetOp1();
- op2 = tree->gtGetOp2IfPresent();
+
+ // Fold "cmp & 1" to just "cmp"
+ if (tree->OperIs(GT_AND) && tree->TypeIs(TYP_INT) && op1->OperIsCompare() && op2->IsIntegralConst(1) &&
+ !gtIsActiveCSE_Candidate(tree) && !gtIsActiveCSE_Candidate(op2))
+ {
+ DEBUG_DESTROY_NODE(op2);
+ DEBUG_DESTROY_NODE(tree);
+ return op1;
+ }
+
+ // See if we can fold floating point operations (can regress minopts mode)
+ if (opts.OptimizationEnabled() && varTypeIsFloating(tree->TypeGet()) && !optValnumCSE_phase)
+ {
+ if ((oper == GT_MUL) && !op1->IsCnsFltOrDbl() && op2->IsCnsFltOrDbl())
+ {
+ if (op2->AsDblCon()->gtDconVal == 2.0)
+ {
+ bool needsComma = !op1->OperIsLeaf() && !op1->IsLocal();
+ // if op1 is not a leaf/local we have to introduce a temp via GT_COMMA.
+ // Unfortunately, it's not optHoistLoopCode-friendly yet so let's do it later.
+ if (!needsComma || (fgOrder == FGOrderLinear))
+ {
+ // Fold "x*2.0" to "x+x"
+ op2 = fgMakeMultiUse(&tree->AsOp()->gtOp1);
+ op1 = tree->AsOp()->gtOp1;
+ oper = GT_ADD;
+ tree = gtNewOperNode(oper, tree->TypeGet(), op1, op2);
+ INDEBUG(tree->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
+ }
+ }
+ else if (op2->AsDblCon()->gtDconVal == 1.0)
+ {
+ // Fold "x*1.0" to "x"
+ DEBUG_DESTROY_NODE(op2);
+ DEBUG_DESTROY_NODE(tree);
+ return op1;
+ }
+ }
+ }
+
+ /* See if we can fold GT_ADD nodes. */
+
+ if (oper == GT_ADD)
+ {
+ /* Fold "((x+icon1)+(y+icon2)) to ((x+y)+(icon1+icon2))" */
+
+ if (op1->gtOper == GT_ADD && op2->gtOper == GT_ADD && !gtIsActiveCSE_Candidate(op2) &&
+ op1->AsOp()->gtOp2->gtOper == GT_CNS_INT && op2->AsOp()->gtOp2->gtOper == GT_CNS_INT &&
+ !op1->gtOverflow() && !op2->gtOverflow())
+ {
+ // Don't create a byref pointer that may point outside of the ref object.
+ // If a GC happens, the byref won't get updated. This can happen if one
+ // of the int components is negative. It also requires the address generation
+ // be in a fully-interruptible code region.
+ if (!varTypeIsGC(op1->AsOp()->gtOp1->TypeGet()) && !varTypeIsGC(op2->AsOp()->gtOp1->TypeGet()))
+ {
+ cns1 = op1->AsOp()->gtOp2;
+ cns2 = op2->AsOp()->gtOp2;
+
+ ssize_t value = cns1->AsIntCon()->IconValue() + cns2->AsIntCon()->IconValue();
+ cns1->AsIntCon()->SetValueTruncating(value);
+
+ tree->AsOp()->gtOp2 = cns1;
+ DEBUG_DESTROY_NODE(cns2);
+
+ op1->AsOp()->gtOp2 = op2->AsOp()->gtOp1;
+ op1->gtFlags |= (op1->AsOp()->gtOp2->gtFlags & GTF_ALL_EFFECT);
+ DEBUG_DESTROY_NODE(op2);
+ op2 = tree->AsOp()->gtOp2;
+ }
+ }
+
+ if (op2->IsCnsIntOrI() && varTypeIsIntegralOrI(typ))
+ {
+ // Fold (x + 0).
+ if ((op2->AsIntConCommon()->IconValue() == 0) && !gtIsActiveCSE_Candidate(tree))
+ {
+ // Remove the addition iff it won't change the tree type
+ // to TYP_REF.
+
+ if (!gtIsActiveCSE_Candidate(op2) &&
+ ((op1->TypeGet() == tree->TypeGet()) || (op1->TypeGet() != TYP_REF)))
+ {
+ if (fgGlobalMorph && (op2->OperGet() == GT_CNS_INT) &&
+ (op2->AsIntCon()->gtFieldSeq != nullptr) &&
+ (op2->AsIntCon()->gtFieldSeq != FieldSeqStore::NotAField()))
+ {
+ fgAddFieldSeqForZeroOffset(op1, op2->AsIntCon()->gtFieldSeq);
+ }
+
+ DEBUG_DESTROY_NODE(op2);
+ DEBUG_DESTROY_NODE(tree);
+
+ return op1;
+ }
+ }
+ }
+
+ if (opts.OptimizationEnabled() && fgGlobalMorph)
+ {
+ // - a + b = > b - a
+ // ADD((NEG(a), b) => SUB(b, a)
+
+ // Skip optimization if non-NEG operand is constant.
+ if (op1->OperIs(GT_NEG) && !op2->OperIs(GT_NEG) && !op2->IsIntegralConst() &&
+ gtCanSwapOrder(op1, op2))
+ {
+ // tree: ADD
+ // op1: NEG
+ // op2: b
+ // op1Child: a
+
+ GenTree* op1Child = op1->AsOp()->gtOp1; // a
+ oper = GT_SUB;
+ tree->SetOper(oper, GenTree::PRESERVE_VN);
+ tree->AsOp()->gtOp1 = op2;
+ tree->AsOp()->gtOp2 = op1Child;
+
+ DEBUG_DESTROY_NODE(op1);
+
+ op1 = op2;
+ op2 = op1Child;
+ }
+ // a + -b = > a - b
+ // ADD(a, (NEG(b)) => SUB(a, b)
+ else if (!op1->OperIs(GT_NEG) && op2->OperIs(GT_NEG))
+ {
+ // a is non constant because it was already canonicalized to have
+ // variable on the left and constant on the right.
+
+ // tree: ADD
+ // op1: a
+ // op2: NEG
+ // op2Child: b
+
+ GenTree* op2Child = op2->AsOp()->gtOp1; // a
+ oper = GT_SUB;
+ tree->SetOper(oper, GenTree::PRESERVE_VN);
+ tree->AsOp()->gtOp2 = op2Child;
+
+ DEBUG_DESTROY_NODE(op2);
+
+ op2 = op2Child;
+ }
+ }
+ }
+ /* See if we can fold GT_MUL by const nodes */
+ else if (oper == GT_MUL && op2->IsCnsIntOrI() && !optValnumCSE_phase)
+ {
+#ifndef TARGET_64BIT
+ noway_assert(typ <= TYP_UINT);
+#endif // TARGET_64BIT
+ noway_assert(!tree->gtOverflow());
+
+ ssize_t mult = op2->AsIntConCommon()->IconValue();
+ bool op2IsConstIndex = op2->OperGet() == GT_CNS_INT && op2->AsIntCon()->gtFieldSeq != nullptr &&
+ op2->AsIntCon()->gtFieldSeq->IsConstantIndexFieldSeq();
+
+ assert(!op2IsConstIndex || op2->AsIntCon()->gtFieldSeq->m_next == nullptr);
+
+ if (mult == 0)
+ {
+ // We may be able to throw away op1 (unless it has side-effects)
+
+ if ((op1->gtFlags & GTF_SIDE_EFFECT) == 0)
+ {
+ DEBUG_DESTROY_NODE(op1);
+ DEBUG_DESTROY_NODE(tree);
+ return op2; // Just return the "0" node
+ }
+
+ // We need to keep op1 for the side-effects. Hang it off
+ // a GT_COMMA node
+
+ tree->ChangeOper(GT_COMMA);
+ return tree;
+ }
+
+ size_t abs_mult = (mult >= 0) ? mult : -mult;
+ size_t lowestBit = genFindLowestBit(abs_mult);
+ bool changeToShift = false;
+
+ // is it a power of two? (positive or negative)
+ if (abs_mult == lowestBit)
+ {
+ // if negative negate (min-int does not need negation)
+ if (mult < 0 && mult != SSIZE_T_MIN)
+ {
+ // The type of the new GT_NEG node cannot just be op1->TypeGet().
+ // Otherwise we may sign-extend incorrectly in cases where the GT_NEG
+ // node ends up feeding directly a cast, for example in
+ // GT_CAST(GT_MUL(-1, s_1.ubyte))
+ tree->AsOp()->gtOp1 = op1 = gtNewOperNode(GT_NEG, genActualType(op1->TypeGet()), op1);
+ fgMorphTreeDone(op1);
+ }
+
+ // If "op2" is a constant array index, the other multiplicand must be a constant.
+ // Transfer the annotation to the other one.
+ if (op2->OperGet() == GT_CNS_INT && op2->AsIntCon()->gtFieldSeq != nullptr &&
+ op2->AsIntCon()->gtFieldSeq->IsConstantIndexFieldSeq())
+ {
+ assert(op2->AsIntCon()->gtFieldSeq->m_next == nullptr);
+ GenTree* otherOp = op1;
+ if (otherOp->OperGet() == GT_NEG)
+ {
+ otherOp = otherOp->AsOp()->gtOp1;
+ }
+ assert(otherOp->OperGet() == GT_CNS_INT);
+ assert(otherOp->AsIntCon()->gtFieldSeq == FieldSeqStore::NotAField());
+ otherOp->AsIntCon()->gtFieldSeq = op2->AsIntCon()->gtFieldSeq;
+ }
+
+ if (abs_mult == 1)
+ {
+ DEBUG_DESTROY_NODE(op2);
+ DEBUG_DESTROY_NODE(tree);
+ return op1;
+ }
+
+ /* Change the multiplication into a shift by log2(val) bits */
+ op2->AsIntConCommon()->SetIconValue(genLog2(abs_mult));
+ changeToShift = true;
+ }
+ else if ((lowestBit > 1) && jitIsScaleIndexMul(lowestBit) && optAvoidIntMult())
+ {
+ int shift = genLog2(lowestBit);
+ ssize_t factor = abs_mult >> shift;
+
+ if (factor == 3 || factor == 5 || factor == 9)
+ {
+ // if negative negate (min-int does not need negation)
+ if (mult < 0 && mult != SSIZE_T_MIN)
+ {
+ tree->AsOp()->gtOp1 = op1 = gtNewOperNode(GT_NEG, genActualType(op1->TypeGet()), op1);
+ fgMorphTreeDone(op1);
+ }
+
+ GenTree* factorIcon = gtNewIconNode(factor, TYP_I_IMPL);
+ if (op2IsConstIndex)
+ {
+ factorIcon->AsIntCon()->gtFieldSeq =
+ GetFieldSeqStore()->CreateSingleton(FieldSeqStore::ConstantIndexPseudoField);
+ }
+
+ // change the multiplication into a smaller multiplication (by 3, 5 or 9) and a shift
+ tree->AsOp()->gtOp1 = op1 = gtNewOperNode(GT_MUL, tree->gtType, op1, factorIcon);
+ fgMorphTreeDone(op1);
+
+ op2->AsIntConCommon()->SetIconValue(shift);
+ changeToShift = true;
+ }
+ }
+ if (changeToShift)
+ {
+ // vnStore is null before the ValueNumber phase has run
+ if (vnStore != nullptr)
+ {
+ // Update the ValueNumber for 'op2', as we just changed the constant
+ fgValueNumberTreeConst(op2);
+ }
+ oper = GT_LSH;
+ // Keep the old ValueNumber for 'tree' as the new expr
+ // will still compute the same value as before
+ tree->ChangeOper(oper, GenTree::PRESERVE_VN);
+
+ goto DONE_MORPHING_CHILDREN;
+ }
+ }
+ else if (fgOperIsBitwiseRotationRoot(oper))
+ {
+ tree = fgRecognizeAndMorphBitwiseRotation(tree);
+
+ // fgRecognizeAndMorphBitwiseRotation may return a new tree
+ oper = tree->OperGet();
+ typ = tree->TypeGet();
+ op1 = tree->AsOp()->gtOp1;
+ op2 = tree->AsOp()->gtOp2;
+ }
+
+ if (fgGlobalMorph && varTypeIsIntegralOrI(tree) && tree->OperIs(GT_AND, GT_OR, GT_XOR))
+ {
+ GenTree* result = fgMorphCastedBitwiseOp(tree->AsOp());
+ if (result != nullptr)
+ {
+ assert(result->OperIs(GT_CAST));
+ assert(result->AsOp()->gtOp2 == nullptr);
+ // tree got folded to a unary (cast) op
+ tree = result;
+ oper = tree->OperGet();
+ typ = tree->TypeGet();
+ op1 = tree->AsOp()->gtGetOp1();
+ op2 = nullptr;
+ }
+ }
+
+ if (varTypeIsIntegralOrI(tree->TypeGet()) && tree->OperIs(GT_ADD, GT_MUL, GT_AND, GT_OR, GT_XOR))
+ {
+ GenTree* foldedTree = fgMorphCommutative(tree->AsOp());
+ if (foldedTree != nullptr)
+ {
+ tree = foldedTree;
+ op1 = tree->gtGetOp1();
+ op2 = tree->gtGetOp2();
+ if (!tree->OperIs(oper))
+ {
+ return tree;
+ }
+ }
+ }
+
break;
case GT_NOT:
@@ -12894,45 +13224,6 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
}
break;
- case GT_INTRINSIC:
- if (tree->AsIntrinsic()->gtIntrinsicName ==
- NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant)
- {
- // Should be expanded by the time it reaches CSE phase
- assert(!optValnumCSE_phase);
-
- JITDUMP("\nExpanding RuntimeHelpers.IsKnownConstant to ");
- if (op1->OperIsConst())
- {
- // We're lucky to catch a constant here while importer was not
- JITDUMP("true\n");
- DEBUG_DESTROY_NODE(tree, op1);
- tree = gtNewIconNode(1);
- }
- else
- {
- GenTree* op1SideEffects = nullptr;
- gtExtractSideEffList(op1, &op1SideEffects, GTF_ALL_EFFECT);
- if (op1SideEffects != nullptr)
- {
- DEBUG_DESTROY_NODE(tree);
- // Keep side-effects of op1
- tree = gtNewOperNode(GT_COMMA, TYP_INT, op1SideEffects, gtNewIconNode(0));
- JITDUMP("false with side effects:\n")
- DISPTREE(tree);
- }
- else
- {
- JITDUMP("false\n");
- DEBUG_DESTROY_NODE(tree, op1);
- tree = gtNewIconNode(0);
- }
- }
- INDEBUG(tree->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
- return tree;
- }
- break;
-
default:
break;
}
@@ -13413,381 +13704,11 @@ GenTree* Compiler::fgOptimizeRelationalComparisonWithConst(GenTreeOp* cmp)
return cmp;
}
-//------------------------------------------------------------------------
-// fgOptimizeCommutativeArithmetic: Optimizes commutative operations.
-//
-// Arguments:
-// tree - the unchecked GT_ADD/GT_MUL/GT_OR/GT_XOR/GT_AND tree to optimize.
-//
-// Return Value:
-// The optimized tree that can have any shape.
-//
-GenTree* Compiler::fgOptimizeCommutativeArithmetic(GenTreeOp* tree)
-{
- assert(tree->OperIs(GT_ADD, GT_MUL, GT_OR, GT_XOR, GT_AND));
- assert(!tree->gtOverflowEx());
-
- // Commute constants to the right.
- if (tree->gtGetOp1()->OperIsConst() && !tree->gtGetOp1()->TypeIs(TYP_REF))
- {
- // TODO-Review: We used to assert here that "(!op2->OperIsConst() || !opts.OptEnabled(CLFLG_CONSTANTFOLD))".
- // This may indicate a missed "remorph". Task is to re-enable this assertion and investigate.
- std::swap(tree->gtOp1, tree->gtOp2);
- }
-
- if (fgOperIsBitwiseRotationRoot(tree->OperGet()))
- {
- GenTree* rotationTree = fgRecognizeAndMorphBitwiseRotation(tree);
- if (rotationTree != nullptr)
- {
- return rotationTree;
- }
- }
-
- if (fgGlobalMorph && tree->OperIs(GT_AND, GT_OR, GT_XOR))
- {
- GenTree* castTree = fgMorphCastedBitwiseOp(tree->AsOp());
- if (castTree != nullptr)
- {
- return castTree;
- }
- }
-
- if (varTypeIsIntegralOrI(tree))
- {
- genTreeOps oldTreeOper = tree->OperGet();
- GenTreeOp* optimizedTree = fgMorphCommutative(tree->AsOp());
- if (optimizedTree != nullptr)
- {
- if (!optimizedTree->OperIs(oldTreeOper))
- {
- // "optimizedTree" could end up being a COMMA.
- return optimizedTree;
- }
-
- tree = optimizedTree;
- }
- }
-
- if (!optValnumCSE_phase)
- {
- GenTree* optimizedTree = nullptr;
- if (tree->OperIs(GT_ADD))
- {
- optimizedTree = fgOptimizeAddition(tree);
- }
- else if (tree->OperIs(GT_MUL))
- {
- optimizedTree = fgOptimizeMultiply(tree);
- }
- else if (tree->OperIs(GT_AND))
- {
- optimizedTree = fgOptimizeBitwiseAnd(tree);
- }
-
- if (optimizedTree != nullptr)
- {
- return optimizedTree;
- }
- }
-
- return tree;
-}
-
-//------------------------------------------------------------------------
-// fgOptimizeAddition: optimizes addition.
-//
-// Arguments:
-// add - the unchecked GT_ADD tree to optimize.
-//
-// Return Value:
-// The optimized tree, that can have any shape, in case any transformations
-// were performed. Otherwise, "nullptr", guaranteeing no state change.
-//
-GenTree* Compiler::fgOptimizeAddition(GenTreeOp* add)
-{
- assert(add->OperIs(GT_ADD) && !add->gtOverflow());
- assert(!optValnumCSE_phase);
-
- GenTree* op1 = add->gtGetOp1();
- GenTree* op2 = add->gtGetOp2();
-
- // Fold "((x + icon1) + (y + icon2))" to ((x + y) + (icon1 + icon2))".
- // Be careful not to create a byref pointer that may point outside of the ref object.
- // Only do this in global morph as we don't recompute the VN for "(x + y)", the new "op2".
- if (op1->OperIs(GT_ADD) && op2->OperIs(GT_ADD) && !op1->gtOverflow() && !op2->gtOverflow() &&
- op1->AsOp()->gtGetOp2()->IsCnsIntOrI() && op2->AsOp()->gtGetOp2()->IsCnsIntOrI() &&
- !varTypeIsGC(op1->AsOp()->gtGetOp1()) && !varTypeIsGC(op2->AsOp()->gtGetOp1()) && fgGlobalMorph)
- {
- GenTreeOp* addOne = op1->AsOp();
- GenTreeOp* addTwo = op2->AsOp();
- GenTreeIntCon* constOne = addOne->gtGetOp2()->AsIntCon();
- GenTreeIntCon* constTwo = addTwo->gtGetOp2()->AsIntCon();
-
- addOne->gtOp2 = addTwo->gtGetOp1();
- addOne->SetAllEffectsFlags(addOne->gtGetOp1(), addOne->gtGetOp2());
- DEBUG_DESTROY_NODE(addTwo);
-
- constOne->SetValueTruncating(constOne->IconValue() + constTwo->IconValue());
- op2 = constOne;
- add->gtOp2 = constOne;
- DEBUG_DESTROY_NODE(constTwo);
- }
-
- // Fold (x + 0) - given it won't change the tree type to TYP_REF.
- // TODO-Bug: this code will lose the GC-ness of a tree like "native int + byref(0)".
- if (op2->IsIntegralConst(0) && ((add->TypeGet() == op1->TypeGet()) || !op1->TypeIs(TYP_REF)))
- {
- if (op2->IsCnsIntOrI() && (op2->AsIntCon()->gtFieldSeq != nullptr) &&
- (op2->AsIntCon()->gtFieldSeq != FieldSeqStore::NotAField()))
- {
- fgAddFieldSeqForZeroOffset(op1, op2->AsIntCon()->gtFieldSeq);
- }
-
- DEBUG_DESTROY_NODE(op2);
- DEBUG_DESTROY_NODE(add);
-
- return op1;
- }
-
- // Note that these transformations are legal for floating-point ADDs as well.
- if (opts.OptimizationEnabled())
- {
- // - a + b = > b - a
- // ADD((NEG(a), b) => SUB(b, a)
-
- // Do not do this if "op2" is constant for canonicalization purposes.
- if (op1->OperIs(GT_NEG) && !op2->OperIs(GT_NEG) && !op2->IsIntegralConst() && gtCanSwapOrder(op1, op2))
- {
- add->SetOper(GT_SUB);
- add->gtOp1 = op2;
- add->gtOp2 = op1->AsOp()->gtGetOp1();
-
- DEBUG_DESTROY_NODE(op1);
-
- return add;
- }
-
- // a + -b = > a - b
- // ADD(a, (NEG(b)) => SUB(a, b)
- if (!op1->OperIs(GT_NEG) && op2->OperIs(GT_NEG))
- {
- add->SetOper(GT_SUB);
- add->gtOp2 = op2->AsOp()->gtGetOp1();
-
- DEBUG_DESTROY_NODE(op2);
-
- return add;
- }
- }
-
- return nullptr;
-}
-
-//------------------------------------------------------------------------
-// fgOptimizeMultiply: optimizes multiplication.
-//
-// Arguments:
-// mul - the unchecked TYP_I_IMPL/TYP_INT GT_MUL tree to optimize.
-//
-// Return Value:
-// The optimized tree, that can have any shape, in case any transformations
-// were performed. Otherwise, "nullptr", guaranteeing no state change.
-//
-GenTree* Compiler::fgOptimizeMultiply(GenTreeOp* mul)
-{
- assert(mul->OperIs(GT_MUL));
- assert(varTypeIsIntOrI(mul) || varTypeIsFloating(mul));
- assert(!mul->gtOverflow());
- assert(!optValnumCSE_phase);
-
- GenTree* op1 = mul->gtGetOp1();
- GenTree* op2 = mul->gtGetOp2();
-
- assert(mul->TypeGet() == genActualType(op1));
- assert(mul->TypeGet() == genActualType(op2));
-
- if (opts.OptimizationEnabled() && op2->IsCnsFltOrDbl())
- {
- double multiplierValue = op2->AsDblCon()->gtDconVal;
-
- if (multiplierValue == 1.0)
- {
- // Fold "x * 1.0" to "x".
- DEBUG_DESTROY_NODE(op2);
- DEBUG_DESTROY_NODE(mul);
-
- return op1;
- }
-
- // Fold "x * 2.0" to "x + x".
- // If op1 is not a local we will have to introduce a temporary via GT_COMMA.
- // Unfortunately, it's not optHoistLoopCode-friendly (yet), so we'll only do
- // this for locals / after hoisting has run (when rationalization remorphs
- // math INTRINSICSs into calls...).
- if ((multiplierValue == 2.0) && (op1->IsLocal() || (fgOrder == FGOrderLinear)))
- {
- op2 = fgMakeMultiUse(&op1);
- GenTree* add = gtNewOperNode(GT_ADD, mul->TypeGet(), op1, op2);
- INDEBUG(add->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
-
- return add;
- }
- }
-
- if (op2->IsIntegralConst())
- {
- ssize_t mult = op2->AsIntConCommon()->IconValue();
- bool op2IsConstIndex = op2->OperGet() == GT_CNS_INT && op2->AsIntCon()->gtFieldSeq != nullptr &&
- op2->AsIntCon()->gtFieldSeq->IsConstantIndexFieldSeq();
-
- assert(!op2IsConstIndex || op2->AsIntCon()->gtFieldSeq->m_next == nullptr);
-
- if (mult == 0)
- {
- // We may be able to throw away op1 (unless it has side-effects)
-
- if ((op1->gtFlags & GTF_SIDE_EFFECT) == 0)
- {
- DEBUG_DESTROY_NODE(op1);
- DEBUG_DESTROY_NODE(mul);
-
- return op2; // Just return the "0" node
- }
-
- // We need to keep op1 for the side-effects. Hang it off a GT_COMMA node.
- mul->ChangeOper(GT_COMMA, GenTree::PRESERVE_VN);
- return mul;
- }
-
-#ifdef TARGET_XARCH
- // Should we try to replace integer multiplication with lea/add/shift sequences?
- bool mulShiftOpt = compCodeOpt() != SMALL_CODE;
-#else // !TARGET_XARCH
- bool mulShiftOpt = false;
-#endif // !TARGET_XARCH
-
- size_t abs_mult = (mult >= 0) ? mult : -mult;
- size_t lowestBit = genFindLowestBit(abs_mult);
- bool changeToShift = false;
-
- // is it a power of two? (positive or negative)
- if (abs_mult == lowestBit)
- {
- // if negative negate (min-int does not need negation)
- if (mult < 0 && mult != SSIZE_T_MIN)
- {
- op1 = gtNewOperNode(GT_NEG, genActualType(op1), op1);
- mul->gtOp1 = op1;
- fgMorphTreeDone(op1);
- }
-
- // If "op2" is a constant array index, the other multiplicand must be a constant.
- // Transfer the annotation to the other one.
- if (op2->OperGet() == GT_CNS_INT && op2->AsIntCon()->gtFieldSeq != nullptr &&
- op2->AsIntCon()->gtFieldSeq->IsConstantIndexFieldSeq())
- {
- assert(op2->AsIntCon()->gtFieldSeq->m_next == nullptr);
- GenTree* otherOp = op1;
- if (otherOp->OperGet() == GT_NEG)
- {
- otherOp = otherOp->AsOp()->gtOp1;
- }
- assert(otherOp->OperGet() == GT_CNS_INT);
- assert(otherOp->AsIntCon()->gtFieldSeq == FieldSeqStore::NotAField());
- otherOp->AsIntCon()->gtFieldSeq = op2->AsIntCon()->gtFieldSeq;
- }
-
- if (abs_mult == 1)
- {
- DEBUG_DESTROY_NODE(op2);
- DEBUG_DESTROY_NODE(mul);
- return op1;
- }
-
- // Change the multiplication into a shift by log2(val) bits.
- op2->AsIntConCommon()->SetIconValue(genLog2(abs_mult));
- changeToShift = true;
- }
- else if (mulShiftOpt && (lowestBit > 1) && jitIsScaleIndexMul(lowestBit))
- {
- int shift = genLog2(lowestBit);
- ssize_t factor = abs_mult >> shift;
-
- if (factor == 3 || factor == 5 || factor == 9)
- {
- // if negative negate (min-int does not need negation)
- if (mult < 0 && mult != SSIZE_T_MIN)
- {
- op1 = gtNewOperNode(GT_NEG, genActualType(op1), op1);
- mul->gtOp1 = op1;
- fgMorphTreeDone(op1);
- }
-
- GenTree* factorIcon = gtNewIconNode(factor, mul->TypeGet());
- if (op2IsConstIndex)
- {
- factorIcon->AsIntCon()->gtFieldSeq =
- GetFieldSeqStore()->CreateSingleton(FieldSeqStore::ConstantIndexPseudoField);
- }
-
- // change the multiplication into a smaller multiplication (by 3, 5 or 9) and a shift
- op1 = gtNewOperNode(GT_MUL, mul->TypeGet(), op1, factorIcon);
- mul->gtOp1 = op1;
- fgMorphTreeDone(op1);
-
- op2->AsIntConCommon()->SetIconValue(shift);
- changeToShift = true;
- }
- }
-
- if (changeToShift)
- {
- fgUpdateConstTreeValueNumber(op2);
- mul->ChangeOper(GT_LSH, GenTree::PRESERVE_VN);
-
- return mul;
- }
- }
-
- return nullptr;
-}
-
-//------------------------------------------------------------------------
-// fgOptimizeBitwiseAnd: optimizes the "and" operation.
-//
-// Arguments:
-// andOp - the GT_AND tree to optimize.
-//
-// Return Value:
-// The optimized tree, currently always a relop, in case any transformations
-// were performed. Otherwise, "nullptr", guaranteeing no state change.
-//
-GenTree* Compiler::fgOptimizeBitwiseAnd(GenTreeOp* andOp)
-{
- assert(andOp->OperIs(GT_AND));
- assert(!optValnumCSE_phase);
-
- GenTree* op1 = andOp->gtGetOp1();
- GenTree* op2 = andOp->gtGetOp2();
-
- // Fold "cmp & 1" to just "cmp".
- if (andOp->TypeIs(TYP_INT) && op1->OperIsCompare() && op2->IsIntegralConst(1))
- {
- DEBUG_DESTROY_NODE(op2);
- DEBUG_DESTROY_NODE(andOp);
-
- return op1;
- }
-
- return nullptr;
-}
-
//------------------------------------------------------------------------
// fgPropagateCommaThrow: propagate a "comma throw" up the tree.
//
// "Comma throws" in the compiler represent the canonical form of an always
-// throwing expression. They have the shape of COMMA(THROW, ZERO), to satisfy
+// throwing expression. They have the shape of COMMA(THROW, ZERO), to satsify
// the semantic that the original expression produced some value and are
// generated by "gtFoldExprConst" when it encounters checked arithmetic that
// will determinably overflow.
@@ -14426,7 +14347,7 @@ bool Compiler::fgOperIsBitwiseRotationRoot(genTreeOps oper)
// tree - tree to check for a rotation pattern
//
// Return Value:
-// An equivalent GT_ROL or GT_ROR tree if a pattern is found; "nullptr" otherwise.
+// An equivalent GT_ROL or GT_ROR tree if a pattern is found; original tree otherwise.
//
// Assumption:
// The input is a GT_OR or a GT_XOR tree.
@@ -14476,7 +14397,7 @@ GenTree* Compiler::fgRecognizeAndMorphBitwiseRotation(GenTree* tree)
// We can't do anything if the tree has assignments, calls, or volatile
// reads. Note that we allow GTF_EXCEPT side effect since any exceptions
// thrown by the original tree will be thrown by the transformed tree as well.
- return nullptr;
+ return tree;
}
genTreeOps oper = tree->OperGet();
@@ -14499,7 +14420,7 @@ GenTree* Compiler::fgRecognizeAndMorphBitwiseRotation(GenTree* tree)
}
else
{
- return nullptr;
+ return tree;
}
// Check if the trees representing the value to shift are identical.
@@ -14531,7 +14452,7 @@ GenTree* Compiler::fgRecognizeAndMorphBitwiseRotation(GenTree* tree)
}
else
{
- return nullptr;
+ return tree;
}
}
@@ -14544,7 +14465,7 @@ GenTree* Compiler::fgRecognizeAndMorphBitwiseRotation(GenTree* tree)
}
else
{
- return nullptr;
+ return tree;
}
}
@@ -14554,7 +14475,7 @@ GenTree* Compiler::fgRecognizeAndMorphBitwiseRotation(GenTree* tree)
// something like (x << y & 15) or
// (x >> (32 - y) & 15 with 32 bit x.
// The transformation is not valid.
- return nullptr;
+ return tree;
}
GenTree* shiftIndexWithAdd = nullptr;
@@ -14600,7 +14521,7 @@ GenTree* Compiler::fgRecognizeAndMorphBitwiseRotation(GenTree* tree)
// TODO-X86-CQ: we need to handle variable-sized long shifts specially on x86.
// GT_LSH, GT_RSH, and GT_RSZ have helpers for this case. We may need
// to add helpers for GT_ROL and GT_ROR.
- return nullptr;
+ return tree;
}
#endif
@@ -14654,8 +14575,7 @@ GenTree* Compiler::fgRecognizeAndMorphBitwiseRotation(GenTree* tree)
return tree;
}
}
-
- return nullptr;
+ return tree;
}
#if !defined(TARGET_64BIT)
@@ -14982,7 +14902,23 @@ GenTree* Compiler::fgMorphTree(GenTree* tree, MorphAddrContext* mac)
break;
case GT_STORE_DYN_BLK:
- tree = fgMorphStoreDynBlock(tree->AsStoreDynBlk());
+ case GT_DYN_BLK:
+ if (tree->OperGet() == GT_STORE_DYN_BLK)
+ {
+ tree->AsDynBlk()->Data() = fgMorphTree(tree->AsDynBlk()->Data());
+ }
+ tree->AsDynBlk()->Addr() = fgMorphTree(tree->AsDynBlk()->Addr());
+ tree->AsDynBlk()->gtDynamicSize = fgMorphTree(tree->AsDynBlk()->gtDynamicSize);
+
+ tree->gtFlags &= ~GTF_CALL;
+ tree->SetIndirExceptionFlags(this);
+
+ if (tree->OperGet() == GT_STORE_DYN_BLK)
+ {
+ tree->gtFlags |= tree->AsDynBlk()->Data()->gtFlags & GTF_ALL_EFFECT;
+ }
+ tree->gtFlags |= tree->AsDynBlk()->Addr()->gtFlags & GTF_ALL_EFFECT;
+ tree->gtFlags |= tree->AsDynBlk()->gtDynamicSize->gtFlags & GTF_ALL_EFFECT;
break;
default:
diff --git a/src/coreclr/jit/morphblock.cpp b/src/coreclr/jit/morphblock.cpp
index d725923478433..233f72ef8f110 100644
--- a/src/coreclr/jit/morphblock.cpp
+++ b/src/coreclr/jit/morphblock.cpp
@@ -26,6 +26,7 @@ class MorphInitBlockHelper
static GenTree* MorphBlock(Compiler* comp, GenTree* tree, bool isDest);
static GenTree* MorphCommaBlock(Compiler* comp, GenTreeOp* firstComma);
+ static GenTreeBlk* MorphDynamicBlock(Compiler* comp, GenTreeDynBlk* dynBlock);
protected:
Compiler* m_comp;
@@ -35,7 +36,9 @@ class MorphInitBlockHelper
GenTree* m_dst = nullptr;
GenTree* m_src = nullptr;
- unsigned m_blockSize = 0;
+ unsigned m_blockSize = 0;
+ bool m_blockSizeIsConst = false;
+
unsigned m_dstLclNum = BAD_VAR_NUM;
GenTreeLclVarCommon* m_dstLclNode = nullptr;
LclVarDsc* m_dstVarDsc = nullptr;
@@ -209,8 +212,9 @@ void MorphInitBlockHelper::PrepareDst()
if (m_dst->IsLocal())
{
- m_dstLclNode = m_dst->AsLclVarCommon();
- m_dstVarDsc = m_comp->lvaGetDesc(m_dstLclNode);
+ m_dstLclNode = m_dst->AsLclVarCommon();
+ m_dstVarDsc = m_comp->lvaGetDesc(m_dstLclNode);
+ m_blockSizeIsConst = true;
if (m_dst->OperIs(GT_LCL_VAR))
{
@@ -244,19 +248,21 @@ void MorphInitBlockHelper::PrepareDst()
else
{
assert(m_dst == m_dst->gtEffectiveVal() && "the commas were skipped in MorphBlock");
- assert(m_dst->OperIs(GT_IND, GT_BLK, GT_OBJ));
+ assert(m_dst->OperIs(GT_IND, GT_BLK, GT_OBJ, GT_DYN_BLK));
GenTree* dstAddr = m_dst->AsIndir()->Addr();
if (m_dst->OperGet() == GT_IND)
{
assert(m_dst->TypeGet() != TYP_STRUCT);
- m_blockSize = genTypeSize(m_dst);
+ m_blockSize = genTypeSize(m_dst);
+ m_blockSizeIsConst = true;
}
else
{
assert(m_dst->OperIsBlk());
- GenTreeBlk* blk = m_dst->AsBlk();
- m_blockSize = blk->Size();
+ GenTreeBlk* blk = m_dst->AsBlk();
+ m_blockSize = blk->Size();
+ m_blockSizeIsConst = !blk->OperIs(GT_DYN_BLK);
}
noway_assert(dstAddr->TypeIs(TYP_BYREF, TYP_I_IMPL));
@@ -438,10 +444,22 @@ GenTree* MorphInitBlockHelper::MorphBlock(Compiler* comp, GenTree* tree, bool is
return tree;
}
- GenTree* blkAddr = tree->AsBlk()->Addr();
+ GenTreeBlk* blkNode = tree->AsBlk();
+ if (blkNode->OperIs(GT_DYN_BLK))
+ {
+ blkNode = MorphDynamicBlock(comp, blkNode->AsDynBlk());
+ if (blkNode->OperIs(GT_DYN_BLK))
+ {
+ JITDUMP("MorphBlock after:\n");
+ DISPTREE(blkNode);
+ return blkNode;
+ }
+ }
+
+ GenTree* blkAddr = blkNode->Addr();
assert(blkAddr != nullptr);
assert(blkAddr->TypeIs(TYP_I_IMPL, TYP_BYREF, TYP_REF));
- // GT_ADDR, GT_LCL_VAR/FLD, GT_ADD, GT_COMMA, GT_CALL, GT_CNS_INT, GT_LCL_VAR/FLD_ADDR
+ // GT_ADDR, GT_LCL_VAR/FLD, GT_ADD, GT_COMMA, GT_CALL, GT_CNST_INT, GT_LCL_VAR/FLD_ADDR
JITDUMP("MorphBlock after:\n");
DISPTREE(tree);
@@ -521,6 +539,41 @@ GenTree* MorphInitBlockHelper::MorphCommaBlock(Compiler* comp, GenTreeOp* firstC
return res;
}
+//------------------------------------------------------------------------
+// MorphDynamicBlock: tries to transform a dynamic block as a const block.
+//
+// static
+GenTreeBlk* MorphInitBlockHelper::MorphDynamicBlock(Compiler* comp, GenTreeDynBlk* dynBlock)
+{
+ if (dynBlock->gtDynamicSize->IsCnsIntOrI())
+ {
+ GenTreeIntCon* dynSize = dynBlock->gtDynamicSize->AsIntCon();
+ assert(dynSize->FitsInI32());
+ unsigned size = static_cast(dynSize->IconValue());
+ // A GT_BLK with size of zero is not supported,
+ // so if we encounter such a thing we just leave it as a GT_DYN_BLK
+ if (size != 0)
+ {
+ dynBlock->gtDynamicSize = nullptr;
+ GenTreeBlk* blkNode = dynBlock;
+ blkNode->ChangeOper(GT_BLK);
+ blkNode->SetLayout(comp->typGetBlkLayout(size));
+ JITDUMP("MorphDynamicBlock: DYN_BLK was morphed into BLK:\n");
+ return blkNode;
+ }
+ else
+ {
+ JITDUMP("MorphDynamicBlock: DYN_BLK with zero size can't be morphed:\n");
+ return dynBlock;
+ }
+ }
+ else
+ {
+ JITDUMP("MorphDynamicBlock: DYN_BLK with non-const size can't be morphed:\n");
+ return dynBlock;
+ }
+}
+
class MorphCopyBlockHelper : public MorphInitBlockHelper
{
public:
@@ -692,7 +745,7 @@ void MorphCopyBlockHelper::MorphStructCases()
if (m_dstVarDsc != nullptr)
{
- if (m_dstVarDsc->lvPromoted)
+ if (m_dstVarDsc->lvPromoted && m_blockSizeIsConst)
{
noway_assert(varTypeIsStruct(m_dstVarDsc));
noway_assert(!m_comp->opts.MinOpts());
@@ -712,7 +765,7 @@ void MorphCopyBlockHelper::MorphStructCases()
if (m_srcVarDsc != nullptr)
{
- if (m_srcVarDsc->lvPromoted)
+ if (m_srcVarDsc->lvPromoted && m_blockSizeIsConst)
{
noway_assert(varTypeIsStruct(m_srcVarDsc));
noway_assert(!m_comp->opts.MinOpts());
@@ -859,7 +912,7 @@ void MorphCopyBlockHelper::MorphStructCases()
// [000085] -A---------- = long
// [000083] D------N---- lclVar long V17 tmp9
//
- if ((m_dstVarDsc->lvFieldCnt == 1) && (m_srcVarDsc != nullptr) &&
+ if (m_blockSizeIsConst && (m_dstVarDsc->lvFieldCnt == 1) && (m_srcVarDsc != nullptr) &&
(m_blockSize == genTypeSize(m_srcVarDsc->TypeGet())))
{
// Reject the following tree:
@@ -897,7 +950,7 @@ void MorphCopyBlockHelper::MorphStructCases()
// [000243] -----+------ \--* addr byref
// [000242] D----+-N---- \--* lclVar byref V28 tmp19
//
- if ((m_srcVarDsc->lvFieldCnt == 1) && (m_dstVarDsc != nullptr) &&
+ if (m_blockSizeIsConst && (m_srcVarDsc->lvFieldCnt == 1) && (m_dstVarDsc != nullptr) &&
(m_blockSize == genTypeSize(m_dstVarDsc->TypeGet())))
{
// Check for type agreement
@@ -995,9 +1048,9 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField()
{
GenTreeOp* asgFields = nullptr;
- GenTree* addrSpill = nullptr;
- unsigned addrSpillSrcLclNum = BAD_VAR_NUM;
- unsigned addrSpillTemp = BAD_VAR_NUM;
+ GenTree* addrSpill = nullptr;
+ unsigned addrSpillTemp = BAD_VAR_NUM;
+ bool addrSpillIsStackDest = false; // true if 'addrSpill' represents the address in our local stack frame
GenTree* addrSpillAsg = nullptr;
@@ -1042,8 +1095,7 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField()
// We will spill m_srcAddr (i.e. assign to a temp "BlockOp address local")
// no need to clone a new copy as it is only used once
//
- addrSpill = m_srcAddr; // addrSpill represents the 'm_srcAddr'
- addrSpillSrcLclNum = m_srcLclNum;
+ addrSpill = m_srcAddr; // addrSpill represents the 'm_srcAddr'
}
}
}
@@ -1092,13 +1144,28 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField()
// We will spill m_dstAddr (i.e. assign to a temp "BlockOp address local")
// no need to clone a new copy as it is only used once
//
- addrSpill = m_dstAddr; // addrSpill represents the 'm_dstAddr'
- addrSpillSrcLclNum = m_dstLclNum;
+ addrSpill = m_dstAddr; // addrSpill represents the 'm_dstAddr'
}
}
}
}
+ // TODO-CQ: this should be based on a more general
+ // "BaseAddress" method, that handles fields of structs, before or after
+ // morphing.
+ if ((addrSpill != nullptr) && addrSpill->OperIs(GT_ADDR))
+ {
+ GenTree* addrSpillOp = addrSpill->AsOp()->gtGetOp1();
+ if (addrSpillOp->IsLocal())
+ {
+ // We will *not* consider this to define the local, but rather have each individual field assign
+ // be a definition.
+ addrSpillOp->gtFlags &= ~(GTF_LIVENESS_MASK);
+ addrSpillIsStackDest = true; // addrSpill represents the address of LclVar[varNum] in our
+ // local stack frame
+ }
+ }
+
if (addrSpill != nullptr)
{
// 'addrSpill' is already morphed
@@ -1111,26 +1178,30 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField()
addrSpillDsc->lvType = TYP_BYREF;
- if (addrSpillSrcLclNum != BAD_VAR_NUM)
+ if (addrSpillIsStackDest)
{
- // addrSpill represents the address of LclVar[varNum] in our local stack frame.
addrSpillDsc->lvStackByref = true;
}
GenTreeLclVar* addrSpillNode = m_comp->gtNewLclvNode(addrSpillTemp, TYP_BYREF);
addrSpillAsg = m_comp->gtNewAssignNode(addrSpillNode, addrSpill);
- // If we are assigning the address of a LclVar here liveness will not
- // account for this kind of address taken use. Mark the local as
- // address-exposed so that we don't do illegal optimizations with it.
+ // If we are assigning the address of a LclVar here
+ // liveness does not account for this kind of address taken use.
//
- // TODO-CQ: usage of "addrSpill" for local addresses is a workaround
- // for cases where we fail to use LCL_FLD nodes instead. Fix them and
- // delete this code.
+ // We have to mark this local as address exposed so
+ // that we don't delete the definition for this LclVar
+ // as a dead store later on.
//
- if (addrSpillSrcLclNum != BAD_VAR_NUM)
+ if (addrSpill->OperGet() == GT_ADDR)
{
- m_comp->lvaSetVarAddrExposed(addrSpillSrcLclNum DEBUGARG(AddressExposedReason::COPY_FLD_BY_FLD));
+ GenTree* addrOp = addrSpill->AsOp()->gtOp1;
+ if (addrOp->IsLocal())
+ {
+ unsigned lclVarNum = addrOp->AsLclVarCommon()->GetLclNum();
+ m_comp->lvaGetDesc(lclVarNum)->SetAddressExposed(true DEBUGARG(AddressExposedReason::COPY_FLD_BY_FLD));
+ m_comp->lvaSetVarDoNotEnregister(lclVarNum DEBUGARG(DoNotEnregisterReason::AddrExposed));
+ }
}
}
@@ -1138,6 +1209,7 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField()
// So, beyond this point we cannot rely on the old values of 'm_srcVarDsc' and 'm_dstVarDsc'.
for (unsigned i = 0; i < fieldCnt; ++i)
{
+
GenTree* dstFld;
if (m_dstDoFldAsg)
{
@@ -1206,7 +1278,7 @@ GenTree* MorphCopyBlockHelper::CopyFieldByField()
// Is the address of a local?
GenTreeLclVarCommon* lclVarTree = nullptr;
bool isEntire = false;
- bool* pIsEntire = &isEntire;
+ bool* pIsEntire = (m_blockSizeIsConst ? &isEntire : nullptr);
if (dstAddrClone->DefinesLocalAddr(m_comp, m_blockSize, &lclVarTree, pIsEntire))
{
lclVarTree->gtFlags |= GTF_VAR_DEF;
@@ -1479,50 +1551,3 @@ GenTree* Compiler::fgMorphInitBlock(GenTree* tree)
{
return MorphInitBlockHelper::MorphInitBlock(this, tree);
}
-
-//------------------------------------------------------------------------
-// fgMorphStoreDynBlock: Morph a dynamic block store (GT_STORE_DYN_BLK).
-//
-// Performs full (pre-order and post-order) morphing for a STORE_DYN_BLK.
-//
-// Arguments:
-// tree - The GT_STORE_DYN_BLK tree to morph.
-//
-// Return Value:
-// In case the size turns into a constant - the store, transformed
-// into an "ordinary" ASG(BLK, Data()) one, and further morphed by
-// "fgMorphInitBlock"/"fgMorphCopyBlock". Otherwise, the original
-// tree (fully morphed).
-//
-GenTree* Compiler::fgMorphStoreDynBlock(GenTreeStoreDynBlk* tree)
-{
- tree->Addr() = fgMorphTree(tree->Addr());
- tree->Data() = fgMorphTree(tree->Data());
- tree->gtDynamicSize = fgMorphTree(tree->gtDynamicSize);
-
- if (tree->gtDynamicSize->IsIntegralConst())
- {
- int64_t size = tree->gtDynamicSize->AsIntConCommon()->IntegralValue();
- assert(FitsIn(size));
-
- if (size != 0)
- {
- GenTree* lhs = gtNewBlockVal(tree->Addr(), static_cast(size));
- lhs->SetIndirExceptionFlags(this);
-
- GenTree* asg = gtNewAssignNode(lhs, tree->Data());
- asg->gtFlags |= (tree->gtFlags & (GTF_ALL_EFFECT | GTF_BLK_VOLATILE | GTF_BLK_UNALIGNED));
- INDEBUG(asg->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
-
- JITDUMP("MorphStoreDynBlock: trasformed STORE_DYN_BLK into ASG(BLK, Data())\n");
-
- return tree->OperIsCopyBlkOp() ? fgMorphCopyBlock(asg) : fgMorphInitBlock(asg);
- }
- }
-
- tree->SetAllEffectsFlags(tree->Addr(), tree->Data(), tree->gtDynamicSize);
- tree->SetIndirExceptionFlags(this);
- tree->gtFlags |= GTF_ASG;
-
- return tree;
-}
diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h
index 68ea721ae4818..25733a41a9c9e 100644
--- a/src/coreclr/jit/namedintrinsiclist.h
+++ b/src/coreclr/jit/namedintrinsiclist.h
@@ -4,10 +4,7 @@
#ifndef _NAMEDINTRINSICLIST_H_
#define _NAMEDINTRINSICLIST_H_
-// Named jit intrinsics.
-
-// When adding a new intrinsic that will use the GT_INTRINSIC node and can throw, make sure
-// to update the "OperMayThrow" and "fgValueNumberAddExceptionSet" methods to account for that.
+// Named jit intrinsics
enum NamedIntrinsic : unsigned short
{
@@ -81,7 +78,6 @@ enum NamedIntrinsic : unsigned short
NI_System_Runtime_CompilerServices_RuntimeHelpers_CreateSpan,
NI_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray,
- NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant,
NI_System_String_get_Chars,
NI_System_String_get_Length,
diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp
index 108fde7e98497..f16fb917a589d 100644
--- a/src/coreclr/jit/optcse.cpp
+++ b/src/coreclr/jit/optcse.cpp
@@ -829,8 +829,7 @@ bool Compiler::optValnumCSE_Locate()
continue;
}
- ValueNum valueVN = vnStore->VNNormalValue(tree->GetVN(VNK_Liberal));
- if (ValueNumStore::isReservedVN(valueVN) && (valueVN != ValueNumStore::VNForNull()))
+ if (ValueNumStore::isReservedVN(tree->GetVN(VNK_Liberal)))
{
continue;
}
@@ -2599,18 +2598,17 @@ class CSE_Heuristic
cse_use_cost *= slotCount;
}
- // If this CSE is live across a call then we may have additional costs
+ // If this CSE is live across a call then we may need to spill an additional caller save register
//
if (candidate->LiveAcrossCall())
{
- // If we have a floating-point CSE that is both live across a call and there
- // are no callee-saved FP registers available, the RA will have to spill at
- // the def site and reload at the (first) use site, if the variable is a register
- // candidate. Account for that.
- if (varTypeIsFloating(candidate->Expr()) && (CNT_CALLEE_SAVED_FLOAT == 0) && !candidate->IsConservative())
+ if (candidate->Expr()->IsCnsFltOrDbl() && (CNT_CALLEE_SAVED_FLOAT == 0) &&
+ (candidate->CseDsc()->csdUseWtCnt <= 4))
{
- cse_def_cost += 1;
- cse_use_cost += 1;
+ // Floating point constants are expected to be contained, so unless there are more than 4 uses
+ // we better not to CSE them, especially on platforms without callee-saved registers
+ // for values living across calls
+ return false;
}
// If we don't have a lot of variables to enregister or we have a floating point type
diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp
index dd2f3a8246ede..2d3aedc94ba0a 100644
--- a/src/coreclr/jit/optimizer.cpp
+++ b/src/coreclr/jit/optimizer.cpp
@@ -302,7 +302,7 @@ void Compiler::optUnmarkLoopBlocks(BasicBlock* begBlk, BasicBlock* endBlk)
}
// We only consider back-edges that are BBJ_COND or BBJ_ALWAYS for loops.
- if (!predBlock->KindIs(BBJ_COND, BBJ_ALWAYS))
+ if ((predBlock->bbJumpKind != BBJ_COND) && (predBlock->bbJumpKind != BBJ_ALWAYS))
{
continue;
}
@@ -402,14 +402,16 @@ void Compiler::optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmar
bool removeLoop = false;
- // If an unreachable block is a loop entry or bottom then the loop is unreachable.
- // Special case: the block was the head of a loop - or pointing to a loop entry.
+ /* If an unreachable block was part of a loop entry or bottom then the loop is unreachable */
+ /* Special case: the block was the head of a loop - or pointing to a loop entry */
for (unsigned loopNum = 0; loopNum < optLoopCount; loopNum++)
{
LoopDsc& loop = optLoopTable[loopNum];
- // Some loops may have been already removed by loop unrolling or conditional folding.
+ /* Some loops may have been already removed by
+ * loop unrolling or conditional folding */
+
if (loop.lpFlags & LPFLG_REMOVED)
{
continue;
@@ -452,9 +454,11 @@ void Compiler::optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmar
continue;
}
- // If the loop is still in the table any block in the loop must be reachable.
+ /* If the loop is still in the table
+ * any block in the loop must be reachable !!! */
- noway_assert((loop.lpEntry != block) && (loop.lpBottom != block));
+ noway_assert(loop.lpEntry != block);
+ noway_assert(loop.lpBottom != block);
if (loop.lpExit == block)
{
@@ -464,26 +468,27 @@ void Compiler::optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmar
loop.lpExit = nullptr;
}
- // If `block` flows to the loop entry then the whole loop will become unreachable if it is the
- // only non-loop predecessor.
+ /* If this points to the actual entry in the loop
+ * then the whole loop may become unreachable */
switch (block->bbJumpKind)
{
case BBJ_NONE:
+ case BBJ_COND:
if (block->bbNext == loop.lpEntry)
{
removeLoop = true;
+ break;
}
- break;
-
- case BBJ_COND:
- if ((block->bbNext == loop.lpEntry) || (block->bbJumpDest == loop.lpEntry))
+ if (block->bbJumpKind == BBJ_NONE)
{
- removeLoop = true;
+ break;
}
- break;
+
+ FALLTHROUGH;
case BBJ_ALWAYS:
+ noway_assert(block->bbJumpDest);
if (block->bbJumpDest == loop.lpEntry)
{
removeLoop = true;
@@ -507,12 +512,13 @@ void Compiler::optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmar
if (removeLoop)
{
- // Check if the entry has other predecessors outside the loop.
- // TODO: Replace this when predecessors are available.
+ /* Check if the entry has other predecessors outside the loop
+ * TODO: Replace this when predecessors are available */
for (BasicBlock* const auxBlock : Blocks())
{
- // Ignore blocks in the loop.
+ /* Ignore blocks in the loop */
+
if (loop.lpContains(auxBlock))
{
continue;
@@ -521,20 +527,21 @@ void Compiler::optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmar
switch (auxBlock->bbJumpKind)
{
case BBJ_NONE:
+ case BBJ_COND:
if (auxBlock->bbNext == loop.lpEntry)
{
removeLoop = false;
+ break;
}
- break;
-
- case BBJ_COND:
- if ((auxBlock->bbNext == loop.lpEntry) || (auxBlock->bbJumpDest == loop.lpEntry))
+ if (auxBlock->bbJumpKind == BBJ_NONE)
{
- removeLoop = false;
+ break;
}
- break;
+
+ FALLTHROUGH;
case BBJ_ALWAYS:
+ noway_assert(auxBlock->bbJumpDest);
if (auxBlock->bbJumpDest == loop.lpEntry)
{
removeLoop = false;
@@ -573,39 +580,18 @@ void Compiler::optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmar
reportAfter();
}
- if ((skipUnmarkLoop == false) && //
- block->KindIs(BBJ_ALWAYS, BBJ_COND) && //
- block->bbJumpDest->isLoopHead() && //
- (block->bbJumpDest->bbNum <= block->bbNum) && //
- fgDomsComputed && //
- (fgCurBBEpochSize == fgDomBBcount + 1) && //
+ if ((skipUnmarkLoop == false) && //
+ ((block->bbJumpKind == BBJ_ALWAYS) || (block->bbJumpKind == BBJ_COND)) && //
+ block->bbJumpDest->isLoopHead() && //
+ (block->bbJumpDest->bbNum <= block->bbNum) && //
+ fgDomsComputed && //
+ (fgCurBBEpochSize == fgDomBBcount + 1) && //
fgReachable(block->bbJumpDest, block))
{
optUnmarkLoopBlocks(block->bbJumpDest, block);
}
}
-//------------------------------------------------------------------------
-// optClearLoopIterInfo: Clear the info related to LPFLG_ITER loops in the loop table.
-// The various fields related to iterators is known to be valid for loop cloning and unrolling,
-// but becomes invalid afterwards. Clear the info that might be used incorrectly afterwards
-// in JitDump or by subsequent phases.
-//
-void Compiler::optClearLoopIterInfo()
-{
- for (unsigned lnum = 0; lnum < optLoopCount; lnum++)
- {
- LoopDsc& loop = optLoopTable[lnum];
- loop.lpFlags &= ~(LPFLG_ITER | LPFLG_VAR_INIT | LPFLG_CONST_INIT | LPFLG_SIMD_LIMIT | LPFLG_VAR_LIMIT |
- LPFLG_CONST_LIMIT | LPFLG_ARRLEN_LIMIT);
-
- loop.lpIterTree = nullptr;
- loop.lpInitBlock = nullptr;
- loop.lpConstInit = -1; // union with loop.lpVarInit
- loop.lpTestTree = nullptr;
- }
-}
-
#ifdef DEBUG
/*****************************************************************************
@@ -1699,7 +1685,9 @@ class LoopSearch
return false;
}
- if (bottom->KindIs(BBJ_EHFINALLYRET, BBJ_EHFILTERRET, BBJ_EHCATCHRET, BBJ_CALLFINALLY, BBJ_SWITCH))
+ if ((bottom->bbJumpKind == BBJ_EHFINALLYRET) || (bottom->bbJumpKind == BBJ_EHFILTERRET) ||
+ (bottom->bbJumpKind == BBJ_EHCATCHRET) || (bottom->bbJumpKind == BBJ_CALLFINALLY) ||
+ (bottom->bbJumpKind == BBJ_SWITCH))
{
// BBJ_EHFINALLYRET, BBJ_EHFILTERRET, BBJ_EHCATCHRET, and BBJ_CALLFINALLY can never form a loop.
// BBJ_SWITCH that has a backward jump appears only for labeled break.
@@ -1841,7 +1829,7 @@ class LoopSearch
}
}
// Can we fall through into the loop?
- else if (head->KindIs(BBJ_NONE, BBJ_COND))
+ else if (head->bbJumpKind == BBJ_NONE || head->bbJumpKind == BBJ_COND)
{
// The ENTRY is at the TOP (a do-while loop)
return top;
@@ -2151,7 +2139,7 @@ class LoopSearch
return nullptr;
}
- if (newMoveAfter->KindIs(BBJ_ALWAYS, BBJ_COND))
+ if ((newMoveAfter->bbJumpKind == BBJ_ALWAYS) || (newMoveAfter->bbJumpKind == BBJ_COND))
{
unsigned int destNum = newMoveAfter->bbJumpDest->bbNum;
if ((destNum >= top->bbNum) && (destNum <= bottom->bbNum) && !loopBlocks.IsMember(destNum))
@@ -2341,8 +2329,8 @@ class LoopSearch
}
// Make sure we don't leave around a goto-next unless it's marked KEEP_BBJ_ALWAYS.
- assert(!block->KindIs(BBJ_COND, BBJ_ALWAYS) || (block->bbJumpDest != newNext) ||
- ((block->bbFlags & BBF_KEEP_BBJ_ALWAYS) != 0));
+ assert(((block->bbJumpKind != BBJ_COND) && (block->bbJumpKind != BBJ_ALWAYS)) ||
+ (block->bbJumpDest != newNext) || ((block->bbFlags & BBF_KEEP_BBJ_ALWAYS) != 0));
return newBlock;
}
@@ -7586,8 +7574,6 @@ void Compiler::fgCreateLoopPreHeader(unsigned lnum)
fgAddRefPred(preHead, predBlock);
}
} while (++jumpTab, --jumpCnt);
-
- UpdateSwitchTableTarget(predBlock, entry, preHead);
break;
default:
@@ -7864,16 +7850,24 @@ bool Compiler::optComputeLoopSideEffectsOfBlock(BasicBlock* blk)
}
else
{
- GenTree* baseAddr = nullptr;
- FieldSeqNode* fldSeq = nullptr;
- if (arg->IsFieldAddr(this, &baseAddr, &fldSeq))
+ // We are only interested in IsFieldAddr()'s fldSeq out parameter.
+ //
+ GenTree* obj = nullptr; // unused
+ GenTree* staticOffset = nullptr; // unused
+ FieldSeqNode* fldSeq = nullptr;
+
+ if (arg->IsFieldAddr(this, &obj, &staticOffset, &fldSeq) &&
+ (fldSeq != FieldSeqStore::NotAField()))
{
- assert((fldSeq != nullptr) && (fldSeq != FieldSeqStore::NotAField()) &&
- !fldSeq->IsPseudoField());
+ // Get the first (object) field from field seq. GcHeap[field] will yield the "field map".
+ assert(fldSeq != nullptr);
+ if (fldSeq->IsFirstElemFieldSeq())
+ {
+ fldSeq = fldSeq->m_next;
+ assert(fldSeq != nullptr);
+ }
- FieldKindForVN fieldKind =
- (baseAddr != nullptr) ? FieldKindForVN::WithBaseAddr : FieldKindForVN::SimpleStatic;
- AddModifiedFieldAllContainingLoops(mostNestedLoop, fldSeq->GetFieldHandle(), fieldKind);
+ AddModifiedFieldAllContainingLoops(mostNestedLoop, fldSeq->m_fieldHnd);
// Conservatively assume byrefs may alias this object.
memoryHavoc |= memoryKindSet(ByrefExposed);
}
@@ -7899,8 +7893,7 @@ bool Compiler::optComputeLoopSideEffectsOfBlock(BasicBlock* blk)
}
else if (lhs->OperGet() == GT_CLS_VAR)
{
- AddModifiedFieldAllContainingLoops(mostNestedLoop, lhs->AsClsVar()->gtClsVarHnd,
- FieldKindForVN::SimpleStatic);
+ AddModifiedFieldAllContainingLoops(mostNestedLoop, lhs->AsClsVar()->gtClsVarHnd);
// Conservatively assume byrefs may alias this static field
memoryHavoc |= memoryKindSet(ByrefExposed);
}
@@ -7979,7 +7972,6 @@ bool Compiler::optComputeLoopSideEffectsOfBlock(BasicBlock* blk)
case GT_XCHG:
case GT_CMPXCHG:
case GT_MEMORYBARRIER:
- case GT_STORE_DYN_BLK:
{
memoryHavoc |= memoryKindSet(GcHeap, ByrefExposed);
}
@@ -8081,12 +8073,12 @@ void Compiler::AddVariableLivenessAllContainingLoops(unsigned lnum, BasicBlock*
}
// Adds "fldHnd" to the set of modified fields of "lnum" and any parent loops.
-void Compiler::AddModifiedFieldAllContainingLoops(unsigned lnum, CORINFO_FIELD_HANDLE fldHnd, FieldKindForVN fieldKind)
+void Compiler::AddModifiedFieldAllContainingLoops(unsigned lnum, CORINFO_FIELD_HANDLE fldHnd)
{
assert(0 <= lnum && lnum < optLoopCount);
while (lnum != BasicBlock::NOT_IN_LOOP)
{
- optLoopTable[lnum].AddModifiedField(this, fldHnd, fieldKind);
+ optLoopTable[lnum].AddModifiedField(this, fldHnd);
lnum = optLoopTable[lnum].lpParent;
}
}
diff --git a/src/coreclr/jit/phase.cpp b/src/coreclr/jit/phase.cpp
index 5f2e2172c6f4a..f08134bf11532 100644
--- a/src/coreclr/jit/phase.cpp
+++ b/src/coreclr/jit/phase.cpp
@@ -141,8 +141,6 @@ void Phase::PrePhase()
//
void Phase::PostPhase(PhaseStatus status)
{
- comp->EndPhase(m_phase);
-
#ifdef DEBUG
// Don't dump or check post phase unless the phase made changes.
@@ -164,33 +162,16 @@ void Phase::PostPhase(PhaseStatus status)
// well as the new-style phases that have been updated to return
// PhaseStatus from their DoPhase methods.
//
- // clang-format off
-
- static Phases s_allowlist[] = {
- PHASE_INCPROFILE,
- PHASE_IBCPREP,
- PHASE_IMPORTATION,
- PHASE_PATCHPOINTS,
- PHASE_IBCINSTR,
- PHASE_INDXCALL,
- PHASE_MORPH_INLINE,
- PHASE_ALLOCATE_OBJECTS,
- PHASE_EMPTY_TRY,
- PHASE_EMPTY_FINALLY,
- PHASE_MERGE_FINALLY_CHAINS,
- PHASE_CLONE_FINALLY,
- PHASE_MERGE_THROWS,
- PHASE_MORPH_GLOBAL,
- PHASE_INVERT_LOOPS,
- PHASE_OPTIMIZE_LAYOUT,
- PHASE_FIND_LOOPS,
- PHASE_BUILD_SSA,
- PHASE_INSERT_GC_POLLS,
- PHASE_RATIONALIZE,
- PHASE_LOWERING,
- PHASE_STACK_LEVEL_SETTER};
-
- // clang-format on
+ static Phases s_allowlist[] = {PHASE_IMPORTATION, PHASE_IBCINSTR,
+ PHASE_IBCPREP, PHASE_INCPROFILE,
+ PHASE_INDXCALL, PHASE_MORPH_INLINE,
+ PHASE_ALLOCATE_OBJECTS, PHASE_EMPTY_TRY,
+ PHASE_EMPTY_FINALLY, PHASE_MERGE_FINALLY_CHAINS,
+ PHASE_CLONE_FINALLY, PHASE_MERGE_THROWS,
+ PHASE_MORPH_GLOBAL, PHASE_INVERT_LOOPS,
+ PHASE_OPTIMIZE_LAYOUT, PHASE_FIND_LOOPS,
+ PHASE_BUILD_SSA, PHASE_RATIONALIZE,
+ PHASE_LOWERING, PHASE_STACK_LEVEL_SETTER};
if (madeChanges)
{
@@ -253,4 +234,6 @@ void Phase::PostPhase(PhaseStatus status)
#if DUMP_FLOWGRAPHS
comp->fgDumpFlowGraph(m_phase, Compiler::PhasePosition::PostPhase);
#endif // DUMP_FLOWGRAPHS
+
+ comp->EndPhase(m_phase);
}
diff --git a/src/coreclr/jit/rangecheck.cpp b/src/coreclr/jit/rangecheck.cpp
index 56ad0323fd6de..4a475806148b7 100644
--- a/src/coreclr/jit/rangecheck.cpp
+++ b/src/coreclr/jit/rangecheck.cpp
@@ -869,7 +869,7 @@ void RangeCheck::MergeAssertion(BasicBlock* block, GenTree* op, Range* pRange DE
JITDUMP("Merge assertions from pred " FMT_BB " edge: ", pred->bbNum);
Compiler::optDumpAssertionIndices(assertions, "\n");
}
- else if (pred->KindIs(BBJ_COND, BBJ_ALWAYS) && (pred->bbJumpDest == block))
+ else if ((pred->bbJumpKind == BBJ_COND || pred->bbJumpKind == BBJ_ALWAYS) && pred->bbJumpDest == block)
{
if (m_pCompiler->bbJtrueAssertionOut != nullptr)
{
diff --git a/src/coreclr/jit/rationalize.cpp b/src/coreclr/jit/rationalize.cpp
index 72c1591c6d425..5e54ca8bd94d4 100644
--- a/src/coreclr/jit/rationalize.cpp
+++ b/src/coreclr/jit/rationalize.cpp
@@ -416,10 +416,13 @@ void Rationalizer::RewriteAssignment(LIR::Use& use)
}
GenTreeSIMD* simdTree =
comp->gtNewSIMDNode(simdType, initVal, SIMDIntrinsicInit, simdBaseJitType, genTypeSize(simdType));
- assignment->gtOp2 = simdTree;
- value = simdTree;
+ assignment->AsOp()->gtOp2 = simdTree;
+ value = simdTree;
+ initVal->gtNext = simdTree;
+ simdTree->gtPrev = initVal;
- BlockRange().InsertAfter(initVal, simdTree);
+ simdTree->gtNext = location;
+ location->gtPrev = simdTree;
}
}
#endif // FEATURE_SIMD
@@ -465,6 +468,7 @@ void Rationalizer::RewriteAssignment(LIR::Use& use)
case GT_BLK:
case GT_OBJ:
+ case GT_DYN_BLK:
{
assert(varTypeIsStruct(location));
GenTreeBlk* storeBlk = location->AsBlk();
@@ -477,6 +481,9 @@ void Rationalizer::RewriteAssignment(LIR::Use& use)
case GT_OBJ:
storeOper = GT_STORE_OBJ;
break;
+ case GT_DYN_BLK:
+ storeOper = GT_STORE_DYN_BLK;
+ break;
default:
unreached();
}
diff --git a/src/coreclr/jit/ssabuilder.cpp b/src/coreclr/jit/ssabuilder.cpp
index 48fe4d84d9aec..4646769263d37 100644
--- a/src/coreclr/jit/ssabuilder.cpp
+++ b/src/coreclr/jit/ssabuilder.cpp
@@ -732,7 +732,7 @@ void SsaBuilder::RenameDef(GenTreeOp* asgNode, BasicBlock* block)
// This is perhaps temporary -- maybe should be done elsewhere. Label GT_INDs on LHS of assignments, so we
// can skip these during (at least) value numbering.
GenTree* lhs = asgNode->gtGetOp1()->gtEffectiveVal(/*commaOnly*/ true);
- if (lhs->OperIs(GT_IND, GT_OBJ, GT_BLK))
+ if (lhs->OperIs(GT_IND, GT_OBJ, GT_BLK, GT_DYN_BLK))
{
lhs->gtFlags |= GTF_IND_ASG_LHS;
}
diff --git a/src/coreclr/jit/targetarm64.h b/src/coreclr/jit/targetarm64.h
index 4cc6b63f73009..cdab21582ffce 100644
--- a/src/coreclr/jit/targetarm64.h
+++ b/src/coreclr/jit/targetarm64.h
@@ -11,10 +11,8 @@
#define ROUND_FLOAT 0 // Do not round intermed float expression results
#define CPU_HAS_BYTE_REGS 0
- #define CPBLK_UNROLL_LIMIT 64 // Upper bound to let the code generator to loop unroll CpBlk
- #define CPBLK_LCL_UNROLL_LIMIT 128 // Upper bound to let the code generator to loop unroll CpBlk (when both srcAddr and dstAddr point to the stack)
- #define INITBLK_UNROLL_LIMIT 64 // Upper bound to let the code generator to loop unroll InitBlk
- #define INITBLK_LCL_UNROLL_LIMIT 128 // Upper bound to let the code generator to loop unroll InitBlk (when dstAddr points to the stack)
+ #define CPBLK_UNROLL_LIMIT 64 // Upper bound to let the code generator to loop unroll CpBlk.
+ #define INITBLK_UNROLL_LIMIT 64 // Upper bound to let the code generator to loop unroll InitBlk.
#ifdef FEATURE_SIMD
#define ALIGN_SIMD_TYPES 1 // whether SIMD type locals are to be aligned
diff --git a/src/coreclr/jit/typeinfo.cpp b/src/coreclr/jit/typeinfo.cpp
index 6bc69965d097b..07809e57268a2 100644
--- a/src/coreclr/jit/typeinfo.cpp
+++ b/src/coreclr/jit/typeinfo.cpp
@@ -20,7 +20,32 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
bool Compiler::tiCompatibleWith(const typeInfo& child, const typeInfo& parent, bool normalisedForStack) const
{
- return typeInfo::tiCompatibleWith(info.compCompHnd, child, parent, normalisedForStack);
+#ifdef DEBUG
+#if VERBOSE_VERIFY
+ if (VERBOSE && tiVerificationNeeded)
+ {
+ printf("\n");
+ printf(TI_DUMP_PADDING);
+ printf("Verifying compatibility against types: ");
+ child.Dump();
+ printf(" and ");
+ parent.Dump();
+ }
+#endif // VERBOSE_VERIFY
+#endif // DEBUG
+
+ bool compatible = typeInfo::tiCompatibleWith(info.compCompHnd, child, parent, normalisedForStack);
+
+#ifdef DEBUG
+#if VERBOSE_VERIFY
+ if (VERBOSE && tiVerificationNeeded)
+ {
+ printf(compatible ? " [YES]" : " [NO]");
+ }
+#endif // VERBOSE_VERIFY
+#endif // DEBUG
+
+ return compatible;
}
bool Compiler::tiMergeCompatibleWith(const typeInfo& child, const typeInfo& parent, bool normalisedForStack) const
@@ -30,7 +55,41 @@ bool Compiler::tiMergeCompatibleWith(const typeInfo& child, const typeInfo& pare
bool Compiler::tiMergeToCommonParent(typeInfo* pDest, const typeInfo* pSrc, bool* changed) const
{
- return typeInfo::tiMergeToCommonParent(info.compCompHnd, pDest, pSrc, changed);
+#ifdef DEBUG
+#if VERBOSE_VERIFY
+ if (VERBOSE && tiVerificationNeeded)
+ {
+ printf("\n");
+ printf(TI_DUMP_PADDING);
+ printf("Attempting to merge types: ");
+ pDest->Dump();
+ printf(" and ");
+ pSrc->Dump();
+ printf("\n");
+ }
+#endif // VERBOSE_VERIFY
+#endif // DEBUG
+
+ bool mergeable = typeInfo::tiMergeToCommonParent(info.compCompHnd, pDest, pSrc, changed);
+
+#ifdef DEBUG
+#if VERBOSE_VERIFY
+ if (VERBOSE && tiVerificationNeeded)
+ {
+ printf(TI_DUMP_PADDING);
+ printf(mergeable ? "Merge successful" : "Couldn't merge types");
+ if (*changed)
+ {
+ assert(mergeable);
+ printf(", destination type changed to: ");
+ pDest->Dump();
+ }
+ printf("\n");
+ }
+#endif // VERBOSE_VERIFY
+#endif // DEBUG
+
+ return mergeable;
}
static bool tiCompatibleWithByRef(COMP_HANDLE CompHnd, const typeInfo& child, const typeInfo& parent)
diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp
index 947f774fbdac0..1c4341e147009 100644
--- a/src/coreclr/jit/valuenum.cpp
+++ b/src/coreclr/jit/valuenum.cpp
@@ -1266,17 +1266,6 @@ bool ValueNumStore::VNExcIsSubset(ValueNum vnFullSet, ValueNum vnCandidateSet)
}
}
-//----------------------------------------------------------------------------------------
-// VNPExcIsSubset - Given two exception sets, returns true when both the liberal and
-// conservative value numbers of vnpCandidateSet represent subsets of
-// the corresponding numbers in vnpFullSet (see VNExcIsSubset).
-//
-bool ValueNumStore::VNPExcIsSubset(ValueNumPair vnpFullSet, ValueNumPair vnpCandidateSet)
-{
- return VNExcIsSubset(vnpFullSet.GetLiberal(), vnpCandidateSet.GetLiberal()) &&
- VNExcIsSubset(vnpFullSet.GetConservative(), vnpCandidateSet.GetConservative());
-}
-
//-------------------------------------------------------------------------------------
// VNUnpackExc: - Given a ValueNum 'vnWx, return via write back parameters both
// the normal and the exception set components.
@@ -1434,64 +1423,6 @@ ValueNumPair ValueNumStore::VNPMakeNormalUniquePair(ValueNumPair vnp)
return ValueNumPair(VNMakeNormalUnique(vnp.GetLiberal()), VNMakeNormalUnique(vnp.GetConservative()));
}
-//------------------------------------------------------------------------------------
-// VNUniqueWithExc:
-//
-// Arguments:
-// type - The type for the unique Value Number
-// vnExcSet - The Value Number for the exception set.
-//
-// Return Value:
-// - VN representing a "new, unique" value, with
-// the exceptions contained in "vnExcSet".
-//
-ValueNum ValueNumStore::VNUniqueWithExc(var_types type, ValueNum vnExcSet)
-{
- ValueNum normVN = VNForExpr(m_pComp->compCurBB, type);
-
- if (vnExcSet == VNForEmptyExcSet())
- {
- return normVN;
- }
-
-#ifdef DEBUG
- VNFuncApp excSetFunc;
- assert(GetVNFunc(vnExcSet, &excSetFunc) && (excSetFunc.m_func == VNF_ExcSetCons));
-#endif // DEBUG
-
- return VNWithExc(normVN, vnExcSet);
-}
-
-//------------------------------------------------------------------------------------
-// VNPUniqueWithExc:
-//
-// Arguments:
-// type - The type for the unique Value Numbers
-// vnExcSet - The Value Number Pair for the exception set.
-//
-// Return Value:
-// - VN Pair representing a "new, unique" value (liberal and conservative
-// values will be equal), with the exceptions contained in "vnpExcSet".
-//
-// Notes: - We use the same unique value number both for liberal and conservative
-// portions of the pair to save memory (it would not be useful to make
-// them different).
-//
-ValueNumPair ValueNumStore::VNPUniqueWithExc(var_types type, ValueNumPair vnpExcSet)
-{
-#ifdef DEBUG
- VNFuncApp excSetFunc;
- assert((GetVNFunc(vnpExcSet.GetLiberal(), &excSetFunc) && (excSetFunc.m_func == VNF_ExcSetCons)) ||
- (vnpExcSet.GetLiberal() == VNForEmptyExcSet()));
- assert((GetVNFunc(vnpExcSet.GetConservative(), &excSetFunc) && (excSetFunc.m_func == VNF_ExcSetCons)) ||
- (vnpExcSet.GetConservative() == VNForEmptyExcSet()));
-#endif // DEBUG
-
- ValueNum normVN = VNForExpr(m_pComp->compCurBB, type);
-
- return VNPWithExc(ValueNumPair(normVN, normVN), vnpExcSet);
-}
-
//--------------------------------------------------------------------------------
// VNNormalValue: - Returns a Value Number that represents the result for the
// normal (non-exceptional) evaluation for the expression.
@@ -4407,21 +4338,21 @@ ValueNum Compiler::fgValueNumberArrIndexAssign(CORINFO_CLASS_HANDLE elemTypeEq,
return vnStore->VNForMapStore(fgCurMemoryVN[GcHeap], elemTypeEqVN, newValAtArrType);
}
-ValueNum Compiler::fgValueNumberArrIndexVal(GenTree* tree, VNFuncApp* pFuncApp, ValueNumPair addrXvnp)
+ValueNum Compiler::fgValueNumberArrIndexVal(GenTree* tree, VNFuncApp* pFuncApp, ValueNum addrXvn)
{
assert(vnStore->IsVNHandle(pFuncApp->m_args[0]));
CORINFO_CLASS_HANDLE arrElemTypeEQ = CORINFO_CLASS_HANDLE(vnStore->ConstantValue(pFuncApp->m_args[0]));
ValueNum arrVN = pFuncApp->m_args[1];
ValueNum inxVN = pFuncApp->m_args[2];
FieldSeqNode* fldSeq = vnStore->FieldSeqVNToFieldSeq(pFuncApp->m_args[3]);
- return fgValueNumberArrIndexVal(tree, arrElemTypeEQ, arrVN, inxVN, addrXvnp, fldSeq);
+ return fgValueNumberArrIndexVal(tree, arrElemTypeEQ, arrVN, inxVN, addrXvn, fldSeq);
}
ValueNum Compiler::fgValueNumberArrIndexVal(GenTree* tree,
CORINFO_CLASS_HANDLE elemTypeEq,
ValueNum arrVN,
ValueNum inxVN,
- ValueNumPair addrXvnp,
+ ValueNum excVN,
FieldSeqNode* fldSeq)
{
assert(tree == nullptr || tree->OperIsIndir());
@@ -4441,7 +4372,7 @@ ValueNum Compiler::fgValueNumberArrIndexVal(GenTree* tree,
JITDUMP(" *** Not a proper arrray access encountered in fgValueNumberArrIndexVal\n");
// a new unique value number
- selectedElem = vnStore->VNForExpr(compCurBB, indType);
+ selectedElem = vnStore->VNForExpr(compCurBB, elemTyp);
#ifdef DEBUG
if (verbose)
@@ -4452,7 +4383,7 @@ ValueNum Compiler::fgValueNumberArrIndexVal(GenTree* tree,
if (tree != nullptr)
{
- tree->gtVNPair = vnStore->VNPWithExc(ValueNumPair(selectedElem, selectedElem), addrXvnp);
+ tree->gtVNPair.SetBoth(selectedElem);
}
}
else
@@ -4491,7 +4422,7 @@ ValueNum Compiler::fgValueNumberArrIndexVal(GenTree* tree,
elemTyp = vnStore->TypeOfVN(selectedElem);
}
selectedElem = vnStore->VNApplySelectorsTypeCheck(selectedElem, indType, elemStructSize);
- selectedElem = vnStore->VNWithExc(selectedElem, addrXvnp.GetLiberal());
+ selectedElem = vnStore->VNWithExc(selectedElem, excVN);
#ifdef DEBUG
if (verbose && (selectedElem != wholeElem))
@@ -4503,7 +4434,10 @@ ValueNum Compiler::fgValueNumberArrIndexVal(GenTree* tree,
if (tree != nullptr)
{
tree->gtVNPair.SetLiberal(selectedElem);
- tree->gtVNPair.SetConservative(vnStore->VNUniqueWithExc(tree->TypeGet(), addrXvnp.GetConservative()));
+
+ // TODO-CQ: what to do here about exceptions? We don't have the array and ind conservative
+ // values, so we don't have their exceptions. Maybe we should.
+ tree->gtVNPair.SetConservative(vnStore->VNForExpr(compCurBB, tree->TypeGet()));
}
}
@@ -6018,7 +5952,8 @@ void ValueNumStore::vnDumpValWithExc(Compiler* comp, VNFuncApp* valWithExc)
GetVNFunc(excVN, &excSeq);
printf("norm=");
- comp->vnPrint(normVN, 1);
+ printf(FMT_VN, normVN);
+ vnDump(comp, normVN);
printf(", exc=");
printf(FMT_VN, excVN);
vnDumpExcSeq(comp, &excSeq, true);
@@ -6208,7 +6143,7 @@ void ValueNumStore::vnDumpZeroObj(Compiler* comp, VNFuncApp* zeroObj)
static UINT8 vnfOpAttribs[VNF_COUNT];
static genTreeOps genTreeOpsIllegalAsVNFunc[] = {GT_IND, // When we do heap memory.
GT_NULLCHECK, GT_QMARK, GT_COLON, GT_LOCKADD, GT_XADD, GT_XCHG,
- GT_CMPXCHG, GT_LCLHEAP, GT_BOX, GT_XORR, GT_XAND, GT_STORE_DYN_BLK,
+ GT_CMPXCHG, GT_LCLHEAP, GT_BOX, GT_XORR, GT_XAND,
// These need special semantics:
GT_COMMA, // == second argument (but with exception(s) from first).
@@ -6858,7 +6793,6 @@ void Compiler::fgValueNumber()
#ifdef DEBUG
JitTestCheckVN();
- fgDebugCheckExceptionSets();
#endif // DEBUG
fgVNPassesCompleted++;
@@ -6878,11 +6812,10 @@ void Compiler::fgValueNumberBlock(BasicBlock* blk)
assert(asg->OperIs(GT_ASG));
GenTreeLclVar* newSsaDef = asg->AsOp()->gtGetOp1()->AsLclVar();
- GenTreePhi* phiNode = asg->AsOp()->gtGetOp2()->AsPhi();
ValueNumPair phiVNP;
ValueNumPair sameVNP;
- for (GenTreePhi::Use& use : phiNode->Uses())
+ for (GenTreePhi::Use& use : asg->AsOp()->gtGetOp2()->AsPhi()->Uses())
{
GenTreePhiArg* phiArg = use.GetNode()->AsPhiArg();
ValueNum phiArgSsaNumVN = vnStore->VNForIntCon(phiArg->GetSsaNum());
@@ -6947,10 +6880,6 @@ void Compiler::fgValueNumberBlock(BasicBlock* blk)
printf(" %s.\n", sameVNP.BothDefined() ? "(all same)" : "");
}
#endif // DEBUG
-
- newSsaDef->gtVNPair = vnStore->VNPForVoid();
- phiNode->gtVNPair = newSsaDefVNP;
- asg->gtVNPair = vnStore->VNPForVoid();
}
// Now do the same for each MemoryKind.
@@ -7199,9 +7128,8 @@ ValueNum Compiler::fgMemoryVNForLoopSideEffects(MemoryKind memoryKind,
for (Compiler::LoopDsc::FieldHandleSet::KeyIterator ki = fieldsMod->Begin(); !ki.Equal(fieldsMod->End());
++ki)
{
- CORINFO_FIELD_HANDLE fldHnd = ki.Get();
- FieldKindForVN fieldKind = ki.GetValue();
- ValueNum fldHndVN = vnStore->VNForHandle(ssize_t(fldHnd), GTF_ICON_FIELD_HDL);
+ CORINFO_FIELD_HANDLE fldHnd = ki.Get();
+ ValueNum fldHndVN = vnStore->VNForHandle(ssize_t(fldHnd), GTF_ICON_FIELD_HDL);
#ifdef DEBUG
if (verbose)
@@ -7212,9 +7140,9 @@ ValueNum Compiler::fgMemoryVNForLoopSideEffects(MemoryKind memoryKind,
}
#endif // DEBUG
- // Instance fields and "complex" statics select "first field maps"
- // with a placeholder type. "Simple" statics select their own types.
- var_types fldMapType = (fieldKind == FieldKindForVN::WithBaseAddr) ? TYP_MEM : eeGetFieldType(fldHnd);
+ // Instance field maps get a placeholder type - they do not represent "singular"
+ // values. Static field maps, on the other hand, do, and so must be given proper types.
+ var_types fldMapType = eeIsFieldStatic(fldHnd) ? eeGetFieldType(fldHnd) : TYP_MEM;
newMemoryVN = vnStore->VNForMapStore(newMemoryVN, fldHndVN, vnStore->VNForExpr(entryBlock, fldMapType));
}
@@ -7536,7 +7464,13 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree)
}
// We have to handle the case where the LHS is a comma. In that case, we don't evaluate the comma,
- // and we're really just interested in the effective value.
+ // so we give it VNForVoid, and we're really interested in the effective value.
+ GenTree* lhsCommaIter = lhs;
+ while (lhsCommaIter->OperGet() == GT_COMMA)
+ {
+ lhsCommaIter->gtVNPair.SetBoth(vnStore->VNForVoid());
+ lhsCommaIter = lhsCommaIter->AsOp()->gtOp2;
+ }
lhs = lhs->gtEffectiveVal();
// Now, record the new VN for an assignment (performing the indicated "state update").
@@ -7693,6 +7627,8 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree)
// Indicates whether the argument of the IND is the address of a local.
bool wasLocal = false;
+ lhs->gtVNPair = rhsVNPair;
+
VNFuncApp funcApp;
ValueNum argVN = arg->gtVNPair.GetLiberal();
@@ -7799,8 +7735,9 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree)
// Was the argument of the GT_IND the address of a local, handled above?
if (!wasLocal)
{
- GenTree* baseAddr = nullptr;
- FieldSeqNode* fldSeq = nullptr;
+ GenTree* obj = nullptr;
+ GenTree* staticOffset = nullptr;
+ FieldSeqNode* fldSeq = nullptr;
// Is the LHS an array index expression?
if (argIsVNFunc && funcApp.m_func == VNF_PtrToArrElem)
@@ -7859,7 +7796,7 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree)
rhsVNPair.GetLiberal(), lhs->TypeGet());
recordGcHeapStore(tree, heapVN DEBUGARG("ArrIndexAssign (case 2)"));
}
- else if (arg->IsFieldAddr(this, &baseAddr, &fldSeq))
+ else if (arg->IsFieldAddr(this, &obj, &staticOffset, &fldSeq))
{
assert((fldSeq != nullptr) && (fldSeq != FieldSeqStore::NotAField()) && !fldSeq->IsPseudoField());
@@ -7870,10 +7807,11 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree)
// We will check that the final field in the sequence matches 'indType'.
var_types indType = lhs->TypeGet();
- if (baseAddr != nullptr)
+ // when (obj != nullptr) we have an instance field, otherwise a static field
+ // when (staticOffset != nullptr) it represents a offset into a static or the call to
+ // Shared Static Base
+ if ((obj != nullptr) || (staticOffset != nullptr))
{
- // Instance field / "complex" static: heap[field][baseAddr][struct fields...] = storeVal.
-
var_types firstFieldType;
ValueNum firstFieldSelectorVN =
vnStore->VNForFieldSelector(fldSeq->GetFieldHandle(), &firstFieldType);
@@ -7883,7 +7821,15 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree)
ValueNum fldMapVN =
vnStore->VNForMapSelect(VNK_Liberal, TYP_MEM, fgCurMemoryVN[GcHeap], firstFieldSelectorVN);
- ValueNum firstFieldValueSelectorVN = vnStore->VNLiberalNormalValue(baseAddr->gtVNPair);
+ ValueNum firstFieldValueSelectorVN = ValueNumStore::NoVN;
+ if (obj != nullptr)
+ {
+ firstFieldValueSelectorVN = vnStore->VNLiberalNormalValue(obj->gtVNPair);
+ }
+ else // (staticOffset != nullptr)
+ {
+ firstFieldValueSelectorVN = vnStore->VNLiberalNormalValue(staticOffset->gtVNPair);
+ }
ValueNum newFirstFieldValueVN = ValueNumStore::NoVN;
// Optimization: avoid traversting the maps for the value of the first field if
@@ -7894,12 +7840,12 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree)
}
else
{
- // Construct the ValueNumber for fldMap[baseAddr]. This (struct)
+ // Construct the ValueNumber for fldMap[obj/offset]. This (struct)
// map represents the specific field we're looking to store to.
ValueNum firstFieldValueVN = vnStore->VNForMapSelect(VNK_Liberal, firstFieldType, fldMapVN,
firstFieldValueSelectorVN);
- // Construct the maps updating the struct fields in the sequence.
+ // Construct the maps updating the rest of the fields in the sequence.
newFirstFieldValueVN = vnStore->VNApplySelectorsAssign(VNK_Liberal, firstFieldValueVN,
fldSeq->m_next, storeVal, indType);
}
@@ -7913,11 +7859,15 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree)
}
else
{
- // "Simple" static: heap[field][struct fields...] = storeVal.
+ // Plain static field.
newHeapVN = vnStore->VNApplySelectorsAssign(VNK_Liberal, fgCurMemoryVN[GcHeap], fldSeq,
storeVal, indType);
}
+ // It is not strictly necessary to set the lhs value number,
+ // but the dumps read better with it set to the 'storeVal' that we just computed
+ lhs->gtVNPair.SetBoth(storeVal);
+
// Update the GcHeap value.
recordGcHeapStore(tree, newHeapVN DEBUGARG("StoreField"));
}
@@ -8215,7 +8165,7 @@ void Compiler::fgValueNumberBlockAssignment(GenTree* tree)
else if (srcAddrFuncApp.m_func == VNF_PtrToArrElem)
{
ValueNum elemLib =
- fgValueNumberArrIndexVal(nullptr, &srcAddrFuncApp, vnStore->VNPForEmptyExcSet());
+ fgValueNumberArrIndexVal(nullptr, &srcAddrFuncApp, vnStore->VNForEmptyExcSet());
rhsVNPair.SetLiberal(elemLib);
rhsVNPair.SetConservative(vnStore->VNForExpr(compCurBB, lclVarTree->TypeGet()));
}
@@ -8371,8 +8321,43 @@ bool Compiler::fgValueNumberIsStructReinterpretation(GenTreeLclVarCommon* lhsLcl
void Compiler::fgValueNumberTree(GenTree* tree)
{
genTreeOps oper = tree->OperGet();
- var_types typ = tree->TypeGet();
+#ifdef FEATURE_SIMD
+ if ((JitConfig.JitDisableSimdVN() & 1) == 1)
+ {
+ // This Jit Config forces the previous behavior of value numbering for SIMD nodes
+ if (oper == GT_SIMD)
+ {
+ tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, TYP_UNKNOWN));
+ return;
+ }
+ }
+#endif // FEATURE_SIMD
+
+#ifdef FEATURE_HW_INTRINSICS
+ if ((JitConfig.JitDisableSimdVN() & 2) == 2)
+ {
+ // This Jit Config forces the previous behavior of value numbering for HW Intrinsic nodes
+ if (oper == GT_HWINTRINSIC)
+ {
+ tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, TYP_UNKNOWN));
+
+ GenTreeHWIntrinsic* hwIntrinsicNode = tree->AsHWIntrinsic();
+ assert(hwIntrinsicNode != nullptr);
+
+ // For safety/correctness we must mutate the global heap valuenumber
+ // for any HW intrinsic that performs a memory store operation
+ if (hwIntrinsicNode->OperIsMemoryStore())
+ {
+ fgMutateGcHeap(tree DEBUGARG("HWIntrinsic - MemoryStore"));
+ }
+
+ return;
+ }
+ }
+#endif // FEATURE_HW_INTRINSICS
+
+ var_types typ = tree->TypeGet();
if (GenTree::OperIsConst(oper))
{
// If this is a struct assignment, with a constant rhs, (i,.e. an initBlk),
@@ -8529,18 +8514,19 @@ void Compiler::fgValueNumberTree(GenTree* tree)
{
// We have a Def (write) of the LclVar
- // The below block ensures we give VNs to the fields of
- // "CanBeReplacedWithItsField" struct locals. To the numbering
- // of block assignments, those appear as untracked locals, but
- // we need to give the SSA defs they represent a VN.
+ // TODO-Review: For the short term, we have a workaround for copyblk/initblk. Those that use
+ // addrSpillTemp will have a statement like "addrSpillTemp = addr(local)." If we previously decided
+ // that this block operation defines the local, we will have labeled the "local" node as a DEF
+ // This flag propagates to the "local" on the RHS. So we'll assume that this is correct,
+ // and treat it as a def (to a new, unique VN).
+ //
if (lcl->GetSsaNum() != SsaConfig::RESERVED_SSA_NUM)
{
ValueNum uniqVN = vnStore->VNForExpr(compCurBB, lcl->TypeGet());
varDsc->GetPerSsaData(lcl->GetSsaNum())->m_vnPair.SetBoth(uniqVN);
}
- // Location nodes get VNForVoid (no exceptions needed).
- lcl->gtVNPair = vnStore->VNPForVoid();
+ lcl->gtVNPair = ValueNumPair(); // Avoid confusion -- we don't set the VN of a lcl being defined.
}
}
break;
@@ -8582,11 +8568,6 @@ void Compiler::fgValueNumberTree(GenTree* tree)
tree->gtVNPair = vnStore->VNPairApplySelectors(lclVNPair, lclFld->GetFieldSeq(), indType);
}
}
- else
- {
- // A location node (LHS).
- lclFld->gtVNPair = vnStore->VNPForVoid();
- }
}
break;
@@ -8671,11 +8652,6 @@ void Compiler::fgValueNumberTree(GenTree* tree)
}
tree->gtVNPair = clsVarVNPair;
}
- else
- {
- // Location nodes get the "Void" VN.
- tree->gtVNPair = vnStore->VNPForVoid();
- }
break;
case GT_MEMORYBARRIER: // Leaf
@@ -8755,42 +8731,38 @@ void Compiler::fgValueNumberTree(GenTree* tree)
// Usually the ADDR and IND just cancel out...
// except when this GT_ADDR has a valid zero-offset field sequence
//
-
- ValueNumPair addrVNP = ValueNumPair();
FieldSeqNode* zeroOffsetFieldSeq = nullptr;
if (GetZeroOffsetFieldMap()->Lookup(tree, &zeroOffsetFieldSeq) &&
(zeroOffsetFieldSeq != FieldSeqStore::NotAField()))
{
- ValueNum addrExtended = vnStore->ExtendPtrVN(arg->AsIndir()->Addr(), zeroOffsetFieldSeq);
+ ValueNum addrExtended = vnStore->ExtendPtrVN(arg->AsOp()->gtOp1, zeroOffsetFieldSeq);
if (addrExtended != ValueNumStore::NoVN)
{
- // We don't care about lib/cons differences for addresses.
- addrVNP.SetBoth(addrExtended);
+ tree->gtVNPair.SetBoth(addrExtended); // We don't care about lib/cons differences for addresses.
}
else
{
- // ExtendPtrVN returned a failure result - give this address a new unique value.
- addrVNP.SetBoth(vnStore->VNForExpr(compCurBB, TYP_BYREF));
+ // ExtendPtrVN returned a failure result
+ // So give this address a new unique value
+ tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, TYP_BYREF));
}
}
else
{
// They just cancel, so fetch the ValueNumber from the op1 of the GT_IND node.
//
- GenTree* addr = arg->AsIndir()->Addr();
- addrVNP = addr->gtVNPair;
+ GenTree* addr = arg->AsIndir()->Addr();
+ tree->gtVNPair = addr->gtVNPair;
// For the CSE phase mark the address as GTF_DONT_CSE
// because it will end up with the same value number as tree (the GT_ADDR).
addr->gtFlags |= GTF_DONT_CSE;
}
-
- tree->gtVNPair = vnStore->VNPWithExc(addrVNP, vnStore->VNPExceptionSet(arg->gtVNPair));
}
else
{
// May be more cases to do here! But we'll punt for now.
- tree->gtVNPair = vnStore->VNPUniqueWithExc(TYP_BYREF, vnStore->VNPExceptionSet(arg->gtVNPair));
+ tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, TYP_BYREF));
}
}
else if ((oper == GT_IND) || GenTree::OperIsBlk(oper))
@@ -8799,11 +8771,12 @@ void Compiler::fgValueNumberTree(GenTree* tree)
// a pointer to an object field or array element. Other cases become uses of
// the current ByrefExposed value and the pointer value, so that at least we
// can recognize redundant loads with no stores between them.
- GenTree* addr = tree->AsIndir()->Addr();
- GenTreeLclVarCommon* lclVarTree = nullptr;
- FieldSeqNode* fldSeq = nullptr;
- GenTree* baseAddr = nullptr;
- bool isVolatile = (tree->gtFlags & GTF_IND_VOLATILE) != 0;
+ GenTree* addr = tree->AsIndir()->Addr();
+ GenTreeLclVarCommon* lclVarTree = nullptr;
+ FieldSeqNode* fldSeq2 = nullptr;
+ GenTree* obj = nullptr;
+ GenTree* staticOffset = nullptr;
+ bool isVolatile = (tree->gtFlags & GTF_IND_VOLATILE) != 0;
// See if the addr has any exceptional part.
ValueNumPair addrNvnp;
@@ -8876,65 +8849,61 @@ void Compiler::fgValueNumberTree(GenTree* tree)
// Try to parse it.
GenTree* arr = nullptr;
addr->ParseArrayAddress(this, &arrInfo, &arr, &inxVN, &fldSeq);
- if (arr != nullptr)
- {
- assert(fldSeq != FieldSeqStore::NotAField());
-
- // Need to form H[arrType][arr][ind][fldSeq]
- // Get the array element type equivalence class rep.
- CORINFO_CLASS_HANDLE elemTypeEq = EncodeElemType(arrInfo.m_elemType, arrInfo.m_elemStructType);
- ValueNum elemTypeEqVN = vnStore->VNForHandle(ssize_t(elemTypeEq), GTF_ICON_CLASS_HDL);
- JITDUMP(" VNForHandle(arrElemType: %s) is " FMT_VN "\n",
- (arrInfo.m_elemType == TYP_STRUCT) ? eeGetClassName(arrInfo.m_elemStructType)
- : varTypeName(arrInfo.m_elemType),
- elemTypeEqVN);
-
- // We take the "VNNormalValue"s here, because if either has exceptional outcomes, they will
- // be captured as part of the value of the composite "addr" operation...
- ValueNum arrVN = vnStore->VNLiberalNormalValue(arr->gtVNPair);
- inxVN = vnStore->VNNormalValue(inxVN);
-
- // Additionally, relabel the address with a PtrToArrElem value number.
- ValueNum fldSeqVN = vnStore->VNForFieldSeq(fldSeq);
- ValueNum elemAddr =
- vnStore->VNForFunc(TYP_BYREF, VNF_PtrToArrElem, elemTypeEqVN, arrVN, inxVN, fldSeqVN);
-
- // The aggregate "addr" VN should have had all the exceptions bubble up...
- addr->gtVNPair = vnStore->VNPWithExc(ValueNumPair(elemAddr, elemAddr), addrXvnp);
+ if (arr == nullptr)
+ {
+ tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, tree->TypeGet()));
+ return;
+ }
+ assert(fldSeq != FieldSeqStore::NotAField());
+
+ // Otherwise...
+ // Need to form H[arrType][arr][ind][fldSeq]
+ // Get the array element type equivalence class rep.
+ CORINFO_CLASS_HANDLE elemTypeEq = EncodeElemType(arrInfo.m_elemType, arrInfo.m_elemStructType);
+ ValueNum elemTypeEqVN = vnStore->VNForHandle(ssize_t(elemTypeEq), GTF_ICON_CLASS_HDL);
+ JITDUMP(" VNForHandle(arrElemType: %s) is " FMT_VN "\n",
+ (arrInfo.m_elemType == TYP_STRUCT) ? eeGetClassName(arrInfo.m_elemStructType)
+ : varTypeName(arrInfo.m_elemType),
+ elemTypeEqVN)
+
+ // We take the "VNNormalValue"s here, because if either has exceptional outcomes, they will be captured
+ // as part of the value of the composite "addr" operation...
+ ValueNum arrVN = vnStore->VNLiberalNormalValue(arr->gtVNPair);
+ inxVN = vnStore->VNNormalValue(inxVN);
+
+ // Additionally, relabel the address with a PtrToArrElem value number.
+ ValueNum fldSeqVN = vnStore->VNForFieldSeq(fldSeq);
+ ValueNum elemAddr =
+ vnStore->VNForFunc(TYP_BYREF, VNF_PtrToArrElem, elemTypeEqVN, arrVN, inxVN, fldSeqVN);
+
+ // The aggregate "addr" VN should have had all the exceptions bubble up...
+ elemAddr = vnStore->VNWithExc(elemAddr, addrXvnp.GetLiberal());
+ addr->gtVNPair.SetBoth(elemAddr);
#ifdef DEBUG
- ValueNum elemAddrWithExc = addr->gtVNPair.GetLiberal();
- if (verbose)
+ if (verbose)
+ {
+ printf(" Relabeled IND_ARR_INDEX address node ");
+ Compiler::printTreeID(addr);
+ printf(" with l:" FMT_VN ": ", elemAddr);
+ vnStore->vnDump(this, elemAddr);
+ printf("\n");
+ if (vnStore->VNNormalValue(elemAddr) != elemAddr)
{
- printf(" Relabeled IND_ARR_INDEX address node ");
- Compiler::printTreeID(addr);
- printf(" with l:" FMT_VN ": ", elemAddrWithExc);
- vnStore->vnDump(this, elemAddrWithExc);
- printf("\n");
- if (elemAddrWithExc != elemAddr)
- {
- printf(" [" FMT_VN " is: ", elemAddr);
- vnStore->vnDump(this, elemAddr);
- printf("]\n");
- }
+ printf(" [" FMT_VN " is: ", vnStore->VNNormalValue(elemAddr));
+ vnStore->vnDump(this, vnStore->VNNormalValue(elemAddr));
+ printf("]\n");
}
+ }
#endif // DEBUG
- // We now need to retrieve the value number for the array element value
- // and give this value number to the GT_IND node 'tree'
- // We do this whenever we have an rvalue, but we don't do it for a
- // normal LHS assignment into an array element.
- //
- if ((tree->gtFlags & GTF_IND_ASG_LHS) == 0)
- {
- fgValueNumberArrIndexVal(tree, elemTypeEq, arrVN, inxVN, addrXvnp, fldSeq);
- }
- }
- else // An unparseable array expression.
+ // We now need to retrieve the value number for the array element value
+ // and give this value number to the GT_IND node 'tree'
+ // We do this whenever we have an rvalue, but we don't do it for a
+ // normal LHS assignment into an array element.
+ //
+ if ((tree->gtFlags & GTF_IND_ASG_LHS) == 0)
{
- if ((tree->gtFlags & GTF_IND_ASG_LHS) == 0)
- {
- tree->gtVNPair = vnStore->VNPUniqueWithExc(tree->TypeGet(), addrXvnp);
- }
+ fgValueNumberArrIndexVal(tree, elemTypeEq, arrVN, inxVN, addrXvnp.GetLiberal(), fldSeq);
}
}
// In general we skip GT_IND nodes on that are the LHS of an assignment. (We labeled these earlier.)
@@ -8993,44 +8962,43 @@ void Compiler::fgValueNumberTree(GenTree* tree)
}
else if (vnStore->GetVNFunc(addrNvnp.GetLiberal(), &funcApp) && (funcApp.m_func == VNF_PtrToArrElem))
{
- fgValueNumberArrIndexVal(tree, &funcApp, addrXvnp);
+ fgValueNumberArrIndexVal(tree, &funcApp, addrXvnp.GetLiberal());
}
- else if (addr->IsFieldAddr(this, &baseAddr, &fldSeq))
+ else if (addr->IsFieldAddr(this, &obj, &staticOffset, &fldSeq2))
{
- assert((fldSeq != nullptr) && (fldSeq != FieldSeqStore::NotAField()) && !fldSeq->IsPseudoField());
+ assert((fldSeq2 != nullptr) && (fldSeq2 != FieldSeqStore::NotAField()) &&
+ !fldSeq2->IsPseudoField());
// The size of the ultimate value we will select, if it is of a struct type.
- size_t structSize = 0;
- ValueNum valueVN = ValueNumStore::NoVN;
-
- if (baseAddr != nullptr)
- {
- // Instance field / "complex" static: heap[field][baseAddr][struct fields...].
-
- // Get the selector for the first field.
- var_types firstFieldType;
- ValueNum firstFieldSelectorVN =
- vnStore->VNForFieldSelector(fldSeq->GetFieldHandle(), &firstFieldType, &structSize);
+ size_t structSize = 0;
- ValueNum fldMapVN =
- vnStore->VNForMapSelect(VNK_Liberal, TYP_MEM, fgCurMemoryVN[GcHeap], firstFieldSelectorVN);
+ // Get the selector for the first field.
+ var_types firstFieldType;
+ ValueNum firstFieldSelectorVN =
+ vnStore->VNForFieldSelector(fldSeq2->GetFieldHandle(), &firstFieldType, &structSize);
- ValueNum firstFieldValueSelectorVN = vnStore->VNLiberalNormalValue(baseAddr->gtVNPair);
+ ValueNum fldMapVN =
+ vnStore->VNForMapSelect(VNK_Liberal, TYP_MEM, fgCurMemoryVN[GcHeap], firstFieldSelectorVN);
- // Construct the value number for fldMap[baseAddr].
- ValueNum firstFieldValueVN =
- vnStore->VNForMapSelect(VNK_Liberal, firstFieldType, fldMapVN, firstFieldValueSelectorVN);
-
- // Finally, account for the rest of the fields in the sequence.
- valueVN =
- vnStore->VNApplySelectors(VNK_Liberal, firstFieldValueVN, fldSeq->m_next, &structSize);
+ ValueNum firstFieldValueSelectorVN;
+ if (obj != nullptr)
+ {
+ firstFieldValueSelectorVN = vnStore->VNLiberalNormalValue(obj->gtVNPair);
}
else
{
- // "Simple" static: heap[static][struct fields...].
- valueVN = vnStore->VNApplySelectors(VNK_Liberal, fgCurMemoryVN[GcHeap], fldSeq, &structSize);
+ assert(staticOffset != nullptr);
+ firstFieldValueSelectorVN = vnStore->VNLiberalNormalValue(staticOffset->gtVNPair);
}
+ // Construct the value number for fldMap[obj/offset].
+ ValueNum firstFieldValueVN =
+ vnStore->VNForMapSelect(VNK_Liberal, firstFieldType, fldMapVN, firstFieldValueSelectorVN);
+
+ // Finally, account for the rest of the fields in the sequence.
+ ValueNum valueVN =
+ vnStore->VNApplySelectors(VNK_Liberal, firstFieldValueVN, fldSeq2->m_next, &structSize);
+
valueVN = vnStore->VNApplySelectorsTypeCheck(valueVN, tree->TypeGet(), structSize);
tree->gtVNPair.SetLiberal(valueVN);
@@ -9047,12 +9015,6 @@ void Compiler::fgValueNumberTree(GenTree* tree)
tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, addrXvnp);
}
}
-
- // To be able to propagate exception sets, we give location nodes the "Void" VN.
- if ((tree->gtFlags & GTF_IND_ASG_LHS) != 0)
- {
- tree->gtVNPair = vnStore->VNPWithExc(vnStore->VNPForVoid(), addrXvnp);
- }
}
else if (tree->OperGet() == GT_CAST)
{
@@ -9149,7 +9111,8 @@ void Compiler::fgValueNumberTree(GenTree* tree)
if (newVN != ValueNumStore::NoVN)
{
// We don't care about differences between liberal and conservative for pointer values.
- tree->gtVNPair = vnStore->VNPWithExc(ValueNumPair(newVN, newVN), excSetPair);
+ newVN = vnStore->VNWithExc(newVN, excSetPair.GetLiberal());
+ tree->gtVNPair.SetBoth(newVN);
}
else
{
@@ -9168,8 +9131,28 @@ void Compiler::fgValueNumberTree(GenTree* tree)
{
case GT_COMMA:
{
- ValueNumPair op1Xvnp = vnStore->VNPExceptionSet(tree->AsOp()->gtOp1->gtVNPair);
- tree->gtVNPair = vnStore->VNPWithExc(tree->AsOp()->gtOp2->gtVNPair, op1Xvnp);
+ ValueNumPair op1vnp;
+ ValueNumPair op1Xvnp;
+ vnStore->VNPUnpackExc(tree->AsOp()->gtOp1->gtVNPair, &op1vnp, &op1Xvnp);
+ ValueNumPair op2vnp;
+ ValueNumPair op2Xvnp = ValueNumStore::VNPForEmptyExcSet();
+ GenTree* op2 = tree->gtGetOp2();
+
+ if (op2->OperIsIndir() && ((op2->gtFlags & GTF_IND_ASG_LHS) != 0))
+ {
+ // If op2 represents the lhs of an assignment then we give a VNForVoid for the lhs
+ op2vnp = ValueNumPair(ValueNumStore::VNForVoid(), ValueNumStore::VNForVoid());
+ }
+ else if ((op2->OperGet() == GT_CLS_VAR) && (op2->gtFlags & GTF_CLS_VAR_ASG_LHS))
+ {
+ // If op2 represents the lhs of an assignment then we give a VNForVoid for the lhs
+ op2vnp = ValueNumPair(ValueNumStore::VNForVoid(), ValueNumStore::VNForVoid());
+ }
+ else
+ {
+ vnStore->VNPUnpackExc(op2->gtVNPair, &op2vnp, &op2Xvnp);
+ }
+ tree->gtVNPair = vnStore->VNPWithExc(op2vnp, vnStore->VNPExcSetUnion(op1Xvnp, op2Xvnp));
}
break;
@@ -9200,6 +9183,18 @@ void Compiler::fgValueNumberTree(GenTree* tree)
}
break;
+ case GT_NULLCHECK:
+ {
+ // An Explicit null check, produces no value
+ // But we do persist any execeptions produced by op1
+ //
+ tree->gtVNPair = vnStore->VNPWithExc(vnStore->VNPForVoid(),
+ vnStore->VNPExceptionSet(tree->AsOp()->gtOp1->gtVNPair));
+ // The exception set with VNF_NullPtrExc will be added below
+ // by fgValueNumberAddExceptionSet
+ }
+ break;
+
case GT_LOCKADD: // Binop
noway_assert("LOCKADD should not appear before lowering");
break;
@@ -9234,41 +9229,20 @@ void Compiler::fgValueNumberTree(GenTree* tree)
break;
}
- // These unary nodes do not produce values. Note that for NULLCHECK the
- // additional exception will be added below by "fgValueNumberAddExceptionSet".
case GT_JTRUE:
- case GT_SWITCH:
- case GT_RETURN:
- case GT_RETFILT:
- case GT_NULLCHECK:
- if (tree->gtGetOp1() != nullptr)
- {
- tree->gtVNPair = vnStore->VNPWithExc(vnStore->VNPForVoid(),
- vnStore->VNPExceptionSet(tree->gtGetOp1()->gtVNPair));
- }
- else
- {
- tree->gtVNPair = vnStore->VNPForVoid();
- }
+ // These nodes never need to have a ValueNumber
+ tree->gtVNPair.SetBoth(ValueNumStore::NoVN);
break;
- // BOX and CKFINITE are passthrough nodes (like NOP). We'll add the exception for the latter later.
case GT_BOX:
- case GT_CKFINITE:
+ // BOX doesn't do anything at this point, the actual object allocation
+ // and initialization happens separately (and not numbering BOX correctly
+ // prevents seeing allocation related assertions through it)
tree->gtVNPair = tree->gtGetOp1()->gtVNPair;
break;
- // These unary nodes will receive a unique VN.
- // TODO-CQ: model INIT_VAL properly.
- case GT_LCLHEAP:
- case GT_INIT_VAL:
- tree->gtVNPair =
- vnStore->VNPUniqueWithExc(tree->TypeGet(),
- vnStore->VNPExceptionSet(tree->gtGetOp1()->gtVNPair));
- break;
-
default:
- assert(!"Unhandled node in fgValueNumberTree");
+ // The default action is to give the node a new, unique VN.
tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, tree->TypeGet()));
break;
}
@@ -9301,30 +9275,6 @@ void Compiler::fgValueNumberTree(GenTree* tree)
break;
#endif // FEATURE_HW_INTRINSICS
- case GT_STORE_DYN_BLK:
- {
- // Conservatively, mutate the heaps - we don't analyze these rare stores.
- // Likewise, any locals possibly defined by them we mark as address-exposed.
- fgMutateGcHeap(tree DEBUGARG("dynamic block store"));
-
- GenTreeStoreDynBlk* store = tree->AsStoreDynBlk();
- ValueNumPair vnpExcSet = ValueNumStore::VNPForEmptyExcSet();
-
- // Propagate the exceptions...
- vnpExcSet = vnStore->VNPUnionExcSet(store->Addr()->gtVNPair, vnpExcSet);
- vnpExcSet = vnStore->VNPUnionExcSet(store->Data()->gtVNPair, vnpExcSet);
- vnpExcSet = vnStore->VNPUnionExcSet(store->gtDynamicSize->gtVNPair, vnpExcSet);
-
- // This is a store, it produces no value. Thus we use VNPForVoid().
- store->gtVNPair = vnStore->VNPWithExc(vnStore->VNPForVoid(), vnpExcSet);
-
- // Note that we are only adding the exception for the destination address.
- // Currently, "Data()" is an explicit indirection in case this is a "cpblk".
- assert(store->Data()->gtEffectiveVal()->OperIsIndir() || store->OperIsInitBlkOp());
- fgValueNumberAddExceptionSetForIndirection(store, store->Addr());
- break;
- }
-
case GT_CMPXCHG: // Specialop
{
// For CMPXCHG and other intrinsics add an arbitrary side effect on GcHeap/ByrefExposed.
@@ -9359,38 +9309,8 @@ void Compiler::fgValueNumberTree(GenTree* tree)
break;
}
- // ARR_ELEM is a bounds-checked address. TODO-CQ: model it precisely.
- case GT_ARR_ELEM:
- {
- GenTreeArrElem* arrElem = tree->AsArrElem();
-
- ValueNumPair vnpExcSet = vnStore->VNPExceptionSet(arrElem->gtArrObj->gtVNPair);
- for (size_t i = 0; i < arrElem->gtArrRank; i++)
- {
- vnpExcSet = vnStore->VNPUnionExcSet(arrElem->gtArrInds[i]->gtVNPair, vnpExcSet);
- }
-
- arrElem->gtVNPair = vnStore->VNPUniqueWithExc(arrElem->TypeGet(), vnpExcSet);
-
- // TODO: model the IndexOutOfRangeException for this node.
- fgValueNumberAddExceptionSetForIndirection(arrElem, arrElem->gtArrObj);
- }
- break;
-
- // FIELD_LIST is an R-value that we currently don't model.
- case GT_FIELD_LIST:
- tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, tree->TypeGet()));
- for (GenTreeFieldList::Use& use : tree->AsFieldList()->Uses())
- {
- tree->gtVNPair =
- vnStore->VNPWithExc(tree->gtVNPair, vnStore->VNPExceptionSet(use.GetNode()->gtVNPair));
- }
- break;
-
default:
- assert(!"Unhandled special node in fgValueNumberTree");
tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, tree->TypeGet()));
- break;
}
}
#ifdef DEBUG
@@ -9464,25 +9384,19 @@ void Compiler::fgValueNumberSimd(GenTreeSIMD* tree)
ValueNumPair excSetPair;
ValueNumPair normalPair;
- if ((tree->GetOperandCount() > 2) || ((JitConfig.JitDisableSimdVN() & 1) == 1))
- {
- // We have a SIMD node with 3 or more args. To retain the
- // previous behavior, we will generate a unique VN for this case.
- excSetPair = ValueNumStore::VNPForEmptyExcSet();
- for (GenTree* operand : tree->Operands())
- {
- excSetPair = vnStore->VNPUnionExcSet(operand->gtVNPair, excSetPair);
- }
- tree->gtVNPair = vnStore->VNPUniqueWithExc(tree->TypeGet(), excSetPair);
- return;
- }
-
// There are some SIMD operations that have zero args, i.e. NI_Vector128_Zero
if (tree->GetOperandCount() == 0)
{
excSetPair = ValueNumStore::VNPForEmptyExcSet();
normalPair = vnStore->VNPairForFunc(tree->TypeGet(), simdFunc);
}
+ else if (tree->GetOperandCount() > 2)
+ {
+ // We have a SIMD node with 3 or more args. To retain the
+ // previous behavior, we will generate a unique VN for this case.
+ tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, tree->TypeGet()));
+ return;
+ }
else // SIMD unary or binary operator.
{
ValueNumPair resvnp = ValueNumPair();
@@ -9607,17 +9521,12 @@ void Compiler::fgValueNumberHWIntrinsic(GenTreeHWIntrinsic* tree)
fgMutateGcHeap(tree DEBUGARG("HWIntrinsic - MemoryStore"));
}
- if ((tree->GetOperandCount() > 2) || ((JitConfig.JitDisableSimdVN() & 2) == 2))
+ if (tree->GetOperandCount() > 2)
{
// TODO-CQ: allow intrinsics with > 2 operands to be properly VN'ed, it will
// allow use to process things like Vector128.Create(1,2,3,4) etc.
- // Generate unique VN for now to retaing previous behavior.
- ValueNumPair vnpExcSet = vnStore->VNPForEmptyExcSet();
- for (GenTree* operand : tree->Operands())
- {
- vnpExcSet = vnStore->VNPUnionExcSet(operand->gtVNPair, vnpExcSet);
- }
- tree->gtVNPair = vnStore->VNPUniqueWithExc(tree->TypeGet(), vnpExcSet);
+ // Generate unique VN for now to retaing previois behavior.
+ tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, tree->TypeGet()));
return;
}
@@ -9629,13 +9538,15 @@ void Compiler::fgValueNumberHWIntrinsic(GenTreeHWIntrinsic* tree)
//
if (isMemoryLoad)
{
- ValueNumPair op1vnp = vnStore->VNPNormalPair(tree->Op(1)->gtVNPair);
+ ValueNumPair op1vnp;
+ ValueNumPair op1Xvnp;
+ vnStore->VNPUnpackExc(tree->Op(1)->gtVNPair, &op1vnp, &op1Xvnp);
// The addrVN incorporates both op1's ValueNumber and the func operation
// The func is used because operations such as LoadLow and LoadHigh perform
// different operations, thus need to compute different ValueNumbers
// We don't need to encode the result type as it will be encoded by the opcode in 'func'
- // TODO-Bug: some HWI loads have more than one operand, we need to encode the rest.
+ //
ValueNum addrVN = vnStore->VNForFunc(TYP_BYREF, func, op1vnp.GetLiberal());
// The address could point anywhere, so it is an ByrefExposed load.
@@ -9643,11 +9554,7 @@ void Compiler::fgValueNumberHWIntrinsic(GenTreeHWIntrinsic* tree)
ValueNum loadVN = fgValueNumberByrefExposedLoad(tree->TypeGet(), addrVN);
tree->gtVNPair.SetLiberal(loadVN);
tree->gtVNPair.SetConservative(vnStore->VNForExpr(compCurBB, tree->TypeGet()));
-
- for (GenTree* operand : tree->Operands())
- {
- tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, vnStore->VNPExceptionSet(operand->gtVNPair));
- }
+ tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, op1Xvnp);
fgValueNumberAddExceptionSetForIndirection(tree, tree->Op(1));
return;
}
@@ -10034,12 +9941,14 @@ void Compiler::fgValueNumberCall(GenTreeCall* call)
{
// First: do value numbering of any argument placeholder nodes in the argument list
// (by transferring from the VN of the late arg that they are standing in for...)
-
- auto updateArgVN = [=](GenTree* arg, unsigned argIndex) {
+ unsigned i = 0;
+ for (GenTreeCall::Use& use : call->Args())
+ {
+ GenTree* arg = use.GetNode();
if (arg->OperGet() == GT_ARGPLACE)
{
// Find the corresponding late arg.
- GenTree* lateArg = call->fgArgInfo->GetArgNode(argIndex);
+ GenTree* lateArg = call->fgArgInfo->GetArgNode(i);
assert(lateArg->gtVNPair.BothDefined());
arg->gtVNPair = lateArg->gtVNPair;
#ifdef DEBUG
@@ -10053,19 +9962,7 @@ void Compiler::fgValueNumberCall(GenTreeCall* call)
}
#endif
}
- };
-
- unsigned argIndex = 0;
- if (call->gtCallThisArg != nullptr)
- {
- updateArgVN(call->gtCallThisArg->GetNode(), argIndex);
- argIndex++;
- }
-
- for (GenTreeCall::Use& use : call->Args())
- {
- updateArgVN(use.GetNode(), argIndex);
- argIndex++;
+ i++;
}
if (call->gtCallType == CT_HELPER)
@@ -10609,16 +10506,27 @@ void Compiler::fgValueNumberAddExceptionSetForIndirection(GenTree* tree, GenTree
// Create baseVNP, from the values we just computed,
baseVNP = ValueNumPair(baseLVN, baseCVN);
- // The exceptions in "baseVNP" should have been added to the "tree"'s set already.
- assert(vnStore->VNPExcIsSubset(vnStore->VNPExceptionSet(tree->gtVNPair), vnStore->VNPExceptionSet(baseVNP)));
-
- // The normal VN for base address is used to create the NullPtrExc
- ValueNumPair vnpBaseNorm = vnStore->VNPNormalPair(baseVNP);
+ // Unpack, Norm,Exc for the tree's op1 VN
+ ValueNumPair vnpBaseNorm;
+ ValueNumPair vnpBaseExc;
+ vnStore->VNPUnpackExc(baseVNP, &vnpBaseNorm, &vnpBaseExc);
+ // The Norm VN for op1 is used to create the NullPtrExc
ValueNumPair excChkSet = vnStore->VNPExcSetSingleton(vnStore->VNPairForFunc(TYP_REF, VNF_NullPtrExc, vnpBaseNorm));
- // Add the NullPtrExc to "tree"'s value numbers.
- tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, excChkSet);
+ // Combine the excChkSet with exception set of op1
+ ValueNumPair excSetBoth = vnStore->VNPExcSetUnion(excChkSet, vnpBaseExc);
+
+ // Retrieve the Normal VN for tree, note that it may be NoVN, so we handle that case
+ ValueNumPair vnpNorm = vnStore->VNPNormalPair(tree->gtVNPair);
+
+ // For as GT_IND on the lhs of an assignment we will get a NoVN value
+ if (vnpNorm.GetLiberal() == ValueNumStore::NoVN)
+ {
+ // Use the special Void VN value instead.
+ vnpNorm = vnStore->VNPForVoid();
+ }
+ tree->gtVNPair = vnStore->VNPWithExc(vnpNorm, excSetBoth);
}
//--------------------------------------------------------------------------------
@@ -10996,13 +10904,20 @@ void Compiler::fgValueNumberAddExceptionSet(GenTree* tree)
break;
case GT_INTRINSIC:
- assert(tree->AsIntrinsic()->gtIntrinsicName == NI_System_Object_GetType);
- fgValueNumberAddExceptionSetForIndirection(tree, tree->AsIntrinsic()->gtGetOp1());
+ // ToDo: model the exceptions for Intrinsics
break;
- case GT_IND:
+ case GT_IND: // Implicit null check.
+ if ((tree->gtFlags & GTF_IND_ASG_LHS) != 0)
+ {
+ // Don't add exception set on LHS of assignment
+ break;
+ }
+ FALLTHROUGH;
+
case GT_BLK:
case GT_OBJ:
+ case GT_DYN_BLK:
case GT_NULLCHECK:
fgValueNumberAddExceptionSetForIndirection(tree, tree->AsIndir()->Addr());
break;
@@ -11041,61 +10956,6 @@ void Compiler::fgValueNumberAddExceptionSet(GenTree* tree)
}
#ifdef DEBUG
-//------------------------------------------------------------------------
-// fgDebugCheckExceptionSets: Verify the exception sets on trees.
-//
-// This function checks that the node's exception set is a superset of
-// the exception sets of its operands.
-//
-void Compiler::fgDebugCheckExceptionSets()
-{
- struct ExceptionSetsChecker
- {
- static void CheckTree(GenTree* tree, ValueNumStore* vnStore)
- {
- // We will fail to VN some PHI_ARGs - their values may not
- // be known at the point we number them because of loops.
- assert(tree->gtVNPair.BothDefined() || tree->OperIs(GT_PHI_ARG));
-
- ValueNumPair operandsExcSet = vnStore->VNPForEmptyExcSet();
- tree->VisitOperands([&](GenTree* operand) -> GenTree::VisitResult {
-
- CheckTree(operand, vnStore);
-
- ValueNumPair operandVNP = operand->gtVNPair.BothDefined() ? operand->gtVNPair : vnStore->VNPForVoid();
- operandsExcSet = vnStore->VNPUnionExcSet(operandVNP, operandsExcSet);
-
- return GenTree::VisitResult::Continue;
- });
-
- // Currently, we fail to properly maintain the exception sets for trees with user
- // calls or assignments.
- if ((tree->gtFlags & (GTF_ASG | GTF_CALL)) != 0)
- {
- return;
- }
-
- ValueNumPair nodeExcSet = vnStore->VNPExceptionSet(tree->gtVNPair);
- assert(vnStore->VNExcIsSubset(nodeExcSet.GetLiberal(), operandsExcSet.GetLiberal()));
- assert(vnStore->VNExcIsSubset(nodeExcSet.GetConservative(), operandsExcSet.GetConservative()));
- }
- };
-
- for (BasicBlock* const block : Blocks())
- {
- for (Statement* const stmt : block->Statements())
- {
- // Exclude statements VN hasn't visited for whichever reason...
- if (stmt->GetRootNode()->GetVN(VNK_Liberal) == ValueNumStore::NoVN)
- {
- continue;
- }
-
- ExceptionSetsChecker::CheckTree(stmt->GetRootNode(), vnStore);
- }
- }
-}
-
// This method asserts that SSA name constraints specified are satisfied.
// Until we figure out otherwise, all VN's are assumed to be liberal.
// TODO-Cleanup: new JitTestLabels for lib vs cons vs both VN classes?
diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h
index 6c19327c80037..289e09fb688b1 100644
--- a/src/coreclr/jit/valuenum.h
+++ b/src/coreclr/jit/valuenum.h
@@ -494,8 +494,6 @@ class ValueNumStore
// Both arguments must be either VNForEmptyExcSet() or applications of VNF_ExcSetCons.
bool VNExcIsSubset(ValueNum vnFullSet, ValueNum vnCandidateSet);
- bool VNPExcIsSubset(ValueNumPair vnpFullSet, ValueNumPair vnpCandidateSet);
-
// Returns "true" iff "vn" is an application of "VNF_ValWithExc".
bool VNHasExc(ValueNum vn)
{
@@ -530,12 +528,6 @@ class ValueNumStore
// Keeps any Exception set values
ValueNumPair VNPMakeNormalUniquePair(ValueNumPair vnp);
- // A new unique value with the given exception set.
- ValueNum VNUniqueWithExc(var_types type, ValueNum vnExcSet);
-
- // A new unique VN pair with the given exception set pair.
- ValueNumPair VNPUniqueWithExc(var_types type, ValueNumPair vnpExcSet);
-
// If "vn" is a "VNF_ValWithExc(norm, excSet)" value, returns the "norm" argument; otherwise,
// just returns "vn".
// The Normal value is the value number of the expression when no exceptions occurred
diff --git a/src/coreclr/md/enc/metamodelrw.cpp b/src/coreclr/md/enc/metamodelrw.cpp
index 3fde673faa5c4..34fe8b84e95c8 100644
--- a/src/coreclr/md/enc/metamodelrw.cpp
+++ b/src/coreclr/md/enc/metamodelrw.cpp
@@ -309,15 +309,16 @@ ULONG CMiniMdRW::m_TruncatedEncTables[] =
ULONG CMiniMdRW::GetTableForToken( // Table index, or -1.
mdToken tkn) // Token to find.
{
+ ULONG ixTbl; // Loop control.
ULONG type = TypeFromToken(tkn);
// Get the type -- if a string, no associated table.
if (type >= mdtString)
return (ULONG) -1;
// Table number is same as high-byte of token.
- ULONG ixTbl = type >> 24;
+ ixTbl = type >> 24;
// Make sure.
- _ASSERTE(ixTbl < TBL_COUNT);
+ _ASSERTE(g_TblIndex[ixTbl].m_Token == type);
return ixTbl;
} // CMiniMdRW::GetTableForToken
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets
index ae6229a0a7afe..67efba61efde9 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Publish.targets
@@ -48,14 +48,12 @@
-
+
-
-
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets
index 529de6be54f55..501384a4c0c6c 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets
@@ -31,7 +31,6 @@ The .NET Foundation licenses this file to you under the MIT license.
false
true
- false
@@ -40,6 +39,8 @@ The .NET Foundation licenses this file to you under the MIT license.
true
true
+ true
+ copyused
@@ -130,6 +131,13 @@ The .NET Foundation licenses this file to you under the MIT license.
+
+
+
+ true
+
+
+
@@ -191,6 +199,35 @@ The .NET Foundation licenses this file to you under the MIT license.
Outputs="%(ManagedBinary.IlcRspFile)"
DependsOnTargets="$(IlcCompileDependsOn)">
+
+
+ true
+
+
+
+
+
+
+ <__SingleWarnIntermediateAssembly Include="@(ManagedAssemblyToLink)" />
+ <__SingleWarnIntermediateAssembly Remove="@(IntermediateAssembly)" />
+
+ <_SingleWarnIntermediateAssembly Include="@(ManagedAssemblyToLink)" />
+ <_SingleWarnIntermediateAssembly Remove="@(__SingleWarnIntermediateAssembly)" />
+
+ <_SingleWarnIntermediateAssembly>
+ false
+
+
+
+
+
+
+
+ false
+
+
+
<_IlcRootedAssemblies Include="@(TrimmerRootAssembly)" />
<_IlcRootedAssemblies Include="@(ManagedAssemblyToLink)" Condition="%(ManagedAssemblyToLink.TrimMode) == 'copy'" />
@@ -209,7 +246,6 @@ The .NET Foundation licenses this file to you under the MIT license.
-
@@ -242,7 +278,6 @@ The .NET Foundation licenses this file to you under the MIT license.
-
@@ -250,6 +285,9 @@ The .NET Foundation licenses this file to you under the MIT license.
+
+
+
@@ -266,8 +304,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 991f67bb9b227..e1025ce27e664 100644
--- a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp
+++ b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp
@@ -109,8 +109,7 @@ struct DotNetRuntimeDebugHeader
#ifdef TARGET_WINDOWS
#pragma comment (linker, "/EXPORT:DotNetRuntimeDebugHeader,DATA")
#endif
-extern "C" struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader;
-struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader = {};
+extern "C" DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader = {};
#define MAKE_DEBUG_ENTRY(TypeName, FieldName, Value) \
do \
@@ -139,8 +138,8 @@ extern "C" void PopulateDebugHeaders()
size_t currentDebugPos = 0;
size_t currentGlobalPos = 0;
- ZeroMemory(s_DebugEntries, sizeof(s_DebugEntries));
- ZeroMemory(s_GlobalEntries, sizeof(s_GlobalEntries));
+ ZeroMemory(s_DebugEntries, DebugTypeEntriesArraySize);
+ ZeroMemory(s_GlobalEntries, GlobalEntriesArraySize);
MAKE_SIZE_ENTRY(GcDacVars);
MAKE_DEBUG_FIELD_ENTRY(GcDacVars, major_version_number);
diff --git a/src/coreclr/nativeaot/Runtime/MethodTable.cpp b/src/coreclr/nativeaot/Runtime/MethodTable.cpp
index 4d3ace8dcf089..4197cd8ba3623 100644
--- a/src/coreclr/nativeaot/Runtime/MethodTable.cpp
+++ b/src/coreclr/nativeaot/Runtime/MethodTable.cpp
@@ -20,6 +20,10 @@ bool MethodTable::Validate(bool assertOnFail /* default: true */)
{
#define REPORT_FAILURE() do { if (assertOnFail) { ASSERT_UNCONDITIONALLY("MethodTable::Validate check failed"); } return false; } while (false)
+ // Deal with the most common case of a bad pointer without an exception.
+ if (this == NULL)
+ REPORT_FAILURE();
+
// MethodTable structures should be at least pointer aligned.
if (dac_cast(this) & (sizeof(TADDR)-1))
REPORT_FAILURE();
diff --git a/src/coreclr/nativeaot/Runtime/arm64/PInvoke.S b/src/coreclr/nativeaot/Runtime/arm64/PInvoke.S
index 4d3fbbbce2216..f66851461f278 100644
--- a/src/coreclr/nativeaot/Runtime/arm64/PInvoke.S
+++ b/src/coreclr/nativeaot/Runtime/arm64/PInvoke.S
@@ -188,7 +188,7 @@ NoAbort:
EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 0xA0
EPILOG_RETURN
- NESTED_END RhpReversePInvokeAttachOrTrapThread, _TEXT
+ NESTED_END RhpReversePInvokeTrapThread
//
// RhpPInvoke
diff --git a/src/coreclr/nativeaot/Runtime/arm64/PInvoke.asm b/src/coreclr/nativeaot/Runtime/arm64/PInvoke.asm
index 4bc165aef0450..7692bfa8341be 100644
--- a/src/coreclr/nativeaot/Runtime/arm64/PInvoke.asm
+++ b/src/coreclr/nativeaot/Runtime/arm64/PInvoke.asm
@@ -180,7 +180,7 @@ NoAbort
EPILOG_RESTORE_REG_PAIR fp, lr, #0xA0!
EPILOG_RETURN
- NESTED_END RhpReversePInvokeAttachOrTrapThread
+ NESTED_END RhpReversePInvokeTrapThread
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/src/coreclr/nativeaot/Runtime/eventtrace.cpp b/src/coreclr/nativeaot/Runtime/eventtrace.cpp
index 0f4646152165b..23dd9726b5ed2 100644
--- a/src/coreclr/nativeaot/Runtime/eventtrace.cpp
+++ b/src/coreclr/nativeaot/Runtime/eventtrace.cpp
@@ -35,9 +35,9 @@
#define Win32EventWrite EventWrite
// Flags used to store some runtime information for Event Tracing
-BOOL g_fEEOtherStartup = FALSE;
-BOOL g_fEEComActivatedStartup = FALSE;
-LPCGUID g_fEEComObjectGuid = &GUID_NULL;
+BOOL g_fEEOtherStartup=FALSE;
+BOOL g_fEEComActivatedStartup=FALSE;
+LPCGUID g_fEEComObjectGuid=&GUID_NULL;
BOOL g_fEEHostedStartup = FALSE;
@@ -188,16 +188,16 @@ BOOL IsRuntimeNgenKeywordEnabledAndNotSuppressed()
LIMITED_METHOD_CONTRACT;
return
- (
- ETW_TRACING_CATEGORY_ENABLED(
- MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
- TRACE_LEVEL_INFORMATION,
- CLR_NGEN_KEYWORD)
- && !(ETW_TRACING_CATEGORY_ENABLED(
+ (
+ ETW_TRACING_CATEGORY_ENABLED(
+ MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ TRACE_LEVEL_INFORMATION,
+ CLR_NGEN_KEYWORD)
+ && ! ( ETW_TRACING_CATEGORY_ENABLED(
MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
- CLR_OVERRIDEANDSUPPRESSNGENEVENTS_KEYWORD))
- );
+ CLR_OVERRIDEANDSUPPRESSNGENEVENTS_KEYWORD) )
+ );
}
// Same as above, but for the rundown provider
@@ -206,16 +206,16 @@ BOOL IsRundownNgenKeywordEnabledAndNotSuppressed()
LIMITED_METHOD_CONTRACT;
return
- (
- ETW_TRACING_CATEGORY_ENABLED(
- MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
- TRACE_LEVEL_INFORMATION,
- CLR_RUNDOWNNGEN_KEYWORD)
- && !(ETW_TRACING_CATEGORY_ENABLED(
+ (
+ ETW_TRACING_CATEGORY_ENABLED(
+ MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ TRACE_LEVEL_INFORMATION,
+ CLR_RUNDOWNNGEN_KEYWORD)
+ && ! ( ETW_TRACING_CATEGORY_ENABLED(
MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
- CLR_RUNDOWNOVERRIDEANDSUPPRESSNGENEVENTS_KEYWORD))
- );
+ CLR_RUNDOWNOVERRIDEANDSUPPRESSNGENEVENTS_KEYWORD) )
+ );
}
/*******************************************************/
@@ -226,7 +226,7 @@ extern "C"
{
CallStackFrame* GetEbp()
{
- CallStackFrame* frame = NULL;
+ CallStackFrame *frame=NULL;
__asm
{
mov frame, ebp
@@ -244,8 +244,8 @@ extern "C"
void ETW::SamplingLog::Append(SIZE_T currentFrame)
{
LIMITED_METHOD_CONTRACT;
- if (m_FrameCount < (ETW::SamplingLog::s_MaxStackSize - 1) &&
- currentFrame != 0)
+ if(m_FrameCount < (ETW::SamplingLog::s_MaxStackSize-1) &&
+ currentFrame != 0)
{
m_EBPStack[m_FrameCount] = currentFrame;
m_FrameCount++;
@@ -255,7 +255,7 @@ void ETW::SamplingLog::Append(SIZE_T currentFrame)
/********************************************************/
/* Function to get the callstack on the current thread */
/********************************************************/
-ETW::SamplingLog::EtwStackWalkStatus ETW::SamplingLog::GetCurrentThreadsCallStack(UINT32* frameCount, PVOID** Stack)
+ETW::SamplingLog::EtwStackWalkStatus ETW::SamplingLog::GetCurrentThreadsCallStack(UINT32 *frameCount, PVOID **Stack)
{
CONTRACTL
{
@@ -278,17 +278,17 @@ ETW::SamplingLog::EtwStackWalkStatus ETW::SamplingLog::GetCurrentThreadsCallStac
// this not really needed, but let's do it
// because we use the framecount while dumping the stack event
- for (int i = m_FrameCount; i < ETW::SamplingLog::s_MaxStackSize; i++)
+ for(int i=m_FrameCount; im_Next;
// Skip the top N frames
- if (skipTopNFrames) {
+ if(skipTopNFrames) {
skipTopNFrames--;
continue;
}
@@ -358,16 +358,16 @@ ETW::SamplingLog::EtwStackWalkStatus ETW::SamplingLog::SaveCurrentStack(int skip
Append(lastEBP->m_ReturnAddress);
// Check for stack limits
- if ((SIZE_T)currentEBP < (SIZE_T)Thread::GetStackLowerBound() || (SIZE_T)currentEBP >(SIZE_T)Thread::GetStackUpperBound())
+ if((SIZE_T)currentEBP < (SIZE_T)Thread::GetStackLowerBound() || (SIZE_T)currentEBP > (SIZE_T)Thread::GetStackUpperBound())
{
break;
}
// If we have a too small address, we are probably bad
- if ((SIZE_T)currentEBP < (SIZE_T)0x10000)
+ if((SIZE_T)currentEBP < (SIZE_T)0x10000)
break;
- if ((SIZE_T)currentEBP < (SIZE_T)lastEBP)
+ if((SIZE_T)currentEBP < (SIZE_T)lastEBP)
{
break;
}
@@ -378,7 +378,7 @@ ETW::SamplingLog::EtwStackWalkStatus ETW::SamplingLog::SaveCurrentStack(int skip
UINT_PTR ControlPc = 0;
UINT_PTR CurrentSP = 0, PrevSP = 0;
- while (1)
+ while(1)
{
// Unwind to the caller
ControlPc = Thread::VirtualUnwindCallFrame(&ctx);
@@ -387,13 +387,13 @@ ETW::SamplingLog::EtwStackWalkStatus ETW::SamplingLog::SaveCurrentStack(int skip
CurrentSP = (UINT_PTR)GetSP(&ctx);
// when to break from this loop
- if (ControlPc == 0 || (PrevSP == CurrentSP))
+ if ( ControlPc == 0 || ( PrevSP == CurrentSP ) )
{
break;
}
// Skip the top N frames
- if (skipTopNFrames) {
+ if ( skipTopNFrames ) {
skipTopNFrames--;
continue;
}
@@ -404,7 +404,7 @@ ETW::SamplingLog::EtwStackWalkStatus ETW::SamplingLog::SaveCurrentStack(int skip
PrevSP = CurrentSP;
}
#endif //TARGET_X86
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
pThread->MarkEtwStackWalkCompleted();
#endif //!DACCESS_COMPILE
@@ -431,7 +431,7 @@ ETW::SamplingLog::EtwStackWalkStatus ETW::SamplingLog::SaveCurrentStack(int skip
/***************************************************************************/
/* This function should be called from the event tracing callback routine
when the private CLR provider is enabled */
- /***************************************************************************/
+/***************************************************************************/
#ifndef FEATURE_REDHAWK
@@ -440,13 +440,13 @@ void ETW::GCLog::GCSettingsEvent()
if (GCHeapUtilities::IsGCHeapInitialized())
{
if (ETW_TRACING_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context,
- GCSettings))
+ GCSettings))
{
ETW::GCLog::ETW_GC_INFO Info;
- Info.GCSettings.ServerGC = GCHeapUtilities::IsServerHeap();
- Info.GCSettings.SegmentSize = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize(FALSE);
- Info.GCSettings.LargeObjectSegmentSize = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize(TRUE);
+ Info.GCSettings.ServerGC = GCHeapUtilities::IsServerHeap ();
+ Info.GCSettings.SegmentSize = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize (FALSE);
+ Info.GCSettings.LargeObjectSegmentSize = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize (TRUE);
FireEtwGCSettings_V1(Info.GCSettings.SegmentSize, Info.GCSettings.LargeObjectSegmentSize, Info.GCSettings.ServerGC, GetClrInstanceId());
}
GCHeapUtilities::GetGCHeap()->TraceGCSegments();
@@ -518,13 +518,13 @@ struct EtwGcMovementContext
// else, a new EtwGcMovementContext is allocated, stored in that pointer, and
// then returned. Callers should test for NULL, which can be returned if out of
// memory
- static EtwGcMovementContext* GetOrCreateInGCContext(EtwGcMovementContext** ppContext)
+ static EtwGcMovementContext * GetOrCreateInGCContext(EtwGcMovementContext ** ppContext)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(ppContext != NULL);
- EtwGcMovementContext* pContext = *ppContext;
+ EtwGcMovementContext * pContext = *ppContext;
if (pContext == NULL)
{
pContext = new (nothrow) EtwGcMovementContext;
@@ -597,13 +597,13 @@ struct MovedReferenceContextForEtwAndProfapi
// returned; else, a new MovedReferenceContextForEtwAndProfapi is allocated, stored
// in that pointer, and then returned. Callers should test for NULL, which can be
// returned if out of memory
- static MovedReferenceContextForEtwAndProfapi* CreateInGCContext(LPVOID pvContext)
+ static MovedReferenceContextForEtwAndProfapi * CreateInGCContext(LPVOID pvContext)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(pvContext != NULL);
- MovedReferenceContextForEtwAndProfapi* pContext = *(MovedReferenceContextForEtwAndProfapi**)pvContext;
+ MovedReferenceContextForEtwAndProfapi * pContext = *(MovedReferenceContextForEtwAndProfapi **) pvContext;
// Shouldn't be called if the context was already created. Perhaps someone made
// one too many BeginMovedReferences calls, or didn't have an EndMovedReferences
@@ -611,7 +611,7 @@ struct MovedReferenceContextForEtwAndProfapi
_ASSERTE(pContext == NULL);
pContext = new (nothrow) MovedReferenceContextForEtwAndProfapi;
- *(MovedReferenceContextForEtwAndProfapi**)pvContext = pContext;
+ *(MovedReferenceContextForEtwAndProfapi **) pvContext = pContext;
return pContext;
}
@@ -626,7 +626,7 @@ struct MovedReferenceContextForEtwAndProfapi
}
LPVOID pctxProfAPI;
- EtwGcMovementContext* pctxEtw;
+ EtwGcMovementContext * pctxEtw;
};
@@ -648,8 +648,8 @@ struct MovedReferenceContextForEtwAndProfapi
// static
void ETW::GCLog::MovedReference(
- BYTE* pbMemBlockStart,
- BYTE* pbMemBlockEnd,
+ BYTE * pbMemBlockStart,
+ BYTE * pbMemBlockEnd,
ptrdiff_t cbRelocDistance,
size_t profilingContext,
BOOL fCompacting,
@@ -665,8 +665,8 @@ void ETW::GCLog::MovedReference(
}
CONTRACTL_END;
- MovedReferenceContextForEtwAndProfapi* pCtxForEtwAndProfapi =
- (MovedReferenceContextForEtwAndProfapi*)profilingContext;
+ MovedReferenceContextForEtwAndProfapi * pCtxForEtwAndProfapi =
+ (MovedReferenceContextForEtwAndProfapi *) profilingContext;
if (pCtxForEtwAndProfapi == NULL)
{
_ASSERTE(!"MovedReference() encountered a NULL profilingContext");
@@ -678,10 +678,10 @@ void ETW::GCLog::MovedReference(
{
BEGIN_PIN_PROFILER(CORProfilerTrackGC());
g_profControlBlock.pProfInterface->MovedReference(pbMemBlockStart,
- pbMemBlockEnd,
- cbRelocDistance,
- &(pCtxForEtwAndProfapi->pctxProfAPI),
- fCompacting);
+ pbMemBlockEnd,
+ cbRelocDistance,
+ &(pCtxForEtwAndProfapi->pctxProfAPI),
+ fCompacting);
END_PIN_PROFILER();
}
#endif // PROFILING_SUPPORTED
@@ -691,7 +691,7 @@ void ETW::GCLog::MovedReference(
if (!ShouldTrackMovementForEtw())
return;
- EtwGcMovementContext* pContext =
+ EtwGcMovementContext * pContext =
EtwGcMovementContext::GetOrCreateInGCContext(&pCtxForEtwAndProfapi->pctxEtw);
if (pContext == NULL)
return;
@@ -701,7 +701,7 @@ void ETW::GCLog::MovedReference(
// Moved references
_ASSERTE(pContext->cBulkMovedObjectRanges < _countof(pContext->rgGCBulkMovedObjectRanges));
- EventStructGCBulkMovedObjectRangesValue* pValue =
+ EventStructGCBulkMovedObjectRangesValue * pValue =
&pContext->rgGCBulkMovedObjectRanges[pContext->cBulkMovedObjectRanges];
pValue->OldRangeBase = pbMemBlockStart;
pValue->NewRangeBase = pbMemBlockStart + cbRelocDistance;
@@ -727,7 +727,7 @@ void ETW::GCLog::MovedReference(
// Surviving references
_ASSERTE(pContext->cBulkSurvivingObjectRanges < _countof(pContext->rgGCBulkSurvivingObjectRanges));
- EventStructGCBulkSurvivingObjectRangesValue* pValue =
+ EventStructGCBulkSurvivingObjectRangesValue * pValue =
&pContext->rgGCBulkSurvivingObjectRanges[pContext->cBulkSurvivingObjectRanges];
pValue->RangeBase = pbMemBlockStart;
pValue->RangeLength = pbMemBlockEnd - pbMemBlockStart;
@@ -763,7 +763,7 @@ void ETW::GCLog::MovedReference(
//
// static
-void ETW::GCLog::BeginMovedReferences(size_t* pProfilingContext)
+void ETW::GCLog::BeginMovedReferences(size_t * pProfilingContext)
{
LIMITED_METHOD_CONTRACT;
@@ -794,7 +794,7 @@ void ETW::GCLog::EndMovedReferences(size_t profilingContext,
}
CONTRACTL_END;
- MovedReferenceContextForEtwAndProfapi* pCtxForEtwAndProfapi = (MovedReferenceContextForEtwAndProfapi*)profilingContext;
+ MovedReferenceContextForEtwAndProfapi * pCtxForEtwAndProfapi = (MovedReferenceContextForEtwAndProfapi *) profilingContext;
if (pCtxForEtwAndProfapi == NULL)
{
_ASSERTE(!"EndMovedReferences() encountered a NULL profilingContext");
@@ -817,7 +817,7 @@ void ETW::GCLog::EndMovedReferences(size_t profilingContext,
// If context isn't already set up for us, then we haven't been collecting any data
// for ETW events.
- EtwGcMovementContext* pContext = pCtxForEtwAndProfapi->pctxEtw;
+ EtwGcMovementContext * pContext = pCtxForEtwAndProfapi->pctxEtw;
if (pContext == NULL)
return;
@@ -893,7 +893,7 @@ void ETW::GCLog::ForceGC(LONGLONG l64ClientSequenceNumber)
//
// static
-void ETW::GCLog::FireGcStart(ETW_GC_INFO* pGcInfo)
+void ETW::GCLog::FireGcStart(ETW_GC_INFO * pGcInfo)
{
LIMITED_METHOD_CONTRACT;
@@ -924,7 +924,7 @@ void ETW::GCLog::FireGcStart(ETW_GC_INFO* pGcInfo)
FireEtwGCStart_V2(pGcInfo->GCStart.Count, pGcInfo->GCStart.Depth, pGcInfo->GCStart.Reason, pGcInfo->GCStart.Type, GetClrInstanceId(), l64ClientSequenceNumberToLog);
#elif defined(FEATURE_DTRACE)
- FireEtwGCStart(pGcInfo->GCStart.Count, pGcInfo->GCStart.Reason);
+ FireEtwGCStart(pGcInfo->GCStart.Count,pGcInfo->GCStart.Reason);
#endif
}
@@ -990,7 +990,7 @@ HRESULT ETW::GCLog::ForceGCForDiagnostics()
_ASSERTE(GCHeapUtilities::IsGCHeapInitialized());
ThreadStore::AttachCurrentThread();
- Thread* pThread = ThreadStore::GetCurrentThread();
+ Thread * pThread = ThreadStore::GetCurrentThread();
// Doing this prevents the GC from trying to walk this thread's stack for roots.
pThread->SetGCSpecial(true);
@@ -1011,11 +1011,11 @@ HRESULT ETW::GCLog::ForceGCForDiagnostics()
pThread->EnablePreemptiveMode();
#else // !FEATURE_REDHAWK
}
-EX_CATCH{ }
-EX_END_CATCH(RethrowCorruptingExceptions);
+ EX_CATCH { }
+ EX_END_CATCH(RethrowCorruptingExceptions);
#endif // FEATURE_REDHAWK
-return hr;
+ return hr;
}
@@ -1142,7 +1142,7 @@ void BulkTypeEventLogger::FireBulkTypeEvent()
#ifdef FEATURE_REDHAWK
((m_rgBulkTypeValues[iTypeData].cTypeParameters == 1) ?
&(m_rgBulkTypeValues[iTypeData].ullSingleTypeParameter) :
- (ULONGLONG*)(m_rgBulkTypeValues[iTypeData].rgTypeParameters)),
+ (ULONGLONG *) (m_rgBulkTypeValues[iTypeData].rgTypeParameters)),
#else
m_rgBulkTypeValues[iTypeData].rgTypeParameters.GetElements(),
#endif
@@ -1200,7 +1200,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th)
return -1;
}
- BulkTypeValue* pVal = &m_rgBulkTypeValues[m_nBulkTypeValueCount];
+ BulkTypeValue * pVal = &m_rgBulkTypeValues[m_nBulkTypeValueCount];
// Clear out pVal before filling it out (array elements can get reused if there
// are enough types that we need to flush to multiple events). Clearing the
@@ -1211,7 +1211,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th)
pVal->Clear();
fSucceeded = TRUE;
}
- EX_CATCH
+ EX_CATCH
{
fSucceeded = FALSE;
}
@@ -1219,11 +1219,11 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th)
if (!fSucceeded)
return -1;
- pVal->fixedSizedData.TypeID = (ULONGLONG)th.AsTAddr();
- pVal->fixedSizedData.ModuleID = (ULONGLONG)(TADDR)th.GetModule();
+ pVal->fixedSizedData.TypeID = (ULONGLONG) th.AsTAddr();
+ pVal->fixedSizedData.ModuleID = (ULONGLONG) (TADDR) th.GetModule();
pVal->fixedSizedData.TypeNameID = (th.GetMethodTable() == NULL) ? 0 : th.GetCl();
pVal->fixedSizedData.Flags = 0;
- pVal->fixedSizedData.CorElementType = (BYTE)th.GetInternalCorElementType();
+ pVal->fixedSizedData.CorElementType = (BYTE) th.GetInternalCorElementType();
if (th.IsArray())
{
@@ -1234,10 +1234,10 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th)
fSucceeded = FALSE;
EX_TRY
{
- pVal->rgTypeParameters.Append((ULONGLONG)th.AsArray()->GetArrayElementTypeHandle().AsTAddr());
+ pVal->rgTypeParameters.Append((ULONGLONG) th.AsArray()->GetArrayElementTypeHandle().AsTAddr());
fSucceeded = TRUE;
}
- EX_CATCH
+ EX_CATCH
{
fSucceeded = FALSE;
}
@@ -1254,10 +1254,10 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th)
fSucceeded = FALSE;
EX_TRY
{
- pVal->rgTypeParameters.Append((ULONGLONG)pTypeDesc->GetTypeParam().AsTAddr());
+ pVal->rgTypeParameters.Append((ULONGLONG) pTypeDesc->GetTypeParam().AsTAddr());
fSucceeded = TRUE;
}
- EX_CATCH
+ EX_CATCH
{
fSucceeded = FALSE;
}
@@ -1290,13 +1290,13 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th)
fSucceeded = FALSE;
EX_TRY
{
- for (DWORD i = 0; i < cTypeParameters; i++)
+ for (DWORD i=0; i < cTypeParameters; i++)
{
- pVal->rgTypeParameters.Append((ULONGLONG)inst[i].AsTAddr());
+ pVal->rgTypeParameters.Append((ULONGLONG) inst[i].AsTAddr());
}
fSucceeded = TRUE;
}
- EX_CATCH
+ EX_CATCH
{
fSucceeded = FALSE;
}
@@ -1332,7 +1332,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th)
}
pVal->sName.Normalize();
}
- EX_CATCH
+ EX_CATCH
{
// If this failed, the name remains empty, which is ok; the event just
// won't have a name in it.
@@ -1397,7 +1397,7 @@ void BulkTypeEventLogger::LogTypeAndParameters(ULONGLONG thAsAddr, ETW::TypeSyst
}
CONTRACTL_END;
- TypeHandle th = TypeHandle::FromTAddr((TADDR)thAsAddr);
+ TypeHandle th = TypeHandle::FromTAddr((TADDR) thAsAddr);
// Batch up this type. This grabs useful info about the type, including any
// type parameters it may have, and sticks it in m_rgBulkTypeValues
@@ -1410,7 +1410,7 @@ void BulkTypeEventLogger::LogTypeAndParameters(ULONGLONG thAsAddr, ETW::TypeSyst
}
// Look at the type info we just batched, so we can get the type parameters
- BulkTypeValue* pVal = &m_rgBulkTypeValues[iBulkTypeEventData];
+ BulkTypeValue * pVal = &m_rgBulkTypeValues[iBulkTypeEventData];
// We're about to recursively call ourselves for the type parameters, so make a
// local copy of their type handles first (else, as we log them we could flush
@@ -1428,7 +1428,7 @@ void BulkTypeEventLogger::LogTypeAndParameters(ULONGLONG thAsAddr, ETW::TypeSyst
}
fSucceeded = TRUE;
}
- EX_CATCH
+ EX_CATCH
{
fSucceeded = FALSE;
}
@@ -1443,7 +1443,7 @@ void BulkTypeEventLogger::LogTypeAndParameters(ULONGLONG thAsAddr, ETW::TypeSyst
typeLogBehavior = ETW::TypeSystemLog::kTypeLogBehaviorAssumeLockAndLogIfFirstTime;
// Recursively log any referenced parameter types
- for (COUNT_T i = 0; i < cParams; i++)
+ for (COUNT_T i=0; i < cParams; i++)
{
ETW::TypeSystemLog::LogTypeAndParametersIfNecessary(this, rgTypeParameters[i], typeLogBehavior);
}
@@ -1463,13 +1463,13 @@ class EtwGcHeapDumpContext
// ProfilerWalkHeapContext::pvEtwContext; if non-NULL it gets returned; else, a new
// EtwGcHeapDumpContext is allocated, stored in that pointer, and then returned.
// Callers should test for NULL, which can be returned if out of memory
- static EtwGcHeapDumpContext* GetOrCreateInGCContext(LPVOID* ppvEtwContext)
+ static EtwGcHeapDumpContext * GetOrCreateInGCContext(LPVOID * ppvEtwContext)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(ppvEtwContext != NULL);
- EtwGcHeapDumpContext* pContext = (EtwGcHeapDumpContext*)*ppvEtwContext;
+ EtwGcHeapDumpContext * pContext = (EtwGcHeapDumpContext *) *ppvEtwContext;
if (pContext == NULL)
{
pContext = new (nothrow) EtwGcHeapDumpContext;
@@ -1644,10 +1644,10 @@ class EtwGcHeapDumpContext
// static
void ETW::GCLog::RootReference(
LPVOID pvHandle,
- Object* pRootedNode,
- Object* pSecondaryNodeForDependentHandle,
+ Object * pRootedNode,
+ Object * pSecondaryNodeForDependentHandle,
BOOL fDependentHandle,
- ProfilingScanContext* profilingScanContext,
+ ProfilingScanContext * profilingScanContext,
DWORD dwGCFlags,
DWORD rootFlags)
{
@@ -1657,14 +1657,14 @@ void ETW::GCLog::RootReference(
if (pRootedNode == NULL)
return;
- EtwGcHeapDumpContext* pContext =
+ EtwGcHeapDumpContext * pContext =
EtwGcHeapDumpContext::GetOrCreateInGCContext(&profilingScanContext->pvEtwContext);
if (pContext == NULL)
return;
// Determine root kind, root ID, and handle-specific flags
LPVOID pvRootID = NULL;
- BYTE nRootKind = (BYTE)profilingScanContext->dwEtwRootKind;
+ BYTE nRootKind = (BYTE) profilingScanContext->dwEtwRootKind;
switch (nRootKind)
{
case kEtwGCRootKindStack:
@@ -1699,7 +1699,7 @@ void ETW::GCLog::RootReference(
{
_ASSERTE(pContext->cGCBulkRootConditionalWeakTableElementEdges <
_countof(pContext->rgGCBulkRootConditionalWeakTableElementEdges));
- EventStructGCBulkRootConditionalWeakTableElementEdgeValue* pRCWTEEdgeValue =
+ EventStructGCBulkRootConditionalWeakTableElementEdgeValue * pRCWTEEdgeValue =
&pContext->rgGCBulkRootConditionalWeakTableElementEdges[pContext->cGCBulkRootConditionalWeakTableElementEdges];
pRCWTEEdgeValue->GCKeyNodeID = pRootedNode;
pRCWTEEdgeValue->GCValueNodeID = pSecondaryNodeForDependentHandle;
@@ -1724,7 +1724,7 @@ void ETW::GCLog::RootReference(
else
{
_ASSERTE(pContext->cGcBulkRootEdges < _countof(pContext->rgGcBulkRootEdges));
- EventStructGCBulkRootEdgeValue* pBulkRootEdgeValue = &pContext->rgGcBulkRootEdges[pContext->cGcBulkRootEdges];
+ EventStructGCBulkRootEdgeValue * pBulkRootEdgeValue = &pContext->rgGcBulkRootEdges[pContext->cGcBulkRootEdges];
pBulkRootEdgeValue->RootedNodeAddress = pRootedNode;
pBulkRootEdgeValue->GCRootKind = nRootKind;
pBulkRootEdgeValue->GCRootFlag = rootFlags;
@@ -1765,11 +1765,11 @@ void ETW::GCLog::RootReference(
// static
void ETW::GCLog::ObjectReference(
- ProfilerWalkHeapContext* profilerWalkHeapContext,
- Object* pObjReferenceSource,
+ ProfilerWalkHeapContext * profilerWalkHeapContext,
+ Object * pObjReferenceSource,
ULONGLONG typeID,
ULONGLONG cRefs,
- Object** rgObjReferenceTargets)
+ Object ** rgObjReferenceTargets)
{
#ifndef WINXP_AND_WIN2K3_BUILD_SUPPORT
CONTRACTL
@@ -1783,7 +1783,7 @@ void ETW::GCLog::ObjectReference(
}
CONTRACTL_END;
- EtwGcHeapDumpContext* pContext =
+ EtwGcHeapDumpContext * pContext =
EtwGcHeapDumpContext::GetOrCreateInGCContext(&profilerWalkHeapContext->pvEtwContext);
if (pContext == NULL)
return;
@@ -1794,7 +1794,7 @@ void ETW::GCLog::ObjectReference(
// Add Node (pObjReferenceSource) to buffer
_ASSERTE(pContext->cGcBulkNodeValues < _countof(pContext->rgGcBulkNodeValues));
- EventStructGCBulkNodeValue* pBulkNodeValue = &pContext->rgGcBulkNodeValues[pContext->cGcBulkNodeValues];
+ EventStructGCBulkNodeValue * pBulkNodeValue = &pContext->rgGcBulkNodeValues[pContext->cGcBulkNodeValues];
pBulkNodeValue->Address = pObjReferenceSource;
pBulkNodeValue->Size = pObjReferenceSource->GetSize();
pBulkNodeValue->TypeID = typeID;
@@ -1830,7 +1830,7 @@ void ETW::GCLog::ObjectReference(
// During heap walk, GC holds the lock for us, so we can directly enter the
// hash to see if the type has already been logged
ETW::TypeSystemLog::kTypeLogBehaviorAssumeLockAndLogIfFirstTime
- );
+ );
}
//---------------------------------------------------------------------------------------
@@ -1842,10 +1842,10 @@ void ETW::GCLog::ObjectReference(
// a lot of edges), so empty Edge buffer into ETW as we go along, as many times as we
// need.
- for (ULONGLONG i = 0; i < cRefs; i++)
+ for (ULONGLONG i=0; i < cRefs; i++)
{
_ASSERTE(pContext->cGcBulkEdgeValues < _countof(pContext->rgGcBulkEdgeValues));
- EventStructGCBulkEdgeValue* pBulkEdgeValue = &pContext->rgGcBulkEdgeValues[pContext->cGcBulkEdgeValues];
+ EventStructGCBulkEdgeValue * pBulkEdgeValue = &pContext->rgGcBulkEdgeValues[pContext->cGcBulkEdgeValues];
pBulkEdgeValue->Value = rgObjReferenceTargets[i];
// FUTURE: ReferencingFieldID
pBulkEdgeValue->ReferencingFieldID = 0;
@@ -1878,14 +1878,14 @@ void ETW::GCLog::ObjectReference(
//
// static
-void ETW::GCLog::EndHeapDump(ProfilerWalkHeapContext* profilerWalkHeapContext)
+void ETW::GCLog::EndHeapDump(ProfilerWalkHeapContext * profilerWalkHeapContext)
{
#ifndef WINXP_AND_WIN2K3_BUILD_SUPPORT
LIMITED_METHOD_CONTRACT;
// If context isn't already set up for us, then we haven't been collecting any data
// for ETW events.
- EtwGcHeapDumpContext* pContext = (EtwGcHeapDumpContext*)profilerWalkHeapContext->pvEtwContext;
+ EtwGcHeapDumpContext * pContext = (EtwGcHeapDumpContext *) profilerWalkHeapContext->pvEtwContext;
if (pContext == NULL)
return;
@@ -1969,7 +1969,7 @@ void ETW::GCLog::EndHeapDump(ProfilerWalkHeapContext* profilerWalkHeapContext)
//
// static
-void ETW::GCLog::SendFinalizeObjectEvent(MethodTable* pMT, Object* pObj)
+void ETW::GCLog::SendFinalizeObjectEvent(MethodTable * pMT, Object * pObj)
{
CONTRACTL
{
@@ -1991,12 +1991,12 @@ void ETW::GCLog::SendFinalizeObjectEvent(MethodTable* pMT, Object* pObj)
// finalized object's type (and parameter types, if any)
ETW::TypeSystemLog::LogTypeAndParametersIfNecessary(
NULL, // Not batching this type with others
- (TADDR)pMT,
+ (TADDR) pMT,
// Don't spend the time entering the lock and checking the hash table to see
// if we've already logged the type; just log it (if type events are enabled).
ETW::TypeSystemLog::kTypeLogBehaviorAlwaysLog
- );
+ );
}
// Send private finalize object event, if it's enabled
@@ -2007,14 +2007,14 @@ void ETW::GCLog::SendFinalizeObjectEvent(MethodTable* pMT, Object* pObj)
DefineFullyQualifiedNameForClassWOnStack();
FireEtwPrvFinalizeObject(pMT, pObj, GetClrInstanceId(), GetFullyQualifiedNameForClassNestedAwareW(pMT));
}
- EX_CATCH
+ EX_CATCH
{
}
EX_END_CATCH(RethrowCorruptingExceptions);
}
}
-DWORD ETW::ThreadLog::GetEtwThreadFlags(Thread* pThread)
+DWORD ETW::ThreadLog::GetEtwThreadFlags(Thread * pThread)
{
LIMITED_METHOD_CONTRACT;
@@ -2037,7 +2037,7 @@ DWORD ETW::ThreadLog::GetEtwThreadFlags(Thread* pThread)
return dwEtwThreadFlags;
}
-void ETW::ThreadLog::FireThreadCreated(Thread* pThread)
+void ETW::ThreadLog::FireThreadCreated(Thread * pThread)
{
LIMITED_METHOD_CONTRACT;
@@ -2050,7 +2050,7 @@ void ETW::ThreadLog::FireThreadCreated(Thread* pThread)
GetClrInstanceId());
}
-void ETW::ThreadLog::FireThreadDC(Thread* pThread)
+void ETW::ThreadLog::FireThreadDC(Thread * pThread)
{
LIMITED_METHOD_CONTRACT;
@@ -2088,7 +2088,7 @@ class LoggedTypesFromModuleTraits : public NoRemoveSHashTraits< DefaultSHashTrai
typedef TypeHandle key_t;
- static key_t GetKey(const element_t& e)
+ static key_t GetKey(const element_t &e)
{
LIMITED_METHOD_CONTRACT;
return e.th;
@@ -2103,10 +2103,10 @@ class LoggedTypesFromModuleTraits : public NoRemoveSHashTraits< DefaultSHashTrai
static count_t Hash(key_t k)
{
LIMITED_METHOD_CONTRACT;
- return (count_t)k.AsTAddr();
+ return (count_t) k.AsTAddr();
}
- static bool IsNull(const element_t& e)
+ static bool IsNull(const element_t &e)
{
LIMITED_METHOD_CONTRACT;
return (e.th.AsTAddr() == NULL);
@@ -2125,23 +2125,23 @@ typedef SHash LoggedTypesFromModuleHash;
class ETW::LoggedTypesFromModule
{
public:
- Module* pModule;
+ Module * pModule;
LoggedTypesFromModuleHash loggedTypesFromModuleHash;
// These are used by the outer hash table (mapping Module*'s to instances of
// LoggedTypesFromModule).
- static COUNT_T Hash(Module* pModule)
+ static COUNT_T Hash(Module * pModule)
{
LIMITED_METHOD_CONTRACT;
- return (COUNT_T)(SIZE_T)pModule;
+ return (COUNT_T) (SIZE_T) pModule;
}
- Module* GetKey()
+ Module * GetKey()
{
LIMITED_METHOD_CONTRACT;
return pModule;
}
- LoggedTypesFromModule(Module* pModuleParam) : loggedTypesFromModuleHash()
+ LoggedTypesFromModule(Module * pModuleParam) : loggedTypesFromModuleHash()
{
LIMITED_METHOD_CONTRACT;
pModule = pModuleParam;
@@ -2156,19 +2156,19 @@ class ETW::LoggedTypesFromModule
// The following define the outer hash table (mapping Module*'s to instances of
// LoggedTypesFromModule).
-class AllLoggedTypesTraits : public DefaultSHashTraits
+class AllLoggedTypesTraits : public DefaultSHashTraits
{
public:
// explicitly declare local typedefs for these traits types, otherwise
// the compiler may get confused
- typedef DefaultSHashTraits PARENT;
+ typedef DefaultSHashTraits PARENT;
typedef PARENT::element_t element_t;
typedef PARENT::count_t count_t;
- typedef Module* key_t;
+ typedef Module * key_t;
- static key_t GetKey(const element_t& e)
+ static key_t GetKey(const element_t &e)
{
LIMITED_METHOD_CONTRACT;
return e->pModule;
@@ -2183,10 +2183,10 @@ class AllLoggedTypesTraits : public DefaultSHashTraitsloggedTypesFromModuleHash.AddOrReplace(*pTypeLoggingInfo);
fSucceeded = TRUE;
}
- EX_CATCH
+ EX_CATCH
{
fSucceeded = FALSE;
}
@@ -2447,7 +2447,7 @@ BOOL ETW::TypeSystemLog::AddOrReplaceTypeLoggingInfo(ETW::LoggedTypesFromModule*
//
// static
-void ETW::TypeSystemLog::SendObjectAllocatedEvent(Object* pObject)
+void ETW::TypeSystemLog::SendObjectAllocatedEvent(Object * pObject)
{
CONTRACTL
{
@@ -2465,7 +2465,7 @@ void ETW::TypeSystemLog::SendObjectAllocatedEvent(Object* pObject)
TypeHandle th = pObject->GetTypeHandle();
SIZE_T size = pObject->GetSize();
- if (size < MIN_OBJECT_SIZE)
+ if(size < MIN_OBJECT_SIZE)
{
size = PtrAlign(size);
}
@@ -2481,7 +2481,7 @@ void ETW::TypeSystemLog::SendObjectAllocatedEvent(Object* pObject)
// Get stats for type
TypeLoggingInfo typeLoggingInfo(NULL);
- LoggedTypesFromModule* pLoggedTypesFromModule = NULL;
+ LoggedTypesFromModule * pLoggedTypesFromModule = NULL;
BOOL fCreatedNew = FALSE;
typeLoggingInfo = LookupOrCreateTypeLoggingInfo(th, &fCreatedNew, &pLoggedTypesFromModule);
if (typeLoggingInfo.th.IsNull())
@@ -2524,19 +2524,19 @@ void ETW::TypeSystemLog::SendObjectAllocatedEvent(Object* pObject)
int nMinAllocPerMSec = typeLoggingInfo.dwAllocCountInCurrentBucket / 16; // This is an underestimation of the true rate.
if (delta >= 16 || (nMinAllocPerMSec > 2 && nMinAllocPerMSec > typeLoggingInfo.flAllocPerMSec * 1.5F))
{
- float flNewAllocPerMSec = 0;
+ float flNewAllocPerMSec = 0;
if (delta >= 16)
{
// This is the normal case, our allocation rate is under control with the current throttling.
- flNewAllocPerMSec = ((float)typeLoggingInfo.dwAllocCountInCurrentBucket) / delta;
+ flNewAllocPerMSec = ((float) typeLoggingInfo.dwAllocCountInCurrentBucket) / delta;
// Do a exponential decay window that is 5 * max(16, AllocationInterval)
- typeLoggingInfo.flAllocPerMSec = 0.8F * typeLoggingInfo.flAllocPerMSec + 0.2F * flNewAllocPerMSec;
+ typeLoggingInfo.flAllocPerMSec = 0.8F * typeLoggingInfo.flAllocPerMSec + 0.2F * flNewAllocPerMSec;
typeLoggingInfo.dwTickOfCurrentTimeBucket = dwTickNow;
typeLoggingInfo.dwAllocCountInCurrentBucket = 0;
}
else
{
- flNewAllocPerMSec = (float)nMinAllocPerMSec;
+ flNewAllocPerMSec = (float) nMinAllocPerMSec;
// This means the second clause above is true, which means our sampling rate is too low
// so we need to throttle quickly.
typeLoggingInfo.flAllocPerMSec = flNewAllocPerMSec;
@@ -2546,7 +2546,7 @@ void ETW::TypeSystemLog::SendObjectAllocatedEvent(Object* pObject)
// Obey the desired sampling rate, but don't ignore > 1000 allocations per second
// per type
int nDesiredMsBetweenEvents = (s_nCustomMsBetweenEvents == 0) ? GetDefaultMsBetweenEvents() : s_nCustomMsBetweenEvents;
- typeLoggingInfo.dwAllocsToSkipPerSample = min((int)(typeLoggingInfo.flAllocPerMSec * nDesiredMsBetweenEvents), 1000);
+ typeLoggingInfo.dwAllocsToSkipPerSample = min((int) (typeLoggingInfo.flAllocPerMSec * nDesiredMsBetweenEvents), 1000);
if (typeLoggingInfo.dwAllocsToSkipPerSample == 1)
typeLoggingInfo.dwAllocsToSkipPerSample = 0;
}
@@ -2586,11 +2586,11 @@ void ETW::TypeSystemLog::SendObjectAllocatedEvent(Object* pObject)
// Now log the allocation
if (s_fHeapAllocHighEventEnabledNow)
{
- FireEtwGCSampledObjectAllocationHigh(pObject, (LPVOID)th.AsTAddr(), dwObjectCountForTypeSample, nTotalSizeForTypeSample, GetClrInstanceId());
+ FireEtwGCSampledObjectAllocationHigh(pObject, (LPVOID) th.AsTAddr(), dwObjectCountForTypeSample, nTotalSizeForTypeSample, GetClrInstanceId());
}
else
{
- FireEtwGCSampledObjectAllocationLow(pObject, (LPVOID)th.AsTAddr(), dwObjectCountForTypeSample, nTotalSizeForTypeSample, GetClrInstanceId());
+ FireEtwGCSampledObjectAllocationLow(pObject, (LPVOID) th.AsTAddr(), dwObjectCountForTypeSample, nTotalSizeForTypeSample, GetClrInstanceId());
}
}
@@ -2603,7 +2603,7 @@ void ETW::TypeSystemLog::SendObjectAllocatedEvent(Object* pObject)
//
// static
-CrstBase* ETW::TypeSystemLog::GetHashCrst()
+CrstBase * ETW::TypeSystemLog::GetHashCrst()
{
LIMITED_METHOD_CONTRACT;
return &AllLoggedTypes::s_cs;
@@ -2629,7 +2629,7 @@ CrstBase* ETW::TypeSystemLog::GetHashCrst()
//
// static
-void ETW::TypeSystemLog::LogTypeAndParametersIfNecessary(BulkTypeEventLogger* pLogger, ULONGLONG thAsAddr, TypeLogBehavior typeLogBehavior)
+void ETW::TypeSystemLog::LogTypeAndParametersIfNecessary(BulkTypeEventLogger * pLogger, ULONGLONG thAsAddr, TypeLogBehavior typeLogBehavior)
{
CONTRACTL
{
@@ -2650,7 +2650,7 @@ void ETW::TypeSystemLog::LogTypeAndParametersIfNecessary(BulkTypeEventLogger* pL
return;
}
- TypeHandle th = TypeHandle::FromTAddr((TADDR)thAsAddr);
+ TypeHandle th = TypeHandle::FromTAddr((TADDR) thAsAddr);
if (!th.IsRestored())
{
return;
@@ -2661,11 +2661,11 @@ void ETW::TypeSystemLog::LogTypeAndParametersIfNecessary(BulkTypeEventLogger* pL
// through to the logging code below. If caller doesn't care, then don't even
// check; just log the type
BOOL fShouldLogType = ((typeLogBehavior == kTypeLogBehaviorAlwaysLog) ||
- (typeLogBehavior == kTypeLogBehaviorAssumeLockAndAlwaysLogTopLevelType)) ?
- TRUE :
- ((typeLogBehavior == kTypeLogBehaviorTakeLockAndLogIfFirstTime) ?
- ShouldLogType(th) :
- ShouldLogTypeNoLock(th));
+ (typeLogBehavior == kTypeLogBehaviorAssumeLockAndAlwaysLogTopLevelType)) ?
+ TRUE :
+ ((typeLogBehavior == kTypeLogBehaviorTakeLockAndLogIfFirstTime) ?
+ ShouldLogType(th) :
+ ShouldLogTypeNoLock(th));
if (!fShouldLogType)
return;
@@ -2767,7 +2767,7 @@ BOOL ETW::TypeSystemLog::ShouldLogTypeNoLock(TypeHandle th)
//
// static
-ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandle th, BOOL* pfCreatedNew, LoggedTypesFromModule** ppLoggedTypesFromModule /* = NULL */)
+ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandle th, BOOL * pfCreatedNew, LoggedTypesFromModule ** ppLoggedTypesFromModule /* = NULL */)
{
LIMITED_METHOD_CONTRACT;
@@ -2794,9 +2794,9 @@ ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandl
// Step 1: go from LoaderModule to hash of types.
- Module* pLoaderModule = th.GetLoaderModule();
+ Module * pLoaderModule = th.GetLoaderModule();
_ASSERTE(pLoaderModule != NULL);
- LoggedTypesFromModule* pLoggedTypesFromModule = s_pAllLoggedTypes->allLoggedTypesHash.Lookup(pLoaderModule);
+ LoggedTypesFromModule * pLoggedTypesFromModule = s_pAllLoggedTypes->allLoggedTypesHash.Lookup(pLoaderModule);
if (pLoggedTypesFromModule == NULL)
{
pLoggedTypesFromModule = new (nothrow) LoggedTypesFromModule(pLoaderModule);
@@ -2813,7 +2813,7 @@ ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandl
s_pAllLoggedTypes->allLoggedTypesHash.Add(pLoggedTypesFromModule);
fSucceeded = TRUE;
}
- EX_CATCH
+ EX_CATCH
{
fSucceeded = FALSE;
}
@@ -2850,7 +2850,7 @@ ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandl
pLoggedTypesFromModule->loggedTypesFromModuleHash.Add(typeLoggingInfoNew);
fSucceeded = TRUE;
}
- EX_CATCH
+ EX_CATCH
{
fSucceeded = FALSE;
}
@@ -2876,7 +2876,7 @@ ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandl
//
// static
-void ETW::TypeSystemLog::OnModuleUnload(Module* pModule)
+void ETW::TypeSystemLog::OnModuleUnload(Module * pModule)
{
CONTRACTL
{
@@ -2895,7 +2895,7 @@ void ETW::TypeSystemLog::OnModuleUnload(Module* pModule)
return;
}
- LoggedTypesFromModule* pLoggedTypesFromModule = NULL;
+ LoggedTypesFromModule * pLoggedTypesFromModule = NULL;
{
CrstHolder _crst(GetHashCrst());
@@ -2943,12 +2943,12 @@ void ETW::TypeSystemLog::OnTypesKeywordTurnedOff()
return;
// Destruct each of the per-module TypesHashes
- AllLoggedTypesHash* pLoggedTypesHash = &s_pAllLoggedTypes->allLoggedTypesHash;
+ AllLoggedTypesHash * pLoggedTypesHash = &s_pAllLoggedTypes->allLoggedTypesHash;
for (AllLoggedTypesHash::Iterator iter = pLoggedTypesHash->Begin();
- iter != pLoggedTypesHash->End();
- ++iter)
+ iter != pLoggedTypesHash->End();
+ ++iter)
{
- LoggedTypesFromModule* pLoggedTypesFromModule = *iter;
+ LoggedTypesFromModule * pLoggedTypesFromModule = *iter;
delete pLoggedTypesFromModule;
}
@@ -2962,10 +2962,10 @@ void ETW::TypeSystemLog::OnTypesKeywordTurnedOff()
/****************************************************************************/
/* Called when ETW is turned ON on an existing process and ModuleRange events are to
be fired */
- /****************************************************************************/
+/****************************************************************************/
void ETW::EnumerationLog::ModuleRangeRundown()
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
} CONTRACTL_END;
@@ -2978,7 +2978,7 @@ void ETW::EnumerationLog::ModuleRangeRundown()
{
ETW::EnumerationLog::EnumerationHelper(NULL, NULL, ETW::EnumerationLog::EnumerationStructs::ModuleRangeLoadPrivate);
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/****************************************************************************/
@@ -2986,7 +2986,7 @@ void ETW::EnumerationLog::ModuleRangeRundown()
/****************************************************************************/
void ETW::EnumerationLog::StartRundown()
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
} CONTRACTL_END;
@@ -3004,7 +3004,7 @@ void ETW::EnumerationLog::StartRundown()
TRACE_LEVEL_INFORMATION,
CLR_RUNDOWNTHREADING_KEYWORD);
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_RUNDOWNJIT_KEYWORD)
||
@@ -3028,30 +3028,30 @@ void ETW::EnumerationLog::StartRundown()
FireEtwDCStartInit_V1(GetClrInstanceId());
// The rundown flag is expected to be checked in the caller, so no need to check here again
- DWORD enumerationOptions = ETW::EnumerationLog::EnumerationStructs::None;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ DWORD enumerationOptions=ETW::EnumerationLog::EnumerationStructs::None;
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_RUNDOWNLOADER_KEYWORD))
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart;
}
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_RUNDOWNJIT_KEYWORD))
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::JitMethodDCStart;
}
- if (IsRundownNgenKeywordEnabledAndNotSuppressed())
+ if(IsRundownNgenKeywordEnabledAndNotSuppressed())
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::NgenMethodDCStart;
}
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_RUNDOWNJITTEDMETHODILTONATIVEMAP_KEYWORD))
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::MethodDCStartILToNativeMap;
}
- if (bIsPerfTrackRundownEnabled)
+ if(bIsPerfTrackRundownEnabled)
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCStart;
}
@@ -3076,7 +3076,7 @@ void ETW::EnumerationLog::StartRundown()
// end marker event will go to the rundown provider
FireEtwDCStartComplete_V1(GetClrInstanceId());
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
//---------------------------------------------------------------------------------------
@@ -3094,26 +3094,26 @@ DWORD ETW::EnumerationLog::GetEnumerationOptionsFromRuntimeKeywords()
{
LIMITED_METHOD_CONTRACT;
- DWORD enumerationOptions = ETW::EnumerationLog::EnumerationStructs::None;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ DWORD enumerationOptions=ETW::EnumerationLog::EnumerationStructs::None;
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_LOADER_KEYWORD))
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload;
}
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_JIT_KEYWORD) &&
ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
- TRACE_LEVEL_INFORMATION,
- CLR_ENDENUMERATION_KEYWORD))
+ TRACE_LEVEL_INFORMATION,
+ CLR_ENDENUMERATION_KEYWORD))
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::JitMethodUnload;
}
- if (IsRuntimeNgenKeywordEnabledAndNotSuppressed() &&
+ if(IsRuntimeNgenKeywordEnabledAndNotSuppressed() &&
ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
- TRACE_LEVEL_INFORMATION,
- CLR_ENDENUMERATION_KEYWORD))
+ TRACE_LEVEL_INFORMATION,
+ CLR_ENDENUMERATION_KEYWORD))
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::NgenMethodUnload;
}
@@ -3149,7 +3149,7 @@ void ETW::EnumerationLog::EnumerateForCaptureState()
EX_TRY
{
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, TRACE_LEVEL_INFORMATION, KEYWORDZERO))
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, TRACE_LEVEL_INFORMATION, KEYWORDZERO))
{
DWORD enumerationOptions = GetEnumerationOptionsFromRuntimeKeywords();
@@ -3165,7 +3165,7 @@ void ETW::EnumerationLog::EnumerateForCaptureState()
SendThreadRundownEvent();
}
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/**************************************************************************************/
@@ -3173,7 +3173,7 @@ void ETW::EnumerationLog::EnumerateForCaptureState()
/**************************************************************************************/
void ETW::EnumerationLog::EndRundown()
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
} CONTRACTL_END;
@@ -3187,7 +3187,7 @@ void ETW::EnumerationLog::EndRundown()
MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_RUNDOWNTHREADING_KEYWORD);
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_RUNDOWNJIT_KEYWORD)
||
@@ -3210,30 +3210,30 @@ void ETW::EnumerationLog::EndRundown()
FireEtwDCEndInit_V1(GetClrInstanceId());
// The rundown flag is expected to be checked in the caller, so no need to check here again
- DWORD enumerationOptions = ETW::EnumerationLog::EnumerationStructs::None;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ DWORD enumerationOptions=ETW::EnumerationLog::EnumerationStructs::None;
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_RUNDOWNLOADER_KEYWORD))
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd;
}
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_RUNDOWNJIT_KEYWORD))
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::JitMethodDCEnd;
}
- if (IsRundownNgenKeywordEnabledAndNotSuppressed())
+ if(IsRundownNgenKeywordEnabledAndNotSuppressed())
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::NgenMethodDCEnd;
}
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_RUNDOWNJITTEDMETHODILTONATIVEMAP_KEYWORD))
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::MethodDCEndILToNativeMap;
}
- if (bIsPerfTrackRundownEnabled)
+ if(bIsPerfTrackRundownEnabled)
{
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCEnd;
}
@@ -3248,7 +3248,7 @@ void ETW::EnumerationLog::EndRundown()
// end marker event will go to the rundown provider
FireEtwDCEndComplete_V1(GetClrInstanceId());
}
- } EX_CATCH{
+ } EX_CATCH {
STRESS_LOG1(LF_ALWAYS, LL_ERROR, "Exception during Rundown Enumeration, EIP of last AV = %p", g_LastAccessViolationEIP);
} EX_END_CATCH(SwallowAllExceptions);
}
@@ -3290,9 +3290,9 @@ void InitializeEventTracing()
// Register CLR providers with the OS
if (g_pEtwTracer == NULL)
{
- NewHolder tempEtwTracer(new (nothrow) ETW::CEtwTracer());
- if (tempEtwTracer != NULL && tempEtwTracer->Register() == ERROR_SUCCESS)
- g_pEtwTracer = tempEtwTracer.Extract();
+ NewHolder tempEtwTracer (new (nothrow) ETW::CEtwTracer());
+ if (tempEtwTracer != NULL && tempEtwTracer->Register () == ERROR_SUCCESS)
+ g_pEtwTracer = tempEtwTracer.Extract ();
}
g_nClrInstanceId = GetRuntimeId() & 0x0000FFFF; // This will give us duplicate ClrInstanceId after UINT16_MAX
@@ -3375,44 +3375,37 @@ HRESULT ETW::CEtwTracer::UnRegister()
extern "C"
{
ETW_INLINE
- void EtwCallout(REGHANDLE RegHandle,
- PCEVENT_DESCRIPTOR Descriptor,
- ULONG ArgumentCount,
- PEVENT_DATA_DESCRIPTOR EventData)
+ void EtwCallout(REGHANDLE RegHandle,
+ PCEVENT_DESCRIPTOR Descriptor,
+ ULONG ArgumentCount,
+ PEVENT_DATA_DESCRIPTOR EventData)
{
WRAPPER_NO_CONTRACT;
UINT8 providerIndex = 0;
- if (RegHandle == Microsoft_Windows_DotNETRuntimeHandle) {
+ if(RegHandle == Microsoft_Windows_DotNETRuntimeHandle) {
providerIndex = 0;
- }
- else if (RegHandle == Microsoft_Windows_DotNETRuntimeRundownHandle) {
+ } else if(RegHandle == Microsoft_Windows_DotNETRuntimeRundownHandle) {
providerIndex = 1;
- }
- else if (RegHandle == Microsoft_Windows_DotNETRuntimeStressHandle) {
+ } else if(RegHandle == Microsoft_Windows_DotNETRuntimeStressHandle) {
providerIndex = 2;
- }
- else if (RegHandle == Microsoft_Windows_DotNETRuntimePrivateHandle) {
+ } else if(RegHandle == Microsoft_Windows_DotNETRuntimePrivateHandle) {
providerIndex = 3;
- }
- else {
+ } else {
_ASSERTE(!"Provider not one of Runtime, Rundown, Private and Stress");
return;
}
// stacks are supposed to be fired for only the events with a bit set in the etwStackSupportedEvents bitmap
- if (((etwStackSupportedEvents[providerIndex][Descriptor->Id / 8]) &
- (1 << (Descriptor->Id % 8))) != 0)
+ if(((etwStackSupportedEvents[providerIndex][Descriptor->Id/8]) &
+ (1<<(Descriptor->Id%8))) != 0)
{
- if (RegHandle == Microsoft_Windows_DotNETRuntimeHandle) {
+ if(RegHandle == Microsoft_Windows_DotNETRuntimeHandle) {
ETW::SamplingLog::SendStackTrace(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, &CLRStackWalk, &CLRStackId);
- }
- else if (RegHandle == Microsoft_Windows_DotNETRuntimeRundownHandle) {
+ } else if(RegHandle == Microsoft_Windows_DotNETRuntimeRundownHandle) {
ETW::SamplingLog::SendStackTrace(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context, &CLRStackWalkDCStart, &CLRStackRundownId);
- }
- else if (RegHandle == Microsoft_Windows_DotNETRuntimePrivateHandle) {
+ } else if(RegHandle == Microsoft_Windows_DotNETRuntimePrivateHandle) {
ETW::SamplingLog::SendStackTrace(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, &CLRStackWalkPrivate, &CLRStackPrivateId);
- }
- else if (RegHandle == Microsoft_Windows_DotNETRuntimeStressHandle) {
+ } else if(RegHandle == Microsoft_Windows_DotNETRuntimeStressHandle) {
ETW::SamplingLog::SendStackTrace(MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_Context, &CLRStackWalkStress, &CLRStackStressId);
}
}
@@ -3437,23 +3430,22 @@ extern "C"
// action in this class, we pass "this" during provider registration and modify the
// context to the relevant context in the C callback later.
ETW_INLINE
- void EtwCallback(
- _In_ LPCGUID SourceId,
- _In_ ULONG ControlCode,
- _In_ UCHAR Level,
- _In_ ULONGLONG MatchAnyKeyword,
- _In_ ULONGLONG MatchAllKeyword,
- _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,
- _Inout_opt_ PVOID CallbackContext)
- {
- CONTRACTL{
+ void EtwCallback(
+ _In_ LPCGUID SourceId,
+ _In_ ULONG ControlCode,
+ _In_ UCHAR Level,
+ _In_ ULONGLONG MatchAnyKeyword,
+ _In_ ULONGLONG MatchAllKeyword,
+ _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,
+ _Inout_opt_ PVOID CallbackContext)
+ {
+ CONTRACTL {
NOTHROW;
- if (g_fEEStarted) { GC_TRIGGERS; }
- else { DISABLED(GC_NOTRIGGER); };
-MODE_ANY;
-CAN_TAKE_LOCK;
-STATIC_CONTRACT_FAULT;
-SO_NOT_MAINLINE;
+ if(g_fEEStarted) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);};
+ MODE_ANY;
+ CAN_TAKE_LOCK;
+ STATIC_CONTRACT_FAULT;
+ SO_NOT_MAINLINE;
} CONTRACTL_END;
// Mark that we are the special ETWRundown thread. Currently all this does
@@ -3467,21 +3459,21 @@ SO_NOT_MAINLINE;
BOOLEAN bIsPublicTraceHandle =
#ifdef WINXP_AND_WIN2K3_BUILD_SUPPORT
- McGenPreVista ? ((ULONGLONG)Microsoft_Windows_DotNETRuntimeHandle == (ULONGLONG)context) :
+ McGenPreVista ? ((ULONGLONG)Microsoft_Windows_DotNETRuntimeHandle==(ULONGLONG)context) :
#endif
- (context->RegistrationHandle == Microsoft_Windows_DotNETRuntimeHandle);
+ (context->RegistrationHandle==Microsoft_Windows_DotNETRuntimeHandle);
BOOLEAN bIsPrivateTraceHandle =
#ifdef WINXP_AND_WIN2K3_BUILD_SUPPORT
- McGenPreVista ? ((ULONGLONG)Microsoft_Windows_DotNETRuntimePrivateHandle == (ULONGLONG)context) :
+ McGenPreVista ? ((ULONGLONG)Microsoft_Windows_DotNETRuntimePrivateHandle==(ULONGLONG)context) :
#endif
- (context->RegistrationHandle == Microsoft_Windows_DotNETRuntimePrivateHandle);
+ (context->RegistrationHandle==Microsoft_Windows_DotNETRuntimePrivateHandle);
BOOLEAN bIsRundownTraceHandle =
#ifdef WINXP_AND_WIN2K3_BUILD_SUPPORT
- McGenPreVista ? ((ULONGLONG)Microsoft_Windows_DotNETRuntimeRundownHandle == (ULONGLONG)context) :
+ McGenPreVista ? ((ULONGLONG)Microsoft_Windows_DotNETRuntimeRundownHandle==(ULONGLONG)context) :
#endif
- (context->RegistrationHandle == Microsoft_Windows_DotNETRuntimeRundownHandle);
+ (context->RegistrationHandle==Microsoft_Windows_DotNETRuntimeRundownHandle);
// A manifest based provider can be enabled to multiple event tracing sessions
@@ -3490,8 +3482,8 @@ SO_NOT_MAINLINE;
// IsEnabled will be TRUE when it is enabled and FALSE when disabled
BOOL bEnabled =
((ControlCode == EVENT_CONTROL_CODE_ENABLE_PROVIDER) ||
- (ControlCode == EVENT_CONTROL_CODE_CAPTURE_STATE));
- if (bEnabled)
+ (ControlCode == EVENT_CONTROL_CODE_CAPTURE_STATE));
+ if(bEnabled)
{
// TypeSystemLog needs a notification when certain keywords are modified, so
// give it a hook here.
@@ -3503,7 +3495,7 @@ SO_NOT_MAINLINE;
if (bIsPrivateTraceHandle)
{
ETW::GCLog::GCSettingsEvent();
- if (g_fEEStarted && !g_fEEShutDown)
+ if(g_fEEStarted && !g_fEEShutDown)
{
ETW::EnumerationLog::ModuleRangeRundown();
}
@@ -3513,10 +3505,10 @@ SO_NOT_MAINLINE;
// If we have turned on the JIT keyword to the VERBOSE setting (needed to get JIT names) then
// we assume that we also want good stack traces so we need to publish unwind information so
// ETW can get at it
- if (bIsPublicTraceHandle && ETW_CATEGORY_ENABLED((*context), TRACE_LEVEL_VERBOSE, CLR_RUNDOWNJIT_KEYWORD))
+ if(bIsPublicTraceHandle && ETW_CATEGORY_ENABLED((*context), TRACE_LEVEL_VERBOSE, CLR_RUNDOWNJIT_KEYWORD))
UnwindInfoTable::PublishUnwindInfo(g_fEEStarted != FALSE);
#endif
- if (g_fEEStarted && !g_fEEShutDown && bIsRundownTraceHandle)
+ if(g_fEEStarted && !g_fEEShutDown && bIsRundownTraceHandle)
{
// Fire the runtime information event
ETW::InfoLog::RuntimeInformation(ETW::InfoLog::InfoStructs::Callback);
@@ -3524,15 +3516,15 @@ SO_NOT_MAINLINE;
// Start and End Method/Module Rundowns
// Used to fire events that we missed since we started the controller after the process started
// flags for immediate start rundown
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
- TRACE_LEVEL_INFORMATION,
- CLR_RUNDOWNSTART_KEYWORD))
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ TRACE_LEVEL_INFORMATION,
+ CLR_RUNDOWNSTART_KEYWORD))
ETW::EnumerationLog::StartRundown();
// flags delayed end rundown
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
- TRACE_LEVEL_INFORMATION,
- CLR_RUNDOWNEND_KEYWORD))
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
+ TRACE_LEVEL_INFORMATION,
+ CLR_RUNDOWNEND_KEYWORD))
ETW::EnumerationLog::EndRundown();
}
@@ -3553,7 +3545,7 @@ SO_NOT_MAINLINE;
(FilterData->Type == 1) &&
(FilterData->Size == sizeof(l64ClientSequenceNumber)))
{
- l64ClientSequenceNumber = *(LONGLONG*)(FilterData->Ptr);
+ l64ClientSequenceNumber = *(LONGLONG *) (FilterData->Ptr);
}
ETW::GCLog::ForceGC(l64ClientSequenceNumber);
}
@@ -3574,7 +3566,7 @@ SO_NOT_MAINLINE;
/* in its printf API, we cast the unicode string to UFT8 string and then output them. */
/**************************************************************************************/
#define DTRACE_OUTPUT_STRING_LEN 512
-const CHAR szDtraceOutputNULL[] = "NULL";
+const CHAR szDtraceOutputNULL[]="NULL";
INT32 WideCharToMultiByte(LPCWSTR wszSrcStr, LPSTR szDstStr);
#include
@@ -3594,7 +3586,7 @@ ULONG ETW::CEtwTracer::Register()
// Get Env Var COMPlus_ETWEnabled
char szETWEnabled[SIZE_ETWEnabled];
DWORD newLen = GetEnvironmentVariableA("COMPlus_ETWEnabled", szETWEnabled, SIZE_ETWEnabled);
- if (newLen == 0 || newLen >= SIZE_ETWEnabled || strcmp(szETWEnabled, "1") != 0)
+ if (newLen == 0 || newLen >= SIZE_ETWEnabled || strcmp(szETWEnabled, "1") != 0)
return 0;
// Get Env Var COMPlus_EventInfo
@@ -3629,12 +3621,12 @@ INT32 WideCharToMultiByte(LPCWSTR wszSrcStr, LPSTR szDstStr)
{
return 0;
}
- if (nSize > DTRACE_OUTPUT_STRING_LEN - 1)
+ if (nSize > DTRACE_OUTPUT_STRING_LEN-1)
{
- nSize = DTRACE_OUTPUT_STRING_LEN - 1;
+ nSize = DTRACE_OUTPUT_STRING_LEN-1;
}
- INT32 nSize2 = WideCharToMultiByte(CP_UTF8, 0, wszSrcStr, -1, szDstStr, nSize, NULL, NULL);
- if (nSize2 != nSize || nSize2 <= 0)
+ INT32 nSize2 = WideCharToMultiByte(CP_UTF8, 0, wszSrcStr, -1, szDstStr, nSize, NULL, NULL);
+ if(nSize2 != nSize || nSize2 <=0 )
{
return 0;
}
@@ -3809,20 +3801,20 @@ void SecurityCatchCallEnd_V1()
/****************************************************************************/
/* This is called by the runtime when an exception is thrown */
/****************************************************************************/
-void ETW::ExceptionLog::ExceptionThrown(CrawlFrame* pCf, BOOL bIsReThrownException, BOOL bIsNewException)
+void ETW::ExceptionLog::ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownException, BOOL bIsNewException)
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
PRECONDITION(GetThread() != NULL);
PRECONDITION(GetThread()->GetThrowable() != NULL);
} CONTRACTL_END;
- if (!(bIsReThrownException || bIsNewException))
+ if(!(bIsReThrownException || bIsNewException))
{
return;
}
- if (!ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ExceptionThrown_V1))
+ if(!ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ExceptionThrown_V1))
{
return;
}
@@ -3830,11 +3822,11 @@ void ETW::ExceptionLog::ExceptionThrown(CrawlFrame* pCf, BOOL bIsReThrownExcepti
{
SString exceptionType(L"");
LPWSTR exceptionMessage = NULL;
- BOOL bIsCLSCompliant = FALSE, bIsCSE = FALSE, bIsNestedException = FALSE, bHasInnerException = FALSE;
- UINT16 exceptionFlags = 0;
- PVOID exceptionEIP = 0;
+ BOOL bIsCLSCompliant=FALSE, bIsCSE=FALSE, bIsNestedException=FALSE, bHasInnerException=FALSE;
+ UINT16 exceptionFlags=0;
+ PVOID exceptionEIP=0;
- Thread* pThread = GetThread();
+ Thread *pThread = GetThread();
struct
{
@@ -3848,7 +3840,7 @@ void ETW::ExceptionLog::ExceptionThrown(CrawlFrame* pCf, BOOL bIsReThrownExcepti
gc.exceptionObj = pThread->GetThrowable();
gc.innerExceptionObj = ((EXCEPTIONREF)gc.exceptionObj)->GetInnerException();
- ThreadExceptionState* pExState = pThread->GetExceptionState();
+ ThreadExceptionState *pExState = pThread->GetExceptionState();
#ifndef WIN64EXCEPTIONS
PTR_ExInfo pExInfo = NULL;
#else
@@ -3863,7 +3855,7 @@ void ETW::ExceptionLog::ExceptionThrown(CrawlFrame* pCf, BOOL bIsReThrownExcepti
// A rethrown exception is also a nested exception
// but since we have a separate flag for it, lets unset the nested flag
- if (bIsReThrownException)
+ if(bIsReThrownException)
{
bIsNestedException = FALSE;
}
@@ -3895,12 +3887,12 @@ void ETW::ExceptionLog::ExceptionThrown(CrawlFrame* pCf, BOOL bIsReThrownExcepti
exceptionEIP = (PVOID)((UINT_PTR)exceptionEIP - 1);
}
- gc.exceptionMessageRef = ((EXCEPTIONREF)gc.exceptionObj)->GetMessage();
+ gc.exceptionMessageRef = ((EXCEPTIONREF)gc.exceptionObj)->GetMessage();
TypeHandle exceptionTypeHandle = (gc.exceptionObj)->GetTypeHandle();
exceptionTypeHandle.GetName(exceptionType);
- WCHAR* exceptionTypeName = (WCHAR*)exceptionType.GetUnicode();
+ WCHAR *exceptionTypeName = (WCHAR *)exceptionType.GetUnicode();
- if (gc.exceptionMessageRef != NULL)
+ if(gc.exceptionMessageRef != NULL)
{
exceptionMessage = (gc.exceptionMessageRef)->GetBuffer();
}
@@ -3914,53 +3906,53 @@ void ETW::ExceptionLog::ExceptionThrown(CrawlFrame* pCf, BOOL bIsReThrownExcepti
exceptionFlags,
GetClrInstanceId());
GCPROTECT_END();
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/****************************************************************************/
/* This is called by the runtime when a domain is loaded */
/****************************************************************************/
-void ETW::LoaderLog::DomainLoadReal(BaseDomain* pDomain, _In_opt_ LPWSTR wszFriendlyName)
+void ETW::LoaderLog::DomainLoadReal(BaseDomain *pDomain, _In_opt_ LPWSTR wszFriendlyName)
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
} CONTRACTL_END;
EX_TRY
{
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_LOADER_KEYWORD))
{
DWORD dwEventOptions = ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad;
ETW::LoaderLog::SendDomainEvent(pDomain, dwEventOptions, wszFriendlyName);
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/****************************************************************************/
/* This is called by the runtime when an AppDomain is unloaded */
/****************************************************************************/
-void ETW::LoaderLog::DomainUnload(AppDomain* pDomain)
+void ETW::LoaderLog::DomainUnload(AppDomain *pDomain)
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
} CONTRACTL_END;
EX_TRY
{
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
KEYWORDZERO))
{
- if (!pDomain->NoAccessToHandleTable())
+ if(!pDomain->NoAccessToHandleTable())
{
DWORD enumerationOptions = ETW::EnumerationLog::GetEnumerationOptionsFromRuntimeKeywords();
// Domain unload also causes type unload events
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_TYPE_KEYWORD))
{
@@ -3970,29 +3962,29 @@ void ETW::LoaderLog::DomainUnload(AppDomain* pDomain)
ETW::EnumerationLog::EnumerationHelper(NULL, pDomain, enumerationOptions);
}
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/****************************************************************************/
/* This is called by the runtime when a LoaderAllocator is unloaded */
/****************************************************************************/
-void ETW::LoaderLog::CollectibleLoaderAllocatorUnload(AssemblyLoaderAllocator* pLoaderAllocator)
+void ETW::LoaderLog::CollectibleLoaderAllocatorUnload(AssemblyLoaderAllocator *pLoaderAllocator)
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
} CONTRACTL_END;
EX_TRY
{
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
KEYWORDZERO))
{
DWORD enumerationOptions = ETW::EnumerationLog::GetEnumerationOptionsFromRuntimeKeywords();
// Collectible Loader Allocator unload also causes type unload events
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_TYPE_KEYWORD))
{
@@ -4001,23 +3993,23 @@ void ETW::LoaderLog::CollectibleLoaderAllocatorUnload(AssemblyLoaderAllocator* p
ETW::EnumerationLog::IterateCollectibleLoaderAllocator(pLoaderAllocator, enumerationOptions);
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/****************************************************************************/
/* This is called by the runtime when the runtime is loaded
Function gets called by both the Callback mechanism and regular ETW events.
Type is used to differentiate whether its a callback or a normal call*/
- /****************************************************************************/
+/****************************************************************************/
void ETW::InfoLog::RuntimeInformation(INT32 type)
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
} CONTRACTL_END;
- EX_TRY{
- if ((type == ETW::InfoLog::InfoStructs::Normal && ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, RuntimeInformationStart))
+ EX_TRY {
+ if((type == ETW::InfoLog::InfoStructs::Normal && ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, RuntimeInformationStart))
#ifndef FEATURE_PAL
||
(type == ETW::InfoLog::InfoStructs::Callback && ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context, RuntimeInformationDCStart))
@@ -4025,21 +4017,21 @@ void ETW::InfoLog::RuntimeInformation(INT32 type)
)
{
#ifndef FEATURE_DTRACE
- PCWSTR szDtraceOutput1 = L"",szDtraceOutput2 = L"";
+ PCWSTR szDtraceOutput1=L"",szDtraceOutput2=L"";
#else
CHAR szDtraceOutput1[DTRACE_OUTPUT_STRING_LEN];
CHAR szDtraceOutput2[DTRACE_OUTPUT_STRING_LEN];
#endif // !FEATURE_DTRACE
UINT8 startupMode = 0;
UINT startupFlags = 0;
- WCHAR dllPath[MAX_PATH + 1] = {0};
+ WCHAR dllPath[MAX_PATH+1] = {0};
UINT8 Sku = 0;
_ASSERTE(g_fEEManagedEXEStartup || //CLR started due to a managed exe
g_fEEIJWStartup || //CLR started as a mixed mode Assembly
CLRHosted() || g_fEEHostedStartup || //CLR started through one of the Hosting API CLRHosted() returns true if CLR started through the V2 Interface while
// g_fEEHostedStartup is true if CLR is hosted through the V1 API.
g_fEEComActivatedStartup || //CLR started as a COM object
- g_fEEOtherStartup); //In case none of the 4 above mentioned cases are true for example ngen, ildasm then we asssume its a "other" startup
+ g_fEEOtherStartup ); //In case none of the 4 above mentioned cases are true for example ngen, ildasm then we asssume its a "other" startup
#ifdef FEATURE_CORECLR
Sku = ETW::InfoLog::InfoStructs::CoreCLR;
@@ -4060,9 +4052,9 @@ void ETW::InfoLog::RuntimeInformation(INT32 type)
USHORT bclQfeVersion = VER_ASSEMBLYBUILD_QFE;
#ifndef FEATURE_PAL
- LPCGUID comGUID = g_fEEComObjectGuid;
+ LPCGUID comGUID=g_fEEComObjectGuid;
#else
- unsigned int comGUID = 0;
+ unsigned int comGUID=0;
#endif //!FEATURE_PAL
#ifndef FEATURE_DTRACE
@@ -4078,12 +4070,12 @@ void ETW::InfoLog::RuntimeInformation(INT32 type)
#endif //!FEATURE_CORECLR
// Determine the startupmode
- if (g_fEEIJWStartup)
+ if(g_fEEIJWStartup)
{
//IJW Mode
startupMode = ETW::InfoLog::InfoStructs::IJW;
}
- else if (g_fEEManagedEXEStartup)
+ else if(g_fEEManagedEXEStartup)
{
//managed exe
startupMode = ETW::InfoLog::InfoStructs::ManagedExe;
@@ -4091,7 +4083,7 @@ void ETW::InfoLog::RuntimeInformation(INT32 type)
lpwszCommandLine = WszGetCommandLine();
#else
INT32 nSize = WideCharToMultiByte(WszGetCommandLine(), szDtraceOutput1);
- if (nSize > 0) {
+ if(nSize > 0) {
lpwszCommandLine = (SIZE_T)szDtraceOutput1;
}
#endif //!FEATURE_DTRACE
@@ -4101,34 +4093,34 @@ void ETW::InfoLog::RuntimeInformation(INT32 type)
//Hosted CLR
startupMode = ETW::InfoLog::InfoStructs::HostedCLR;
}
- else if (g_fEEComActivatedStartup)
+ else if(g_fEEComActivatedStartup)
{
//com activated
startupMode = ETW::InfoLog::InfoStructs::COMActivated;
}
- else if (g_fEEOtherStartup)
+ else if(g_fEEOtherStartup)
{
//startup type is other
startupMode = ETW::InfoLog::InfoStructs::Other;
}
- _ASSERTE(NumItems(dllPath) > MAX_PATH);
+ _ASSERTE (NumItems(dllPath) > MAX_PATH);
// if WszGetModuleFileName fails, we return an empty string
if (!WszGetModuleFileName(GetCLRModule(), dllPath, MAX_PATH)) {
dllPath[0] = 0;
}
dllPath[MAX_PATH] = 0;
#ifdef FEATURE_DTRACE
- _ASSERTE(NumItems(szDtraceOutput2) >= NumItems(dllPath));
+ _ASSERTE (NumItems(szDtraceOutput2) >= NumItems(dllPath));
INT32 nSize = WideCharToMultiByte(dllPath, szDtraceOutput2);
- if (nSize > 0) {
+ if(nSize > 0) {
lpwszRuntimeDllPath = (SIZE_T)szDtraceOutput2;
}
#endif // FEATURE_DTRACE
- if (type == ETW::InfoLog::InfoStructs::Callback)
+ if(type == ETW::InfoLog::InfoStructs::Callback)
{
- FireEtwRuntimeInformationDCStart(GetClrInstanceId(),
+ FireEtwRuntimeInformationDCStart( GetClrInstanceId(),
Sku,
bclMajorVersion,
bclMinorVersion,
@@ -4142,11 +4134,11 @@ void ETW::InfoLog::RuntimeInformation(INT32 type)
startupMode,
lpwszCommandLine,
comGUID,
- lpwszRuntimeDllPath);
+ lpwszRuntimeDllPath );
}
else
{
- FireEtwRuntimeInformationStart(GetClrInstanceId(),
+ FireEtwRuntimeInformationStart( GetClrInstanceId(),
Sku,
bclMajorVersion,
bclMinorVersion,
@@ -4160,32 +4152,32 @@ void ETW::InfoLog::RuntimeInformation(INT32 type)
startupMode,
lpwszCommandLine,
comGUID,
- lpwszRuntimeDllPath);
+ lpwszRuntimeDllPath );
}
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/*******************************************************/
/* This is called by the runtime when a method is jitted completely */
/*******************************************************/
-void ETW::MethodLog::MethodJitted(MethodDesc* pMethodDesc, SString* namespaceOrClassName, SString* methodName, SString* methodSignature, SIZE_T pCode, ReJITID rejitID)
+void ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, SIZE_T pCode, ReJITID rejitID)
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
} CONTRACTL_END;
EX_TRY
{
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_JIT_KEYWORD))
{
ETW::MethodLog::SendMethodEvent(pMethodDesc, ETW::EnumerationLog::EnumerationStructs::JitMethodLoad, TRUE, namespaceOrClassName, methodName, methodSignature, pCode, rejitID);
}
#ifndef WINXP_AND_WIN2K3_BUILD_SUPPORT
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_JITTEDMETHODILTONATIVEMAP_KEYWORD))
{
@@ -4200,15 +4192,15 @@ void ETW::MethodLog::MethodJitted(MethodDesc* pMethodDesc, SString* namespaceOrC
ETW::MethodLog::SendMethodILToNativeMapEvent(pMethodDesc, ETW::EnumerationLog::EnumerationStructs::JitMethodILToNativeMap, rejitID);
}
#endif // WINXP_AND_WIN2K3_BUILD_SUPPORT
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/*************************************************/
/* This is called by the runtime when method jitting started */
/*************************************************/
-void ETW::MethodLog::MethodJitting(MethodDesc* pMethodDesc, SString* namespaceOrClassName, SString* methodName, SString* methodSignature)
+void ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
PRECONDITION(pMethodDesc != NULL);
@@ -4216,14 +4208,14 @@ void ETW::MethodLog::MethodJitting(MethodDesc* pMethodDesc, SString* namespaceOr
EX_TRY
{
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_VERBOSE,
CLR_JIT_KEYWORD))
{
pMethodDesc->GetMethodInfo(*namespaceOrClassName, *methodName, *methodSignature);
ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, namespaceOrClassName, methodName, methodSignature);
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/**********************************************************************/
@@ -4231,7 +4223,7 @@ void ETW::MethodLog::MethodJitting(MethodDesc* pMethodDesc, SString* namespaceOr
/**********************************************************************/
void ETW::MethodLog::StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName)
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
PRECONDITION(ullHelperStartAddress != 0);
@@ -4239,31 +4231,31 @@ void ETW::MethodLog::StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pH
EX_TRY
{
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
CLR_JIT_KEYWORD))
{
- DWORD dwHelperSize = 0;
+ DWORD dwHelperSize=0;
Stub::RecoverStubAndSize((TADDR)ullHelperStartAddress, &dwHelperSize);
ETW::MethodLog::SendHelperEvent(ullHelperStartAddress, dwHelperSize, pHelperName);
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/**********************************************************/
/* This is called by the runtime when helpers with stubs are initialized */
/**********************************************************/
-void ETW::MethodLog::StubsInitialized(PVOID* pHelperStartAddresss, PVOID* pHelperNames, LONG lNoOfHelpers)
+void ETW::MethodLog::StubsInitialized(PVOID *pHelperStartAddresss, PVOID *pHelperNames, LONG lNoOfHelpers)
{
WRAPPER_NO_CONTRACT;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
- TRACE_LEVEL_INFORMATION,
- CLR_JIT_KEYWORD))
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ TRACE_LEVEL_INFORMATION,
+ CLR_JIT_KEYWORD))
{
- for (int i = 0; i < lNoOfHelpers; i++)
+ for(int i=0; iIsThunking())
+ if(!pMethodTable->IsThunking())
#endif
{
MethodTable::MethodIterator iter(pMethodTable);
for (; iter.IsValid(); iter.Next())
{
- MethodDesc* pMD = (MethodDesc*)(iter.GetMethodDesc());
- if (pMD && pMD->IsRestored() && pMD->GetMethodTable_NoLogging() == pMethodTable)
+ MethodDesc *pMD = (MethodDesc *)(iter.GetMethodDesc());
+ if(pMD && pMD->IsRestored() && pMD->GetMethodTable_NoLogging() == pMethodTable)
ETW::MethodLog::SendMethodEvent(pMD, ETW::EnumerationLog::EnumerationStructs::NgenMethodLoad, FALSE);
}
}
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
@@ -4370,7 +4362,7 @@ void ETW::SecurityLog::StrongNameVerificationStart(DWORD dwInFlags, _In_ LPWSTR
/****************************************************************************/
/* This is called by the runtime when a Strong Name Verification Ends */
/****************************************************************************/
-void ETW::SecurityLog::StrongNameVerificationStop(DWORD dwInFlags, ULONG result, _In_ LPWSTR strFullyQualifiedAssemblyName)
+void ETW::SecurityLog::StrongNameVerificationStop(DWORD dwInFlags,ULONG result, _In_ LPWSTR strFullyQualifiedAssemblyName)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_CORECLR
@@ -4390,8 +4382,8 @@ void ETW::SecurityLog::StrongNameVerificationStop(DWORD dwInFlags, ULONG result,
/* This is called by the runtime when field transparency calculations begin */
/****************************************************************************/
void ETW::SecurityLog::FireFieldTransparencyComputationStart(LPCWSTR wszFieldName,
- LPCWSTR wszModuleName,
- DWORD dwAppDomain)
+ LPCWSTR wszModuleName,
+ DWORD dwAppDomain)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_DTRACE
@@ -4412,10 +4404,10 @@ void ETW::SecurityLog::FireFieldTransparencyComputationStart(LPCWSTR wszFieldNam
/* This is called by the runtime when field transparency calculations end */
/****************************************************************************/
void ETW::SecurityLog::FireFieldTransparencyComputationEnd(LPCWSTR wszFieldName,
- LPCWSTR wszModuleName,
- DWORD dwAppDomain,
- BOOL fIsCritical,
- BOOL fIsTreatAsSafe)
+ LPCWSTR wszModuleName,
+ DWORD dwAppDomain,
+ BOOL fIsCritical,
+ BOOL fIsTreatAsSafe)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_DTRACE
@@ -4436,8 +4428,8 @@ void ETW::SecurityLog::FireFieldTransparencyComputationEnd(LPCWSTR wszFieldName,
/* This is called by the runtime when method transparency calculations begin */
/*****************************************************************************/
void ETW::SecurityLog::FireMethodTransparencyComputationStart(LPCWSTR wszMethodName,
- LPCWSTR wszModuleName,
- DWORD dwAppDomain)
+ LPCWSTR wszModuleName,
+ DWORD dwAppDomain)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_DTRACE
@@ -4458,10 +4450,10 @@ void ETW::SecurityLog::FireMethodTransparencyComputationStart(LPCWSTR wszMethodN
/* This is called by the runtime when method transparency calculations end */
/********************************************(********************************/
void ETW::SecurityLog::FireMethodTransparencyComputationEnd(LPCWSTR wszMethodName,
- LPCWSTR wszModuleName,
- DWORD dwAppDomain,
- BOOL fIsCritical,
- BOOL fIsTreatAsSafe)
+ LPCWSTR wszModuleName,
+ DWORD dwAppDomain,
+ BOOL fIsCritical,
+ BOOL fIsTreatAsSafe)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_DTRACE
@@ -4482,7 +4474,7 @@ void ETW::SecurityLog::FireMethodTransparencyComputationEnd(LPCWSTR wszMethodNam
/* This is called by the runtime when module transparency calculations begin */
/*****************************************************************************/
void ETW::SecurityLog::FireModuleTransparencyComputationStart(LPCWSTR wszModuleName,
- DWORD dwAppDomain)
+ DWORD dwAppDomain)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_DTRACE
@@ -4501,12 +4493,12 @@ void ETW::SecurityLog::FireModuleTransparencyComputationStart(LPCWSTR wszModuleN
/* This is called by the runtime when module transparency calculations end */
/****************************************************************************/
void ETW::SecurityLog::FireModuleTransparencyComputationEnd(LPCWSTR wszModuleName,
- DWORD dwAppDomain,
- BOOL fIsAllCritical,
- BOOL fIsAllTransparent,
- BOOL fIsTreatAsSafe,
- BOOL fIsOpportunisticallyCritical,
- DWORD dwSecurityRuleSet)
+ DWORD dwAppDomain,
+ BOOL fIsAllCritical,
+ BOOL fIsAllTransparent,
+ BOOL fIsTreatAsSafe,
+ BOOL fIsOpportunisticallyCritical,
+ DWORD dwSecurityRuleSet)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_DTRACE
@@ -4525,8 +4517,8 @@ void ETW::SecurityLog::FireModuleTransparencyComputationEnd(LPCWSTR wszModuleNam
/* This is called by the runtime when token transparency calculations begin */
/****************************************************************************/
void ETW::SecurityLog::FireTokenTransparencyComputationStart(DWORD dwToken,
- LPCWSTR wszModuleName,
- DWORD dwAppDomain)
+ LPCWSTR wszModuleName,
+ DWORD dwAppDomain)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_DTRACE
@@ -4545,10 +4537,10 @@ void ETW::SecurityLog::FireTokenTransparencyComputationStart(DWORD dwToken,
/* This is called by the runtime when token transparency calculations end */
/****************************************************************************/
void ETW::SecurityLog::FireTokenTransparencyComputationEnd(DWORD dwToken,
- LPCWSTR wszModuleName,
- DWORD dwAppDomain,
- BOOL fIsCritical,
- BOOL fIsTreatAsSafe)
+ LPCWSTR wszModuleName,
+ DWORD dwAppDomain,
+ BOOL fIsCritical,
+ BOOL fIsTreatAsSafe)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_DTRACE
@@ -4567,8 +4559,8 @@ void ETW::SecurityLog::FireTokenTransparencyComputationEnd(DWORD dwToken,
/* This is called by the runtime when type transparency calculations begin */
/*****************************************************************************/
void ETW::SecurityLog::FireTypeTransparencyComputationStart(LPCWSTR wszTypeName,
- LPCWSTR wszModuleName,
- DWORD dwAppDomain)
+ LPCWSTR wszModuleName,
+ DWORD dwAppDomain)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_DTRACE
@@ -4589,12 +4581,12 @@ void ETW::SecurityLog::FireTypeTransparencyComputationStart(LPCWSTR wszTypeName,
/* This is called by the runtime when type transparency calculations end */
/****************************************************************************/
void ETW::SecurityLog::FireTypeTransparencyComputationEnd(LPCWSTR wszTypeName,
- LPCWSTR wszModuleName,
- DWORD dwAppDomain,
- BOOL fIsAllCritical,
- BOOL fIsAllTransparent,
- BOOL fIsCritical,
- BOOL fIsTreatAsSafe)
+ LPCWSTR wszModuleName,
+ DWORD dwAppDomain,
+ BOOL fIsAllCritical,
+ BOOL fIsAllTransparent,
+ BOOL fIsCritical,
+ BOOL fIsTreatAsSafe)
{
WRAPPER_NO_CONTRACT;
#ifndef FEATURE_DTRACE
@@ -4615,9 +4607,9 @@ void ETW::SecurityLog::FireTypeTransparencyComputationEnd(LPCWSTR wszTypeName,
/* This is called by the runtime when a module is loaded */
/* liReportedSharedModule will be 0 when this module is reported for the 1st time */
/**********************************************************************************/
-void ETW::LoaderLog::ModuleLoad(Module* pModule, LONG liReportedSharedModule)
+void ETW::LoaderLog::ModuleLoad(Module *pModule, LONG liReportedSharedModule)
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
} CONTRACTL_END;
@@ -4625,7 +4617,7 @@ void ETW::LoaderLog::ModuleLoad(Module* pModule, LONG liReportedSharedModule)
EX_TRY
{
DWORD enumerationOptions = ETW::EnumerationLog::EnumerationStructs::None;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
KEYWORDZERO))
{
@@ -4640,27 +4632,27 @@ void ETW::LoaderLog::ModuleLoad(Module* pModule, LONG liReportedSharedModule)
TRACE_LEVEL_INFORMATION,
CLR_PERFTRACK_KEYWORD);
- if (liReportedSharedModule == 0)
+ if(liReportedSharedModule == 0)
{
- if (bTraceFlagLoaderSet)
+ if(bTraceFlagLoaderSet)
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad;
if (bTraceFlagPerfTrackSet)
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::ModuleRangeLoad;
- if (bTraceFlagNgenMethodSet && bTraceFlagStartRundownSet)
+ if(bTraceFlagNgenMethodSet && bTraceFlagStartRundownSet)
enumerationOptions |= ETW::EnumerationLog::EnumerationStructs::NgenMethodLoad;
- if (pModule->IsManifest() && bTraceFlagLoaderSet)
+ if(pModule->IsManifest() && bTraceFlagLoaderSet)
ETW::LoaderLog::SendAssemblyEvent(pModule->GetAssembly(), enumerationOptions);
- if (bTraceFlagLoaderSet || bTraceFlagPerfTrackSet)
+ if(bTraceFlagLoaderSet || bTraceFlagPerfTrackSet)
ETW::LoaderLog::SendModuleEvent(pModule, ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad | ETW::EnumerationLog::EnumerationStructs::ModuleRangeLoad);
ETW::EnumerationLog::EnumerationHelper(pModule, NULL, enumerationOptions);
}
// we want to report domainmodule events whenever they are loaded in any AppDomain
- if (bTraceFlagLoaderSet)
+ if(bTraceFlagLoaderSet)
ETW::LoaderLog::SendModuleEvent(pModule, ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad, TRUE);
}
@@ -4676,7 +4668,7 @@ void ETW::LoaderLog::ModuleLoad(Module* pModule, LONG liReportedSharedModule)
}
}
#endif
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/****************************************************************************/
@@ -4684,14 +4676,14 @@ void ETW::LoaderLog::ModuleLoad(Module* pModule, LONG liReportedSharedModule)
/****************************************************************************/
void ETW::EnumerationLog::ProcessShutdown()
{
- CONTRACTL{
+ CONTRACTL {
NOTHROW;
GC_TRIGGERS;
} CONTRACTL_END;
EX_TRY
{
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, TRACE_LEVEL_INFORMATION, KEYWORDZERO))
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, TRACE_LEVEL_INFORMATION, KEYWORDZERO))
{
DWORD enumerationOptions = GetEnumerationOptionsFromRuntimeKeywords();
@@ -4699,7 +4691,7 @@ void ETW::EnumerationLog::ProcessShutdown()
// default domain.
ETW::EnumerationLog::EnumerationHelper(NULL /* module filter */, NULL /* domain filter */, enumerationOptions);
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/****************************************************************************/
@@ -4711,18 +4703,18 @@ void ETW::EnumerationLog::ProcessShutdown()
/****************************************************************************/
/* This routine is used to send a domain load/unload or rundown event */
/****************************************************************************/
-void ETW::LoaderLog::SendDomainEvent(BaseDomain* pBaseDomain, DWORD dwEventOptions, LPCWSTR wszFriendlyName)
+void ETW::LoaderLog::SendDomainEvent(BaseDomain *pBaseDomain, DWORD dwEventOptions, LPCWSTR wszFriendlyName)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
} CONTRACTL_END;
- if (!pBaseDomain)
+ if(!pBaseDomain)
return;
#ifndef FEATURE_DTRACE
- PCWSTR szDtraceOutput1 = L"";
+ PCWSTR szDtraceOutput1=L"";
#else
CHAR szDtraceOutput1[DTRACE_OUTPUT_STRING_LEN];
#endif // !FEATURE_DTRACE
@@ -4730,22 +4722,22 @@ void ETW::LoaderLog::SendDomainEvent(BaseDomain* pBaseDomain, DWORD dwEventOptio
BOOL bIsAppDomain = pBaseDomain->IsAppDomain();
BOOL bIsExecutable = bIsAppDomain ? !(pBaseDomain->AsAppDomain()->IsPassiveDomain()) : FALSE;
BOOL bIsSharedDomain = pBaseDomain->IsSharedDomain();
- UINT32 uSharingPolicy = bIsAppDomain ? (pBaseDomain->AsAppDomain()->GetSharePolicy()) : 0;
+ UINT32 uSharingPolicy = bIsAppDomain?(pBaseDomain->AsAppDomain()->GetSharePolicy()):0;
ULONGLONG ullDomainId = (ULONGLONG)pBaseDomain;
ULONG ulDomainFlags = ((bIsDefaultDomain ? ETW::LoaderLog::LoaderStructs::DefaultDomain : 0) |
- (bIsExecutable ? ETW::LoaderLog::LoaderStructs::ExecutableDomain : 0) |
- (bIsSharedDomain ? ETW::LoaderLog::LoaderStructs::SharedDomain : 0) |
- (uSharingPolicy << 28));
+ (bIsExecutable ? ETW::LoaderLog::LoaderStructs::ExecutableDomain : 0) |
+ (bIsSharedDomain ? ETW::LoaderLog::LoaderStructs::SharedDomain : 0) |
+ (uSharingPolicy<<28));
LPCWSTR wsEmptyString = L"";
LPCWSTR wsSharedString = L"SharedDomain";
LPWSTR lpswzDomainName = (LPWSTR)wsEmptyString;
- if (bIsAppDomain)
+ if(bIsAppDomain)
{
- if (wszFriendlyName)
+ if(wszFriendlyName)
lpswzDomainName = (PWCHAR)wszFriendlyName;
else
lpswzDomainName = (PWCHAR)pBaseDomain->AsAppDomain()->GetFriendlyName();
@@ -4763,28 +4755,28 @@ void ETW::LoaderLog::SendDomainEvent(BaseDomain* pBaseDomain, DWORD dwEventOptio
return;
#endif // !FEATURE_DTRACE
- if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad)
+ if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad)
{
FireEtwAppDomainLoad_V1(ullDomainId, ulDomainFlags, szDtraceOutput1, pBaseDomain->GetId().m_dwId, GetClrInstanceId());
}
- else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload)
+ else if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload)
{
FireEtwAppDomainUnload_V1(ullDomainId, ulDomainFlags, szDtraceOutput1, pBaseDomain->GetId().m_dwId, GetClrInstanceId());
}
- else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
+ else if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
{
FireEtwAppDomainDCStart_V1(ullDomainId, ulDomainFlags, szDtraceOutput1, pBaseDomain->GetId().m_dwId, GetClrInstanceId());
}
- else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd)
+ else if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd)
{
FireEtwAppDomainDCEnd_V1(ullDomainId, ulDomainFlags, szDtraceOutput1, pBaseDomain->GetId().m_dwId, GetClrInstanceId());
}
else
{
_ASSERTE((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd));
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd));
}
}
@@ -4793,13 +4785,13 @@ void ETW::LoaderLog::SendDomainEvent(BaseDomain* pBaseDomain, DWORD dwEventOptio
/********************************************************/
void ETW::EnumerationLog::SendThreadRundownEvent()
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
} CONTRACTL_END;
#ifndef DACCESS_COMPILE
- Thread* pThread = NULL;
+ Thread *pThread = NULL;
// Take the thread store lock while we enumerate threads.
ThreadStoreLockHolder tsl;
@@ -4819,24 +4811,24 @@ void ETW::EnumerationLog::SendThreadRundownEvent()
/****************************************************************************/
/* This routine is used to send an assembly load/unload or rundown event ****/
/****************************************************************************/
-void ETW::LoaderLog::SendAssemblyEvent(Assembly* pAssembly, DWORD dwEventOptions)
+void ETW::LoaderLog::SendAssemblyEvent(Assembly *pAssembly, DWORD dwEventOptions)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
} CONTRACTL_END;
- if (!pAssembly)
+ if(!pAssembly)
return;
#ifndef FEATURE_DTRACE
- PCWSTR szDtraceOutput1 = L"";
+ PCWSTR szDtraceOutput1=L"";
#else
CHAR szDtraceOutput1[DTRACE_OUTPUT_STRING_LEN];
#endif // !FEATURE_DTRACE
BOOL bIsDynamicAssembly = pAssembly->IsDynamic();
BOOL bIsCollectibleAssembly = pAssembly->IsCollectible();
- BOOL bIsDomainNeutral = pAssembly->IsDomainNeutral();
+ BOOL bIsDomainNeutral = pAssembly->IsDomainNeutral() ;
BOOL bHasNativeImage = pAssembly->GetManifestFile()->HasNativeImage();
ULONGLONG ullAssemblyId = (ULONGLONG)pAssembly;
@@ -4846,15 +4838,15 @@ void ETW::LoaderLog::SendAssemblyEvent(Assembly* pAssembly, DWORD dwEventOptions
ullBindingID = pAssembly->GetManifestFile()->GetBindingID();
#endif
ULONG ulAssemblyFlags = ((bIsDomainNeutral ? ETW::LoaderLog::LoaderStructs::DomainNeutralAssembly : 0) |
- (bIsDynamicAssembly ? ETW::LoaderLog::LoaderStructs::DynamicAssembly : 0) |
- (bHasNativeImage ? ETW::LoaderLog::LoaderStructs::NativeAssembly : 0) |
- (bIsCollectibleAssembly ? ETW::LoaderLog::LoaderStructs::CollectibleAssembly : 0));
+ (bIsDynamicAssembly ? ETW::LoaderLog::LoaderStructs::DynamicAssembly : 0) |
+ (bHasNativeImage ? ETW::LoaderLog::LoaderStructs::NativeAssembly : 0) |
+ (bIsCollectibleAssembly ? ETW::LoaderLog::LoaderStructs::CollectibleAssembly : 0));
SString sAssemblyPath;
pAssembly->GetDisplayName(sAssemblyPath);
LPWSTR lpszAssemblyPath = (LPWSTR)sAssemblyPath.GetUnicode();
- /* prepare events args for ETW and ETM */
+/* prepare events args for ETW and ETM */
#ifndef FEATURE_DTRACE
szDtraceOutput1 = (PCWSTR)lpszAssemblyPath;
#else // !FEATURE_DTRACE
@@ -4864,36 +4856,36 @@ void ETW::LoaderLog::SendAssemblyEvent(Assembly* pAssembly, DWORD dwEventOptions
return;
#endif // !FEATURE_DTRACE
- if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad)
+ if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad)
{
FireEtwAssemblyLoad_V1(ullAssemblyId, ullDomainId, ullBindingID, ulAssemblyFlags, szDtraceOutput1, GetClrInstanceId());
}
- else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload)
+ else if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload)
{
FireEtwAssemblyUnload_V1(ullAssemblyId, ullDomainId, ullBindingID, ulAssemblyFlags, szDtraceOutput1, GetClrInstanceId());
}
- else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
+ else if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
{
FireEtwAssemblyDCStart_V1(ullAssemblyId, ullDomainId, ullBindingID, ulAssemblyFlags, szDtraceOutput1, GetClrInstanceId());
}
- else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd)
+ else if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd)
{
FireEtwAssemblyDCEnd_V1(ullAssemblyId, ullDomainId, ullBindingID, ulAssemblyFlags, szDtraceOutput1, GetClrInstanceId());
}
else
{
_ASSERTE((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd));
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd));
}
}
#if !defined(FEATURE_PAL)
ETW_INLINE
-ULONG
-ETW::LoaderLog::SendModuleRange(
- _In_ Module* pModule,
+ ULONG
+ ETW::LoaderLog::SendModuleRange(
+ _In_ Module *pModule,
_In_ DWORD dwEventOptions)
{
@@ -4903,22 +4895,22 @@ ETW::LoaderLog::SendModuleRange(
// do not fire the ETW event when:
// 1. We did not load the native image
// 2. We do not have IBC data for the native image
- if (!pModule || !pModule->HasNativeImage() || !pModule->IsIbcOptimized())
+ if( !pModule || !pModule->HasNativeImage() || !pModule->IsIbcOptimized() )
{
return Result;
}
// get information about the hot sections from the native image that has been loaded
COUNT_T cbSizeOfSectionTable;
- CORCOMPILE_VIRTUAL_SECTION_INFO* pVirtualSectionsTable = (CORCOMPILE_VIRTUAL_SECTION_INFO*)pModule->GetNativeImage()->GetVirtualSectionsTable(&cbSizeOfSectionTable);
+ CORCOMPILE_VIRTUAL_SECTION_INFO* pVirtualSectionsTable = (CORCOMPILE_VIRTUAL_SECTION_INFO* )pModule->GetNativeImage()->GetVirtualSectionsTable(&cbSizeOfSectionTable);
- COUNT_T RangeCount = cbSizeOfSectionTable / sizeof(CORCOMPILE_VIRTUAL_SECTION_INFO);
+ COUNT_T RangeCount = cbSizeOfSectionTable/sizeof(CORCOMPILE_VIRTUAL_SECTION_INFO);
// if we do not have any hot ranges, we do not fire the ETW event
// Figure out the rest of the event data
UINT16 ClrInstanceId = GetClrInstanceId();
- UINT64 ModuleID = (ULONGLONG)(TADDR)pModule;
+ UINT64 ModuleID = (ULONGLONG)(TADDR) pModule;
for (COUNT_T i = 0; i < RangeCount; ++i)
{
@@ -4980,13 +4972,13 @@ ETW::LoaderLog::SendModuleRange(
// untrusted, and reported sizes of buffers are verified against their data.
//
-static void GetCodeViewInfo(Module* pModule, CV_INFO_PDB70* pCvInfoIL, CV_INFO_PDB70* pCvInfoNative)
+static void GetCodeViewInfo(Module * pModule, CV_INFO_PDB70 * pCvInfoIL, CV_INFO_PDB70 * pCvInfoNative)
{
LIMITED_METHOD_CONTRACT;
- _ASSERTE(pModule != NULL);
- _ASSERTE(pCvInfoIL != NULL);
- _ASSERTE(pCvInfoNative != NULL);
+ _ASSERTE (pModule != NULL);
+ _ASSERTE (pCvInfoIL != NULL);
+ _ASSERTE (pCvInfoNative != NULL);
ZeroMemory(pCvInfoIL, sizeof(*pCvInfoIL));
ZeroMemory(pCvInfoNative, sizeof(*pCvInfoNative));
@@ -5021,8 +5013,8 @@ static void GetCodeViewInfo(Module* pModule, CV_INFO_PDB70* pCvInfoIL, CV_INFO_P
return;
COUNT_T cbDebugEntries;
- IMAGE_DEBUG_DIRECTORY* rgDebugEntries =
- (IMAGE_DEBUG_DIRECTORY*)pLayout->GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_DEBUG, &cbDebugEntries);
+ IMAGE_DEBUG_DIRECTORY * rgDebugEntries =
+ (IMAGE_DEBUG_DIRECTORY *) pLayout->GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_DEBUG, &cbDebugEntries);
if (cbDebugEntries < sizeof(IMAGE_DEBUG_DIRECTORY))
return;
@@ -5036,15 +5028,15 @@ static void GetCodeViewInfo(Module* pModule, CV_INFO_PDB70* pCvInfoIL, CV_INFO_P
// sizeof(CV_INFO_PDB70); see below).
struct PdbInfo
{
- CV_INFO_PDB70* m_pPdb70;
+ CV_INFO_PDB70 * m_pPdb70;
ULONG m_cbPdb70;
};
// Iterate through all debug directory entries. The very last one will be the
// managed PDB entry. The next to last one (if it exists) will be the (native) NGEN
// PDB entry. Treat raw bytes we read as untrusted.
- PdbInfo pdbInfoLast = { 0 };
- PdbInfo pdbInfoNextToLast = { 0 };
+ PdbInfo pdbInfoLast = {0};
+ PdbInfo pdbInfoNextToLast = {0};
int cEntries = cbDebugEntries / sizeof(IMAGE_DEBUG_DIRECTORY);
for (int i = 0; i < cEntries; i++)
{
@@ -5076,7 +5068,7 @@ static void GetCodeViewInfo(Module* pModule, CV_INFO_PDB70* pCvInfoIL, CV_INFO_P
}
// Verify the magic number is as expected
- CV_INFO_PDB70* pPdb70 = (CV_INFO_PDB70*)pLayout->GetRvaData(rvaOfRawData);
+ CV_INFO_PDB70 * pPdb70 = (CV_INFO_PDB70 *) pLayout->GetRvaData(rvaOfRawData);
if (pPdb70->magic != CV_SIGNATURE_RSDS)
{
// Unrecognized magic number. Skip
@@ -5151,18 +5143,18 @@ static void GetCodeViewInfo(Module* pModule, CV_INFO_PDB70* pCvInfoIL, CV_INFO_P
// * bFireDomainModuleEvents - nonzero if we are to fire DomainModule events; zero
// if we are to fire Module events
//
-void ETW::LoaderLog::SendModuleEvent(Module* pModule, DWORD dwEventOptions, BOOL bFireDomainModuleEvents)
+void ETW::LoaderLog::SendModuleEvent(Module *pModule, DWORD dwEventOptions, BOOL bFireDomainModuleEvents)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
} CONTRACTL_END;
- if (!pModule)
+ if(!pModule)
return;
#ifndef FEATURE_DTRACE
- PCWSTR szDtraceOutput1 = L"", szDtraceOutput2 = L"";
+ PCWSTR szDtraceOutput1=L"",szDtraceOutput2=L"";
#else
CHAR szDtraceOutput1[DTRACE_OUTPUT_STRING_LEN];
CHAR szDtraceOutput2[DTRACE_OUTPUT_STRING_LEN];
@@ -5174,35 +5166,35 @@ void ETW::LoaderLog::SendModuleEvent(Module* pModule, DWORD dwEventOptions, BOOL
#endif // FEATURE_PREJIT
BOOL bIsManifestModule = pModule->IsManifest();
ULONGLONG ullAppDomainId = 0; // This is used only with DomainModule events
- ULONGLONG ullModuleId = (ULONGLONG)(TADDR)pModule;
+ ULONGLONG ullModuleId = (ULONGLONG)(TADDR) pModule;
ULONGLONG ullAssemblyId = (ULONGLONG)pModule->GetAssembly();
BOOL bIsDomainNeutral = pModule->GetAssembly()->IsDomainNeutral();
BOOL bIsIbcOptimized = FALSE;
- if (bHasNativeImage)
+ if(bHasNativeImage)
{
bIsIbcOptimized = pModule->IsIbcOptimized();
}
ULONG ulReservedFlags = 0;
ULONG ulFlags = ((bIsDomainNeutral ? ETW::LoaderLog::LoaderStructs::DomainNeutralModule : 0) |
- (bHasNativeImage ? ETW::LoaderLog::LoaderStructs::NativeModule : 0) |
- (bIsDynamicAssembly ? ETW::LoaderLog::LoaderStructs::DynamicModule : 0) |
- (bIsManifestModule ? ETW::LoaderLog::LoaderStructs::ManifestModule : 0) |
- (bIsIbcOptimized ? ETW::LoaderLog::LoaderStructs::IbcOptimized : 0));
+ (bHasNativeImage ? ETW::LoaderLog::LoaderStructs::NativeModule : 0) |
+ (bIsDynamicAssembly ? ETW::LoaderLog::LoaderStructs::DynamicModule : 0) |
+ (bIsManifestModule ? ETW::LoaderLog::LoaderStructs::ManifestModule : 0) |
+ (bIsIbcOptimized ? ETW::LoaderLog::LoaderStructs::IbcOptimized : 0));
#ifndef FEATURE_DTRACE
// Grab PDB path, guid, and age for managed PDB and native (NGEN) PDB when
// available. Any failures are not fatal. The corresponding PDB info will remain
// zeroed out, and that's what we'll include in the event.
- CV_INFO_PDB70 cvInfoIL = { 0 };
- CV_INFO_PDB70 cvInfoNative = { 0 };
+ CV_INFO_PDB70 cvInfoIL = {0};
+ CV_INFO_PDB70 cvInfoNative = {0};
GetCodeViewInfo(pModule, &cvInfoIL, &cvInfoNative);
#endif // FEATURE_DTRACE
- PWCHAR ModuleILPath = L"", ModuleNativePath = L"";
+ PWCHAR ModuleILPath=L"", ModuleNativePath=L"";
- if (bFireDomainModuleEvents)
+ if(bFireDomainModuleEvents)
{
- if (pModule->GetDomain()->IsSharedDomain()) // for shared domains, we do not fire domainmodule event
+ if(pModule->GetDomain()->IsSharedDomain()) // for shared domains, we do not fire domainmodule event
return;
ullAppDomainId = (ULONGLONG)pModule->FindDomainAssembly(pModule->GetDomain()->AsAppDomain())->GetAppDomain();
}
@@ -5213,19 +5205,19 @@ void ETW::LoaderLog::SendModuleEvent(Module* pModule, DWORD dwEventOptions, BOOL
#else // !FEATURE_PAL
SString moduleName;
#endif // !FEATURE_PAL
- if (!bIsDynamicAssembly)
+ if(!bIsDynamicAssembly)
{
ModuleILPath = (PWCHAR)pModule->GetAssembly()->GetManifestFile()->GetILimage()->GetPath().GetUnicode();
ModuleNativePath = (PWCHAR)pEmptyString;
#ifdef FEATURE_PREJIT
- if (bHasNativeImage)
+ if(bHasNativeImage)
ModuleNativePath = (PWCHAR)pModule->GetNativeImage()->GetPath().GetUnicode();
#endif // FEATURE_PREJIT
}
// if we do not have a module path yet, we put the module name
- if (bIsDynamicAssembly || ModuleILPath == NULL || wcslen(ModuleILPath) <= 2)
+ if(bIsDynamicAssembly || ModuleILPath==NULL || wcslen(ModuleILPath) <= 2)
{
moduleName.SetUTF8(pModule->GetSimpleName());
ModuleILPath = (PWCHAR)moduleName.GetUnicode();
@@ -5250,52 +5242,52 @@ void ETW::LoaderLog::SendModuleEvent(Module* pModule, DWORD dwEventOptions, BOOL
return;
#endif // !FEATURE_DTRACE
- if (bFireDomainModuleEvents)
+ if(bFireDomainModuleEvents)
{
- if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad)
+ if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad)
{
FireEtwDomainModuleLoad_V1(ullModuleId, ullAssemblyId, ullAppDomainId, ulFlags, ulReservedFlags, szDtraceOutput1, szDtraceOutput2, GetClrInstanceId());
}
- else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
+ else if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
{
FireEtwDomainModuleDCStart_V1(ullModuleId, ullAssemblyId, ullAppDomainId, ulFlags, ulReservedFlags, szDtraceOutput1, szDtraceOutput2, GetClrInstanceId());
}
- else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd)
+ else if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd)
{
FireEtwDomainModuleDCEnd_V1(ullModuleId, ullAssemblyId, ullAppDomainId, ulFlags, ulReservedFlags, szDtraceOutput1, szDtraceOutput2, GetClrInstanceId());
}
else
{
_ASSERTE((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd));
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd));
}
}
else
{
- if ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad) || (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeLoad))
+ if((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad) || (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeLoad))
{
FireEtwModuleLoad_V1_or_V2(ullModuleId, ullAssemblyId, ulFlags, ulReservedFlags, szDtraceOutput1, szDtraceOutput2, GetClrInstanceId(), &cvInfoIL.signature, cvInfoIL.age, managedPdbPath, &cvInfoNative.signature, cvInfoNative.age, nativePdbPath);
}
- else if (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload)
+ else if(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload)
{
FireEtwModuleUnload_V1_or_V2(ullModuleId, ullAssemblyId, ulFlags, ulReservedFlags, szDtraceOutput1, szDtraceOutput2, GetClrInstanceId(), &cvInfoIL.signature, cvInfoIL.age, managedPdbPath, &cvInfoNative.signature, cvInfoNative.age, nativePdbPath);
}
- else if ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) || (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCStart))
+ else if((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) || (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCStart))
{
FireEtwModuleDCStart_V1_or_V2(ullModuleId, ullAssemblyId, ulFlags, ulReservedFlags, szDtraceOutput1, szDtraceOutput2, GetClrInstanceId(), &cvInfoIL.signature, cvInfoIL.age, managedPdbPath, &cvInfoNative.signature, cvInfoNative.age, nativePdbPath);
}
- else if ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) || (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCEnd))
+ else if((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) || (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCEnd))
{
FireEtwModuleDCEnd_V1_or_V2(ullModuleId, ullAssemblyId, ulFlags, ulReservedFlags, szDtraceOutput1, szDtraceOutput2, GetClrInstanceId(), &cvInfoIL.signature, cvInfoIL.age, managedPdbPath, &cvInfoNative.signature, cvInfoNative.age, nativePdbPath);
}
else
{
_ASSERTE((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleLoad) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeEnabledAny));
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeEnabledAny));
}
#if !defined(FEATURE_PAL)
@@ -5311,55 +5303,55 @@ void ETW::LoaderLog::SendModuleEvent(Module* pModule, DWORD dwEventOptions, BOOL
/*****************************************************************/
/* This routine is used to send an ETW event just before a method starts jitting*/
/*****************************************************************/
-void ETW::MethodLog::SendMethodJitStartEvent(MethodDesc* pMethodDesc, SString* namespaceOrClassName, SString* methodName, SString* methodSignature)
+void ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
} CONTRACTL_END;
- Module* pModule = NULL;
- Module* pLoaderModule = NULL; // This must not be used except for getting the ModuleID
+ Module *pModule = NULL;
+ Module *pLoaderModule = NULL; // This must not be used except for getting the ModuleID
- ULONGLONG ullMethodIdentifier = 0;
- ULONGLONG ullModuleID = 0;
- ULONG ulMethodToken = 0;
- ULONG ulMethodILSize = 0;
+ ULONGLONG ullMethodIdentifier=0;
+ ULONGLONG ullModuleID=0;
+ ULONG ulMethodToken=0;
+ ULONG ulMethodILSize=0;
#ifndef FEATURE_DTRACE
- PCWSTR szDtraceOutput1 = L"", szDtraceOutput2 = L"", szDtraceOutput3 = L"";
+ PCWSTR szDtraceOutput1=L"",szDtraceOutput2=L"",szDtraceOutput3=L"";
#else
CHAR szDtraceOutput1[DTRACE_OUTPUT_STRING_LEN];
CHAR szDtraceOutput2[DTRACE_OUTPUT_STRING_LEN];
CHAR szDtraceOutput3[DTRACE_OUTPUT_STRING_LEN];
#endif // !FEATURE_DTRACE
- if (pMethodDesc) {
+ if(pMethodDesc) {
pModule = pMethodDesc->GetModule_NoLogging();
- if (!pMethodDesc->IsRestored()) {
- return;
+ if(!pMethodDesc->IsRestored()) {
+ return;
}
bool bIsDynamicMethod = pMethodDesc->IsDynamicMethod();
BOOL bIsGenericMethod = FALSE;
- if (pMethodDesc->GetMethodTable_NoLogging())
+ if(pMethodDesc->GetMethodTable_NoLogging())
bIsGenericMethod = pMethodDesc->HasClassOrMethodInstantiation_NoLogging();
- ullModuleID = (ULONGLONG)(TADDR)pModule;
+ ullModuleID = (ULONGLONG)(TADDR) pModule;
ullMethodIdentifier = (ULONGLONG)pMethodDesc;
// Use MethodDesc if Dynamic or Generic methods
- if (bIsDynamicMethod || bIsGenericMethod)
+ if( bIsDynamicMethod || bIsGenericMethod)
{
- if (bIsGenericMethod)
+ if(bIsGenericMethod)
ulMethodToken = (ULONG)pMethodDesc->GetMemberDef_NoLogging();
- if (bIsDynamicMethod) // if its a generic and a dynamic method, we would set the methodtoken to 0
+ if(bIsDynamicMethod) // if its a generic and a dynamic method, we would set the methodtoken to 0
ulMethodToken = (ULONG)0;
}
else
ulMethodToken = (ULONG)pMethodDesc->GetMemberDef_NoLogging();
- if (pMethodDesc->IsIL())
+ if(pMethodDesc->IsIL())
{
COR_ILMETHOD_DECODER::DecoderStatus decoderstatus = COR_ILMETHOD_DECODER::FORMAT_ERROR;
COR_ILMETHOD_DECODER ILHeader(pMethodDesc->GetILHeader(), pMethodDesc->GetMDImport(), &decoderstatus);
@@ -5367,7 +5359,7 @@ void ETW::MethodLog::SendMethodJitStartEvent(MethodDesc* pMethodDesc, SString* n
}
SString tNamespace, tMethodName, tMethodSignature;
- if (!namespaceOrClassName || !methodName || !methodSignature || (methodName->IsEmpty() && namespaceOrClassName->IsEmpty() && methodSignature->IsEmpty()))
+ if(!namespaceOrClassName|| !methodName|| !methodSignature || (methodName->IsEmpty() && namespaceOrClassName->IsEmpty() && methodSignature->IsEmpty()))
{
pMethodDesc->GetMethodInfo(tNamespace, tMethodName, tMethodSignature);
namespaceOrClassName = &tNamespace;
@@ -5395,35 +5387,35 @@ void ETW::MethodLog::SendMethodJitStartEvent(MethodDesc* pMethodDesc, SString* n
#endif // !FEATURE_DTRACE
FireEtwMethodJittingStarted_V1(ullMethodIdentifier,
- ullModuleID,
- ulMethodToken,
- ulMethodILSize,
- szDtraceOutput1,
- szDtraceOutput2,
- szDtraceOutput3,
- GetClrInstanceId());
+ ullModuleID,
+ ulMethodToken,
+ ulMethodILSize,
+ szDtraceOutput1,
+ szDtraceOutput2,
+ szDtraceOutput3,
+ GetClrInstanceId());
}
}
/****************************************************************************/
/* This routine is used to send a method load/unload or rundown event */
/****************************************************************************/
-void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString* namespaceOrClassName, SString* methodName, SString* methodSignature, SIZE_T pCode, ReJITID rejitID)
+void ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, SIZE_T pCode, ReJITID rejitID)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_NOTRIGGER;
SO_NOT_MAINLINE;
} CONTRACTL_END;
- Module* pModule = NULL;
- Module* pLoaderModule = NULL; // This must not be used except for getting the ModuleID
- ULONGLONG ullMethodStartAddress = 0, ullColdMethodStartAddress = 0, ullModuleID = 0, ullMethodIdentifier = 0;
- ULONG ulMethodSize = 0, ulColdMethodSize = 0, ulMethodToken = 0, ulMethodFlags = 0, ulColdMethodFlags = 0;
- PWCHAR pMethodName = NULL, pNamespaceName = NULL, pMethodSignature = NULL;
+ Module *pModule = NULL;
+ Module *pLoaderModule = NULL; // This must not be used except for getting the ModuleID
+ ULONGLONG ullMethodStartAddress=0, ullColdMethodStartAddress=0, ullModuleID=0, ullMethodIdentifier=0;
+ ULONG ulMethodSize=0, ulColdMethodSize=0, ulMethodToken=0, ulMethodFlags=0, ulColdMethodFlags=0;
+ PWCHAR pMethodName=NULL, pNamespaceName=NULL, pMethodSignature=NULL;
BOOL bHasNativeImage = FALSE, bShowVerboseOutput = FALSE, bIsDynamicMethod = FALSE, bHasSharedGenericCode = FALSE, bIsGenericMethod = FALSE;
#ifndef FEATURE_DTRACE
- PCWSTR szDtraceOutput1 = L"", szDtraceOutput2 = L"", szDtraceOutput3 = L"";
+ PCWSTR szDtraceOutput1=L"",szDtraceOutput2=L"",szDtraceOutput3=L"";
#else
CHAR szDtraceOutput1[DTRACE_OUTPUT_STRING_LEN];
CHAR szDtraceOutput2[DTRACE_OUTPUT_STRING_LEN];
@@ -5431,25 +5423,25 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
#endif // !FEATURE_DTRACE
BOOL bIsRundownProvider = ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodDCStart) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodDCEnd) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodDCStart) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodDCEnd));
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodDCEnd) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodDCStart) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodDCEnd));
BOOL bIsRuntimeProvider = ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodLoad) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodUnload) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodLoad) ||
- (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodUnload));
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodUnload) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodLoad) ||
+ (dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodUnload));
if (pMethodDesc == NULL)
return;
- if (!pMethodDesc->IsRestored())
+ if(!pMethodDesc->IsRestored())
{
// Forcibly restoring ngen methods can cause all sorts of deadlocks and contract violations
// These events are therefore put under the private provider
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context,
- TRACE_LEVEL_INFORMATION,
- CLR_PRIVATENGENFORCERESTORE_KEYWORD))
+ if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context,
+ TRACE_LEVEL_INFORMATION,
+ CLR_PRIVATENGENFORCERESTORE_KEYWORD))
{
PERMANENT_CONTRACT_VIOLATION(GCViolation, ReasonNonShippingCode);
pMethodDesc->CheckRestore();
@@ -5461,13 +5453,13 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
}
- if (bIsRundownProvider)
+ if(bIsRundownProvider)
{
bShowVerboseOutput = ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context,
TRACE_LEVEL_VERBOSE,
KEYWORDZERO);
}
- else if (bIsRuntimeProvider)
+ else if(bIsRuntimeProvider)
{
bShowVerboseOutput = ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_VERBOSE,
@@ -5481,7 +5473,7 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
bIsDynamicMethod = (BOOL)pMethodDesc->IsDynamicMethod();
bHasSharedGenericCode = pMethodDesc->IsSharedByGenericInstantiations();
- if (pMethodDesc->GetMethodTable_NoLogging())
+ if(pMethodDesc->GetMethodTable_NoLogging())
bIsGenericMethod = pMethodDesc->HasClassOrMethodInstantiation_NoLogging();
ulMethodFlags = ((ulMethodFlags |
@@ -5497,7 +5489,7 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
// MethodDesc ==> Code Address ==>JitMananger
TADDR start = pCode ? pCode : PCODEToPINSTR(pMethodDesc->GetNativeCode());
- if (start == 0) {
+ if(start == 0) {
// this method hasn't been jitted
return;
}
@@ -5513,22 +5505,22 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
ullMethodStartAddress = (ULONGLONG)methodRegionInfo.hotStartAddress;
ulMethodSize = (ULONG)methodRegionInfo.hotSize;
- ullModuleID = (ULONGLONG)(TADDR)pModule;
+ ullModuleID = (ULONGLONG)(TADDR) pModule;
ullMethodIdentifier = (ULONGLONG)pMethodDesc;
// Use MethodDesc if Dynamic or Generic methods
- if (bIsDynamicMethod || bIsGenericMethod)
+ if( bIsDynamicMethod || bIsGenericMethod)
{
bShowVerboseOutput = TRUE;
- if (bIsGenericMethod)
+ if(bIsGenericMethod)
ulMethodToken = (ULONG)pMethodDesc->GetMemberDef_NoLogging();
- if (bIsDynamicMethod) // if its a generic and a dynamic method, we would set the methodtoken to 0
+ if(bIsDynamicMethod) // if its a generic and a dynamic method, we would set the methodtoken to 0
ulMethodToken = (ULONG)0;
}
else
ulMethodToken = (ULONG)pMethodDesc->GetMemberDef_NoLogging();
- if (bHasNativeImage)
+ if(bHasNativeImage)
{
ullColdMethodStartAddress = (ULONGLONG)methodRegionInfo.coldStartAddress;
ulColdMethodSize = (ULONG)methodRegionInfo.coldSize; // methodRegionInfo.coldSize is size_t and info.MethodLoadInfo.MethodSize is 32 bit; will give incorrect values on a 64-bit machine
@@ -5538,9 +5530,9 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
// if verbose method load info needed, only then
// find method name and signature and fire verbose method load info
- if (bShowVerboseOutput)
+ if(bShowVerboseOutput)
{
- if (!namespaceOrClassName || !methodName || !methodSignature || (methodName->IsEmpty() && namespaceOrClassName->IsEmpty() && methodSignature->IsEmpty()))
+ if(!namespaceOrClassName|| !methodName|| !methodSignature || (methodName->IsEmpty() && namespaceOrClassName->IsEmpty() && methodSignature->IsEmpty()))
{
pMethodDesc->GetMethodInfo(tNamespace, tMethodName, tMethodSignature);
namespaceOrClassName = &tNamespace;
@@ -5572,10 +5564,10 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
return;
#endif // !FEATURE_DTRACE
- if ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodLoad) ||
+ if((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodLoad) ||
(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodLoad))
{
- if (bShowVerboseOutput)
+ if(bShowVerboseOutput)
{
FireEtwMethodLoadVerbose_V1_or_V2(ullMethodIdentifier,
ullModuleID,
@@ -5600,9 +5592,9 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
GetClrInstanceId(),
rejitID);
}
- if (bFireEventForColdSection)
+ if(bFireEventForColdSection)
{
- if (bShowVerboseOutput)
+ if(bShowVerboseOutput)
{
FireEtwMethodLoadVerbose_V1_or_V2(ullMethodIdentifier,
ullModuleID,
@@ -5629,10 +5621,10 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
}
}
}
- else if ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodUnload) ||
+ else if((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodUnload) ||
(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodUnload))
{
- if (bShowVerboseOutput)
+ if(bShowVerboseOutput)
{
FireEtwMethodUnloadVerbose_V1_or_V2(ullMethodIdentifier,
ullModuleID,
@@ -5657,9 +5649,9 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
GetClrInstanceId(),
rejitID);
}
- if (bFireEventForColdSection)
+ if(bFireEventForColdSection)
{
- if (bShowVerboseOutput)
+ if(bShowVerboseOutput)
{
FireEtwMethodUnloadVerbose_V1_or_V2(ullMethodIdentifier,
ullModuleID,
@@ -5686,10 +5678,10 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
}
}
}
- else if ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodDCStart) ||
+ else if((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodDCStart) ||
(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodDCStart))
{
- if (bShowVerboseOutput)
+ if(bShowVerboseOutput)
{
FireEtwMethodDCStartVerbose_V1_or_V2(ullMethodIdentifier,
ullModuleID,
@@ -5714,9 +5706,9 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
GetClrInstanceId(),
rejitID);
}
- if (bFireEventForColdSection)
+ if(bFireEventForColdSection)
{
- if (bShowVerboseOutput)
+ if(bShowVerboseOutput)
{
FireEtwMethodDCStartVerbose_V1_or_V2(ullMethodIdentifier,
ullModuleID,
@@ -5743,10 +5735,10 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
}
}
}
- else if ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodDCEnd) ||
+ else if((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodDCEnd) ||
(dwEventOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodDCEnd))
{
- if (bShowVerboseOutput)
+ if(bShowVerboseOutput)
{
FireEtwMethodDCEndVerbose_V1_or_V2(ullMethodIdentifier,
ullModuleID,
@@ -5771,9 +5763,9 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
GetClrInstanceId(),
rejitID);
}
- if (bFireEventForColdSection)
+ if(bFireEventForColdSection)
{
- if (bShowVerboseOutput)
+ if(bShowVerboseOutput)
{
FireEtwMethodDCEndVerbose_V1_or_V2(ullMethodIdentifier,
ullModuleID,
@@ -5830,7 +5822,7 @@ void ETW::MethodLog::SendMethodEvent(MethodDesc* pMethodDesc, DWORD dwEventOptio
//
// static
-void ETW::MethodLog::SendMethodILToNativeMapEvent(MethodDesc* pMethodDesc, DWORD dwEventOptions, ReJITID rejitID)
+void ETW::MethodLog::SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, ReJITID rejitID)
{
CONTRACTL
{
@@ -5907,42 +5899,42 @@ void ETW::MethodLog::SendMethodILToNativeMapEvent(MethodDesc* pMethodDesc, DWORD
void ETW::MethodLog::SendHelperEvent(ULONGLONG ullHelperStartAddress, ULONG ulHelperSize, LPCWSTR pHelperName)
{
WRAPPER_NO_CONTRACT;
- if (pHelperName)
+ if(pHelperName)
{
#ifndef FEATURE_DTRACE
- PCWSTR szDtraceOutput1 = L"";
+ PCWSTR szDtraceOutput1=L"";
#else
- CHAR szDtraceOutput1[DTRACE_OUTPUT_STRING_LEN];
+ CHAR szDtraceOutput1[DTRACE_OUTPUT_STRING_LEN];
#endif // !FEATURE_DTRACE
- ULONG methodFlags = ETW::MethodLog::MethodStructs::JitHelperMethod; // helper flag set
+ ULONG methodFlags = ETW::MethodLog::MethodStructs::JitHelperMethod; // helper flag set
#ifndef FEATURE_DTRACE
- FireEtwMethodLoadVerbose_V1(ullHelperStartAddress,
- 0,
- ullHelperStartAddress,
- ulHelperSize,
- 0,
- methodFlags,
- NULL,
- pHelperName,
- NULL,
- GetClrInstanceId());
+ FireEtwMethodLoadVerbose_V1(ullHelperStartAddress,
+ 0,
+ ullHelperStartAddress,
+ ulHelperSize,
+ 0,
+ methodFlags,
+ NULL,
+ pHelperName,
+ NULL,
+ GetClrInstanceId());
#else // !FEATURE_DTRACE
// since DTrace do not support UNICODE string, they need to be converted to ANSI string
- INT32 nTempHelperName = WideCharToMultiByte(pHelperName, szDtraceOutput1);
- if (nTempHelperName == 0)
- return;
- // in the action, printf, of DTtrace, it cannot print an arg with value NULL when the format is set %s.
- // Dtrace does not provide the condition statement so that we give a string "NULL" to it.
- FireEtwMethodLoadVerbose_V1(ullHelperStartAddress,
- 0,
- ullHelperStartAddress,
- ulHelperSize,
- 0,
- methodFlags,
- szDtraceOutputNULL,
- szDtraceOutput1,
- szDtraceOutputNULL,
- GetClrInstanceId());
+ INT32 nTempHelperName = WideCharToMultiByte(pHelperName, szDtraceOutput1);
+ if (nTempHelperName == 0)
+ return;
+ // in the action, printf, of DTtrace, it cannot print an arg with value NULL when the format is set %s.
+ // Dtrace does not provide the condition statement so that we give a string "NULL" to it.
+ FireEtwMethodLoadVerbose_V1(ullHelperStartAddress,
+ 0,
+ ullHelperStartAddress,
+ ulHelperSize,
+ 0,
+ methodFlags,
+ szDtraceOutputNULL,
+ szDtraceOutput1,
+ szDtraceOutputNULL,
+ GetClrInstanceId());
#endif // !FEATURE_DTRACE
}
}
@@ -5951,23 +5943,23 @@ void ETW::MethodLog::SendHelperEvent(ULONGLONG ullHelperStartAddress, ULONG ulHe
/****************************************************************************/
/* This routine sends back method events of type 'dwEventOptions', for all
NGEN methods in pModule */
- /****************************************************************************/
-void ETW::MethodLog::SendEventsForNgenMethods(Module* pModule, DWORD dwEventOptions)
+/****************************************************************************/
+void ETW::MethodLog::SendEventsForNgenMethods(Module *pModule, DWORD dwEventOptions)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
} CONTRACTL_END;
#ifdef FEATURE_PREJIT
- if (!pModule || !pModule->HasNativeImage())
+ if(!pModule || !pModule->HasNativeImage())
return;
MethodIterator mi(pModule);
- while (mi.Next())
+ while(mi.Next())
{
- MethodDesc* hotDesc = (MethodDesc*)mi.GetMethodDesc();
+ MethodDesc *hotDesc = (MethodDesc *)mi.GetMethodDesc();
ETW::MethodLog::SendMethodEvent(hotDesc, dwEventOptions, FALSE);
}
#endif // FEATURE_PREJIT
@@ -5978,10 +5970,10 @@ void ETW::MethodLog::SendEventsForNgenMethods(Module* pModule, DWORD dwEventOpti
JITed methods in either a given LoaderAllocator (if pLoaderAllocatorFilter is non NULL)
or in a given Domain (if pDomainFilter is non NULL) or for
all methods (if both filters are null) */
- /****************************************************************************/
-void ETW::MethodLog::SendEventsForJitMethods(BaseDomain* pDomainFilter, LoaderAllocator* pLoaderAllocatorFilter, DWORD dwEventOptions)
+/****************************************************************************/
+void ETW::MethodLog::SendEventsForJitMethods(BaseDomain *pDomainFilter, LoaderAllocator *pLoaderAllocatorFilter, DWORD dwEventOptions)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
} CONTRACTL_END;
@@ -5991,19 +5983,19 @@ void ETW::MethodLog::SendEventsForJitMethods(BaseDomain* pDomainFilter, LoaderAl
// This is only called for JITted methods loading xor unloading
BOOL fLoadOrDCStart = ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodLoadOrDCStartAny) != 0);
BOOL fUnloadOrDCEnd = ((dwEventOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodUnloadOrDCEndAny) != 0);
- _ASSERTE((fLoadOrDCStart || fUnloadOrDCEnd) && !(fLoadOrDCStart&& fUnloadOrDCEnd));
+ _ASSERTE((fLoadOrDCStart || fUnloadOrDCEnd) && !(fLoadOrDCStart && fUnloadOrDCEnd));
BOOL fSendMethodEvent =
(dwEventOptions &
(ETW::EnumerationLog::EnumerationStructs::JitMethodLoad |
- ETW::EnumerationLog::EnumerationStructs::JitMethodDCStart |
- ETW::EnumerationLog::EnumerationStructs::JitMethodUnload |
- ETW::EnumerationLog::EnumerationStructs::JitMethodDCEnd)) != 0;
+ ETW::EnumerationLog::EnumerationStructs::JitMethodDCStart |
+ ETW::EnumerationLog::EnumerationStructs::JitMethodUnload |
+ ETW::EnumerationLog::EnumerationStructs::JitMethodDCEnd)) != 0;
BOOL fSendILToNativeMapEvent =
(dwEventOptions &
(ETW::EnumerationLog::EnumerationStructs::MethodDCStartILToNativeMap |
- ETW::EnumerationLog::EnumerationStructs::MethodDCEndILToNativeMap)) != 0;
+ ETW::EnumerationLog::EnumerationStructs::MethodDCEndILToNativeMap)) != 0;
BOOL fCollectibleLoaderAllocatorFilter =
((pLoaderAllocatorFilter != NULL) && (pLoaderAllocatorFilter->IsCollectible()));
@@ -6022,9 +6014,9 @@ void ETW::MethodLog::SendEventsForJitMethods(BaseDomain* pDomainFilter, LoaderAl
#endif // WINXP_AND_WIN2K3_BUILD_SUPPORT
EEJitManager::CodeHeapIterator heapIterator(pDomainFilter, pLoaderAllocatorFilter);
- while (heapIterator.Next())
+ while(heapIterator.Next())
{
- MethodDesc* pMD = heapIterator.GetMethod();
+ MethodDesc * pMD = heapIterator.GetMethod();
if (pMD == NULL)
continue;
@@ -6111,7 +6103,7 @@ void ETW::MethodLog::SendEventsForJitMethods(BaseDomain* pDomainFilter, LoaderAl
// enumerationOptions - Flags indicating what to enumerate. Just passed
// straight through to IterateDomain
//
-void ETW::EnumerationLog::IterateAppDomain(AppDomain* pAppDomain, DWORD enumerationOptions)
+void ETW::EnumerationLog::IterateAppDomain(AppDomain * pAppDomain, DWORD enumerationOptions)
{
CONTRACTL
{
@@ -6151,10 +6143,10 @@ void ETW::EnumerationLog::IterateAppDomain(AppDomain* pAppDomain, DWORD enumerat
JIT methods in them,
and the NGEN methods in them
based on enumerationOptions.*/
- /********************************************************************************/
-void ETW::EnumerationLog::IterateDomain(BaseDomain* pDomain, DWORD enumerationOptions)
+/********************************************************************************/
+void ETW::EnumerationLog::IterateDomain(BaseDomain *pDomain, DWORD enumerationOptions)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
PRECONDITION(pDomain != NULL);
@@ -6174,86 +6166,86 @@ void ETW::EnumerationLog::IterateDomain(BaseDomain* pDomain, DWORD enumerationOp
EX_TRY
{
// DC Start events for Domain
- if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
+ if(enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
{
ETW::LoaderLog::SendDomainEvent(pDomain, enumerationOptions);
}
- // DC End or Unload Jit Method events
- if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodUnloadOrDCEndAny)
- {
- ETW::MethodLog::SendEventsForJitMethods(pDomain, NULL, enumerationOptions);
- }
+ // DC End or Unload Jit Method events
+ if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodUnloadOrDCEndAny)
+ {
+ ETW::MethodLog::SendEventsForJitMethods(pDomain, NULL, enumerationOptions);
+ }
- if (pDomain->IsAppDomain())
- {
- AppDomain::AssemblyIterator assemblyIterator = pDomain->AsAppDomain()->IterateAssembliesEx(
- (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution));
- CollectibleAssemblyHolder pDomainAssembly;
- while (assemblyIterator.Next(pDomainAssembly.This()))
+ if (pDomain->IsAppDomain())
{
- CollectibleAssemblyHolder pAssembly = pDomainAssembly->GetLoadedAssembly();
- BOOL bIsDomainNeutral = pAssembly->IsDomainNeutral();
- if (bIsDomainNeutral)
- continue;
- if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
+ AppDomain::AssemblyIterator assemblyIterator = pDomain->AsAppDomain()->IterateAssembliesEx(
+ (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution));
+ CollectibleAssemblyHolder pDomainAssembly;
+ while (assemblyIterator.Next(pDomainAssembly.This()))
{
- ETW::EnumerationLog::IterateAssembly(pAssembly, enumerationOptions);
- }
+ CollectibleAssemblyHolder pAssembly = pDomainAssembly->GetLoadedAssembly();
+ BOOL bIsDomainNeutral = pAssembly->IsDomainNeutral();
+ if (bIsDomainNeutral)
+ continue;
+ if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
+ {
+ ETW::EnumerationLog::IterateAssembly(pAssembly, enumerationOptions);
+ }
- DomainModuleIterator domainModuleIterator = pDomainAssembly->IterateModules(kModIterIncludeLoaded);
- while (domainModuleIterator.Next())
- {
- Module* pModule = domainModuleIterator.GetModule();
- ETW::EnumerationLog::IterateModule(pModule, enumerationOptions);
- }
+ DomainModuleIterator domainModuleIterator = pDomainAssembly->IterateModules(kModIterIncludeLoaded);
+ while (domainModuleIterator.Next())
+ {
+ Module * pModule = domainModuleIterator.GetModule();
+ ETW::EnumerationLog::IterateModule(pModule, enumerationOptions);
+ }
- if ((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload))
- {
- ETW::EnumerationLog::IterateAssembly(pAssembly, enumerationOptions);
+ if((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload))
+ {
+ ETW::EnumerationLog::IterateAssembly(pAssembly, enumerationOptions);
+ }
}
}
- }
- else
- {
- SharedDomain::SharedAssemblyIterator sharedDomainIterator;
- while (sharedDomainIterator.Next())
+ else
{
- Assembly* pAssembly = sharedDomainIterator.GetAssembly();
- if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
+ SharedDomain::SharedAssemblyIterator sharedDomainIterator;
+ while (sharedDomainIterator.Next())
{
- ETW::EnumerationLog::IterateAssembly(pAssembly, enumerationOptions);
- }
+ Assembly * pAssembly = sharedDomainIterator.GetAssembly();
+ if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
+ {
+ ETW::EnumerationLog::IterateAssembly(pAssembly, enumerationOptions);
+ }
- ModuleIterator domainModuleIterator = pAssembly->IterateModules();
- while (domainModuleIterator.Next())
- {
- Module* pModule = domainModuleIterator.GetModule();
- ETW::EnumerationLog::IterateModule(pModule, enumerationOptions);
- }
+ ModuleIterator domainModuleIterator = pAssembly->IterateModules();
+ while (domainModuleIterator.Next())
+ {
+ Module * pModule = domainModuleIterator.GetModule();
+ ETW::EnumerationLog::IterateModule(pModule, enumerationOptions);
+ }
- if ((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload))
- {
- ETW::EnumerationLog::IterateAssembly(pAssembly, enumerationOptions);
+ if ((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload))
+ {
+ ETW::EnumerationLog::IterateAssembly(pAssembly, enumerationOptions);
+ }
}
}
- }
- // DC Start or Load Jit Method events
- if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodLoadOrDCStartAny)
- {
- ETW::MethodLog::SendEventsForJitMethods(pDomain, NULL, enumerationOptions);
- }
+ // DC Start or Load Jit Method events
+ if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::JitMethodLoadOrDCStartAny)
+ {
+ ETW::MethodLog::SendEventsForJitMethods(pDomain, NULL, enumerationOptions);
+ }
- // DC End or Unload events for Domain
- if ((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload))
- {
- ETW::LoaderLog::SendDomainEvent(pDomain, enumerationOptions);
- }
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ // DC End or Unload events for Domain
+ if((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload))
+ {
+ ETW::LoaderLog::SendDomainEvent(pDomain, enumerationOptions);
+ }
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
@@ -6265,10 +6257,10 @@ void ETW::EnumerationLog::IterateDomain(BaseDomain* pDomain, DWORD enumerationOp
JIT methods in them,
and the NGEN methods in them
based on enumerationOptions.*/
- /********************************************************************************/
-void ETW::EnumerationLog::IterateCollectibleLoaderAllocator(AssemblyLoaderAllocator* pLoaderAllocator, DWORD enumerationOptions)
+/********************************************************************************/
+void ETW::EnumerationLog::IterateCollectibleLoaderAllocator(AssemblyLoaderAllocator *pLoaderAllocator, DWORD enumerationOptions)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
PRECONDITION(pLoaderAllocator != NULL);
@@ -6282,13 +6274,13 @@ void ETW::EnumerationLog::IterateCollectibleLoaderAllocator(AssemblyLoaderAlloca
ETW::MethodLog::SendEventsForJitMethods(NULL, pLoaderAllocator, enumerationOptions);
}
- Assembly* pAssembly = pLoaderAllocator->Id()->GetDomainAssembly()->GetAssembly();
+ Assembly *pAssembly = pLoaderAllocator->Id()->GetDomainAssembly()->GetAssembly();
_ASSERTE(!pAssembly->IsDomainNeutral()); // Collectible Assemblies are not domain neutral.
DomainModuleIterator domainModuleIterator = pLoaderAllocator->Id()->GetDomainAssembly()->IterateModules(kModIterIncludeLoaded);
while (domainModuleIterator.Next())
{
- Module* pModule = domainModuleIterator.GetModule();
+ Module *pModule = domainModuleIterator.GetModule();
ETW::EnumerationLog::IterateModule(pModule, enumerationOptions);
}
@@ -6302,16 +6294,16 @@ void ETW::EnumerationLog::IterateCollectibleLoaderAllocator(AssemblyLoaderAlloca
{
ETW::MethodLog::SendEventsForJitMethods(NULL, pLoaderAllocator, enumerationOptions);
}
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/********************************************************************************/
/* This routine fires ETW events for Assembly and the DomainModule's in them
based on enumerationOptions.*/
- /********************************************************************************/
-void ETW::EnumerationLog::IterateAssembly(Assembly* pAssembly, DWORD enumerationOptions)
+/********************************************************************************/
+void ETW::EnumerationLog::IterateAssembly(Assembly *pAssembly, DWORD enumerationOptions)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
PRECONDITION(pAssembly != NULL);
@@ -6320,41 +6312,41 @@ void ETW::EnumerationLog::IterateAssembly(Assembly* pAssembly, DWORD enumeration
EX_TRY
{
// DC Start events for Assembly
- if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
+ if(enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
{
ETW::LoaderLog::SendAssemblyEvent(pAssembly, enumerationOptions);
}
- // DC Start, DCEnd, events for DomainModule
- if ((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart))
- {
- if (pAssembly->GetDomain()->IsAppDomain())
+ // DC Start, DCEnd, events for DomainModule
+ if((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart))
{
- DomainModuleIterator dmIterator = pAssembly->FindDomainAssembly(pAssembly->GetDomain()->AsAppDomain())->IterateModules(kModIterIncludeLoaded);
- while (dmIterator.Next())
+ if(pAssembly->GetDomain()->IsAppDomain())
{
- ETW::LoaderLog::SendModuleEvent(dmIterator.GetModule(), enumerationOptions, TRUE);
+ DomainModuleIterator dmIterator = pAssembly->FindDomainAssembly(pAssembly->GetDomain()->AsAppDomain())->IterateModules(kModIterIncludeLoaded);
+ while (dmIterator.Next())
+ {
+ ETW::LoaderLog::SendModuleEvent(dmIterator.GetModule(), enumerationOptions, TRUE);
+ }
}
}
- }
- // DC End or Unload events for Assembly
- if ((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload))
- {
- ETW::LoaderLog::SendAssemblyEvent(pAssembly, enumerationOptions);
- }
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ // DC End or Unload events for Assembly
+ if((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload))
+ {
+ ETW::LoaderLog::SendAssemblyEvent(pAssembly, enumerationOptions);
+ }
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
/********************************************************************************/
/* This routine fires ETW events for Module, their range information and the NGEN methods in them
based on enumerationOptions.*/
- /********************************************************************************/
-void ETW::EnumerationLog::IterateModule(Module* pModule, DWORD enumerationOptions)
+/********************************************************************************/
+void ETW::EnumerationLog::IterateModule(Module *pModule, DWORD enumerationOptions)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
PRECONDITION(pModule != NULL);
@@ -6363,45 +6355,45 @@ void ETW::EnumerationLog::IterateModule(Module* pModule, DWORD enumerationOption
EX_TRY
{
// DC Start events for Module
- if ((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) ||
+ if((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart) ||
(enumerationOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCStart))
{
ETW::LoaderLog::SendModuleEvent(pModule, enumerationOptions);
}
- // DC Start or Load or DC End or Unload Ngen Method events
- if ((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodLoad) ||
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodDCStart) ||
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodUnload) ||
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodDCEnd))
- {
- ETW::MethodLog::SendEventsForNgenMethods(pModule, enumerationOptions);
- }
+ // DC Start or Load or DC End or Unload Ngen Method events
+ if((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodLoad) ||
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodDCStart) ||
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodUnload) ||
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::NgenMethodDCEnd))
+ {
+ ETW::MethodLog::SendEventsForNgenMethods(pModule, enumerationOptions);
+ }
- // DC End or Unload events for Module
- if ((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload) ||
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCEnd))
- {
- ETW::LoaderLog::SendModuleEvent(pModule, enumerationOptions);
- }
+ // DC End or Unload events for Module
+ if((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload) ||
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeDCEnd))
+ {
+ ETW::LoaderLog::SendModuleEvent(pModule, enumerationOptions);
+ }
- // If we're logging types, then update the internal Type hash table to account
- // for the module's unloading
- if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::TypeUnload)
- {
- ETW::TypeSystemLog::OnModuleUnload(pModule);
- }
+ // If we're logging types, then update the internal Type hash table to account
+ // for the module's unloading
+ if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::TypeUnload)
+ {
+ ETW::TypeSystemLog::OnModuleUnload(pModule);
+ }
- // ModuleRangeLoadPrivate events for module range information from attach/detach scenarios
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context,
- TRACE_LEVEL_INFORMATION,
- CLR_PERFTRACK_PRIVATE_KEYWORD) &&
- (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeLoadPrivate))
- {
- ETW::LoaderLog::SendModuleEvent(pModule, enumerationOptions);
- }
- } EX_CATCH{ } EX_END_CATCH(SwallowAllExceptions);
+ // ModuleRangeLoadPrivate events for module range information from attach/detach scenarios
+ if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context,
+ TRACE_LEVEL_INFORMATION,
+ CLR_PERFTRACK_PRIVATE_KEYWORD) &&
+ (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::ModuleRangeLoadPrivate))
+ {
+ ETW::LoaderLog::SendModuleEvent(pModule, enumerationOptions);
+ }
+ } EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
}
//---------------------------------------------------------------------------------------
@@ -6437,9 +6429,9 @@ void ETW::EnumerationLog::IterateModule(Module* pModule, DWORD enumerationOption
//
// static
-void ETW::EnumerationLog::EnumerationHelper(Module* moduleFilter, BaseDomain* domainFilter, DWORD enumerationOptions)
+void ETW::EnumerationLog::EnumerationHelper(Module *moduleFilter, BaseDomain *domainFilter, DWORD enumerationOptions)
{
- CONTRACTL{
+ CONTRACTL {
THROWS;
GC_TRIGGERS;
} CONTRACTL_END;
@@ -6452,7 +6444,7 @@ void ETW::EnumerationLog::EnumerationHelper(Module* moduleFilter, BaseDomain* do
// See code:#TableLockHolder
ReJitManager::TableLockHolder lkRejitMgrSharedDomain(SharedDomain::GetDomain()->GetReJitManager());
- if (moduleFilter)
+ if(moduleFilter)
{
// See code:#TableLockHolder
ReJitManager::TableLockHolder lkRejitMgrModule(moduleFilter->GetReJitManager());
@@ -6474,12 +6466,12 @@ void ETW::EnumerationLog::EnumerationHelper(Module* moduleFilter, BaseDomain* do
}
else
{
- if (domainFilter)
+ if(domainFilter)
{
// See code:#TableLockHolder
ReJitManager::TableLockHolder lkRejitMgrAD(domainFilter->GetReJitManager());
- if (domainFilter->IsAppDomain())
+ if(domainFilter->IsAppDomain())
{
ETW::EnumerationLog::IterateAppDomain(domainFilter->AsAppDomain(), enumerationOptions);
}
@@ -6491,9 +6483,9 @@ void ETW::EnumerationLog::EnumerationHelper(Module* moduleFilter, BaseDomain* do
else
{
AppDomainIterator appDomainIterator(FALSE);
- while (appDomainIterator.Next())
+ while(appDomainIterator.Next())
{
- AppDomain* pDomain = appDomainIterator.GetDomain();
+ AppDomain *pDomain = appDomainIterator.GetDomain();
if (pDomain != NULL)
{
// See code:#TableLockHolder
diff --git a/src/coreclr/nativeaot/Runtime/eventtracebase.h b/src/coreclr/nativeaot/Runtime/eventtracebase.h
index e4a16fd87d6e0..79b8fac860612 100644
--- a/src/coreclr/nativeaot/Runtime/eventtracebase.h
+++ b/src/coreclr/nativeaot/Runtime/eventtracebase.h
@@ -147,6 +147,13 @@ struct ProfilingScanContext;
#ifndef FEATURE_REDHAWK
+#if defined(FEATURE_CORECLR) && !defined(FEATURE_CORESYSTEM)
+// For Silverlight non-CoreSys builds we still use an older toolset,
+// headers/libs, and a different value for WINVER. We use this symbol
+// to distinguish between whether we built the ETW header files from
+// the ETW manifest using the -mof command line or not.
+#define WINXP_AND_WIN2K3_BUILD_SUPPORT
+#endif
#include "corprof.h"
// g_nClrInstanceId is defined in Utilcode\Util.cpp. The definition goes into Utilcode.lib.
diff --git a/src/coreclr/nativeaot/Runtime/gcrhenv.cpp b/src/coreclr/nativeaot/Runtime/gcrhenv.cpp
index 0001de5370c1d..2f6f6ea4f7c0c 100644
--- a/src/coreclr/nativeaot/Runtime/gcrhenv.cpp
+++ b/src/coreclr/nativeaot/Runtime/gcrhenv.cpp
@@ -585,8 +585,7 @@ void RedhawkGCInterface::UnregisterFrozenSegment(GcSegmentHandle segment)
GCHeapUtilities::GetGCHeap()->UnregisterFrozenSegment((segment_handle)segment);
}
-EXTERN_C UInt32_BOOL g_fGcStressStarted;
-UInt32_BOOL g_fGcStressStarted = UInt32_FALSE; // UInt32_BOOL because asm code reads it
+EXTERN_C UInt32_BOOL g_fGcStressStarted = UInt32_FALSE; // UInt32_BOOL because asm code reads it
#ifdef FEATURE_GC_STRESS
// static
void RedhawkGCInterface::StressGc()
diff --git a/src/coreclr/nativeaot/Runtime/startup.cpp b/src/coreclr/nativeaot/Runtime/startup.cpp
index 9f82aebdbf39e..ada010f8a573e 100644
--- a/src/coreclr/nativeaot/Runtime/startup.cpp
+++ b/src/coreclr/nativeaot/Runtime/startup.cpp
@@ -45,17 +45,14 @@ static bool DetectCPUFeatures();
extern RhConfig * g_pRhConfig;
-EXTERN_C bool g_fHasFastFxsave;
-bool g_fHasFastFxsave = false;
+EXTERN_C bool g_fHasFastFxsave = false;
CrstStatic g_CastCacheLock;
CrstStatic g_ThunkPoolLock;
#if defined(HOST_X86) || defined(HOST_AMD64) || defined(HOST_ARM64)
// This field is inspected from the generated code to determine what intrinsics are available.
-EXTERN_C int g_cpuFeatures;
-int g_cpuFeatures = 0;
-
+EXTERN_C int g_cpuFeatures = 0;
// This field is defined in the generated code and sets the ISA expectations.
EXTERN_C int g_requiredCpuFeatures;
#endif
diff --git a/src/coreclr/nativeaot/Runtime/threadstore.cpp b/src/coreclr/nativeaot/Runtime/threadstore.cpp
index 36bf43c1a359f..e0a7d528358ab 100644
--- a/src/coreclr/nativeaot/Runtime/threadstore.cpp
+++ b/src/coreclr/nativeaot/Runtime/threadstore.cpp
@@ -27,8 +27,7 @@
#include "slist.inl"
#include "GCMemoryHelpers.h"
-EXTERN_C volatile uint32_t RhpTrapThreads;
-volatile uint32_t RhpTrapThreads = (uint32_t)TrapThreadsFlags::None;
+EXTERN_C volatile uint32_t RhpTrapThreads = (uint32_t)TrapThreadsFlags::None;
GVAL_IMPL_INIT(PTR_Thread, RhpSuspendingThread, 0);
@@ -374,8 +373,7 @@ COOP_PINVOKE_HELPER(void, RhpCancelThreadAbort, (void* thread))
C_ASSERT(sizeof(Thread) == sizeof(ThreadBuffer));
-EXTERN_C DECLSPEC_THREAD ThreadBuffer tls_CurrentThread;
-DECLSPEC_THREAD ThreadBuffer tls_CurrentThread =
+EXTERN_C DECLSPEC_THREAD ThreadBuffer tls_CurrentThread =
{
{ 0 }, // m_rgbAllocContextBuffer
Thread::TSF_Unknown, // m_ThreadStateFlags
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 198172362464a..2cc2f40a841f8 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
@@ -1091,10 +1091,5 @@ public static bool IsPrimitive(RuntimeTypeHandle typeHandle)
{
return typeHandle.ToEETypePtr().IsPrimitive && !typeHandle.ToEETypePtr().IsEnum;
}
-
- public static byte[] ComputePublicKeyToken(byte[] publicKey)
- {
- return System.Reflection.AssemblyNameHelpers.ComputePublicKeyToken(publicKey);
- }
}
}
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 2284e13f66135..cf0cab0700eba 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
@@ -123,12 +123,15 @@
+
+
+
+
-
-
+
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Math.CoreRT.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Math.CoreRT.cs
index 15b629dbee219..8a53e1588b83d 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Math.CoreRT.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Math.CoreRT.cs
@@ -16,6 +16,18 @@ namespace System
{
public static partial class Math
{
+ [Intrinsic]
+ public static float Abs(float value)
+ {
+ return RuntimeImports.fabsf(value);
+ }
+
+ [Intrinsic]
+ public static double Abs(double value)
+ {
+ return RuntimeImports.fabs(value);
+ }
+
[Intrinsic]
public static double Acos(double d)
{
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ModuleHandle.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ModuleHandle.cs
index d1bb831f34772..3714e7ce510fb 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ModuleHandle.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ModuleHandle.cs
@@ -6,7 +6,7 @@
namespace System
{
- public struct ModuleHandle : IEquatable
+ public struct ModuleHandle
{
public static readonly ModuleHandle EmptyHandle;
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyName.CoreRT.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyName.CoreRT.cs
new file mode 100644
index 0000000000000..bc3ef37804315
--- /dev/null
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyName.CoreRT.cs
@@ -0,0 +1,34 @@
+// 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.Serialization;
+
+namespace System.Reflection
+{
+ public sealed partial class AssemblyName : ICloneable, IDeserializationCallback, ISerializable
+ {
+ public AssemblyName(string assemblyName)
+ : this()
+ {
+ if (assemblyName == null)
+ throw new ArgumentNullException(nameof(assemblyName));
+ if ((assemblyName.Length == 0) ||
+ (assemblyName[0] == '\0'))
+ throw new ArgumentException(SR.Format_StringZeroLength);
+
+ _name = assemblyName;
+ RuntimeAssemblyName runtimeAssemblyName = AssemblyNameParser.Parse(_name);
+ runtimeAssemblyName.CopyToAssemblyName(this);
+ }
+
+ private byte[] ComputePublicKeyToken()
+ {
+ return AssemblyNameHelpers.ComputePublicKeyToken(_publicKey);
+ }
+
+ private static AssemblyName GetFileInformationCore(string assemblyFile)
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_AssemblyName_GetAssemblyName);
+ }
+ }
+}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameHelpers.StrongName.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameHelpers.StrongName.cs
similarity index 98%
rename from src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameHelpers.StrongName.cs
rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameHelpers.StrongName.cs
index ef05ef39f8a7e..85e437548102e 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyNameHelpers.StrongName.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameHelpers.StrongName.cs
@@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Buffers.Binary;
+using System.Runtime;
using System.Security;
namespace System.Reflection
{
- internal static partial class AssemblyNameHelpers
+ public static partial class AssemblyNameHelpers
{
public static byte[]? ComputePublicKeyToken(byte[]? publicKey)
{
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameHelpers.cs
index a79f9f7f65307..b259e2b6bfbdc 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameHelpers.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameHelpers.cs
@@ -9,8 +9,41 @@
namespace System.Reflection
{
- internal static partial class AssemblyNameHelpers
+ [System.Runtime.CompilerServices.ReflectionBlocked]
+ public static partial class AssemblyNameHelpers
{
+ //
+ // Converts an AssemblyName to a RuntimeAssemblyName that is free from any future mutations on the AssemblyName.
+ //
+ public static RuntimeAssemblyName ToRuntimeAssemblyName(this AssemblyName assemblyName)
+ {
+ if (assemblyName.Name == null)
+ throw new ArgumentException();
+
+ AssemblyNameFlags flags = assemblyName.Flags;
+ AssemblyContentType contentType = assemblyName.ContentType;
+#pragma warning disable SYSLIB0037 // AssemblyName.ProcessorArchitecture is obsolete
+ ProcessorArchitecture processorArchitecture = assemblyName.ProcessorArchitecture;
+#pragma warning restore SYSLIB0037
+ AssemblyNameFlags combinedFlags = CombineAssemblyNameFlags(flags, contentType, processorArchitecture);
+ byte[]? pkOriginal;
+ if (0 != (flags & AssemblyNameFlags.PublicKey))
+ pkOriginal = assemblyName.GetPublicKey();
+ else
+ pkOriginal = assemblyName.GetPublicKeyToken();
+
+ // AssemblyName's PKT property getters do NOT copy the array before giving it out. Make our own copy
+ // as the original is wide open to tampering by anyone.
+ byte[]? pkCopy = null;
+ if (pkOriginal != null)
+ {
+ pkCopy = new byte[pkOriginal.Length];
+ ((ICollection)pkOriginal).CopyTo(pkCopy, 0);
+ }
+
+ return new RuntimeAssemblyName(assemblyName.Name, assemblyName.Version, assemblyName.CultureName, combinedFlags, pkCopy);
+ }
+
//
// These helpers convert between the combined flags+contentType+processorArchitecture value and the separated parts.
//
@@ -22,9 +55,19 @@ internal static AssemblyContentType ExtractAssemblyContentType(this AssemblyName
return (AssemblyContentType)((((int)flags) >> 9) & 0x7);
}
- internal static AssemblyNameFlags ExtractAssemblyNameFlags(this AssemblyNameFlags combinedFlags)
+ internal static ProcessorArchitecture ExtractProcessorArchitecture(this AssemblyNameFlags flags)
+ {
+ return (ProcessorArchitecture)((((int)flags) >> 4) & 0x7);
+ }
+
+ public static AssemblyNameFlags ExtractAssemblyNameFlags(this AssemblyNameFlags combinedFlags)
{
return combinedFlags & unchecked((AssemblyNameFlags)0xFFFFF10F);
}
+
+ internal static AssemblyNameFlags CombineAssemblyNameFlags(AssemblyNameFlags flags, AssemblyContentType contentType, ProcessorArchitecture processorArchitecture)
+ {
+ return (AssemblyNameFlags)(((int)flags) | (((int)contentType) << 9) | ((int)processorArchitecture << 4));
+ }
}
}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameLexer.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameLexer.cs
new file mode 100644
index 0000000000000..84555ab310d45
--- /dev/null
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameLexer.cs
@@ -0,0 +1,136 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Text;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace System.Reflection
+{
+ //
+ // A simple lexer for assembly display names.
+ //
+ internal struct AssemblyNameLexer
+ {
+ internal AssemblyNameLexer(string s)
+ {
+ // Convert string to char[] with NUL terminator. (An actual NUL terminator in the input string will be treated
+ // as an actual end of string: this is compatible with desktop behavior.)
+ char[] chars = new char[s.Length + 1];
+ s.CopyTo(0, chars, 0, s.Length);
+ _chars = chars;
+ _index = 0;
+ }
+
+ //
+ // Return the next token in assembly name. If you expect the result to be DisplayNameToken.String,
+ // use GetNext(out String) instead.
+ //
+ internal Token GetNext()
+ {
+ return GetNext(out _);
+ }
+
+ //
+ // Return the next token in assembly name. If the result is DisplayNameToken.String,
+ // sets "tokenString" to the tokenized string.
+ //
+ internal Token GetNext(out string tokenString)
+ {
+ tokenString = null;
+ while (char.IsWhiteSpace(_chars[_index]))
+ _index++;
+
+ char c = _chars[_index++];
+ if (c == 0)
+ return Token.End;
+ if (c == ',')
+ return Token.Comma;
+ if (c == '=')
+ return Token.Equals;
+
+ StringBuilder sb = new StringBuilder();
+
+ char quoteChar = (char)0;
+ if (c == '\'' || c == '\"')
+ {
+ quoteChar = c;
+ c = _chars[_index++];
+ }
+
+ for (;;)
+ {
+ if (c == 0)
+ {
+ _index--;
+ break; // Terminate: End of string (desktop compat: if string was quoted, permitted to terminate without end-quote.)
+ }
+
+ if (quoteChar != 0 && c == quoteChar)
+ break; // Terminate: Found closing quote of quoted string.
+
+ if (quoteChar == 0 && (c == ',' || c == '='))
+ {
+ _index--;
+ break; // Terminate: Found start of a new ',' or '=' token.
+ }
+
+ if (quoteChar == 0 && (c == '\'' || c == '\"'))
+ throw new FileLoadException(); // Desktop compat: Unescaped quote illegal unless entire string is quoted.
+
+ if (c == '\\')
+ {
+ c = _chars[_index++];
+
+ switch (c)
+ {
+ case '\\':
+ case ',':
+ case '=':
+ case '\'':
+ case '"':
+ sb.Append(c);
+ break;
+ case 't':
+ sb.Append('\t');
+ break;
+ case 'r':
+ sb.Append('\r');
+ break;
+ case 'n':
+ sb.Append('\n');
+ break;
+ default:
+ throw new FileLoadException(); // Unrecognized escape
+ }
+ }
+ else
+ {
+ sb.Append(c);
+ }
+
+ c = _chars[_index++];
+ }
+
+ tokenString = sb.ToString();
+ if (quoteChar == 0)
+ tokenString = tokenString.Trim(); // Unless quoted, whitespace at beginning or end doesn't count.
+ return Token.String;
+ }
+
+ // Token categories for display name lexer.
+ internal enum Token
+ {
+ Equals = 1,
+ Comma = 2,
+ String = 3,
+ End = 4,
+ }
+
+ private readonly char[] _chars;
+ private int _index;
+ }
+}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameParser.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameParser.cs
new file mode 100644
index 0000000000000..5d8f2ef1c34b0
--- /dev/null
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyNameParser.cs
@@ -0,0 +1,230 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Text;
+using System.Diagnostics;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace System.Reflection
+{
+ //
+ // Parses an assembly name.
+ //
+ [System.Runtime.CompilerServices.ReflectionBlocked]
+ public static class AssemblyNameParser
+ {
+ public static void Parse(AssemblyName blank, string s)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ RuntimeAssemblyName runtimeAssemblyName = Parse(s);
+ runtimeAssemblyName.CopyToAssemblyName(blank);
+ }
+
+ public static RuntimeAssemblyName Parse(string s)
+ {
+ Debug.Assert(s != null);
+
+ int indexOfNul = s.IndexOf((char)0);
+ if (indexOfNul != -1)
+ s = s.Substring(0, indexOfNul);
+ if (s.Length == 0)
+ throw new ArgumentException(SR.Format_StringZeroLength);
+
+ AssemblyNameLexer lexer = new AssemblyNameLexer(s);
+
+ // Name must come first.
+ string name;
+ AssemblyNameLexer.Token token = lexer.GetNext(out name);
+ if (token != AssemblyNameLexer.Token.String)
+ throw new FileLoadException(SR.InvalidAssemblyName);
+
+ if (name == string.Empty || name.IndexOfAny(s_illegalCharactersInSimpleName) != -1)
+ throw new FileLoadException(SR.InvalidAssemblyName);
+
+ Version? version = null;
+ string? cultureName = null;
+ byte[]? pkt = null;
+ AssemblyNameFlags flags = 0;
+
+ LowLevelList alreadySeen = new LowLevelList();
+ token = lexer.GetNext();
+ while (token != AssemblyNameLexer.Token.End)
+ {
+ if (token != AssemblyNameLexer.Token.Comma)
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ string attributeName;
+
+ token = lexer.GetNext(out attributeName);
+ if (token != AssemblyNameLexer.Token.String)
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ token = lexer.GetNext();
+
+ // Compat note: Inside AppX apps, the desktop CLR's AssemblyName parser skips past any elements that don't follow the "=" pattern.
+ // (when running classic Windows apps, such an illegal construction throws an exception as expected.)
+ // Naturally, at least one app unwittingly takes advantage of this.
+ if (token == AssemblyNameLexer.Token.Comma || token == AssemblyNameLexer.Token.End)
+ continue;
+
+ if (token != AssemblyNameLexer.Token.Equals)
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ string attributeValue;
+ token = lexer.GetNext(out attributeValue);
+ if (token != AssemblyNameLexer.Token.String)
+ throw new FileLoadException(SR.InvalidAssemblyName);
+
+ if (attributeName == string.Empty)
+ throw new FileLoadException(SR.InvalidAssemblyName);
+
+ for (int i = 0; i < alreadySeen.Count; i++)
+ {
+ if (alreadySeen[i].Equals(attributeName, StringComparison.OrdinalIgnoreCase))
+ throw new FileLoadException(SR.InvalidAssemblyName); // Cannot specify the same attribute twice.
+ }
+ alreadySeen.Add(attributeName);
+
+ if (attributeName.Equals("Version", StringComparison.OrdinalIgnoreCase))
+ {
+ version = ParseVersion(attributeValue);
+ }
+
+ if (attributeName.Equals("Culture", StringComparison.OrdinalIgnoreCase))
+ {
+ cultureName = ParseCulture(attributeValue);
+ }
+
+ if (attributeName.Equals("PublicKeyToken", StringComparison.OrdinalIgnoreCase))
+ {
+ pkt = ParsePKT(attributeValue);
+ }
+
+ if (attributeName.Equals("ProcessorArchitecture", StringComparison.OrdinalIgnoreCase))
+ {
+ flags |= (AssemblyNameFlags)(((int)ParseProcessorArchitecture(attributeValue)) << 4);
+ }
+
+ if (attributeName.Equals("Retargetable", StringComparison.OrdinalIgnoreCase))
+ {
+ if (attributeValue.Equals("Yes", StringComparison.OrdinalIgnoreCase))
+ flags |= AssemblyNameFlags.Retargetable;
+ else if (attributeValue.Equals("No", StringComparison.OrdinalIgnoreCase))
+ {
+ // nothing to do
+ }
+ else
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ }
+
+ if (attributeName.Equals("ContentType", StringComparison.OrdinalIgnoreCase))
+ {
+ if (attributeValue.Equals("WindowsRuntime", StringComparison.OrdinalIgnoreCase))
+ flags |= (AssemblyNameFlags)(((int)AssemblyContentType.WindowsRuntime) << 9);
+ else
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ }
+
+ // Desktop compat: If we got here, the attribute name is unknown to us. Ignore it (as long it's not duplicated.)
+ token = lexer.GetNext();
+ }
+ return new RuntimeAssemblyName(name, version, cultureName, flags, pkt);
+ }
+
+ private static Version ParseVersion(string attributeValue)
+ {
+ string[] parts = attributeValue.Split('.');
+ if (parts.Length > 4)
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ ushort[] versionNumbers = new ushort[4];
+ for (int i = 0; i < versionNumbers.Length; i++)
+ {
+ if (i >= parts.Length)
+ versionNumbers[i] = ushort.MaxValue;
+ else
+ {
+ // Desktop compat: TryParse is a little more forgiving than Fusion.
+ for (int j = 0; j < parts[i].Length; j++)
+ {
+ if (!char.IsDigit(parts[i][j]))
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ }
+ if (!(ushort.TryParse(parts[i], out versionNumbers[i])))
+ {
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ }
+ }
+ }
+
+ if (versionNumbers[0] == ushort.MaxValue || versionNumbers[1] == ushort.MaxValue)
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ if (versionNumbers[2] == ushort.MaxValue)
+ return new Version(versionNumbers[0], versionNumbers[1]);
+ if (versionNumbers[3] == ushort.MaxValue)
+ return new Version(versionNumbers[0], versionNumbers[1], versionNumbers[2]);
+ return new Version(versionNumbers[0], versionNumbers[1], versionNumbers[2], versionNumbers[3]);
+ }
+
+ private static string ParseCulture(string attributeValue)
+ {
+ if (attributeValue.Equals("Neutral", StringComparison.OrdinalIgnoreCase))
+ {
+ return "";
+ }
+ else
+ {
+ CultureInfo culture = CultureInfo.GetCultureInfo(attributeValue); // Force a CultureNotFoundException if not a valid culture.
+ return culture.Name;
+ }
+ }
+
+ private static byte[] ParsePKT(string attributeValue)
+ {
+ if (attributeValue.Equals("null", StringComparison.OrdinalIgnoreCase) || attributeValue == string.Empty)
+ return Array.Empty();
+
+ if (attributeValue.Length != 8 * 2)
+ throw new FileLoadException(SR.InvalidAssemblyName);
+
+ byte[] pkt = new byte[8];
+ int srcIndex = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ char hi = attributeValue[srcIndex++];
+ char lo = attributeValue[srcIndex++];
+ pkt[i] = (byte)((ParseHexNybble(hi) << 4) | ParseHexNybble(lo));
+ }
+ return pkt;
+ }
+
+ private static ProcessorArchitecture ParseProcessorArchitecture(string attributeValue)
+ {
+ if (attributeValue.Equals("msil", StringComparison.OrdinalIgnoreCase))
+ return ProcessorArchitecture.MSIL;
+ if (attributeValue.Equals("x86", StringComparison.OrdinalIgnoreCase))
+ return ProcessorArchitecture.X86;
+ if (attributeValue.Equals("ia64", StringComparison.OrdinalIgnoreCase))
+ return ProcessorArchitecture.IA64;
+ if (attributeValue.Equals("amd64", StringComparison.OrdinalIgnoreCase))
+ return ProcessorArchitecture.Amd64;
+ if (attributeValue.Equals("arm", StringComparison.OrdinalIgnoreCase))
+ return ProcessorArchitecture.Arm;
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ }
+
+ private static byte ParseHexNybble(char c)
+ {
+ if (c >= '0' && c <= '9')
+ return (byte)(c - '0');
+ if (c >= 'a' && c <= 'f')
+ return (byte)(c - 'a' + 10);
+ if (c >= 'A' && c <= 'F')
+ return (byte)(c - 'A' + 10);
+ throw new FileLoadException(SR.InvalidAssemblyName);
+ }
+
+ private static readonly char[] s_illegalCharactersInSimpleName = { '/', '\\', ':' };
+ }
+}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyRuntimeNameHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyRuntimeNameHelpers.cs
deleted file mode 100644
index fc4ed2816e580..0000000000000
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/AssemblyRuntimeNameHelpers.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Globalization;
-using System.IO;
-using System.Text;
-using System.Collections.Generic;
-
-namespace System.Reflection
-{
- [System.Runtime.CompilerServices.ReflectionBlocked]
- public static class AssemblyRuntimeNameHelpers
- {
- //
- // Converts an AssemblyName to a RuntimeAssemblyName that is free from any future mutations on the AssemblyName.
- //
- public static RuntimeAssemblyName ToRuntimeAssemblyName(this AssemblyName assemblyName)
- {
- if (assemblyName.Name == null)
- throw new ArgumentException(SR.InvalidAssemblyName);
-
- AssemblyNameFlags flags = assemblyName.Flags;
- AssemblyContentType contentType = assemblyName.ContentType;
-#pragma warning disable SYSLIB0037 // AssemblyName.ProcessorArchitecture is obsolete
- ProcessorArchitecture processorArchitecture = assemblyName.ProcessorArchitecture;
-#pragma warning restore SYSLIB0037
- AssemblyNameFlags combinedFlags = CombineAssemblyNameFlags(flags, contentType, processorArchitecture);
- byte[]? pkOriginal;
- if (0 != (flags & AssemblyNameFlags.PublicKey))
- pkOriginal = assemblyName.GetPublicKey();
- else
- pkOriginal = assemblyName.GetPublicKeyToken();
-
- // AssemblyName's PKT property getters do NOT copy the array before giving it out. Make our own copy
- // as the original is wide open to tampering by anyone.
- byte[]? pkCopy = null;
- if (pkOriginal != null)
- {
- pkCopy = new byte[pkOriginal.Length];
- Array.Copy(pkOriginal, pkCopy, pkOriginal.Length);
- }
-
- return new RuntimeAssemblyName(assemblyName.Name, assemblyName.Version, assemblyName.CultureName, combinedFlags, pkCopy);
- }
-
- internal static AssemblyNameFlags CombineAssemblyNameFlags(AssemblyNameFlags flags, AssemblyContentType contentType, ProcessorArchitecture processorArchitecture)
- {
- return (AssemblyNameFlags)(((int)flags) | (((int)contentType) << 9) | ((int)processorArchitecture << 4));
- }
- }
-}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssemblyName.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssemblyName.cs
index f4dbc0d667140..90c0fe5ff824a 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssemblyName.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/RuntimeAssemblyName.cs
@@ -16,7 +16,7 @@ namespace System.Reflection
//
public sealed class RuntimeAssemblyName : IEquatable
{
- public RuntimeAssemblyName(string name, Version? version, string? cultureName, AssemblyNameFlags flags, byte[]? publicKeyOrToken)
+ public RuntimeAssemblyName(string name, Version version, string cultureName, AssemblyNameFlags flags, byte[] publicKeyOrToken)
{
Debug.Assert(name != null);
this.Name = name;
@@ -34,26 +34,20 @@ public RuntimeAssemblyName(string name, Version? version, string? cultureName, A
this.PublicKeyOrToken = publicKeyOrToken;
}
- public static RuntimeAssemblyName Parse(string name)
- {
- AssemblyNameParser.AssemblyNameParts parts = AssemblyNameParser.Parse(name);
- return new RuntimeAssemblyName(parts._name, parts._version, parts._cultureName, parts._flags, parts._publicKeyOrToken);
- }
-
// Simple name.
public string Name { get; }
// Optional version.
- public Version? Version { get; }
+ public Version Version { get; }
// Optional culture name.
- public string? CultureName { get; }
+ public string CultureName { get; }
// Optional flags (this is actually an OR of the classic flags and the ContentType.)
public AssemblyNameFlags Flags { get; }
// Optional public key (if Flags.PublicKey == true) or public key token.
- public byte[]? PublicKeyOrToken { get; }
+ public byte[] PublicKeyOrToken { get; }
// Equality - this compares every bit of data in the RuntimeAssemblyName which is acceptable for use as keys in a cache
// where semantic duplication is permissible. This method is *not* meant to define ref->def binding rules or
@@ -79,8 +73,8 @@ public bool Equals(RuntimeAssemblyName? other)
if (this.Flags != other.Flags)
return false;
- byte[]? thisPK = this.PublicKeyOrToken;
- byte[]? otherPK = other.PublicKeyOrToken;
+ byte[] thisPK = this.PublicKeyOrToken;
+ byte[] otherPK = other.PublicKeyOrToken;
if (thisPK == null)
{
if (otherPK != null)
@@ -145,7 +139,7 @@ public void CopyToAssemblyName(AssemblyName blank)
blank.Flags = this.Flags.ExtractAssemblyNameFlags();
blank.ContentType = this.Flags.ExtractAssemblyContentType();
#pragma warning disable SYSLIB0037 // AssemblyName.ProcessorArchitecture is obsolete
- blank.ProcessorArchitecture = ExtractProcessorArchitecture(this.Flags);
+ blank.ProcessorArchitecture = this.Flags.ExtractProcessorArchitecture();
#pragma warning restore SYSLIB0037
if (this.PublicKeyOrToken != null)
@@ -168,14 +162,9 @@ public string FullName
{
get
{
- byte[]? pkt = (0 != (Flags & AssemblyNameFlags.PublicKey)) ? AssemblyNameHelpers.ComputePublicKeyToken(PublicKeyOrToken) : PublicKeyOrToken;
+ byte[] pkt = (0 != (Flags & AssemblyNameFlags.PublicKey)) ? AssemblyNameHelpers.ComputePublicKeyToken(PublicKeyOrToken) : PublicKeyOrToken;
return AssemblyNameFormatter.ComputeDisplayName(Name, Version, CultureName, pkt, Flags.ExtractAssemblyNameFlags(), Flags.ExtractAssemblyContentType());
}
}
-
- internal static ProcessorArchitecture ExtractProcessorArchitecture(AssemblyNameFlags flags)
- {
- return (ProcessorArchitecture)((((int)flags) >> 4) & 0x7);
- }
}
}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
index a7edbf10d819a..304f7073e7ec3 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
@@ -679,6 +679,18 @@ internal struct ConservativelyReportedRegionDesc
[RuntimeImport(RuntimeLibrary, "RhpMemoryBarrier")]
internal static extern void MemoryBarrier();
+ [Intrinsic]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [RuntimeImport(RuntimeLibrary, "fabs")]
+ internal static extern double fabs(double x);
+
+ [Intrinsic]
+ internal static float fabsf(float x)
+ {
+ // fabsf is not a real export for some architectures
+ return (float)fabs(x);
+ }
+
[Intrinsic]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "acos")]
diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs
index 2227d4a59682b..53edc6a6ec5e4 100644
--- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs
+++ b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs
@@ -89,7 +89,7 @@ private static CoreTypeResolver CreateCoreTypeResolver(Func
-
namespace System.Reflection.Runtime.General
{
internal static partial class TypeUnifier
diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs
index fdbcf0b53685d..209a91e0cb102 100644
--- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs
+++ b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs
@@ -10,8 +10,6 @@
using Internal.Reflection.Tracing;
-#pragma warning disable CA1067 // override Equals because it implements IEquatable
-
namespace System.Reflection.Runtime.TypeInfos
{
//
diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeLexer.cs b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeLexer.cs
index 2dc289a7c2fa4..dfebfcacea21d 100644
--- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeLexer.cs
+++ b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeLexer.cs
@@ -139,7 +139,7 @@ public RuntimeAssemblyName GetNextAssemblyName()
}
_index = src;
string fullName = new string(buffer, 0, dst);
- return RuntimeAssemblyName.Parse(fullName);
+ return AssemblyNameParser.Parse(fullName);
}
//
@@ -173,7 +173,7 @@ public RuntimeAssemblyName GetNextEmbeddedAssemblyName()
}
_index = src;
string fullName = new string(buffer, 0, dst);
- return RuntimeAssemblyName.Parse(fullName);
+ return AssemblyNameParser.Parse(fullName);
}
//
diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h
index db22c68fde053..237b75275cec9 100644
--- a/src/coreclr/pal/inc/pal.h
+++ b/src/coreclr/pal/inc/pal.h
@@ -345,7 +345,6 @@ typedef __int64 time_t;
#define PAL_INITIALIZE_DEBUGGER_EXCEPTIONS 0x10
#define PAL_INITIALIZE_ENSURE_STACK_SIZE 0x20
#define PAL_INITIALIZE_REGISTER_SIGNALS 0x40
-#define PAL_INITIALIZE_REGISTER_ACTIVATION_SIGNAL 0x80
// PAL_Initialize() flags
#define PAL_INITIALIZE (PAL_INITIALIZE_SYNC_THREAD | \
@@ -360,8 +359,7 @@ typedef __int64 time_t;
PAL_INITIALIZE_REGISTER_SIGTERM_HANDLER | \
PAL_INITIALIZE_DEBUGGER_EXCEPTIONS | \
PAL_INITIALIZE_ENSURE_STACK_SIZE | \
- PAL_INITIALIZE_REGISTER_SIGNALS | \
- PAL_INITIALIZE_REGISTER_ACTIVATION_SIGNAL)
+ PAL_INITIALIZE_REGISTER_SIGNALS)
typedef DWORD (PALAPI_NOEXPORT *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
@@ -2844,6 +2842,24 @@ VirtualQuery(
#define FillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
#define ZeroMemory(Destination,Length) memset((Destination),0,(Length))
+#define LMEM_FIXED 0x0000
+#define LMEM_MOVEABLE 0x0002
+#define LMEM_ZEROINIT 0x0040
+#define LPTR (LMEM_FIXED | LMEM_ZEROINIT)
+
+PALIMPORT
+HLOCAL
+PALAPI
+LocalAlloc(
+ IN UINT uFlags,
+ IN SIZE_T uBytes);
+
+PALIMPORT
+HLOCAL
+PALAPI
+LocalFree(
+ IN HLOCAL hMem);
+
PALIMPORT
BOOL
PALAPI
@@ -3245,8 +3261,8 @@ FORCEINLINE void PAL_ArmInterlockedOperationBarrier()
Function:
InterlockedAdd
-The InterlockedAdd function adds the value of the specified variable
-with another specified value. The function prevents more than one thread
+The InterlockedAdd function adds the value of the specified variable
+with another specified value. The function prevents more than one thread
from using the same variable simultaneously.
Parameters
@@ -3918,6 +3934,8 @@ PAL_GetCurrentThreadAffinitySet(SIZE_T size, UINT_PTR* data);
#define wcspbrk PAL_wcspbrk
#define wcscmp PAL_wcscmp
#define wcsncpy PAL_wcsncpy
+#define wcstok PAL_wcstok
+#define wcscspn PAL_wcscspn
#define realloc PAL_realloc
#define fopen PAL_fopen
#define strtok PAL_strtok
@@ -4107,6 +4125,8 @@ PALIMPORT DLLEXPORT const WCHAR * __cdecl PAL_wcschr(const WCHAR *, WCHAR);
PALIMPORT DLLEXPORT const WCHAR * __cdecl PAL_wcsrchr(const WCHAR *, WCHAR);
PALIMPORT WCHAR _WConst_return * __cdecl PAL_wcspbrk(const WCHAR *, const WCHAR *);
PALIMPORT DLLEXPORT WCHAR _WConst_return * __cdecl PAL_wcsstr(const WCHAR *, const WCHAR *);
+PALIMPORT WCHAR * __cdecl PAL_wcstok(WCHAR *, const WCHAR *);
+PALIMPORT DLLEXPORT size_t __cdecl PAL_wcscspn(const WCHAR *, const WCHAR *);
PALIMPORT int __cdecl PAL_swprintf(WCHAR *, const WCHAR *, ...);
PALIMPORT int __cdecl PAL_vswprintf(WCHAR *, const WCHAR *, va_list);
PALIMPORT int __cdecl PAL_swscanf(const WCHAR *, const WCHAR *, ...);
diff --git a/src/coreclr/pal/inc/palprivate.h b/src/coreclr/pal/inc/palprivate.h
index f90352b32355e..097229eb64ef4 100644
--- a/src/coreclr/pal/inc/palprivate.h
+++ b/src/coreclr/pal/inc/palprivate.h
@@ -203,6 +203,8 @@ CompareFileTime(
IN CONST FILETIME *lpFileTime1,
IN CONST FILETIME *lpFileTime2);
+PALIMPORT char * __cdecl _fullpath(char *, const char *, size_t);
+
/* These are from the file in windows.
They are needed for _open_osfhandle.*/
#define _O_RDONLY 0x0000
diff --git a/src/coreclr/pal/inc/rt/sal.h b/src/coreclr/pal/inc/rt/sal.h
index ef976be402fdc..198b46d4a4e06 100644
--- a/src/coreclr/pal/inc/rt/sal.h
+++ b/src/coreclr/pal/inc/rt/sal.h
@@ -2862,10 +2862,6 @@ of each annotation, see the advanced annotations section.
#define __useHeader _Use_decl_anno_impl_
#define __on_failure(annotes) _On_failure_impl_(annotes _SAL_nop_impl_)
-#ifndef __has_cpp_attribute
-#define __has_cpp_attribute(x) (0)
-#endif
-
#ifndef __fallthrough // [
#if __has_cpp_attribute(fallthrough)
#define __fallthrough [[fallthrough]]
diff --git a/src/coreclr/pal/inc/unixasmmacros.inc b/src/coreclr/pal/inc/unixasmmacros.inc
index a1bad6300f3cf..1fe285eef162d 100644
--- a/src/coreclr/pal/inc/unixasmmacros.inc
+++ b/src/coreclr/pal/inc/unixasmmacros.inc
@@ -39,8 +39,6 @@
#include "unixasmmacrosamd64.inc"
#elif defined(HOST_ARM)
#include "unixasmmacrosarm.inc"
-#elif defined(HOST_ARMV6)
-#include "unixasmmacrosarm.inc"
#elif defined(HOST_ARM64)
#include "unixasmmacrosarm64.inc"
#elif defined(HOST_S390X)
diff --git a/src/coreclr/pal/inc/unixasmmacrosarm.inc b/src/coreclr/pal/inc/unixasmmacrosarm.inc
index d323ccc49fbd2..e0c0016cc26ab 100644
--- a/src/coreclr/pal/inc/unixasmmacrosarm.inc
+++ b/src/coreclr/pal/inc/unixasmmacrosarm.inc
@@ -197,11 +197,7 @@ C_FUNC(\Name\()_End):
.endm
.macro EMIT_BREAKPOINT
-#ifdef __armv6__
- .inst 0xe7f001f0
-#else
.inst.w 0xde01
-#endif
.endm
.macro PROLOG_PUSH RegList
diff --git a/src/coreclr/pal/src/CMakeLists.txt b/src/coreclr/pal/src/CMakeLists.txt
index 29765f81ea77a..4f071b21046b0 100644
--- a/src/coreclr/pal/src/CMakeLists.txt
+++ b/src/coreclr/pal/src/CMakeLists.txt
@@ -45,9 +45,6 @@ if(CLR_CMAKE_HOST_ARCH_AMD64)
set(PAL_ARCH_SOURCES_DIR amd64)
elseif(CLR_CMAKE_HOST_ARCH_ARM)
set(PAL_ARCH_SOURCES_DIR arm)
-elseif(CLR_CMAKE_HOST_ARCH_ARMV6)
- set(PAL_ARCH_SOURCES_DIR arm)
- add_definitions(-D__armv6__)
elseif(CLR_CMAKE_HOST_ARCH_ARM64)
set(PAL_ARCH_SOURCES_DIR arm64)
elseif(CLR_CMAKE_HOST_ARCH_I386)
@@ -126,6 +123,7 @@ set(SOURCES
cruntime/malloc.cpp
cruntime/math.cpp
cruntime/misc.cpp
+ cruntime/path.cpp
cruntime/printf.cpp
cruntime/printfcpp.cpp
cruntime/silent_printf.cpp
@@ -133,6 +131,7 @@ set(SOURCES
cruntime/stringtls.cpp
cruntime/thread.cpp
cruntime/wchar.cpp
+ cruntime/wchartls.cpp
debug/debug.cpp
exception/seh.cpp
exception/signal.cpp
@@ -146,12 +145,14 @@ set(SOURCES
init/pal.cpp
init/sxs.cpp
loader/module.cpp
+ loader/modulename.cpp
locale/unicode.cpp
locale/unicodedata.cpp
locale/utf8.cpp
map/common.cpp
map/map.cpp
map/virtual.cpp
+ memory/local.cpp
misc/cgroup.cpp
misc/dbgmsg.cpp
misc/environ.cpp
diff --git a/src/coreclr/pal/src/arch/arm/callsignalhandlerwrapper.S b/src/coreclr/pal/src/arch/arm/callsignalhandlerwrapper.S
index a7c92e93188e4..4179f61e16276 100644
--- a/src/coreclr/pal/src/arch/arm/callsignalhandlerwrapper.S
+++ b/src/coreclr/pal/src/arch/arm/callsignalhandlerwrapper.S
@@ -5,9 +5,7 @@
#include "asmconstants.h"
.syntax unified
-#ifndef __armv6__
.thumb
-#endif
.macro CALL_SIGNAL_HANDLER_WRAPPER Alignment
diff --git a/src/coreclr/pal/src/arch/arm/context2.S b/src/coreclr/pal/src/arch/arm/context2.S
index edb5d35bf1e40..1cd7684a953e8 100644
--- a/src/coreclr/pal/src/arch/arm/context2.S
+++ b/src/coreclr/pal/src/arch/arm/context2.S
@@ -10,9 +10,7 @@
#include "asmconstants.h"
.syntax unified
-#ifndef __armv6__
.thumb
-#endif
#define CONTEXT_ARM 0x00200000
diff --git a/src/coreclr/pal/src/arch/arm/debugbreak.S b/src/coreclr/pal/src/arch/arm/debugbreak.S
index 88301b98548c3..dd8a9348352dc 100644
--- a/src/coreclr/pal/src/arch/arm/debugbreak.S
+++ b/src/coreclr/pal/src/arch/arm/debugbreak.S
@@ -4,9 +4,7 @@
#include "unixasmmacros.inc"
.syntax unified
-#ifndef __armv6__
.thumb
-#endif
LEAF_ENTRY DBG_DebugBreak, _TEXT
EMIT_BREAKPOINT
diff --git a/src/coreclr/pal/src/arch/arm/exceptionhelper.S b/src/coreclr/pal/src/arch/arm/exceptionhelper.S
index a43ed14be7d98..f733aad613379 100644
--- a/src/coreclr/pal/src/arch/arm/exceptionhelper.S
+++ b/src/coreclr/pal/src/arch/arm/exceptionhelper.S
@@ -5,9 +5,7 @@
#include "asmconstants.h"
.syntax unified
-#ifndef __armv6__
.thumb
-#endif
// EXTERN_C void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex);
LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT
diff --git a/src/coreclr/pal/src/cruntime/path.cpp b/src/coreclr/pal/src/cruntime/path.cpp
new file mode 100644
index 0000000000000..c25636771bc61
--- /dev/null
+++ b/src/coreclr/pal/src/cruntime/path.cpp
@@ -0,0 +1,113 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*++
+
+
+
+Module Name:
+
+ path.c
+
+Abstract:
+
+ Implementation of path functions part of Windows runtime library.
+
+Revision History:
+
+
+
+--*/
+
+#include "pal/palinternal.h"
+#include "pal/dbgmsg.h"
+#include "pal/file.h"
+#include "pal/printfcpp.hpp"
+
+#include
+#include
+#include
+#include
+#include
+
+SET_DEFAULT_DEBUG_CHANNEL(CRT);
+
+/*++
+Function:
+ _fullpath
+
+See MSDN doc.
+
+--*/
+char *
+__cdecl
+_fullpath(
+ char *absPath,
+ const char *relPath,
+ size_t maxLength)
+{
+ char realpath_buf[PATH_MAX+1];
+ char path_copy[PATH_MAX+1];
+ char *retval = NULL;
+ DWORD cPathCopy = sizeof(path_copy)/sizeof(path_copy[0]);
+ size_t min_length;
+ BOOL fBufAllocated = FALSE;
+
+ PERF_ENTRY(_fullpath);
+ ENTRY("_fullpath (absPath=%p, relPath=%p (%s), maxLength = %lu)\n",
+ absPath, relPath ? relPath:"NULL", relPath ? relPath:"NULL", maxLength);
+
+ if (strncpy_s(path_copy, sizeof(path_copy), relPath ? relPath : ".", cPathCopy) != SAFECRT_SUCCESS)
+ {
+ TRACE("_fullpath: strncpy_s failed!\n");
+ goto fullpathExit;
+ }
+
+ FILEDosToUnixPathA(path_copy);
+
+ if(NULL == realpath(path_copy, realpath_buf))
+ {
+ ERROR("realpath() failed; problem path is '%s'. errno is %d (%s)\n",
+ realpath_buf, errno, strerror(errno));
+ goto fullpathExit;
+ }
+
+ TRACE("real path is %s\n", realpath_buf);
+ min_length = strlen(realpath_buf)+1; // +1 for the NULL terminator
+
+ if(NULL == absPath)
+ {
+ absPath = static_cast(
+ PAL_malloc(_MAX_PATH * sizeof(char)));
+ if (!absPath)
+ {
+ ERROR("PAL_malloc failed with error %d\n", errno);
+ goto fullpathExit;
+ }
+ maxLength = _MAX_PATH;
+ fBufAllocated = TRUE;
+ }
+
+ if(min_length > maxLength)
+ {
+ ERROR("maxLength is %lu, we need at least %lu\n",
+ maxLength, min_length);
+ if (fBufAllocated)
+ {
+ PAL_free(absPath);
+ fBufAllocated = FALSE;
+ }
+ goto fullpathExit;
+ }
+
+ strcpy_s(absPath, maxLength, realpath_buf);
+ retval = absPath;
+
+fullpathExit:
+ LOGEXIT("_fullpath returns char * %p\n", retval);
+ PERF_EXIT(_fullpath);
+ return retval;
+}
+
+
+
diff --git a/src/coreclr/pal/src/cruntime/printfcpp.cpp b/src/coreclr/pal/src/cruntime/printfcpp.cpp
index fee79c91df12b..d7e992c090a00 100644
--- a/src/coreclr/pal/src/cruntime/printfcpp.cpp
+++ b/src/coreclr/pal/src/cruntime/printfcpp.cpp
@@ -86,7 +86,7 @@ static int Internal_Convertfwrite(CPalThread *pthrCurrent, const void *buffer, s
free(newBuff);
return -1;
}
- ret = InternalFwrite(newBuff, 1, nsize, stream, &iError);
+ ret = InternalFwrite(newBuff, 1, count, stream, &iError);
if (iError != 0)
{
ERROR("InternalFwrite did not write the whole buffer. Error is %d\n", iError);
diff --git a/src/coreclr/pal/src/cruntime/wchar.cpp b/src/coreclr/pal/src/cruntime/wchar.cpp
index 3d887aecdb883..5c21d7bd01533 100644
--- a/src/coreclr/pal/src/cruntime/wchar.cpp
+++ b/src/coreclr/pal/src/cruntime/wchar.cpp
@@ -3,6 +3,8 @@
/*++
+
+
Module Name:
wchar.c
@@ -11,8 +13,11 @@ Module Name:
Implementation of wide char string functions.
+
+
--*/
+
#include "pal/palinternal.h"
#include "pal/cruntime.h"
#include "pal/dbgmsg.h"
@@ -20,6 +25,7 @@ Module Name:
#include "pal/thread.hpp"
#include "pal/threadsusp.hpp"
+
#if HAVE_CONFIG_H
#include "config.h"
#endif
@@ -944,3 +950,46 @@ PAL_wcstod( const wchar_16 * nptr, wchar_16 **endptr )
PERF_EXIT(wcstod);
return RetVal;
}
+
+/*++
+Function:
+ PAL_wcscspn
+
+Finds the number of consecutive characters from the start of the string
+that are not in the set.
+
+Return value:
+
+The number of characters from the start of the string that are not in
+the set.
+
+Parameters:
+string String
+strCharSet Set of delimiter characters
+
+--*/
+size_t
+__cdecl
+PAL_wcscspn(const wchar_16 *string, const wchar_16 *strCharSet)
+{
+ const wchar_16 *temp;
+ size_t count = 0;
+
+ PERF_ENTRY(wcscspn);
+
+ while(*string != 0)
+ {
+ for(temp = strCharSet; *temp != 0; temp++)
+ {
+ if (*string == *temp)
+ {
+ PERF_EXIT(wcscspn);
+ return count;
+ }
+ }
+ count++;
+ string++;
+ }
+ PERF_EXIT(wcscspn);
+ return count;
+}
diff --git a/src/coreclr/pal/src/cruntime/wchartls.cpp b/src/coreclr/pal/src/cruntime/wchartls.cpp
new file mode 100644
index 0000000000000..35b73359889a5
--- /dev/null
+++ b/src/coreclr/pal/src/cruntime/wchartls.cpp
@@ -0,0 +1,125 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*++
+
+
+
+Module Name:
+
+ wchartls.c
+
+Abstract:
+
+ Implementation of wide char string functions that depend on per-thread data
+
+
+
+--*/
+
+#include "pal/palinternal.h"
+#include "pal/thread.hpp"
+#include "pal/dbgmsg.h"
+
+using namespace CorUnix;
+
+
+SET_DEFAULT_DEBUG_CHANNEL(CRT);
+
+/*++
+Function:
+ PAL_wcstok
+
+Finds the next token in a wide character string.
+
+Return value:
+
+A pointer to the next token found in strToken. Returns NULL when no more
+tokens are found. Each call modifies strToken by substituting a NULL
+character for each delimiter that is encountered.
+
+Parameters:
+strToken String containing token(s)
+strDelimit Set of delimiter characters
+
+--*/
+WCHAR *
+__cdecl
+PAL_wcstok(WCHAR *strToken, const WCHAR *strDelimit)
+{
+ CPalThread *pThread = NULL;
+ WCHAR *retval = NULL;
+ WCHAR *delim_ptr;
+ WCHAR *next_context; /* string to save in TLS for future calls */
+
+ PERF_ENTRY(wcstok);
+ ENTRY("PAL_wcstok (strToken=%p (%S), strDelimit=%p (%S))\n",
+ strToken?strToken:W16_NULLSTRING,
+ strToken?strToken:W16_NULLSTRING,
+ strDelimit?strDelimit:W16_NULLSTRING,
+ strDelimit?strDelimit:W16_NULLSTRING);
+
+ /* Get the per-thread buffer from the thread structure. */
+ pThread = InternalGetCurrentThread();
+
+ if(NULL == strDelimit)
+ {
+ ERROR("delimiter string is NULL\n");
+ goto done;
+ }
+
+ /* get token string from TLS if none is provided */
+ if(NULL == strToken)
+ {
+ TRACE("wcstok() called with NULL string, using previous string\n");
+ strToken = pThread->crtInfo.wcstokContext;
+ if(NULL == strToken)
+ {
+ ERROR("wcstok called with NULL string without a previous call\n");
+ goto done;
+ }
+ }
+
+ /* first, skip all leading delimiters */
+ while ((*strToken != '\0') && (PAL_wcschr(strDelimit,*strToken)))
+ {
+ strToken++;
+ }
+
+ /* if there were only delimiters, there's no string */
+ if('\0' == strToken[0])
+ {
+ TRACE("end of string already reached, returning NULL\n");
+ goto done;
+ }
+
+ /* we're now at the beginning of the token; look for the first delimiter */
+ delim_ptr = PAL_wcspbrk(strToken,strDelimit);
+ if(NULL == delim_ptr)
+ {
+ TRACE("no delimiters found, this is the last token\n");
+ /* place the next context at the end of the string, so that subsequent
+ calls will return NULL */
+ next_context = strToken+PAL_wcslen(strToken);
+ retval = strToken;
+ }
+ else
+ {
+ /* null-terminate current token */
+ *delim_ptr=0;
+
+ /* place the next context right after the delimiter */
+ next_context = delim_ptr+1;
+ retval = strToken;
+
+ TRACE("found delimiter; next token will be %p\n",next_context);
+ }
+
+ pThread->crtInfo.wcstokContext = next_context;
+
+done:
+ LOGEXIT("PAL_wcstok() returns %p (%S)\n", retval?retval:W16_NULLSTRING, retval?retval:W16_NULLSTRING);
+ PERF_EXIT(wcstok);
+ return(retval);
+}
+
diff --git a/src/coreclr/pal/src/exception/machexception.cpp b/src/coreclr/pal/src/exception/machexception.cpp
index eca89e0a204c6..e5aebdf652c6a 100644
--- a/src/coreclr/pal/src/exception/machexception.cpp
+++ b/src/coreclr/pal/src/exception/machexception.cpp
@@ -369,13 +369,19 @@ void PAL_DispatchException(PCONTEXT pContext, PEXCEPTION_RECORD pExRecord, MachE
{
CPalThread *pThread = InternalGetCurrentThread();
- CONTEXT *contextRecord = pContext;
- g_hardware_exception_context_locvar_offset = (int)((char*)&contextRecord - (char*)__builtin_frame_address(0));
+ CONTEXT *contextRecord;
+ EXCEPTION_RECORD *exceptionRecord;
+ AllocateExceptionRecords(&exceptionRecord, &contextRecord);
- pContext->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
+ *contextRecord = *pContext;
+ *exceptionRecord = *pExRecord;
+
+ contextRecord->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
bool continueExecution;
+
{
- PAL_SEHException exception(pExRecord, pContext, true);
+ // The exception object takes ownership of the exceptionRecord and contextRecord
+ PAL_SEHException exception(exceptionRecord, contextRecord);
TRACE("PAL_DispatchException(EC %08x EA %p)\n", pExRecord->ExceptionCode, pExRecord->ExceptionAddress);
@@ -383,8 +389,8 @@ void PAL_DispatchException(PCONTEXT pContext, PEXCEPTION_RECORD pExRecord, MachE
if (continueExecution)
{
// Make a copy of the exception records so that we can free them before restoring the context
- *pContext = *exception.ExceptionPointers.ContextRecord;
- *pExRecord = *exception.ExceptionPointers.ExceptionRecord;
+ *pContext = *contextRecord;
+ *pExRecord = *exceptionRecord;
}
// The exception records are destroyed by the PAL_SEHException destructor now.
diff --git a/src/coreclr/pal/src/exception/seh-unwind.cpp b/src/coreclr/pal/src/exception/seh-unwind.cpp
index 3091650ec5faa..4b149f941b5dc 100644
--- a/src/coreclr/pal/src/exception/seh-unwind.cpp
+++ b/src/coreclr/pal/src/exception/seh-unwind.cpp
@@ -496,9 +496,7 @@ void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext, KNONVOL
#ifndef HOST_WINDOWS
-// Frame pointer relative offset of a local containing a pointer to the windows style context of a location
-// where a hardware exception occured.
-int g_hardware_exception_context_locvar_offset = 0;
+extern int g_common_signal_handler_context_locvar_offset;
BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers)
{
@@ -508,17 +506,19 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP
DWORD64 curPc = CONTEXTGetPC(context);
- // Check if the PC is the return address from the SEHProcessException.
- // If that's the case, extract its local variable containing a pointer to the windows style context of the hardware
+#ifndef __APPLE__
+ // Check if the PC is the return address from the SEHProcessException in the common_signal_handler.
+ // If that's the case, extract its local variable containing the windows style context of the hardware
// exception and return that. This skips the hardware signal handler trampoline that the libunwind
- // cannot cross on some systems. On macOS, it skips a similar trampoline we create in HijackFaultingThread.
+ // cannot cross on some systems.
if ((void*)curPc == g_SEHProcessExceptionReturnAddress)
{
- CONTEXT* exceptionContext = *(CONTEXT**)(CONTEXTGetFP(context) + g_hardware_exception_context_locvar_offset);
- memcpy_s(context, sizeof(CONTEXT), exceptionContext, sizeof(CONTEXT));
+ CONTEXT* signalContext = (CONTEXT*)(CONTEXTGetFP(context) + g_common_signal_handler_context_locvar_offset);
+ memcpy_s(context, sizeof(CONTEXT), signalContext, sizeof(CONTEXT));
return TRUE;
}
+#endif
if ((context->ContextFlags & CONTEXT_EXCEPTION_ACTIVE) != 0)
{
@@ -699,7 +699,7 @@ PAL_FreeExceptionRecords(IN EXCEPTION_RECORD *exceptionRecord, IN CONTEXT *conte
Note:
The name of this function and the name of the ExceptionRecord
parameter is used in the sos lldb plugin code to read the exception
- record. See coreclr\tools\SOS\lldbplugin\services.cpp.
+ record. See coreclr\ToolBox\SOS\lldbplugin\services.cpp.
This function must not be inlined or optimized so the below PAL_VirtualUnwind
calls end up with RaiseException caller's context and so the above debugger
diff --git a/src/coreclr/pal/src/exception/signal.cpp b/src/coreclr/pal/src/exception/signal.cpp
index 63b7ef115f26d..521150530fa33 100644
--- a/src/coreclr/pal/src/exception/signal.cpp
+++ b/src/coreclr/pal/src/exception/signal.cpp
@@ -116,6 +116,10 @@ struct sigaction g_previous_sigabrt;
#if !HAVE_MACH_EXCEPTIONS
+// Offset of the local variable containing pointer to windows style context in the common_signal_handler function.
+// This offset is relative to the frame pointer.
+int g_common_signal_handler_context_locvar_offset = 0;
+
// TOP of special stack for handling stack overflow
volatile void* g_stackOverflowHandlerStack = NULL;
@@ -236,11 +240,8 @@ BOOL SEHInitializeSignals(CorUnix::CPalThread *pthrCurrent, DWORD flags)
}
#ifdef INJECT_ACTIVATION_SIGNAL
- if (flags & PAL_INITIALIZE_REGISTER_ACTIVATION_SIGNAL)
- {
- handle_signal(INJECT_ACTIVATION_SIGNAL, inject_activation_handler, &g_previous_activation);
- g_registered_activation_handler = true;
- }
+ handle_signal(INJECT_ACTIVATION_SIGNAL, inject_activation_handler, &g_previous_activation);
+ g_registered_activation_handler = true;
#endif
return TRUE;
@@ -938,12 +939,11 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
#if !HAVE_MACH_EXCEPTIONS
sigset_t signal_set;
CONTEXT signalContextRecord;
- CONTEXT* signalContextRecordPtr = &signalContextRecord;
EXCEPTION_RECORD exceptionRecord;
native_context_t *ucontext;
ucontext = (native_context_t *)sigcontext;
- g_hardware_exception_context_locvar_offset = (int)((char*)&signalContextRecordPtr - (char*)__builtin_frame_address(0));
+ g_common_signal_handler_context_locvar_offset = (int)((char*)&signalContextRecord - (char*)__builtin_frame_address(0));
if (code == (SIGSEGV | StackOverflowFlag))
{
diff --git a/src/coreclr/pal/src/include/pal/modulename.h b/src/coreclr/pal/src/include/pal/modulename.h
new file mode 100644
index 0000000000000..87d54b77a5b95
--- /dev/null
+++ b/src/coreclr/pal/src/include/pal/modulename.h
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*++
+
+
+
+Module Name:
+
+ include/pal/modulename.h
+
+Abstract:
+ Header file for functions to get the name of a module
+
+Revision History:
+
+
+
+--*/
+
+#ifndef _PAL_MODULENAME_H_
+#define _PAL_MODULENAME_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+const char *PAL_dladdr(LPVOID ProcAddress);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif /*_PAL_MODULENAME_H_*/
diff --git a/src/coreclr/pal/src/include/pal/palinternal.h b/src/coreclr/pal/src/include/pal/palinternal.h
index ff3703c6ae4f7..3a12d78910364 100644
--- a/src/coreclr/pal/src/include/pal/palinternal.h
+++ b/src/coreclr/pal/src/include/pal/palinternal.h
@@ -526,6 +526,8 @@ function_name() to call the system's implementation
#undef wcsstr
#undef wcscmp
#undef wcsncpy
+#undef wcstok
+#undef wcscspn
#undef iswupper
#undef iswspace
#undef towlower
diff --git a/src/coreclr/pal/src/include/pal/seh.hpp b/src/coreclr/pal/src/include/pal/seh.hpp
index 327fe0d7fb03e..6ad89df0fdd65 100644
--- a/src/coreclr/pal/src/include/pal/seh.hpp
+++ b/src/coreclr/pal/src/include/pal/seh.hpp
@@ -145,10 +145,5 @@ CorUnix::PAL_ERROR SEHDisable(CorUnix::CPalThread *pthrCurrent);
}
-// Offset of the local variable containing pointer to windows style context in the common_signal_handler / PAL_DispatchException function.
-// This offset is relative to the frame pointer.
-extern int g_hardware_exception_context_locvar_offset;
-
-
#endif /* _PAL_SEH_HPP_ */
diff --git a/src/coreclr/pal/src/init/pal.cpp b/src/coreclr/pal/src/init/pal.cpp
index 951680114d886..5469b4bebd483 100644
--- a/src/coreclr/pal/src/init/pal.cpp
+++ b/src/coreclr/pal/src/init/pal.cpp
@@ -1242,7 +1242,7 @@ static LPWSTR INIT_FormatCommandLine (int argc, const char * const *argv)
return NULL;
}
- if(!MultiByteToWideChar(CP_ACP, 0,command_line, -1, retval, i))
+ if(!MultiByteToWideChar(CP_ACP, 0,command_line, i, retval, i))
{
ASSERT("MultiByteToWideChar failure\n");
free(retval);
diff --git a/src/coreclr/pal/src/libunwind/CMakeLists.txt b/src/coreclr/pal/src/libunwind/CMakeLists.txt
index dfcd140a89a5b..17659432fd0e4 100644
--- a/src/coreclr/pal/src/libunwind/CMakeLists.txt
+++ b/src/coreclr/pal/src/libunwind/CMakeLists.txt
@@ -19,7 +19,6 @@ add_definitions(-D_GNU_SOURCE)
add_definitions(-DPACKAGE_STRING="")
add_definitions(-DPACKAGE_BUGREPORT="")
-
if(CLR_CMAKE_HOST_UNIX)
if (CLR_CMAKE_HOST_ARCH_AMD64)
set(arch x86_64)
@@ -27,8 +26,6 @@ if(CLR_CMAKE_HOST_UNIX)
set(arch aarch64)
elseif(CLR_CMAKE_HOST_ARCH_ARM)
set(arch arm)
- elseif(CLR_CMAKE_HOST_ARCH_ARMV6)
- set(arch arm)
elseif(CLR_CMAKE_HOST_ARCH_I386)
set(arch x86)
elseif(CLR_CMAKE_HOST_ARCH_S390X)
@@ -48,7 +45,7 @@ if(CLR_CMAKE_HOST_UNIX)
add_compile_options(-Wno-incompatible-pointer-types)
endif()
- if(CLR_CMAKE_HOST_ARCH_ARM OR CLR_CMAKE_HOST_ARCH_ARMV6)
+ if(CLR_CMAKE_HOST_ARCH_ARM)
# Ensure that the remote and local unwind code can reside in the same binary without name clashing
add_definitions("-Darm_search_unwind_table=UNW_OBJ(arm_search_unwind_table)")
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
@@ -112,10 +109,6 @@ if(CLR_CMAKE_HOST_WIN32)
set(TARGET_ARM 1)
set(arch arm)
add_definitions(-D__arm__)
- elseif(CLR_CMAKE_TARGET_ARCH_ARMV6)
- set(TARGET_ARM 1)
- set(arch arm)
- add_definitions(-D__arm__)
elseif(CLR_CMAKE_TARGET_ARCH_S390X)
set(TARGET_S390X 1)
set(arch s390x)
@@ -162,7 +155,7 @@ if(CLR_CMAKE_HOST_WIN32)
add_compile_options(-wd4477) # fprintf argument type
endif (CLR_CMAKE_HOST_WIN32)
-if(CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARMV6)
+if(CLR_CMAKE_TARGET_ARCH_ARM)
# The arm sources include ex_tables.h from include/tdep-arm without going through a redirection
# in include/tdep like it works for similar files on other architectures. So we need to add
# the include/tdep-arm to include directories
diff --git a/src/coreclr/pal/src/libunwind/src/CMakeLists.txt b/src/coreclr/pal/src/libunwind/src/CMakeLists.txt
index 17a30e027e03e..b6dee4f413a80 100644
--- a/src/coreclr/pal/src/libunwind/src/CMakeLists.txt
+++ b/src/coreclr/pal/src/libunwind/src/CMakeLists.txt
@@ -316,11 +316,6 @@ if(CLR_CMAKE_HOST_UNIX)
SET(libunwind_remote_la_SOURCES ${libunwind_arm_la_SOURCES_arm})
SET(libunwind_elf_la_SOURCES ${libunwind_elf32_la_SOURCES})
list(APPEND libunwind_setjmp_la_SOURCES arm/siglongjmp.S)
- elseif(CLR_CMAKE_HOST_ARCH_ARMV6)
- SET(libunwind_la_SOURCES ${libunwind_la_SOURCES_arm})
- SET(libunwind_remote_la_SOURCES ${libunwind_arm_la_SOURCES_arm})
- SET(libunwind_elf_la_SOURCES ${libunwind_elf32_la_SOURCES})
- list(APPEND libunwind_setjmp_la_SOURCES arm/siglongjmp.S)
elseif(CLR_CMAKE_HOST_ARCH_I386)
SET(libunwind_la_SOURCES ${libunwind_la_SOURCES_x86} ${libunwind_x86_la_SOURCES_os})
SET(libunwind_remote_la_SOURCES ${libunwind_x86_la_SOURCES_x86})
@@ -368,11 +363,6 @@ else(CLR_CMAKE_HOST_UNIX)
SET(libunwind_remote_la_SOURCES ${libunwind_arm_la_SOURCES_arm})
SET(libunwind_elf_la_SOURCES ${libunwind_elf32_la_SOURCES})
list(APPEND libunwind_setjmp_la_SOURCES arm/siglongjmp.S)
- elseif(CLR_CMAKE_TARGET_ARCH_ARMV6)
- SET(libunwind_la_SOURCES ${libunwind_la_SOURCES_arm})
- SET(libunwind_remote_la_SOURCES ${libunwind_arm_la_SOURCES_arm})
- SET(libunwind_elf_la_SOURCES ${libunwind_elf32_la_SOURCES})
- list(APPEND libunwind_setjmp_la_SOURCES arm/siglongjmp.S)
elseif(CLR_CMAKE_TARGET_ARCH_I386)
SET(libunwind_la_SOURCES ${libunwind_la_SOURCES_x86} ${libunwind_x86_la_SOURCES_os})
SET(libunwind_remote_la_SOURCES ${libunwind_x86_la_SOURCES_x86})
diff --git a/src/coreclr/pal/src/libunwind/src/oop/_OOP_find_proc_info.c b/src/coreclr/pal/src/libunwind/src/oop/_OOP_find_proc_info.c
index 07bd4a73b276c..74d42ffe2abb2 100644
--- a/src/coreclr/pal/src/libunwind/src/oop/_OOP_find_proc_info.c
+++ b/src/coreclr/pal/src/libunwind/src/oop/_OOP_find_proc_info.c
@@ -28,8 +28,6 @@ _OOP_find_proc_info (
int ret = 0;
unw_dyn_info_t di;
- memset(&di, 0, sizeof(di));
-
di.start_ip = start_ip;
di.end_ip = end_ip;
di.gp = pi->gp;
diff --git a/src/coreclr/pal/src/loader/module.cpp b/src/coreclr/pal/src/loader/module.cpp
index 2a559b56e2bef..e792f75a2b22e 100644
--- a/src/coreclr/pal/src/loader/module.cpp
+++ b/src/coreclr/pal/src/loader/module.cpp
@@ -30,6 +30,7 @@ SET_DEFAULT_DEBUG_CHANNEL(LOADER); // some headers have code with asserts, so do
#include "pal/file.h"
#include "pal/utils.h"
#include "pal/init.h"
+#include "pal/modulename.h"
#include "pal/environ.h"
#include "pal/virtual.h"
#include "pal/map.hpp"
@@ -341,10 +342,9 @@ GetProcAddress(
/* if we don't know the module's full name yet, this is our chance to obtain it */
if (!module->lib_name && module->dl_handle)
{
- Dl_info dl_info;
- if (dladdr((LPVOID)ProcAddress, &dl_info) != 0)
+ const char* libName = PAL_dladdr((LPVOID)ProcAddress);
+ if (libName)
{
- const char* libName = dl_info.dli_fname;
module->lib_name = UTIL_MBToWC_Alloc(libName, -1);
if (nullptr == module->lib_name)
{
@@ -356,10 +356,6 @@ GetProcAddress(
module, libName);
}
}
- else
- {
- TRACE("GetProcAddress: dladdr() call failed!\n");
- }
}
}
else
@@ -929,7 +925,7 @@ struct CopyModuleDataParam
int result;
};
-void handle_image_range(uint8_t* source_start, size_t size, struct CopyModuleDataParam* param)
+void handle_image_range(uint8_t* source_start, size_t size, struct CopyModuleDataParam* param)
{
uint8_t* source_end = source_start + size;
if (param->destination_buffer_start != NULL)
diff --git a/src/coreclr/pal/src/loader/modulename.cpp b/src/coreclr/pal/src/loader/modulename.cpp
new file mode 100644
index 0000000000000..40c1c6de5c3d6
--- /dev/null
+++ b/src/coreclr/pal/src/loader/modulename.cpp
@@ -0,0 +1,68 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*++
+
+
+
+Module Name:
+
+ modulename.cpp
+
+Abstract:
+
+ Implementation of internal functions to get module names
+
+
+
+--*/
+
+#include "pal/thread.hpp"
+#include "pal/malloc.hpp"
+#include "pal/palinternal.h"
+#include "pal/dbgmsg.h"
+#include "pal/modulename.h"
+
+#include
+
+using namespace CorUnix;
+
+SET_DEFAULT_DEBUG_CHANNEL(LOADER);
+
+/*++
+ PAL_dladdr
+
+ Internal wrapper for dladder used only to get module name
+
+Parameters:
+ LPVOID ProcAddress: a pointer to a function in a shared library
+
+Return value:
+ Pointer to string with the fullpath to the shared library containing
+ ProcAddress.
+
+ NULL if error occurred.
+
+Notes:
+ The string returned by this function is owned by the OS.
+ If you need to keep it, strdup() it, because it is unknown how long
+ this ptr will point at the string you want (over the lifetime of
+ the system running) It is only safe to use it immediately after calling
+ this function.
+--*/
+const char *PAL_dladdr(LPVOID ProcAddress)
+{
+ Dl_info dl_info;
+ if (!dladdr(ProcAddress, &dl_info))
+ {
+ WARN("dladdr() call failed!\n");
+ /* If we get an error, return NULL */
+ return (NULL);
+ }
+ else
+ {
+ /* Return the module name */
+ return dl_info.dli_fname;
+ }
+}
+
diff --git a/src/coreclr/pal/src/memory/local.cpp b/src/coreclr/pal/src/memory/local.cpp
new file mode 100644
index 0000000000000..fc62ef428b1e2
--- /dev/null
+++ b/src/coreclr/pal/src/memory/local.cpp
@@ -0,0 +1,93 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*++
+
+
+
+Module Name:
+
+ local.c
+
+Abstract:
+
+ Implementation of local memory management functions.
+
+Revision History:
+
+
+
+--*/
+
+#include "pal/palinternal.h"
+#include "pal/dbgmsg.h"
+
+
+SET_DEFAULT_DEBUG_CHANNEL(MEM);
+
+
+/*++
+Function:
+ LocalAlloc
+
+See MSDN doc.
+--*/
+HLOCAL
+PALAPI
+LocalAlloc(
+ IN UINT uFlags,
+ IN SIZE_T uBytes)
+{
+ LPVOID lpRetVal = NULL;
+ PERF_ENTRY(LocalAlloc);
+ ENTRY("LocalAlloc (uFlags=%#x, uBytes=%u)\n", uFlags, uBytes);
+
+ if ((uFlags & ~LMEM_ZEROINIT) != 0)
+ {
+ ASSERT("Invalid parameter AllocFlags=0x%x\n", uFlags);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ goto done;
+ }
+
+ lpRetVal = PAL_malloc(uBytes);
+
+ if (lpRetVal == NULL)
+ {
+ ERROR("Not enough memory\n");
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto done;
+ }
+
+ if ((uFlags & LMEM_ZEROINIT) != 0)
+ {
+ memset(lpRetVal, 0, uBytes);
+ }
+
+done:
+ LOGEXIT( "LocalAlloc returning %p.\n", lpRetVal );
+ PERF_EXIT(LocalAlloc);
+ return (HLOCAL) lpRetVal;
+}
+
+/*++
+Function:
+ LocalFree
+
+See MSDN doc.
+--*/
+HLOCAL
+PALAPI
+LocalFree(
+ IN HLOCAL hMem)
+{
+ BOOL bRetVal = FALSE;
+ PERF_ENTRY(LocalFree);
+ ENTRY("LocalFree (hmem=%p)\n", hMem);
+
+ free(hMem);
+ bRetVal = TRUE;
+
+ LOGEXIT( "LocalFree returning %p.\n", bRetVal == TRUE ? (HLOCAL)NULL : hMem );
+ PERF_EXIT(LocalFree);
+ return bRetVal == TRUE ? (HLOCAL)NULL : hMem;
+}
diff --git a/src/coreclr/pal/src/misc/fmtmessage.cpp b/src/coreclr/pal/src/misc/fmtmessage.cpp
index e9d87d19c4a08..81502bfc7722e 100644
--- a/src/coreclr/pal/src/misc/fmtmessage.cpp
+++ b/src/coreclr/pal/src/misc/fmtmessage.cpp
@@ -63,7 +63,7 @@ static LPWSTR FMTMSG_GetMessageString( DWORD dwErrCode )
allocChars = MAX_ERROR_STRING_LENGTH + 1;
}
- LPWSTR lpRetVal = (LPWSTR)PAL_malloc(allocChars * sizeof(WCHAR));
+ LPWSTR lpRetVal = (LPWSTR)LocalAlloc(LMEM_FIXED, allocChars * sizeof(WCHAR));
if (lpRetVal)
{
@@ -135,7 +135,7 @@ static INT FMTMSG__watoi( LPWSTR str )
UINT NumOfBytes = 0; \
nSize *= 2; \
NumOfBytes = nSize * sizeof( WCHAR ); \
- lpTemp = static_cast( PAL_malloc( NumOfBytes ) ); \
+ lpTemp = static_cast( LocalAlloc( LMEM_FIXED, NumOfBytes ) ); \
TRACE( "Growing the buffer.\n" );\
\
if ( !lpTemp ) \
@@ -149,7 +149,7 @@ static INT FMTMSG__watoi( LPWSTR str )
\
*lpWorkingString = '\0';\
PAL_wcscpy( lpTemp, lpReturnString );\
- free( lpReturnString ); \
+ LocalFree( lpReturnString ); \
lpWorkingString = lpReturnString = lpTemp; \
lpWorkingString += nCount; \
} \
@@ -341,7 +341,7 @@ FormatMessageW(
/* Parameter processing. */
if ( dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER )
{
- TRACE( "Allocated %d TCHARs. Don't forget to call free to "
+ TRACE( "Allocated %d TCHARs. Don't forget to call LocalFree to "
"free the memory when done.\n", nSize );
bIsLocalAlloced = TRUE;
}
@@ -418,7 +418,7 @@ FormatMessageW(
}
lpWorkingString = static_cast(
- PAL_malloc( nSize * sizeof( WCHAR ) ) );
+ LocalAlloc( LMEM_FIXED, nSize * sizeof( WCHAR ) ) );
if ( !lpWorkingString )
{
ERROR( "Unable to allocate memory for the working string.\n" );
@@ -675,14 +675,14 @@ FormatMessageW(
{
TRACE( "Copying the string into the buffer.\n" );
PAL_wcsncpy( lpBuffer, lpReturnString, nCount + 1 );
- free( lpReturnString );
+ LocalFree( lpReturnString );
}
}
else /* Error, something occurred. */
{
if ( lpReturnString )
{
- free( lpReturnString );
+ LocalFree( lpReturnString );
}
}
LOGEXIT( "FormatMessageW returns %d.\n", nCount );
diff --git a/src/coreclr/pal/tests/palsuite/CMakeLists.txt b/src/coreclr/pal/tests/palsuite/CMakeLists.txt
index f14b2442afa78..f58757a1f6d5f 100644
--- a/src/coreclr/pal/tests/palsuite/CMakeLists.txt
+++ b/src/coreclr/pal/tests/palsuite/CMakeLists.txt
@@ -415,6 +415,7 @@ add_executable_clr(paltests
c_runtime/wcsstr/test1/test1.cpp
c_runtime/wcstod/test1/test1.cpp
c_runtime/wcstod/test2/test2.cpp
+ c_runtime/wcstok/test1/test1.cpp
c_runtime/wcstoul/test1/test1.cpp
c_runtime/wcstoul/test2/test2.cpp
c_runtime/wcstoul/test3/test3.cpp
@@ -580,6 +581,9 @@ add_executable_clr(paltests
# filemapping_memmgt/GetProcAddress/test1/testlib.cpp
filemapping_memmgt/GetProcAddress/test2/test2.cpp
# filemapping_memmgt/GetProcAddress/test2/testlib.cpp
+ filemapping_memmgt/LocalAlloc/test1/LocalAlloc.cpp
+ filemapping_memmgt/LocalFree/test1/LocalFree.cpp
+ filemapping_memmgt/LocalFree/test2/LocalFree.cpp
filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.cpp
filemapping_memmgt/MapViewOfFile/test2/MapViewOfFile.cpp
filemapping_memmgt/MapViewOfFile/test3/MapViewOfFile.cpp
diff --git a/src/coreclr/pal/tests/palsuite/c_runtime/wcstok/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/c_runtime/wcstok/test1/test1.cpp
new file mode 100644
index 0000000000000..564466c2a4e7f
--- /dev/null
+++ b/src/coreclr/pal/tests/palsuite/c_runtime/wcstok/test1/test1.cpp
@@ -0,0 +1,113 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*============================================================================
+**
+** Source: test1.c
+**
+** Purpose:
+** Search for a number of tokens within strings. Check that the return values
+** are what is expected, and also that the strings match up with our expected
+** results.
+**
+**
+**==========================================================================*/
+
+#include
+
+PALTEST(c_runtime_wcstok_test1_paltest_wcstok_test1, "c_runtime/wcstok/test1/paltest_wcstok_test1")
+{
+ /* foo bar baz */
+ WCHAR str[] = {'f','o','o',' ','b','a','r',' ','b','a','z','\0'};
+
+ /* foo \0ar baz */
+ WCHAR result1[] = {'f','o','o',' ','\0','a','r',' ','b','a','z','\0'};
+
+ /* foo \0a\0 baz */
+ WCHAR result2[] = {'f','o','o',' ','\0','a','\0',' ','b','a','z','\0'};
+
+ WCHAR* tempString;
+ int len = 0;
+ WCHAR *ptr;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ len = (wcslen(str)*sizeof(WCHAR)) + 2;
+
+ /* Tokenize 'str'. It will hit the 'b' delimiter first. Check to see
+ that the ptr is pointing to the start of the string and do a compare
+ to ensure the tokenized string is what we expected.
+ */
+
+ tempString = convert("bz");
+ ptr = wcstok(str, tempString);
+ free(tempString);
+
+ if (ptr != str)
+ {
+ Fail("ERROR: Expected wcstok() to return %p, got %p!\n", str, ptr);
+ }
+
+ if (memcmp(str, result1, len) != 0)
+ {
+ Fail("ERROR: wcstok altered the string in an unexpected fashion.");
+ }
+
+ /* If NULL is passed as the first parameter, wcstok will continue
+ tokenizing the same string. Test that this works properly.
+ */
+ tempString = convert("r ");
+ ptr = wcstok(NULL, tempString);
+ free(tempString);
+
+ if (ptr != str + 5)
+ {
+ Fail("ERROR: Expected wcstok() to return %p, got %p!\n", str+5, ptr);
+ }
+
+ if (memcmp(str, result2, len) != 0)
+ {
+ Fail("ERROR: wcstok altered the string in an unexpected fashion.");
+ }
+
+ /* Continue onward, and search for 'X' now, which won't be found. The
+ pointer should point just after the last NULL in the string. And
+ the string itself shouldn't have changed.
+ */
+ tempString = convert("X");
+ ptr = wcstok(NULL, tempString);
+ free(tempString);
+
+ if (ptr != str + 7)
+ {
+ Fail("ERROR: Expected wcstok() to return %p, got %p!\n", str + 7, ptr);
+ }
+
+ if (memcmp(str, result2, len) != 0)
+ {
+ Fail("ERROR: wcstok altered the string in an unexpeced fashion.\n");
+ }
+
+ /* Call wcstok again. Now the ptr should point to the end of the
+ string at NULL. And the string itself shouldn't have changed.
+ */
+ tempString = convert("X");
+ ptr = wcstok(NULL, tempString);
+ free(tempString);
+
+ if (ptr != NULL)
+ {
+ Fail("ERROR: Expected wcstok() to return %p, got %p!\n", NULL, ptr);
+ }
+
+ if (memcmp(str, result2, len) != 0)
+ {
+ Fail("ERROR: wcstok altered the string in an unexpeced fashion.\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/coreclr/pal/tests/palsuite/compilableTests.txt b/src/coreclr/pal/tests/palsuite/compilableTests.txt
index a7e27f9228976..c674de294db45 100644
--- a/src/coreclr/pal/tests/palsuite/compilableTests.txt
+++ b/src/coreclr/pal/tests/palsuite/compilableTests.txt
@@ -348,6 +348,7 @@ c_runtime/wcsrchr/test1/paltest_wcsrchr_test1
c_runtime/wcsstr/test1/paltest_wcsstr_test1
c_runtime/wcstod/test1/paltest_wcstod_test1
c_runtime/wcstod/test2/paltest_wcstod_test2
+c_runtime/wcstok/test1/paltest_wcstok_test1
c_runtime/wcstoul/test1/paltest_wcstoul_test1
c_runtime/wcstoul/test2/paltest_wcstoul_test2
c_runtime/wcstoul/test3/paltest_wcstoul_test3
@@ -486,6 +487,9 @@ filemapping_memmgt/GetModuleFileNameW/test1/paltest_getmodulefilenamew_test1
filemapping_memmgt/GetModuleFileNameW/test2/paltest_getmodulefilenamew_test2
filemapping_memmgt/GetProcAddress/test1/paltest_getprocaddress_test1
filemapping_memmgt/GetProcAddress/test2/paltest_getprocaddress_test2
+filemapping_memmgt/LocalAlloc/test1/paltest_localalloc_test1
+filemapping_memmgt/LocalFree/test1/paltest_localfree_test1
+filemapping_memmgt/LocalFree/test2/paltest_localfree_test2
filemapping_memmgt/MapViewOfFile/test1/paltest_mapviewoffile_test1
filemapping_memmgt/MapViewOfFile/test2/paltest_mapviewoffile_test2
filemapping_memmgt/MapViewOfFile/test3/paltest_mapviewoffile_test3
diff --git a/src/coreclr/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/LocalAlloc.cpp b/src/coreclr/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/LocalAlloc.cpp
new file mode 100644
index 0000000000000..5879ed598071a
--- /dev/null
+++ b/src/coreclr/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/LocalAlloc.cpp
@@ -0,0 +1,48 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*=============================================================
+**
+** Source: LocalAlloc.c
+**
+** Purpose: Positive test the LocalAlloc API.
+** Call LocalAlloc with zero as the allocation attribute
+**
+**
+**============================================================*/
+#include
+
+PALTEST(filemapping_memmgt_LocalAlloc_test1_paltest_localalloc_test1, "filemapping_memmgt/LocalAlloc/test1/paltest_localalloc_test1")
+{
+ HLOCAL LocalHeap;
+ HLOCAL FreeHeap;
+ int err;
+ const SIZE_T heapSize = 64;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ /*Allocate the specified number of bytes from the heap*/
+ /*with allocation attribute: zero which is required by PAL Doc*/
+ LocalHeap = LocalAlloc(0, heapSize);
+ if(!LocalHeap)
+ {
+ Fail("\nFailed to call LocalAlloc API, "
+ "error code=%u\n", GetLastError());
+ }
+
+ /*Free the allocated local heap memory*/
+ FreeHeap = LocalFree(LocalHeap);
+ if(FreeHeap)
+ {
+ Fail("Failed to call LocalFree API, "
+ "error code=%u\n", GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/coreclr/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/LocalFree.cpp b/src/coreclr/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/LocalFree.cpp
new file mode 100644
index 0000000000000..0fcb32d6fc96f
--- /dev/null
+++ b/src/coreclr/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/LocalFree.cpp
@@ -0,0 +1,48 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*=============================================================
+**
+** Source: LocalFree.c
+**
+** Purpose: Positive test the LocalFree API.
+** Call LocalFree to free a specified local memory object
+**
+**
+**============================================================*/
+#include
+
+PALTEST(filemapping_memmgt_LocalFree_test1_paltest_localfree_test1, "filemapping_memmgt/LocalFree/test1/paltest_localfree_test1")
+{
+ HLOCAL LocalHeap;
+ HLOCAL FreeHeap;
+ int err;
+ const SIZE_T heapSize = 64;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ /*Allocate the specified number of bytes from the heap*/
+ /*with zero ad the allocation attribute*/
+ LocalHeap = LocalAlloc(0, heapSize);
+ if(!LocalHeap)
+ {
+ Fail("\nFailed to call LocalAlloc API, "
+ "error code=%u\n", GetLastError());
+ }
+
+ /*Free the allocated local heap memory*/
+ FreeHeap = LocalFree(LocalHeap);
+ if(FreeHeap)
+ {
+ Fail("Failed to call LocalFree API, "
+ "error code=%u\n", GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/coreclr/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/LocalFree.cpp b/src/coreclr/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/LocalFree.cpp
new file mode 100644
index 0000000000000..5d66077a2cfd7
--- /dev/null
+++ b/src/coreclr/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/LocalFree.cpp
@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*=============================================================
+**
+** Source: LocalFree.c
+**
+** Purpose: Positive test the LocalFree API.
+** call LocalFree by passing NULL as local memory
+** object handle
+**
+**
+**============================================================*/
+#include
+
+PALTEST(filemapping_memmgt_LocalFree_test2_paltest_localfree_test2, "filemapping_memmgt/LocalFree/test2/paltest_localfree_test2")
+{
+ HLOCAL FreeHeap;
+ int err;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ /*call LocalFree by passing NULL as local memory object handle*/
+ FreeHeap = LocalFree(NULL);
+ if(FreeHeap)
+ {
+ Fail("Failed to call LocalFree API, "
+ "error code=%u\n", GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp
index 93363488bc61d..d71e0ea85c333 100644
--- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp
+++ b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp
@@ -7,9 +7,9 @@
**
** Purpose: Positive test the LoadLibrary API. Test will verify
** that it is unable to load the library twice. Once by
-** using the full path name and secondly by using the
+** using the full path name and secondly by using the
** short name.
-**
+**
**
**============================================================*/
@@ -25,13 +25,14 @@ typedef int (*dllfunct)();
#define GETATTACHCOUNTNAME "_GetAttachCount@0"
#endif
+
/* Helper function to test the loaded library.
*/
BOOL PALAPI TestDll(HMODULE hLib)
{
int RetVal;
char FunctName[] = GETATTACHCOUNTNAME;
- FARPROC DllFunc;
+ FARPROC DllFunc;
/* Access a function from the loaded library.
*/
@@ -44,7 +45,7 @@ BOOL PALAPI TestDll(HMODULE hLib)
return (FALSE);
}
- /* Verify that the DLL_PROCESS_ATTACH is only
+ /* Verify that the DLL_PROCESS_ATTACH is only
* accessed once.*/
RetVal = DllFunc();
if (RetVal != 1)
@@ -69,7 +70,7 @@ PALTEST(loader_LoadLibraryA_test6_paltest_loadlibrarya_test6, "loader/LoadLibrar
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
-
+
/* Initialize the PAL. */
if ((PAL_Initialize(argc, argv)) != 0)
@@ -83,15 +84,15 @@ PALTEST(loader_LoadLibraryA_test6_paltest_loadlibrarya_test6, "loader/LoadLibrar
/* Get the full path to the library (DLL).
*/
-
- if (NULL != realpath(argv[0],fullpath)) {
-
+
+ if (NULL != _fullpath(fullPath,argv[0],_MAX_DIR)) {
+
_splitpath(fullPath,drive,dir,fname,ext);
_makepath(fullPath,drive,dir,LibraryName,"");
-
-
+
+
} else {
- Fail("ERROR: conversion from relative path \" %s \" to absolute path failed. realpath returned NULL\n",argv[0]);
+ Fail("ERROR: conversion from relative path \" %s \" to absolute path failed. _fullpath returned NULL\n",argv[0]);
}
/* Call Load library with the short name of
@@ -100,11 +101,11 @@ PALTEST(loader_LoadLibraryA_test6_paltest_loadlibrarya_test6, "loader/LoadLibrar
hShortLib = LoadLibrary(LibraryName);
if(hShortLib == NULL)
{
- Fail("ERROR:%u:Unable to load library %s\n",
- GetLastError(),
+ Fail("ERROR:%u:Unable to load library %s\n",
+ GetLastError(),
LibraryName);
}
-
+
/* Test the loaded library.
*/
if (!TestDll(hShortLib))
@@ -119,8 +120,8 @@ PALTEST(loader_LoadLibraryA_test6_paltest_loadlibrarya_test6, "loader/LoadLibrar
hFullLib = LoadLibrary(fullPath);
if(hFullLib == NULL)
{
- Trace("ERROR:%u:Unable to load library %s\n",
- GetLastError(),
+ Trace("ERROR:%u:Unable to load library %s\n",
+ GetLastError(),
fullPath);
iRetVal = FAIL;
goto cleanUpTwo;
@@ -140,11 +141,11 @@ PALTEST(loader_LoadLibraryA_test6_paltest_loadlibrarya_test6, "loader/LoadLibrar
cleanUpTwo:
- /* Call the FreeLibrary API.
- */
+ /* Call the FreeLibrary API.
+ */
if (!FreeLibrary(hFullLib))
{
- Trace("ERROR:%u: Unable to free library \"%s\"\n",
+ Trace("ERROR:%u: Unable to free library \"%s\"\n",
GetLastError(),
fullPath);
iRetVal = FAIL;
@@ -152,11 +153,11 @@ PALTEST(loader_LoadLibraryA_test6_paltest_loadlibrarya_test6, "loader/LoadLibrar
cleanUpOne:
- /* Call the FreeLibrary API.
- */
+ /* Call the FreeLibrary API.
+ */
if (!FreeLibrary(hShortLib))
{
- Trace("ERROR:%u: Unable to free library \"%s\"\n",
+ Trace("ERROR:%u: Unable to free library \"%s\"\n",
GetLastError(),
LibraryName);
iRetVal = FAIL;
@@ -166,4 +167,5 @@ PALTEST(loader_LoadLibraryA_test6_paltest_loadlibrarya_test6, "loader/LoadLibrar
*/
PAL_TerminateEx(iRetVal);
return iRetVal;
+
}
diff --git a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp
index 1bbf9a6d08ad1..b489ef27f965e 100644
--- a/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp
+++ b/src/coreclr/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp
@@ -7,9 +7,9 @@
**
** Purpose: Positive test the LoadLibrary API. Test will verify
** that it is unable to load the library twice. Once by
-** using the full path name and secondly by using the
+** using the full path name and secondly by using the
** short name.
-**
+**
**
**============================================================*/
@@ -25,13 +25,14 @@ typedef int (*dllfunct)();
#define GETATTACHCOUNTNAME "_GetAttachCount@0"
#endif
+
/* Helper function to test the loaded library.
*/
BOOL PALAPI TestDll(HMODULE hLib)
{
int RetVal;
char FunctName[] = GETATTACHCOUNTNAME;
- FARPROC DllFunc;
+ FARPROC DllFunc;
/* Access a function from the loaded library.
*/
@@ -44,7 +45,7 @@ BOOL PALAPI TestDll(HMODULE hLib)
return (FALSE);
}
- /* Verify that the DLL_PROCESS_ATTACH is only
+ /* Verify that the DLL_PROCESS_ATTACH is only
* accessed once.*/
RetVal = DllFunc();
if (RetVal != 1)
@@ -71,7 +72,7 @@ PALTEST(loader_LoadLibraryA_test8_paltest_loadlibrarya_test8, "loader/LoadLibrar
char relTestDir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
-
+
BOOL bRc = FALSE;
char relLibPath[_MAX_DIR];
@@ -88,15 +89,15 @@ PALTEST(loader_LoadLibraryA_test8_paltest_loadlibrarya_test8, "loader/LoadLibrar
/* Get the full path to the library (DLL).
*/
-
- if (NULL != realpath(argv[0],fullpath)) {
-
+
+ if (NULL != _fullpath(fullPath,argv[0],_MAX_DIR)) {
+
_splitpath(fullPath,drive,dir,fname,ext);
_makepath(fullPath,drive,dir,LibraryName,"");
-
-
+
+
} else {
- Fail("ERROR: conversion from relative path \" %s \" to absolute path failed. realpath returned NULL\n",argv[0]);
+ Fail("ERROR: conversion from relative path \" %s \" to absolute path failed. _fullpath returned NULL\n",argv[0]);
}
/* Get relative path to the library
@@ -111,11 +112,11 @@ PALTEST(loader_LoadLibraryA_test8_paltest_loadlibrarya_test8, "loader/LoadLibrar
hShortLib = LoadLibrary(LibraryName);
if(hShortLib == NULL)
{
- Fail("ERROR:%u:Short:Unable to load library %s\n",
- GetLastError(),
+ Fail("ERROR:%u:Short:Unable to load library %s\n",
+ GetLastError(),
LibraryName);
}
-
+
/* Test the loaded library.
*/
if (!TestDll(hShortLib))
@@ -130,8 +131,8 @@ PALTEST(loader_LoadLibraryA_test8_paltest_loadlibrarya_test8, "loader/LoadLibrar
hFullLib = LoadLibrary(fullPath);
if(hFullLib == NULL)
{
- Trace("ERROR:%u:Full:Unable to load library %s\n",
- GetLastError(),
+ Trace("ERROR:%u:Full:Unable to load library %s\n",
+ GetLastError(),
fullPath);
iRetVal = FAIL;
goto cleanUpTwo;
@@ -147,14 +148,14 @@ PALTEST(loader_LoadLibraryA_test8_paltest_loadlibrarya_test8, "loader/LoadLibrar
/*
** Call the load library with the relative path
- ** wrt to the directory ./testloadlibrary/..
+ ** wrt to the directory ./testloadlibrary/..
** since we don't want to make any assumptions
** regarding the type of build
*/
hRelLib = LoadLibrary(relLibPath);
if(hRelLib == NULL)
{
- Trace("ERROR:%u:Rel:Unable to load library at %s\n",
+ Trace("ERROR:%u:Rel:Unable to load library at %s\n",
GetLastError(), relLibPath);
iRetVal = FAIL;
goto cleanUpTwo;
@@ -189,12 +190,12 @@ PALTEST(loader_LoadLibraryA_test8_paltest_loadlibrarya_test8, "loader/LoadLibrar
cleanUpThree:
- /* Call the FreeLibrary API.
- */
+ /* Call the FreeLibrary API.
+ */
if (!FreeLibrary(hRelLib))
{
- Trace("ERROR:%u: Unable to free library \"%s\"\n",
+ Trace("ERROR:%u: Unable to free library \"%s\"\n",
GetLastError(),
relLibPath);
iRetVal = FAIL;
@@ -202,11 +203,11 @@ PALTEST(loader_LoadLibraryA_test8_paltest_loadlibrarya_test8, "loader/LoadLibrar
cleanUpTwo:
- /* Call the FreeLibrary API.
- */
+ /* Call the FreeLibrary API.
+ */
if (!FreeLibrary(hFullLib))
{
- Trace("ERROR:%u: Unable to free library \"%s\"\n",
+ Trace("ERROR:%u: Unable to free library \"%s\"\n",
GetLastError(),
fullPath);
iRetVal = FAIL;
@@ -214,18 +215,20 @@ PALTEST(loader_LoadLibraryA_test8_paltest_loadlibrarya_test8, "loader/LoadLibrar
cleanUpOne:
- /* Call the FreeLibrary API.
- */
+ /* Call the FreeLibrary API.
+ */
if (!FreeLibrary(hShortLib))
{
- Trace("ERROR:%u: Unable to free library \"%s\"\n",
+ Trace("ERROR:%u: Unable to free library \"%s\"\n",
GetLastError(),
LibraryName);
iRetVal = FAIL;
}
+
/* Terminate the PAL.
*/
PAL_TerminateEx(iRetVal);
return iRetVal;
+
}
diff --git a/src/coreclr/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/test.cpp b/src/coreclr/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/test.cpp
index 15d94411bb030..b16b0ea27754e 100644
--- a/src/coreclr/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/test.cpp
+++ b/src/coreclr/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/test.cpp
@@ -36,9 +36,9 @@ PALTEST(miscellaneous_FormatMessageW_test6_paltest_formatmessagew_test6, "miscel
the error message it extracts is correct, only that it does place some
information into the buffer when it is called.
*/
-
+
/*
-
+
ERROR_SUCCESS (0L) is normally returned by GetLastError,
But, the ERROR_SUCCESS is removed from messages for Unix based Systems
To ensure that we have some information into the buffer we are using the message
@@ -54,25 +54,25 @@ PALTEST(miscellaneous_FormatMessageW_test6_paltest_formatmessagew_test6, "miscel
0, /* maximum size of message buffer */
NULL /* array of message inserts */
);
-
- if(ReturnResult == 0)
+
+ if(ReturnResult == 0)
{
Fail("ERROR: The return value was 0, which indicates failure. The "
"function failed when trying to Format a FROM_SYSTEM message.");
}
-
- if(wcslen(OutBuffer) <= 0)
+
+ if(wcslen(OutBuffer) <= 0)
{
Fail("ERROR: There are no characters in the buffer, and when the "
"FORMAT_MESSAGE_FROM_SYSTEM flag is used with ERROR_FILE_NOT_FOUND error, "
"something should be put into the buffer.");
}
-
- free(OutBuffer);
-
+
+ LocalFree(OutBuffer);
+
PAL_Terminate();
return PASS;
-
+
}
diff --git a/src/coreclr/pal/tests/palsuite/paltestlist.txt b/src/coreclr/pal/tests/palsuite/paltestlist.txt
index 2afdf101d5b68..2b9ac7ccd4eb1 100644
--- a/src/coreclr/pal/tests/palsuite/paltestlist.txt
+++ b/src/coreclr/pal/tests/palsuite/paltestlist.txt
@@ -333,6 +333,7 @@ c_runtime/wcsrchr/test1/paltest_wcsrchr_test1
c_runtime/wcsstr/test1/paltest_wcsstr_test1
c_runtime/wcstod/test1/paltest_wcstod_test1
c_runtime/wcstod/test2/paltest_wcstod_test2
+c_runtime/wcstok/test1/paltest_wcstok_test1
c_runtime/wcstoul/test1/paltest_wcstoul_test1
c_runtime/wcstoul/test2/paltest_wcstoul_test2
c_runtime/wcstoul/test3/paltest_wcstoul_test3
@@ -448,6 +449,9 @@ filemapping_memmgt/CreateFileMappingW/test9/paltest_createfilemappingw_test9
filemapping_memmgt/FreeLibrary/test2/paltest_freelibrary_test2
filemapping_memmgt/GetModuleFileNameA/test2/paltest_getmodulefilenamea_test2
filemapping_memmgt/GetModuleFileNameW/test2/paltest_getmodulefilenamew_test2
+filemapping_memmgt/LocalAlloc/test1/paltest_localalloc_test1
+filemapping_memmgt/LocalFree/test1/paltest_localfree_test1
+filemapping_memmgt/LocalFree/test2/paltest_localfree_test2
filemapping_memmgt/MapViewOfFile/test1/paltest_mapviewoffile_test1
filemapping_memmgt/MapViewOfFile/test2/paltest_mapviewoffile_test2
filemapping_memmgt/MapViewOfFile/test3/paltest_mapviewoffile_test3
diff --git a/src/coreclr/runtime-prereqs.proj b/src/coreclr/runtime-prereqs.proj
index 36ed2ce497be1..1127c3df8bdf3 100644
--- a/src/coreclr/runtime-prereqs.proj
+++ b/src/coreclr/runtime-prereqs.proj
@@ -7,7 +7,7 @@
-
+
diff --git a/src/coreclr/runtime.proj b/src/coreclr/runtime.proj
index 26801ea8c198c..5f062c9af2f40 100644
--- a/src/coreclr/runtime.proj
+++ b/src/coreclr/runtime.proj
@@ -48,7 +48,6 @@
<_CoreClrBuildArg Condition="'$(ClrAllJitsSubset)' == 'true'" Include="-component alljits" />
<_CoreClrBuildArg Condition="'$(ClrILToolsSubset)' == 'true'" Include="-component iltools" />
<_CoreClrBuildArg Condition="'$(ClrNativeAotSubset)' == 'true'" Include="-component nativeaot" />
- <_CoreClrBuildArg Condition="'$(ClrSpmiSubset)' == 'true'" Include="-component spmi" />
diff --git a/src/coreclr/scripts/jitrollingbuild.py b/src/coreclr/scripts/jitrollingbuild.py
index 71e7d148a61d1..100aff85c3522 100644
--- a/src/coreclr/scripts/jitrollingbuild.py
+++ b/src/coreclr/scripts/jitrollingbuild.py
@@ -74,13 +74,6 @@
git_hash_help = "git hash"
-use_latest_jit_change_help = """\
-Starting with the given git hash, look backwards in the git log for the first change that includes any JIT
-change. We want to ensure that any git hash uploaded to the JIT rolling build store is a JIT change. This
-addresses a problem where Azure DevOps sometimes builds changes that come soon after a JIT change, instead of
-the JIT change itself.
-"""
-
target_dir_help = "Directory to put the downloaded JIT."
skip_cleanup_help = "Skip intermediate file removal."
@@ -104,7 +97,6 @@
upload_parser = subparsers.add_parser("upload", description=upload_description, parents=[common_parser])
upload_parser.add_argument("-git_hash", required=True, help=git_hash_help)
-upload_parser.add_argument("--use_latest_jit_change", action="store_true", help=use_latest_jit_change_help)
upload_parser.add_argument("-az_storage_key", help="Key for the clrjit Azure Storage location. Default: use the value of the CLRJIT_AZ_KEY environment variable.")
upload_parser.add_argument("--skip_cleanup", action="store_true", help=skip_cleanup_help)
@@ -466,32 +458,6 @@ def upload_blob(file, blob_name):
# pdb_paths = [os.path.join(pdb_dir, item) for item in os.listdir(pdb_dir) if re.match(r'.*clrjit.*', item)]
# files += pdb_paths
- # Figure out which git hash to use for the upload. By default, it is the required coreclr_args.git_hash argument.
- # However, if "--use_latest_jit_change" is passed, we look backwards in the git log for the nearest git commit
- # with a JIT change (it could, and often will be, the same as the argument git_hash).
- jit_git_hash = coreclr_args.git_hash
-
- if coreclr_args.use_latest_jit_change:
- # Do all the remaining commands, including a number of 'git' commands including relative paths,
- # from the root of the runtime repo.
-
- with ChangeDir(coreclr_args.runtime_repo_location):
- # Enumerate the last change, starting with the jit_git_hash, that included JIT changes.
- command = [ "git", "log", "--pretty=format:%H", jit_git_hash, "-1", "--", "src/coreclr/jit/*" ]
- print("Invoking: {}".format(" ".join(command)))
- proc = subprocess.Popen(command, stdout=subprocess.PIPE)
- stdout_change_list, _ = proc.communicate()
- return_code = proc.returncode
- change_list_hashes = []
- if return_code == 0:
- change_list_hashes = stdout_change_list.decode('utf-8').strip().splitlines()
-
- if len(change_list_hashes) == 0:
- print("Couldn't find any JIT changes! Just using the argument git_hash")
- else:
- jit_git_hash = change_list_hashes[0]
- print("Using git_hash {}".format(jit_git_hash))
-
print("Uploading:")
for item in files:
print(" {}".format(item))
@@ -506,7 +472,7 @@ def upload_blob(file, blob_name):
raise RuntimeError("Missing azure storage package.")
blob_service_client = BlobServiceClient(account_url=az_blob_storage_account_uri, credential=coreclr_args.az_storage_key)
- blob_folder_name = "{}/{}/{}/{}/{}".format(az_builds_root_folder, jit_git_hash, coreclr_args.host_os, coreclr_args.arch, coreclr_args.build_type)
+ blob_folder_name = "{}/{}/{}/{}/{}".format(az_builds_root_folder, coreclr_args.git_hash, coreclr_args.host_os, coreclr_args.arch, coreclr_args.build_type)
total_bytes_uploaded = 0
@@ -718,11 +684,6 @@ def setup_spmi_location_arg(spmi_location):
lambda unused: True,
"Unable to set git_hash")
- coreclr_args.verify(args,
- "use_latest_jit_change",
- lambda unused: True,
- "Unable to set use_latest_jit_change")
-
coreclr_args.verify(args,
"az_storage_key",
lambda item: item is not None,
diff --git a/src/coreclr/scripts/jitutil.py b/src/coreclr/scripts/jitutil.py
index 5df464da5fc0c..c7906124b45d4 100644
--- a/src/coreclr/scripts/jitutil.py
+++ b/src/coreclr/scripts/jitutil.py
@@ -85,31 +85,12 @@ def set_pipeline_variable(name, value):
print(define_variable_format.format(name, value)) # set variable
-
################################################################################
##
## Helper functions
##
################################################################################
-def decode_string(str_to_decode):
- """Decode a UTF-8 encoded bytes to string.
-
- Args:
- str_to_decode (byte stream): Byte stream to decode
-
- Returns:
- String output. If there any encoding/decoding errors, it will replace it with
- UnicodeEncodeError.
- """
- try:
- output = str_to_decode.decode("utf-8", errors='replace')
- except UnicodeEncodeError:
- output = "UnicodeEncodeError"
- except UnicodeDecodeError:
- output = "UnicodeDecodeError"
- return output
-
def run_command(command_to_run, _cwd=None, _exit_on_fail=False, _output_file=None):
""" Runs the command.
@@ -138,15 +119,15 @@ def run_command(command_to_run, _cwd=None, _exit_on_fail=False, _output_file=Non
if proc.poll() is not None:
break
if output:
- output_str = decode_string(output.strip())
+ output_str = output.strip().decode("utf-8")
print(output_str)
of.write(output_str + "\n")
else:
command_stdout, command_stderr = proc.communicate()
if len(command_stdout) > 0:
- print(decode_string(command_stdout))
+ print(command_stdout.decode("utf-8"))
if len(command_stderr) > 0:
- print(decode_string(command_stderr))
+ print(command_stderr.decode("utf-8"))
return_code = proc.returncode
if _exit_on_fail and return_code != 0:
diff --git a/src/coreclr/scripts/superpmi-asmdiffs.proj b/src/coreclr/scripts/superpmi-asmdiffs.proj
index 661a60aca831a..aef782d769cb9 100644
--- a/src/coreclr/scripts/superpmi-asmdiffs.proj
+++ b/src/coreclr/scripts/superpmi-asmdiffs.proj
@@ -55,8 +55,7 @@
-
-
+
diff --git a/src/coreclr/scripts/superpmi-collect.proj b/src/coreclr/scripts/superpmi-collect.proj
index 8d59a8218ae88..963e117688f57 100644
--- a/src/coreclr/scripts/superpmi-collect.proj
+++ b/src/coreclr/scripts/superpmi-collect.proj
@@ -42,14 +42,6 @@
PmiAssembliesPayload - Path that will be sent to helix machine to run collection on
PmiAssembliesDirectory - Path on helix machine itself where superpmi.py will discover the sent assemblies.
-->
-
-
-
-
-
-
-
-
%HELIX_PYTHONPATH%
$(WorkItemDirectory)\pmiAssembliesDirectory
@@ -62,7 +54,7 @@
%HELIX_WORKITEM_UPLOAD_ROOT%
$(BUILD_SOURCESDIRECTORY)\artifacts\helixresults
- $(SuperPMIDirectory)\superpmi.py collect -log_level DEBUG --$(CollectionType) -pmi_location $(SuperPMIDirectory)\pmi.dll -pmi_path @(PmiPathDirectories->'$(SuperPMIDirectory)\%(Identity)', ' ')
+ $(SuperPMIDirectory)\superpmi.py collect -log_level DEBUG --$(CollectionType) -pmi_location $(SuperPMIDirectory)\pmi.dll
$HELIX_PYTHONPATH
@@ -76,7 +68,7 @@
$HELIX_WORKITEM_UPLOAD_ROOT
$(BUILD_SOURCESDIRECTORY)/artifacts/helixresults
- $(SuperPMIDirectory)/superpmi.py collect -log_level DEBUG --$(CollectionType) -pmi_location $(SuperPMIDirectory)/pmi.dll -pmi_path @(PmiPathDirectories->'$(SuperPMIDirectory)/%(Identity)', ' ')
+ $(SuperPMIDirectory)/superpmi.py collect -log_level DEBUG --$(CollectionType) -pmi_location $(SuperPMIDirectory)/pmi.dll
diff --git a/src/coreclr/scripts/superpmi-replay.proj b/src/coreclr/scripts/superpmi-replay.proj
index cac87c580fdde..e76a4a3d810e5 100644
--- a/src/coreclr/scripts/superpmi-replay.proj
+++ b/src/coreclr/scripts/superpmi-replay.proj
@@ -55,8 +55,7 @@
-
-
+
diff --git a/src/coreclr/scripts/superpmi.md b/src/coreclr/scripts/superpmi.md
index 36e24711637ae..d9404dc32d740 100644
--- a/src/coreclr/scripts/superpmi.md
+++ b/src/coreclr/scripts/superpmi.md
@@ -1,7 +1,7 @@
# Documentation for the superpmi.py tool
SuperPMI is a tool for developing and testing the JIT compiler.
-General information on SuperPMI can be found [here](../tools/superpmi/readme.md).
+General information on SuperPMI can be found [here](../ToolBox/superpmi/readme.md).
## Overview
diff --git a/src/coreclr/scripts/superpmi.py b/src/coreclr/scripts/superpmi.py
index 3c9d417f81cc0..8433294a146d8 100755
--- a/src/coreclr/scripts/superpmi.py
+++ b/src/coreclr/scripts/superpmi.py
@@ -276,7 +276,6 @@
collect_parser.add_argument("-assemblies", dest="assemblies", nargs="+", default=[], help="A list of managed dlls or directories to recursively use while collecting with PMI or crossgen2. Required if --pmi or --crossgen2 is specified.")
collect_parser.add_argument("-exclude", dest="exclude", nargs="+", default=[], help="A list of files or directories to exclude from the files and directories specified by `-assemblies`.")
collect_parser.add_argument("-pmi_location", help="Path to pmi.dll to use during PMI run. Optional; pmi.dll will be downloaded from Azure Storage if necessary.")
-collect_parser.add_argument("-pmi_path", metavar="PMIPATH_DIR", nargs='*', help="Specify a \"load path\" where assemblies can be found during pmi.dll run. Optional; the argument values are translated to PMIPATH environment variable.")
collect_parser.add_argument("-output_mch_path", help="Location to place the final MCH file.")
collect_parser.add_argument("--merge_mch_files", action="store_true", help="Merge multiple MCH files. Use the -mch_files flag to pass a list of MCH files to merge.")
collect_parser.add_argument("-mch_files", metavar="MCH_FILE", nargs='+', help="Pass a sequence of MCH files which will be merged. Required by --merge_mch_files.")
@@ -832,14 +831,7 @@ async def run_pmi(print_prefix, assembly, self):
pmi_command_env = env_copy.copy()
pmi_complus_env = complus_env.copy()
pmi_complus_env["JitName"] = self.collection_shim_name
-
- if self.coreclr_args.pmi_path is not None:
- pmi_root_env = root_env.copy()
- pmi_root_env["PMIPATH"] = ";".join(self.coreclr_args.pmi_path)
- else:
- pmi_root_env = root_env
-
- set_and_report_env(pmi_command_env, pmi_root_env, pmi_complus_env)
+ set_and_report_env(pmi_command_env, root_env, pmi_complus_env)
old_env = os.environ.copy()
os.environ.update(pmi_command_env)
@@ -3113,11 +3105,6 @@ def verify_replay_common_args():
lambda unused: True,
"Unable to set tiered_compilation")
- coreclr_args.verify(args,
- "pmi_path",
- lambda unused: True,
- "Unable to set pmi_path")
-
if (args.collection_command is None) and (args.pmi is False) and (args.crossgen2 is False):
print("Either a collection command or `--pmi` or `--crossgen2` must be specified")
sys.exit(1)
@@ -3134,12 +3121,6 @@ def verify_replay_common_args():
print("Specify `-assemblies` if `--pmi` or `--crossgen2` is given")
sys.exit(1)
- if not args.pmi:
- if args.pmi_path is not None:
- logging.warning("Warning: -pmi_path is set but --pmi is not.")
- if args.pmi_location is not None:
- logging.warning("Warning: -pmi_location is set but --pmi is not.")
-
if args.collection_command is None and args.merge_mch_files is not True:
assert args.collection_args is None
assert (args.pmi is True) or (args.crossgen2 is True)
diff --git a/src/coreclr/tools/CMakeLists.txt b/src/coreclr/tools/CMakeLists.txt
index db59797e26f78..a50b1e6a1afbd 100644
--- a/src/coreclr/tools/CMakeLists.txt
+++ b/src/coreclr/tools/CMakeLists.txt
@@ -1,6 +1,3 @@
-add_subdirectory(SOS)
-add_subdirectory(superpmi)
-
if (CLR_CMAKE_TARGET_WIN32 AND NOT CLR_CMAKE_CROSS_ARCH)
add_subdirectory(GenClrDebugResource)
add_subdirectory(InjectResource)
diff --git a/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs b/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs
index 5357e2f68234b..b246a9847f227 100644
--- a/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs
+++ b/src/coreclr/tools/Common/Compiler/CompilationBuilder.cs
@@ -24,7 +24,6 @@ public abstract partial class CompilationBuilder
protected IEnumerable _compilationRoots = Array.Empty();
protected OptimizationMode _optimizationMode = OptimizationMode.None;
protected int _parallelism = -1;
- protected bool _resilient;
public CompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup compilationGroup, NameMangler nameMangler)
{
@@ -73,12 +72,6 @@ public CompilationBuilder UseOptimizationMode(OptimizationMode mode)
return this;
}
- public CompilationBuilder UseResilience(bool resilient)
- {
- _resilient = resilient;
- return this;
- }
-
public abstract CompilationBuilder UseBackendOptions(IEnumerable options);
public abstract CompilationBuilder UseILProvider(ILProvider ilProvider);
diff --git a/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.cs b/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.cs
index 029949cda3846..fa0828fc034e8 100644
--- a/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.cs
+++ b/src/coreclr/tools/Common/Compiler/CompilerTypeSystemContext.cs
@@ -157,7 +157,7 @@ public static unsafe PEReader OpenPEFile(string filePath, out MemoryMappedViewAc
try
{
// Create stream because CreateFromFile(string, ...) uses FileShare.None which is too strict
- fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1);
+ fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
mappedFile = MemoryMappedFile.CreateFromFile(
fileStream, null, fileStream.Length, MemoryMappedFileAccess.Read, HandleInheritability.None, true);
accessor = mappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);
@@ -174,9 +174,12 @@ public static unsafe PEReader OpenPEFile(string filePath, out MemoryMappedViewAc
}
finally
{
- accessor?.Dispose();
- mappedFile?.Dispose();
- fileStream?.Dispose();
+ if (accessor != null)
+ accessor.Dispose();
+ if (mappedFile != null)
+ mappedFile.Dispose();
+ if (fileStream != null)
+ fileStream.Dispose();
}
}
diff --git a/src/coreclr/tools/Common/Compiler/Logger.cs b/src/coreclr/tools/Common/Compiler/Logger.cs
index 5ecd5e846c4be..eb77c7cd681e1 100644
--- a/src/coreclr/tools/Common/Compiler/Logger.cs
+++ b/src/coreclr/tools/Common/Compiler/Logger.cs
@@ -10,7 +10,6 @@
using Internal.TypeSystem.Ecma;
using ILCompiler.Logging;
-using ILLink.Shared;
using ILSequencePoint = Internal.IL.ILSequencePoint;
using MethodIL = Internal.IL.MethodIL;
@@ -48,13 +47,6 @@ public Logger(TextWriter writer, bool isVerbose)
{
}
- public void LogMessage(string message)
- {
- MessageContainer? messageContainer = MessageContainer.CreateInfoMessage(message);
- if(messageContainer.HasValue)
- Writer.WriteLine(messageContainer.Value.ToMSBuildString());
- }
-
public void LogWarning(string text, int code, MessageOrigin origin, string subcategory = MessageSubCategory.None)
{
MessageContainer? warning = MessageContainer.CreateWarningMessage(this, text, code, origin, subcategory);
@@ -62,19 +54,14 @@ public void LogWarning(string text, int code, MessageOrigin origin, string subca
Writer.WriteLine(warning.Value.ToMSBuildString());
}
- public void LogWarning(MessageOrigin origin, DiagnosticId id, params string[] args)
+ public void LogWarning(string text, int code, TypeSystemEntity origin, string subcategory = MessageSubCategory.None)
{
- MessageContainer? warning = MessageContainer.CreateWarningMessage(this, origin, id, args);
+ MessageOrigin messageOrigin = new MessageOrigin(origin);
+ MessageContainer? warning = MessageContainer.CreateWarningMessage(this, text, code, messageOrigin, subcategory);
if (warning.HasValue)
Writer.WriteLine(warning.Value.ToMSBuildString());
}
- public void LogWarning(string text, int code, TypeSystemEntity origin, string subcategory = MessageSubCategory.None) =>
- LogWarning(text, code, new MessageOrigin(origin), subcategory);
-
- public void LogWarning(TypeSystemEntity origin, DiagnosticId id, params string[] args) =>
- LogWarning(new MessageOrigin(origin), id, args);
-
public void LogWarning(string text, int code, MethodIL origin, int ilOffset, string subcategory = MessageSubCategory.None)
{
string document = null;
@@ -99,62 +86,12 @@ public void LogWarning(string text, int code, MethodIL origin, int ilOffset, str
LogWarning(text, code, messageOrigin, subcategory);
}
- public void LogWarning(MethodIL origin, int ilOffset, DiagnosticId id, params string[] args)
- {
- string document = null;
- int? lineNumber = null;
-
- IEnumerable sequencePoints = origin.GetDebugInfo()?.GetSequencePoints();
- if (sequencePoints != null)
- {
- foreach (var sequencePoint in sequencePoints)
- {
- if (sequencePoint.Offset <= ilOffset)
- {
- document = sequencePoint.Document;
- lineNumber = sequencePoint.LineNumber;
- }
- }
- }
-
- MethodDesc warnedMethod = CompilerGeneratedState.GetUserDefinedMethodForCompilerGeneratedMember(origin.OwningMethod) ?? origin.OwningMethod;
-
- MessageOrigin messageOrigin = new MessageOrigin(warnedMethod, document, lineNumber, null);
- LogWarning(messageOrigin, id, args);
- }
-
public void LogWarning(string text, int code, string origin, string subcategory = MessageSubCategory.None)
{
MessageOrigin _origin = new MessageOrigin(origin);
LogWarning(text, code, _origin, subcategory);
}
- public void LogWarning(string origin, DiagnosticId id, params string[] args)
- {
- MessageOrigin _origin = new MessageOrigin(origin);
- LogWarning(_origin, id, args);
- }
-
- public void LogError(string text, int code, string subcategory = MessageSubCategory.None, MessageOrigin? origin = null)
- {
- MessageContainer? error = MessageContainer.CreateErrorMessage(text, code, subcategory, origin);
- if (error.HasValue)
- Writer.WriteLine(error.Value.ToMSBuildString());
- }
-
- public void LogError(MessageOrigin? origin, DiagnosticId id, params string[] args)
- {
- MessageContainer? error = MessageContainer.CreateErrorMessage(origin, id, args);
- if (error.HasValue)
- Writer.WriteLine(error.Value.ToMSBuildString());
- }
-
- public void LogError(string text, int code, TypeSystemEntity origin, string subcategory = MessageSubCategory.None) =>
- LogError(text, code, subcategory, new MessageOrigin(origin));
-
- public void LogError(TypeSystemEntity origin, DiagnosticId id, params string[] args) =>
- LogError(new MessageOrigin(origin), id, args);
-
internal bool IsWarningSuppressed(int code, MessageOrigin origin)
{
// This is causing too much noise
@@ -230,7 +167,7 @@ internal bool IsSingleWarn(ModuleDesc owningModule, string messageSubcategory)
{
if (_trimWarnedAssemblies.Add(assemblyName))
{
- LogWarning(GetModuleFileName(owningModule), DiagnosticId.AssemblyProducedTrimWarnings, assemblyName);
+ LogWarning($"Assembly '{assemblyName}' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries", 2104, GetModuleFileName(owningModule));
}
}
}
@@ -240,12 +177,12 @@ internal bool IsSingleWarn(ModuleDesc owningModule, string messageSubcategory)
{
if (_aotWarnedAssemblies.Add(assemblyName))
{
- LogWarning(GetModuleFileName(owningModule), DiagnosticId.AssemblyProducedAOTWarnings, assemblyName);
+ LogWarning($"Assembly '{assemblyName}' produced AOT analysis warnings.", 3053, GetModuleFileName(owningModule));
}
}
}
}
-
+
return result;
}
@@ -261,4 +198,11 @@ private static string GetModuleFileName(ModuleDesc module)
return assemblyName;
}
}
+
+ public static class MessageSubCategory
+ {
+ public const string None = "";
+ public const string TrimAnalysis = "Trim analysis";
+ public const string AotAnalysis = "AOT analysis";
+ }
}
diff --git a/src/coreclr/tools/Common/Compiler/Logging/MessageContainer.cs b/src/coreclr/tools/Common/Compiler/Logging/MessageContainer.cs
index 060315e345555..95ed5bf04fa0c 100644
--- a/src/coreclr/tools/Common/Compiler/Logging/MessageContainer.cs
+++ b/src/coreclr/tools/Common/Compiler/Logging/MessageContainer.cs
@@ -6,8 +6,6 @@
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
-using ILLink.Shared;
-
using Debug = System.Diagnostics.Debug;
namespace ILCompiler.Logging
@@ -67,22 +65,6 @@ internal static MessageContainer CreateErrorMessage(string text, int code, strin
return new MessageContainer(MessageCategory.Error, text, code, subcategory, origin);
}
- ///
- /// Create an error message.
- ///
- /// Filename, line, and column where the error was found
- /// Unique error ID. Please see https://github.com/dotnet/linker/blob/main/docs/error-codes.md
- /// for the list of errors and possibly add a new one
- /// Additional arguments to form a humanly readable message describing the warning
- /// New MessageContainer of 'Error' category
- internal static MessageContainer CreateErrorMessage(MessageOrigin? origin, DiagnosticId id, params string[] args)
- {
- if (!((int)id >= 1000 && (int)id <= 2000))
- throw new ArgumentOutOfRangeException(nameof(id), $"The provided code '{(int)id}' does not fall into the error category, which is in the range of 1000 to 2000 (inclusive).");
-
- return new MessageContainer(MessageCategory.Error, id, origin: origin, args: args);
- }
-
///
/// Create a warning message.
///
@@ -97,29 +79,12 @@ internal static MessageContainer CreateErrorMessage(MessageOrigin? origin, Diagn
/// New MessageContainer of 'Warning' category
internal static MessageContainer? CreateWarningMessage(Logger context, string text, int code, MessageOrigin origin, string subcategory = MessageSubCategory.None)
{
- if (!(code > 2000 && code <= 6000))
- throw new ArgumentOutOfRangeException(nameof(code), $"The provided code '{code}' does not fall into the warning category, which is in the range of 2001 to 6000 (inclusive).");
+ //if (!(code > 2000 && code <= 6000))
+ // throw new ArgumentOutOfRangeException(nameof(code), $"The provided code '{code}' does not fall into the warning category, which is in the range of 2001 to 6000 (inclusive).");
return CreateWarningMessageContainer(context, text, code, origin, subcategory);
}
- ///
- /// Create a warning message.
- ///
- /// Context with the relevant warning suppression info.
- /// Filename or member where the warning is coming from
- /// Unique warning ID. Please see https://github.com/dotnet/linker/blob/main/docs/error-codes.md
- /// for the list of warnings and possibly add a new one
- /// Additional arguments to form a humanly readable message describing the warning
- /// New MessageContainer of 'Warning' category
- internal static MessageContainer? CreateWarningMessage(Logger context, MessageOrigin origin, DiagnosticId id, params string[] args)
- {
- if (!((int)id > 2000 && (int)id <= 6000))
- throw new ArgumentOutOfRangeException(nameof(id), $"The provided code '{(int)id}' does not fall into the warning category, which is in the range of 2001 to 6000 (inclusive).");
-
- return CreateWarningMessageContainer(context, origin, id, id.GetDiagnosticSubcategory(), args);
- }
-
private static MessageContainer? CreateWarningMessageContainer(Logger context, string text, int code, MessageOrigin origin, string subcategory = MessageSubCategory.None)
{
if (context.IsWarningSuppressed(code, origin))
@@ -134,20 +99,6 @@ internal static MessageContainer CreateErrorMessage(MessageOrigin? origin, Diagn
return new MessageContainer(MessageCategory.Warning, text, code, subcategory, origin);
}
- private static MessageContainer? CreateWarningMessageContainer(Logger context, MessageOrigin origin, DiagnosticId id, string subcategory, params string[] args)
- {
- if (context.IsWarningSuppressed((int)id, origin))
- return null;
-
- if (TryLogSingleWarning(context, (int)id, origin, subcategory))
- return null;
-
- if (context.IsWarningAsError((int)id))
- return new MessageContainer(MessageCategory.WarningAsError, id, subcategory, origin, args);
-
- return new MessageContainer(MessageCategory.Warning, id, subcategory, origin, args);
- }
-
private static bool TryLogSingleWarning(Logger context, int code, MessageOrigin origin, string subcategory)
{
if (subcategory != MessageSubCategory.AotAnalysis && subcategory != MessageSubCategory.TrimAnalysis)
@@ -184,7 +135,7 @@ private static bool TryLogSingleWarning(Logger context, int code, MessageOrigin
private static bool IsTrimmableAssembly(ModuleDesc assembly)
{
if (assembly is EcmaAssembly ecmaAssembly)
- {
+ {
foreach (var attribute in ecmaAssembly.GetDecodedCustomAttributes("System.Reflection", "AssemblyMetadataAttribute"))
{
if (attribute.FixedArguments.Length != 2)
@@ -242,15 +193,6 @@ private MessageContainer(MessageCategory category, string text, int? code, strin
Text = text;
}
- private MessageContainer(MessageCategory category, DiagnosticId id, string subcategory = MessageSubCategory.None, MessageOrigin? origin = null, params string[] args)
- {
- Code = (int)id;
- Category = category;
- Origin = origin;
- SubCategory = subcategory;
- Text = new DiagnosticString(id).GetMessage(args);
- }
-
public override string ToString() => ToMSBuildString();
public string ToMSBuildString()
@@ -296,7 +238,7 @@ public string ToMSBuildString()
{
if (Origin?.MemberDefinition is MethodDesc method)
sb.Append(method.GetDisplayName());
- else
+ else
sb.Append(Origin?.MemberDefinition.ToString());
sb.Append(": ");
diff --git a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/CompilerGeneratedState.cs b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/CompilerGeneratedState.cs
index 3c22da1f5478b..34821288b76d9 100644
--- a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/CompilerGeneratedState.cs
+++ b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/CompilerGeneratedState.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
-using ILLink.Shared;
using Mono.Cecil;
namespace Mono.Linker
@@ -42,11 +41,15 @@ void PopulateCacheForType (TypeDefinition type)
case "AsyncIteratorStateMachineAttribute":
case "AsyncStateMachineAttribute":
case "IteratorStateMachineAttribute":
- TypeDefinition? stateMachineType = GetFirstConstructorArgumentAsType (attribute);
+ TypeDefinition stateMachineType = GetFirstConstructorArgumentAsType (attribute);
if (stateMachineType != null) {
if (!_compilerGeneratedTypeToUserCodeMethod.TryAdd (stateMachineType, method)) {
var alreadyAssociatedMethod = _compilerGeneratedTypeToUserCodeMethod[stateMachineType];
- _context.LogWarning (new MessageOrigin (method), DiagnosticId.MethodsAreAssociatedWithStateMachine, method.GetDisplayName (), alreadyAssociatedMethod.GetDisplayName (), stateMachineType.GetDisplayName ());
+ _context.LogWarning (
+ $"Methods '{method.GetDisplayName ()}' and '{alreadyAssociatedMethod.GetDisplayName ()}' are both associated with state machine type '{stateMachineType.GetDisplayName ()}'. This is currently unsupported and may lead to incorrectly reported warnings.",
+ 2107,
+ new MessageOrigin (method),
+ MessageSubCategory.TrimAnalysis);
}
}
@@ -56,7 +59,7 @@ void PopulateCacheForType (TypeDefinition type)
}
}
- static TypeDefinition? GetFirstConstructorArgumentAsType (CustomAttribute attribute)
+ static TypeDefinition GetFirstConstructorArgumentAsType (CustomAttribute attribute)
{
if (!attribute.HasConstructorArguments)
return null;
@@ -64,13 +67,13 @@ void PopulateCacheForType (TypeDefinition type)
return attribute.ConstructorArguments[0].Value as TypeDefinition;
}
- public MethodDefinition? GetUserDefinedMethodForCompilerGeneratedMember (IMemberDefinition sourceMember)
+ public MethodDefinition GetUserDefinedMethodForCompilerGeneratedMember (IMemberDefinition sourceMember)
{
if (sourceMember == null)
return null;
TypeDefinition compilerGeneratedType = (sourceMember as TypeDefinition) ?? sourceMember.DeclaringType;
- if (_compilerGeneratedTypeToUserCodeMethod.TryGetValue (compilerGeneratedType, out MethodDefinition? userDefinedMethod))
+ if (_compilerGeneratedTypeToUserCodeMethod.TryGetValue (compilerGeneratedType, out MethodDefinition userDefinedMethod))
return userDefinedMethod;
// Only handle async or iterator state machine
diff --git a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/DocumentationSignatureGenerator.PartVisitor.cs b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/DocumentationSignatureGenerator.PartVisitor.cs
index 65211abd93c07..ed4763b75cda8 100644
--- a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/DocumentationSignatureGenerator.PartVisitor.cs
+++ b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/DocumentationSignatureGenerator.PartVisitor.cs
@@ -1,5 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
@@ -146,10 +147,7 @@ public void VisitTypeReference (TypeReference typeReference, StringBuilder build
}
if (typeReference.IsNested) {
- Debug.Assert (typeReference is not SentinelType && typeReference is not PinnedType);
- // GetInflatedDeclaringType may return null for generic parameters, byrefs, and pointers, but these
- // are separately handled above.
- VisitTypeReference (typeReference.GetInflatedDeclaringType (resolver)!, builder, resolver);
+ VisitTypeReference (typeReference.GetInflatedDeclaringType (resolver), builder, resolver);
builder.Append ('.');
}
diff --git a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/DocumentationSignatureParser.cs b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/DocumentationSignatureParser.cs
index 8a6594e47f205..923197f58b6bf 100644
--- a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/DocumentationSignatureParser.cs
+++ b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/DocumentationSignatureParser.cs
@@ -1,5 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#nullable enable
using System;
using System.Collections.Generic;
diff --git a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/MessageContainer.cs b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/MessageContainer.cs
index 69fb968c4ef9c..f0a4afd09b187 100644
--- a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/MessageContainer.cs
+++ b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/MessageContainer.cs
@@ -6,7 +6,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text;
-using ILLink.Shared;
using Mono.Cecil;
namespace Mono.Linker
@@ -55,22 +54,6 @@ internal static MessageContainer CreateErrorMessage (string text, int code, stri
return new MessageContainer (MessageCategory.Error, text, code, subcategory, origin);
}
- ///
- /// Create an error message.
- ///
- /// Filename, line, and column where the error was found
- /// Unique error ID. Please see https://github.com/dotnet/linker/blob/main/docs/error-codes.md
- /// for the list of errors and possibly add a new one
- /// Additional arguments to form a humanly readable message describing the warning
- /// New MessageContainer of 'Error' category
- internal static MessageContainer CreateErrorMessage (MessageOrigin? origin, DiagnosticId id, params string[] args)
- {
- if (!((int) id >= 1000 && (int) id <= 2000))
- throw new ArgumentOutOfRangeException (nameof (id), $"The provided code '{(int) id}' does not fall into the error category, which is in the range of 1000 to 2000 (inclusive).");
-
- return new MessageContainer (MessageCategory.Error, id, origin: origin, args: args);
- }
-
///
/// Create a custom error message.
///
@@ -113,25 +96,6 @@ internal static MessageContainer CreateWarningMessage (LinkContext context, stri
return CreateWarningMessageContainer (context, text, code, origin, version, subcategory);
}
- ///
- /// Create a warning message.
- ///
- /// Context with the relevant warning suppression info.
- /// Filename or member where the warning is coming from
- /// Unique warning ID. Please see https://github.com/dotnet/linker/blob/main/docs/error-codes.md
- /// for the list of warnings and possibly add a new one
- /// Optional warning version number. Versioned warnings can be controlled with the
- /// warning wave option --warn VERSION. Unversioned warnings are unaffected by this option.
- /// Additional arguments to form a humanly readable message describing the warning
- /// New MessageContainer of 'Warning' category
- internal static MessageContainer CreateWarningMessage (LinkContext context, MessageOrigin origin, DiagnosticId id, WarnVersion version, params string[] args)
- {
- if (!((int) id > 2000 && (int) id <= 6000))
- throw new ArgumentOutOfRangeException (nameof (id), $"The provided code '{(int) id}' does not fall into the warning category, which is in the range of 2001 to 6000 (inclusive).");
-
- return CreateWarningMessageContainer (context, origin, id, version, id.GetDiagnosticSubcategory (), args);
- }
-
///
/// Create a custom warning message.
///
@@ -177,26 +141,6 @@ private static MessageContainer CreateWarningMessageContainer (LinkContext conte
return new MessageContainer (MessageCategory.Warning, text, code, subcategory, origin);
}
- private static MessageContainer CreateWarningMessageContainer (LinkContext context, MessageOrigin origin, DiagnosticId id, WarnVersion version, string subcategory, params string[] args)
- {
- if (!(version >= WarnVersion.ILLink0 && version <= WarnVersion.Latest))
- throw new ArgumentException ($"The provided warning version '{version}' is invalid.");
-
- if (context.IsWarningSuppressed ((int) id, origin))
- return Empty;
-
- if (version > context.WarnVersion)
- return Empty;
-
- if (TryLogSingleWarning (context, (int) id, origin, subcategory))
- return Empty;
-
- if (context.IsWarningAsError ((int) id))
- return new MessageContainer (MessageCategory.WarningAsError, id, subcategory, origin, args);
-
- return new MessageContainer (MessageCategory.Warning, id, subcategory, origin, args);
- }
-
public bool IsWarningMessage ([NotNullWhen (true)] out int? code)
{
code = null;
@@ -215,16 +159,15 @@ static bool TryLogSingleWarning (LinkContext context, int code, MessageOrigin or
if (subcategory != MessageSubCategory.TrimAnalysis)
return false;
- // There are valid cases where we can't map the message to an assembly
- // For example if it's caused by something in an xml file passed on the command line
- // In that case, give up on single-warn collapse and just print out the warning on its own.
+ Debug.Assert (origin.Provider != null);
var assembly = origin.Provider switch {
AssemblyDefinition asm => asm,
TypeDefinition type => type.Module.Assembly,
IMemberDefinition member => member.DeclaringType.Module.Assembly,
- _ => null
+ _ => throw new NotSupportedException ()
};
+ Debug.Assert (assembly != null);
if (assembly == null)
return false;
@@ -238,7 +181,7 @@ static bool TryLogSingleWarning (LinkContext context, int code, MessageOrigin or
return false;
if (context.AssembliesWithGeneratedSingleWarning.Add (assemblyName))
- context.LogWarning (context.GetAssemblyLocation (assembly), DiagnosticId.AssemblyProducedTrimWarnings, assemblyName);
+ context.LogWarning ($"Assembly '{assemblyName}' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries", 2104, context.GetAssemblyLocation (assembly));
return true;
}
@@ -272,15 +215,6 @@ private MessageContainer (MessageCategory category, string text, int? code, stri
Text = text;
}
- private MessageContainer (MessageCategory category, DiagnosticId id, string subcategory = MessageSubCategory.None, MessageOrigin? origin = null, params string[] args)
- {
- Code = (int) id;
- Category = category;
- Origin = origin;
- SubCategory = subcategory;
- Text = new DiagnosticString (id).GetMessage (args);
- }
-
public override string ToString () => ToMSBuildString ();
public string ToMSBuildString ()
@@ -322,8 +256,6 @@ public string ToMSBuildString ()
if (Origin?.Provider != null) {
if (Origin?.Provider is MethodDefinition method)
sb.Append (method.GetDisplayName ());
- else if (Origin?.Provider is MemberReference memberRef)
- sb.Append (memberRef.GetDisplayName ());
else if (Origin?.Provider is IMemberDefinition member)
sb.Append (member.FullName);
else if (Origin?.Provider is AssemblyDefinition assembly)
@@ -342,7 +274,7 @@ public string ToMSBuildString ()
public bool Equals (MessageContainer other) =>
(Category, Text, Code, SubCategory, Origin) == (other.Category, other.Text, other.Code, other.SubCategory, other.Origin);
- public override bool Equals (object? obj) => obj is MessageContainer messageContainer && Equals (messageContainer);
+ public override bool Equals (object obj) => obj is MessageContainer messageContainer && Equals (messageContainer);
public override int GetHashCode () => (Category, Text, Code, SubCategory, Origin).GetHashCode ();
public int CompareTo (MessageContainer other)
diff --git a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/MessageOrigin.cs b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/MessageOrigin.cs
index 62de5fb3268fb..84357b26ae221 100644
--- a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/MessageOrigin.cs
+++ b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/MessageOrigin.cs
@@ -12,55 +12,49 @@ namespace Mono.Linker
{
public readonly struct MessageOrigin : IComparable, IEquatable
{
+#nullable enable
public string? FileName { get; }
public ICustomAttributeProvider? Provider { get; }
- readonly ICustomAttributeProvider? _suppressionContextMember;
+ readonly ICustomAttributeProvider _suppressionContextMember;
public ICustomAttributeProvider? SuppressionContextMember {
get {
Debug.Assert (_suppressionContextMember == null || _suppressionContextMember is IMemberDefinition || _suppressionContextMember is AssemblyDefinition);
return _suppressionContextMember ?? Provider;
}
}
-
+#nullable disable
public int SourceLine { get; }
public int SourceColumn { get; }
public int? ILOffset { get; }
const int HiddenLineNumber = 0xfeefee;
- public MessageOrigin (IMemberDefinition? memberDefinition, int? ilOffset = null)
+ public MessageOrigin (IMemberDefinition memberDefinition, int? ilOffset = null)
: this (memberDefinition as ICustomAttributeProvider, ilOffset)
{
}
- public MessageOrigin (ICustomAttributeProvider? provider)
+ public MessageOrigin (ICustomAttributeProvider provider)
: this (provider, null)
{
}
public MessageOrigin (string fileName, int sourceLine = 0, int sourceColumn = 0)
- : this (fileName, sourceLine, sourceColumn, null)
- {
- }
-
- // The assembly attribute should be specified if available as it allows assigning the diagnostic
- // to a an assembly (we group based on assembly).
- public MessageOrigin (string fileName, int sourceLine, int sourceColumn, AssemblyDefinition? assembly)
{
FileName = fileName;
SourceLine = sourceLine;
SourceColumn = sourceColumn;
- Provider = assembly;
+ Provider = null;
_suppressionContextMember = null;
ILOffset = null;
}
- public MessageOrigin (ICustomAttributeProvider? provider, int? ilOffset)
+ public MessageOrigin (ICustomAttributeProvider provider, int? ilOffset)
: this (provider, ilOffset, null)
{
}
- public MessageOrigin (ICustomAttributeProvider? provider, int? ilOffset, ICustomAttributeProvider? suppressionContextMember)
+ public MessageOrigin (ICustomAttributeProvider provider, int? ilOffset, ICustomAttributeProvider suppressionContextMember)
{
Debug.Assert (provider == null || provider is IMemberDefinition || provider is AssemblyDefinition);
Debug.Assert (suppressionContextMember == null || suppressionContextMember is IMemberDefinition || provider is AssemblyDefinition);
@@ -72,7 +66,7 @@ public MessageOrigin (ICustomAttributeProvider? provider, int? ilOffset, ICustom
ILOffset = ilOffset;
}
- public MessageOrigin (MessageOrigin other, IMemberDefinition? suppressionContextMember)
+ public MessageOrigin (MessageOrigin other, IMemberDefinition suppressionContextMember)
{
FileName = other.FileName;
Provider = other.Provider;
@@ -82,21 +76,21 @@ public MessageOrigin (MessageOrigin other, IMemberDefinition? suppressionContext
ILOffset = other.ILOffset;
}
- public override string? ToString ()
+ public override string ToString ()
{
int sourceLine = SourceLine, sourceColumn = SourceColumn;
- string? fileName = FileName;
+ string fileName = FileName;
if (Provider is MethodDefinition method &&
method.DebugInformation.HasSequencePoints) {
var offset = ILOffset ?? 0;
- SequencePoint? correspondingSequencePoint = method.DebugInformation.SequencePoints
+ SequencePoint correspondingSequencePoint = method.DebugInformation.SequencePoints
.Where (s => s.Offset <= offset)?.Last ();
// If the warning comes from hidden line (compiler generated code typically)
// search for any sequence point with non-hidden line number and report that as a best effort.
- if (correspondingSequencePoint?.StartLine == HiddenLineNumber) {
+ if (correspondingSequencePoint.StartLine == HiddenLineNumber) {
correspondingSequencePoint = method.DebugInformation.SequencePoints
- .Where (s => s.StartLine != HiddenLineNumber).FirstOrDefault ();
+ .Where (s => s.StartLine != HiddenLineNumber)?.FirstOrDefault ();
}
if (correspondingSequencePoint != null) {
@@ -124,7 +118,7 @@ public MessageOrigin (MessageOrigin other, IMemberDefinition? suppressionContext
public bool Equals (MessageOrigin other) =>
(FileName, Provider, SourceLine, SourceColumn, ILOffset) == (other.FileName, other.Provider, other.SourceLine, other.SourceColumn, other.ILOffset);
- public override bool Equals (object? obj) => obj is MessageOrigin messageOrigin && Equals (messageOrigin);
+ public override bool Equals (object obj) => obj is MessageOrigin messageOrigin && Equals (messageOrigin);
public override int GetHashCode () => (FileName, Provider, SourceLine, SourceColumn).GetHashCode ();
public static bool operator == (MessageOrigin lhs, MessageOrigin rhs) => lhs.Equals (rhs);
public static bool operator != (MessageOrigin lhs, MessageOrigin rhs) => !lhs.Equals (rhs);
@@ -134,12 +128,12 @@ public int CompareTo (MessageOrigin other)
if (Provider != null && other.Provider != null) {
var thisMember = Provider as IMemberDefinition;
var otherMember = other.Provider as IMemberDefinition;
- TypeDefinition? thisTypeDef = (Provider as TypeDefinition) ?? (Provider as IMemberDefinition)?.DeclaringType;
- TypeDefinition? otherTypeDef = (other.Provider as TypeDefinition) ?? (other.Provider as IMemberDefinition)?.DeclaringType;
+ TypeDefinition thisTypeDef = (Provider as TypeDefinition) ?? (Provider as IMemberDefinition)?.DeclaringType;
+ TypeDefinition otherTypeDef = (other.Provider as TypeDefinition) ?? (other.Provider as IMemberDefinition)?.DeclaringType;
var thisAssembly = thisTypeDef?.Module.Assembly ?? Provider as AssemblyDefinition;
var otherAssembly = otherTypeDef?.Module.Assembly ?? other.Provider as AssemblyDefinition;
- int result = (thisAssembly?.Name.Name, thisTypeDef?.Name, thisMember?.Name).CompareTo
- ((otherAssembly?.Name.Name, otherTypeDef?.Name, otherMember?.Name));
+ int result = (thisAssembly.Name.Name, thisTypeDef?.Name, thisMember?.Name).CompareTo
+ ((otherAssembly.Name.Name, otherTypeDef?.Name, otherMember?.Name));
if (result != 0)
return result;
diff --git a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/README.md b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/README.md
index 4fdfbf1c1fdac..883332600e88d 100644
--- a/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/README.md
+++ b/src/coreclr/tools/Common/Compiler/Logging/ReferenceSource/README.md
@@ -1 +1 @@
-Sources from the dotnet/linker repo at commit 2999a6a9dd884d554be18d3c86a4a9db4b61e156.
+Sources from the dotnet/linker repo at commit c0567db0b9088e2ad4144cd0fe2a985611ec28f0.
diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/ReaderGen.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/ReaderGen.cs
index aa1a796bfaa0f..55b09b37b3431 100644
--- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/ReaderGen.cs
+++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/ReaderGen.cs
@@ -20,7 +20,6 @@ public void EmitSource()
WriteLine("#pragma warning disable 649");
WriteLine("#pragma warning disable 169");
WriteLine("#pragma warning disable 282 // There is no defined ordering between fields in multiple declarations of partial class or struct");
- WriteLine("#pragma warning disable CA1066 // IEquatable implementations aren't used");
WriteLine("#pragma warning disable IDE0059");
WriteLine();
diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs
index bbc23ec878484..1d92be5677148 100644
--- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs
+++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs
@@ -6,7 +6,6 @@
#pragma warning disable 649
#pragma warning disable 169
#pragma warning disable 282 // There is no defined ordering between fields in multiple declarations of partial class or struct
-#pragma warning disable CA1066 // IEquatable implementations aren't used
#pragma warning disable IDE0059
using System;
diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeMetadataReader.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeMetadataReader.cs
index 5b7921f972f97..8eba905400e42 100644
--- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeMetadataReader.cs
+++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeMetadataReader.cs
@@ -1,9 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+
#pragma warning disable 169
-#pragma warning disable 282 // There is no defined ordering between fields in multiple declarations of partial class or struct
-#pragma warning disable CA1066 // IEquatable implementations aren't used
+
+// There is no defined ordering between fields in multiple declarations of partial class or struct
+#pragma warning disable 282
+
using System;
using System.IO;
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
index cd464db795534..30189ccc4cb52 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
@@ -658,7 +658,7 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN
methodInfo->options |= CorInfoOptions.CORINFO_GENERICS_CTXT_FROM_METHODTABLE;
}
methodInfo->regionKind = CorInfoRegionKind.CORINFO_REGION_NONE;
- Get_CORINFO_SIG_INFO(method, sig: &methodInfo->args, methodIL);
+ Get_CORINFO_SIG_INFO(method, sig: &methodInfo->args);
Get_CORINFO_SIG_INFO(methodIL.GetLocals(), &methodInfo->locals);
return true;
@@ -683,9 +683,9 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN
return (CORINFO_CLASS_STRUCT_**)GetPin(jitVisibleInstantiation);
}
- private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, MethodILScope scope, bool suppressHiddenArgument = false)
+ private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false)
{
- Get_CORINFO_SIG_INFO(method.Signature, sig, scope);
+ Get_CORINFO_SIG_INFO(method.Signature, sig);
// Does the method have a hidden parameter?
bool hasHiddenParameter = !suppressHiddenArgument && method.RequiresInstArg();
@@ -845,7 +845,7 @@ private static CorInfoCallConvExtension GetMemberFunctionCallingConventionVarian
var c => c
};
- private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* sig, MethodILScope scope)
+ private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* sig)
{
sig->callConv = (CorInfoCallConv)(signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask);
@@ -875,7 +875,7 @@ private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* s
sig->pSig = null;
sig->cbSig = 0; // Not used by the JIT
sig->methodSignature = ObjectToHandle(signature);
- sig->scope = scope is not null ? ObjectToHandle(scope) : null; // scope can be null for internal calls and COM methods.
+ sig->scope = null;
sig->token = 0; // Not used by the JIT
}
@@ -1149,7 +1149,7 @@ private void getMethodSig(CORINFO_METHOD_STRUCT_* ftn, CORINFO_SIG_INFO* sig, CO
}
}
- Get_CORINFO_SIG_INFO(method, sig: sig, scope: null);
+ Get_CORINFO_SIG_INFO(method, sig: sig);
}
private bool getMethodInfo(CORINFO_METHOD_STRUCT_* ftn, CORINFO_METHOD_INFO* info)
@@ -1795,7 +1795,7 @@ private void findSig(CORINFO_MODULE_STRUCT_* module, uint sigTOK, CORINFO_CONTEX
var methodIL = HandleToObject(module);
var methodSig = (MethodSignature)methodIL.GetObject((int)sigTOK);
- Get_CORINFO_SIG_INFO(methodSig, sig, methodIL);
+ Get_CORINFO_SIG_INFO(methodSig, sig);
#if !READYTORUN
// Check whether we need to report this as a fat pointer call
@@ -1811,7 +1811,7 @@ private void findSig(CORINFO_MODULE_STRUCT_* module, uint sigTOK, CORINFO_CONTEX
private void findCallSiteSig(CORINFO_MODULE_STRUCT_* module, uint methTOK, CORINFO_CONTEXT_STRUCT* context, CORINFO_SIG_INFO* sig)
{
var methodIL = HandleToObject(module);
- Get_CORINFO_SIG_INFO(((MethodDesc)methodIL.GetObject((int)methTOK)), sig: sig, methodIL);
+ Get_CORINFO_SIG_INFO(((MethodDesc)methodIL.GetObject((int)methTOK)), sig: sig);
}
private CORINFO_CLASS_STRUCT_* getTokenTypeAsHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken)
@@ -3745,7 +3745,7 @@ private uint getJitFlags(ref CORJIT_FLAGS flags, uint sizeInBytes)
#if READYTORUN
// TODO: enable this check in full AOT
- if (Marshaller.IsMarshallingRequired(this.MethodBeingCompiled.Signature, Array.Empty(), ((MetadataType)this.MethodBeingCompiled.OwningType).Module)) // Only blittable arguments
+ if (Marshaller.IsMarshallingRequired(this.MethodBeingCompiled.Signature, Array.Empty())) // Only blittable arguments
{
ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramNonBlittableTypes, this.MethodBeingCompiled);
}
diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/gen.bat b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/gen.bat
index 69e3367c4e094..c775755558de9 100644
--- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/gen.bat
+++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/gen.bat
@@ -1,4 +1,4 @@
pushd %~dp0
-call ..\..\..\..\..\..\dotnet.cmd run -- ThunkInput.txt ..\CorInfoBase.cs ..\..\..\aot\jitinterface\jitinterface.h ..\..\..\..\jit\ICorJitInfo_API_names.h ..\..\..\..\jit\ICorJitInfo_API_wrapper.hpp ..\..\..\..\inc\icorjitinfoimpl_generated.h ..\..\..\..\tools\superpmi\superpmi-shim-counter\icorjitinfo.cpp ..\..\..\..\tools\superpmi\superpmi-shim-simple\icorjitinfo.cpp
+call ..\..\..\..\..\..\dotnet.cmd run -- ThunkInput.txt ..\CorInfoBase.cs ..\..\..\aot\jitinterface\jitinterface.h ..\..\..\..\jit\ICorJitInfo_API_names.h ..\..\..\..\jit\ICorJitInfo_API_wrapper.hpp ..\..\..\..\inc\icorjitinfoimpl_generated.h ..\..\..\..\ToolBox\superpmi\superpmi-shim-counter\icorjitinfo.cpp ..\..\..\..\ToolBox\superpmi\superpmi-shim-simple\icorjitinfo.cpp
call ..\..\..\..\..\..\dotnet.cmd run -- InstructionSetGenerator InstructionSetDesc.txt ..\..\Internal\Runtime\ReadyToRunInstructionSet.cs ..\..\Internal\Runtime\ReadyToRunInstructionSetHelper.cs ..\CorInfoInstructionSet.cs ..\..\..\..\inc\corinfoinstructionset.h ..\..\..\..\inc\readytoruninstructionset.h
popd
diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/gen.sh b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/gen.sh
index ca9cdcb52ef11..7dc71bd378d85 100755
--- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/gen.sh
+++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/gen.sh
@@ -1,4 +1,4 @@
#!/usr/bin/env bash
cd "$(dirname ${BASH_SOURCE[0]})"
-../../../../../../dotnet.sh run -- ThunkInput.txt ../CorInfoBase.cs ../../../aot/jitinterface/jitinterface.h ../../../../jit/ICorJitInfo_API_names.h ../../../../jit/ICorJitInfo_API_wrapper.hpp ../../../../inc/icorjitinfoimpl_generated.h ../../../../tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp ../../../../tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp
+../../../../../../dotnet.sh run -- ThunkInput.txt ../CorInfoBase.cs ../../../aot/jitinterface/jitinterface.h ../../../../jit/ICorJitInfo_API_names.h ../../../../jit/ICorJitInfo_API_wrapper.hpp ../../../../inc/icorjitinfoimpl_generated.h ../../../../ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp ../../../../ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
../../../../../../dotnet.sh run -- InstructionSetGenerator InstructionSetDesc.txt ../../Internal/Runtime/ReadyToRunInstructionSet.cs ../../Internal/Runtime/ReadyToRunInstructionSetHelper.cs ../CorInfoInstructionSet.cs ../../../../inc/corinfoinstructionset.h ../../../../inc/readytoruninstructionset.h
diff --git a/src/coreclr/tools/Common/TypeSystem/Common/CastingHelper.cs b/src/coreclr/tools/Common/TypeSystem/Common/CastingHelper.cs
index 03a59a840e1de..1b067af21b476 100644
--- a/src/coreclr/tools/Common/TypeSystem/Common/CastingHelper.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Common/CastingHelper.cs
@@ -263,7 +263,7 @@ private static bool CanCastParamTo(this ParameterizedType thisType, TypeDesc par
else if (curTypesParm.IsGenericParameter)
{
var genericVariableFromParam = (GenericParameterDesc)curTypesParm;
- if (genericVariableFromParam.HasReferenceTypeConstraint || IsConstrainedAsGCPointer(genericVariableFromParam))
+ if (genericVariableFromParam.HasReferenceTypeConstraint)
{
return genericVariableFromParam.CanCastToInternal(paramType, protect);
}
@@ -281,30 +281,6 @@ private static bool CanCastParamTo(this ParameterizedType thisType, TypeDesc par
return false;
}
- private static bool IsConstrainedAsGCPointer(GenericParameterDesc type)
- {
- foreach (var typeConstraint in type.TypeConstraints)
- {
- if (typeConstraint.IsGenericParameter)
- {
- if (IsConstrainedAsGCPointer((GenericParameterDesc)typeConstraint))
- return true;
- }
-
- if (!typeConstraint.IsInterface && typeConstraint.IsGCPointer)
- {
- // Object, ValueType, and Enum are GCPointers but they do not constrain the type to GCPointer!
- if (!typeConstraint.IsWellKnownType(WellKnownType.Object) &&
- !typeConstraint.IsWellKnownType(WellKnownType.ValueType) &&
- !typeConstraint.IsWellKnownType(WellKnownType.Enum))
- {
- return true;
- }
- }
- }
- return false;
- }
-
private static TypeFlags GetNormalizedIntegralArrayElementType(TypeDesc type)
{
Debug.Assert(!type.IsEnum);
@@ -526,7 +502,7 @@ private static bool IsBoxedAndCanCastTo(this TypeDesc thisType, TypeDesc otherTy
else if (thisType.IsGenericParameter)
{
var genericVariableFromParam = (GenericParameterDesc)thisType;
- if (genericVariableFromParam.HasReferenceTypeConstraint || IsConstrainedAsGCPointer(genericVariableFromParam))
+ if (genericVariableFromParam.HasReferenceTypeConstraint)
{
return genericVariableFromParam.CanCastToInternal(otherType, protect);
}
diff --git a/src/coreclr/tools/Common/TypeSystem/Common/DefType.FieldLayout.cs b/src/coreclr/tools/Common/TypeSystem/Common/DefType.FieldLayout.cs
index 2190f9ac1a278..71c7423b8fbb0 100644
--- a/src/coreclr/tools/Common/TypeSystem/Common/DefType.FieldLayout.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Common/DefType.FieldLayout.cs
@@ -63,11 +63,6 @@ private static class FieldLayoutFlags
/// True if type transitively has UnsafeValueTypeAttribute
///
public const int IsUnsafeValueType = 0x200;
-
- ///
- /// True if the type transitively has any types with LayoutKind.Auto in its layout.
- ///
- public const int IsAutoLayoutOrHasAutoLayoutFields = 0x400;
}
private class StaticBlockInfo
@@ -120,21 +115,6 @@ public bool IsUnsafeValueType
}
}
- ///
- /// Does a type have auto-layout or transitively have any fields of a type with auto-layout.
- ///
- public virtual bool IsAutoLayoutOrHasAutoLayoutFields
- {
- get
- {
- if (!_fieldLayoutFlags.HasFlags(FieldLayoutFlags.ComputedInstanceTypeLayout))
- {
- ComputeInstanceLayout(InstanceLayoutKind.TypeAndFields);
- }
- return _fieldLayoutFlags.HasFlags(FieldLayoutFlags.IsAutoLayoutOrHasAutoLayoutFields);
- }
- }
-
///
/// The number of bytes required to hold a field of this type
@@ -426,10 +406,6 @@ public void ComputeInstanceLayout(InstanceLayoutKind layoutKind)
{
_fieldLayoutFlags.AddFlags(FieldLayoutFlags.ComputedInstanceLayoutAbiUnstable);
}
- if (computedLayout.IsAutoLayoutOrHasAutoLayoutFields)
- {
- _fieldLayoutFlags.AddFlags(FieldLayoutFlags.IsAutoLayoutOrHasAutoLayoutFields);
- }
if (computedLayout.Offsets != null)
{
diff --git a/src/coreclr/tools/Common/TypeSystem/Common/FieldLayoutAlgorithm.cs b/src/coreclr/tools/Common/TypeSystem/Common/FieldLayoutAlgorithm.cs
index a19ec4b3603bf..863e857a21def 100644
--- a/src/coreclr/tools/Common/TypeSystem/Common/FieldLayoutAlgorithm.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Common/FieldLayoutAlgorithm.cs
@@ -82,7 +82,6 @@ public struct ComputedInstanceFieldLayout
public LayoutInt ByteCountUnaligned;
public LayoutInt ByteCountAlignment;
public bool LayoutAbiStable; // Is the layout stable such that it can safely be used in function calling conventions
- public bool IsAutoLayoutOrHasAutoLayoutFields;
///
/// If Offsets is non-null, then all field based layout is complete.
diff --git a/src/coreclr/tools/Common/TypeSystem/Common/LayoutInt.cs b/src/coreclr/tools/Common/TypeSystem/Common/LayoutInt.cs
index c794377bf1971..2ec3883af9f08 100644
--- a/src/coreclr/tools/Common/TypeSystem/Common/LayoutInt.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Common/LayoutInt.cs
@@ -12,9 +12,7 @@ namespace Internal.TypeSystem
/// type system do not have a known size. This type is used to make such sizes viral through the type layout
/// computations)
///
-#pragma warning disable CA1066 // IEquatable implementation wouldn't be used
public struct LayoutInt
-#pragma warning restore CA1066
{
private int _value;
diff --git a/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs b/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs
index 637f1f7538ff8..249faef7cd040 100644
--- a/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs
@@ -37,8 +37,12 @@ public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defTyp
TypeDesc fieldType = field.FieldType;
- // ByRef and byref-like instance fields on non-byref-like types are not allowed.
- if ((fieldType.IsByRef || fieldType.IsByRefLike) && !type.IsByRefLike)
+ // ByRef instance fields are not allowed.
+ if (fieldType.IsByRef)
+ ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
+
+ // ByRef-like instance fields on non-byref-like types are not allowed.
+ if (fieldType.IsByRefLike && !type.IsByRefLike)
ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
numInstanceFields++;
@@ -108,8 +112,7 @@ out instanceByteSizeAndAlignment
ByteCountAlignment = instanceByteSizeAndAlignment.Alignment,
FieldAlignment = sizeAndAlignment.Alignment,
FieldSize = sizeAndAlignment.Size,
- LayoutAbiStable = true,
- IsAutoLayoutOrHasAutoLayoutFields = false,
+ LayoutAbiStable = true
};
if (numInstanceFields > 0)
@@ -211,7 +214,7 @@ public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType defTy
}
ref StaticsBlock block = ref GetStaticsBlockForField(ref result, field);
- SizeAndAlignment sizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, hasLayout: false, context.Target.DefaultPackingSize, out bool _, out bool _);
+ SizeAndAlignment sizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, hasLayout: false, context.Target.DefaultPackingSize, out bool _);
block.Size = LayoutInt.AlignUp(block.Size, sizeAndAlignment.Alignment, context.Target);
result.Offsets[index] = new FieldAndOffset(field, block.Size);
@@ -302,16 +305,13 @@ protected ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType ty
var offsets = new FieldAndOffset[numInstanceFields];
int fieldOrdinal = 0;
bool layoutAbiStable = true;
- bool hasAutoLayoutField = false;
foreach (var fieldAndOffset in layoutMetadata.Offsets)
{
TypeDesc fieldType = fieldAndOffset.Field.FieldType;
- var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType.UnderlyingType, hasLayout: true, packingSize, out bool fieldLayoutAbiStable, out bool fieldHasAutoLayout);
+ var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType.UnderlyingType, hasLayout: true, packingSize, out bool fieldLayoutAbiStable);
if (!fieldLayoutAbiStable)
layoutAbiStable = false;
- if (fieldHasAutoLayout)
- hasAutoLayoutField = true;
largestAlignmentRequired = LayoutInt.Max(fieldSizeAndAlignment.Alignment, largestAlignmentRequired);
@@ -354,10 +354,7 @@ protected ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType ty
layoutMetadata.Size,
out instanceByteSizeAndAlignment);
- ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout
- {
- IsAutoLayoutOrHasAutoLayoutFields = hasAutoLayoutField,
- };
+ ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();
computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment;
computedLayout.FieldSize = instanceSizeAndAlignment.Size;
computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
@@ -391,18 +388,15 @@ protected ComputedInstanceFieldLayout ComputeSequentialFieldLayout(MetadataType
int fieldOrdinal = 0;
int packingSize = ComputePackingSize(type, layoutMetadata);
bool layoutAbiStable = true;
- bool hasAutoLayoutField = false;
foreach (var field in type.GetFields())
{
if (field.IsStatic)
continue;
- var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType.UnderlyingType, hasLayout: true, packingSize, out bool fieldLayoutAbiStable, out bool fieldHasAutoLayout);
+ var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType.UnderlyingType, hasLayout: true, packingSize, out bool fieldLayoutAbiStable);
if (!fieldLayoutAbiStable)
layoutAbiStable = false;
- if (fieldHasAutoLayout)
- hasAutoLayoutField = true;
largestAlignmentRequirement = LayoutInt.Max(fieldSizeAndAlignment.Alignment, largestAlignmentRequirement);
@@ -421,10 +415,7 @@ protected ComputedInstanceFieldLayout ComputeSequentialFieldLayout(MetadataType
layoutMetadata.Size,
out instanceByteSizeAndAlignment);
- ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout
- {
- IsAutoLayoutOrHasAutoLayoutFields = hasAutoLayoutField,
- };
+ ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();
computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment;
computedLayout.FieldSize = instanceSizeAndAlignment.Size;
computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
@@ -477,9 +468,9 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
}
else
{
- Debug.Assert(fieldType.IsPrimitive || fieldType.IsPointer || fieldType.IsFunctionPointer || fieldType.IsEnum || fieldType.IsByRef);
+ Debug.Assert(fieldType.IsPrimitive || fieldType.IsPointer || fieldType.IsFunctionPointer || fieldType.IsEnum);
- var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, hasLayout, packingSize, out bool _, out bool _);
+ var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, hasLayout, packingSize, out bool _);
instanceNonGCPointerFieldsCount[CalculateLog2(fieldSizeAndAlignment.Size.AsInt)]++;
}
}
@@ -516,7 +507,7 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
TypeDesc fieldType = field.FieldType;
- var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, hasLayout, packingSize, out bool fieldLayoutAbiStable, out bool _);
+ var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, hasLayout, packingSize, out bool fieldLayoutAbiStable);
if (!fieldLayoutAbiStable)
layoutAbiStable = false;
@@ -655,7 +646,7 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
for (int i = 0; i < instanceValueClassFieldsArr.Length; i++)
{
// Align the cumulative field offset to the indeterminate value
- var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(instanceValueClassFieldsArr[i].FieldType, hasLayout, packingSize, out bool fieldLayoutAbiStable, out bool _);
+ var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(instanceValueClassFieldsArr[i].FieldType, hasLayout, packingSize, out bool fieldLayoutAbiStable);
if (!fieldLayoutAbiStable)
layoutAbiStable = false;
@@ -703,10 +694,7 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
classLayoutSize: 0,
byteCount: out instanceByteSizeAndAlignment);
- ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout
- {
- IsAutoLayoutOrHasAutoLayoutFields = true,
- };
+ ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();
computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment;
computedLayout.FieldSize = instanceSizeAndAlignment.Size;
computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
@@ -719,7 +707,7 @@ protected ComputedInstanceFieldLayout ComputeAutoFieldLayout(MetadataType type,
private static void PlaceInstanceField(FieldDesc field, bool hasLayout, int packingSize, FieldAndOffset[] offsets, ref LayoutInt instanceFieldPos, ref int fieldOrdinal, LayoutInt offsetBias)
{
- var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, hasLayout, packingSize, out bool _, out bool _);
+ var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, hasLayout, packingSize, out bool _);
instanceFieldPos = AlignUpInstanceFieldOffset(field.OwningType, instanceFieldPos, fieldSizeAndAlignment.Alignment, field.Context.Target);
offsets[fieldOrdinal] = new FieldAndOffset(field, instanceFieldPos + offsetBias);
@@ -779,11 +767,10 @@ public LayoutInt CalculateFieldBaseOffset(MetadataType type, bool requiresAlign8
return cumulativeInstanceFieldPos;
}
- private static SizeAndAlignment ComputeFieldSizeAndAlignment(TypeDesc fieldType, bool hasLayout, int packingSize, out bool layoutAbiStable, out bool fieldTypeHasAutoLayout)
+ private static SizeAndAlignment ComputeFieldSizeAndAlignment(TypeDesc fieldType, bool hasLayout, int packingSize, out bool layoutAbiStable)
{
SizeAndAlignment result;
layoutAbiStable = true;
- fieldTypeHasAutoLayout = true;
if (fieldType.IsDefType)
{
@@ -793,7 +780,6 @@ private static SizeAndAlignment ComputeFieldSizeAndAlignment(TypeDesc fieldType,
result.Size = defType.InstanceFieldSize;
result.Alignment = defType.InstanceFieldAlignment;
layoutAbiStable = defType.LayoutAbiStable;
- fieldTypeHasAutoLayout = defType.IsAutoLayoutOrHasAutoLayoutFields;
}
else
{
@@ -811,7 +797,7 @@ private static SizeAndAlignment ComputeFieldSizeAndAlignment(TypeDesc fieldType,
}
else
{
- Debug.Assert(fieldType.IsPointer || fieldType.IsFunctionPointer || fieldType.IsByRef);
+ Debug.Assert(fieldType.IsPointer || fieldType.IsFunctionPointer);
result.Size = fieldType.Context.Target.LayoutPointerSize;
result.Alignment = fieldType.Context.Target.LayoutPointerSize;
}
diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaAssembly.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaAssembly.cs
index 5a281d21ba11a..0e155fda998f3 100644
--- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaAssembly.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaAssembly.cs
@@ -67,7 +67,7 @@ public override string ToString()
public bool HasAssemblyCustomAttribute(string attributeNamespace, string attributeName)
{
- return !_metadataReader.GetCustomAttributeHandle(_assemblyDefinition.GetCustomAttributes(),
+ return _metadataReader.GetCustomAttributeHandle(_assemblyDefinition.GetCustomAttributes(),
attributeNamespace, attributeName).IsNil;
}
}
diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs
index 537b494b0d6f9..48ca23cf1ea26 100644
--- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs
@@ -256,8 +256,7 @@ private TypeDesc ParseTypeImpl(SignatureTypeCode typeCode)
else
return null;
default:
- ThrowHelper.ThrowBadImageFormatException();
- return null;
+ throw new BadImageFormatException();
}
}
diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/PortablePdbSymbolReader.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/PortablePdbSymbolReader.cs
index b270b73ab8d90..5d8d4fd0f4c2b 100644
--- a/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/PortablePdbSymbolReader.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/PortablePdbSymbolReader.cs
@@ -26,7 +26,7 @@ private static unsafe MetadataReader TryOpenMetadataFile(string filePath, Metada
try
{
// Create stream because CreateFromFile(string, ...) uses FileShare.None which is too strict
- fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1);
+ fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
mappedFile = MemoryMappedFile.CreateFromFile(
fileStream, null, fileStream.Length, MemoryMappedFileAccess.Read, HandleInheritability.None, true);
@@ -56,9 +56,12 @@ private static unsafe MetadataReader TryOpenMetadataFile(string filePath, Metada
}
finally
{
- accessor?.Dispose();
- mappedFile?.Dispose();
- fileStream?.Dispose();
+ if (accessor != null)
+ accessor.Dispose();
+ if (mappedFile != null)
+ mappedFile.Dispose();
+ if (fileStream != null)
+ fileStream.Dispose();
}
}
diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Mangling.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Mangling.cs
index dd91b65fa9079..c68f9a10fe2fa 100644
--- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Mangling.cs
+++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Mangling.cs
@@ -20,7 +20,7 @@ string IPrefixMangledSignature.Prefix
{
get
{
- return RuntimeMarshallingEnabled ? "CalliWithRuntimeMarshalling" : "Calli";
+ return "Calli";
}
}
}
diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Sorting.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Sorting.cs
index cd6e620aa8607..89be9fa3a7d88 100644
--- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Sorting.cs
+++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Sorting.cs
@@ -13,11 +13,6 @@ partial class CalliMarshallingMethodThunk
protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
{
var otherMethod = (CalliMarshallingMethodThunk)other;
- int result = RuntimeMarshallingEnabled.CompareTo(otherMethod.RuntimeMarshallingEnabled);
- if (result != 0)
- {
- return result;
- }
return comparer.Compare(_targetSignature, otherMethod._targetSignature);
}
}
diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.cs
index d0d397bafdf38..bdbd7b67998f4 100644
--- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.cs
+++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.cs
@@ -21,13 +21,11 @@ public partial class CalliMarshallingMethodThunk : ILStubMethod
private MethodSignature _signature;
public CalliMarshallingMethodThunk(MethodSignature targetSignature, TypeDesc owningType,
- InteropStateManager interopStateManager,
- bool runtimeMarshallingEnabled)
+ InteropStateManager interopStateManager)
{
_targetSignature = targetSignature;
_owningType = owningType;
_interopStateManager = interopStateManager;
- RuntimeMarshallingEnabled = runtimeMarshallingEnabled;
}
public MethodSignature TargetSignature
@@ -89,8 +87,6 @@ public override string DiagnosticName
}
}
- public bool RuntimeMarshallingEnabled { get; }
-
public override PInvokeMetadata GetPInvokeMethodMetadata()
{
// Return PInvokeAttributes.PreserveSig to circumvent marshalling required checks
diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/DelegateMarshallingMethodThunk.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/DelegateMarshallingMethodThunk.cs
index 5b09863069020..276f7dc4a42fc 100644
--- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/DelegateMarshallingMethodThunk.cs
+++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/DelegateMarshallingMethodThunk.cs
@@ -27,14 +27,6 @@ public partial class DelegateMarshallingMethodThunk : ILStubMethod
private readonly MethodDesc _invokeMethod;
private MethodSignature _signature; // signature of the native callable marshalling stub
- public MethodDesc InvokeMethod
- {
- get
- {
- return _invokeMethod;
- }
- }
-
public DelegateMarshallingMethodThunkKind Kind
{
get;
diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeILEmitter.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeILEmitter.cs
index 81245ffe82515..d77bb5994ec0e 100644
--- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeILEmitter.cs
+++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeILEmitter.cs
@@ -12,6 +12,11 @@ namespace Internal.IL.Stubs
{
///
/// Provides method bodies for PInvoke methods
+ ///
+ /// This by no means intends to provide full PInvoke support. The intended use of this is to
+ /// a) prevent calls getting generated to targets that require a full marshaller
+ /// (this compiler doesn't provide that), and b) offer a hand in some very simple marshalling
+ /// situations (but support for this part might go away as the product matures).
///
public struct PInvokeILEmitter
{
@@ -50,27 +55,23 @@ private static Marshaller[] InitializeMarshallers(MethodDesc targetMethod, Inter
{
MarshalDirection direction = MarshalDirection.Forward;
MethodSignature methodSig;
- bool runtimeMarshallingEnabled;
switch (targetMethod)
{
case DelegateMarshallingMethodThunk delegateMethod:
methodSig = delegateMethod.DelegateSignature;
direction = delegateMethod.Direction;
- runtimeMarshallingEnabled = MarshalHelpers.IsRuntimeMarshallingEnabled(delegateMethod.DelegateType.Module);
break;
case CalliMarshallingMethodThunk calliMethod:
methodSig = calliMethod.TargetSignature;
- runtimeMarshallingEnabled = calliMethod.RuntimeMarshallingEnabled;
break;
default:
methodSig = targetMethod.Signature;
- runtimeMarshallingEnabled = MarshalHelpers.IsRuntimeMarshallingEnabled(((MetadataType)targetMethod.OwningType).Module);
break;
}
int indexOffset = 0;
if (!methodSig.IsStatic && direction == MarshalDirection.Forward)
{
- // For instance methods(eg. Forward delegate marshalling thunk), first argument is
+ // For instance methods(eg. Forward delegate marshalling thunk), first argument is
// the instance
indexOffset = 1;
}
@@ -87,7 +88,7 @@ private static Marshaller[] InitializeMarshallers(MethodDesc targetMethod, Inter
// if we don't have metadata for the parameter, create a dummy one
parameterMetadata = new ParameterMetadata(i, ParameterMetadataAttributes.None, null);
}
- else
+ else
{
Debug.Assert(i == parameterMetadataArray[parameterIndex].Index);
parameterMetadata = parameterMetadataArray[parameterIndex++];
@@ -103,7 +104,7 @@ private static Marshaller[] InitializeMarshallers(MethodDesc targetMethod, Inter
{
// PreserveSig = false can only show up an regular forward PInvokes
Debug.Assert(direction == MarshalDirection.Forward);
-
+
parameterType = methodSig.Context.GetByRefType(parameterType);
isHRSwappedRetVal = true;
}
@@ -113,35 +114,20 @@ private static Marshaller[] InitializeMarshallers(MethodDesc targetMethod, Inter
parameterType = methodSig[i - 1];
}
- if (runtimeMarshallingEnabled)
- {
- marshallers[i] = Marshaller.CreateMarshaller(parameterType,
- parameterIndex,
- methodSig.GetEmbeddedSignatureData(),
- MarshallerType.Argument,
- parameterMetadata.MarshalAsDescriptor,
- direction,
- marshallers,
- interopStateManager,
- indexOffset + parameterMetadata.Index,
- flags,
- parameterMetadata.In,
- isHRSwappedRetVal ? true : parameterMetadata.Out,
- isHRSwappedRetVal ? false : parameterMetadata.Return
- );
- }
- else
- {
- marshallers[i] = Marshaller.CreateDisabledMarshaller(
- parameterType,
- parameterIndex,
- MarshallerType.Argument,
- direction,
- marshallers,
- indexOffset + parameterMetadata.Index,
- flags,
- parameterMetadata.Return);
- }
+ marshallers[i] = Marshaller.CreateMarshaller(parameterType,
+ parameterIndex,
+ methodSig.GetEmbeddedSignatureData(),
+ MarshallerType.Argument,
+ parameterMetadata.MarshalAsDescriptor,
+ direction,
+ marshallers,
+ interopStateManager,
+ indexOffset + parameterMetadata.Index,
+ flags,
+ parameterMetadata.In,
+ isHRSwappedRetVal ? true : parameterMetadata.Out,
+ isHRSwappedRetVal ? false : parameterMetadata.Return
+ );
}
return marshallers;
@@ -160,10 +146,10 @@ private void EmitDelegateCall(DelegateMarshallingMethodThunk delegateMethod, PIn
if (delegateMethod.Kind == DelegateMarshallingMethodThunkKind.ReverseOpenStatic)
{
//
- // For Open static delegates call
+ // For Open static delegates call
// InteropHelpers.GetCurrentCalleeOpenStaticDelegateFunctionPointer()
// which returns a function pointer. Just call the function pointer and we are done.
- //
+ //
TypeDesc[] parameters = new TypeDesc[_marshallers.Length - 1];
for (int i = 1; i < _marshallers.Length; i++)
{
@@ -207,7 +193,7 @@ private void EmitDelegateCall(DelegateMarshallingMethodThunk delegateMethod, PIn
else if (delegateMethod.Kind == DelegateMarshallingMethodThunkKind
.ForwardNativeFunctionWrapper)
{
- // if the SetLastError flag is set in UnmanagedFunctionPointerAttribute, clear the error code before doing P/Invoke
+ // if the SetLastError flag is set in UnmanagedFunctionPointerAttribute, clear the error code before doing P/Invoke
if (_flags.SetLastError)
{
callsiteSetupCodeStream.Emit(ILOpcode.call, emitter.NewToken(
@@ -239,7 +225,7 @@ private void EmitDelegateCall(DelegateMarshallingMethodThunk delegateMethod, PIn
MethodSignatureFlags unmanagedCallingConvention = _flags.UnmanagedCallingConvention;
if (unmanagedCallingConvention == MethodSignatureFlags.None)
unmanagedCallingConvention = MethodSignatureFlags.UnmanagedCallingConvention;
-
+
MethodSignature nativeSig = new MethodSignature(
MethodSignatureFlags.Static | unmanagedCallingConvention, 0, nativeReturnType, nativeParameterTypes);
@@ -271,16 +257,9 @@ private void EmitPInvokeCall(PInvokeILCodeStreams ilCodeStreams)
TypeDesc nativeReturnType = _flags.PreserveSig ? _marshallers[0].NativeParameterType : context.GetWellKnownType(WellKnownType.Int32);
TypeDesc[] nativeParameterTypes = new TypeDesc[isHRSwappedRetVal ? _marshallers.Length : _marshallers.Length - 1];
- bool runtimeMarshallingEnabled = MarshalHelpers.IsRuntimeMarshallingEnabled(((MetadataType)_targetMethod.OwningType).Module);
-
- // if the SetLastError flag is set in DllImport, clear the error code before doing P/Invoke
+ // if the SetLastError flag is set in DllImport, clear the error code before doing P/Invoke
if (_flags.SetLastError)
{
- if (!runtimeMarshallingEnabled)
- {
- // When runtime marshalling is disabled, we don't support SetLastError
- throw new NotSupportedException();
- }
callsiteSetupCodeStream.Emit(ILOpcode.call, emitter.NewToken(
InteropTypes.GetPInvokeMarshal(context).GetKnownMethod("ClearLastError", null)));
}
@@ -292,11 +271,6 @@ private void EmitPInvokeCall(PInvokeILCodeStreams ilCodeStreams)
if (isHRSwappedRetVal)
{
- if (!runtimeMarshallingEnabled)
- {
- // When runtime marshalling is disabled, we don't support HResult-return-swapping
- throw new NotSupportedException();
- }
nativeParameterTypes[_marshallers.Length - 1] = _marshallers[0].NativeParameterType;
}
@@ -390,9 +364,6 @@ private void EmitCalli(PInvokeILCodeStreams ilCodeStreams, CalliMarshallingMetho
private MethodIL EmitIL()
{
- if (_targetMethod.HasCustomAttribute("System.Runtime.InteropServices", "LCIDConversionAttribute"))
- throw new NotSupportedException();
-
PInvokeILCodeStreams pInvokeILCodeStreams = new PInvokeILCodeStreams();
ILEmitter emitter = pInvokeILCodeStreams.Emitter;
ILCodeStream marshallingCodestream = pInvokeILCodeStreams.MarshallingCodeStream;
@@ -446,8 +417,8 @@ private MethodIL EmitIL()
return new PInvokeILStubMethodIL((ILStubMethodIL)emitter.Link(_targetMethod), IsStubRequired());
}
- public static MethodIL EmitIL(MethodDesc method,
- PInvokeILEmitterConfiguration pinvokeILEmitterConfiguration,
+ public static MethodIL EmitIL(MethodDesc method,
+ PInvokeILEmitterConfiguration pinvokeILEmitterConfiguration,
InteropStateManager interopStateManager)
{
try
diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.Aot.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.Aot.cs
index b047f29e9ec64..8925f9964b093 100644
--- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.Aot.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.Aot.cs
@@ -126,7 +126,7 @@ public static MethodIL EmitExceptionBody(string message, MethodDesc method)
TypeSystemContext context = method.Context;
MethodSignature ctorSignature = new MethodSignature(0, 0, context.GetWellKnownType(WellKnownType.Void),
new TypeDesc[] { context.GetWellKnownType(WellKnownType.String) });
- MethodDesc exceptionCtor = InteropTypes.GetMarshalDirectiveException(context).GetKnownMethod(".ctor", ctorSignature);
+ MethodDesc exceptionCtor = method.Context.GetWellKnownType(WellKnownType.Exception).GetKnownMethod(".ctor", ctorSignature);
ILCodeStream codeStream = emitter.NewCodeStream();
codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(message));
diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs
index d37f44971968b..f23a4479634a9 100644
--- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs
@@ -5,7 +5,6 @@
using Internal.IL;
using Debug = System.Diagnostics.Debug;
using Internal.IL.Stubs;
-using Internal.TypeSystem.Ecma;
namespace Internal.TypeSystem.Interop
{
@@ -76,7 +75,6 @@ internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type,
#if !READYTORUN
case MarshallerKind.Struct:
case MarshallerKind.LayoutClass:
- Debug.Assert(interopStateManager is not null, "An InteropStateManager is required to look up the native representation of a non-blittable struct or class with layout.");
return interopStateManager.GetStructMarshallingNativeType((MetadataType)type);
#endif
@@ -95,9 +93,6 @@ internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type,
case MarshallerKind.OleDateTime:
return context.GetWellKnownType(WellKnownType.Double);
- case MarshallerKind.FailedTypeLoad:
- return context.GetWellKnownType(WellKnownType.IntPtr);
-
case MarshallerKind.SafeHandle:
case MarshallerKind.CriticalHandle:
return context.GetWellKnownType(WellKnownType.IntPtr);
@@ -459,7 +454,7 @@ internal static MarshallerKind GetMarshallerKind(
case NativeTypeKind.Array:
{
if (isField)
- return MarshallerKind.FailedTypeLoad;
+ return MarshallerKind.Invalid;
var arrayType = (ArrayType)type;
@@ -586,8 +581,6 @@ internal static MarshallerKind GetMarshallerKind(
}
else if (type.IsObject)
{
- if (nativeType == NativeTypeKind.AsAny && isField)
- return MarshallerKind.FailedTypeLoad;
if (nativeType == NativeTypeKind.AsAny)
return isAnsi ? MarshallerKind.AsAnyA : MarshallerKind.AsAnyW;
else
@@ -851,37 +844,6 @@ private static MarshallerKind GetArrayElementMarshallerKind(
}
}
- internal static MarshallerKind GetDisabledMarshallerKind(
- TypeDesc type)
- {
- if (type.Category == TypeFlags.Void)
- {
- return MarshallerKind.VoidReturn;
- }
- else if (type.IsByRef)
- {
- // Managed refs are not supported when runtime marshalling is disabled.
- return MarshallerKind.Invalid;
- }
- else if (type.IsPrimitive)
- {
- return MarshallerKind.BlittableValue;
- }
- else if (type.IsPointer || type.IsFunctionPointer)
- {
- return MarshallerKind.BlittableValue;
- }
- else if (type.IsValueType)
- {
- var defType = (DefType)type;
- if (!defType.ContainsGCPointers && !defType.IsAutoLayoutOrHasAutoLayoutFields)
- {
- return MarshallerKind.BlittableValue;
- }
- }
- return MarshallerKind.Invalid;
- }
-
internal static bool ShouldCheckForPendingException(TargetDetails target, PInvokeMetadata metadata)
{
if (!target.IsOSX)
@@ -899,10 +861,5 @@ internal static bool ShouldCheckForPendingException(TargetDetails target, PInvok
return metadata.Module.Equals(ObjectiveCLibrary)
&& metadata.Name.StartsWith(ObjectiveCMsgSend);
}
-
- public static bool IsRuntimeMarshallingEnabled(ModuleDesc module)
- {
- return module.Assembly is not EcmaAssembly assembly || !assembly.HasAssemblyCustomAttribute("System.Runtime.CompilerServices", "DisableRuntimeMarshallingAttribute");
- }
}
}
diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs
index 01b2702615238..4244a04ab1810 100644
--- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.Aot.cs
@@ -86,8 +86,6 @@ protected static Marshaller CreateMarshaller(MarshallerKind kind)
return new OleDateTimeMarshaller();
case MarshallerKind.OleCurrency:
return new OleCurrencyMarshaller();
- case MarshallerKind.FailedTypeLoad:
- return new FailedTypeLoadMarshaller();
case MarshallerKind.Variant:
return new VariantMarshaller();
default:
@@ -1075,19 +1073,6 @@ protected override void TransformNativeToManaged(ILCodeStream codeStream)
}
}
- class FailedTypeLoadMarshaller : Marshaller
- {
- protected override void TransformManagedToNative(ILCodeStream codeStream)
- {
- ThrowHelper.ThrowTypeLoadException(ManagedType);
- }
-
- protected override void TransformNativeToManaged(ILCodeStream codeStream)
- {
- ThrowHelper.ThrowTypeLoadException(ManagedType);
- }
- }
-
class VariantMarshaller : Marshaller
{
protected override void AllocManagedToNative(ILCodeStream codeStream)
diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs
index 7b7e3a24d9813..ea0494643a14a 100644
--- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/Marshaller.cs
@@ -329,44 +329,6 @@ public static Marshaller CreateMarshaller(TypeDesc parameterType,
return marshaller;
}
-
- ///
- /// Create a marshaller
- ///
- /// type of the parameter to marshal
- /// The created Marshaller
- public static Marshaller CreateDisabledMarshaller(TypeDesc parameterType,
- int? parameterIndex,
- MarshallerType marshallerType,
- MarshalDirection direction,
- Marshaller[] marshallers,
- int index,
- PInvokeFlags flags,
- bool isReturn)
- {
- MarshallerKind marshallerKind = MarshalHelpers.GetDisabledMarshallerKind(parameterType);
-
- TypeSystemContext context = parameterType.Context;
- // Create the marshaller based on MarshallerKind
- Marshaller marshaller = CreateMarshaller(marshallerKind);
- marshaller.Context = context;
- marshaller.MarshallerKind = marshallerKind;
- marshaller.MarshallerType = marshallerType;
- marshaller.ElementMarshallerKind = MarshallerKind.Unknown;
- marshaller.ManagedParameterType = parameterType;
- marshaller.ManagedType = parameterType;
- marshaller.Return = isReturn;
- marshaller.IsManagedByRef = false;
- marshaller.IsNativeByRef = false;
- marshaller.MarshalDirection = direction;
- marshaller.MarshalAsDescriptor = null;
- marshaller.Marshallers = marshallers;
- marshaller.Index = index;
- marshaller.PInvokeFlags = flags;
- marshaller.In = true;
- marshaller.Out = false;
- return marshaller;
- }
#endregion
@@ -1598,7 +1560,7 @@ protected override void EmitCleanupManaged(ILCodeStream codeStream)
class AnsiStringMarshaller : Marshaller
{
#if READYTORUN
- const int MAX_LOCAL_BUFFER_LENGTH = 260 + 1; // MAX_PATH + 1
+ const int MAX_LOCAL_BUFFER_LENGTH = 260 + 1; // MAX_PATH + 1
private ILLocalVariable? _localBuffer = null;
#endif
@@ -1635,7 +1597,7 @@ protected override void TransformManagedToNative(ILCodeStream codeStream)
.GetKnownMethod("ConvertToNative", null);
bool bPassByValueInOnly = In && !Out && !IsManagedByRef;
-
+
if (bPassByValueInOnly)
{
var bufSize = emitter.NewLocal(Context.GetWellKnownType(WellKnownType.Int32));
@@ -1670,7 +1632,7 @@ protected override void TransformManagedToNative(ILCodeStream codeStream)
codeStream.EmitStLoc(bufSize);
// if (MAX_LOCAL_BUFFER_LENGTH < BufSize ) goto NoOptimize
- codeStream.EmitLdc(MAX_LOCAL_BUFFER_LENGTH + 1);
+ codeStream.EmitLdc(MAX_LOCAL_BUFFER_LENGTH + 1);
codeStream.EmitLdLoc(bufSize);
codeStream.Emit(ILOpcode.clt);
codeStream.Emit(ILOpcode.brtrue, noOptimize);
diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshallerKind.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshallerKind.cs
index 888a174ff38fc..37d09857b694a 100644
--- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshallerKind.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/MarshallerKind.cs
@@ -45,7 +45,6 @@ enum MarshallerKind
LayoutClassPtr,
AsAnyA,
AsAnyW,
- FailedTypeLoad,
ComInterface,
BlittableValueClassWithCopyCtor,
Invalid
diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/InteropStateManager.cs b/src/coreclr/tools/Common/TypeSystem/Interop/InteropStateManager.cs
index 0d594010328e6..202fcce90bece 100644
--- a/src/coreclr/tools/Common/TypeSystem/Interop/InteropStateManager.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Interop/InteropStateManager.cs
@@ -38,7 +38,7 @@ public InteropStateManager(ModuleDesc generatedAssembly)
//
// Delegate Marshalling Stubs
//
-
+
///
/// Generates marshalling stubs for open static delegates
///
@@ -105,9 +105,9 @@ public PInvokeDelegateWrapper GetPInvokeDelegateWrapper(TypeDesc delegateType)
}
//
- // Struct Marshalling
+ // Struct Marshalling
// To support struct marshalling compiler needs to generate a native type which
- // imitates the original struct being passed to managed side with corresponding
+ // imitates the original struct being passed to managed side with corresponding
// fields of marshalled types. Additionally it needs to generate three thunks
// 1. Managed to Native Thunk: For forward marshalling
// 2. Native to Managed Thunk: For reverse marshalling
@@ -186,9 +186,9 @@ public FieldDesc GetPInvokeLazyFixupField(MethodDesc method)
return _pInvokeLazyFixupFieldHashtable.GetOrCreateValue(method);
}
- public MethodDesc GetPInvokeCalliStub(MethodSignature signature, ModuleDesc moduleContext)
+ public MethodDesc GetPInvokeCalliStub(MethodSignature signature)
{
- return _pInvokeCalliHashtable.GetOrCreateValue(new CalliMarshallingMethodThunkKey(signature, MarshalHelpers.IsRuntimeMarshallingEnabled(moduleContext)));
+ return _pInvokeCalliHashtable.GetOrCreateValue(signature);
}
private class NativeStructTypeHashtable : LockFreeReaderHashtable
@@ -355,7 +355,7 @@ protected override bool CompareValueToValue(DelegateMarshallingMethodThunk value
protected override DelegateMarshallingMethodThunk CreateValueFromKey(DelegateMarshallingStubHashtableKey key)
{
- return new DelegateMarshallingMethodThunk(key.DelegateType, _owningType,
+ return new DelegateMarshallingMethodThunk(key.DelegateType, _owningType,
_interopStateManager, key.Kind);
}
@@ -478,36 +478,34 @@ public PInvokeLazyFixupFieldHashtable(DefType owningType)
}
}
- private readonly record struct CalliMarshallingMethodThunkKey(MethodSignature Signature, bool RuntimeMarshallingEnabled);
-
- private class PInvokeCalliHashtable : LockFreeReaderHashtable
+ private class PInvokeCalliHashtable : LockFreeReaderHashtable
{
private readonly InteropStateManager _interopStateManager;
private readonly TypeDesc _owningType;
- protected override int GetKeyHashCode(CalliMarshallingMethodThunkKey key)
+ protected override int GetKeyHashCode(MethodSignature key)
{
return key.GetHashCode();
}
protected override int GetValueHashCode(CalliMarshallingMethodThunk value)
{
- return new CalliMarshallingMethodThunkKey(value.TargetSignature, value.RuntimeMarshallingEnabled).GetHashCode();
+ return value.TargetSignature.GetHashCode();
}
- protected override bool CompareKeyToValue(CalliMarshallingMethodThunkKey key, CalliMarshallingMethodThunk value)
+ protected override bool CompareKeyToValue(MethodSignature key, CalliMarshallingMethodThunk value)
{
- return key.Signature.Equals(value.TargetSignature) && key.RuntimeMarshallingEnabled == value.RuntimeMarshallingEnabled;
+ return key.Equals(value.TargetSignature);
}
protected override bool CompareValueToValue(CalliMarshallingMethodThunk value1, CalliMarshallingMethodThunk value2)
{
- return value1.TargetSignature.Equals(value2.TargetSignature) && value1.RuntimeMarshallingEnabled == value2.RuntimeMarshallingEnabled;
+ return value1.TargetSignature.Equals(value2.TargetSignature);
}
- protected override CalliMarshallingMethodThunk CreateValueFromKey(CalliMarshallingMethodThunkKey key)
+ protected override CalliMarshallingMethodThunk CreateValueFromKey(MethodSignature key)
{
- return new CalliMarshallingMethodThunk(key.Signature, _owningType, _interopStateManager, key.RuntimeMarshallingEnabled);
+ return new CalliMarshallingMethodThunk(key, _owningType, _interopStateManager);
}
public PInvokeCalliHashtable(InteropStateManager interopStateManager, TypeDesc owningType)
diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs b/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs
index ac32fbbe54647..96ffe8868422d 100644
--- a/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Interop/InteropTypes.cs
@@ -54,11 +54,6 @@ public static MetadataType GetNativeFunctionPointerWrapper(TypeSystemContext con
return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "NativeFunctionPointerWrapper");
}
- public static MetadataType GetMarshalDirectiveException(TypeSystemContext context)
- {
- return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "MarshalDirectiveException");
- }
-
public static MetadataType GetVariant(TypeSystemContext context)
{
return context.SystemModule.GetKnownType("System.Runtime.InteropServices", "Variant");
diff --git a/src/coreclr/tools/ILVerification/ILImporter.Verify.cs b/src/coreclr/tools/ILVerification/ILImporter.Verify.cs
index 258a005ffdd09..d1b3d10ed5a3f 100644
--- a/src/coreclr/tools/ILVerification/ILImporter.Verify.cs
+++ b/src/coreclr/tools/ILVerification/ILImporter.Verify.cs
@@ -2060,7 +2060,7 @@ void ImportLoadField(int token, bool isStatic)
actualThis = StackValue.CreateByRef(actualThis.Type);
var declaredThis = owningType.IsValueType ?
- StackValue.CreateByRef(owningType, readOnly : true) : StackValue.CreateObjRef(owningType);
+ StackValue.CreateByRef(owningType) : StackValue.CreateObjRef(owningType);
CheckIsAssignable(actualThis, declaredThis);
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs
index d19b60b104c24..f3f780e87e060 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs
@@ -143,9 +143,8 @@ public virtual ISymbolNode GetFieldRvaData(FieldDesc field)
{
// Use the typical field definition in case this is an instantiated generic type
field = field.GetTypicalFieldDefinition();
- int fieldTypePack = (field.FieldType as MetadataType)?.GetClassLayout().PackingSize ?? 1;
return NodeFactory.ReadOnlyDataBlob(NameMangler.GetMangledFieldName(field),
- ((EcmaField)field).GetFieldRvaData(), Math.Max(NodeFactory.Target.PointerSize, fieldTypePack));
+ ((EcmaField)field).GetFieldRvaData(), NodeFactory.Target.PointerSize);
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs
index 232df5cd22d4e..fb4ad5ce51b7f 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs
@@ -24,7 +24,6 @@ partial class CompilationBuilder
protected bool _methodBodyFolding;
protected InstructionSetSupport _instructionSetSupport;
protected SecurityMitigationOptions _mitigationOptions;
- protected bool _useDwarf5;
partial void InitializePartial()
{
@@ -104,12 +103,6 @@ public CompilationBuilder UseMethodImportationErrorProvider(MethodImportationErr
return this;
}
- public CompilationBuilder UseDwarf5(bool value)
- {
- _useDwarf5 = value;
- return this;
- }
-
protected PreinitializationManager GetPreinitializationManager()
{
if (_preinitializationManager == null)
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/FlowAnnotations.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/FlowAnnotations.cs
index 6e659a95eb7e7..f3585e0e098f0 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/FlowAnnotations.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/FlowAnnotations.cs
@@ -10,8 +10,6 @@
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
-using ILLink.Shared;
-
using Debug = System.Diagnostics.Debug;
namespace ILCompiler.Dataflow
@@ -289,7 +287,9 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
if (!IsTypeInterestingForDataflow(field.FieldType))
{
// Already know that there's a non-empty annotation on a field which is not System.Type/String and we're about to ignore it
- _logger.LogWarning(field, DiagnosticId.DynamicallyAccessedMembersOnFieldCanOnlyApplyToTypesOrStrings, field.GetDisplayName());
+ _logger.LogWarning(
+ $"Field '{field.GetDisplayName()}' has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to fields of type 'System.Type' or 'System.String'.",
+ 2097, field, subcategory: MessageSubCategory.TrimAnalysis);
continue;
}
@@ -341,7 +341,9 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
}
else
{
- _logger.LogWarning(method, DiagnosticId.DynamicallyAccessedMembersIsNotAllowedOnMethods);
+ _logger.LogWarning(
+ $"The 'DynamicallyAccessedMembersAttribute' is not allowed on methods. It is allowed on method return value or method parameters though.",
+ 2041, method, subcategory: MessageSubCategory.TrimAnalysis);
}
}
@@ -360,7 +362,9 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
returnAnnotation = GetMemberTypesForDynamicallyAccessedMembersAttribute(reader, parameter.GetCustomAttributes());
if (returnAnnotation != DynamicallyAccessedMemberTypes.None && !IsTypeInterestingForDataflow(signature.ReturnType))
{
- _logger.LogWarning(method, DiagnosticId.DynamicallyAccessedMembersOnMethodReturnValueCanOnlyApplyToTypesOrStrings, method.GetDisplayName());
+ _logger.LogWarning(
+ $"Return type of method '{method.GetDisplayName()}' has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to parameters of type 'System.Type' or 'System.String'.",
+ 2106, method, subcategory: MessageSubCategory.TrimAnalysis);
}
}
else
@@ -371,7 +375,9 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
if (!IsTypeInterestingForDataflow(signature[parameter.SequenceNumber - 1]))
{
- _logger.LogWarning(method, DiagnosticId.DynamicallyAccessedMembersOnMethodParameterCanOnlyApplyToTypesOrStrings, $"#{parameter.SequenceNumber}", method.GetDisplayName());
+ _logger.LogWarning(
+ $"Parameter #{parameter.SequenceNumber} of method '{method.GetDisplayName()}' has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to parameters of type 'System.Type' or 'System.String'.",
+ 2098, method, subcategory: MessageSubCategory.TrimAnalysis);
continue;
}
@@ -427,7 +433,9 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
if (!IsTypeInterestingForDataflow(property.Signature.ReturnType))
{
- _logger.LogWarning(property, DiagnosticId.DynamicallyAccessedMembersOnPropertyCanOnlyApplyToTypesOrStrings, property.GetDisplayName());
+ _logger.LogWarning(
+ $"Property '{property.GetDisplayName()}' has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to properties of type 'System.Type' or 'System.String'.",
+ 2099, property, subcategory: MessageSubCategory.TrimAnalysis);
continue;
}
@@ -452,7 +460,9 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
if (annotatedMethods.Any(a => a.Method == setMethod))
{
- _logger.LogWarning(setMethod, DiagnosticId.DynamicallyAccessedMembersConflictsBetweenPropertyAndAccessor, property.GetDisplayName(), setMethod.GetDisplayName());
+ _logger.LogWarning(
+ $"'DynamicallyAccessedMembersAttribute' on property '{property.GetDisplayName()}' conflicts with the same attribute on its accessor '{setMethod.GetDisplayName()}'.",
+ 2043, setMethod, subcategory: MessageSubCategory.TrimAnalysis);
}
else
{
@@ -486,7 +496,9 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
if (annotatedMethods.Any(a => a.Method == getMethod))
{
- _logger.LogWarning(getMethod, DiagnosticId.DynamicallyAccessedMembersConflictsBetweenPropertyAndAccessor, property.GetDisplayName(), getMethod.GetDisplayName());
+ _logger.LogWarning(
+ $"'DynamicallyAccessedMembersAttribute' on property '{property.GetDisplayName()}' conflicts with the same attribute on its accessor '{getMethod.GetDisplayName()}'.",
+ 2043, getMethod, subcategory: MessageSubCategory.TrimAnalysis);
}
else
{
@@ -498,7 +510,9 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
if (backingFieldFromGetter != null && backingFieldFromSetter != null &&
backingFieldFromGetter != backingFieldFromSetter)
{
- _logger.LogWarning(property, DiagnosticId.DynamicallyAccessedMembersCouldNotFindBackingField, property.GetDisplayName());
+ _logger.LogWarning(
+ $"Could not find a unique backing field for property '{property.GetDisplayName()}' to propagate 'DynamicallyAccessedMembersAttribute'.",
+ 2042, property, subcategory: MessageSubCategory.TrimAnalysis);
backingField = null;
}
else
@@ -510,7 +524,9 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
{
if (annotatedFields.Any(a => a.Field == backingField))
{
- _logger.LogWarning(backingField, DiagnosticId.DynamicallyAccessedMembersOnPropertyConflictsWithBackingField, property.GetDisplayName(), backingField.GetDisplayName());
+ _logger.LogWarning(
+ $"'DynamicallyAccessedMemberAttribute' on property '{property.GetDisplayName()}' conflicts with the same attribute on its backing field '{backingField.GetDisplayName()}'.",
+ 2056, backingField, subcategory: MessageSubCategory.TrimAnalysis);
}
else
{
@@ -713,23 +729,33 @@ void LogValidationWarning(object provider, object baseProvider, MethodDesc origi
switch (provider)
{
case int parameterNumber:
- _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodParameterBetweenOverrides,
- $"#{parameterNumber}", DiagnosticUtilities.GetMethodSignatureDisplayName(origin),
- $"#{parameterNumber}", DiagnosticUtilities.GetMethodSignatureDisplayName((MethodDesc)baseProvider));
+ _logger.LogWarning(
+ $"'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter #{parameterNumber} of method '{DiagnosticUtilities.GetMethodSignatureDisplayName(origin)}' " +
+ $"don't match overridden parameter #{parameterNumber} of method '{DiagnosticUtilities.GetMethodSignatureDisplayName((MethodDesc)baseProvider)}'. " +
+ $"All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.",
+ 2092, origin, subcategory: MessageSubCategory.TrimAnalysis);
break;
case GenericParameterDesc genericParameterOverride:
- _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersMismatchOnGenericParameterBetweenOverrides,
- genericParameterOverride.Name, DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(new GenericParameterOrigin(genericParameterOverride)),
- ((GenericParameterDesc)baseProvider).Name, DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(new GenericParameterOrigin((GenericParameterDesc)baseProvider)));
+ _logger.LogWarning(
+ $"'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the generic parameter '{genericParameterOverride.Name}' of '{DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(new GenericParameterOrigin(genericParameterOverride))}' " +
+ $"don't match overridden generic parameter '{((GenericParameterDesc)baseProvider).Name}' of '{DiagnosticUtilities.GetGenericParameterDeclaringMemberDisplayName(new GenericParameterOrigin((GenericParameterDesc)baseProvider))}'. " +
+ $"All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.",
+ 2095, origin, subcategory: MessageSubCategory.TrimAnalysis);
break;
case TypeDesc methodReturnType:
- _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersMismatchOnMethodReturnValueBetweenOverrides,
- DiagnosticUtilities.GetMethodSignatureDisplayName(origin), DiagnosticUtilities.GetMethodSignatureDisplayName((MethodDesc)baseProvider));
+ _logger.LogWarning(
+ $"'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the return value of method '{DiagnosticUtilities.GetMethodSignatureDisplayName(origin)}' " +
+ $"don't match overridden return value of method '{DiagnosticUtilities.GetMethodSignatureDisplayName((MethodDesc)baseProvider)}'. " +
+ $"All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.",
+ 2093, origin, subcategory: MessageSubCategory.TrimAnalysis);
break;
// No fields - it's not possible to have a virtual field and override it
case MethodDesc methodDefinition:
- _logger.LogWarning(origin, DiagnosticId.DynamicallyAccessedMembersMismatchOnImplicitThisBetweenOverrides,
- DiagnosticUtilities.GetMethodSignatureDisplayName(methodDefinition), DiagnosticUtilities.GetMethodSignatureDisplayName((MethodDesc)baseProvider));
+ _logger.LogWarning(
+ $"'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the implicit 'this' parameter of method '{DiagnosticUtilities.GetMethodSignatureDisplayName(methodDefinition)}' " +
+ $"don't match overridden implicit 'this' parameter of method '{DiagnosticUtilities.GetMethodSignatureDisplayName((MethodDesc)baseProvider)}'. " +
+ $"All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.",
+ 2094, origin, subcategory: MessageSubCategory.TrimAnalysis);
break;
default:
throw new NotImplementedException($"Unsupported provider type {provider.GetType()}");
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs
index 420dc07dcfa75..06d371cd17aea 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs
@@ -1029,8 +1029,8 @@ public override bool HandleCall(MethodIL callingMethodBody, MethodDesc calledMet
// We don't know what method the `MakeGenericMethod` was called on, so we have to assume
// that the method may have requirements which we can't fullfil -> warn.
reflectionContext.RecordUnrecognizedPattern(
- (int)DiagnosticId.MakeGenericMethod,
- new DiagnosticString(DiagnosticId.MakeGenericMethod).GetMessage(DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
+ (int)DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed,
+ new DiagnosticString(DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed).GetMessage(DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
}
RequireDynamicallyAccessedMembers(
@@ -1048,8 +1048,8 @@ public override bool HandleCall(MethodIL callingMethodBody, MethodDesc calledMet
// We don't know what method the `MakeGenericMethod` was called on, so we have to assume
// that the method may have requirements which we can't fullfil -> warn.
reflectionContext.RecordUnrecognizedPattern(
- (int)DiagnosticId.MakeGenericMethod,
- new DiagnosticString(DiagnosticId.MakeGenericMethod).GetMessage(DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
+ (int)DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed,
+ new DiagnosticString(DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed).GetMessage(DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
}
RequireDynamicallyAccessedMembers(
@@ -2162,8 +2162,8 @@ public override bool HandleCall(MethodIL callingMethodBody, MethodDesc calledMet
// We don't know what method the `MakeGenericMethod` was called on, so we have to assume
// that the method may have requirements which we can't fullfil -> warn.
reflectionContext.RecordUnrecognizedPattern(
- (int)DiagnosticId.MakeGenericMethod,
- new DiagnosticString(DiagnosticId.MakeGenericMethod).GetMessage(
+ (int)DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed,
+ new DiagnosticString(DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed).GetMessage(
DiagnosticUtilities.GetMethodSignatureDisplayName(calledMethod)));
}
}
@@ -2226,8 +2226,9 @@ public override bool HandleCall(MethodIL callingMethodBody, MethodDesc calledMet
{
string arg1 = MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeMessage(calledMethod, "RequiresUnreferencedCodeAttribute"));
string arg2 = MessageFormat.FormatRequiresAttributeUrlArg(DiagnosticUtilities.GetRequiresAttributeUrl(calledMethod, "RequiresUnreferencedCodeAttribute"));
+ string message = new DiagnosticString(DiagnosticId.RequiresUnreferencedCode).GetMessage(calledMethod.GetDisplayName(), arg1, arg2);
- _logger.LogWarning(callingMethodBody, offset, DiagnosticId.RequiresUnreferencedCode, calledMethod.GetDisplayName(), arg1, arg2);
+ _logger.LogWarning(message, (int)DiagnosticId.RequiresUnreferencedCode, callingMethodBody, offset, MessageSubCategory.TrimAnalysis);
}
if (shouldEnableAotWarnings &&
@@ -2240,8 +2241,9 @@ static void LogDynamicCodeWarning(Logger logger, MethodIL callingMethodBody, int
{
string arg1 = MessageFormat.FormatRequiresAttributeMessageArg(DiagnosticUtilities.GetRequiresAttributeMessage(calledMethod, "RequiresDynamicCodeAttribute"));
string arg2 = MessageFormat.FormatRequiresAttributeUrlArg(DiagnosticUtilities.GetRequiresAttributeUrl(calledMethod, "RequiresDynamicCodeAttribute"));
+ string message = new DiagnosticString(DiagnosticId.RequiresDynamicCode).GetMessage(calledMethod.GetDisplayName(), arg1, arg2);
- logger.LogWarning(callingMethodBody, offset, DiagnosticId.RequiresDynamicCode, calledMethod.GetDisplayName(), arg1, arg2);
+ logger.LogWarning(message, (int)DiagnosticId.RequiresDynamicCode, callingMethodBody, offset, MessageSubCategory.AotAnalysis);
}
// To get good reporting of errors we need to track the origin of the value for all method calls
@@ -2931,20 +2933,32 @@ void WarnOnReflectionAccess(ref ReflectionPatternContext context, TypeSystemEnti
// are not suppressed in RUC scopes. Here the scope represents the DynamicallyAccessedMembers
// annotation on a type, not a callsite which uses the annotation. We always want to warn about
// possible reflection access indicated by these annotations.
- _logger.LogWarning(context.Source, DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithDynamicallyAccessedMembers,
- ((TypeOrigin)context.MemberWithRequirements).GetDisplayName(), entity.GetDisplayName());
+
+ var message = string.Format(
+ "'DynamicallyAccessedMembersAttribute' on '{0}' or one of its base types references '{1}' which has 'DynamicallyAccessedMembersAttribute' requirements.",
+ ((TypeOrigin)context.MemberWithRequirements).GetDisplayName(),
+ entity.GetDisplayName());
+ _logger.LogWarning(message, 2115, context.Source, MessageSubCategory.TrimAnalysis);
}
else
{
if (entity is FieldDesc && context.ReportingEnabled)
{
- _logger.LogWarning(context.Source, DiagnosticId.DynamicallyAccessedMembersFieldAccessedViaReflection, entity.GetDisplayName());
+ _logger.LogWarning(
+ $"Field '{entity.GetDisplayName()}' with 'DynamicallyAccessedMembersAttribute' is accessed via reflection. Trimmer can't guarantee availability of the requirements of the field.",
+ 2110,
+ context.Source,
+ MessageSubCategory.TrimAnalysis);
}
else
{
Debug.Assert(entity is MethodDesc);
- _logger.LogWarning(context.Source, DiagnosticId.DynamicallyAccessedMembersMethodAccessedViaReflection, entity.GetDisplayName());
+ _logger.LogWarning(
+ $"Method '{entity.GetDisplayName()}' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.",
+ 2111,
+ context.Source,
+ MessageSubCategory.TrimAnalysis);
}
}
}
@@ -2955,8 +2969,11 @@ void MarkMethod(ref ReflectionPatternContext reflectionContext, MethodDesc metho
{
if (_purpose == ScanningPurpose.GetTypeDataflow)
{
- _logger.LogWarning(reflectionContext.Source, DiagnosticId.DynamicallyAccessedMembersOnTypeReferencesMemberOnBaseWithRequiresUnreferencedCode,
- ((TypeOrigin)reflectionContext.MemberWithRequirements).GetDisplayName(), method.GetDisplayName());
+ var message = string.Format(
+ "'DynamicallyAccessedMembersAttribute' on '{0}' or one of its base types references '{1}' which requires unreferenced code.",
+ ((TypeOrigin)reflectionContext.MemberWithRequirements).GetDisplayName(),
+ method.GetDisplayName());
+ _logger.LogWarning(message, 2113, reflectionContext.Source, MessageSubCategory.TrimAnalysis);
}
}
@@ -3049,8 +3066,8 @@ void ValidateGenericMethodInstantiation(
if (!AnalyzeGenericInstantiationTypeArray(genericParametersArray, ref reflectionContext, reflectionMethod, genericMethod.GetMethodDefinition().Instantiation))
{
reflectionContext.RecordUnrecognizedPattern(
- (int)DiagnosticId.MakeGenericMethod,
- new DiagnosticString(DiagnosticId.MakeGenericMethod).GetMessage(DiagnosticUtilities.GetMethodSignatureDisplayName(reflectionMethod)));
+ (int)DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed,
+ new DiagnosticString(DiagnosticId.MakeGenericMethodCannotBeStaticallyAnalyzed).GetMessage(DiagnosticUtilities.GetMethodSignatureDisplayName(reflectionMethod)));
}
else
{
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionPatternContext.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionPatternContext.cs
index 61a48fe965a0c..99d97784e7811 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionPatternContext.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionPatternContext.cs
@@ -7,8 +7,6 @@
using Internal.IL;
using Internal.TypeSystem;
-using ILLink.Shared;
-
namespace ILCompiler.Dataflow
{
///
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericCompositionNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericCompositionNode.cs
index 9857c633784db..a4388b4eeb4a9 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericCompositionNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericCompositionNode.cs
@@ -36,7 +36,6 @@ public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
if (_details.Variance != null)
{
- sb.Append("__Variance__");
for (int i = 0; i < _details.Variance.Length; i++)
{
sb.Append('_');
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs
index 5462b8fedc11b..e690b5d420078 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs
@@ -85,9 +85,6 @@ public class ObjectWriter : IDisposable, ITypesDebugInfoWriter
[DllImport(NativeObjectWriterFileName)]
private static extern void FinishObjWriter(IntPtr objWriter);
- [DllImport(NativeObjectWriterFileName)]
- private static extern void SetDwarfVersion(IntPtr objWriter, ushort v);
-
[DllImport(NativeObjectWriterFileName)]
private static extern void SwitchSection(IntPtr objWriter, string sectionName, CustomSectionAttributes attributes = 0, string comdatName = null);
@@ -887,11 +884,6 @@ public ObjectWriter(string objectFilePath, NodeFactory factory, ObjectWritingOpt
_isSingleFileCompilation = _nodeFactory.CompilationModuleGroup.IsSingleFileCompilation;
_userDefinedTypeDescriptor = new UserDefinedTypeDescriptor(this, factory);
_options = options;
-
- if ((_options & ObjectWritingOptions.UseDwarf5) != 0)
- {
- SetDwarfVersion(_nativeObjectWriter, 5);
- }
}
public void Dispose()
@@ -1327,6 +1319,5 @@ public enum ObjectWritingOptions
{
GenerateDebugInfo = 0x01,
ControlFlowGuard = 0x02,
- UseDwarf5 = 0x4,
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSettings.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSettings.cs
deleted file mode 100644
index 773c061081e45..0000000000000
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSettings.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Collections.Generic;
-using System.Xml.XPath;
-using ILLink.Shared;
-using Internal.TypeSystem;
-
-namespace ILCompiler
-{
- public static class FeatureSettings
- {
- public static bool ShouldProcessElement(XPathNavigator nav, IReadOnlyDictionary featureSwitchValues)
- {
- var feature = GetAttribute(nav, "feature");
- if (string.IsNullOrEmpty(feature))
- return true;
-
- var value = GetAttribute(nav, "featurevalue");
- if (string.IsNullOrEmpty(value))
- {
- //context.LogError(null, DiagnosticId.XmlFeatureDoesNotSpecifyFeatureValue, documentLocation, feature);
- return false;
- }
-
- if (!bool.TryParse(value, out bool bValue))
- {
- //context.LogError(null, DiagnosticId.XmlUnsupportedNonBooleanValueForFeature, documentLocation, feature);
- return false;
- }
-
- var isDefault = GetAttribute(nav, "featuredefault");
- bool bIsDefault = false;
- if (!string.IsNullOrEmpty(isDefault) && (!bool.TryParse(isDefault, out bIsDefault) || !bIsDefault))
- {
- //context.LogError(null, DiagnosticId.XmlDocumentLocationHasInvalidFeatureDefault, documentLocation);
- return false;
- }
-
- if (!featureSwitchValues.TryGetValue(feature, out bool featureSetting))
- return bIsDefault;
-
- return bValue == featureSetting;
- }
-
- public static string GetAttribute(XPathNavigator nav, string attribute)
- {
- return nav.GetAttribute(attribute, String.Empty);
- }
- }
-}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs
index 20050db2c8cda..5f06913b97d37 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs
@@ -792,7 +792,7 @@ public MethodIL EmitIL(MethodDesc method)
}
}
- private class SubstitutionsReader : ProcessXmlBase
+ private class SubstitutionsReader : ProcessLinkerXmlBase
{
private readonly Dictionary _methodSubstitutions;
private readonly Dictionary _fieldSubstitutions;
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/LazyGenerics/ModuleCycleInfo.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/LazyGenerics/ModuleCycleInfo.cs
index cfbfe6d7a5e47..378af488af020 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/LazyGenerics/ModuleCycleInfo.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/LazyGenerics/ModuleCycleInfo.cs
@@ -8,8 +8,6 @@
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
-using ILLink.Shared;
-
using Debug = System.Diagnostics.Debug;
namespace ILCompiler
@@ -234,9 +232,14 @@ public void LogWarnings(Logger logger)
if (!reportedProblems.Add(new EntityPair(ownerDefinition, referentDefinition)))
continue;
+ string message = $"Generic expansion to '{actualProblem.Key.Referent.GetDisplayName()}' was aborted " +
+ "due to generic recursion. An exception will be thrown at runtime if this codepath is ever reached. " +
+ "Generic recursion also negatively affects compilation speed and the size of the compilation output. " +
+ "It is advisable to remove the source of the generic recursion by restructuring the program around " +
+ "the source of recursion. The source of generic recursion might include: ";
+
ModuleCycleInfo cycleInfo = actualProblem.Value;
bool first = true;
- string message = "";
foreach (TypeSystemEntity cycleEntity in cycleInfo.EntitiesInCycles)
{
if (!first)
@@ -247,7 +250,7 @@ public void LogWarnings(Logger logger)
message += $"'{cycleEntity.GetDisplayName()}'";
}
- logger.LogWarning(actualProblem.Key.Owner, DiagnosticId.GenericRecursionCycle, actualProblem.Key.Referent.GetDisplayName(), message);
+ logger.LogWarning(message, 3054, actualProblem.Key.Owner, MessageSubCategory.AotAnalysis);
}
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ManifestResourceBlockingPolicy.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ManifestResourceBlockingPolicy.cs
index 3b2b3a2e25384..f9df59bfa816f 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ManifestResourceBlockingPolicy.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ManifestResourceBlockingPolicy.cs
@@ -100,7 +100,7 @@ public AssemblyFeatureInfo(EcmaModule module, IReadOnlyDictionary
}
}
- private class SubstitutionsReader : ProcessXmlBase
+ private class SubstitutionsReader : ProcessLinkerXmlBase
{
private readonly HashSet _substitutions = new HashSet();
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs
index e157381162aa5..c5101bde818fa 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs
@@ -1,511 +1,316 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.IO;
-using System.Linq;
using System.Reflection;
-using System.Reflection.Metadata;
using System.Text;
-using System.Text.RegularExpressions;
using System.Xml;
-using System.Xml.Linq;
-using System.Xml.XPath;
-using ILLink.Shared;
-using Internal.TypeSystem;
-#nullable enable
+using Internal.TypeSystem;
namespace ILCompiler
{
- [Flags]
- public enum AllowedAssemblies
+ ///
+ /// Base class for readers of IL Linker XML file format.
+ ///
+ internal abstract class ProcessLinkerXmlBase
{
- ContainingAssembly = 0x1,
- AnyAssembly = 0x2 | ContainingAssembly,
- AllAssemblies = 0x4 | AnyAssembly
- }
-
- public abstract class ProcessLinkerXmlBase
- {
- const string FullNameAttributeName = "fullname";
- const string LinkerElementName = "linker";
- const string TypeElementName = "type";
- const string SignatureAttributeName = "signature";
- const string NameAttributeName = "name";
- const string FieldElementName = "field";
- const string MethodElementName = "method";
- const string EventElementName = "event";
- const string PropertyElementName = "property";
- const string AllAssembliesFullName = "*";
- protected const string XmlNamespace = "";
-
- protected readonly string _xmlDocumentLocation;
- readonly XPathNavigator _document;
- protected readonly ModuleDesc? _owningModule;
+ private readonly XmlReader _reader;
+ private readonly ModuleDesc _owningModule;
private readonly IReadOnlyDictionary _featureSwitchValues;
protected readonly TypeSystemContext _context;
- protected ProcessLinkerXmlBase(TypeSystemContext context, UnmanagedMemoryStream documentStream, string xmlDocumentLocation, IReadOnlyDictionary featureSwitchValues)
+ public ProcessLinkerXmlBase(TypeSystemContext context, XmlReader reader, ModuleDesc owningModule, IReadOnlyDictionary featureSwitchValues)
{
- _context = context;
- using (documentStream)
- {
- _document = XDocument.Load(documentStream, LoadOptions.SetLineInfo).CreateNavigator();
- }
- _xmlDocumentLocation = xmlDocumentLocation;
+ _reader = reader;
+ _owningModule = owningModule;
_featureSwitchValues = featureSwitchValues;
+ _context = context;
}
- protected ProcessLinkerXmlBase(TypeSystemContext context, UnmanagedMemoryStream documentStream, ManifestResource resource, ModuleDesc resourceAssembly, string xmlDocumentLocation, IReadOnlyDictionary featureSwitchValues)
- : this(context, documentStream, xmlDocumentLocation, featureSwitchValues)
- {
- _owningModule = resourceAssembly ?? throw new ArgumentNullException(nameof(resourceAssembly));
- }
-
- protected virtual bool ShouldProcessElement(XPathNavigator nav) => FeatureSettings.ShouldProcessElement(nav, _featureSwitchValues);
-
- protected virtual void ProcessXml(bool ignoreResource)
+ public void ProcessXml()
{
- if (!AllowedAssemblySelector.HasFlag(AllowedAssemblies.AnyAssembly) && _owningModule == null)
- throw new InvalidOperationException("The containing assembly must be specified for XML which is restricted to modifying that assembly only.");
-
- try
+ if (_reader.IsStartElement() && _reader.Name == "linker")
{
- XPathNavigator nav = _document.CreateNavigator();
-
- // Initial structure check - ignore XML document which don't look like linker XML format
- if (!nav.MoveToChild(LinkerElementName, XmlNamespace))
- return;
-
- if (_owningModule != null)
- {
- if (ignoreResource)
- return;
- }
-
- if (!ShouldProcessElement(nav))
+ if (!ShouldProcessElement())
return;
- ProcessAssemblies(nav);
+ _reader.Read();
- // For embedded XML, allow not specifying the assembly explicitly in XML.
- if (_owningModule != null)
- ProcessAssembly(_owningModule, nav, warnOnUnresolvedTypes: true);
-
- }
- catch (Exception ex)
- {
- // throw new LinkerFatalErrorException(MessageContainer.CreateErrorMessage(null, DiagnosticId.ErrorProcessingXmlLocation, _xmlDocumentLocation), ex);
- throw ex;
+ ProcessAssemblies();
}
}
- protected virtual AllowedAssemblies AllowedAssemblySelector { get => _owningModule != null ? AllowedAssemblies.ContainingAssembly : AllowedAssemblies.AnyAssembly; }
-
- bool ShouldProcessAllAssemblies(XPathNavigator nav, [NotNullWhen(false)] out AssemblyName? assemblyName)
+ protected string GetAttribute(string attribute)
{
- assemblyName = null;
- if (GetFullName(nav) == AllAssembliesFullName)
- return true;
+ return _reader.GetAttribute(attribute);
+ }
- assemblyName = GetAssemblyName(nav);
- return false;
+ protected bool IsEmpty()
+ {
+ return _reader.IsEmptyElement;
}
- protected virtual void ProcessAssemblies(XPathNavigator nav)
+ private void ProcessAssemblies()
{
- foreach (XPathNavigator assemblyNav in nav.SelectChildren("assembly", ""))
+ while (_reader.IsStartElement())
{
- // Errors for invalid assembly names should show up even if this element will be
- // skipped due to feature conditions.
- bool processAllAssemblies = ShouldProcessAllAssemblies(assemblyNav, out AssemblyName? name);
- if (processAllAssemblies && AllowedAssemblySelector != AllowedAssemblies.AllAssemblies)
+ if (_reader.Name == "assembly")
{
- //LogWarning(assemblyNav, DiagnosticId.XmlUnsuportedWildcard);
- continue;
- }
+ string assemblyName = _reader.GetAttribute("fullname");
- ModuleDesc? assemblyToProcess = null;
- if (!AllowedAssemblySelector.HasFlag(AllowedAssemblies.AnyAssembly))
- {
- Debug.Assert(!processAllAssemblies);
- Debug.Assert(_owningModule != null);
- if (_owningModule.Assembly.GetName().Name != name!.Name)
+ if (assemblyName == "*")
{
- //LogWarning(assemblyNav, DiagnosticId.AssemblyWithEmbeddedXmlApplyToAnotherAssembly, _resource.Value.Assembly.Name.Name, name.ToString());
+ // https://github.com/dotnet/runtimelab/issues/1381
+ _reader.Skip();
continue;
}
- assemblyToProcess = _owningModule;
- }
- if (!ShouldProcessElement(assemblyNav))
- continue;
+ // Errors for invalid assembly names should show up even if this element will be
+ // skipped due to feature conditions.
+ var name = new AssemblyName(assemblyName);
- if (processAllAssemblies)
- {
- throw new NotImplementedException();
- // We could avoid loading all references in this case: https://github.com/dotnet/linker/issues/1708
- //foreach (ModuleDesc assembly in GetReferencedAssemblies())
- // ProcessAssembly(assembly, assemblyNav, warnOnUnresolvedTypes: false);
- }
- else
- {
- Debug.Assert(!processAllAssemblies);
- ModuleDesc? assembly = assemblyToProcess ?? _context.ResolveAssembly(name!);
-
- if (assembly == null)
+ if (!ShouldProcessElement())
{
- //LogWarning(assemblyNav, DiagnosticId.XmlCouldNotResolveAssembly, name!.Name);
+ _reader.Skip();
continue;
}
- ProcessAssembly(assembly, assemblyNav, warnOnUnresolvedTypes: true);
- }
- }
- }
-
-
- protected abstract void ProcessAssembly(ModuleDesc assembly, XPathNavigator nav, bool warnOnUnresolvedTypes);
+ ModuleDesc assembly = GetAssembly(name);
- protected virtual void ProcessTypes(ModuleDesc assembly, XPathNavigator nav, bool warnOnUnresolvedTypes)
- {
- foreach (XPathNavigator typeNav in nav.SelectChildren(TypeElementName, XmlNamespace))
- {
-
- if (!ShouldProcessElement(typeNav))
- continue;
+ if (assembly == null)
+ {
+ //Context.LogWarning($"Could not resolve assembly '{name.Name}'", 2007, _xmlDocumentLocation);
+ _reader.Skip();
+ continue;
+ }
- string fullname = GetFullName(typeNav);
+ _reader.Read();
- if (fullname.IndexOf("*") != -1)
+ ProcessAssembly(assembly);
+ }
+ else if (_reader.Name == "type")
{
- if (ProcessTypePattern(fullname, assembly, typeNav))
- continue;
+ ProcessType(_owningModule);
}
-
- // TODO: Process exported types
-
- // TODO: Semantics differ and xml format is cecil specific, therefore they are discrepancies on things like nested types
- TypeDesc type = CustomAttributeTypeNameParser.GetTypeByCustomAttributeTypeName(assembly, fullname, throwIfNotFound: false);
-
- if (type == null)
+ else if (_reader.Name == "resource")
{
- //if (warnOnUnresolvedTypes)
- // LogWarning(typeNav, DiagnosticId.XmlCouldNotResolveType, fullname);
- continue;
+ ProcessResource(_owningModule);
+ }
+ else
+ {
+ _reader.Skip();
}
-
- ProcessType(type, typeNav);
}
}
- void MatchType(TypeDesc type, Regex regex, XPathNavigator nav)
+ protected ModuleDesc GetAssembly(AssemblyName name)
{
- StringBuilder sb = new StringBuilder();
- CecilTypeNameFormatter.Instance.AppendName(sb, type);
- if (regex.Match(sb.ToString()).Success)
- ProcessType(type, nav);
+ return _context.ResolveAssembly(name);
}
- protected virtual bool ProcessTypePattern(string fullname, ModuleDesc assembly, XPathNavigator nav)
+ private void ProcessAssembly(ModuleDesc assembly)
{
- Regex regex = new Regex(fullname.Replace(".", @"\.").Replace("*", "(.*)"));
+ while (_reader.IsStartElement())
+ {
+ if (_reader.Name == "type")
+ {
+ ProcessType(assembly);
+ }
+ else if (_reader.Name == "resource")
+ {
+ ProcessResource(assembly);
+ }
- foreach (TypeDesc type in assembly.GetAllTypes())
- MatchType(type, regex, nav);
+ _reader.Skip();
+ }
- return true;
+ _reader.ReadEndElement();
}
- protected abstract void ProcessType(TypeDesc type, XPathNavigator nav);
-
- protected void ProcessTypeChildren(TypeDesc type, XPathNavigator nav, object? customData = null)
+ private void ProcessType(ModuleDesc assembly)
{
- if (nav.HasChildren)
+ if (ShouldProcessElement())
{
- ProcessSelectedFields(nav, type);
- ProcessSelectedMethods(nav, type, customData);
- // TODO: In order to be compatible with the format we need to be able to recognize properties, events and maybe attributes
- }
- }
+ string typeName = _reader.GetAttribute("fullname");
- void ProcessSelectedFields(XPathNavigator nav, TypeDesc type)
- {
- foreach (XPathNavigator fieldNav in nav.SelectChildren(FieldElementName, XmlNamespace))
- {
- if (!ShouldProcessElement(fieldNav))
- continue;
- ProcessField(type, fieldNav);
- }
- }
+ if (typeName.Contains('*'))
+ throw new NotSupportedException();
- protected virtual void ProcessField(TypeDesc type, XPathNavigator nav)
- {
- string signature = GetSignature(nav);
- if (!String.IsNullOrEmpty(signature))
- {
- FieldDesc? field = GetField(type, signature);
- if (field == null)
+ TypeDesc type = CustomAttributeTypeNameParser.GetTypeByCustomAttributeTypeName(assembly, typeName, throwIfNotFound: false);
+ if (type == null)
{
- //LogWarning(nav, DiagnosticId.XmlCouldNotFindFieldOnType, signature, type.GetDisplayName());
+ //Context.LogWarning ($"Could not resolve type '{fullname}'", 2008, _xmlDocumentLocation);
+ _reader.Skip();
return;
}
- ProcessField(type, field, nav);
- }
+ _reader.Read();
- string name = GetName(nav);
- if (!String.IsNullOrEmpty(name))
- {
- bool foundMatch = false;
- foreach (FieldDesc field in type.GetFields())
+ while (_reader.IsStartElement())
{
- if (field.Name == name)
+ if (_reader.Name == "method")
{
- foundMatch = true;
- ProcessField(type, field, nav);
+ ProcessMethod(type);
+ }
+ else if (_reader.Name == "field")
+ {
+ ProcessField(type);
+ }
+ else if (_reader.Name == "attribute")
+ {
+ ProcessAttribute(type);
}
- }
-
- if (!foundMatch)
- {
- // LogWarning(nav, DiagnosticId.XmlCouldNotFindFieldOnType, name, type.GetDisplayName());
+ _reader.Skip();
}
}
- }
-
- protected static FieldDesc? GetField(TypeDesc type, string signature)
- {
- StringBuilder sb = new StringBuilder();
- foreach (FieldDesc field in type.GetFields())
- {
- sb.Clear();
- CecilTypeNameFormatter.Instance.AppendName(sb, field.FieldType);
- if (signature == sb.ToString() + " " + field.Name)
- return field;
- }
-
- return null;
- }
-
- protected virtual void ProcessField(TypeDesc type, FieldDesc field, XPathNavigator nav) { }
- void ProcessSelectedMethods(XPathNavigator nav, TypeDesc type, object? customData)
- {
- foreach (XPathNavigator methodNav in nav.SelectChildren(MethodElementName, XmlNamespace))
- {
- if (!ShouldProcessElement(methodNav))
- continue;
- ProcessMethod(type, methodNav, customData);
- }
+ _reader.Skip();
}
- protected virtual void ProcessMethod(TypeDesc type, XPathNavigator nav, object? customData)
+ private void ProcessMethod(TypeDesc type)
{
- string signature = GetSignature(nav);
- if (!String.IsNullOrEmpty(signature))
+ if (ShouldProcessElement())
{
- MethodDesc? method = GetMethod(type, signature);
- if (method == null)
+ string signature = _reader.GetAttribute("signature");
+ if (!String.IsNullOrEmpty(signature))
{
- //LogWarning(nav, DiagnosticId.XmlCouldNotFindMethodOnType, signature, type.GetDisplayName());
- return;
- }
+ MethodDesc method = GetMethod(type, signature);
+ if (method == null)
+ {
+ //Context.LogWarning($"Could not find method '{signature}' on type '{type.GetDisplayName()}'", 2009, _xmlDocumentLocation);
+ return;
+ }
- ProcessMethod(type, method, nav, customData);
- }
+ ProcessMethod(method);
+ }
- string name = GetAttribute(nav, NameAttributeName);
- if (!String.IsNullOrEmpty(name))
- {
- bool foundMatch = false;
- foreach (MethodDesc method in type.GetAllMethods())
+ string methodName = _reader.GetAttribute("name");
+ if (!String.IsNullOrEmpty(methodName))
{
- if (name == method.Name)
+ bool foundMatch = false;
+ foreach (MethodDesc method in type.GetMethods())
{
- foundMatch = true;
- ProcessMethod(type, method, nav, customData);
+ if (method.Name == methodName)
+ {
+ foundMatch = true;
+ ProcessMethod(method);
+ }
+ }
+
+ if (!foundMatch)
+ {
+ //Context.LogWarning($"Could not find method '{name}' on type '{type.GetDisplayName()}'", 2009, _xmlDocumentLocation);
}
- }
- if (!foundMatch)
- {
- // LogWarning(nav, DiagnosticId.XmlCouldNotFindMethodOnType, name, type.GetDisplayName());
}
}
}
- protected virtual MethodDesc? GetMethod(TypeDesc type, string signature) => null;
-
- protected virtual void ProcessMethod(TypeDesc type, MethodDesc method, XPathNavigator nav, object? customData) { }
-
-#if false
- void ProcessSelectedEvents(XPathNavigator nav, TypeDefinition type, object? customData)
+ protected virtual void ProcessMethod(MethodDesc method)
{
- foreach (XPathNavigator eventNav in nav.SelectChildren(EventElementName, XmlNamespace))
- {
- if (!ShouldProcessElement(eventNav))
- continue;
- ProcessEvent(type, eventNav, customData);
- }
}
- protected virtual void ProcessEvent(TypeDefinition type, XPathNavigator nav, object? customData)
+ private void ProcessField(TypeDesc type)
{
- string signature = GetSignature(nav);
- if (!String.IsNullOrEmpty(signature))
+ if (ShouldProcessElement())
{
- EventDefinition? @event = GetEvent(type, signature);
- if (@event == null)
+ string fieldName = _reader.GetAttribute("name");
+ if (!String.IsNullOrEmpty(fieldName))
{
- LogWarning(nav, DiagnosticId.XmlCouldNotFindEventOnType, signature, type.GetDisplayName());
- return;
- }
+ FieldDesc field = type.GetField(fieldName);
- ProcessEvent(type, @event, nav, customData);
- }
-
- string name = GetAttribute(nav, NameAttributeName);
- if (!String.IsNullOrEmpty(name))
- {
- bool foundMatch = false;
- foreach (EventDefinition @event in type.Events)
- {
- if (@event.Name == name)
+ if (field == null)
{
- foundMatch = true;
- ProcessEvent(type, @event, nav, customData);
+ //Context.LogWarning($"Could not find field '{name}' on type '{type.GetDisplayName()}'", 2012, _xmlDocumentLocation);
+ }
+ else
+ {
+ ProcessField(field);
}
- }
-
- if (!foundMatch)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindEventOnType, name, type.GetDisplayName());
}
}
}
- protected static EventDefinition? GetEvent(TypeDefinition type, string signature)
+ protected virtual void ProcessField(FieldDesc field)
{
- if (!type.HasEvents)
- return null;
-
- foreach (EventDefinition @event in type.Events)
- if (signature == @event.EventType.FullName + " " + @event.Name)
- return @event;
+ }
- return null;
+ protected virtual void ProcessAttribute(TypeDesc type)
+ {
}
- protected virtual void ProcessEvent(TypeDefinition type, EventDefinition @event, XPathNavigator nav, object? customData) { }
+ protected virtual void ProcessResource(ModuleDesc module)
+ {
+ }
- void ProcessSelectedProperties(XPathNavigator nav, TypeDefinition type, object? customData)
+ protected MethodDesc GetMethod(TypeDesc type, string signature)
{
- foreach (XPathNavigator propertyNav in nav.SelectChildren(PropertyElementName, XmlNamespace))
- {
- if (!ShouldProcessElement(propertyNav))
- continue;
- ProcessProperty(type, propertyNav, customData);
- }
+ foreach (MethodDesc meth in type.GetMethods())
+ if (signature == GetMethodSignature(meth, false))
+ return meth;
+
+ return null;
}
- protected virtual void ProcessProperty(TypeDefinition type, XPathNavigator nav, object? customData)
+ public static string GetMethodSignature(MethodDesc meth, bool includeGenericParameters)
{
- string signature = GetSignature(nav);
- if (!String.IsNullOrEmpty(signature))
+ StringBuilder sb = new StringBuilder();
+ CecilTypeNameFormatter.Instance.AppendName(sb, meth.Signature.ReturnType);
+ sb.Append(' ');
+ sb.Append(meth.Name);
+ if (includeGenericParameters && meth.HasInstantiation)
{
- PropertyDefinition? property = GetProperty(type, signature);
- if (property == null)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindPropertyOnType, signature, type.GetDisplayName());
- return;
- }
-
- ProcessProperty(type, property, nav, customData, true);
+ sb.Append('`');
+ sb.Append(meth.Instantiation.Length);
}
- string name = GetAttribute(nav, NameAttributeName);
- if (!String.IsNullOrEmpty(name))
+ sb.Append('(');
+ for (int i = 0; i < meth.Signature.Length; i++)
{
- bool foundMatch = false;
- foreach (PropertyDefinition property in type.Properties)
- {
- if (property.Name == name)
- {
- foundMatch = true;
- ProcessProperty(type, property, nav, customData, false);
- }
- }
+ if (i > 0)
+ sb.Append(',');
- if (!foundMatch)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindPropertyOnType, name, type.GetDisplayName());
- }
+ CecilTypeNameFormatter.Instance.AppendName(sb, meth.Signature[i]);
}
- }
-
- protected static PropertyDefinition? GetProperty(TypeDefinition type, string signature)
- {
- if (!type.HasProperties)
- return null;
-
- foreach (PropertyDefinition property in type.Properties)
- if (signature == property.PropertyType.FullName + " " + property.Name)
- return property;
- return null;
- }
-
- protected virtual void ProcessProperty(TypeDefinition type, PropertyDefinition property, XPathNavigator nav, object? customData, bool fromSignature) { }
-#endif
-
- protected virtual AssemblyName GetAssemblyName(XPathNavigator nav)
- {
- return new AssemblyName(GetFullName(nav));
+ sb.Append(')');
+ return sb.ToString();
}
- protected static string GetFullName(XPathNavigator nav)
+ private bool ShouldProcessElement()
{
- return GetAttribute(nav, FullNameAttributeName);
- }
+ string feature = _reader.GetAttribute("feature");
+ if (string.IsNullOrEmpty(feature))
+ return true;
- protected static string GetName(XPathNavigator nav)
- {
- return GetAttribute(nav, NameAttributeName);
- }
+ string value = _reader.GetAttribute("featurevalue");
+ if (string.IsNullOrEmpty(value))
+ {
+ //context.LogError($"Failed to process '{documentLocation}'. Feature '{feature}' does not specify a 'featurevalue' attribute", 1001);
+ return false;
+ }
- protected static string GetSignature(XPathNavigator nav)
- {
- return GetAttribute(nav, SignatureAttributeName);
- }
+ if (!bool.TryParse(value, out bool bValue))
+ {
+ //context.LogError($"Failed to process '{documentLocation}'. Unsupported non-boolean feature definition '{feature}'", 1002);
+ return false;
+ }
- protected static string GetAttribute(XPathNavigator nav, string attribute)
- {
- return nav.GetAttribute(attribute, XmlNamespace);
- }
+ var isDefault = _reader.GetAttribute("featuredefault");
+ bool bIsDefault = false;
+ if (!string.IsNullOrEmpty(isDefault) && (!bool.TryParse(isDefault, out bIsDefault) || !bIsDefault))
+ {
+ //context.LogError($"Failed to process '{documentLocation}'. Unsupported value for featuredefault attribute", 1014);
+ return false;
+ }
-#if false
- protected MessageOrigin GetMessageOriginForPosition(XPathNavigator position)
- {
- return (position is IXmlLineInfo lineInfo)
- ? new MessageOrigin(_xmlDocumentLocation, lineInfo.LineNumber, lineInfo.LinePosition, _resource?.Assembly)
- : new MessageOrigin(_xmlDocumentLocation, 0, 0, _resource?.Assembly);
- }
- protected void LogWarning(string message, int warningCode, XPathNavigator position)
- {
- _context.LogWarning(message, warningCode, GetMessageOriginForPosition(position));
- }
+ if (!_featureSwitchValues.TryGetValue(feature, out bool featureSetting))
+ return bIsDefault;
- protected void LogWarning(XPathNavigator position, DiagnosticId id, params string[] args)
- {
- _context.LogWarning(GetMessageOriginForPosition(position), id, args);
+ return bValue == featureSetting;
}
-#endif
class CecilTypeNameFormatter : TypeNameFormatter
{
@@ -594,106 +399,6 @@ protected override void AppendNameForNestedType(StringBuilder sb, DefType nested
sb.Append('/');
sb.Append(nestedType.Name);
}
-
-#if false
- public bool TryConvertValue(string value, TypeDesc type, out object? result)
- {
- switch (type.UnderlyingType.Category)
- {
- case TypeFlags.Boolean:
- if ((bool.TryParse(value, out bool bvalue)))
- {
- result = bvalue ? 1 : 0;
- return true;
- }
- else
- goto case TypeFlags.Int32;
-
- case TypeFlags.Byte:
- if (!byte.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out byte byteresult))
- break;
-
- result = (int)byteresult;
- return true;
-
- case TypeFlags.SByte:
- if (!sbyte.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out sbyte sbyteresult))
- break;
-
- result = (int)sbyteresult;
- return true;
-
- case TypeFlags.Int16:
- if (!short.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out short shortresult))
- break;
-
- result = (int)shortresult;
- return true;
-
- case TypeFlags.UInt16:
- if (!ushort.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out ushort ushortresult))
- break;
-
- result = (int)ushortresult;
- return true;
-
- case TypeFlags.Int32:
- if (!int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int iresult))
- break;
-
- result = iresult;
- return true;
-
- case TypeFlags.UInt32:
- if (!uint.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out uint uresult))
- break;
-
- result = (int)uresult;
- return true;
-
- case TypeFlags.Double:
- if (!double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out double dresult))
- break;
-
- result = dresult;
- return true;
-
- case TypeFlags.Single:
- if (!float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out float fresult))
- break;
-
- result = fresult;
- return true;
-
- case TypeFlags.Int64:
- if (!long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long lresult))
- break;
-
- result = lresult;
- return true;
-
- case TypeFlags.UInt64:
- if (!ulong.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out ulong ulresult))
- break;
-
- result = (long)ulresult;
- return true;
-
- case TypeFlags.Char:
- if (!char.TryParse(value, out char chresult))
- break;
-
- result = (int)chresult;
- return true;
-
- default:
- throw new NotSupportedException(type.ToString());
- }
-
- result = null;
- return false;
- }
-#endif
}
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessXmlBase.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessXmlBase.cs
deleted file mode 100644
index b00f56a0c2ce4..0000000000000
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessXmlBase.cs
+++ /dev/null
@@ -1,404 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Text;
-using System.Xml;
-
-using Internal.TypeSystem;
-
-namespace ILCompiler
-{
- ///
- /// Base class for readers of IL Linker XML file format.
- ///
- internal abstract class ProcessXmlBase
- {
- private readonly XmlReader _reader;
- private readonly ModuleDesc _owningModule;
- private readonly IReadOnlyDictionary _featureSwitchValues;
- protected readonly TypeSystemContext _context;
-
- public ProcessXmlBase(TypeSystemContext context, XmlReader reader, ModuleDesc owningModule, IReadOnlyDictionary featureSwitchValues)
- {
- _reader = reader;
- _owningModule = owningModule;
- _featureSwitchValues = featureSwitchValues;
- _context = context;
- }
-
- public void ProcessXml()
- {
- if (_reader.IsStartElement() && _reader.Name == "linker")
- {
- if (!ShouldProcessElement())
- return;
-
- _reader.Read();
-
- ProcessAssemblies();
- }
- }
-
- protected string GetAttribute(string attribute)
- {
- return _reader.GetAttribute(attribute);
- }
-
- protected bool IsEmpty()
- {
- return _reader.IsEmptyElement;
- }
-
- private void ProcessAssemblies()
- {
- while (_reader.IsStartElement())
- {
- if (_reader.Name == "assembly")
- {
- string assemblyName = _reader.GetAttribute("fullname");
-
- if (assemblyName == "*")
- {
- // https://github.com/dotnet/runtimelab/issues/1381
- _reader.Skip();
- continue;
- }
-
- // Errors for invalid assembly names should show up even if this element will be
- // skipped due to feature conditions.
- var name = new AssemblyName(assemblyName);
-
- if (!ShouldProcessElement())
- {
- _reader.Skip();
- continue;
- }
-
- ModuleDesc assembly = GetAssembly(name);
-
- if (assembly == null)
- {
- //Context.LogWarning($"Could not resolve assembly '{name.Name}'", 2007, _xmlDocumentLocation);
- _reader.Skip();
- continue;
- }
-
- _reader.Read();
-
- ProcessAssembly(assembly);
- }
- else if (_reader.Name == "type")
- {
- ProcessType(_owningModule);
- }
- else if (_reader.Name == "resource")
- {
- ProcessResource(_owningModule);
- }
- else
- {
- _reader.Skip();
- }
- }
- }
-
- protected ModuleDesc GetAssembly(AssemblyName name)
- {
- return _context.ResolveAssembly(name);
- }
-
- private void ProcessAssembly(ModuleDesc assembly)
- {
- while (_reader.IsStartElement())
- {
- if (_reader.Name == "type")
- {
- ProcessType(assembly);
- }
- else if (_reader.Name == "resource")
- {
- ProcessResource(assembly);
- }
-
- _reader.Skip();
- }
-
- _reader.ReadEndElement();
- }
-
- private void ProcessType(ModuleDesc assembly)
- {
- if (ShouldProcessElement())
- {
- string typeName = _reader.GetAttribute("fullname");
-
- if (typeName.Contains('*'))
- throw new NotSupportedException();
-
- TypeDesc type = CustomAttributeTypeNameParser.GetTypeByCustomAttributeTypeName(assembly, typeName, throwIfNotFound: false);
- if (type == null)
- {
- //Context.LogWarning ($"Could not resolve type '{fullname}'", 2008, _xmlDocumentLocation);
- _reader.Skip();
- return;
- }
-
- _reader.Read();
-
- while (_reader.IsStartElement())
- {
- if (_reader.Name == "method")
- {
- ProcessMethod(type);
- }
- else if (_reader.Name == "field")
- {
- ProcessField(type);
- }
- else if (_reader.Name == "attribute")
- {
- ProcessAttribute(type);
- }
-
- _reader.Skip();
- }
- }
-
- _reader.Skip();
- }
-
- private void ProcessMethod(TypeDesc type)
- {
- if (ShouldProcessElement())
- {
- string signature = _reader.GetAttribute("signature");
- if (!String.IsNullOrEmpty(signature))
- {
- MethodDesc method = GetMethod(type, signature);
- if (method == null)
- {
- //Context.LogWarning($"Could not find method '{signature}' on type '{type.GetDisplayName()}'", 2009, _xmlDocumentLocation);
- return;
- }
-
- ProcessMethod(method);
- }
-
- string methodName = _reader.GetAttribute("name");
- if (!String.IsNullOrEmpty(methodName))
- {
- bool foundMatch = false;
- foreach (MethodDesc method in type.GetMethods())
- {
- if (method.Name == methodName)
- {
- foundMatch = true;
- ProcessMethod(method);
- }
- }
-
- if (!foundMatch)
- {
- //Context.LogWarning($"Could not find method '{name}' on type '{type.GetDisplayName()}'", 2009, _xmlDocumentLocation);
- }
- }
- }
- }
-
- protected virtual void ProcessMethod(MethodDesc method)
- {
- }
-
- private void ProcessField(TypeDesc type)
- {
- if (ShouldProcessElement())
- {
- string fieldName = _reader.GetAttribute("name");
- if (!String.IsNullOrEmpty(fieldName))
- {
- FieldDesc field = type.GetField(fieldName);
-
- if (field == null)
- {
- //Context.LogWarning($"Could not find field '{name}' on type '{type.GetDisplayName()}'", 2012, _xmlDocumentLocation);
- }
- else
- {
- ProcessField(field);
- }
- }
- }
- }
-
- protected virtual void ProcessField(FieldDesc field)
- {
- }
-
- protected virtual void ProcessAttribute(TypeDesc type)
- {
- }
-
- protected virtual void ProcessResource(ModuleDesc module)
- {
- }
-
- protected MethodDesc GetMethod(TypeDesc type, string signature)
- {
- foreach (MethodDesc meth in type.GetMethods())
- if (signature == GetMethodSignature(meth, false))
- return meth;
-
- return null;
- }
-
- public static string GetMethodSignature(MethodDesc meth, bool includeGenericParameters)
- {
- StringBuilder sb = new StringBuilder();
- CecilTypeNameFormatter.Instance.AppendName(sb, meth.Signature.ReturnType);
- sb.Append(' ');
- sb.Append(meth.Name);
- if (includeGenericParameters && meth.HasInstantiation)
- {
- sb.Append('`');
- sb.Append(meth.Instantiation.Length);
- }
-
- sb.Append('(');
- for (int i = 0; i < meth.Signature.Length; i++)
- {
- if (i > 0)
- sb.Append(',');
-
- CecilTypeNameFormatter.Instance.AppendName(sb, meth.Signature[i]);
- }
-
- sb.Append(')');
- return sb.ToString();
- }
-
- private bool ShouldProcessElement()
- {
- string feature = _reader.GetAttribute("feature");
- if (string.IsNullOrEmpty(feature))
- return true;
-
- string value = _reader.GetAttribute("featurevalue");
- if (string.IsNullOrEmpty(value))
- {
- //context.LogError($"Failed to process '{documentLocation}'. Feature '{feature}' does not specify a 'featurevalue' attribute", 1001);
- return false;
- }
-
- if (!bool.TryParse(value, out bool bValue))
- {
- //context.LogError($"Failed to process '{documentLocation}'. Unsupported non-boolean feature definition '{feature}'", 1002);
- return false;
- }
-
- var isDefault = _reader.GetAttribute("featuredefault");
- bool bIsDefault = false;
- if (!string.IsNullOrEmpty(isDefault) && (!bool.TryParse(isDefault, out bIsDefault) || !bIsDefault))
- {
- //context.LogError($"Failed to process '{documentLocation}'. Unsupported value for featuredefault attribute", 1014);
- return false;
- }
-
- if (!_featureSwitchValues.TryGetValue(feature, out bool featureSetting))
- return bIsDefault;
-
- return bValue == featureSetting;
- }
-
- class CecilTypeNameFormatter : TypeNameFormatter
- {
- public static readonly CecilTypeNameFormatter Instance = new CecilTypeNameFormatter();
-
- public override void AppendName(StringBuilder sb, ArrayType type)
- {
- AppendName(sb, type.ElementType);
- sb.Append('[');
- if (type.Rank > 1)
- sb.Append(new string(',', type.Rank - 1));
- sb.Append(']');
- }
- public override void AppendName(StringBuilder sb, ByRefType type)
- {
- AppendName(sb, type.ParameterType);
- sb.Append('&');
- }
-
- public override void AppendName(StringBuilder sb, PointerType type)
- {
- AppendName(sb, type.ParameterType);
- sb.Append('*');
- }
-
- public override void AppendName(StringBuilder sb, FunctionPointerType type)
- {
- sb.Append(" ");
- AppendName(sb, type.Signature.ReturnType);
- sb.Append(" *");
-
- sb.Append("(");
-
- for (int i = 0; i < type.Signature.Length; i++)
- {
- var parameter = type.Signature[i];
- if (i > 0)
- sb.Append(",");
-
- AppendName(sb, parameter);
- }
-
- sb.Append(")");
- }
-
- public override void AppendName(StringBuilder sb, GenericParameterDesc type)
- {
- sb.Append(type.Name);
- }
- public override void AppendName(StringBuilder sb, SignatureMethodVariable type)
- {
- }
- public override void AppendName(StringBuilder sb, SignatureTypeVariable type)
- {
- }
- protected override void AppendNameForInstantiatedType(StringBuilder sb, DefType type)
- {
- AppendName(sb, type.GetTypeDefinition());
-
- sb.Append('<');
-
- for (int i = 0; i < type.Instantiation.Length; i++)
- {
- if (i != 0)
- sb.Append(',');
-
- AppendName(sb, type.Instantiation[i]);
- }
-
- sb.Append('>');
- }
- protected override void AppendNameForNamespaceType(StringBuilder sb, DefType type)
- {
- if (!String.IsNullOrEmpty(type.Namespace))
- {
- sb.Append(type.Namespace);
- sb.Append('.');
- }
-
- sb.Append(type.Name);
- }
-
- protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType)
- {
- AppendName(sb, containingType);
- sb.Append('/');
- sb.Append(nestedType.Name);
- }
- }
- }
-}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/BodySubstitutionParser.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/BodySubstitutionParser.cs
deleted file mode 100644
index 403eb9207342e..0000000000000
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/BodySubstitutionParser.cs
+++ /dev/null
@@ -1,174 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Xml.XPath;
-using ILLink.Shared;
-using Mono.Cecil;
-
-namespace Mono.Linker.Steps
-{
- public class BodySubstitutionParser : ProcessLinkerXmlBase
- {
- SubstitutionInfo? _substitutionInfo;
-
- public BodySubstitutionParser(LinkContext context, Stream documentStream, string xmlDocumentLocation)
- : base(context, documentStream, xmlDocumentLocation)
- {
- }
-
- public BodySubstitutionParser(LinkContext context, Stream documentStream, EmbeddedResource resource, AssemblyDefinition resourceAssembly, string xmlDocumentLocation = "")
- : base(context, documentStream, resource, resourceAssembly, xmlDocumentLocation)
- {
- }
-
- public void Parse(SubstitutionInfo xmlInfo)
- {
- _substitutionInfo = xmlInfo;
- bool stripSubstitutions = _context.IsOptimizationEnabled(CodeOptimizations.RemoveSubstitutions, _resource?.Assembly);
- ProcessXml(stripSubstitutions, _context.IgnoreSubstitutions);
- }
-
- protected override void ProcessAssembly(AssemblyDefinition assembly, XPathNavigator nav, bool warnOnUnresolvedTypes)
- {
- ProcessTypes(assembly, nav, warnOnUnresolvedTypes);
- ProcessResources(assembly, nav);
- }
-
- protected override TypeDefinition? ProcessExportedType(ExportedType exported, AssemblyDefinition assembly, XPathNavigator nav) => null;
-
- protected override bool ProcessTypePattern(string fullname, AssemblyDefinition assembly, XPathNavigator nav) => false;
-
- protected override void ProcessType(TypeDefinition type, XPathNavigator nav)
- {
- Debug.Assert(ShouldProcessElement(nav));
- ProcessTypeChildren(type, nav);
- }
-
- protected override void ProcessMethod(TypeDefinition type, XPathNavigator methodNav, object? _customData)
- {
- Debug.Assert(_substitutionInfo != null);
- string signature = GetSignature(methodNav);
- if (string.IsNullOrEmpty(signature))
- return;
-
- MethodDefinition? method = FindMethod(type, signature);
- if (method == null)
- {
- LogWarning(methodNav, DiagnosticId.XmlCouldNotFindMethodOnType, signature, type.GetDisplayName());
- return;
- }
-
- string action = GetAttribute(methodNav, "body");
- switch (action)
- {
- case "remove":
- _substitutionInfo.SetMethodAction(method, MethodAction.ConvertToThrow);
- return;
- case "stub":
- string value = GetAttribute(methodNav, "value");
- if (!string.IsNullOrEmpty(value))
- {
- if (!TryConvertValue(value, method.ReturnType, out object? res))
- {
- LogWarning(methodNav, DiagnosticId.XmlInvalidValueForStub, method.GetDisplayName());
- return;
- }
-
- _substitutionInfo.SetMethodStubValue(method, res);
- }
-
- _substitutionInfo.SetMethodAction(method, MethodAction.ConvertToStub);
- return;
- default:
- LogWarning(methodNav, DiagnosticId.XmlUnkownBodyModification, action, method.GetDisplayName());
- return;
- }
- }
-
- protected override void ProcessField(TypeDefinition type, XPathNavigator fieldNav)
- {
- Debug.Assert(_substitutionInfo != null);
- string name = GetAttribute(fieldNav, "name");
- if (string.IsNullOrEmpty(name))
- return;
-
- var field = type.Fields.FirstOrDefault(f => f.Name == name);
- if (field == null)
- {
- LogWarning(fieldNav, DiagnosticId.XmlCouldNotFindFieldOnType, name, type.GetDisplayName());
- return;
- }
-
- if (!field.IsStatic || field.IsLiteral)
- {
- LogWarning(fieldNav, DiagnosticId.XmlSubstitutedFieldNeedsToBeStatic, field.GetDisplayName());
- return;
- }
-
- string value = GetAttribute(fieldNav, "value");
- if (string.IsNullOrEmpty(value))
- {
- LogWarning(fieldNav, DiagnosticId.XmlMissingSubstitutionValueForField, field.GetDisplayName());
- return;
- }
- if (!TryConvertValue(value, field.FieldType, out object? res))
- {
- LogWarning(fieldNav, DiagnosticId.XmlInvalidSubstitutionValueForField, value, field.GetDisplayName());
- return;
- }
-
- _substitutionInfo.SetFieldValue(field, res);
-
- string init = GetAttribute(fieldNav, "initialize");
- if (init?.ToLowerInvariant() == "true")
- {
- _substitutionInfo.SetFieldInit(field);
- }
- }
-
- void ProcessResources(AssemblyDefinition assembly, XPathNavigator nav)
- {
- foreach (XPathNavigator resourceNav in nav.SelectChildren("resource", ""))
- {
- if (!ShouldProcessElement(resourceNav))
- continue;
-
- string name = GetAttribute(resourceNav, "name");
- if (String.IsNullOrEmpty(name))
- {
- LogWarning(resourceNav, DiagnosticId.XmlMissingNameAttributeInResource);
- continue;
- }
-
- string action = GetAttribute(resourceNav, "action");
- if (action != "remove")
- {
- LogWarning(resourceNav, DiagnosticId.XmlInvalidValueForAttributeActionForResource, action, name);
- continue;
- }
-
- EmbeddedResource? resource = assembly.FindEmbeddedResource(name);
- if (resource == null)
- {
- LogWarning(resourceNav, DiagnosticId.XmlCouldNotFindResourceToRemoveInAssembly, name, assembly.Name.Name);
- continue;
- }
-
- _context.Annotations.AddResourceToRemove(assembly, resource);
- }
- }
-
- static MethodDefinition? FindMethod(TypeDefinition type, string signature)
- {
- if (!type.HasMethods)
- return null;
-
- foreach (MethodDefinition meth in type.Methods)
- if (signature == DescriptorMarker.GetMethodSignature(meth, includeGenericParameters: true))
- return meth;
-
- return null;
- }
- }
-}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/DescriptorMarker.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/DescriptorMarker.cs
deleted file mode 100644
index 49404575e41f9..0000000000000
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/DescriptorMarker.cs
+++ /dev/null
@@ -1,292 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Text;
-using System.Xml.XPath;
-using ILLink.Shared;
-
-using Mono.Cecil;
-
-namespace Mono.Linker.Steps
-{
- public class DescriptorMarker : ProcessLinkerXmlBase
- {
- const string NamespaceElementName = "namespace";
-
- const string _required = "required";
- const string _preserve = "preserve";
- const string _accessors = "accessors";
-
- static readonly string[] _accessorsAll = new string[] { "all" };
- static readonly char[] _accessorsSep = new char[] { ';' };
-
- public DescriptorMarker(LinkContext context, Stream documentStream, string xmlDocumentLocation)
- : base(context, documentStream, xmlDocumentLocation)
- {
- }
-
- public DescriptorMarker(LinkContext context, Stream documentStream, EmbeddedResource resource, AssemblyDefinition resourceAssembly, string xmlDocumentLocation = "")
- : base(context, documentStream, resource, resourceAssembly, xmlDocumentLocation)
- {
- }
-
- public void Mark()
- {
- bool stripDescriptors = _context.IsOptimizationEnabled(CodeOptimizations.RemoveDescriptors, _resource?.Assembly);
- ProcessXml(stripDescriptors, _context.IgnoreDescriptors);
- }
-
- protected override AllowedAssemblies AllowedAssemblySelector { get => AllowedAssemblies.AnyAssembly; }
-
- protected override void ProcessAssembly(AssemblyDefinition assembly, XPathNavigator nav, bool warnOnUnresolvedTypes)
- {
- if (GetTypePreserve(nav) == TypePreserve.All)
- {
- foreach (var type in assembly.MainModule.Types)
- MarkAndPreserveAll(type, nav);
-
- foreach (var exportedType in assembly.MainModule.ExportedTypes)
- _context.MarkingHelpers.MarkExportedType(exportedType, assembly.MainModule, new DependencyInfo(DependencyKind.XmlDescriptor, assembly.MainModule), GetMessageOriginForPosition(nav));
- }
- else
- {
- ProcessTypes(assembly, nav, warnOnUnresolvedTypes);
- ProcessNamespaces(assembly, nav);
- }
- }
-
- void ProcessNamespaces(AssemblyDefinition assembly, XPathNavigator nav)
- {
- foreach (XPathNavigator namespaceNav in nav.SelectChildren(NamespaceElementName, XmlNamespace))
- {
- if (!ShouldProcessElement(namespaceNav))
- continue;
-
- string fullname = GetFullName(namespaceNav);
- bool foundMatch = false;
- foreach (TypeDefinition type in assembly.MainModule.Types)
- {
- if (type.Namespace != fullname)
- continue;
-
- foundMatch = true;
- MarkAndPreserveAll(type, nav);
- }
-
- if (!foundMatch)
- {
- LogWarning(namespaceNav, DiagnosticId.XmlCouldNotFindAnyTypeInNamespace, fullname);
- }
- }
- }
-
- void MarkAndPreserveAll(TypeDefinition type, XPathNavigator nav)
- {
- _context.Annotations.Mark(type, new DependencyInfo(DependencyKind.XmlDescriptor, _xmlDocumentLocation), GetMessageOriginForPosition(nav));
- _context.Annotations.SetPreserve(type, TypePreserve.All);
-
- if (!type.HasNestedTypes)
- return;
-
- foreach (TypeDefinition nested in type.NestedTypes)
- MarkAndPreserveAll(nested, nav);
- }
-
- protected override TypeDefinition? ProcessExportedType(ExportedType exported, AssemblyDefinition assembly, XPathNavigator nav)
- {
- _context.MarkingHelpers.MarkExportedType(exported, assembly.MainModule, new DependencyInfo(DependencyKind.XmlDescriptor, _xmlDocumentLocation), GetMessageOriginForPosition(nav));
- return base.ProcessExportedType(exported, assembly, nav);
- }
-
- protected override void ProcessType(TypeDefinition type, XPathNavigator nav)
- {
- Debug.Assert(ShouldProcessElement(nav));
-
- TypePreserve preserve = GetTypePreserve(nav);
- switch (preserve)
- {
- case TypePreserve.Fields when !type.HasFields:
- LogWarning(nav, DiagnosticId.TypeHasNoFieldsToPreserve, type.GetDisplayName());
- break;
-
- case TypePreserve.Methods when !type.HasMethods:
- LogWarning(nav, DiagnosticId.TypeHasNoMethodsToPreserve, type.GetDisplayName());
- break;
-
- case TypePreserve.Fields:
- case TypePreserve.Methods:
- case TypePreserve.All:
- _context.Annotations.SetPreserve(type, preserve);
- break;
- }
-
- bool required = IsRequired(nav);
- ProcessTypeChildren(type, nav, required);
-
- if (!required)
- return;
-
- _context.Annotations.Mark(type, new DependencyInfo(DependencyKind.XmlDescriptor, _xmlDocumentLocation), GetMessageOriginForPosition(nav));
-
- if (type.IsNested)
- {
- var currentType = type;
- while (currentType.IsNested)
- {
- var parent = currentType.DeclaringType;
- _context.Annotations.Mark(parent, new DependencyInfo(DependencyKind.DeclaringType, currentType), GetMessageOriginForPosition(nav));
- currentType = parent;
- }
- }
- }
-
- static TypePreserve GetTypePreserve(XPathNavigator nav)
- {
- string attribute = GetAttribute(nav, _preserve);
- if (string.IsNullOrEmpty(attribute))
- return nav.HasChildren ? TypePreserve.Nothing : TypePreserve.All;
-
- if (Enum.TryParse(attribute, true, out TypePreserve result))
- return result;
- return TypePreserve.Nothing;
- }
-
- protected override void ProcessField(TypeDefinition type, FieldDefinition field, XPathNavigator nav)
- {
- if (_context.Annotations.IsMarked(field))
- LogWarning(nav, DiagnosticId.XmlDuplicatePreserveMember, field.FullName);
-
- _context.Annotations.Mark(field, new DependencyInfo(DependencyKind.XmlDescriptor, _xmlDocumentLocation), GetMessageOriginForPosition(nav));
- }
-
- protected override void ProcessMethod(TypeDefinition type, MethodDefinition method, XPathNavigator nav, object? customData)
- {
- if (_context.Annotations.IsMarked(method))
- LogWarning(nav, DiagnosticId.XmlDuplicatePreserveMember, method.GetDisplayName());
-
- _context.Annotations.MarkIndirectlyCalledMethod(method);
- _context.Annotations.SetAction(method, MethodAction.Parse);
-
- if (customData is bool required && !required)
- {
- _context.Annotations.AddPreservedMethod(type, method);
- }
- else
- {
- _context.Annotations.Mark(method, new DependencyInfo(DependencyKind.XmlDescriptor, _xmlDocumentLocation), GetMessageOriginForPosition(nav));
- }
- }
-
- void ProcessMethodIfNotNull(TypeDefinition type, MethodDefinition method, XPathNavigator nav, object? customData)
- {
- if (method == null)
- return;
-
- ProcessMethod(type, method, nav, customData);
- }
-
- protected override MethodDefinition? GetMethod(TypeDefinition type, string signature)
- {
- if (type.HasMethods)
- foreach (MethodDefinition meth in type.Methods)
- if (signature == GetMethodSignature(meth, false))
- return meth;
-
- return null;
- }
-
- public static string GetMethodSignature(MethodDefinition meth, bool includeGenericParameters)
- {
- StringBuilder sb = new StringBuilder();
- sb.Append(meth.ReturnType.FullName);
- sb.Append(" ");
- sb.Append(meth.Name);
- if (includeGenericParameters && meth.HasGenericParameters)
- {
- sb.Append("`");
- sb.Append(meth.GenericParameters.Count);
- }
-
- sb.Append("(");
- if (meth.HasParameters)
- {
- for (int i = 0; i < meth.Parameters.Count; i++)
- {
- if (i > 0)
- sb.Append(",");
-
- sb.Append(meth.Parameters[i].ParameterType.FullName);
- }
- }
- sb.Append(")");
- return sb.ToString();
- }
-
- protected override void ProcessEvent(TypeDefinition type, EventDefinition @event, XPathNavigator nav, object? customData)
- {
- if (_context.Annotations.IsMarked(@event))
- LogWarning(nav, DiagnosticId.XmlDuplicatePreserveMember, @event.FullName);
-
- ProcessMethod(type, @event.AddMethod, nav, customData);
- ProcessMethod(type, @event.RemoveMethod, nav, customData);
- ProcessMethodIfNotNull(type, @event.InvokeMethod, nav, customData);
- }
-
- protected override void ProcessProperty(TypeDefinition type, PropertyDefinition property, XPathNavigator nav, object? customData, bool fromSignature)
- {
- string[] accessors = fromSignature ? GetAccessors(nav) : _accessorsAll;
-
- if (_context.Annotations.IsMarked(property))
- LogWarning(nav, DiagnosticId.XmlDuplicatePreserveMember, property.FullName);
-
- if (Array.IndexOf(accessors, "all") >= 0)
- {
- ProcessMethodIfNotNull(type, property.GetMethod, nav, customData);
- ProcessMethodIfNotNull(type, property.SetMethod, nav, customData);
- return;
- }
-
- if (property.GetMethod != null && Array.IndexOf(accessors, "get") >= 0)
- ProcessMethod(type, property.GetMethod, nav, customData);
- else if (property.GetMethod == null)
- LogWarning(nav, DiagnosticId.XmlCouldNotFindGetAccesorOfPropertyOnType, property.Name, type.FullName);
-
- if (property.SetMethod != null && Array.IndexOf(accessors, "set") >= 0)
- ProcessMethod(type, property.SetMethod, nav, customData);
- else if (property.SetMethod == null)
- LogWarning(nav, DiagnosticId.XmlCouldNotFindSetAccesorOfPropertyOnType, property.Name, type.FullName);
- }
-
- static bool IsRequired(XPathNavigator nav)
- {
- string attribute = GetAttribute(nav, _required);
- if (attribute == null || attribute.Length == 0)
- return true;
-
- return bool.TryParse(attribute, out bool result) && result;
- }
-
- protected static string[] GetAccessors(XPathNavigator nav)
- {
- string accessorsValue = GetAttribute(nav, _accessors);
-
- if (accessorsValue != null)
- {
- string[] accessors = accessorsValue.Split(
- _accessorsSep, StringSplitOptions.RemoveEmptyEntries);
-
- if (accessors.Length > 0)
- {
- for (int i = 0; i < accessors.Length; ++i)
- accessors[i] = accessors[i].ToLower();
-
- return accessors;
- }
- }
- return _accessorsAll;
- }
- }
-}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/FeatureSettings.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/FeatureSettings.cs
deleted file mode 100644
index 5e89376022684..0000000000000
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/FeatureSettings.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Xml.XPath;
-using ILLink.Shared;
-
-namespace Mono.Linker
-{
- public static class FeatureSettings
- {
- public static bool ShouldProcessElement(XPathNavigator nav, LinkContext context, string documentLocation)
- {
- var feature = GetAttribute(nav, "feature");
- if (string.IsNullOrEmpty(feature))
- return true;
-
- var value = GetAttribute(nav, "featurevalue");
- if (string.IsNullOrEmpty(value))
- {
- context.LogError(null, DiagnosticId.XmlFeatureDoesNotSpecifyFeatureValue, documentLocation, feature);
- return false;
- }
-
- if (!bool.TryParse(value, out bool bValue))
- {
- context.LogError(null, DiagnosticId.XmlUnsupportedNonBooleanValueForFeature, documentLocation, feature);
- return false;
- }
-
- var isDefault = GetAttribute(nav, "featuredefault");
- bool bIsDefault = false;
- if (!string.IsNullOrEmpty(isDefault) && (!bool.TryParse(isDefault, out bIsDefault) || !bIsDefault))
- {
- context.LogError(null, DiagnosticId.XmlDocumentLocationHasInvalidFeatureDefault, documentLocation);
- return false;
- }
-
- if (!context.FeatureSettings.TryGetValue(feature, out bool featureSetting))
- return bIsDefault;
-
- return bValue == featureSetting;
- }
-
- public static string GetAttribute(XPathNavigator nav, string attribute)
- {
- return nav.GetAttribute(attribute, String.Empty);
- }
- }
-}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/LinkAttributesParser.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/LinkAttributesParser.cs
deleted file mode 100644
index 0acfdda2dccbe..0000000000000
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/LinkAttributesParser.cs
+++ /dev/null
@@ -1,578 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Xml.XPath;
-using ILLink.Shared;
-using Mono.Cecil;
-
-namespace Mono.Linker.Steps
-{
- public class LinkAttributesParser : ProcessLinkerXmlBase
- {
- AttributeInfo? _attributeInfo;
-
- public LinkAttributesParser(LinkContext context, Stream documentStream, string xmlDocumentLocation)
- : base(context, documentStream, xmlDocumentLocation)
- {
- }
-
- public LinkAttributesParser(LinkContext context, Stream documentStream, EmbeddedResource resource, AssemblyDefinition resourceAssembly, string xmlDocumentLocation = "")
- : base(context, documentStream, resource, resourceAssembly, xmlDocumentLocation)
- {
- }
-
- public void Parse(AttributeInfo xmlInfo)
- {
- _attributeInfo = xmlInfo;
- bool stripLinkAttributes = _context.IsOptimizationEnabled(CodeOptimizations.RemoveLinkAttributes, _resource?.Assembly);
- ProcessXml(stripLinkAttributes, _context.IgnoreLinkAttributes);
- }
-
- CustomAttribute[]? ProcessAttributes(XPathNavigator nav, ICustomAttributeProvider provider)
- {
- var builder = new ArrayBuilder();
- foreach (XPathNavigator argumentNav in nav.SelectChildren("attribute", string.Empty))
- {
- if (!ShouldProcessElement(argumentNav))
- continue;
-
- TypeDefinition? attributeType;
- string internalAttribute = GetAttribute(argumentNav, "internal");
- if (!string.IsNullOrEmpty(internalAttribute))
- {
- attributeType = GenerateRemoveAttributeInstancesAttribute();
- if (attributeType == null)
- continue;
-
- // TODO: Replace with IsAttributeType check once we have it
- if (provider is not TypeDefinition)
- {
- LogWarning(argumentNav, DiagnosticId.XmlRemoveAttributeInstancesCanOnlyBeUsedOnType, attributeType.Name);
- continue;
- }
- }
- else
- {
- string attributeFullName = GetFullName(argumentNav);
- if (string.IsNullOrEmpty(attributeFullName))
- {
- LogWarning(argumentNav, DiagnosticId.XmlElementDoesNotContainRequiredAttributeFullname);
- continue;
- }
-
- if (!GetAttributeType(argumentNav, attributeFullName, out attributeType))
- continue;
- }
-
- CustomAttribute? customAttribute = CreateCustomAttribute(argumentNav, attributeType);
- if (customAttribute != null)
- {
- _context.LogMessage($"Assigning external custom attribute '{FormatCustomAttribute(customAttribute)}' instance to '{provider}'.");
- builder.Add(customAttribute);
- }
- }
-
- return builder.ToArray();
-
- static string FormatCustomAttribute(CustomAttribute ca)
- {
- StringBuilder sb = new StringBuilder();
- sb.Append(ca.Constructor.GetDisplayName());
- sb.Append(" { args: ");
- for (int i = 0; i < ca.ConstructorArguments.Count; ++i)
- {
- if (i > 0)
- sb.Append(", ");
-
- var caa = ca.ConstructorArguments[i];
- sb.Append($"{caa.Type.GetDisplayName()} {caa.Value}");
- }
- sb.Append(" }");
-
- return sb.ToString();
- }
- }
-
- TypeDefinition? GenerateRemoveAttributeInstancesAttribute()
- {
- if (_context.MarkedKnownMembers.RemoveAttributeInstancesAttributeDefinition != null)
- return _context.MarkedKnownMembers.RemoveAttributeInstancesAttributeDefinition;
-
- var voidType = BCL.FindPredefinedType("System", "Void", _context);
- if (voidType == null)
- return null;
-
- var attributeType = BCL.FindPredefinedType("System", "Attribute", _context);
- if (attributeType == null)
- return null;
-
- var objectType = BCL.FindPredefinedType("System", "Object", _context);
- if (objectType == null)
- return null;
-
- //
- // Generates metadata information for internal type
- //
- // public sealed class RemoveAttributeInstancesAttribute : Attribute
- // {
- // public RemoveAttributeInstancesAttribute () {}
- // public RemoveAttributeInstancesAttribute (object value1) {}
- // }
- //
- var td = new TypeDefinition("", "RemoveAttributeInstancesAttribute", TypeAttributes.Public);
- td.BaseType = attributeType;
-
- const MethodAttributes ctorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Final;
- var ctor = new MethodDefinition(".ctor", ctorAttributes, voidType);
- td.Methods.Add(ctor);
-
- ctor = new MethodDefinition(".ctor", ctorAttributes, voidType);
- ctor.Parameters.Add(new ParameterDefinition(objectType));
- td.Methods.Add(ctor);
-
- return _context.MarkedKnownMembers.RemoveAttributeInstancesAttributeDefinition = td;
- }
-
- CustomAttribute? CreateCustomAttribute(XPathNavigator nav, TypeDefinition attributeType)
- {
- CustomAttributeArgument[] arguments = ReadCustomAttributeArguments(nav, attributeType);
-
- MethodDefinition? constructor = FindBestMatchingConstructor(attributeType, arguments);
- if (constructor == null)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindMatchingConstructorForCustomAttribute, attributeType.GetDisplayName());
- return null;
- }
-
- CustomAttribute customAttribute = new CustomAttribute(constructor);
- foreach (var argument in arguments)
- customAttribute.ConstructorArguments.Add(argument);
-
- ReadCustomAttributeProperties(nav, attributeType, customAttribute);
-
- return customAttribute;
- }
-
- MethodDefinition? FindBestMatchingConstructor(TypeDefinition attributeType, CustomAttributeArgument[] args)
- {
- var methods = attributeType.Methods;
- for (int i = 0; i < attributeType.Methods.Count; ++i)
- {
- var m = methods[i];
- if (!m.IsInstanceConstructor())
- continue;
-
- var p = m.Parameters;
- if (args.Length != p.Count)
- continue;
-
- bool match = true;
- for (int ii = 0; match && ii != args.Length; ++ii)
- {
- //
- // No candidates betterness, only exact matches are supported
- //
- var parameterType = _context.TryResolve(p[ii].ParameterType);
- if (parameterType == null || parameterType != _context.TryResolve(args[ii].Type))
- match = false;
- }
-
- if (match)
- return m;
- }
-
- return null;
- }
-
- void ReadCustomAttributeProperties(XPathNavigator nav, TypeDefinition attributeType, CustomAttribute customAttribute)
- {
- foreach (XPathNavigator propertyNav in nav.SelectChildren("property", string.Empty))
- {
- string propertyName = GetName(propertyNav);
- if (string.IsNullOrEmpty(propertyName))
- {
- LogWarning(propertyNav, DiagnosticId.XmlPropertyDoesNotContainAttributeName);
- continue;
- }
-
- PropertyDefinition? property = attributeType.Properties.Where(prop => prop.Name == propertyName).FirstOrDefault();
- if (property == null)
- {
- LogWarning(propertyNav, DiagnosticId.XmlCouldNotFindProperty, propertyName);
- continue;
- }
-
- var caa = ReadCustomAttributeArgument(propertyNav, property);
- if (caa is null)
- continue;
-
- customAttribute.Properties.Add(new CustomAttributeNamedArgument(property.Name, caa.Value));
- }
- }
-
- CustomAttributeArgument[] ReadCustomAttributeArguments(XPathNavigator nav, TypeDefinition attributeType)
- {
- var args = new ArrayBuilder();
-
- foreach (XPathNavigator argumentNav in nav.SelectChildren("argument", string.Empty))
- {
- CustomAttributeArgument? caa = ReadCustomAttributeArgument(argumentNav, attributeType);
- if (caa is not null)
- args.Add(caa.Value);
- }
-
- return args.ToArray() ?? Array.Empty();
- }
-
- CustomAttributeArgument? ReadCustomAttributeArgument(XPathNavigator nav, IMemberDefinition memberWithAttribute)
- {
- TypeReference? typeref = ResolveArgumentType(nav, memberWithAttribute);
- if (typeref is null)
- return null;
-
- string svalue = nav.Value;
-
- //
- // Builds CustomAttributeArgument in the same way as it would be
- // represented in the metadata if encoded there. This simplifies
- // any custom attributes handling in linker by using same attributes
- // value extraction or mathing logic.
- //
- switch (typeref.MetadataType)
- {
- case MetadataType.Object:
- var argumentIterator = nav.SelectChildren("argument", string.Empty);
- if (argumentIterator?.MoveNext() != true)
- {
- _context.LogError(null, DiagnosticId.CustomAttributeArgumentForTypeRequiresNestedNode, "System.Object", "argument");
- return null;
- }
-
- var typedef = _context.TryResolve(typeref);
- if (typedef == null)
- return null;
-
- var boxedValue = ReadCustomAttributeArgument(argumentIterator.Current!, typedef);
- if (boxedValue is null)
- return null;
-
- return new CustomAttributeArgument(typeref, boxedValue);
-
- case MetadataType.Char:
- case MetadataType.Byte:
- case MetadataType.SByte:
- case MetadataType.Int16:
- case MetadataType.UInt16:
- case MetadataType.Int32:
- case MetadataType.UInt32:
- case MetadataType.UInt64:
- case MetadataType.Int64:
- case MetadataType.String:
- return new CustomAttributeArgument(typeref, ConvertStringValue(svalue, typeref));
-
- case MetadataType.ValueType:
- var enumType = _context.Resolve(typeref);
- if (enumType?.IsEnum != true)
- goto default;
-
- var enumField = enumType.Fields.Where(f => f.IsStatic && f.Name == svalue).FirstOrDefault();
- object evalue = enumField?.Constant ?? svalue;
-
- typeref = enumType.GetEnumUnderlyingType();
- return new CustomAttributeArgument(enumType, ConvertStringValue(evalue, typeref));
-
- case MetadataType.Class:
- if (!typeref.IsTypeOf("System", "Type"))
- goto default;
-
- if (!_context.TypeNameResolver.TryResolveTypeName(svalue, memberWithAttribute, out TypeReference? type, out _))
- {
- _context.LogError(GetMessageOriginForPosition(nav), DiagnosticId.CouldNotResolveCustomAttributeTypeValue, svalue);
- return null;
- }
-
- return new CustomAttributeArgument(typeref, type);
- default:
- // No support for null and arrays, consider adding - dotnet/linker/issues/1957
- _context.LogError(GetMessageOriginForPosition(nav), DiagnosticId.UnexpectedAttributeArgumentType, typeref.GetDisplayName());
- return null;
- }
-
- TypeReference? ResolveArgumentType(XPathNavigator nav, IMemberDefinition memberWithAttribute)
- {
- string typeName = GetAttribute(nav, "type");
- if (string.IsNullOrEmpty(typeName))
- typeName = "System.String";
-
- if (!_context.TypeNameResolver.TryResolveTypeName(typeName, memberWithAttribute, out TypeReference? typeref, out _))
- {
- _context.LogError(GetMessageOriginForPosition(nav), DiagnosticId.TypeUsedWithAttributeValueCouldNotBeFound, typeName, nav.Value);
- return null;
- }
-
- return typeref;
- }
- }
-
- object? ConvertStringValue(object value, TypeReference targetType)
- {
- TypeCode typeCode;
- switch (targetType.MetadataType)
- {
- case MetadataType.String:
- typeCode = TypeCode.String;
- break;
- case MetadataType.Char:
- typeCode = TypeCode.Char;
- break;
- case MetadataType.Byte:
- typeCode = TypeCode.Byte;
- break;
- case MetadataType.SByte:
- typeCode = TypeCode.SByte;
- break;
- case MetadataType.Int16:
- typeCode = TypeCode.Int16;
- break;
- case MetadataType.UInt16:
- typeCode = TypeCode.UInt16;
- break;
- case MetadataType.Int32:
- typeCode = TypeCode.Int32;
- break;
- case MetadataType.UInt32:
- typeCode = TypeCode.UInt32;
- break;
- case MetadataType.UInt64:
- typeCode = TypeCode.UInt64;
- break;
- case MetadataType.Int64:
- typeCode = TypeCode.Int64;
- break;
- case MetadataType.Boolean:
- typeCode = TypeCode.Boolean;
- break;
- case MetadataType.Single:
- typeCode = TypeCode.Single;
- break;
- case MetadataType.Double:
- typeCode = TypeCode.Double;
- break;
- default:
- throw new NotSupportedException(targetType.ToString());
- }
-
- try
- {
- return Convert.ChangeType(value, typeCode);
- }
- catch
- {
- _context.LogError(null, DiagnosticId.CannotConverValueToType, value.ToString() ?? "", targetType.GetDisplayName());
- return null;
- }
- }
-
- bool GetAttributeType(XPathNavigator nav, string attributeFullName, [NotNullWhen(true)] out TypeDefinition? attributeType)
- {
- string assemblyName = GetAttribute(nav, "assembly");
- if (string.IsNullOrEmpty(assemblyName))
- {
- attributeType = _context.GetType(attributeFullName);
- }
- else
- {
- AssemblyDefinition? assembly;
- try
- {
- assembly = _context.TryResolve(AssemblyNameReference.Parse(assemblyName));
- if (assembly == null)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotResolveAssemblyForAttribute, assemblyName, attributeFullName);
-
- attributeType = default;
- return false;
- }
- }
- catch (Exception)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotResolveAssemblyForAttribute, assemblyName, attributeFullName);
- attributeType = default;
- return false;
- }
-
- attributeType = _context.TryResolve(assembly, attributeFullName);
- }
-
- if (attributeType == null)
- {
- LogWarning(nav, DiagnosticId.XmlAttributeTypeCouldNotBeFound, attributeFullName);
- return false;
- }
-
- return true;
- }
-
- protected override AllowedAssemblies AllowedAssemblySelector
- {
- get
- {
- if (_resource?.Assembly == null)
- return AllowedAssemblies.AllAssemblies;
-
- // Corelib XML may contain assembly wildcard to support compiler-injected attribute types
- if (_resource?.Assembly.Name.Name == PlatformAssemblies.CoreLib)
- return AllowedAssemblies.AllAssemblies;
-
- return AllowedAssemblies.ContainingAssembly;
- }
- }
-
- protected override void ProcessAssembly(AssemblyDefinition assembly, XPathNavigator nav, bool warnOnUnresolvedTypes)
- {
- PopulateAttributeInfo(assembly, nav);
- ProcessTypes(assembly, nav, warnOnUnresolvedTypes);
- }
-
- protected override void ProcessType(TypeDefinition type, XPathNavigator nav)
- {
- Debug.Assert(ShouldProcessElement(nav));
-
- PopulateAttributeInfo(type, nav);
- ProcessTypeChildren(type, nav);
-
- if (!type.HasNestedTypes)
- return;
-
- foreach (XPathNavigator nestedTypeNav in nav.SelectChildren("type", string.Empty))
- {
- foreach (TypeDefinition nested in type.NestedTypes)
- {
- if (nested.Name == GetAttribute(nestedTypeNav, "name") && ShouldProcessElement(nestedTypeNav))
- ProcessType(nested, nestedTypeNav);
- }
- }
- }
-
- protected override void ProcessField(TypeDefinition type, FieldDefinition field, XPathNavigator nav)
- {
- PopulateAttributeInfo(field, nav);
- }
-
- protected override void ProcessMethod(TypeDefinition type, MethodDefinition method, XPathNavigator nav, object? customData)
- {
- PopulateAttributeInfo(method, nav);
- ProcessReturnParameters(method, nav);
- ProcessParameters(method, nav);
- }
-
- void ProcessParameters(MethodDefinition method, XPathNavigator nav)
- {
- Debug.Assert(_attributeInfo != null);
- foreach (XPathNavigator parameterNav in nav.SelectChildren("parameter", string.Empty))
- {
- var attributes = ProcessAttributes(parameterNav, method);
- if (attributes != null)
- {
- string paramName = GetAttribute(parameterNav, "name");
- foreach (ParameterDefinition parameter in method.Parameters)
- {
- if (paramName == parameter.Name)
- {
- if (parameter.HasCustomAttributes || _attributeInfo.CustomAttributes.ContainsKey(parameter))
- LogWarning(parameterNav, DiagnosticId.XmlMoreThanOneValyForParameterOfMethod, paramName, method.GetDisplayName());
- _attributeInfo.AddCustomAttributes(parameter, attributes);
- break;
- }
- }
- }
- }
- }
-
- void ProcessReturnParameters(MethodDefinition method, XPathNavigator nav)
- {
- bool firstAppearance = true;
- foreach (XPathNavigator returnNav in nav.SelectChildren("return", string.Empty))
- {
- if (firstAppearance)
- {
- firstAppearance = false;
- PopulateAttributeInfo(method.MethodReturnType, returnNav);
- }
- else
- {
- LogWarning(returnNav, DiagnosticId.XmlMoreThanOneReturnElementForMethod, method.GetDisplayName());
- }
- }
- }
-
- protected override MethodDefinition? GetMethod(TypeDefinition type, string signature)
- {
- if (type.HasMethods)
- foreach (MethodDefinition method in type.Methods)
- if (signature.Replace(" ", "") == GetMethodSignature(method) || signature.Replace(" ", "") == GetMethodSignature(method, true))
- return method;
-
- return null;
- }
-
- static string GetMethodSignature(MethodDefinition method, bool includeReturnType = false)
- {
- StringBuilder sb = new StringBuilder();
- if (includeReturnType)
- {
- sb.Append(method.ReturnType.FullName);
- }
- sb.Append(method.Name);
- if (method.HasGenericParameters)
- {
- sb.Append("<");
- for (int i = 0; i < method.GenericParameters.Count; i++)
- {
- if (i > 0)
- sb.Append(",");
-
- sb.Append(method.GenericParameters[i].Name);
- }
- sb.Append(">");
- }
- sb.Append("(");
- if (method.HasParameters)
- {
- for (int i = 0; i < method.Parameters.Count; i++)
- {
- if (i > 0)
- sb.Append(",");
-
- sb.Append(method.Parameters[i].ParameterType.FullName);
- }
- }
- sb.Append(")");
- return sb.ToString();
- }
-
- protected override void ProcessProperty(TypeDefinition type, PropertyDefinition property, XPathNavigator nav, object? customData, bool fromSignature)
- {
- PopulateAttributeInfo(property, nav);
- }
-
- protected override void ProcessEvent(TypeDefinition type, EventDefinition @event, XPathNavigator nav, object? customData)
- {
- PopulateAttributeInfo(@event, nav);
- }
-
- void PopulateAttributeInfo(ICustomAttributeProvider provider, XPathNavigator nav)
- {
- Debug.Assert(_attributeInfo != null);
- var attributes = ProcessAttributes(nav, provider);
- if (attributes != null)
- _attributeInfo.AddCustomAttributes(provider, attributes);
- }
- }
-}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/ProcessLinkerXmlBase.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/ProcessLinkerXmlBase.cs
deleted file mode 100644
index 842c56639fdd0..0000000000000
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/ProcessLinkerXmlBase.cs
+++ /dev/null
@@ -1,662 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text.RegularExpressions;
-using System.Xml;
-using System.Xml.Linq;
-using System.Xml.XPath;
-using ILLink.Shared;
-using Mono.Cecil;
-
-namespace Mono.Linker.Steps
-{
- [Flags]
- public enum AllowedAssemblies
- {
- ContainingAssembly = 0x1,
- AnyAssembly = 0x2 | ContainingAssembly,
- AllAssemblies = 0x4 | AnyAssembly
- }
-
- public abstract class ProcessLinkerXmlBase
- {
- const string FullNameAttributeName = "fullname";
- const string LinkerElementName = "linker";
- const string TypeElementName = "type";
- const string SignatureAttributeName = "signature";
- const string NameAttributeName = "name";
- const string FieldElementName = "field";
- const string MethodElementName = "method";
- const string EventElementName = "event";
- const string PropertyElementName = "property";
- const string AllAssembliesFullName = "*";
- protected const string XmlNamespace = "";
-
- protected readonly string _xmlDocumentLocation;
- readonly XPathNavigator _document;
- protected readonly (EmbeddedResource Resource, AssemblyDefinition Assembly)? _resource;
- protected readonly LinkContext _context;
-
- protected ProcessLinkerXmlBase(LinkContext context, Stream documentStream, string xmlDocumentLocation)
- {
- _context = context;
- using (documentStream)
- {
- _document = XDocument.Load(documentStream, LoadOptions.SetLineInfo).CreateNavigator();
- }
- _xmlDocumentLocation = xmlDocumentLocation;
- }
-
- protected ProcessLinkerXmlBase(LinkContext context, Stream documentStream, EmbeddedResource resource, AssemblyDefinition resourceAssembly, string xmlDocumentLocation)
- : this(context, documentStream, xmlDocumentLocation)
- {
- _resource = (
- resource ?? throw new ArgumentNullException(nameof(resource)),
- resourceAssembly ?? throw new ArgumentNullException(nameof(resourceAssembly))
- );
- }
-
- protected virtual bool ShouldProcessElement(XPathNavigator nav) => FeatureSettings.ShouldProcessElement(nav, _context, _xmlDocumentLocation);
-
- protected virtual void ProcessXml(bool stripResource, bool ignoreResource)
- {
- if (!AllowedAssemblySelector.HasFlag(AllowedAssemblies.AnyAssembly) && _resource == null)
- throw new InvalidOperationException("The containing assembly must be specified for XML which is restricted to modifying that assembly only.");
-
- try
- {
- XPathNavigator nav = _document.CreateNavigator();
-
- // Initial structure check - ignore XML document which don't look like linker XML format
- if (!nav.MoveToChild(LinkerElementName, XmlNamespace))
- return;
-
- if (_resource != null)
- {
- if (stripResource)
- _context.Annotations.AddResourceToRemove(_resource.Value.Assembly, _resource.Value.Resource);
- if (ignoreResource)
- return;
- }
-
- if (!ShouldProcessElement(nav))
- return;
-
- ProcessAssemblies(nav);
-
- // For embedded XML, allow not specifying the assembly explicitly in XML.
- if (_resource != null)
- ProcessAssembly(_resource.Value.Assembly, nav, warnOnUnresolvedTypes: true);
-
- }
- catch (Exception ex) when (!(ex is LinkerFatalErrorException))
- {
- throw new LinkerFatalErrorException(MessageContainer.CreateErrorMessage(null, DiagnosticId.ErrorProcessingXmlLocation, _xmlDocumentLocation), ex);
- }
- }
-
- protected virtual AllowedAssemblies AllowedAssemblySelector { get => _resource != null ? AllowedAssemblies.ContainingAssembly : AllowedAssemblies.AnyAssembly; }
-
- bool ShouldProcessAllAssemblies(XPathNavigator nav, [NotNullWhen(false)] out AssemblyNameReference? assemblyName)
- {
- assemblyName = null;
- if (GetFullName(nav) == AllAssembliesFullName)
- return true;
-
- assemblyName = GetAssemblyName(nav);
- return false;
- }
-
- protected virtual void ProcessAssemblies(XPathNavigator nav)
- {
- foreach (XPathNavigator assemblyNav in nav.SelectChildren("assembly", ""))
- {
- // Errors for invalid assembly names should show up even if this element will be
- // skipped due to feature conditions.
- bool processAllAssemblies = ShouldProcessAllAssemblies(assemblyNav, out AssemblyNameReference? name);
- if (processAllAssemblies && AllowedAssemblySelector != AllowedAssemblies.AllAssemblies)
- {
- LogWarning(assemblyNav, DiagnosticId.XmlUnsuportedWildcard);
- continue;
- }
-
- AssemblyDefinition? assemblyToProcess = null;
- if (!AllowedAssemblySelector.HasFlag(AllowedAssemblies.AnyAssembly))
- {
- Debug.Assert(!processAllAssemblies);
- Debug.Assert(_resource != null);
- if (_resource.Value.Assembly.Name.Name != name!.Name)
- {
- LogWarning(assemblyNav, DiagnosticId.AssemblyWithEmbeddedXmlApplyToAnotherAssembly, _resource.Value.Assembly.Name.Name, name.ToString());
- continue;
- }
- assemblyToProcess = _resource.Value.Assembly;
- }
-
- if (!ShouldProcessElement(assemblyNav))
- continue;
-
- if (processAllAssemblies)
- {
- // We could avoid loading all references in this case: https://github.com/dotnet/linker/issues/1708
- foreach (AssemblyDefinition assembly in _context.GetReferencedAssemblies())
- ProcessAssembly(assembly, assemblyNav, warnOnUnresolvedTypes: false);
- }
- else
- {
- Debug.Assert(!processAllAssemblies);
- AssemblyDefinition? assembly = assemblyToProcess ?? _context.TryResolve(name!);
-
- if (assembly == null)
- {
- LogWarning(assemblyNav, DiagnosticId.XmlCouldNotResolveAssembly, name!.Name);
- continue;
- }
-
- ProcessAssembly(assembly, assemblyNav, warnOnUnresolvedTypes: true);
- }
- }
- }
-
- protected abstract void ProcessAssembly(AssemblyDefinition assembly, XPathNavigator nav, bool warnOnUnresolvedTypes);
-
- protected virtual void ProcessTypes(AssemblyDefinition assembly, XPathNavigator nav, bool warnOnUnresolvedTypes)
- {
- foreach (XPathNavigator typeNav in nav.SelectChildren(TypeElementName, XmlNamespace))
- {
-
- if (!ShouldProcessElement(typeNav))
- continue;
-
- string fullname = GetFullName(typeNav);
-
- if (fullname.IndexOf("*") != -1)
- {
- if (ProcessTypePattern(fullname, assembly, typeNav))
- continue;
- }
-
- TypeDefinition type = assembly.MainModule.GetType(fullname);
-
- if (type == null && assembly.MainModule.HasExportedTypes)
- {
- foreach (var exported in assembly.MainModule.ExportedTypes)
- {
- if (fullname == exported.FullName)
- {
- var resolvedExternal = ProcessExportedType(exported, assembly, typeNav);
- if (resolvedExternal != null)
- {
- type = resolvedExternal;
- break;
- }
- }
- }
- }
-
- if (type == null)
- {
- if (warnOnUnresolvedTypes)
- LogWarning(typeNav, DiagnosticId.XmlCouldNotResolveType, fullname);
- continue;
- }
-
- ProcessType(type, typeNav);
- }
- }
-
- protected virtual TypeDefinition? ProcessExportedType(ExportedType exported, AssemblyDefinition assembly, XPathNavigator nav) => exported.Resolve();
-
- void MatchType(TypeDefinition type, Regex regex, XPathNavigator nav)
- {
- if (regex.Match(type.FullName).Success)
- ProcessType(type, nav);
-
- if (!type.HasNestedTypes)
- return;
-
- foreach (var nt in type.NestedTypes)
- MatchType(nt, regex, nav);
- }
-
- protected virtual bool ProcessTypePattern(string fullname, AssemblyDefinition assembly, XPathNavigator nav)
- {
- Regex regex = new Regex(fullname.Replace(".", @"\.").Replace("*", "(.*)"));
-
- foreach (TypeDefinition type in assembly.MainModule.Types)
- {
- MatchType(type, regex, nav);
- }
-
- if (assembly.MainModule.HasExportedTypes)
- {
- foreach (var exported in assembly.MainModule.ExportedTypes)
- {
- if (regex.Match(exported.FullName).Success)
- {
- var type = ProcessExportedType(exported, assembly, nav);
- if (type != null)
- {
- ProcessType(type, nav);
- }
- }
- }
- }
-
- return true;
- }
-
- protected abstract void ProcessType(TypeDefinition type, XPathNavigator nav);
-
- protected void ProcessTypeChildren(TypeDefinition type, XPathNavigator nav, object? customData = null)
- {
- if (nav.HasChildren)
- {
- ProcessSelectedFields(nav, type);
- ProcessSelectedMethods(nav, type, customData);
- ProcessSelectedEvents(nav, type, customData);
- ProcessSelectedProperties(nav, type, customData);
- }
- }
-
- void ProcessSelectedFields(XPathNavigator nav, TypeDefinition type)
- {
- foreach (XPathNavigator fieldNav in nav.SelectChildren(FieldElementName, XmlNamespace))
- {
- if (!ShouldProcessElement(fieldNav))
- continue;
- ProcessField(type, fieldNav);
- }
- }
-
- protected virtual void ProcessField(TypeDefinition type, XPathNavigator nav)
- {
- string signature = GetSignature(nav);
- if (!String.IsNullOrEmpty(signature))
- {
- FieldDefinition? field = GetField(type, signature);
- if (field == null)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindFieldOnType, signature, type.GetDisplayName());
- return;
- }
-
- ProcessField(type, field, nav);
- }
-
- string name = GetName(nav);
- if (!String.IsNullOrEmpty(name))
- {
- bool foundMatch = false;
- if (type.HasFields)
- {
- foreach (FieldDefinition field in type.Fields)
- {
- if (field.Name == name)
- {
- foundMatch = true;
- ProcessField(type, field, nav);
- }
- }
- }
-
- if (!foundMatch)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindFieldOnType, name, type.GetDisplayName());
- }
- }
- }
-
- protected static FieldDefinition? GetField(TypeDefinition type, string signature)
- {
- if (!type.HasFields)
- return null;
-
- foreach (FieldDefinition field in type.Fields)
- if (signature == field.FieldType.FullName + " " + field.Name)
- return field;
-
- return null;
- }
-
- protected virtual void ProcessField(TypeDefinition type, FieldDefinition field, XPathNavigator nav) { }
-
- void ProcessSelectedMethods(XPathNavigator nav, TypeDefinition type, object? customData)
- {
- foreach (XPathNavigator methodNav in nav.SelectChildren(MethodElementName, XmlNamespace))
- {
- if (!ShouldProcessElement(methodNav))
- continue;
- ProcessMethod(type, methodNav, customData);
- }
- }
-
- protected virtual void ProcessMethod(TypeDefinition type, XPathNavigator nav, object? customData)
- {
- string signature = GetSignature(nav);
- if (!String.IsNullOrEmpty(signature))
- {
- MethodDefinition? method = GetMethod(type, signature);
- if (method == null)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindMethodOnType, signature, type.GetDisplayName());
- return;
- }
-
- ProcessMethod(type, method, nav, customData);
- }
-
- string name = GetAttribute(nav, NameAttributeName);
- if (!String.IsNullOrEmpty(name))
- {
- bool foundMatch = false;
- if (type.HasMethods)
- {
- foreach (MethodDefinition method in type.Methods)
- {
- if (name == method.Name)
- {
- foundMatch = true;
- ProcessMethod(type, method, nav, customData);
- }
- }
- }
-
- if (!foundMatch)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindMethodOnType, name, type.GetDisplayName());
- }
- }
- }
-
- protected virtual MethodDefinition? GetMethod(TypeDefinition type, string signature) => null;
-
- protected virtual void ProcessMethod(TypeDefinition type, MethodDefinition method, XPathNavigator nav, object? customData) { }
-
- void ProcessSelectedEvents(XPathNavigator nav, TypeDefinition type, object? customData)
- {
- foreach (XPathNavigator eventNav in nav.SelectChildren(EventElementName, XmlNamespace))
- {
- if (!ShouldProcessElement(eventNav))
- continue;
- ProcessEvent(type, eventNav, customData);
- }
- }
-
- protected virtual void ProcessEvent(TypeDefinition type, XPathNavigator nav, object? customData)
- {
- string signature = GetSignature(nav);
- if (!String.IsNullOrEmpty(signature))
- {
- EventDefinition? @event = GetEvent(type, signature);
- if (@event == null)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindEventOnType, signature, type.GetDisplayName());
- return;
- }
-
- ProcessEvent(type, @event, nav, customData);
- }
-
- string name = GetAttribute(nav, NameAttributeName);
- if (!String.IsNullOrEmpty(name))
- {
- bool foundMatch = false;
- foreach (EventDefinition @event in type.Events)
- {
- if (@event.Name == name)
- {
- foundMatch = true;
- ProcessEvent(type, @event, nav, customData);
- }
- }
-
- if (!foundMatch)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindEventOnType, name, type.GetDisplayName());
- }
- }
- }
-
- protected static EventDefinition? GetEvent(TypeDefinition type, string signature)
- {
- if (!type.HasEvents)
- return null;
-
- foreach (EventDefinition @event in type.Events)
- if (signature == @event.EventType.FullName + " " + @event.Name)
- return @event;
-
- return null;
- }
-
- protected virtual void ProcessEvent(TypeDefinition type, EventDefinition @event, XPathNavigator nav, object? customData) { }
-
- void ProcessSelectedProperties(XPathNavigator nav, TypeDefinition type, object? customData)
- {
- foreach (XPathNavigator propertyNav in nav.SelectChildren(PropertyElementName, XmlNamespace))
- {
- if (!ShouldProcessElement(propertyNav))
- continue;
- ProcessProperty(type, propertyNav, customData);
- }
- }
-
- protected virtual void ProcessProperty(TypeDefinition type, XPathNavigator nav, object? customData)
- {
- string signature = GetSignature(nav);
- if (!String.IsNullOrEmpty(signature))
- {
- PropertyDefinition? property = GetProperty(type, signature);
- if (property == null)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindPropertyOnType, signature, type.GetDisplayName());
- return;
- }
-
- ProcessProperty(type, property, nav, customData, true);
- }
-
- string name = GetAttribute(nav, NameAttributeName);
- if (!String.IsNullOrEmpty(name))
- {
- bool foundMatch = false;
- foreach (PropertyDefinition property in type.Properties)
- {
- if (property.Name == name)
- {
- foundMatch = true;
- ProcessProperty(type, property, nav, customData, false);
- }
- }
-
- if (!foundMatch)
- {
- LogWarning(nav, DiagnosticId.XmlCouldNotFindPropertyOnType, name, type.GetDisplayName());
- }
- }
- }
-
- protected static PropertyDefinition? GetProperty(TypeDefinition type, string signature)
- {
- if (!type.HasProperties)
- return null;
-
- foreach (PropertyDefinition property in type.Properties)
- if (signature == property.PropertyType.FullName + " " + property.Name)
- return property;
-
- return null;
- }
-
- protected virtual void ProcessProperty(TypeDefinition type, PropertyDefinition property, XPathNavigator nav, object? customData, bool fromSignature) { }
-
- protected virtual AssemblyNameReference GetAssemblyName(XPathNavigator nav)
- {
- return AssemblyNameReference.Parse(GetFullName(nav));
- }
-
- protected static string GetFullName(XPathNavigator nav)
- {
- return GetAttribute(nav, FullNameAttributeName);
- }
-
- protected static string GetName(XPathNavigator nav)
- {
- return GetAttribute(nav, NameAttributeName);
- }
-
- protected static string GetSignature(XPathNavigator nav)
- {
- return GetAttribute(nav, SignatureAttributeName);
- }
-
- protected static string GetAttribute(XPathNavigator nav, string attribute)
- {
- return nav.GetAttribute(attribute, XmlNamespace);
- }
-
- protected MessageOrigin GetMessageOriginForPosition(XPathNavigator position)
- {
- return (position is IXmlLineInfo lineInfo)
- ? new MessageOrigin(_xmlDocumentLocation, lineInfo.LineNumber, lineInfo.LinePosition, _resource?.Assembly)
- : new MessageOrigin(_xmlDocumentLocation, 0, 0, _resource?.Assembly);
- }
- protected void LogWarning(string message, int warningCode, XPathNavigator position)
- {
- _context.LogWarning(message, warningCode, GetMessageOriginForPosition(position));
- }
-
- protected void LogWarning(XPathNavigator position, DiagnosticId id, params string[] args)
- {
- _context.LogWarning(GetMessageOriginForPosition(position), id, args);
- }
-
- public override string ToString() => GetType().Name + ": " + _xmlDocumentLocation;
-
- public bool TryConvertValue(string value, TypeReference target, out object? result)
- {
- switch (target.MetadataType)
- {
- case MetadataType.Boolean:
- if (bool.TryParse(value, out bool bvalue))
- {
- result = bvalue ? 1 : 0;
- return true;
- }
-
- goto case MetadataType.Int32;
-
- case MetadataType.Byte:
- if (!byte.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out byte byteresult))
- break;
-
- result = (int)byteresult;
- return true;
-
- case MetadataType.SByte:
- if (!sbyte.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out sbyte sbyteresult))
- break;
-
- result = (int)sbyteresult;
- return true;
-
- case MetadataType.Int16:
- if (!short.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out short shortresult))
- break;
-
- result = (int)shortresult;
- return true;
-
- case MetadataType.UInt16:
- if (!ushort.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out ushort ushortresult))
- break;
-
- result = (int)ushortresult;
- return true;
-
- case MetadataType.Int32:
- if (!int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int iresult))
- break;
-
- result = iresult;
- return true;
-
- case MetadataType.UInt32:
- if (!uint.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out uint uresult))
- break;
-
- result = (int)uresult;
- return true;
-
- case MetadataType.Double:
- if (!double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out double dresult))
- break;
-
- result = dresult;
- return true;
-
- case MetadataType.Single:
- if (!float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out float fresult))
- break;
-
- result = fresult;
- return true;
-
- case MetadataType.Int64:
- if (!long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long lresult))
- break;
-
- result = lresult;
- return true;
-
- case MetadataType.UInt64:
- if (!ulong.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out ulong ulresult))
- break;
-
- result = (long)ulresult;
- return true;
-
- case MetadataType.Char:
- if (!char.TryParse(value, out char chresult))
- break;
-
- result = (int)chresult;
- return true;
-
- case MetadataType.String:
- if (value is string || value == null)
- {
- result = value;
- return true;
- }
-
- break;
-
- case MetadataType.ValueType:
- if (value is string &&
- _context.TryResolve(target) is TypeDefinition typeDefinition &&
- typeDefinition.IsEnum)
- {
- var enumField = typeDefinition.Fields.Where(f => f.IsStatic && f.Name == value).FirstOrDefault();
- if (enumField != null)
- {
- result = Convert.ToInt32(enumField.Constant);
- return true;
- }
- }
-
- break;
- }
-
- result = null;
- return false;
- }
- }
-}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/README.md b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/README.md
deleted file mode 100644
index a75e53a1f949a..0000000000000
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReferenceSource/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Sources taken from https://github.com/dotnet/linker/tree/c4abaf33f967a8fa42eb20fc386b774ad74ef319/src/linker/Linker.Steps.
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedInteropStubManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedInteropStubManager.cs
index 430c77f98f905..a1e931e172539 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedInteropStubManager.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedInteropStubManager.cs
@@ -30,7 +30,7 @@ public UsageBasedInteropStubManager(InteropStateManager interopStateManager, PIn
public override void AddDependeciesDueToPInvoke(ref DependencyList dependencies, NodeFactory factory, MethodDesc method)
{
- if (method.IsPInvoke && method.OwningType is MetadataType type && MarshalHelpers.IsRuntimeMarshallingEnabled(type.Module))
+ if (method.IsPInvoke)
{
dependencies = dependencies ?? new DependencyList();
@@ -61,19 +61,12 @@ private void AddParameterMarshallingDependencies(ref DependencyList dependencies
if ((type.IsWellKnownType(WellKnownType.MulticastDelegate)
|| type == context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType))
{
- // If we hit this p/invoke as part of delegate marshalling (i.e. this is a delegate
- // that has another delegate in the signature), blame the delegate type, not the marshalling thunk.
- // This should ideally warn from the use site (e.g. where GetDelegateForFunctionPointer
- // is called) but it's currently hard to get a warning from those spots and this guarantees
- // we won't miss a spot (e.g. a p/invoke that has a delegate and that delegate contains
- // a System.Delegate parameter).
- MethodDesc reportedMethod = method;
- if (reportedMethod is Internal.IL.Stubs.DelegateMarshallingMethodThunk delegateThunkMethod)
- {
- reportedMethod = delegateThunkMethod.InvokeMethod;
- }
-
- _logger.LogWarning(reportedMethod, DiagnosticId.CorrectnessOfAbstractDelegatesCannotBeGuaranteed, DiagnosticUtilities.GetMethodSignatureDisplayName(method));
+ var message = new DiagnosticString(DiagnosticId.CorrectnessOfAbstractDelegatesCannotBeGuaranteed).GetMessage(DiagnosticUtilities.GetMethodSignatureDisplayName(method));
+ _logger.LogWarning(
+ message,
+ (int)DiagnosticId.CorrectnessOfAbstractDelegatesCannotBeGuaranteed,
+ method,
+ MessageSubCategory.AotAnalysis);
}
// struct may contain delegate fields, hence we need to add dependencies for it
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs
index 46702412ba73a..bd649904129bf 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs
@@ -15,7 +15,6 @@
using ILCompiler.Metadata;
using ILCompiler.DependencyAnalysis;
using ILCompiler.DependencyAnalysisFramework;
-using ILLink.Shared;
using FlowAnnotations = ILCompiler.Dataflow.FlowAnnotations;
using DependencyList = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore.DependencyList;
@@ -683,12 +682,16 @@ public override void NoteOverridingMethod(MethodDesc baseMethod, MethodDesc over
if (baseMethodRequiresUnreferencedCode != overridingMethodRequiresUnreferencedCode)
{
- Logger.LogWarning(overridingMethod, DiagnosticId.RequiresUnreferencedCodeAttributeMismatch, overridingMethod.GetDisplayName(), baseMethod.GetDisplayName());
+ Logger.LogWarning(
+ $"Presence of 'RequiresUnreferencedCodeAttribute' on method '{overridingMethod.GetDisplayName()}' doesn't match overridden method '{baseMethod.GetDisplayName()}'. " +
+ $"All overridden methods must have 'RequiresUnreferencedCodeAttribute'.", 2046, overridingMethod, MessageSubCategory.TrimAnalysis);
}
if (baseMethodRequiresDynamicCode != overridingMethodRequiresDynamicCode)
{
- Logger.LogWarning(overridingMethod, DiagnosticId.RequiresDynamicCodeAttributeMismatch, overridingMethod.GetDisplayName(), baseMethod.GetDisplayName());
+ Logger.LogWarning(
+ $"Presence of 'RequiresDynamicCodeAttribute' on method '{overridingMethod.GetDisplayName()}' doesn't match overridden method '{baseMethod.GetDisplayName()}'. " +
+ $"All overridden methods must have 'RequiresDynamicCodeAttribute'.", 2046, overridingMethod, MessageSubCategory.AotAnalysis);
}
if (baseMethodRequiresDataflow || overridingMethodRequiresDataflow)
@@ -970,7 +973,7 @@ public AssemblyFeatureInfo(EcmaModule module, IReadOnlyDictionary
}
}
- private class LinkAttributesReader : ProcessXmlBase
+ private class LinkAttributesReader : ProcessLinkerXmlBase
{
private readonly HashSet _removedAttributes;
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/Stubs/PInvokeILProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/Stubs/PInvokeILProvider.cs
index 93fb4cc376c07..830fb11d1ef21 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/Stubs/PInvokeILProvider.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/Stubs/PInvokeILProvider.cs
@@ -30,9 +30,9 @@ public override MethodIL GetMethodIL(MethodDesc method)
return PInvokeILEmitter.EmitIL(method, _pInvokeILEmitterConfiguration, _interopStateManager);
}
- public MethodDesc GetCalliStub(MethodSignature signature, ModuleDesc moduleContext)
+ public MethodDesc GetCalliStub(MethodSignature signature)
{
- return _interopStateManager.GetPInvokeCalliStub(signature, moduleContext);
+ return _interopStateManager.GetPInvokeCalliStub(signature);
}
public string GetDirectCallExternName(MethodDesc method)
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
index d2df0a825ca40..3420564b0715e 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
@@ -373,7 +373,6 @@
-
@@ -528,7 +527,6 @@
-
diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompiler.Diagnostics.csproj b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompiler.Diagnostics.csproj
index 0d1b23ad73b3c..97c97bb7de720 100644
--- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompiler.Diagnostics.csproj
+++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompiler.Diagnostics.csproj
@@ -15,7 +15,6 @@
binaries are up to date and which are stale. -->
false
Debug;Release;Checked
- true
diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompilerComWrappers.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompilerComWrappers.cs
deleted file mode 100644
index d9972da41f76c..0000000000000
--- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ILCompilerComWrappers.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-
-using System;
-using System.Collections;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace Microsoft.DiaSymReader
-{
- internal unsafe sealed class ILCompilerComWrappers : ComWrappers
- {
- protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
- {
- // passing the managed object to COM is not currently supported
- throw new NotImplementedException();
- }
-
- protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags)
- {
- // Assert use of the UniqueInstance flag since the returned Native Object Wrapper always
- // supports IDisposable and its Dispose will always release and suppress finalization.
- // If the wrapper doesn't always support IDisposable the assert can be relaxed.
- Debug.Assert(flags.HasFlag(CreateObjectFlags.UniqueInstance));
-
- // Throw an exception if the type is not supported by the implementation.
- // Null can be returned as well, but an ArgumentNullException will be thrown for
- // the consumer of this ComWrappers instance.
- return SymNgenWriterWrapper.CreateIfSupported(externalComObject) ?? throw new NotSupportedException();
- }
-
- protected override void ReleaseObjects(IEnumerable objects) => throw new NotImplementedException();
- }
-}
\ No newline at end of file
diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ISymNGenWriter.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ISymNGenWriter.cs
index 40702fd187a75..4c4b6b97d60a9 100644
--- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/ISymNGenWriter.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/ISymNGenWriter.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-#pragma warning disable 436 // SuppressUnmanagedCodeSecurityAttribute defined in source and mscorlib
+#pragma warning disable 436 // SuppressUnmanagedCodeSecurityAttribute defined in source and mscorlib
using System;
using System.Collections.Generic;
@@ -11,39 +11,9 @@
namespace Microsoft.DiaSymReader
{
- ///
- /// IUnknown COM type for writing NGen PDBs
- ///
- ///
- ///
- /// [
- /// object,
- /// uuid(d682fd12-43de-411c-811b-be8404cea126),
- /// pointer_default(unique)
- /// ]
- /// interface ISymNGenWriter : IUnknown
- /// {
- /// /*
- /// * Add a new public symbol to the NGEN PDB.
- /// */
- /// HRESULT AddSymbol([in] BSTR pSymbol,
- /// [in] USHORT iSection,
- /// [in] ULONGLONG rva);
- ///
- /// /*
- /// * Adds a new section to the NGEN PDB.
- /// */
- /// HRESULT AddSection([in] USHORT iSection,
- /// [in] USHORT flags,
- /// [in] long offset,
- /// [in] long cb);
- /// };
- ///
- ///
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("D682FD12-43dE-411C-811B-BE8404CEA126"), SuppressUnmanagedCodeSecurity]
internal interface ISymNGenWriter
{
- public static readonly Guid IID = new Guid("D682FD12-43dE-411C-811B-BE8404CEA126");
-
// Add a new public symbol to the NGEN PDB.
void AddSymbol([MarshalAs(UnmanagedType.BStr)] string pSymbol,
ushort iSection,
@@ -76,46 +46,9 @@ internal enum OMF : ushort
}
- ///
- /// IUnknown COM type for writing NGen PDBs
- ///
- ///
- ///
- /// [
- /// object,
- /// local,
- /// uuid(B029E51B-4C55-4fe2-B993-9F7BC1F10DB4),
- /// pointer_default(unique)
- /// ]
- /// interface ISymNGenWriter2 : ISymNGenWriter
- /// {
- /// HRESULT OpenModW([in] const wchar_t* wszModule,
- /// [in] const wchar_t* wszObjFile,
- /// [out] BYTE** ppmod);
- ///
- /// HRESULT CloseMod([in] BYTE* pmod);
- ///
- /// HRESULT ModAddSymbols([in] BYTE* pmod, [in] BYTE* pbSym, [in] long cb);
- ///
- /// HRESULT ModAddSecContribEx(
- /// [in] BYTE* pmod,
- /// [in] USHORT isect,
- /// [in] long off,
- /// [in] long cb,
- /// [in] ULONG dwCharacteristics,
- /// [in] DWORD dwDataCrc,
- /// [in] DWORD dwRelocCrc);
- ///
- /// HRESULT QueryPDBNameExW(
- /// [out, size_is(cchMax)] wchar_t wszPDB[],
- /// [in] SIZE_T cchMax);
- /// };
- ///
- ///
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B029E51B-4C55-4fe2-B993-9F7BC1F10DB4"), SuppressUnmanagedCodeSecurity]
internal interface ISymNGenWriter2 : ISymNGenWriter
{
- public readonly static new Guid IID = new Guid("B029E51B-4C55-4fe2-B993-9F7BC1F10DB4");
-
// Add a new public symbol to the NGEN PDB.
new void AddSymbol([MarshalAs(UnmanagedType.BStr)] string pSymbol,
ushort iSection,
@@ -145,7 +78,7 @@ void ModAddSecContribEx(
uint dwRelocCrc);
void QueryPDBNameExW(
- [MarshalAs(UnmanagedType.LPWStr)] char[] pdb,
+ [MarshalAs(UnmanagedType.LPWStr)] StringBuilder pdb,
IntPtr cchMax);
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs
index be0d8af909f72..a16d5bf19a8e6 100644
--- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs
@@ -89,7 +89,7 @@ public class PdbWriter
Dictionary _documentToChecksumOffsetMapping;
UIntPtr _pdbMod;
- SymNgenWriterWrapper _ngenWriter;
+ ISymNGenWriter2 _ngenWriter;
static PdbWriter()
{
@@ -116,7 +116,7 @@ private static IntPtr DllImportResolver(string libraryName, Assembly assembly, D
private extern static void CreateNGenPdbWriter(
[MarshalAs(UnmanagedType.LPWStr)] string ngenImagePath,
[MarshalAs(UnmanagedType.LPWStr)] string pdbPath,
- out IntPtr ngenPdbWriterPtr);
+ [MarshalAs(UnmanagedType.Interface)] out ISymNGenWriter2 ngenPdbWriter);
public PdbWriter(string pdbPath, PDBExtraData pdbExtraData, TargetDetails target)
{
@@ -138,14 +138,23 @@ public void WritePDBData(string dllPath, IEnumerable methods)
{
try
{
- WritePDBDataHelper(dllPath, methods);
+ try
+ {
+ WritePDBDataHelper(dllPath, methods);
+ }
+ finally
+ {
+ if ((_ngenWriter != null) && (_pdbMod != UIntPtr.Zero))
+ {
+ _ngenWriter.CloseMod(_pdbMod);
+ }
+ }
}
finally
{
- if ((_ngenWriter != null) && (_pdbMod != UIntPtr.Zero))
+ if (_ngenWriter != null)
{
- _ngenWriter.CloseMod(_pdbMod);
- _ngenWriter?.Dispose();
+ Marshal.FinalReleaseComObject(_ngenWriter);
}
}
@@ -208,16 +217,14 @@ private void WritePDBDataHelper(string dllPath, IEnumerable methods)
// Delete any preexisting PDB file upfront, otherwise CreateNGenPdbWriter silently opens it
File.Delete(_pdbFilePath);
- var comWrapper = new ILCompilerComWrappers();
- CreateNGenPdbWriter(dllPath, _pdbFilePath, out var pdbWriterInst);
- _ngenWriter = (SymNgenWriterWrapper)comWrapper.GetOrCreateObjectForComInstance(pdbWriterInst, CreateObjectFlags.UniqueInstance);
+ CreateNGenPdbWriter(dllPath, _pdbFilePath, out _ngenWriter);
{
// PDB file is now created. Get its path and update _pdbFilePath so the PDB file
// can be deleted if we don't make it successfully to the end.
- const int capacity = 1024;
- var pdbFilePathBuilder = new char[capacity];
- _ngenWriter.QueryPDBNameExW(pdbFilePathBuilder, new IntPtr(capacity - 1) /* remove 1 byte for null */);
+ StringBuilder pdbFilePathBuilder = new StringBuilder();
+ pdbFilePathBuilder.Capacity = 1024;
+ _ngenWriter.QueryPDBNameExW(pdbFilePathBuilder, new IntPtr(pdbFilePathBuilder.Capacity));
_pdbFilePath = pdbFilePathBuilder.ToString();
}
@@ -421,9 +428,9 @@ private void WriteCompilerVersion()
byte iLanguage = (byte)CV_CFL_LANG.CV_CFL_MSIL;
writer.Write(iLanguage);
// Write rest of flags
- writer.Write((byte)0);
- writer.Write((byte)0);
- writer.Write((byte)0);
+ writer.Write((byte)0);
+ writer.Write((byte)0);
+ writer.Write((byte)0);
switch (_target.Architecture)
{
diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs
deleted file mode 100644
index 8a1166f43a39b..0000000000000
--- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-
-using System;
-using System.Runtime.InteropServices;
-using System.Text;
-
-#nullable enable
-
-namespace Microsoft.DiaSymReader
-{
- internal class SymNgenWriterWrapper : ISymNGenWriter2, IDisposable
- {
- private bool _isDisposed = false;
- public IntPtr ISymNGenWriter2Inst { get; }
-
- private SymNgenWriterWrapper(IntPtr writer2Inst)
- {
- ISymNGenWriter2Inst = writer2Inst;
- }
-
- public static SymNgenWriterWrapper? CreateIfSupported(IntPtr ptr)
- {
- var iid = ISymNGenWriter2.IID;
- int hr = Marshal.QueryInterface(ptr, ref iid, out IntPtr ngenWriterInst);
- if (hr != 0)
- {
- return null;
- }
-
- return new SymNgenWriterWrapper(ngenWriterInst);
- }
-
- ~SymNgenWriterWrapper()
- {
- DisposeInternal();
- }
-
- public void Dispose()
- {
- DisposeInternal();
- GC.SuppressFinalize(this);
- }
-
- private void DisposeInternal()
- {
- if (_isDisposed)
- {
- return;
- }
- Marshal.Release(ISymNGenWriter2Inst);
- _isDisposed = true;
- }
-
- public unsafe void AddSymbol(string pSymbol, ushort iSection, ulong rva)
- {
- IntPtr strLocal = Marshal.StringToBSTR(pSymbol);
- var inst = ISymNGenWriter2Inst;
- var func = (delegate* unmanaged)(*(*(void***)inst + 3 /* ISymNGenWriter2.AddSymbol slot */));
- int hr = func(inst, strLocal, iSection, rva);
- Marshal.FreeBSTR(strLocal);
- if (hr != 0)
- {
- Marshal.ThrowExceptionForHR(hr);
- }
- }
-
- public unsafe void AddSection(ushort iSection, OMF flags, int offset, int cb)
- {
- var inst = ISymNGenWriter2Inst;
- var func = (delegate* unmanaged)(*(*(void***)inst + 4));
- int hr = func(inst, iSection, flags, offset, cb);
- if (hr != 0)
- {
- Marshal.ThrowExceptionForHR(hr);
- }
- }
-
- public unsafe void OpenModW(string wszModule, string wszObjFile, out UIntPtr ppmod)
- {
- var inst = ISymNGenWriter2Inst;
- fixed (char* wszModulePtr = wszModule)
- fixed (char* wszObjFilePtr = wszObjFile)
- {
- UIntPtr ppmodPtr;
- var func = (delegate* unmanaged)(*(*(void***)inst + 5));
- int hr = func(inst, wszModulePtr, wszObjFilePtr, &ppmodPtr);
- ppmod = ppmodPtr;
- if (hr != 0)
- {
- Marshal.ThrowExceptionForHR(hr);
- }
- }
- }
-
- public unsafe void CloseMod(UIntPtr pmod)
- {
- var inst = ISymNGenWriter2Inst;
- var func = (delegate* unmanaged)(*(*(void***)inst + 6));
- int hr = func(inst, pmod);
- if (hr != 0)
- {
- Marshal.ThrowExceptionForHR(hr);
- }
- }
-
- public unsafe void ModAddSymbols(UIntPtr pmod, byte[] pbSym, int cb)
- {
- fixed (byte* pbSymPtr = pbSym)
- {
- var pbSymLocal = (IntPtr)pbSymPtr;
- var inst = ISymNGenWriter2Inst;
- var func = (delegate* unmanaged)(*(*(void***)inst + 7));
- int hr = func(inst, pmod, pbSymLocal, cb);
- if (hr != 0)
- {
- Marshal.ThrowExceptionForHR(hr);
- }
- }
- }
-
- public unsafe void ModAddSecContribEx(UIntPtr pmod, ushort isect, int off, int cb, uint dwCharacteristics, uint dwDataCrc, uint dwRelocCrc)
- {
- var inst = ISymNGenWriter2Inst;
- var func = (delegate* unmanaged)(*(*(void***)inst + 8));
- int hr = func(inst, pmod, isect, off, cb, dwCharacteristics, dwDataCrc, dwRelocCrc);
- if (hr != 0)
- {
- Marshal.ThrowExceptionForHR(hr);
- }
- }
-
- public unsafe void QueryPDBNameExW(char[] pdb, IntPtr cchMax)
- {
- fixed (char* pdbPtr = pdb)
- {
- var pdbLocal = (IntPtr)pdbPtr;
- var inst = ISymNGenWriter2Inst;
- var func = (delegate* unmanaged)(*(*(void***)inst + 9));
- int hr = func(inst, pdbPtr, cchMax);
- if (hr != 0)
- {
- Marshal.ThrowExceptionForHR(hr);
- }
- }
- }
-
- void ISymNGenWriter.AddSymbol(string pSymbol, ushort iSection, ulong rva) => AddSymbol(pSymbol, iSection, rva);
- void ISymNGenWriter.AddSection(ushort iSection, OMF flags, int offset, int cb) => AddSection(iSection, flags, offset, cb);
- }
-}
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs
index a8ff518ac7591..e8596cf24c894 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs
@@ -46,17 +46,15 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
}
ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);
- byte[] rvaData = GetRvaData(factory.Target.PointerSize, out int requiredAlignment);
- builder.RequireInitialAlignment(requiredAlignment);
+ builder.RequireInitialPointerAlignment();
builder.AddSymbol(this);
- builder.EmitBytes(rvaData);
+ builder.EmitBytes(GetRvaData(factory.Target.PointerSize));
return builder.ToObjectData();
}
- private unsafe byte[] GetRvaData(int targetPointerSize, out int requiredAlignment)
+ private unsafe byte[] GetRvaData(int targetPointerSize)
{
int size = 0;
- requiredAlignment = targetPointerSize;
MetadataReader metadataReader = _module.MetadataReader;
BlobReader metadataBlob = new BlobReader(_module.PEReader.GetMetadata().Pointer, _module.PEReader.GetMetadata().Length);
@@ -82,7 +80,6 @@ private unsafe byte[] GetRvaData(int targetPointerSize, out int requiredAlignmen
Debug.Assert(field.HasRva);
int currentSize = field.FieldType.GetElementSize().AsInt;
- requiredAlignment = Math.Max(requiredAlignment, (field.FieldType as MetadataType)?.GetClassLayout().PackingSize ?? 1);
if (currentSize > size)
{
// We need to handle overlapping fields by reusing blobs based on the rva, and just update
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs
index 46ed11d236a95..8f468f78b3977 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs
@@ -24,6 +24,7 @@ public sealed class ReadyToRunCodegenCompilationBuilder : CompilationBuilder
private readonly IEnumerable _inputFiles;
private readonly string _compositeRootPath;
private bool _ibcTuning;
+ private bool _resilient;
private bool _generateMapFile;
private bool _generateMapCsvFile;
private bool _generatePdbFile;
@@ -116,6 +117,12 @@ public ReadyToRunCodegenCompilationBuilder UseIbcTuning(bool ibcTuning)
return this;
}
+ public ReadyToRunCodegenCompilationBuilder UseResilience(bool resilient)
+ {
+ _resilient = resilient;
+ return this;
+ }
+
public ReadyToRunCodegenCompilationBuilder UseProfileData(ProfileDataManager profileData)
{
_profileData = profileData;
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunHashCode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunHashCode.cs
index 9380a829b8f3c..e506bb8b3b6ef 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunHashCode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunHashCode.cs
@@ -34,10 +34,10 @@ public static int NameHashCode(string name)
byte[] src = Encoding.UTF8.GetBytes(name);
for (int i = 0; i < src.Length; i += 2)
{
- hash1 = unchecked(hash1 + RotateLeft(hash1, 5)) ^ (int)unchecked((sbyte)src[i]);
+ hash1 = unchecked(hash1 + RotateLeft(hash1, 5)) ^ src[i];
if (i + 1 < src.Length)
{
- hash2 = unchecked(hash2 + RotateLeft(hash2, 5)) ^ (int)unchecked((sbyte)src[i + 1]);
+ hash2 = unchecked(hash2 + RotateLeft(hash2, 5)) ^ src[i + 1];
}
else
{
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs
index 6fc1687d7a7f9..a8e42ec37b9bc 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/IL/Stubs/PInvokeILEmitter.cs
@@ -46,13 +46,6 @@ private void EmitPInvokeCall(PInvokeILCodeStreams ilCodeStreams)
// if the SetLastError flag is set in DllImport, clear the error code before doing P/Invoke
if (_importMetadata.Flags.SetLastError)
{
- if (!MarshalHelpers.IsRuntimeMarshallingEnabled(((MetadataType)_targetMethod.OwningType).Module))
- {
- // When runtime marshalling is disabled, we don't support generating the stub IL
- // in Ready-to-Run so we can correctly throw an exception at runtime when the user tries to
- // use SetLastError=true when marshalling is disabled.
- throw new NotSupportedException();
- }
callsiteSetupCodeStream.Emit(ILOpcode.call, emitter.NewToken(
stubHelpersType.GetKnownMethod("ClearLastError", null)));
}
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
index 6c7d67517a9ee..5154db358a8b8 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
@@ -283,5 +283,4 @@
-
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs
index ddb1d24c1b535..927148cf006e2 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Interop/IL/Marshaller.ReadyToRun.cs
@@ -43,8 +43,7 @@ protected static Marshaller CreateMarshaller(MarshallerKind kind)
private static Marshaller[] GetMarshallers(
MethodSignature methodSig,
PInvokeFlags flags,
- ParameterMetadata[] parameterMetadataArray,
- bool runtimeMarshallingEnabled)
+ ParameterMetadata[] parameterMetadataArray)
{
Marshaller[] marshallers = new Marshaller[methodSig.Length + 1];
@@ -65,55 +64,39 @@ private static Marshaller[] GetMarshallers(
}
TypeDesc parameterType = (i == 0) ? methodSig.ReturnType : methodSig[i - 1]; //first item is the return type
- if (runtimeMarshallingEnabled)
- {
- marshallers[i] = CreateMarshaller(parameterType,
- parameterIndex,
- methodSig.GetEmbeddedSignatureData(),
- MarshallerType.Argument,
- parameterMetadata.MarshalAsDescriptor,
- MarshalDirection.Forward,
- marshallers,
- parameterMetadata.Index,
- flags,
- parameterMetadata.In,
- parameterMetadata.Out,
- parameterMetadata.Return);
- }
- else
- {
- marshallers[i] = CreateDisabledMarshaller(
- parameterType,
- parameterIndex,
- MarshallerType.Argument,
- MarshalDirection.Forward,
- marshallers,
- parameterMetadata.Index,
- flags,
- parameterMetadata.Return);
- }
+ marshallers[i] = CreateMarshaller(parameterType,
+ parameterIndex,
+ methodSig.GetEmbeddedSignatureData(),
+ MarshallerType.Argument,
+ parameterMetadata.MarshalAsDescriptor,
+ MarshalDirection.Forward,
+ marshallers,
+ parameterMetadata.Index,
+ flags,
+ parameterMetadata.In,
+ parameterMetadata.Out,
+ parameterMetadata.Return);
}
return marshallers;
}
+
public static Marshaller[] GetMarshallersForMethod(MethodDesc targetMethod)
{
Debug.Assert(targetMethod.IsPInvoke);
return GetMarshallers(
targetMethod.Signature,
targetMethod.GetPInvokeMethodMetadata().Flags,
- targetMethod.GetParameterMetadata(),
- MarshalHelpers.IsRuntimeMarshallingEnabled(((MetadataType)targetMethod.OwningType).Module));
+ targetMethod.GetParameterMetadata());
}
- public static Marshaller[] GetMarshallersForSignature(MethodSignature methodSig, ParameterMetadata[] paramMetadata, ModuleDesc moduleContext)
+ public static Marshaller[] GetMarshallersForSignature(MethodSignature methodSig, ParameterMetadata[] paramMetadata)
{
return GetMarshallers(
methodSig,
new PInvokeFlags(PInvokeAttributes.None),
- paramMetadata,
- MarshalHelpers.IsRuntimeMarshallingEnabled(moduleContext));
+ paramMetadata);
}
public static bool IsMarshallingRequired(MethodDesc targetMethod)
@@ -145,9 +128,9 @@ public static bool IsMarshallingRequired(MethodDesc targetMethod)
return false;
}
- public static bool IsMarshallingRequired(MethodSignature methodSig, ParameterMetadata[] paramMetadata, ModuleDesc moduleContext)
+ public static bool IsMarshallingRequired(MethodSignature methodSig, ParameterMetadata[] paramMetadata)
{
- Marshaller[] marshallers = GetMarshallersForSignature(methodSig, paramMetadata, moduleContext);
+ Marshaller[] marshallers = GetMarshallersForSignature(methodSig, paramMetadata);
for (int i = 0; i < marshallers.Length; i++)
{
if (marshallers[i].IsMarshallingRequired())
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
index c2dcc6b397016..f8282ab82cd27 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
@@ -1811,7 +1811,7 @@ private void ceeInfoGetCallInfo(
pResult->wrapperDelegateInvoke = false;
- Get_CORINFO_SIG_INFO(methodToCall, &pResult->sig, scope: null, useInstantiatingStub);
+ Get_CORINFO_SIG_INFO(methodToCall, &pResult->sig, useInstantiatingStub);
}
private uint getMethodAttribs(CORINFO_METHOD_STRUCT_* ftn)
@@ -2579,7 +2579,7 @@ private bool pInvokeMarshalingRequired(CORINFO_METHOD_STRUCT_* handle, CORINFO_S
else
{
var sig = HandleToObject(callSiteSig->methodSignature);
- return Marshaller.IsMarshallingRequired(sig, Array.Empty(), ((MetadataType)HandleToObject(callSiteSig->scope).OwningMethod.OwningType).Module);
+ return Marshaller.IsMarshallingRequired(sig, Array.Empty());
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs
index 7e2b624a3131f..0d8b11c51f82e 100644
--- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs
+++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs
@@ -9,7 +9,6 @@
using ILCompiler.DependencyAnalysis;
using ILCompiler.DependencyAnalysisFramework;
-using ILLink.Shared;
using Internal.IL;
using Internal.IL.Stubs;
@@ -93,9 +92,6 @@ protected override void CompileInternal(string outputFile, ObjectDumper dumper)
NodeFactory.SetMarkingComplete();
ObjectWritingOptions options = default;
- if ((_compilationOptions & RyuJitCompilationOptions.UseDwarf5) != 0)
- options |= ObjectWritingOptions.UseDwarf5;
-
if (_debugInformationProvider is not NullDebugInformationProvider)
options |= ObjectWritingOptions.GenerateDebugInfo;
@@ -199,6 +195,8 @@ private void CompileSingleMethod(CorInfoImpl corInfo, MethodCodeNode methodCodeN
if (exception != null)
{
+ // TODO: fail compilation if a switch was passed
+
// Try to compile the method again, but with a throwing method body this time.
MethodIL throwingIL = TypeSystemThrowingILEmitter.EmitIL(method, exception);
corInfo.CompileMethod(methodCodeNodeNeedingCode, throwingIL);
@@ -207,12 +205,12 @@ private void CompileSingleMethod(CorInfoImpl corInfo, MethodCodeNode methodCodeN
&& method.OwningType is MetadataType mdOwningType
&& mdOwningType.HasCustomAttribute("System.Runtime.InteropServices", "ClassInterfaceAttribute"))
{
- Logger.LogWarning(method, DiagnosticId.COMInteropNotSupportedInFullAOT);
+ Logger.LogWarning("COM interop is not supported with full ahead of time compilation", 3052, method, MessageSubCategory.AotAnalysis);
}
- if ((_compilationOptions & RyuJitCompilationOptions.UseResilience) != 0)
- Logger.LogMessage($"Ignoring unresolved method {method}, because: {exception.Message}");
else
- Logger.LogError($"Method will always throw because: {exception.Message}", 1005, method, MessageSubCategory.AotAnalysis);
+ {
+ Logger.LogWarning($"Method will always throw because: {exception.Message}", 1005, method, MessageSubCategory.AotAnalysis);
+ }
}
}
@@ -244,7 +242,5 @@ public enum RyuJitCompilationOptions
{
MethodBodyFolding = 0x1,
ControlFlowGuardAnnotations = 0x2,
- UseDwarf5 = 0x4,
- UseResilience = 0x8,
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs
index a1446f9d3ff27..8b753c7103994 100644
--- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs
+++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs
@@ -110,12 +110,6 @@ public override ICompilation ToCompilation()
if ((_mitigationOptions & SecurityMitigationOptions.ControlFlowGuardAnnotations) != 0)
options |= RyuJitCompilationOptions.ControlFlowGuardAnnotations;
- if (_useDwarf5)
- options |= RyuJitCompilationOptions.UseDwarf5;
-
- if (_resilient)
- options |= RyuJitCompilationOptions.UseResilience;
-
var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, _interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider, GetPreinitializationManager());
JitConfigProvider.Initialize(_context.Target, jitFlagBuilder.ToArray(), _ryujitOptions);
diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs
index 1b1fbdf550777..5966efead0066 100644
--- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs
+++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs
@@ -1027,7 +1027,7 @@ private CorInfoHelpFunc getNewHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken,
TypeDesc type = HandleToObject(pResolvedToken.hClass);
Debug.Assert(!type.IsString && !type.IsArray && !type.IsCanonicalDefinitionType(CanonicalFormKind.Any));
-
+
pHasSideEffects = type.HasFinalizer;
if (type.RequiresAlign8())
@@ -1520,7 +1520,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO
targetIsFatFunctionPointer |= (flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_CALLVIRT) != 0 && !(pResult->kind == CORINFO_CALL_KIND.CORINFO_CALL);
- Get_CORINFO_SIG_INFO(targetMethod, &pResult->sig, scope: null, targetIsFatFunctionPointer);
+ Get_CORINFO_SIG_INFO(targetMethod, &pResult->sig, targetIsFatFunctionPointer);
if (useFatCallTransform)
{
pResult->sig.flags |= CorInfoSigInfoFlags.CORINFO_SIGFLAG_FAT_CALL;
@@ -1531,7 +1531,7 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO
if (pResult->hMethod != pResolvedToken.hMethod)
{
pResult->verMethodFlags = getMethodAttribsInternal(targetMethod);
- Get_CORINFO_SIG_INFO(targetMethod, &pResult->verSig, scope: null);
+ Get_CORINFO_SIG_INFO(targetMethod, &pResult->verSig);
}
else
{
@@ -1791,9 +1791,7 @@ private bool pInvokeMarshalingRequired(CORINFO_METHOD_STRUCT_* handle, CORINFO_S
#if DEBUG
MethodSignature methodSignature = (MethodSignature)HandleToObject((IntPtr)callSiteSig->pSig);
- MethodDesc stub = _compilation.PInvokeILProvider.GetCalliStub(
- methodSignature,
- ((MetadataType)HandleToObject(callSiteSig->scope).OwningMethod.OwningType).Module);
+ MethodDesc stub = _compilation.PInvokeILProvider.GetCalliStub(methodSignature);
Debug.Assert(!IsPInvokeStubRequired(stub));
#endif
@@ -1827,9 +1825,7 @@ private bool convertPInvokeCalliToCall(ref CORINFO_RESOLVED_TOKEN pResolvedToken
if ((signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) == 0)
return false;
- MethodDesc stub = _compilation.PInvokeILProvider.GetCalliStub(
- signature,
- ((MetadataType)methodIL.OwningMethod.OwningType).Module);
+ MethodDesc stub = _compilation.PInvokeILProvider.GetCalliStub(signature);
if (!mustConvert && !IsPInvokeStubRequired(stub))
return false;
diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CastingTests.cs b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CastingTests.cs
index 4bcf3432f522f..f6cd2e187d46c 100644
--- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CastingTests.cs
+++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CastingTests.cs
@@ -202,21 +202,6 @@ public void TestNullableCasting()
Assert.True(intType.CanCastTo(nullableOfIntType));
}
- [Fact]
- public void TestGenericParameterArrayCasting()
- {
- TypeDesc baseArrayType = _testModule.GetType("Casting", "Base").MakeArrayType();
- TypeDesc iFooArrayType = _testModule.GetType("Casting", "IFoo").MakeArrayType();
-
- TypeDesc paramArrayWithBaseClassConstraint =
- _testModule.GetType("Casting", "ClassWithBaseClassConstraint`1").Instantiation[0].MakeArrayType();
- TypeDesc paramArrayWithInterfaceConstraint =
- _testModule.GetType("Casting", "ClassWithInterfaceConstraint`1").Instantiation[0].MakeArrayType();
-
- Assert.True(paramArrayWithBaseClassConstraint.CanCastTo(baseArrayType));
- Assert.False(paramArrayWithInterfaceConstraint.CanCastTo(iFooArrayType));
- }
-
[Fact]
public void TestRecursiveCanCast()
{
diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/Casting.cs b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/Casting.cs
index 03ce4ae4332cd..a6ae700e942a1 100644
--- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/Casting.cs
+++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/CoreTestAssembly/Casting.cs
@@ -3,8 +3,6 @@
namespace Casting
{
- class Base { }
-
interface IFoo { }
interface IContravariant { }
@@ -23,8 +21,6 @@ class ClassWithNoConstraint { }
class ClassWithValueTypeConstraint where T : struct { }
- class ClassWithBaseClassConstraint where T : Base { }
-
class ClassWithInterfaceConstraint where T : IFoo { }
class ClassWithRecursiveImplementation : IContravariant> { }
diff --git a/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj b/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj
index 6c5a4a6d377d8..6c559924f405c 100644
--- a/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj
+++ b/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj
@@ -1,4 +1,4 @@
-
+
ilc
true
@@ -121,6 +121,10 @@
On Linux renaming the library makes it difficult to debug it. -->
-
+
diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs
index 51400a9e939be..e973c05b08c2c 100644
--- a/src/coreclr/tools/aot/ILCompiler/Program.cs
+++ b/src/coreclr/tools/aot/ILCompiler/Program.cs
@@ -61,7 +61,6 @@ internal class Program
private string _instructionSet;
private string _guard;
private int _maxGenericCycle = CompilerTypeSystemContext.DefaultGenericCycleCutoffPoint;
- private bool _useDwarf5;
private string _singleMethodTypeName;
private string _singleMethodName;
@@ -85,8 +84,6 @@ internal class Program
private IReadOnlyList _directPInvokeLists = Array.Empty();
- private bool _resilient;
-
private IReadOnlyList _rootedAssemblies = Array.Empty();
private IReadOnlyList _conditionallyRootedAssemblies = Array.Empty();
private IReadOnlyList _trimmedAssemblies = Array.Empty();
@@ -181,7 +178,6 @@ private ArgumentSyntax ParseCommandLine(string[] args)
syntax.DefineOption("Ot", ref optimizeTime, "Enable optimizations, favor code speed");
syntax.DefineOptionList("m|mibc", ref _mibcFilePaths, "Mibc file(s) for profile guided optimization"); ;
syntax.DefineOption("g", ref _enableDebugInfo, "Emit debugging information");
- syntax.DefineOption("gdwarf-5", ref _useDwarf5, "Generate source-level debug information with dwarf version 5");
syntax.DefineOption("nativelib", ref _nativeLib, "Compile as static or shared library");
syntax.DefineOption("exportsfile", ref _exportsFile, "File to write exported method definitions");
syntax.DefineOption("dgmllog", ref _dgmlLogFileName, "Save result of dependency analysis as DGML");
@@ -192,7 +188,6 @@ private ArgumentSyntax ParseCommandLine(string[] args)
syntax.DefineOption("systemmodule", ref _systemModuleName, "System module name (default: System.Private.CoreLib)");
syntax.DefineOption("multifile", ref _multiFile, "Compile only input files (do not compile referenced assemblies)");
syntax.DefineOption("waitfordebugger", ref waitForDebugger, "Pause to give opportunity to attach debugger");
- syntax.DefineOption("resilient", ref _resilient, "Ignore unresolved types, methods, and assemblies. Defaults to false");
syntax.DefineOptionList("codegenopt", ref _codegenOptions, "Define a codegen option");
syntax.DefineOptionList("rdxml", ref _rdXmlFilePaths, "RD.XML file(s) for compilation");
syntax.DefineOption("map", ref _mapFileName, "Generate a map file");
@@ -774,8 +769,7 @@ static string ILLinkify(string rootedAssembly)
.UseCompilationRoots(compilationRoots)
.UseOptimizationMode(_optimizationMode)
.UseSecurityMitigationOptions(securityMitigationOptions)
- .UseDebugInfoProvider(debugInfoProvider)
- .UseDwarf5(_useDwarf5);
+ .UseDebugInfoProvider(debugInfoProvider);
if (scanResults != null)
{
@@ -804,8 +798,6 @@ static string ILLinkify(string rootedAssembly)
builder.UseMethodImportationErrorProvider(scanResults.GetMethodImportationErrorProvider());
}
- builder.UseResilience(_resilient);
-
ICompilation compilation = builder.ToCompilation();
ObjectDumper dumper = _mapFileName != null ? new ObjectDumper(_mapFileName) : null;
diff --git a/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj b/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj
index c0df3bfd2c6ee..52b0f44fc4891 100644
--- a/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj
+++ b/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj
@@ -9,7 +9,7 @@
linux-x64;win-x64;osx-x64
Debug;Release;Checked
true
- false
+ 649;169;414
$"IL{(int)diagnosticId}";
-
- public static string GetDiagnosticSubcategory(this DiagnosticId diagnosticId) =>
- (int)diagnosticId switch
- {
- 2026 => MessageSubCategory.TrimAnalysis,
- 2032 => MessageSubCategory.TrimAnalysis,
- 2041 => MessageSubCategory.TrimAnalysis,
- 2042 => MessageSubCategory.TrimAnalysis,
- 2043 => MessageSubCategory.TrimAnalysis,
- 2045 => MessageSubCategory.TrimAnalysis,
- 2046 => MessageSubCategory.TrimAnalysis,
- 2050 => MessageSubCategory.TrimAnalysis,
- >= 2055 and <= 2099 => MessageSubCategory.TrimAnalysis,
- 2103 => MessageSubCategory.TrimAnalysis,
- 2106 => MessageSubCategory.TrimAnalysis,
- 2107 => MessageSubCategory.TrimAnalysis,
- >= 2109 and <= 2116 => MessageSubCategory.TrimAnalysis,
- >= 3050 and <= 3052 => MessageSubCategory.AotAnalysis,
- >= 3054 and <= 3055 => MessageSubCategory.AotAnalysis,
- _ => MessageSubCategory.None,
- };
}
}
diff --git a/src/coreclr/tools/aot/ILLink.Shared/DiagnosticString.cs b/src/coreclr/tools/aot/ILLink.Shared/DiagnosticString.cs
index f14b58b060083..103b93ed28bb0 100644
--- a/src/coreclr/tools/aot/ILLink.Shared/DiagnosticString.cs
+++ b/src/coreclr/tools/aot/ILLink.Shared/DiagnosticString.cs
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System;
-
namespace ILLink.Shared
{
public readonly struct DiagnosticString
@@ -13,15 +11,15 @@ public readonly struct DiagnosticString
public DiagnosticString(DiagnosticId diagnosticId)
{
var resourceManager = SharedStrings.ResourceManager;
- _titleFormat = resourceManager.GetString($"{diagnosticId}Title") ?? throw new InvalidOperationException($"{diagnosticId} does not have a matching resource called {diagnosticId}Title");
- _messageFormat = resourceManager.GetString($"{diagnosticId}Message") ?? throw new InvalidOperationException($"{diagnosticId} does not have a matching resource called {diagnosticId}Message");
+ _titleFormat = resourceManager.GetString($"{diagnosticId}Title") ?? string.Empty;
+ _messageFormat = resourceManager.GetString($"{diagnosticId}Message") ?? string.Empty;
}
public DiagnosticString(string diagnosticResourceStringName)
{
var resourceManager = SharedStrings.ResourceManager;
- _titleFormat = resourceManager.GetString($"{diagnosticResourceStringName}Title") ?? throw new InvalidOperationException($"{diagnosticResourceStringName} does not have a matching resource called {diagnosticResourceStringName}Title");
- _messageFormat = resourceManager.GetString($"{diagnosticResourceStringName}Message") ?? throw new InvalidOperationException($"{diagnosticResourceStringName} does not have a matching resource called {diagnosticResourceStringName}Message");
+ _titleFormat = resourceManager.GetString($"{diagnosticResourceStringName}Title") ?? string.Empty;
+ _messageFormat = resourceManager.GetString($"{diagnosticResourceStringName}Message") ?? string.Empty;
}
public string GetMessage(params string[] args) =>
diff --git a/src/coreclr/tools/aot/ILLink.Shared/ILLink.LinkAttributes.xsd b/src/coreclr/tools/aot/ILLink.Shared/ILLink.LinkAttributes.xsd
deleted file mode 100644
index f1156b0a4d690..0000000000000
--- a/src/coreclr/tools/aot/ILLink.Shared/ILLink.LinkAttributes.xsd
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/coreclr/tools/aot/ILLink.Shared/ILLink.Shared.projitems b/src/coreclr/tools/aot/ILLink.Shared/ILLink.Shared.projitems
index ffbfab3b98417..0a61390d8d025 100644
--- a/src/coreclr/tools/aot/ILLink.Shared/ILLink.Shared.projitems
+++ b/src/coreclr/tools/aot/ILLink.Shared/ILLink.Shared.projitems
@@ -13,7 +13,6 @@
-
@@ -22,9 +21,4 @@
Designer
-
-
- Designer
-
-
-
+
\ No newline at end of file
diff --git a/src/coreclr/tools/aot/ILLink.Shared/MessageSubCategory.cs b/src/coreclr/tools/aot/ILLink.Shared/MessageSubCategory.cs
deleted file mode 100644
index 92c1077b14baf..0000000000000
--- a/src/coreclr/tools/aot/ILLink.Shared/MessageSubCategory.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace ILLink.Shared
-{
- public static class MessageSubCategory
- {
- public const string None = "";
- public const string TrimAnalysis = "Trim analysis";
- public const string UnresolvedAssembly = "Unresolved assembly";
- public const string AotAnalysis = "AOT analysis";
- }
-}
diff --git a/src/coreclr/tools/aot/ILLink.Shared/README.md b/src/coreclr/tools/aot/ILLink.Shared/README.md
deleted file mode 100644
index 229b67e492bf0..0000000000000
--- a/src/coreclr/tools/aot/ILLink.Shared/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Sources taken from https://github.com/dotnet/linker/tree/890591b13da936d2c38a52afdaeac0db69858d4f/src/ILLink.Shared.
diff --git a/src/coreclr/tools/aot/ILLink.Shared/SharedStrings.resx b/src/coreclr/tools/aot/ILLink.Shared/SharedStrings.resx
index fe39e38906517..0d53dff7e254e 100644
--- a/src/coreclr/tools/aot/ILLink.Shared/SharedStrings.resx
+++ b/src/coreclr/tools/aot/ILLink.Shared/SharedStrings.resx
@@ -53,6 +53,7 @@
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
+
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
@@ -116,954 +117,12 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- An Xml Feature does not specify a 'featurevalue' attribute.
-
-
- Failed to process '{0}'. Feature '{1}' does not specify a 'featurevalue' attribute.
-
-
- Feature definition has to be a boolean.
-
-
- Failed to process '{0}'. Unsupported non-boolean feature definition '{1}'.
-
-
- An exception was thrown while processing the xml file.
-
-
- Error processing '{0}': {1}.
-
-
- An error ocurred while processing a method in assembly.
-
-
- Error processing method '{0}' in assembly '{1}'.
-
-
- Cannot stub constructor of a type when base type does not have default constructor. Constructors of derived types marked for substitution require to have a default constructor in its base type.
-
-
- Cannot stub constructor on '{0}' when base type does not have default constructor.
-
-
- Could not find predefined type".
-
-
- Missing predefined '{0}' type".
-
-
- Could not find constructor.
-
-
- Could not find constructor on '{0}'.
-
-
- Assembly reference could not be resolved.
-
-
- Assembly reference '{0}' could not be resolved.
-
-
- Assembly cannot be loaded due to failure in processing the reference assembly.
-
-
- Assembly '{0}' cannot be loaded due to failure in processing '{1}' reference
-
-
- There was an error writing the linked assembly 'output'.
-
-
- Failed to write '{0}'.
-
-
- There was an unexpected error while trimming. An exception with more details is printed to the MSBuild log. Please share this stack trace with the IL Linker team to further investigate the cause and possible solution.
-
-
- IL Trimmer has encountered an unexpected error. Please report the issue at https://github.com/dotnet/linker/issues
-
-
- There was an error processing 'XML document location' xml file. The most likely reason for this is that the XML file has syntactical errors.
-
-
- Error processing '{0}'.
-
-
- Element in XML document contains a 'featuredefault' attribute with an invalid value.
-
-
- Failed to process '{0}'. Unsupported value for featuredefault attribute.
-
-
- The string passed to the command-line does not correspond to a valid command-line option.
-
-
- Unrecognized command-line option: '{0}'.
-
-
- The value given for the --warn argument was not a valid warning version.
-
-
- Invalid warning version '{0}'.
-
-
- Invalid value 'value' was used for command-line option '--generate-warning-suppressions'; must be 'cs' or 'xml'.
-
-
- Invalid value '{0}' for '--generate-warning-suppressions' option.
-
-
- The command-line option 'optionName' was specified but no argument was given.
-
-
- Missing argument for '{0}' option.
-
-
- The command-line option --custom-data receives a key-value pair using the format KEY=VALUE.
-
-
- Value used with '--custom-data' has to be in the KEY=VALUE format.
-
-
- No input files were specified. Use one of the resolver options.
-
-
- No input files were specified. Use one of '{0}' options.
-
-
- Options '--new-mvid' and '--deterministic' cannot be used at the same time.
-
-
- Options '--new-mvid' and '--deterministic' cannot be used at the same time.
-
-
- The assembly argument specified for '--custom-step' option could not be found.
-
-
- The assembly '{0}' specified for '--custom-step' option could not be found.
-
-
- The path to the assembly specified for '--custom-step' must be fully qualified.
-
-
- The path to the assembly '{0}' specified for '--custom-step' must be fully qualified.
-
-
- An invalid value was specified for '--custom-step' option.
-
-
- Invalid value '{0}' specified for '--custom-step' option.
-
-
- A custom step that is inserted relative to an existing step in the pipeline must specify whether to be added before (-) or after (+) the step it's relative to.
-
-
- Expected '+' or '-' to control new step insertion.
-
-
- A custom step was specified for insertion relative to a non existent step.
-
-
- Pipeline step '{0}' could not be found.
-
-
- The custom step could not be found in the given assembly.
-
-
- Custom step '{0}' could not be found.
-
-
- Custom step is incompatible with this trimmer version.
-
-
- Custom step '{0}' is incompatible with this trimmer version.
-
-
- The optimization 'text' is invalid. Optimization values can either be 'beforefieldinit', 'overrideremoval', 'unreachablebodies', 'unusedinterfaces', 'ipconstprop', or 'sealer'.
-
-
- Invalid optimization value '{0}'.
-
-
- Invalid argument for 'token' option.
-
-
- Invalid argument for '{0}' option.
-
-
- Invalid assembly action.
-
-
- Invalid assembly action '{0}'.
-
-
- Root assembly could not be found.
-
-
- Root assembly '{0}' could not be found.
-
-
- XML descriptor file could not be found'.
-
-
- XML descriptor file '{0}' could not be found'.
-
-
- Root assembly does not have entry point.
-
-
- Root assembly '{0}' does not have entry point.
-
-
- Referenced root assembly cannot use the specified action.
-
-
- Root assembly '{0}' cannot use action '{1}'.
-
-
- Invalid assembly name.
-
-
- Invalid assembly name '{0}'.
-
-
- Invalid assembly root mode.
-
-
- Invalid assembly root mode '{0}'.
-
-
- Exported type cannot be resolved.
-
-
- Exported type '{0}' cannot be resolved.
-
-
- A reference assembly input passed via -reference could not be loaded.
-
-
- Reference assembly '{0}' could not be loaded.
-
-
- Metadata element cannot be resolved. This usually means there is a version mismatch between dependencies.
-
-
- {0}.
-
-
- Field element cannot be resolved. This usually means there is a version mismatch between dependencies.
-
-
- Field '{0}' reference could not be resolved.
-
-
- Method element cannot be resolved. This usually means there is a version mismatch between dependencies.
-
-
- Method '{0}' reference could not be resolved.
-
-
- Type element cannot be resolved. This usually means there is a version mismatch between dependencies.
-
-
- Type '{0}' reference could not be resolved.
-
-
- The type name used to define custom attribute value could not be resolved.
-
-
- The type '{0}' used with attribute value '{1}' could not be found.
-
-
- The 'value' specified for the custom attribute value cannot be converted to specified argument type 'typeName'.
-
-
- Cannot convert value '{0}' to type '{1}'.
-
-
- The syntax for custom attribute value for 'type' requires to also specify the underlying attribute type.
-
-
- Custom attribute argument for '{0}' requires nested '{1}' node.
-
-
- The value specified for the custom attribute of System.Type type could not be resolved.
-
-
- Could not resolve custom attribute type value '{0}'.
-
-
- The type name used with attribute type is not one of the supported types.
-
-
- Unexpected attribute argument type '{0}'.
-
-
- Invalid metadata value.
-
-
- Invalid metadata value '{0}'.
-
-
- The XML descriptor preserves fields on type, but this type has no fields.
-
-
- Type '{0}' has no fields to preserve.
-
-
- The XML descriptor preserves methods on type, but this type has no methods.
-
-
- Type '{0}' has no methods to preserve.
-
-
- The assembly in PreserveDependency attribute could not be resolved.
-
-
- Could not resolve dependency assembly '{0}' specified in a 'PreserveDependency' attribute.
-
-
- The type in PreserveDependency attribute could not be resolved.
-
-
- Could not resolve dependency type '{0}' specified in a 'PreserveDependency' attribute.
-
-
- The member in PreserveDependency attribute could not be resolved.
-
-
- Could not resolve dependency member '{0}' declared in type '{1}' specified in a 'PreserveDependency' attribute.
-
-
- The assembly in the XML could not be resolved.
-
-
- Could not resolve assembly '{0}'.
-
-
- The type in the XML could not be resolved.
-
-
- Could not resolve type '{0}'.
-
-
- The XML defined a method on a type, but the method was not found.
-
-
- Could not find method '{0}' on type '{1}'.
-
-
- Invalid value for 'signature' stub in the substitution XML.
-
-
- Invalid value for '{0}' stub.
-
-
- The value of the body attribute used in the substitution XML is invalid (the only supported options are remove and stub).
-
-
- Unknown body modification '{0}' for '{1}'.
-
-
- The XML defined a field on a type, but the field was not found.
-
-
- Could not find field '{0}' on type '{1}'.
-
-
- The substituted field 'field' was non-static or constant. Only static non-constant fields are supported.
-
-
- Substituted field '{0}' needs to be static field.
-
-
- A field was specified for substitution but no value to be substituted was given.
-
-
- Missing 'value' attribute for field '{0}'.
-
-
- The value used in the substitution XML for field is not a built-in type, or does not match the type of the field.
-
-
- Invalid value '{0}' for '{1}'.
-
-
- The XML defined a event on a type, but the event was not found.
-
-
- Could not find event '{0}' on type '{1}'.
-
-
- The XML defined a property on a type, but the property was not found.
-
-
- Could not find property '{0}' on type '{1}'.
-
-
- The XML defined the get accessor of property on a type, but the accessor was not found.
-
-
- Could not find the get accessor of property '{0}' on type '{1}'.
-
-
- The XML defined the set accessor of property on a type, but the accessor was not found.
-
-
- Could not find the set accessor of property '{0}' in type '{1}'.
-
-
- The XML attribute arguments use values or types which don't match to any constructor
-
-
- Could not find matching constructor for custom attribute '{0}' arguments.
-
-
- Method 'method' has more than one return element specified. There can only be one return element.
-
-
- There is more than one 'return' child element specified for method '{0}'.
-
-
- Method has more than one parameter for the XML element 'parameter'. There can only be one value specified for each parameter.
-
-
- More than one value specified for parameter '{0}' of method '{1}'.
-
-
- The XML descriptor marks for preservation the member more than once.
-
-
- Duplicate preserve of '{0}'.
-
Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
Using member '{0}' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code.{1}{2}
-
- Using dynamic types might cause types or members to be removed by trimmer.
-
-
- Invoking members on dynamic types is not trimming-compatible. Types or members might have been removed by the trimmer.
-
-
- The linker found multiple instances of attribute on a member. This attribute is only allowed to have one instance.
-
-
- Attribute '{0}' should only be used once on '{1}
-
-
- Attribute doesn't have the required number of parameters specified.
-
-
- Attribute '{0}' doesn't have the required number of parameters specified.
-
-
- 'attribute' element does not contain attribute 'fullname' or it's empty.
-
-
- 'attribute' element does not contain attribute 'fullname' or it's empty.
-
-
- The assembly name specified for attribute could not be resolved.
-
-
- Could not resolve assembly '{0}' for attribute '{1}'.
-
-
- The described attribute type could not be found in the assemblies.
-
-
- Attribute type '{0}' could not be found.
-
-
- The value passed as the assembly name or type name to the CreateInstance method can't be statically analyzed.
-
-
- Unrecognized value passed to the parameter '{0}' of method '{1}'. It's not possible to guarantee the availability of the target type.
-
-
- 'PreserveDependencyAttribute' is deprecated. Use 'DynamicDependencyAttribute' instead.
-
-
- 'PreserveDependencyAttribute' is deprecated. Use 'DynamicDependencyAttribute' instead.
-
-
- The input contains an invalid use of DynamicDependencyAttribute.
-
-
- The 'DynamicDependencyAttribute' could not be analyzed.
-
-
- The assembly string given in a DynamicDependencyAttribute constructor could not be resolved.
-
-
- Unresolved assembly '{0}' in 'DynamicDependencyAttribute'.
-
-
- The type in a DynamicDependencyAttribute constructor could not be resolved.
-
-
- Unresolved type '{0}' in 'DynamicDependencyAttribute'.
-
-
- The member signature or DynamicallyAccessedMemberTypes in a DynamicDependencyAttribute constructor did not resolve to any members on the type.
-
-
- No members were resolved for '{0}'.
-
-
- The resource element in a substitution file did not have a 'name' attribute.
-
-
- Missing 'name' attribute for resource.
-
-
- The resource element in a substitution file did not have a valid 'action' attribute.
-
-
- Invalid value '{0}' for attribute 'action' for resource '{1}'.
-
-
- The resource name in a substitution file could not be found in the specified assembly.
-
-
- Could not find embedded resource '{0}' to remove in assembly '{1}'.
-
-
- The 'DynamicallyAccessedMembersAttribute' is not allowed on methods. It is allowed on method return value or method parameters.
-
-
- The 'DynamicallyAccessedMembersAttribute' is not allowed on methods. It is allowed on method return value or method parameters though.
-
-
- Could not find a unique backing field for property to propagate 'DynamicallyAccessedMembersAttribute'.
-
-
- Could not find a unique backing field for property '{0}' to propagate 'DynamicallyAccessedMembersAttribute'.
-
-
- 'DynamicallyAccessedMembersAttribute' on property conflicts with the same attribute on its accessor.
-
-
- 'DynamicallyAccessedMembersAttribute' on property '{0}' conflicts with the same attribute on its accessor '{1}'.
-
-
- The XML descriptor specifies a namespace but there are no types found in such namespace.
-
-
- Could not find any type in namespace '{0}'.
-
-
- An attribute is being referenced in the code but the attribute instances have been removed using the 'RemoveAttributeInstances' internal attribute.
-
-
- Attribute '{0}' is being referenced in code but the trimmer was instructed to remove all instances of this attribute. If the attribute instances are necessary make sure to either remove the trimmer attribute XML portion which removes the attribute instances, or override the removal by using the trimmer XML descriptor to keep the attribute type (which in turn keeps all of its instances).
-
-
- 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
-
-
- {0}. 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
-
-
- Internal attribute 'RemoveAttributeInstances' can only be used on attribute types.
-
-
- Internal attribute '{0}' can only be used on attribute types.
-
-
- Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed.
-
-
- P/invoke method '{0}' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed.
-
-
- An attribute element has property but this could not be found.
-
-
- Property element does not contain attribute 'name'.
-
-
- An attribute element has property but this could not be found.
-
-
- Property '{0}' could not be found.
-
-
- Either the type on which the MakeGenericType is called can't be statically determined, or the type parameters to be used for generic arguments can't be statically determined.
-
-
- Call to '{0}' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic type.
-
-
- 'DynamicallyAccessedMemberAttribute' on property conflicts with the same attribute on its backing field.
-
-
- 'DynamicallyAccessedMemberAttribute' on property '{0}' conflicts with the same attribute on its backing field '{1}'.
-
-
- Unrecognized value passed to the parameter of method. It's not possible to guarantee the availability of the target type.
-
-
- Unrecognized value passed to the parameter 'typeName' of method '{0}'. It's not possible to guarantee the availability of the target type.
-
-
- Parameters passed to method cannot be analyzed. Consider using methods 'System.Type.GetType' and `System.Activator.CreateInstance` instead.
-
-
- Parameters passed to method '{0}' cannot be analyzed. Consider using methods 'System.Type.GetType' and `System.Activator.CreateInstance` instead.
-
-
- The type passed to the RunClassConstructor is not statically known, Trimmer can't make sure that its static constructor is available.
-
-
- Unrecognized value passed to the parameter 'type' of method '{0}'. It's not possible to guarantee the availability of the target static constructor.
-
-
- Call to 'System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method.
-
-
- Call to '{0}' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method.
-
-
- Calling CreateInstance with assembly name which can't be resolved.
-
-
- The assembly name '{0}' passed to method '{1}' references assembly which is not available.
-
-
- The parameter of method has a DynamicallyAccessedMembersAttribute, but the value passed to it can not be statically analyzed.
-
-
- Value passed to parameter '{0}' of method '{1}' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements.
-
-
- The return value of method has a DynamicallyAccessedMembersAttribute, but the value returned from the method can not be statically analyzed.
-
-
- Value returned from method '{0}' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements.
-
-
- The field has a DynamicallyAccessedMembersAttribute, but the value assigned to it can not be statically analyzed.
-
-
- Value assigned to {0} can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements.
-
-
- The method has a DynamicallyAccessedMembersAttribute (which applies to the implicit 'this' parameter), but the value used for the 'this' parameter can not be statically analyzed.
-
-
- Value passed to implicit 'this' parameter of method '{0}' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements.
-
-
- The generic parameter of type or method has a DynamicallyAccessedMembersAttribute, but the value used for it can not be statically analyzed.
-
-
- Type passed to generic parameter '{0}' of '{1}' can not be statically determined and may not meet 'DynamicallyAccessedMembersAttribute' requirements.
-
-
- Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.
-
-
- '{0}' argument does not satisfy {4} in call to '{1}'. The parameter '{2}' of method '{3}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target method return value does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The parameter of method does not have matching annotations.
-
-
- '{0}' method return value does not satisfy {3} requirements. The parameter '{1}' of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Value stored in field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The parameter of method does not have matching annotations.
-
-
- value stored in field '{0}' does not satisfy {3} requirements. The parameter '{1}' of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.
-
-
- 'this' argument does not satisfy {3} in call to '{0}'. The parameter '{1}' of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The parameter of method does not have matching annotations.
-
-
- '{0}' generic argument does not satisfy {4} in '{1}'. The parameter '{2}' of method '{3}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations.
-
-
- '{0}' argument does not satisfy {3} in call to '{1}'. The return value of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target method return value does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The return value of the source method does not have matching annotations.
-
-
- '{0}' method return value does not satisfy {2} requirements. The return value of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Value stored in field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The return value of the source method does not have matching annotations.
-
-
- value stored in field '{0}' does not satisfy {2} requirements. The return value of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations.
-
-
- 'this' argument does not satisfy {2} in call to '{0}'. The return value of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The return value of the source method does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- '{0}' generic argument does not satisfy {3} in '{1}'. The return value of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The source field does not have matching annotations.
-
-
- '{0}' argument does not satisfy {3} in call to '{1}'. The field '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target method return value does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The source field does not have matching annotations.
-
-
- '{0}' method return value does not satisfy {2} requirements. The field '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Value stored in target field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The source field does not have matching annotations.
-
-
- value stored in field '{0}' does not satisfy {2} requirements. The field '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The source field does not have matching annotations.
-
-
- 'this' argument does not satisfy {2} in call to '{0}'. The field '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The source field does not have matching annotations.
-
-
- '{0}' generic argument does not satisfy {3} in '{1}'. The field '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The implicit 'this' argument of source method does not have matching annotations.
-
-
- '{0}' argument does not satisfy {3} in call to '{1}'. The implicit 'this' argument of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target method return value does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The implicit 'this' argument of source method does not have matching annotations.
-
-
- '{0}' method return value does not satisfy {2} requirements. The implicit 'this' argument of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Value stored in target field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The implicit 'this' argument of source method does not have matching annotations.
-
-
- value stored in field '{0}' does not satisfy {2} requirements. The implicit 'this' argument of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The implicit 'this' argument of source method does not have matching annotations.
-
-
- 'this' argument does not satisfy {2} in call to '{0}'. The implicit 'this' argument of method '{1}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The implicit 'this' argument of source method does not have matching annotations.
-
-
- '{0}' generic argument does not satisfy {3} in '{1}'. The implicit 'this' argument of method '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The generic parameter of the source method or type does not have matching annotations.
-
-
- '{0}' argument does not satisfy {4} in call to '{1}'. The generic parameter '{2}' of '{3}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target method return value does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The generic parameter of the source method or type does not have matching annotations.
-
-
- '{0}' method return value does not satisfy {3} requirements. The generic parameter '{1}' of '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Value stored in target field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The generic parameter of the source method or type does not have matching annotations.
-
-
- value stored in field '{0}' does not satisfy {3} requirements. The generic parameter '{1}' of '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- 'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The generic parameter of the source method or type does not have matching annotations.
-
-
- 'this' argument does not satisfy {3} in call to '{0}'. The generic parameter '{1}' of '{2}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The generic parameter of the source method or type does not have matching annotations.
-
-
- '{0}' generic argument does not satisfy {4} in '{1}'. The generic parameter '{2}' of '{3}' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
-
-
- 'DynamicallyAccessedMemberTypes' on the parameter of method don't match overridden parameter of method. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.
-
-
- 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the parameter '{0}' of method '{1}' don't match overridden parameter '{2}' of method '{3}'. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.
-
-
- 'DynamicallyAccessedMemberTypes' on the return value of method don't match overridden return value of method. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.
-
-
- 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the return value of method '{0}' don't match overridden return value of method '{1}'. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.
-
-
- 'DynamicallyAccessedMemberTypes' on the implicit 'this' parameter of method don't match overridden implicit 'this' parameter of method. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.
-
-
- 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the implicit 'this' parameter of method '{0}' don't match overridden implicit 'this' parameter of method '{1}'. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.
-
-
- 'DynamicallyAccessedMemberTypes' on the generic parameter of method or type don't match overridden generic parameter method or type. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.
-
-
- 'DynamicallyAccessedMemberTypes' in 'DynamicallyAccessedMembersAttribute' on the generic parameter '{0}' of '{1}' don't match overridden generic parameter '{2}' of '{3}'. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.
-
-
- Call to 'Type.GetType' method can perform case insensitive lookup of the type, currently ILLink can not guarantee presence of all the matching types.
-
-
- Call to '{0}' can perform case insensitive lookup of the type, currently ILLink can not guarantee presence of all the matching types.
-
-
- Field has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to fields of type 'System.Type' or 'System.String'.
-
-
- Field '{0}' has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to fields of type 'System.Type' or 'System.String'.
-
-
- Parameter of method has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to parameters of type 'System.Type' or 'System.String'.
-
-
- Parameter '{0}' of method '{1}' has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to parameters of type 'System.Type' or 'System.String'.
-
-
- Property has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to properties of type 'System.Type' or 'System.String'.
-
-
- Property '{0}' has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to properties of type 'System.Type' or 'System.String'.
-
-
- XML contains unsupported wildcard for assembly 'fullname' attribute.
-
-
- XML contains unsupported wildcard for assembly 'fullname' attribute.
-
-
- Embedded XML in assembly contains assembly "fullname" attribute for another assembly
-
-
- Embedded XML in assembly '{0}' contains assembly "fullname" attribute for another assembly '{1}'
-
-
- Invalid AssemblyMetadata 'IsTrimmable' attribute in assembly. Value must be "True".
-
-
- Invalid AssemblyMetadata("IsTrimmable", "{0}") attribute in assembly '{1}'. Value must be "True".
-
-
- Value passed to the parameter of method cannot be statically determined as a property accessor.
-
-
- Value passed to the '{0}' parameter of method '{1}' cannot be statically determined as a property accessor.
-
-
- Assembly produced trim warnings.
-
-
- Assembly '{0}' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries
-
-
- Type was not found in the caller assembly nor in the base library. Type name strings used for dynamically accessing a type should be assembly qualified.
-
-
- Type '{0}' was not found in the caller assembly nor in the base library. Type name strings used for dynamically accessing a type should be assembly qualified.
-
-
- Return type of method has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to properties of type 'System.Type' or 'System.String'.
-
-
- Return type of method '{0}' has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to properties of type 'System.Type' or 'System.String'.
-
-
- Trimmer currently can't correctly handle if the same compiler generated state machine type is associated (via the state machine attributes) with two different methods.
-
-
- Methods '{0}' and '{1}' are both associated with state machine type '{2}'. This is currently unsupported and may lead to incorrectly reported warnings.
-
-
- Invalid scope used in 'UnconditionalSuppressMessageAttribute'. The only scopes supported on global unconditional suppressions are 'module', 'type' and 'member'.
-
-
- Invalid scope '{0}' used in 'UnconditionalSuppressMessageAttribute' on module '{1}' with target '{2}'.
-
-
- Types that derive from a base class with 'RequiresUnreferencedCodeAttribute' need to explicitly use the 'RequiresUnreferencedCodeAttribute' or suppress this warning
-
-
- Type '{0}' derives from '{1}' which has 'RequiresUnreferencedCodeAttribute'. {2}{3}
-
-
- Field with 'DynamicallyAccessedMembersAttribute' is accessed via reflection. Trimmer can't guarantee availability of the requirements of the field.
-
-
- Field '{0}' with 'DynamicallyAccessedMembersAttribute' is accessed via reflection. Trimmer can't guarantee availability of the requirements of the field.
-
-
- Method with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
-
-
- Method '{0}' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
-
-
- 'DynamicallyAccessedMembersAttribute' on a type or one of its base types references a member which requires unreferenced code.
-
-
- 'DynamicallyAccessedMembersAttribute' on '{0}' or one of its base types references '{1}' which requires unreferenced code.{2}{3}
-
-
- 'DynamicallyAccessedMembersAttribute' on a type or one of its base types references a member which requires unreferenced code.
-
-
- 'DynamicallyAccessedMembersAttribute' on '{0}' or one of its base types references '{1}' which requires unreferenced code.{2}{3}
-
-
- 'DynamicallyAccessedMembersAttribute' on a type or one of its base types references a member which has 'DynamicallyAccessedMembersAttribute' requirements.
-
-
- 'DynamicallyAccessedMembersAttribute' on '{0}' or one of its base types references '{1}' which has 'DynamicallyAccessedMembersAttribute' requirements.
-
-
- 'DynamicallyAccessedMembersAttribute' on a type or one of its base types references a member which has 'DynamicallyAccessedMembersAttribute' requirements.
-
-
- 'DynamicallyAccessedMembersAttribute' on '{0}' or one of its base types references '{1}' which has 'DynamicallyAccessedMembersAttribute' requirements.
-
-
- The use of 'RequiresUnreferencedCodeAttribute' on static constructors is disallowed since is a method not callable by the user, is only called by the runtime. Placing the attribute directly on the static constructor will have no effect, instead use 'RequiresUnreferencedCodeAttribute' on the type which will handle warning and silencing from the static constructor.
-
-
- 'RequiresUnreferencedCodeAttribute' cannot be placed directly on static constructor '{0}', consider placing 'RequiresUnreferencedCodeAttribute' on the type declaration instead.
-
Avoid accessing Assembly file path when publishing as a single file
@@ -1082,47 +141,29 @@
Using member '{0}' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app.{1}{2}
-
- 'RequiresAssemblyFilesAttribute' annotations must match across all interface implementations or overrides.
-
-
- {0}. 'RequiresAssemblyFilesAttribute' annotations must match across all interface implementations or overrides.
-
Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
Using member '{0}' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling.{1}{2}
-
- 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
+
+ {0}. 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
+
+
+ 'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.
{0}. 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
-
- COM interop is not supported with full ahead of time compilation.
-
-
- COM interop is not supported with full ahead of time compilation.
-
-
- Assembly produced AOT analysis warnings.
-
-
- Assembly '{0}' produced AOT analysis warnings.
-
-
- Generic expansion to was aborted due to generic recursion. An exception will be thrown at runtime if this codepath is ever reached.
-
-
- Generic expansion to '{0}' was aborted due to generic recursion. An exception will be thrown at runtime if this codepath is ever reached. Generic recursion also negatively affects compilation speed and the size of the compilation output. It is advisable to remove the source of the generic recursion by restructuring the program around the source of recursion. The source of generic recursion might include: {1}
+
+ 'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides.
-
- P/invoke method declares a parameter with an abstract delegate. Correctness of interop for abstract delegates cannot be guaranteed after native compilation.
+
+ {0}. 'RequiresAssemblyFilesAttribute' annotations must match across all interface implementations or overrides.
-
- P/invoke method '{0}' declares a parameter with an abstract delegate. Correctness of interop for abstract delegates cannot be guaranteed after native compilation: the marshalling code for the delegate might not be available. Use a non-abstract delegate type or ensure any delegate instance passed as parameter is marked with `UnmanagedFunctionPointerAttribute`.
+
+ 'RequiresAssemblyFilesAttribute' annotations must match across all interface implementations or overrides.
Base member '{2}' with '{0}' has a derived member '{1}' without '{0}'
@@ -1136,4 +177,40 @@
Interface member '{2}' with '{0}' has an implementation member '{1}' without '{0}'
+
+ Type '{0}' derives from '{1}' which has 'RequiresUnreferencedCodeAttribute'. {2}{3}
+
+
+ Types that derive from a base class with 'RequiresUnreferencedCodeAttribute' need to explicitly use the 'RequiresUnreferencedCodeAttribute' or suppress this warning
+
+
+ Invoking members on dynamic types is not trimming-compatible. Types or members might have been removed by the trimmer.
+
+
+ Using dynamic types might cause types or members to be removed by trimmer.
+
+
+ Call to '{0}' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method.
+
+
+ Call to '{0}' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic type.
+
+
+ 'RequiresUnreferencedCodeAttribute' cannot be placed directly on static constructor '{0}', consider placing 'RequiresUnreferencedCodeAttribute' on the type declaration instead.
+
+
+ The use of 'RequiresUnreferencedCodeAttribute' on static constructors is disallowed since is a method not callable by the user, is only called by the runtime. Placing the attribute directly on the static constructor will have no effect, instead use 'RequiresUnreferencedCodeAttribute' on the type which will handle warning and silencing from the static constructor.
+
+
+ Call to '{0}' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method.
+
+
+ Value passed to the '{0}' parameter of method '{1}' cannot be statically determined as a property accessor.
+
+
+ P/invoke method '{0}' declares a parameter with COM marshalling. Correctness of COM interop cannot be guaranteed after trimming. Interfaces and interface members might be removed.
+
+
+ P/invoke method '{0}' declares a parameter with an abstract delegate. Correctness of interop for abstract delegates cannot be guaranteed after native compilation: the marshalling code for the delegate might not be available. Use a non-abstract delegate type or ensure any delegate instance passed as parameter is marked with `UnmanagedFunctionPointerAttribute`.
+
diff --git a/src/coreclr/tools/aot/crossgen2/Program.cs b/src/coreclr/tools/aot/crossgen2/Program.cs
index 6eedd33da4a6d..ff538c05fd64c 100644
--- a/src/coreclr/tools/aot/crossgen2/Program.cs
+++ b/src/coreclr/tools/aot/crossgen2/Program.cs
@@ -730,6 +730,7 @@ private void RunSingleCompilation(Dictionary inFilePaths, Instru
builder
.UseIbcTuning(_commandLineOptions.Tuning)
+ .UseResilience(_commandLineOptions.Resilient)
.UseMapFile(_commandLineOptions.Map)
.UseMapCsvFile(_commandLineOptions.MapCsv)
.UsePdbFile(_commandLineOptions.Pdb, _commandLineOptions.PdbPath)
@@ -747,7 +748,6 @@ private void RunSingleCompilation(Dictionary inFilePaths, Instru
.UseBackendOptions(_commandLineOptions.CodegenOptions)
.UseLogger(logger)
.UseParallelism(_commandLineOptions.Parallelism)
- .UseResilience(_commandLineOptions.Resilient)
.UseDependencyTracking(trackingLevel)
.UseCompilationRoots(compilationRoots)
.UseOptimizationMode(optimizationMode);
diff --git a/src/coreclr/tools/dotnet-pgo/TraceTypeSystemContext.cs b/src/coreclr/tools/dotnet-pgo/TraceTypeSystemContext.cs
index afdb148089b26..09e2f52ea053a 100644
--- a/src/coreclr/tools/dotnet-pgo/TraceTypeSystemContext.cs
+++ b/src/coreclr/tools/dotnet-pgo/TraceTypeSystemContext.cs
@@ -260,7 +260,7 @@ public static unsafe PEReader OpenPEFile(string filePath, byte[] moduleBytes, ou
try
{
// Create stream because CreateFromFile(string, ...) uses FileShare.None which is too strict
- fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1);
+ fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
mappedFile = MemoryMappedFile.CreateFromFile(
fileStream, null, fileStream.Length, MemoryMappedFileAccess.Read, HandleInheritability.None, true);
accessor = mappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);
@@ -278,9 +278,12 @@ public static unsafe PEReader OpenPEFile(string filePath, byte[] moduleBytes, ou
}
finally
{
- accessor?.Dispose();
- mappedFile?.Dispose();
- fileStream?.Dispose();
+ if (accessor != null)
+ accessor.Dispose();
+ if (mappedFile != null)
+ mappedFile.Dispose();
+ if (fileStream != null)
+ fileStream.Dispose();
}
}
diff --git a/src/coreclr/utilcode/securitywrapper.cpp b/src/coreclr/utilcode/securitywrapper.cpp
index 67b462bf00a26..8f7ac38f444a0 100644
--- a/src/coreclr/utilcode/securitywrapper.cpp
+++ b/src/coreclr/utilcode/securitywrapper.cpp
@@ -206,6 +206,117 @@ HRESULT GetSidFromProcessWorker(DWORD dwProcessId, SidType sidType, PSID *ppSid)
return hr;
}
+#ifndef FEATURE_CORESYSTEM
+//-----------------------------------------------------------------------------
+// get the sid of a given process id using WTSEnumerateProcesses
+// @todo: Make this function fail when WTSEnumerateProcesses is not available
+// Or is it always available on all of our platform?
+//
+// Caller remember to call delete on *ppSid
+//-----------------------------------------------------------------------------
+HRESULT GetSidFromProcessEXWorker(DWORD dwProcessId, PSID *ppSid)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ PRECONDITION(CheckPointer(ppSid));
+ }
+ CONTRACTL_END;
+
+ HRESULT hr = S_OK;
+ PWTS_PROCESS_INFOW rgProcessInfo = NULL;
+ DWORD dwNumProcesses;
+ DWORD iProc;
+ DWORD cbSid;
+ PSID pSid = NULL;
+
+ LOG((LF_CORDB, LL_INFO10000,
+ "SecurityUtil::GetSidFromProcessEx: 0x%08x\n",
+ dwProcessId));
+
+
+ *ppSid = NULL;
+ if (!WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, // use local server
+ 0, // Reserved must be zero
+ 1, // version must be 1
+ &rgProcessInfo, // Receives pointer to process list
+ &dwNumProcesses))
+ {
+ hr = HRESULT_FROM_GetLastError();
+ goto exit;
+ }
+
+ for (iProc = 0; iProc < dwNumProcesses; iProc++)
+ {
+
+ if (rgProcessInfo[iProc].ProcessId == dwProcessId)
+ {
+ if (rgProcessInfo[iProc].pUserSid == NULL)
+ {
+ LOG((LF_CORDB, LL_INFO10000,
+ "SecurityUtil::GetSidFromProcessEx is not able to retrieve SID\n"));
+
+ // if there is no Sid for the user, don't call GetLengthSid.
+ // It will crash! It is ok to return E_FAIL as caller will ignore it.
+ hr = E_FAIL;
+ goto exit;
+ }
+ cbSid = GetLengthSid(rgProcessInfo[iProc].pUserSid);
+ pSid = new (nothrow) BYTE[cbSid];
+ if (pSid == NULL)
+ {
+ hr = E_OUTOFMEMORY;
+ }
+ else
+ {
+ if (!CopySid(cbSid, pSid, rgProcessInfo[iProc].pUserSid))
+ {
+ hr = HRESULT_FROM_GetLastError();
+ }
+ else
+ {
+ // We are done. Go to exit
+ hr = S_OK;
+ }
+ }
+
+ // we already find a match. Even if we fail from memory allocation of CopySid, still
+ // goto exit.
+ goto exit;
+ }
+ }
+
+ // Walk the whole list and cannot find the matching PID
+ // Find a better error code.
+ hr = E_FAIL;
+
+exit:
+
+ if (rgProcessInfo)
+ {
+ WTSFreeMemory(rgProcessInfo);
+ }
+
+ if (FAILED(hr) && pSid)
+ {
+ delete [] (reinterpret_cast(pSid));
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ _ASSERTE(pSid);
+ *ppSid = pSid;
+ }
+ LOG((LF_CORDB, LL_INFO10000,
+ "SecurityUtil::GetSidFromProcessEx return hr : 0x%08x\n",
+ hr));
+
+
+ return hr;
+}
+#endif // !FEATURE_CORESYSTEM
+
//-----------------------------------------------------------------------------
// The functions below initialize this SidBuffer instance with a Sid from
// the token of the specified process. The first pair use the OWNER sid from
@@ -250,6 +361,12 @@ HRESULT SidBuffer::InitFromProcessNoThrow(DWORD pid)
_ASSERTE(m_pBuffer == NULL);
HRESULT hr = GetSidFromProcessWorker(pid, kOwnerSid, (PSID *) &m_pBuffer);
+#ifndef FEATURE_CORESYSTEM
+ if (FAILED(hr))
+ {
+ hr = GetSidFromProcessEXWorker(pid, (PSID *) &m_pBuffer);
+ }
+#endif // !FEATURE_CORESYSTEM
if (FAILED(hr))
{
return hr;
@@ -409,6 +526,12 @@ HRESULT SidBuffer::InitFromProcessUserNoThrow(DWORD pid)
_ASSERTE(m_pBuffer == NULL);
HRESULT hr = GetSidFromProcessWorker(pid, kUserSid, (PSID *) &m_pBuffer);
+#ifndef FEATURE_CORESYSTEM
+ if (FAILED(hr))
+ {
+ hr = GetSidFromProcessEXWorker(pid, (PSID *) &m_pBuffer);
+ }
+#endif // !FEATURE_CORESYSTEM
if (FAILED(hr))
{
return hr;
diff --git a/src/coreclr/utilcode/sstring.cpp b/src/coreclr/utilcode/sstring.cpp
index 9ab6790efb3f6..6b5f7af901ac1 100644
--- a/src/coreclr/utilcode/sstring.cpp
+++ b/src/coreclr/utilcode/sstring.cpp
@@ -2137,7 +2137,11 @@ void SString::PVPrintf(const WCHAR *format, va_list args)
{
// First, try to use the existing buffer
va_copy(ap, args);
+#if defined(FEATURE_CORESYSTEM)
int result = _vsnwprintf_s(GetRawUnicode(), GetRawCount()+1, _TRUNCATE, format, ap);
+#else
+ int result = _vswprintf_p(GetRawUnicode(), GetRawCount()+1, format, ap);
+#endif
va_end(ap);
if (result >= 0)
{
@@ -2167,7 +2171,11 @@ void SString::PVPrintf(const WCHAR *format, va_list args)
errno = 0;
va_copy(ap, args);
+#if defined(FEATURE_CORESYSTEM)
int result = _vsnwprintf_s(GetRawUnicode(), GetRawCount()+1, _TRUNCATE, format, ap);
+#else
+ int result = _vswprintf_p(GetRawUnicode(), GetRawCount()+1, format, ap);
+#endif
va_end(ap);
if (result >= 0)
diff --git a/src/coreclr/utilcode/stresslog.cpp b/src/coreclr/utilcode/stresslog.cpp
index 5d13b2ec7695c..a9e36516b6dcd 100644
--- a/src/coreclr/utilcode/stresslog.cpp
+++ b/src/coreclr/utilcode/stresslog.cpp
@@ -345,12 +345,6 @@ void StressLog::AddModule(uint8_t* moduleBase)
}
#endif //MEMORY_MAPPED_STRESSLOG
theLog.modules[moduleIndex].size = PAL_CopyModuleData(moduleBase, destination, destination_end);
-#ifdef MEMORY_MAPPED_STRESSLOG
- if (hdr != nullptr)
- {
- hdr->modules[moduleIndex].size = theLog.modules[moduleIndex].size;
- }
-#endif //MEMORY_MAPPED_STRESSLOG
#endif //HOST_WINDOWS
}
@@ -890,6 +884,7 @@ void StressLog::LogMsg(unsigned level, unsigned facility, const StressLogMsg &ms
if (InlinedStressLogOn(facility, level))
{
+#ifdef HOST_WINDOWS // On Linux, this cast: (va_list)msg.m_args gives a compile error
ThreadStressLog* msgs = t_pCurrentThreadLog;
if (msgs == 0)
@@ -899,15 +894,7 @@ void StressLog::LogMsg(unsigned level, unsigned facility, const StressLogMsg &ms
if (msgs == 0)
return;
}
-#ifdef HOST_WINDOWS
- // On Linux, this cast: (va_list)msg.m_args gives a compile error
msgs->LogMsg(facility, msg.m_cArgs, msg.m_format, (va_list)msg.m_args);
-#else
- msgs->LogMsg(facility, msg.m_cArgs, msg.m_format,
- msg.m_args[0], msg.m_args[1], msg.m_args[2], msg.m_args[3],
- msg.m_args[4], msg.m_args[5], msg.m_args[6], msg.m_args[7],
- msg.m_args[8], msg.m_args[9], msg.m_args[10], msg.m_args[11],
- msg.m_args[12], msg.m_args[13], msg.m_args[14], msg.m_args[15]);
#endif //HOST_WINDOWS
}
diff --git a/src/coreclr/utilcode/util.cpp b/src/coreclr/utilcode/util.cpp
index ee90f9db6c538..afc0c057d3ee5 100644
--- a/src/coreclr/utilcode/util.cpp
+++ b/src/coreclr/utilcode/util.cpp
@@ -19,12 +19,66 @@
#include "corinfo.h"
#include "volatile.h"
#include "mdfileformat.h"
-#include
#ifndef DACCESS_COMPILE
UINT32 g_nClrInstanceId = 0;
#endif //!DACCESS_COMPILE
+//********** Code. ************************************************************
+
+#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORESYSTEM)
+extern WinRTStatusEnum gWinRTStatus = WINRT_STATUS_UNINITED;
+#endif // FEATURE_COMINTEROP && !FEATURE_CORESYSTEM
+
+#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORESYSTEM)
+//------------------------------------------------------------------------------
+//
+// Attempt to detect the presense of Windows Runtime support on the current OS.
+// Our algorithm to do this is to ensure that:
+// 1. combase.dll exists
+// 2. combase.dll contains a RoInitialize export
+//
+
+void InitWinRTStatus()
+{
+ STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_GC_NOTRIGGER;
+ STATIC_CONTRACT_CANNOT_TAKE_LOCK;
+
+ WinRTStatusEnum winRTStatus = WINRT_STATUS_UNSUPPORTED;
+
+ const WCHAR wszComBaseDll[] = W("\\combase.dll");
+ const SIZE_T cchComBaseDll = ARRAY_SIZE(wszComBaseDll);
+
+ WCHAR wszComBasePath[MAX_LONGPATH + 1];
+ const SIZE_T cchComBasePath = ARRAY_SIZE(wszComBasePath);
+
+ ZeroMemory(wszComBasePath, cchComBasePath * sizeof(wszComBasePath[0]));
+
+ UINT cchSystemDirectory = WszGetSystemDirectory(wszComBasePath, MAX_LONGPATH);
+
+ // Make sure that we're only probing in the system directory. If we can't find the system directory, or
+ // we find it but combase.dll doesn't fit into it, we'll fall back to a safe default of saying that WinRT
+ // is simply not present.
+ if (cchSystemDirectory > 0 && cchComBasePath - cchSystemDirectory >= cchComBaseDll)
+ {
+ if (wcscat_s(wszComBasePath, wszComBaseDll) == 0)
+ {
+ HModuleHolder hComBase(WszLoadLibrary(wszComBasePath));
+ if (hComBase != NULL)
+ {
+ FARPROC activateInstace = GetProcAddress(hComBase, "RoInitialize");
+ if (activateInstace != NULL)
+ {
+ winRTStatus = WINRT_STATUS_SUPPORTED;
+ }
+ }
+ }
+ }
+
+ gWinRTStatus = winRTStatus;
+}
+#endif // FEATURE_COMINTEROP && !FEATURE_CORESYSTEM
//*****************************************************************************
// Convert a string of hex digits into a hex value of the specified # of bytes.
//*****************************************************************************
@@ -773,7 +827,7 @@ DWORD LCM(DWORD u, DWORD v)
CONTRACTL_END;
#if !defined(FEATURE_REDHAWK) && (defined(TARGET_AMD64) || defined(TARGET_ARM64))
- BOOL enableGCCPUGroups = Configuration::GetKnobBooleanValue(W("System.GC.CpuGroup"), CLRConfig::EXTERNAL_GCCpuGroup);
+ BOOL enableGCCPUGroups = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_GCCpuGroup) != 0;
if (!enableGCCPUGroups)
return;
@@ -1751,7 +1805,9 @@ HRESULT validateOneArg(
// Validate the referenced type.
if(FAILED(hr = validateOneArg(tk, pSig, pulNSentinels, pImport, FALSE))) IfFailGo(hr);
break;
- case ELEMENT_TYPE_BYREF:
+ case ELEMENT_TYPE_BYREF: //fallthru
+ if(TypeFromToken(tk)==mdtFieldDef) IfFailGo(VLDTR_E_SIG_BYREFINFIELD);
+ FALLTHROUGH;
case ELEMENT_TYPE_PINNED:
case ELEMENT_TYPE_SZARRAY:
// Validate the referenced type.
diff --git a/src/coreclr/utilcode/utilmessagebox.cpp b/src/coreclr/utilcode/utilmessagebox.cpp
index 8ae1d046169e7..5a8b1f5e2d69b 100644
--- a/src/coreclr/utilcode/utilmessagebox.cpp
+++ b/src/coreclr/utilcode/utilmessagebox.cpp
@@ -17,6 +17,12 @@
#include "clrversion.h"
#include "../dlls/mscorrc/resource.h"
#include "ex.h"
+#if !defined(FEATURE_CORESYSTEM)
+#undef NTDDI_VERSION
+#define NTDDI_VERSION NTDDI_WIN7
+#include "commctrl.h"
+#endif
+
BOOL ShouldDisplayMsgBoxOnCriticalFailure()
{
@@ -187,46 +193,48 @@ int UtilMessageBoxNonLocalizedVA(
}
#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
-#ifdef HOST_UNIX
- // For non-interactive processes, we report the message in the event log and via OutputDebugString.
+ // If the current process isn't interactive (a service for example), then we report the message
+ // in the event log and via OutputDebugString.
//
// We may still however attempt to display the message box if the MB_SERVICE_NOTIFICATION
// message box style was specified.
- StackSString message;
-
- message.Printf(W(".NET Runtime version : %s - "), CLR_PRODUCT_VERSION_L);
- if (lpTitle)
- message.Append(lpTitle);
- if (!formattedMessage.IsEmpty())
- message.Append(formattedMessage);
-
- ClrReportEvent(W(".NET Runtime"),
- EVENTLOG_ERROR_TYPE, // event type
- 0, // category zero
- 1024, // event identifier
- NULL, // no user security identifier
- message.GetUnicode());
-
- if(lpTitle != NULL)
- WszOutputDebugString(lpTitle);
- if(!formattedMessage.IsEmpty())
- WszOutputDebugString(formattedMessage);
-
- // If we are running as a service and displayForNonInteractive is FALSE then IDABORT is
- // the best value to return as it will most likely cause callers of this API to abort the process.
- // This is the right thing to do since attaching a debugger doesn't make much sense when the process isn't
- // running in interactive mode.
- if(!displayForNonInteractive)
- {
- fDisplayMsgBox = FALSE;
- result = IDABORT;
- }
- else
+ if (!RunningInteractive())
{
- // Include in the MB_DEFAULT_DESKTOP_ONLY style.
- uType |= MB_DEFAULT_DESKTOP_ONLY;
+ StackSString message;
+
+ message.Printf(W(".NET Runtime version : %s - "), CLR_PRODUCT_VERSION_L);
+ if (lpTitle)
+ message.Append(lpTitle);
+ if (!formattedMessage.IsEmpty())
+ message.Append(formattedMessage);
+
+ ClrReportEvent(W(".NET Runtime"),
+ EVENTLOG_ERROR_TYPE, // event type
+ 0, // category zero
+ 1024, // event identifier
+ NULL, // no user security identifier
+ message.GetUnicode());
+
+ if(lpTitle != NULL)
+ WszOutputDebugString(lpTitle);
+ if(!formattedMessage.IsEmpty())
+ WszOutputDebugString(formattedMessage);
+
+ // If we are running as a service and displayForNonInteractive is FALSE then IDABORT is
+ // the best value to return as it will most likely cause callers of this API to abort the process.
+ // This is the right thing to do since attaching a debugger doesn't make much sense when the process isn't
+ // running in interactive mode.
+ if(!displayForNonInteractive)
+ {
+ fDisplayMsgBox = FALSE;
+ result = IDABORT;
+ }
+ else
+ {
+ // Include in the MB_DEFAULT_DESKTOP_ONLY style.
+ uType |= MB_DEFAULT_DESKTOP_ONLY;
+ }
}
-#endif // HOST_UNIX
#endif //!defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
if (fDisplayMsgBox)
diff --git a/src/coreclr/utilcode/winfix.cpp b/src/coreclr/utilcode/winfix.cpp
index c6733767e77bf..d572c8edb26ef 100644
--- a/src/coreclr/utilcode/winfix.cpp
+++ b/src/coreclr/utilcode/winfix.cpp
@@ -217,6 +217,39 @@ void EnsureCharSetInfoInitialized()
return;
}
+
+// Running with an interactive workstation.
+BOOL RunningInteractive()
+{
+ STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_FORBID_FAULT;
+
+ static int fInteractive = -1;
+ if (fInteractive != -1)
+ return fInteractive != 0;
+
+#if !defined(FEATURE_CORESYSTEM)
+ HWINSTA hwinsta = NULL;
+
+ if ((hwinsta = GetProcessWindowStation() ) != NULL)
+ {
+ DWORD lengthNeeded;
+ USEROBJECTFLAGS flags;
+
+ if (GetUserObjectInformationW (hwinsta, UOI_FLAGS, &flags, sizeof(flags), &lengthNeeded))
+ {
+ if ((flags.dwFlags & WSF_VISIBLE) == 0)
+ fInteractive = 0;
+ }
+ }
+#endif // !FEATURE_CORESYSTEM
+
+ if (fInteractive != 0)
+ fInteractive = 1;
+
+ return fInteractive != 0;
+}
+
typedef HRESULT(WINAPI *pfnSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription);
extern pfnSetThreadDescription g_pfnSetThreadDescription;
diff --git a/src/coreclr/vm/.vscode/c_cpp_properties.json b/src/coreclr/vm/.vscode/c_cpp_properties.json
index 16279d8db9e74..3e0fa37196a65 100644
--- a/src/coreclr/vm/.vscode/c_cpp_properties.json
+++ b/src/coreclr/vm/.vscode/c_cpp_properties.json
@@ -50,6 +50,7 @@
"FEATURE_COMINTEROP_UNMANAGED_ACTIVATION",
"FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION",
"FEATURE_CORECLR",
+ "FEATURE_CORESYSTEM",
"FEATURE_DATABREAKPOINT",
"FEATURE_DEFAULT_INTERFACES",
"FEATURE_EVENT_TRACE=1",
diff --git a/src/coreclr/vm/CMakeLists.txt b/src/coreclr/vm/CMakeLists.txt
index 08a5bb92a66ed..2f34d2c0ceaa1 100644
--- a/src/coreclr/vm/CMakeLists.txt
+++ b/src/coreclr/vm/CMakeLists.txt
@@ -63,7 +63,7 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON
debuginfostore.cpp
decodemd.cpp
disassembler.cpp
- domainassembly.cpp
+ domainfile.cpp
dynamicmethod.cpp
ecall.cpp
eedbginterfaceimpl.cpp
@@ -161,7 +161,8 @@ set(VM_HEADERS_DAC_AND_WKS_COMMON
debuginfostore.h
decodemd.h
disassembler.h
- domainassembly.h
+ domainfile.h
+ domainfile.inl
dynamicmethod.h
ecall.h
eedbginterfaceimpl.h
@@ -288,6 +289,7 @@ set(GC_HEADERS_DAC
set(VM_SOURCES_WKS
${VM_SOURCES_DAC_AND_WKS_COMMON}
appdomainnative.cpp
+ assemblyname.cpp
assemblynative.cpp
assemblyspec.cpp
baseassemblyspec.cpp
@@ -390,6 +392,7 @@ set(VM_HEADERS_WKS
${VM_HEADERS_DAC_AND_WKS_COMMON}
../inc/jithelpers.h
appdomainnative.hpp
+ assemblyname.hpp
assemblynative.hpp
assemblyspec.hpp
assemblyspecbase.h
diff --git a/src/coreclr/vm/amd64/cgencpu.h b/src/coreclr/vm/amd64/cgencpu.h
index 33589c27bae39..29b9dddfb7de4 100644
--- a/src/coreclr/vm/amd64/cgencpu.h
+++ b/src/coreclr/vm/amd64/cgencpu.h
@@ -415,6 +415,8 @@ extern "C" void setFPReturn(int fpSize, INT64 retVal);
extern "C" void getFPReturn(int fpSize, INT64 *retval);
+struct ComToManagedExRecord; // defined in cgencpu.cpp
+
#include
struct DECLSPEC_ALIGN(8) UMEntryThunkCode
{
diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp
index 80e22d4f7f209..0194f960809d9 100644
--- a/src/coreclr/vm/appdomain.cpp
+++ b/src/coreclr/vm/appdomain.cpp
@@ -11,6 +11,7 @@
#include "eeconfig.h"
#include "gcheaputilities.h"
#include "eventtrace.h"
+#include "assemblyname.hpp"
#include "eeprofinterfaces.h"
#include "dbginterface.h"
#ifndef DACCESS_COMPILE
@@ -1321,10 +1322,10 @@ void SystemDomain::LoadBaseSystemClasses()
// Only partially load the system assembly. Other parts of the code will want to access
// the globals in this function before finishing the load.
- m_pSystemAssembly = DefaultDomain()->LoadDomainAssembly(NULL, m_pSystemPEAssembly, FILE_LOAD_POST_LOADLIBRARY)->GetAssembly();
+ m_pSystemAssembly = DefaultDomain()->LoadDomainAssembly(NULL, m_pSystemPEAssembly, FILE_LOAD_POST_LOADLIBRARY)->GetCurrentAssembly();
// Set up binder for CoreLib
- CoreLibBinder::AttachModule(m_pSystemAssembly->GetModule());
+ CoreLibBinder::AttachModule(m_pSystemAssembly->GetManifestModule());
// Load Object
g_pObjectClass = CoreLibBinder::GetClass(CLASS__OBJECT);
@@ -2173,7 +2174,7 @@ BOOL AppDomain::ContainsAssembly(Assembly * assem)
while (i.Next(pDomainAssembly.This()))
{
- CollectibleAssemblyHolder pAssembly = pDomainAssembly->GetAssembly();
+ CollectibleAssemblyHolder pAssembly = pDomainAssembly->GetLoadedAssembly();
if (pAssembly == assem)
return TRUE;
}
@@ -2238,7 +2239,7 @@ DispIDCache* AppDomain::SetupRefDispIDCache()
#endif // FEATURE_COMINTEROP
-FileLoadLock *FileLoadLock::Create(PEFileListLock *pLock, PEAssembly * pPEAssembly, DomainAssembly *pDomainAssembly)
+FileLoadLock *FileLoadLock::Create(PEFileListLock *pLock, PEAssembly * pPEAssembly, DomainFile *pDomainFile)
{
CONTRACTL
{
@@ -2251,7 +2252,7 @@ FileLoadLock *FileLoadLock::Create(PEFileListLock *pLock, PEAssembly * pPEAssemb
}
CONTRACTL_END;
- NewHolder result(new FileLoadLock(pLock, pPEAssembly, pDomainAssembly));
+ NewHolder result(new FileLoadLock(pLock, pPEAssembly, pDomainFile));
pLock->AddElement(result);
result->AddRef(); // Add one ref on behalf of the ListLock's reference. The corresponding Release() happens in FileLoadLock::CompleteLoadLevel.
@@ -2271,10 +2272,10 @@ FileLoadLock::~FileLoadLock()
((PEAssembly *) m_data)->Release();
}
-DomainAssembly *FileLoadLock::GetDomainAssembly()
+DomainFile *FileLoadLock::GetDomainFile()
{
LIMITED_METHOD_CONTRACT;
- return m_pDomainAssembly;
+ return m_pDomainFile;
}
FileLoadLevel FileLoadLock::GetLoadLevel()
@@ -2356,7 +2357,7 @@ BOOL FileLoadLock::CompleteLoadLevel(FileLoadLevel level, BOOL success)
if (level > m_level)
{
// Must complete each level in turn, unless we have an error
- CONSISTENCY_CHECK(m_pDomainAssembly->IsError() || (level == (m_level+1)));
+ CONSISTENCY_CHECK(m_pDomainFile->IsError() || (level == (m_level+1)));
// Remove the lock from the list if the load is completed
if (level >= FILE_ACTIVE)
{
@@ -2370,18 +2371,18 @@ BOOL FileLoadLock::CompleteLoadLevel(FileLoadLevel level, BOOL success)
m_pList->Unlink(this);
_ASSERTE(fDbgOnly_SuccessfulUnlink);
- m_pDomainAssembly->ClearLoading();
+ m_pDomainFile->ClearLoading();
- CONSISTENCY_CHECK(m_dwRefCount >= 2); // Caller (LoadDomainAssembly) should have 1 refcount and m_pList should have another which was acquired in FileLoadLock::Create.
+ CONSISTENCY_CHECK(m_dwRefCount >= 2); // Caller (LoadDomainFile) should have 1 refcount and m_pList should have another which was acquired in FileLoadLock::Create.
m_level = (FileLoadLevel)level;
// Dev11 bug 236344
// In AppDomain::IsLoading, if the lock is taken on m_pList and then FindFileLock returns NULL,
- // we depend on the DomainAssembly's load level being up to date. Hence we must update the load
+ // we depend on the DomainFile's load level being up to date. Hence we must update the load
// level while the m_pList lock is held.
if (success)
- m_pDomainAssembly->SetLoadLevel(level);
+ m_pDomainFile->SetLoadLevel(level);
}
@@ -2393,7 +2394,7 @@ BOOL FileLoadLock::CompleteLoadLevel(FileLoadLevel level, BOOL success)
m_level = (FileLoadLevel)level;
if (success)
- m_pDomainAssembly->SetLoadLevel(level);
+ m_pDomainFile->SetLoadLevel(level);
}
#ifndef DACCESS_COMPILE
@@ -2404,7 +2405,7 @@ BOOL FileLoadLock::CompleteLoadLevel(FileLoadLevel level, BOOL success)
case FILE_LOAD_DELIVER_EVENTS:
case FILE_LOADED:
case FILE_ACTIVE: // The timing of stress logs is not critical, so even for the FILE_ACTIVE stage we need not do it while the m_pList lock is held.
- STRESS_LOG3(LF_CLASSLOADER, LL_INFO100, "Completed Load Level %s for DomainAssembly %p - success = %i\n", fileLoadLevelName[level], m_pDomainAssembly, success);
+ STRESS_LOG3(LF_CLASSLOADER, LL_INFO100, "Completed Load Level %s for DomainFile %p - success = %i\n", fileLoadLevelName[level], m_pDomainFile, success);
break;
default:
break;
@@ -2433,9 +2434,9 @@ void FileLoadLock::SetError(Exception *ex)
m_cachedHR = ex->GetHR();
LOG((LF_LOADER, LL_WARNING, "LOADER: %x:***%s*\t!!!Non-transient error 0x%x\n",
- m_pDomainAssembly->GetAppDomain(), m_pDomainAssembly->GetSimpleName(), m_cachedHR));
+ m_pDomainFile->GetAppDomain(), m_pDomainFile->GetSimpleName(), m_cachedHR));
- m_pDomainAssembly->SetError(ex);
+ m_pDomainFile->SetError(ex);
CompleteLoadLevel(FILE_ACTIVE, FALSE);
}
@@ -2463,10 +2464,10 @@ UINT32 FileLoadLock::Release()
return count;
}
-FileLoadLock::FileLoadLock(PEFileListLock *pLock, PEAssembly * pPEAssembly, DomainAssembly *pDomainAssembly)
+FileLoadLock::FileLoadLock(PEFileListLock *pLock, PEAssembly * pPEAssembly, DomainFile *pDomainFile)
: ListLockEntry(pLock, pPEAssembly, "File load lock"),
m_level((FileLoadLevel) (FILE_LOAD_CREATE)),
- m_pDomainAssembly(pDomainAssembly),
+ m_pDomainFile(pDomainFile),
m_cachedHR(S_OK)
{
WRAPPER_NO_CONTRACT;
@@ -2521,6 +2522,26 @@ void AppDomain::LoadSystemAssemblies()
LoadAssembly(NULL, SystemDomain::System()->SystemPEAssembly(), FILE_ACTIVE);
}
+FileLoadLevel AppDomain::GetDomainFileLoadLevel(DomainFile *pFile)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END
+
+ LoadLockHolder lock(this);
+
+ FileLoadLock* pLockEntry = (FileLoadLock *) lock->FindFileLock(pFile->GetPEAssembly());
+
+ if (pLockEntry == NULL)
+ return pFile->GetLoadLevel();
+ else
+ return pLockEntry->GetLoadLevel();
+}
+
// This checks if the thread has initiated (or completed) loading at the given level. A false guarantees that
// (a) The current thread (or a thread blocking on the current thread) has not started loading the file
// at the given level, and
@@ -2534,7 +2555,7 @@ void AppDomain::LoadSystemAssemblies()
// thread has completed the load step.
//
-BOOL AppDomain::IsLoading(DomainAssembly *pFile, FileLoadLevel level)
+BOOL AppDomain::IsLoading(DomainFile *pFile, FileLoadLevel level)
{
// Cheap out
if (pFile->GetLoadLevel() < level)
@@ -2571,7 +2592,7 @@ BOOL AppDomain::IsLoading(DomainAssembly *pFile, FileLoadLevel level)
// CheckLoading is a weaker form of IsLoading, which will not block on
// other threads waiting for their status. This is appropriate for asserts.
-CHECK AppDomain::CheckLoading(DomainAssembly *pFile, FileLoadLevel level)
+CHECK AppDomain::CheckLoading(DomainFile *pFile, FileLoadLevel level)
{
// Cheap out
if (pFile->GetLoadLevel() < level)
@@ -2605,7 +2626,7 @@ CHECK AppDomain::CheckCanLoadTypes(Assembly *pAssembly)
MODE_ANY;
}
CONTRACTL_END;
- CHECK_MSG(CheckValidModule(pAssembly->GetModule()),
+ CHECK_MSG(CheckValidModule(pAssembly->GetManifestModule()),
"Type loading can occur only when executing in the assembly's app domain");
CHECK_OK;
}
@@ -2637,7 +2658,7 @@ CHECK AppDomain::CheckCanExecuteManagedCode(MethodDesc* pMD)
#endif // !DACCESS_COMPILE
-void AppDomain::LoadDomainAssembly(DomainAssembly *pFile,
+void AppDomain::LoadDomainFile(DomainFile *pFile,
FileLoadLevel targetLevel)
{
CONTRACTL
@@ -2677,7 +2698,7 @@ void AppDomain::LoadDomainAssembly(DomainAssembly *pFile,
lock.Release();
- LoadDomainAssembly(pLockEntry, targetLevel);
+ LoadDomainFile(pLockEntry, targetLevel);
}
#else // DACCESS_COMPILE
@@ -2854,12 +2875,12 @@ DomainAssembly *AppDomain::LoadDomainAssemblyInternal(AssemblySpec* pIdentity,
if (result == NULL)
{
- // We pass our ref on fileLock to LoadDomainAssembly to release.
+ // We pass our ref on fileLock to LoadDomainFile to release.
// Note that if we throw here, we will poison fileLock with an error condition,
// so it will not be removed until app domain unload. So there is no need
// to release our ref count.
- result = (DomainAssembly *)LoadDomainAssembly(fileLock, targetLevel);
+ result = (DomainAssembly *)LoadDomainFile(fileLock, targetLevel);
}
else
{
@@ -2868,12 +2889,20 @@ DomainAssembly *AppDomain::LoadDomainAssemblyInternal(AssemblySpec* pIdentity,
if (registerNewAssembly)
{
- pPEAssembly->GetAssemblyBinder()->AddLoadedAssembly(pDomainAssembly->GetAssembly());
+ pPEAssembly->GetAssemblyBinder()->AddLoadedAssembly(pDomainAssembly->GetCurrentAssembly());
}
}
else
result->EnsureLoadLevel(targetLevel);
+ // Malformed metadata may contain a Module reference to what is actually
+ // an Assembly. In this case we need to throw an exception, since returning
+ // a DomainModule as a DomainAssembly is a type safety violation.
+ if (!result->IsAssembly())
+ {
+ ThrowHR(COR_E_ASSEMBLYEXPECTED);
+ }
+
// Cache result in all cases, since found pPEAssembly could be from a different AssemblyRef than pIdentity
if (pIdentity == NULL)
{
@@ -2889,20 +2918,28 @@ DomainAssembly *AppDomain::LoadDomainAssemblyInternal(AssemblySpec* pIdentity,
RETURN result;
} // AppDomain::LoadDomainAssembly
-DomainAssembly *AppDomain::LoadDomainAssembly(FileLoadLock *pLock, FileLoadLevel targetLevel)
+
+struct LoadFileArgs
{
- CONTRACT(DomainAssembly *)
+ FileLoadLock *pLock;
+ FileLoadLevel targetLevel;
+ DomainFile *result;
+};
+
+DomainFile *AppDomain::LoadDomainFile(FileLoadLock *pLock, FileLoadLevel targetLevel)
+{
+ CONTRACT(DomainFile *)
{
STANDARD_VM_CHECK;
PRECONDITION(CheckPointer(pLock));
- PRECONDITION(pLock->GetDomainAssembly()->GetAppDomain() == this);
+ PRECONDITION(pLock->GetDomainFile()->GetAppDomain() == this);
POSTCONDITION(RETVAL->GetLoadLevel() >= GetThreadFileLoadLevel()
|| RETVAL->GetLoadLevel() >= targetLevel);
POSTCONDITION(RETVAL->CheckNoError(targetLevel));
}
CONTRACT_END;
- DomainAssembly *pFile = pLock->GetDomainAssembly();
+ DomainFile *pFile = pLock->GetDomainFile();
// Make sure we release the lock on exit
FileLoadLockRefHolder lockRef(pLock);
@@ -2997,7 +3034,7 @@ DomainAssembly *AppDomain::LoadDomainAssembly(FileLoadLock *pLock, FileLoadLevel
// lower level. In such a case, we throw an exception which transiently fails the current
// load, since it is likely we have not satisfied the caller.
// (An alternate, and possibly preferable, strategy here would be for all callers to explicitly
- // specify the minimum load level acceptable and throw if not reached.)
+ // identify the minimum load level acceptable via CheckLoadDomainFile and throw from there.)
pFile->RequireLoadLevel((FileLoadLevel)(immediateTargetLevel-1));
@@ -3005,7 +3042,7 @@ DomainAssembly *AppDomain::LoadDomainAssembly(FileLoadLock *pLock, FileLoadLevel
RETURN pFile;
}
-void AppDomain::TryIncrementalLoad(DomainAssembly *pFile, FileLoadLevel workLevel, FileLoadLockHolder &lockHolder)
+void AppDomain::TryIncrementalLoad(DomainFile *pFile, FileLoadLevel workLevel, FileLoadLockHolder &lockHolder)
{
STANDARD_VM_CONTRACT;
@@ -3019,7 +3056,7 @@ void AppDomain::TryIncrementalLoad(DomainAssembly *pFile, FileLoadLevel workLeve
// Special case: for LoadLibrary, we cannot hold the lock during the
// actual LoadLibrary call, because we might get a callback from _CorDllMain on any
- // other thread. (Note that this requires DomainAssembly's LoadLibrary to be independently threadsafe.)
+ // other thread. (Note that this requires DomainFile's LoadLibrary to be independently threadsafe.)
if (workLevel == FILE_LOAD_LOADLIBRARY)
{
@@ -3103,7 +3140,7 @@ CHECK AppDomain::CheckValidModule(Module * pModule)
}
CONTRACTL_END;
- if (pModule->GetDomainAssembly() != NULL)
+ if (pModule->GetDomainFile() != NULL)
CHECK_OK;
CHECK_OK;
@@ -3790,7 +3827,7 @@ PEAssembly *AppDomain::TryResolveAssemblyUsingEvent(AssemblySpec *pSpec)
Assembly *pAssembly = RaiseAssemblyResolveEvent(pSpec);
if (pAssembly != nullptr)
{
- PEAssembly* pPEAssembly = pAssembly->GetPEAssembly();
+ PEAssembly* pPEAssembly = pAssembly->GetManifestFile();
pPEAssembly->AddRef();
result = pPEAssembly;
}
@@ -4178,7 +4215,7 @@ DWORD DomainLocalModule::GetClassFlags(MethodTable* pMT, DWORD iClassIndex /*=(D
} CONTRACTL_END;
{
- CONSISTENCY_CHECK(GetDomainAssembly()->GetModule() == pMT->GetModuleForStatics());
+ CONSISTENCY_CHECK(GetDomainFile()->GetModule() == pMT->GetModuleForStatics());
}
if (pMT->IsDynamicStatics())
@@ -4209,7 +4246,7 @@ void DomainLocalModule::SetClassInitialized(MethodTable* pMT)
}
CONTRACTL_END;
- BaseDomain::DomainLocalBlockLockHolder lh(GetDomainAssembly()->GetAppDomain());
+ BaseDomain::DomainLocalBlockLockHolder lh(GetDomainFile()->GetAppDomain());
_ASSERTE(!IsClassInitialized(pMT));
_ASSERTE(!IsClassInitError(pMT));
@@ -4221,7 +4258,7 @@ void DomainLocalModule::SetClassInitError(MethodTable* pMT)
{
WRAPPER_NO_CONTRACT;
- BaseDomain::DomainLocalBlockLockHolder lh(GetDomainAssembly()->GetAppDomain());
+ BaseDomain::DomainLocalBlockLockHolder lh(GetDomainFile()->GetAppDomain());
SetClassFlags(pMT, ClassInitFlags::ERROR_FLAG);
}
@@ -4231,9 +4268,9 @@ void DomainLocalModule::SetClassFlags(MethodTable* pMT, DWORD dwFlags)
CONTRACTL {
THROWS;
GC_TRIGGERS;
- PRECONDITION(GetDomainAssembly()->GetModule() == pMT->GetModuleForStatics());
+ PRECONDITION(GetDomainFile()->GetModule() == pMT->GetModuleForStatics());
// Assumes BaseDomain::DomainLocalBlockLockHolder is taken
- PRECONDITION(GetDomainAssembly()->GetAppDomain()->OwnDomainLocalBlockLock());
+ PRECONDITION(GetDomainFile()->GetAppDomain()->OwnDomainLocalBlockLock());
} CONTRACTL_END;
if (pMT->IsDynamicStatics())
@@ -4258,7 +4295,7 @@ void DomainLocalModule::EnsureDynamicClassIndex(DWORD dwID)
MODE_ANY;
INJECT_FAULT(COMPlusThrowOM(););
// Assumes BaseDomain::DomainLocalBlockLockHolder is taken
- PRECONDITION(GetDomainAssembly()->GetAppDomain()->OwnDomainLocalBlockLock());
+ PRECONDITION(GetDomainFile()->GetAppDomain()->OwnDomainLocalBlockLock());
}
CONTRACTL_END;
@@ -4276,7 +4313,7 @@ void DomainLocalModule::EnsureDynamicClassIndex(DWORD dwID)
DynamicClassInfo* pNewDynamicClassTable;
pNewDynamicClassTable = (DynamicClassInfo*)
- (void*)GetDomainAssembly()->GetLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(
+ (void*)GetDomainFile()->GetLoaderAllocator()->GetHighFrequencyHeap()->AllocMem(
S_SIZE_T(sizeof(DynamicClassInfo)) * S_SIZE_T(aDynamicEntries));
memcpy(pNewDynamicClassTable, m_pDynamicClassTable, sizeof(DynamicClassInfo) * m_aDynamicEntries);
@@ -4300,13 +4337,13 @@ void DomainLocalModule::AllocateDynamicClass(MethodTable *pMT)
THROWS;
GC_TRIGGERS;
// Assumes BaseDomain::DomainLocalBlockLockHolder is taken
- PRECONDITION(GetDomainAssembly()->GetAppDomain()->OwnDomainLocalBlockLock());
+ PRECONDITION(GetDomainFile()->GetAppDomain()->OwnDomainLocalBlockLock());
}
CONTRACTL_END;
_ASSERTE(!pMT->ContainsGenericVariables());
_ASSERTE(!pMT->IsSharedByGenericInstantiations());
- _ASSERTE(GetDomainAssembly()->GetModule() == pMT->GetModuleForStatics());
+ _ASSERTE(GetDomainFile()->GetModule() == pMT->GetModuleForStatics());
_ASSERTE(pMT->IsDynamicStatics());
DWORD dynamicEntryIDIndex = pMT->GetModuleDynamicEntryID();
@@ -4331,7 +4368,7 @@ void DomainLocalModule::AllocateDynamicClass(MethodTable *pMT)
{
if (pDynamicStatics == NULL)
{
- LoaderHeap * pLoaderAllocator = GetDomainAssembly()->GetLoaderAllocator()->GetHighFrequencyHeap();
+ LoaderHeap * pLoaderAllocator = GetDomainFile()->GetLoaderAllocator()->GetHighFrequencyHeap();
if (pMT->Collectible())
{
@@ -4370,7 +4407,7 @@ void DomainLocalModule::AllocateDynamicClass(MethodTable *pMT)
else
#endif
nongcStaticsArray = AllocatePrimitiveArray(ELEMENT_TYPE_U1, dwStaticBytes);
- ((CollectibleDynamicEntry *)pDynamicStatics)->m_hNonGCStatics = GetDomainAssembly()->GetModule()->GetLoaderAllocator()->AllocateHandle(nongcStaticsArray);
+ ((CollectibleDynamicEntry *)pDynamicStatics)->m_hNonGCStatics = GetDomainFile()->GetModule()->GetLoaderAllocator()->AllocateHandle(nongcStaticsArray);
GCPROTECT_END();
}
if (dwNumHandleStatics > 0)
@@ -4386,7 +4423,7 @@ void DomainLocalModule::AllocateDynamicClass(MethodTable *pMT)
OBJECTREF gcStaticsArray = NULL;
GCPROTECT_BEGIN(gcStaticsArray);
gcStaticsArray = AllocateObjectArray(dwNumHandleStatics, g_pObjectClass);
- ((CollectibleDynamicEntry *)pDynamicStatics)->m_hGCStatics = GetDomainAssembly()->GetModule()->GetLoaderAllocator()->AllocateHandle(gcStaticsArray);
+ ((CollectibleDynamicEntry *)pDynamicStatics)->m_hGCStatics = GetDomainFile()->GetModule()->GetLoaderAllocator()->AllocateHandle(gcStaticsArray);
GCPROTECT_END();
}
}
@@ -4411,7 +4448,7 @@ void DomainLocalModule::PopulateClass(MethodTable *pMT)
if (!IsClassAllocated(pMT, iClassIndex))
{
- BaseDomain::DomainLocalBlockLockHolder lh(GetDomainAssembly()->GetAppDomain());
+ BaseDomain::DomainLocalBlockLockHolder lh(GetDomainFile()->GetAppDomain());
if (!IsClassAllocated(pMT, iClassIndex))
{
@@ -4866,7 +4903,7 @@ AppDomain::AssemblyIterator::Next_Unlocked(
// Un-tenured collectible assemblies should not be returned. (This can only happen in a brief
// window during collectible assembly creation. No thread should need to have a pointer
// to the just allocated DomainAssembly at this stage.)
- if (!pDomainAssembly->GetAssembly()->GetModule()->IsTenured())
+ if (!pDomainAssembly->GetAssembly()->GetManifestModule()->IsTenured())
{
continue; // reject
}
@@ -5149,9 +5186,9 @@ DomainLocalModule::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
// sizeof(DomainLocalModule) == 0x28
DAC_ENUM_DTHIS();
- if (m_pDomainAssembly.IsValid())
+ if (m_pDomainFile.IsValid())
{
- m_pDomainAssembly->EnumMemoryRegions(flags);
+ m_pDomainFile->EnumMemoryRegions(flags);
}
if (m_pDynamicClassTable.Load().IsValid())
diff --git a/src/coreclr/vm/appdomain.hpp b/src/coreclr/vm/appdomain.hpp
index fbe728ff7e1c0..a369823a53937 100644
--- a/src/coreclr/vm/appdomain.hpp
+++ b/src/coreclr/vm/appdomain.hpp
@@ -21,7 +21,7 @@
#include "arraylist.h"
#include "comreflectioncache.hpp"
#include "comutilnative.h"
-#include "domainassembly.h"
+#include "domainfile.h"
#include "fptrstubs.h"
#include "gcheaputilities.h"
#include "gchandleutilities.h"
@@ -201,18 +201,18 @@ struct DomainLocalModule
static SIZE_T GetOffsetOfDataBlob() { return offsetof(DomainLocalModule, m_pDataBlob); }
static SIZE_T GetOffsetOfGCStaticPointer() { return offsetof(DomainLocalModule, m_pGCStatics); }
- inline DomainAssembly* GetDomainAssembly()
+ inline DomainFile* GetDomainFile()
{
LIMITED_METHOD_CONTRACT
SUPPORTS_DAC;
- return m_pDomainAssembly;
+ return m_pDomainFile;
}
#ifndef DACCESS_COMPILE
- inline void SetDomainAssembly(DomainAssembly* pDomainAssembly)
+ inline void SetDomainFile(DomainFile* pDomainFile)
{
LIMITED_METHOD_CONTRACT
- m_pDomainAssembly = pDomainAssembly;
+ m_pDomainFile = pDomainFile;
}
#endif
@@ -236,7 +236,7 @@ struct DomainLocalModule
if (pMT->IsDynamicStatics())
{
- _ASSERTE(GetDomainAssembly()->GetModule() == pMT->GetModuleForStatics());
+ _ASSERTE(GetDomainFile()->GetModule() == pMT->GetModuleForStatics());
return GetDynamicEntryGCStaticsBasePointer(pMT->GetModuleDynamicEntryID(), pMT->GetLoaderAllocator());
}
else
@@ -252,7 +252,7 @@ struct DomainLocalModule
if (pMT->IsDynamicStatics())
{
- _ASSERTE(GetDomainAssembly()->GetModule() == pMT->GetModuleForStatics());
+ _ASSERTE(GetDomainFile()->GetModule() == pMT->GetModuleForStatics());
return GetDynamicEntryNonGCStaticsBasePointer(pMT->GetModuleDynamicEntryID(), pMT->GetLoaderAllocator());
}
else
@@ -403,7 +403,7 @@ struct DomainLocalModule
FORCEINLINE MethodTable * GetMethodTableFromClassDomainID(DWORD dwClassDomainID)
{
DWORD rid = (DWORD)(dwClassDomainID) + 1;
- TypeHandle th = GetDomainAssembly()->GetModule()->LookupTypeDef(TokenFromRid(rid, mdtTypeDef));
+ TypeHandle th = GetDomainFile()->GetModule()->LookupTypeDef(TokenFromRid(rid, mdtTypeDef));
_ASSERTE(!th.IsNull());
MethodTable * pMT = th.AsMethodTable();
PREFIX_ASSUME(pMT != NULL);
@@ -416,7 +416,7 @@ struct DomainLocalModule
void SetClassFlags(MethodTable* pMT, DWORD dwFlags);
DWORD GetClassFlags(MethodTable* pMT, DWORD iClassIndex);
- PTR_DomainAssembly m_pDomainAssembly;
+ PTR_DomainFile m_pDomainFile;
VolatilePtr m_pDynamicClassTable; // used for generics and reflection.emit in memory
Volatile m_aDynamicEntries; // number of entries in dynamic table
VolatilePtr m_pADThunkTable;
@@ -747,7 +747,7 @@ typedef PEFileListLock::Holder PEFileListLockHolder;
// Loading infrastructure:
//
-// a DomainAssembly is a file being loaded. Files are loaded in layers to enable loading in the
+// a DomainFile is a file being loaded. Files are loaded in layers to enable loading in the
// presence of dependency loops.
//
// FileLoadLevel describes the various levels available. These are implemented slightly
@@ -773,14 +773,14 @@ class FileLoadLock : public ListLockEntry
{
private:
FileLoadLevel m_level;
- DomainAssembly *m_pDomainAssembly;
+ DomainFile *m_pDomainFile;
HRESULT m_cachedHR;
public:
- static FileLoadLock *Create(PEFileListLock *pLock, PEAssembly *pPEAssembly, DomainAssembly *pDomainAssembly);
+ static FileLoadLock *Create(PEFileListLock *pLock, PEAssembly *pPEAssembly, DomainFile *pDomainFile);
~FileLoadLock();
- DomainAssembly *GetDomainAssembly();
+ DomainFile *GetDomainFile();
FileLoadLevel GetLoadLevel();
// CanAcquire will return FALSE if Acquire will definitely not take the lock due
@@ -807,7 +807,7 @@ class FileLoadLock : public ListLockEntry
private:
- FileLoadLock(PEFileListLock *pLock, PEAssembly *pPEAssembly, DomainAssembly *pDomainAssembly);
+ FileLoadLock(PEFileListLock *pLock, PEAssembly *pPEAssembly, DomainFile *pDomainFile);
static void HolderLeave(FileLoadLock *pThis);
@@ -1307,7 +1307,7 @@ enum AssemblyIterationFlags
// (all m_level values)
kIncludeAvailableToProfilers
= 0x00000020, // include assemblies available to profilers
- // See comment at code:DomainAssembly::IsAvailableToProfilers
+ // See comment at code:DomainFile::IsAvailableToProfilers
// Execution / introspection flags
kIncludeExecution = 0x00000004, // include assemblies that are loaded for execution only
@@ -1797,12 +1797,13 @@ class AppDomain : public BaseDomain
CHECK CheckCanLoadTypes(Assembly *pAssembly);
CHECK CheckCanExecuteManagedCode(MethodDesc* pMD);
- CHECK CheckLoading(DomainAssembly *pFile, FileLoadLevel level);
+ CHECK CheckLoading(DomainFile *pFile, FileLoadLevel level);
- BOOL IsLoading(DomainAssembly *pFile, FileLoadLevel level);
+ FileLoadLevel GetDomainFileLoadLevel(DomainFile *pFile);
+ BOOL IsLoading(DomainFile *pFile, FileLoadLevel level);
static FileLoadLevel GetThreadFileLoadLevel();
- void LoadDomainAssembly(DomainAssembly *pFile,
+ void LoadDomainFile(DomainFile *pFile,
FileLoadLevel targetLevel);
enum FindAssemblyOptions
@@ -1838,10 +1839,10 @@ class AppDomain : public BaseDomain
// private:
void LoadSystemAssemblies();
- DomainAssembly *LoadDomainAssembly(FileLoadLock *pLock,
+ DomainFile *LoadDomainFile(FileLoadLock *pLock,
FileLoadLevel targetLevel);
- void TryIncrementalLoad(DomainAssembly *pFile, FileLoadLevel workLevel, FileLoadLockHolder &lockHolder);
+ void TryIncrementalLoad(DomainFile *pFile, FileLoadLevel workLevel, FileLoadLockHolder &lockHolder);
#ifndef DACCESS_COMPILE // needs AssemblySpec
@@ -2452,7 +2453,7 @@ class SystemDomain : public BaseDomain
{
WRAPPER_NO_CONTRACT;
- return SystemAssembly()->GetModule();
+ return SystemAssembly()->GetManifestModule();
}
static BOOL IsSystemLoaded()
@@ -2579,7 +2580,7 @@ class SystemDomain : public BaseDomain
// Or, it might be the location of CoreLib
if (System()->SystemAssembly() != NULL
- && path.EqualsCaseInsensitive(System()->SystemAssembly()->GetPEAssembly()->GetPath()))
+ && path.EqualsCaseInsensitive(System()->SystemAssembly()->GetManifestFile()->GetPath()))
return TRUE;
return FALSE;
diff --git a/src/coreclr/vm/arm64/asmhelpers.S b/src/coreclr/vm/arm64/asmhelpers.S
index e7725cd16e63b..7d8b3c7dd88b2 100644
--- a/src/coreclr/vm/arm64/asmhelpers.S
+++ b/src/coreclr/vm/arm64/asmhelpers.S
@@ -551,6 +551,152 @@ LOCAL_LABEL(LNullThis):
LEAF_END SinglecastDelegateInvokeStub, _TEXT
+#ifdef FEATURE_COMINTEROP
+
+#define ComCallPreStub_FrameSize (SIZEOF__GSCookie + SIZEOF__ComMethodFrame)
+#define ComCallPreStub_FirstStackAdjust (8 + SIZEOF__ArgumentRegisters + 2 * 8) // x8, reg args , fp & lr already pushed
+#define ComCallPreStub_StackAlloc0 (ComCallPreStub_FrameSize - ComCallPreStub_FirstStackAdjust)
+#define ComCallPreStub_StackAlloc1 (ComCallPreStub_StackAlloc0 + SIZEOF__FloatArgumentRegisters + 8)// 8 for ErrorReturn
+#define ComCallPreStub_StackAlloc (ComCallPreStub_StackAlloc1 + (ComCallPreStub_StackAlloc1 & 8))
+
+#define ComCallPreStub_FrameOffset (ComCallPreStub_StackAlloc - (SIZEOF__ComMethodFrame - ComCallPreStub_FirstStackAdjust))
+#define ComCallPreStub_ErrorReturnOffset0 SIZEOF__FloatArgumentRegisters
+
+#define ComCallPreStub_FirstStackAdjust (ComCallPreStub_ErrorReturnOffset0 + (ComCallPreStub_ErrorReturnOffset0 & 8))
+
+// ------------------------------------------------------------------
+// COM to CLR stub called the first time a particular method is invoked.//
+//
+// On entry:
+// x12 : ComCallMethodDesc* provided by prepad thunk
+// plus user arguments in registers and on the stack
+//
+// On exit:
+// tail calls to real method
+//
+NESTED_ENTRY ComCallPreStub, _TEXT, NoHandler
+
+ // Save arguments and return address
+ PROLOG_SAVE_REG_PAIR fp, lr, -ComCallPreStub_FirstStackAdjust!
+ PROLOG_STACK_ALLOC ComCallPreStub_StackAlloc
+
+ SAVE_ARGUMENT_REGISTERS sp, (16+ComCallPreStub_StackAlloc)
+
+ SAVE_FLOAT_ARGUMENT_REGISTERS sp, 0
+
+ str x12, [sp, #(ComCallPreStub_FrameOffset + UnmanagedToManagedFrame__m_pvDatum)]
+ add x0, sp, #(ComCallPreStub_FrameOffset)
+ add x1, sp, #(ComCallPreStub_ErrorReturnOffset)
+ bl C_FUNC(ComPreStubWorker)
+
+ cbz x0, LOCAL_LABEL(ComCallPreStub_ErrorExit)
+
+ mov x12, x0
+
+ // pop the stack and restore original register state
+ RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 0
+ RESTORE_ARGUMENT_REGISTERS sp, (16+ComCallPreStub_StackAlloc)
+
+ EPILOG_STACK_FREE ComCallPreStub_StackAlloc
+ EPILOG_RESTORE_REG_PAIR fp, lr, ComCallPreStub_FirstStackAdjust!
+
+ // and tailcall to the actual method
+ EPILOG_BRANCH_REG x12
+
+ComCallPreStub_ErrorExit
+ ldr x0, [sp, #(ComCallPreStub_ErrorReturnOffset)] // ErrorReturn
+
+ // pop the stack
+ EPILOG_STACK_FREE ComCallPreStub_StackAlloc
+ EPILOG_RESTORE_REG_PAIR fp, lr, ComCallPreStub_FirstStackAdjust!
+
+ EPILOG_RETURN
+
+NESTED_END ComCallPreStub, _TEXT
+
+// ------------------------------------------------------------------
+// COM to CLR stub which sets up a ComMethodFrame and calls COMToCLRWorker.
+//
+// On entry:
+// x12 : ComCallMethodDesc* provided by prepad thunk
+// plus user arguments in registers and on the stack
+//
+// On exit:
+// Result in x0/d0 as per the real method being called
+//
+ NESTED_ENTRY GenericComCallStub, _TEXT, NoHandler
+
+ // Save arguments and return address
+ PROLOG_SAVE_REG_PAIR fp, lr, -GenericComCallStub_FirstStackAdjust!
+ PROLOG_STACK_ALLOC GenericComCallStub_StackAlloc
+
+ SAVE_ARGUMENT_REGISTERS sp, (16+GenericComCallStub_StackAlloc)
+ SAVE_FLOAT_ARGUMENT_REGISTERS sp, 0
+
+ str x12, [sp, #(GenericComCallStub_FrameOffset + UnmanagedToManagedFrame__m_pvDatum)]
+ add x1, sp, #GenericComCallStub_FrameOffset
+ bl C_FUNC(COMToCLRWorker)
+
+ // pop the stack
+ EPILOG_STACK_FREE GenericComCallStub_StackAlloc
+ EPILOG_RESTORE_REG_PAIR fp, lr, GenericComCallStub_FirstStackAdjust!
+
+ EPILOG_RETURN
+
+ NESTED_END GenericComCallStub, _TEXT
+
+// ------------------------------------------------------------------
+// COM to CLR stub called from COMToCLRWorker that actually dispatches to the real managed method.
+//
+// On entry:
+// x0 : dwStackSlots, count of argument stack slots to copy
+// x1 : pFrame, ComMethodFrame pushed by GenericComCallStub above
+// x2 : pTarget, address of code to call
+// x3 : pSecretArg, hidden argument passed to target above in x12
+// x4 : pDangerousThis, managed 'this' reference
+//
+// On exit:
+// Result in x0/d0 as per the real method being called
+//
+ NESTED_ENTRY COMToCLRDispatchHelper, _TEXT,CallDescrWorkerUnwindFrameChainHandler
+
+ PROLOG_SAVE_REG_PAIR fp, lr, -16!
+
+ cbz x0, LOCAL_LABEL(COMToCLRDispatchHelper_RegSetup)
+
+ add x9, x1, #SIZEOF__ComMethodFrame
+ add x9, x9, x0, LSL #3
+COMToCLRDispatchHelper_StackLoop
+ ldr x8, [x9, #-8]!
+ str x8, [sp, #-8]!
+ sub x0, x0, #1
+ cbnz x0, LOCAL_LABEL(COMToCLRDispatchHelper_StackLoop)
+
+COMToCLRDispatchHelper_RegSetup
+
+ RESTORE_FLOAT_ARGUMENT_REGISTERS x1, -1 * GenericComCallStub_FrameOffset
+
+ mov lr, x2
+ mov x12, x3
+
+ mov x0, x4
+
+ ldp x2, x3, [x1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters + 16)]
+ ldp x4, x5, [x1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters + 32)]
+ ldp x6, x7, [x1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters + 48)]
+ ldr x8, [x1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters - 8)]
+
+ ldr x1, [x1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters + 8)]
+
+ blr lr
+
+ EPILOG_STACK_RESTORE
+ EPILOG_RESTORE_REG_PAIR fp, lr, 16!
+ EPILOG_RETURN
+
+ NESTED_END COMToCLRDispatchHelper, _TEXT
+
+#endif // FEATURE_COMINTEROP
//
// x12 = UMEntryThunk*
//
@@ -893,6 +1039,39 @@ DynamicHelper DynamicHelperFrameFlags_ObjectArg, _Obj
DynamicHelper DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_ObjectArg2, _ObjObj
#endif
+#ifdef FEATURE_COMINTEROP
+
+// Function used by COM interop to get floating point return value (since it's not in the same
+// register(s) as non-floating point values).
+//
+// On entry//
+// x0 : size of the FP result (4 or 8 bytes)
+// x1 : pointer to 64-bit buffer to receive result
+//
+// On exit:
+// buffer pointed to by x1 on entry contains the float or double argument as appropriate
+//
+LEAF_ENTRY getFPReturn, _TEXT
+ str d0, [x1]
+LEAF_END getFPReturn, _TEXT
+
+// ------------------------------------------------------------------
+// Function used by COM interop to set floating point return value (since it's not in the same
+// register(s) as non-floating point values).
+//
+// On entry:
+// x0 : size of the FP result (4 or 8 bytes)
+// x1 : 32-bit or 64-bit FP result
+//
+// On exit:
+// s0 : float result if x0 == 4
+// d0 : double result if x0 == 8
+//
+LEAF_ENTRY setFPReturn, _TEXT
+ fmov d0, x1
+LEAF_END setFPReturn, _TEXT
+#endif
+
//
// JIT Static access helpers when coreclr host specifies single appdomain flag
//
diff --git a/src/coreclr/vm/assembly.cpp b/src/coreclr/vm/assembly.cpp
index 83840af5b5138..09c6ff22c2f83 100644
--- a/src/coreclr/vm/assembly.cpp
+++ b/src/coreclr/vm/assembly.cpp
@@ -17,6 +17,9 @@
#include "assembly.hpp"
#include "appdomain.hpp"
+#include "assemblyname.hpp"
+
+
#include "eeprofinterfaces.h"
#include "reflectclasswriter.h"
@@ -123,13 +126,14 @@ Assembly::Assembly(BaseDomain *pDomain, PEAssembly* pPEAssembly, DebuggerAssembl
m_pDomain(pDomain),
m_pClassLoader(NULL),
m_pEntryPoint(NULL),
- m_pModule(NULL),
- m_pPEAssembly(clr::SafeAddRef(pPEAssembly)),
+ m_pManifest(NULL),
+ m_pManifestFile(clr::SafeAddRef(pPEAssembly)),
m_pFriendAssemblyDescriptor(NULL),
m_isDynamic(false),
#ifdef FEATURE_COLLECTIBLE_TYPES
m_isCollectible(fIsCollectible),
#endif
+ m_nextAvailableModuleIndex(1),
m_pLoaderAllocator(NULL),
#ifdef FEATURE_COMINTEROP
m_pITypeLib(NULL),
@@ -185,7 +189,7 @@ void Assembly::Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocat
m_pClassLoader = new ClassLoader(this);
m_pClassLoader->Init(pamTracker);
- PEAssembly* pPEAssembly = GetPEAssembly();
+ PEAssembly* pPEAssembly = GetManifestFile();
// "Module::Create" will initialize R2R support, if there is an R2R header.
// make sure the PE is loaded or R2R will be disabled.
@@ -193,15 +197,17 @@ void Assembly::Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocat
if (pPEAssembly->IsDynamic())
// manifest modules of dynamic assemblies are always transient
- m_pModule = ReflectionModule::Create(this, pPEAssembly, pamTracker, REFEMIT_MANIFEST_MODULE_NAME);
+ m_pManifest = ReflectionModule::Create(this, pPEAssembly, pamTracker, REFEMIT_MANIFEST_MODULE_NAME);
else
- m_pModule = Module::Create(this, mdFileNil, pPEAssembly, pamTracker);
+ m_pManifest = Module::Create(this, mdFileNil, pPEAssembly, pamTracker);
FastInterlockIncrement((LONG*)&g_cAssemblies);
- PrepareModuleForAssembly(m_pModule, pamTracker);
+ PrepareModuleForAssembly(m_pManifest, pamTracker);
+
+ CacheManifestFiles();
- if (!m_pModule->IsReadyToRun())
+ if (!m_pManifest->IsReadyToRun())
CacheManifestExportedTypes(pamTracker);
// We'll load the friend assembly information lazily. For the ngen case we should avoid
@@ -225,7 +231,7 @@ void Assembly::Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocat
FAULT_FORBID();
//Cannot fail after this point.
- PublishModuleIntoAssembly(m_pModule);
+ PublishModuleIntoAssembly(m_pManifest);
return; // Explicit return to let you know you are NOT welcome to add code after the CANNOTTHROW/FAULT_FORBID expires
}
@@ -246,9 +252,9 @@ Assembly::~Assembly()
if (m_pFriendAssemblyDescriptor != NULL)
m_pFriendAssemblyDescriptor->Release();
- if (m_pPEAssembly)
+ if (m_pManifestFile)
{
- m_pPEAssembly->Release();
+ m_pManifestFile->Release();
}
#ifdef FEATURE_COMINTEROP
@@ -328,7 +334,7 @@ void Assembly::Terminate( BOOL signalProfiler )
Assembly * Assembly::Create(
BaseDomain * pDomain,
- PEAssembly * pPEAssembly,
+ PEAssembly * pFile,
DebuggerAssemblyControlFlags debuggerFlags,
BOOL fIsCollectible,
AllocMemTracker * pamTracker,
@@ -336,7 +342,7 @@ Assembly * Assembly::Create(
{
STANDARD_VM_CONTRACT;
- NewHolder pAssembly (new Assembly(pDomain, pPEAssembly, debuggerFlags, fIsCollectible));
+ NewHolder pAssembly (new Assembly(pDomain, pFile, debuggerFlags, fIsCollectible));
#ifdef PROFILING_SUPPORTED
{
@@ -423,7 +429,7 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, AssemblyBinder* pBinder, C
|| name.Find(i, ':')
|| name.Find(i, '/'))
{
- COMPlusThrow(kArgumentException, W("InvalidAssemblyName"));
+ COMPlusThrow(kArgumentException, W("Argument_InvalidAssemblyName"));
}
// Set up the assembly manifest metadata
@@ -510,7 +516,7 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, AssemblyBinder* pBinder, C
IfFailThrow(pAssemblyEmit->DefineAssembly(publicKey, publicKey.GetSize(), ulHashAlgId,
name, &assemData, dwFlags,
&ma));
- pPEAssembly = PEAssembly::Create(pCallerAssembly->GetPEAssembly(), pAssemblyEmit);
+ pPEAssembly = PEAssembly::Create(pCallerAssembly->GetManifestFile(), pAssemblyEmit);
AssemblyBinder* pFallbackBinder = pBinder;
@@ -525,7 +531,7 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, AssemblyBinder* pBinder, C
// and will have a fallback load context binder associated with it.
// There is always a manifest file - wehther working with static or dynamic assemblies.
- PEAssembly* pCallerAssemblyManifestFile = pCallerAssembly->GetPEAssembly();
+ PEAssembly* pCallerAssemblyManifestFile = pCallerAssembly->GetManifestFile();
_ASSERTE(pCallerAssemblyManifestFile != NULL);
if (!pCallerAssemblyManifestFile->IsDynamic())
@@ -619,7 +625,7 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, AssemblyBinder* pBinder, C
// Assembly::Create will call SuppressRelease on the NewHolder that holds the LoaderAllocator when it transfers ownership
pAssem = Assembly::Create(pDomain, pPEAssembly, pDomainAssembly->GetDebuggerInfoBits(), pLoaderAllocator->IsCollectible(), pamTracker, pLoaderAllocator);
- ReflectionModule* pModule = (ReflectionModule*) pAssem->GetModule();
+ ReflectionModule* pModule = (ReflectionModule*) pAssem->GetManifestModule();
pModule->SetCreatingAssembly( pCallerAssembly );
@@ -690,7 +696,7 @@ void Assembly::SetDomainAssembly(DomainAssembly *pDomainAssembly)
}
CONTRACTL_END;
- GetModule()->SetDomainAssembly(pDomainAssembly);
+ GetManifestModule()->SetDomainFile(pDomainAssembly);
} // Assembly::SetDomainAssembly
@@ -699,7 +705,7 @@ void Assembly::SetDomainAssembly(DomainAssembly *pDomainAssembly)
DomainAssembly *Assembly::GetDomainAssembly()
{
LIMITED_METHOD_DAC_CONTRACT;
- return GetModule()->GetDomainAssembly();
+ return GetManifestModule()->GetDomainAssembly();
}
PTR_LoaderHeap Assembly::GetLowFrequencyHeap()
@@ -792,9 +798,9 @@ Module *Assembly::FindModuleByExportedType(mdExportedType mdType,
mdToken mdLinkRef;
mdToken mdBinding;
- IMDInternalImport *pMDImport = GetMDImport();
+ IMDInternalImport *pManifestImport = GetManifestImport();
- IfFailThrow(pMDImport->GetExportedTypeProps(
+ IfFailThrow(pManifestImport->GetExportedTypeProps(
mdType,
NULL,
NULL,
@@ -803,7 +809,7 @@ Module *Assembly::FindModuleByExportedType(mdExportedType mdType,
NULL)); // dwflags
// Don't trust the returned tokens.
- if (!pMDImport->IsValidToken(mdLinkRef))
+ if (!pManifestImport->IsValidToken(mdLinkRef))
{
if (loadFlag != Loader::Load)
{
@@ -828,27 +834,27 @@ Module *Assembly::FindModuleByExportedType(mdExportedType mdType,
#ifndef DACCESS_COMPILE
// LoadAssembly never returns NULL
DomainAssembly * pDomainAssembly =
- GetModule()->LoadAssembly(mdLinkRef);
+ GetManifestModule()->LoadAssembly(mdLinkRef);
PREFIX_ASSUME(pDomainAssembly != NULL);
- RETURN pDomainAssembly->GetModule();
+ RETURN pDomainAssembly->GetCurrentModule();
#else
_ASSERTE(!"DAC shouldn't attempt to trigger loading");
return NULL;
#endif // !DACCESS_COMPILE
};
case Loader::DontLoad:
- pAssembly = GetModule()->GetAssemblyIfLoaded(mdLinkRef);
+ pAssembly = GetManifestModule()->GetAssemblyIfLoaded(mdLinkRef);
break;
case Loader::SafeLookup:
- pAssembly = GetModule()->LookupAssemblyRef(mdLinkRef);
+ pAssembly = GetManifestModule()->LookupAssemblyRef(mdLinkRef);
break;
default:
_ASSERTE(FALSE);
}
if (pAssembly)
- RETURN pAssembly->GetModule();
+ RETURN pAssembly->GetManifestModule();
else
RETURN NULL;
@@ -865,7 +871,7 @@ Module *Assembly::FindModuleByExportedType(mdExportedType mdType,
// Note that we don't want to attempt a LoadModule if a GetModuleIfLoaded will
// succeed, because it has a stronger contract.
- Module *pModule = GetModule()->GetModuleIfLoaded(mdLinkRef);
+ Module *pModule = GetManifestModule()->GetModuleIfLoaded(mdLinkRef);
#ifdef DACCESS_COMPILE
return pModule;
#else
@@ -878,17 +884,17 @@ Module *Assembly::FindModuleByExportedType(mdExportedType mdType,
// We should never get here in the GC case - the above should have succeeded.
CONSISTENCY_CHECK(!FORBIDGC_LOADER_USE_ENABLED());
- DomainAssembly* pDomainModule = NULL;
+ DomainFile* pDomainModule = NULL;
if (loadFlag == Loader::Load)
{
- pDomainModule = GetModule()->LoadModule(::GetAppDomain(), mdLinkRef);
+ pDomainModule = GetManifestModule()->LoadModule(::GetAppDomain(), mdLinkRef);
}
if (pDomainModule == NULL)
RETURN NULL;
else
{
- pModule = pDomainModule->GetModule();
+ pModule = pDomainModule->GetCurrentModule();
if (pModule == NULL)
{
_ASSERTE(loadFlag!=Loader::Load);
@@ -1011,8 +1017,8 @@ Module * Assembly::FindModuleByTypeRef(
#ifndef DACCESS_COMPILE
if (loadFlag == Loader::Load)
{
- DomainAssembly* pActualDomainAssembly = pModule->LoadModule(::GetAppDomain(), tkType);
- RETURN(pActualDomainAssembly->GetModule());
+ DomainFile* pActualDomainFile = pModule->LoadModule(::GetAppDomain(), tkType);
+ RETURN(pActualDomainFile->GetModule());
}
else
{
@@ -1048,7 +1054,7 @@ Module * Assembly::FindModuleByTypeRef(
if (pAssembly != NULL)
{
- RETURN pAssembly->m_pModule;
+ RETURN pAssembly->m_pManifest;
}
#ifdef DACCESS_COMPILE
@@ -1066,14 +1072,14 @@ Module * Assembly::FindModuleByTypeRef(
if (pDomainAssembly == NULL)
RETURN NULL;
- pAssembly = pDomainAssembly->GetAssembly();
+ pAssembly = pDomainAssembly->GetCurrentAssembly();
if (pAssembly == NULL)
{
RETURN NULL;
}
else
{
- RETURN pAssembly->m_pModule;
+ RETURN pAssembly->m_pManifest;
}
#endif //!DACCESS_COMPILE
}
@@ -1108,9 +1114,9 @@ Module *Assembly::FindModuleByName(LPCSTR pszModuleName)
ThrowHR(COR_E_UNAUTHORIZEDACCESS);
if (this == SystemDomain::SystemAssembly())
- RETURN m_pModule->GetModuleIfLoaded(kFile);
+ RETURN m_pManifest->GetModuleIfLoaded(kFile);
else
- RETURN m_pModule->LoadModule(::GetAppDomain(), kFile)->GetModule();
+ RETURN m_pManifest->LoadModule(::GetAppDomain(), kFile)->GetModule();
}
void Assembly::CacheManifestExportedTypes(AllocMemTracker *pamTracker)
@@ -1126,24 +1132,28 @@ void Assembly::CacheManifestExportedTypes(AllocMemTracker *pamTracker)
// Prejitted assemblies are expected to have their table prebuilt.
// If not, we do it here at load time (as if we would jit the assembly).
- if (m_pModule->IsPersistedObject(m_pModule->m_pAvailableClasses))
+ if (m_pManifest->IsPersistedObject(m_pManifest->m_pAvailableClasses))
RETURN;
mdToken mdExportedType;
- HENUMInternalHolder phEnum(GetMDImport());
+ HENUMInternalHolder phEnum(GetManifestImport());
phEnum.EnumInit(mdtExportedType,
mdTokenNil);
ClassLoader::AvailableClasses_LockHolder lh(m_pClassLoader);
- for(int i = 0; GetMDImport()->EnumNext(&phEnum, &mdExportedType); i++)
- m_pClassLoader->AddExportedTypeHaveLock(GetModule(),
+ for(int i = 0; GetManifestImport()->EnumNext(&phEnum, &mdExportedType); i++)
+ m_pClassLoader->AddExportedTypeHaveLock(GetManifestModule(),
mdExportedType,
pamTracker);
RETURN;
}
+void Assembly::CacheManifestFiles()
+{
+}
+
//@TODO: if module is not signed it needs to acquire the
//permissions from the assembly.
@@ -1176,7 +1186,7 @@ void Assembly::PrepareModuleForAssembly(Module* module, AllocMemTracker *pamTrac
module->GetDebuggerInfoBits()));
#endif // DEBUGGING_SUPPORTED
- m_pModule->EnsureFileCanBeStored(module->GetModuleRef());
+ m_pManifest->EnsureFileCanBeStored(module->GetModuleRef());
}
// This is the final step of publishing a Module into an Assembly. This step cannot fail.
@@ -1190,7 +1200,7 @@ void Assembly::PublishModuleIntoAssembly(Module *module)
}
CONTRACTL_END
- GetModule()->EnsuredStoreFile(module->GetModuleRef(), module);
+ GetManifestModule()->EnsuredStoreFile(module->GetModuleRef(), module);
FastInterlockIncrement((LONG*)&m_pClassLoader->m_cUnhashedModules);
}
@@ -1212,7 +1222,7 @@ void Assembly::CacheFriendAssemblyInfo()
if (m_pFriendAssemblyDescriptor == NULL)
{
- ReleaseHolder pFriendAssemblies = FriendAssemblyDescriptor::CreateFriendAssemblyDescriptor(this->GetPEAssembly());
+ ReleaseHolder pFriendAssemblies = FriendAssemblyDescriptor::CreateFriendAssemblyDescriptor(this->GetManifestFile());
_ASSERTE(pFriendAssemblies != NULL);
CrstHolder friendDescriptorLock(&g_friendAssembliesCrst);
@@ -1247,7 +1257,7 @@ void Assembly::UpdateCachedFriendAssemblyInfo()
while (true)
{
- ReleaseHolder pFriendAssemblies = FriendAssemblyDescriptor::CreateFriendAssemblyDescriptor(this->GetPEAssembly());
+ ReleaseHolder pFriendAssemblies = FriendAssemblyDescriptor::CreateFriendAssemblyDescriptor(this->GetManifestFile());
FriendAssemblyDescriptor* pFriendAssemblyDescriptorNextLoop = NULL;
{
@@ -1689,14 +1699,14 @@ MethodDesc* Assembly::GetEntryPoint()
if (m_pEntryPoint)
RETURN m_pEntryPoint;
- mdToken mdEntry = m_pPEAssembly->GetEntryPointToken();
+ mdToken mdEntry = m_pManifestFile->GetEntryPointToken();
if (IsNilToken(mdEntry))
RETURN NULL;
Module *pModule = NULL;
switch(TypeFromToken(mdEntry)) {
case mdtFile:
- pModule = m_pModule->LoadModule(::GetAppDomain(), mdEntry)->GetModule();
+ pModule = m_pManifest->LoadModule(::GetAppDomain(), mdEntry)->GetModule();
mdEntry = pModule->GetEntryPointToken();
if ( (TypeFromToken(mdEntry) != mdtMethodDef) ||
@@ -1705,8 +1715,8 @@ MethodDesc* Assembly::GetEntryPoint()
break;
case mdtMethodDef:
- if (m_pPEAssembly->GetMDImport()->IsValidToken(mdEntry))
- pModule = m_pModule;
+ if (m_pManifestFile->GetMDImport()->IsValidToken(mdEntry))
+ pModule = m_pManifest;
break;
}
@@ -1864,7 +1874,7 @@ BOOL Assembly::IsInstrumentedHelper()
return false;
// We must have a native image in order to perform IBC instrumentation
- if (!GetPEAssembly()->IsReadyToRun())
+ if (!GetManifestFile()->IsReadyToRun())
return false;
// @Consider using the full name instead of the short form
@@ -1991,7 +2001,7 @@ mdAssemblyRef Assembly::AddAssemblyRef(Assembly *refedAssembly, IMetaDataAssembl
SafeComHolder emitHolder;
AssemblySpec spec;
- spec.InitializeSpec(refedAssembly->GetPEAssembly());
+ spec.InitializeSpec(refedAssembly->GetManifestFile());
if (refedAssembly->IsCollectible())
{
@@ -2049,7 +2059,7 @@ void Assembly::AddExportedType(mdExportedType cl)
CONTRACTL_END
AllocMemTracker amTracker;
- m_pClassLoader->AddExportedTypeDontHaveLock(GetModule(),
+ m_pClassLoader->AddExportedTypeDontHaveLock(GetManifestModule(),
cl,
&amTracker);
amTracker.SuppressRelease();
@@ -2228,13 +2238,13 @@ Assembly::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
{
m_pClassLoader->EnumMemoryRegions(flags);
}
- if (m_pModule.IsValid())
+ if (m_pManifest.IsValid())
{
- m_pModule->EnumMemoryRegions(flags, true);
+ m_pManifest->EnumMemoryRegions(flags, true);
}
- if (m_pPEAssembly.IsValid())
+ if (m_pManifestFile.IsValid())
{
- m_pPEAssembly->EnumMemoryRegions(flags);
+ m_pManifestFile->EnumMemoryRegions(flags);
}
}
diff --git a/src/coreclr/vm/assembly.hpp b/src/coreclr/vm/assembly.hpp
index 8c72128f3e4f6..f8de5c162e752 100644
--- a/src/coreclr/vm/assembly.hpp
+++ b/src/coreclr/vm/assembly.hpp
@@ -56,8 +56,16 @@ struct CreateDynamicAssemblyArgs : CreateDynamicAssemblyArgsGC
StackCrawlMark* stackMark;
};
-// An assembly is the unit of deployment for managed code.
-// Assemblies are one to one with files since coreclr does not support multimodule assemblies.
+// An assembly is the unit of deployment for managed code. Typically Assemblies are one to one with files
+// (Modules), however this is not necessary, as an assembly can contain serveral files (typically you only
+// do this so that you can resource-only modules that are national language specific)
+//
+// Conceptually Assemblies are loaded into code:AppDomain
+//
+// So in general an assemly is a list of code:Module, where a code:Module is 1-1 with a DLL or EXE file.
+//
+// One of the modules the code:Assembly.m_pManifest is special in that it knows about all the other
+// modules in an assembly (often it is the only one).
//
class Assembly
{
@@ -80,7 +88,7 @@ class Assembly
static Assembly *Create(BaseDomain *pDomain, PEAssembly *pPEAssembly, DebuggerAssemblyControlFlags debuggerFlags, BOOL fIsCollectible, AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocator);
static void Initialize();
- BOOL IsSystem() { WRAPPER_NO_CONTRACT; return m_pPEAssembly->IsSystem(); }
+ BOOL IsSystem() { WRAPPER_NO_CONTRACT; return m_pManifestFile->IsSystem(); }
static Assembly *CreateDynamic(AppDomain *pDomain, AssemblyBinder* pBinder, CreateDynamicAssemblyArgs *args);
@@ -100,7 +108,15 @@ class Assembly
void SetIsTenured()
{
WRAPPER_NO_CONTRACT;
- m_pModule->SetIsTenured();
+ m_pManifest->SetIsTenured();
+ }
+
+ // CAUTION: This should only be used as backout code if an assembly is unsuccessfully
+ // added to the shared domain assembly map.
+ void UnsetIsTenured()
+ {
+ WRAPPER_NO_CONTRACT;
+ m_pManifest->UnsetIsTenured();
}
#endif // DACCESS_COMPILE
@@ -114,6 +130,72 @@ class Assembly
return m_pClassLoader;
}
+ // ------------------------------------------------------------
+ // Modules
+ // ------------------------------------------------------------
+
+ class ModuleIterator
+ {
+ Module* m_pManifest;
+ DWORD m_i;
+
+ public:
+ // The preferred constructor. If you use this, you don't have to
+ // call Start() yourself
+ ModuleIterator(Assembly *pAssembly)
+ {
+ WRAPPER_NO_CONTRACT;
+ Start(pAssembly);
+ }
+
+ // When you don't have the Assembly at contruction time, use this
+ // constructor, and explicitly call Start() to begin the iteration.
+ ModuleIterator()
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ m_pManifest = NULL;
+ m_i = (DWORD) -1;
+ }
+
+ void Start(Assembly * pAssembly)
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ m_pManifest = pAssembly->GetManifestModule();
+ m_i = (DWORD) -1;
+ }
+
+ BOOL Next()
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+ while (++m_i <= m_pManifest->GetFileMax())
+ {
+ if (GetModule() != NULL)
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ Module *GetModule()
+ {
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+ return m_pManifest->LookupFile(TokenFromRid(m_i, mdtFile));
+ }
+ };
+
+ ModuleIterator IterateModules()
+ {
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+ return ModuleIterator(this);
+ }
+
+
//****************************************************************************************
//
// Get the domain the assembly lives in.
@@ -149,75 +231,75 @@ class Assembly
LPCWSTR GetDebugName()
{
WRAPPER_NO_CONTRACT;
- return GetPEAssembly()->GetDebugName();
+ return GetManifestFile()->GetDebugName();
}
#endif
LPCUTF8 GetSimpleName()
{
WRAPPER_NO_CONTRACT;
- return GetPEAssembly()->GetSimpleName();
+ return GetManifestFile()->GetSimpleName();
}
BOOL IsStrongNamed()
{
WRAPPER_NO_CONTRACT;
- return GetPEAssembly()->IsStrongNamed();
+ return GetManifestFile()->IsStrongNamed();
}
const void *GetPublicKey(DWORD *pcbPK)
{
WRAPPER_NO_CONTRACT;
- return GetPEAssembly()->GetPublicKey(pcbPK);
+ return GetManifestFile()->GetPublicKey(pcbPK);
}
ULONG GetHashAlgId()
{
WRAPPER_NO_CONTRACT;
- return GetPEAssembly()->GetHashAlgId();
+ return GetManifestFile()->GetHashAlgId();
}
HRESULT GetVersion(USHORT *pMajor, USHORT *pMinor, USHORT *pBuild, USHORT *pRevision)
{
WRAPPER_NO_CONTRACT;
- return GetPEAssembly()->GetVersion(pMajor, pMinor, pBuild, pRevision);
+ return GetManifestFile()->GetVersion(pMajor, pMinor, pBuild, pRevision);
}
LPCUTF8 GetLocale()
{
WRAPPER_NO_CONTRACT;
- return GetPEAssembly()->GetLocale();
+ return GetManifestFile()->GetLocale();
}
DWORD GetFlags()
{
WRAPPER_NO_CONTRACT;
- return GetPEAssembly()->GetFlags();
+ return GetManifestFile()->GetFlags();
}
PTR_LoaderHeap GetLowFrequencyHeap();
PTR_LoaderHeap GetHighFrequencyHeap();
PTR_LoaderHeap GetStubHeap();
- PTR_Module GetModule()
+ PTR_Module GetManifestModule()
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;
- return m_pModule;
+ return m_pManifest;
}
- PTR_PEAssembly GetPEAssembly()
+ PTR_PEAssembly GetManifestFile()
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;
- return m_pPEAssembly;
+ return m_pManifestFile;
}
- IMDInternalImport* GetMDImport()
+ IMDInternalImport* GetManifestImport()
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;
- return m_pPEAssembly->GetMDImport();
+ return m_pManifestFile->GetMDImport();
}
HRESULT GetCustomAttribute(mdToken parentToken,
@@ -227,7 +309,7 @@ class Assembly
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;
- return GetModule()->GetCustomAttribute(parentToken, attribute, ppData, pcbData);
+ return GetManifestModule()->GetCustomAttribute(parentToken, attribute, ppData, pcbData);
}
mdAssembly GetManifestToken()
@@ -242,7 +324,7 @@ class Assembly
{
WRAPPER_NO_CONTRACT;
- return m_pPEAssembly->GetDisplayName(result, flags);
+ return m_pManifestFile->GetDisplayName(result, flags);
}
#endif // DACCESS_COMPILE
@@ -250,7 +332,7 @@ class Assembly
{
WRAPPER_NO_CONTRACT;
- return m_pPEAssembly->GetCodeBase(result);
+ return m_pManifestFile->GetCodeBase(result);
}
OBJECTREF GetExposedObject();
@@ -278,7 +360,7 @@ class Assembly
ULONG HashIdentity()
{
- return GetPEAssembly()->HashIdentity();
+ return GetManifestFile()->HashIdentity();
}
//****************************************************************************************
@@ -326,6 +408,8 @@ class Assembly
FORCEINLINE BOOL IsDynamic() { LIMITED_METHOD_CONTRACT; return m_isDynamic; }
FORCEINLINE BOOL IsCollectible() { LIMITED_METHOD_DAC_CONTRACT; return m_isCollectible; }
+ DWORD GetNextModuleIndex() { LIMITED_METHOD_CONTRACT; return m_nextAvailableModuleIndex++; }
+
void AddType(Module* pModule,
mdTypeDef cl);
void AddExportedType(mdExportedType cl);
@@ -436,9 +520,9 @@ class Assembly
int mask = INTEROP_ATTRIBUTE_UNSET;
- if (GetModule()->GetCustomAttribute(TokenFromRid(1, mdtAssembly), WellKnownAttribute::ImportedFromTypeLib, NULL, 0) == S_OK)
+ if (GetManifestModule()->GetCustomAttribute(TokenFromRid(1, mdtAssembly), WellKnownAttribute::ImportedFromTypeLib, NULL, 0) == S_OK)
mask |= INTEROP_ATTRIBUTE_IMPORTED_FROM_TYPELIB;
- if (GetModule()->GetCustomAttribute(TokenFromRid(1, mdtAssembly), WellKnownAttribute::PrimaryInteropAssembly, NULL, 0) == S_OK)
+ if (GetManifestModule()->GetCustomAttribute(TokenFromRid(1, mdtAssembly), WellKnownAttribute::PrimaryInteropAssembly, NULL, 0) == S_OK)
mask |= INTEROP_ATTRIBUTE_PRIMARY_INTEROP_ASSEMBLY;
if (!IsDynamic())
@@ -456,6 +540,7 @@ class Assembly
//****************************************************************************************
void CacheManifestExportedTypes(AllocMemTracker *pamTracker);
+ void CacheManifestFiles();
void CacheFriendAssemblyInfo();
#ifndef DACCESS_COMPILE
@@ -469,9 +554,11 @@ class Assembly
PTR_BaseDomain m_pDomain; // Parent Domain
PTR_ClassLoader m_pClassLoader; // Single Loader
+
+
PTR_MethodDesc m_pEntryPoint; // Method containing the entry point
- PTR_Module m_pModule;
- PTR_PEAssembly m_pPEAssembly;
+ PTR_Module m_pManifest;
+ PTR_PEAssembly m_pManifestFile;
FriendAssemblyDescriptor *m_pFriendAssemblyDescriptor;
@@ -479,6 +566,7 @@ class Assembly
#ifdef FEATURE_COLLECTIBLE_TYPES
BOOL m_isCollectible;
#endif // FEATURE_COLLECTIBLE_TYPES
+ DWORD m_nextAvailableModuleIndex;
PTR_LoaderAllocator m_pLoaderAllocator;
#ifdef FEATURE_COMINTEROP
@@ -502,6 +590,8 @@ class Assembly
};
+typedef Assembly::ModuleIterator ModuleIterator;
+
#ifndef DACCESS_COMPILE
//---------------------------------------------------------------------------------------
@@ -583,7 +673,7 @@ class FriendAssemblyDescriptor
static
bool IsAssemblyOnList(Assembly *pAssembly, const ArrayList &alAssemblyNames)
{
- return IsAssemblyOnList(pAssembly->GetPEAssembly(), alAssemblyNames);
+ return IsAssemblyOnList(pAssembly->GetManifestFile(), alAssemblyNames);
}
static
diff --git a/src/coreclr/vm/assemblyname.cpp b/src/coreclr/vm/assemblyname.cpp
new file mode 100644
index 0000000000000..bd6e41e52611b
--- /dev/null
+++ b/src/coreclr/vm/assemblyname.cpp
@@ -0,0 +1,140 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*============================================================
+**
+** Header: AssemblyName.cpp
+**
+** Purpose: Implements AssemblyName (loader domain) architecture
+**
+**
+
+
+**
+===========================================================*/
+
+#include "common.h"
+
+#include
+#include
+
+#include "assemblyname.hpp"
+#include "field.h"
+#include "strongnameholders.h"
+#include "strongnameinternal.h"
+#include "eeconfig.h"
+
+FCIMPL1(Object*, AssemblyNameNative::GetFileInformation, StringObject* filenameUNSAFE)
+{
+ FCALL_CONTRACT;
+
+ struct _gc
+ {
+ ASSEMBLYNAMEREF result;
+ STRINGREF filename;
+ } gc;
+
+ gc.result = NULL;
+ gc.filename = (STRINGREF) filenameUNSAFE;
+
+ HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
+
+ if (gc.filename == NULL)
+ COMPlusThrow(kArgumentNullException, W("ArgumentNull_FileName"));
+
+ if (gc.filename->GetStringLength() == 0)
+ COMPlusThrow(kArgumentException, W("Argument_EmptyFileName"));
+
+ gc.result = (ASSEMBLYNAMEREF) AllocateObject(CoreLibBinder::GetClass(CLASS__ASSEMBLY_NAME));
+
+
+ ///////////////////////////////////////////////
+ SString sFileName(gc.filename->GetBuffer());
+ PEImageHolder pImage = PEImage::OpenImage(sFileName, MDInternalImport_NoCache);
+
+ // Ask for FLAT. We will only look at metadata and release the image shortly.
+ // Besides we may be getting the assembly name for images that contain native code for a
+ // non-native platform and would end up using flat anyways.
+ PEImageLayout* pLayout = pImage->GetOrCreateLayout(PEImageLayout::LAYOUT_FLAT);
+
+ pImage->VerifyIsAssembly();
+
+ AssemblySpec spec;
+ spec.InitializeSpec(TokenFromRid(mdtAssembly,1),pImage->GetMDImport(),NULL);
+ spec.AssemblyNameInit(&gc.result, pImage);
+
+ HELPER_METHOD_FRAME_END();
+ return OBJECTREFToObject(gc.result);
+}
+FCIMPLEND
+
+FCIMPL1(Object*, AssemblyNameNative::GetPublicKeyToken, Object* refThisUNSAFE)
+{
+ FCALL_CONTRACT;
+
+ U1ARRAYREF orOutputArray = NULL;
+ OBJECTREF refThis = (OBJECTREF) refThisUNSAFE;
+ HELPER_METHOD_FRAME_BEGIN_RET_1(refThis);
+
+ if (refThis == NULL)
+ COMPlusThrow(kNullReferenceException, W("NullReference_This"));
+
+ ASSEMBLYNAMEREF orThis = (ASSEMBLYNAMEREF)refThis;
+ U1ARRAYREF orPublicKey = orThis->GetPublicKey();
+
+ if (orPublicKey != NULL) {
+ DWORD cb = orPublicKey->GetNumComponents();
+ StrongNameBufferHolder pbToken;
+
+ if (cb) {
+ CQuickBytes qb;
+ BYTE *pbKey = (BYTE*) qb.AllocThrows(cb);
+ memcpy(pbKey, orPublicKey->GetDataPtr(), cb);
+
+ {
+ GCX_PREEMP();
+ IfFailThrow(StrongNameTokenFromPublicKey(pbKey, cb, &pbToken, &cb));
+ }
+ }
+
+ orOutputArray = (U1ARRAYREF)AllocatePrimitiveArray(ELEMENT_TYPE_U1, cb);
+ memcpyNoGCRefs(orOutputArray->m_Array, pbToken, cb);
+ }
+
+ HELPER_METHOD_FRAME_END();
+ return OBJECTREFToObject(orOutputArray);
+}
+FCIMPLEND
+
+
+FCIMPL1(void, AssemblyNameNative::Init, Object * refThisUNSAFE)
+{
+ FCALL_CONTRACT;
+
+ ASSEMBLYNAMEREF pThis = (ASSEMBLYNAMEREF) (OBJECTREF) refThisUNSAFE;
+ HRESULT hr = S_OK;
+
+ HELPER_METHOD_FRAME_BEGIN_1(pThis);
+
+ if (pThis == NULL)
+ COMPlusThrow(kNullReferenceException, W("NullReference_This"));
+
+ ACQUIRE_STACKING_ALLOCATOR(pStackingAllocator);
+
+ AssemblySpec spec;
+ hr = spec.InitializeSpec(pStackingAllocator, (ASSEMBLYNAMEREF *) &pThis, TRUE);
+
+ if (SUCCEEDED(hr))
+ {
+ spec.AssemblyNameInit(&pThis,NULL);
+ }
+ else
+ {
+ ThrowHR(hr);
+ }
+
+ HELPER_METHOD_FRAME_END();
+}
+FCIMPLEND
+
+
diff --git a/src/coreclr/vm/assemblyname.hpp b/src/coreclr/vm/assemblyname.hpp
new file mode 100644
index 0000000000000..9e818fc1a9f7c
--- /dev/null
+++ b/src/coreclr/vm/assemblyname.hpp
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+/*============================================================
+**
+** Header: AssemblyName.hpp
+**
+** Purpose: Implements AssemblyName (loader domain) architecture
+**
+**
+
+
+**
+===========================================================*/
+#ifndef _AssemblyName_H
+#define _AssemblyName_H
+
+class AssemblyNameNative
+{
+public:
+ static FCDECL1(Object*, GetFileInformation, StringObject* filenameUNSAFE);
+ static FCDECL1(Object*, GetPublicKeyToken, Object* refThisUNSAFE);
+ static FCDECL1(void, Init, Object * refThisUNSAFE);
+};
+
+#endif // _AssemblyName_H
+
diff --git a/src/coreclr/vm/assemblynative.cpp b/src/coreclr/vm/assemblynative.cpp
index dba5110590717..a51280e21e4a3 100644
--- a/src/coreclr/vm/assemblynative.cpp
+++ b/src/coreclr/vm/assemblynative.cpp
@@ -20,6 +20,7 @@
#include "assemblynative.hpp"
#include "dllimport.h"
#include "field.h"
+#include "assemblyname.hpp"
#include "eeconfig.h"
#include "interoputil.h"
#include "frames.h"
@@ -85,8 +86,9 @@ extern "C" void QCALLTYPE AssemblyNative_InternalLoad(QCall::ObjectHandleOnStack
}
// Initialize spec
- spec.InitializeSpec(pStackingAllocator, &assemblyNameRef);
-
+ spec.InitializeSpec(pStackingAllocator,
+ &assemblyNameRef,
+ FALSE);
GCPROTECT_END();
spec.SetCodeBase(NULL);
@@ -105,7 +107,7 @@ extern "C" void QCALLTYPE AssemblyNative_InternalLoad(QCall::ObjectHandleOnStack
{
// If the requesting assembly has Fallback LoadContext binder available,
// then set it up in the AssemblySpec.
- PEAssembly *pRefAssemblyManifestFile = pRefAssembly->GetPEAssembly();
+ PEAssembly *pRefAssemblyManifestFile = pRefAssembly->GetManifestFile();
spec.SetFallbackBinderForRequestingAssembly(pRefAssemblyManifestFile->GetFallbackBinder());
}
@@ -269,7 +271,7 @@ extern "C" void QCALLTYPE AssemblyNative_LoadFromStream(INT_PTR ptrNativeAssembl
// we created above. We need pointer comparison instead of pe image equivalence
// to avoid mixed binaries/PDB pairs of other images.
// This applies to both Desktop CLR and CoreCLR, with or without fusion.
- BOOL fIsSameAssembly = (pLoadedAssembly->GetPEAssembly()->GetPEImage() == pILImage);
+ BOOL fIsSameAssembly = (pLoadedAssembly->GetManifestFile()->GetPEImage() == pILImage);
// Setting the PDB info is only applicable for our original assembly.
// This applies to both Desktop CLR and CoreCLR, with or without fusion.
@@ -280,7 +282,7 @@ extern "C" void QCALLTYPE AssemblyNative_LoadFromStream(INT_PTR ptrNativeAssembl
if (ptrSymbolArray != NULL)
{
PBYTE pSymbolArray = reinterpret_cast(ptrSymbolArray);
- pLoadedAssembly->GetModule()->SetSymbolBytes(pSymbolArray, (DWORD)cbSymbolArrayLength);
+ pLoadedAssembly->GetManifestModule()->SetSymbolBytes(pSymbolArray, (DWORD)cbSymbolArrayLength);
}
#endif // DEBUGGING_SUPPORTED
}
@@ -402,7 +404,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetForwardedType(QCall::AssemblyHandle
mdToken mdImpl;
Assembly * pAsm = pAssembly->GetAssembly();
- Module *pManifestModule = pAsm->GetModule();
+ Module *pManifestModule = pAsm->GetManifestModule();
IfFailThrow(pManifestModule->GetMDImport()->GetExportedTypeProps(mdtExternalType, &pszNameSpace, &pszClassName, &mdImpl, NULL, NULL));
if (TypeFromToken(mdImpl) == mdtAssemblyRef)
{
@@ -612,7 +614,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetModules(QCall::AssemblyHandle pAssem
HENUMInternalHolder phEnum(pAssembly->GetMDImport());
phEnum.EnumInit(mdtFile, mdTokenNil);
- InlineSArray modules;
+ InlineSArray modules;
modules.Append(pAssembly);
@@ -621,7 +623,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetModules(QCall::AssemblyHandle pAssem
{
if (fLoadIfNotFound)
{
- DomainAssembly* pModule = pAssembly->GetModule()->LoadModule(GetAppDomain(), mdFile);
+ DomainFile* pModule = pAssembly->GetModule()->LoadModule(GetAppDomain(), mdFile);
modules.Append(pModule);
}
}
@@ -638,7 +640,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetModules(QCall::AssemblyHandle pAssem
for(COUNT_T i = 0; i < modules.GetCount(); i++)
{
- DomainAssembly * pModule = modules[i];
+ DomainFile * pModule = modules[i];
OBJECTREF o = pModule->GetExposedModuleObject();
orModules->SetAt(i, o);
@@ -697,10 +699,10 @@ extern "C" void QCALLTYPE AssemblyNative_GetModule(QCall::AssemblyHandle pAssemb
LPCUTF8 pModuleName = NULL;
- if SUCCEEDED(pAssembly->GetModule()->GetScopeName(&pModuleName))
+ if SUCCEEDED(pAssembly->GetDomainAssembly()->GetModule()->GetScopeName(&pModuleName))
{
if (::SString::_stricmp(pModuleName, szModuleName) == 0)
- pModule = pAssembly->GetModule();
+ pModule = pAssembly->GetDomainAssembly()->GetModule();
}
@@ -725,7 +727,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetExportedTypes(QCall::AssemblyHandle
Assembly * pAsm = pAssembly->GetAssembly();
- IMDInternalImport *pImport = pAsm->GetMDImport();
+ IMDInternalImport *pImport = pAsm->GetManifestImport();
{
HENUMTypeDefInternalHolder phTDEnum(pImport);
@@ -753,7 +755,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetExportedTypes(QCall::AssemblyHandle
if (IsTdPublic(dwFlags))
{
- TypeHandle typeHnd = ClassLoader::LoadTypeDefThrowing(pAsm->GetModule(), mdTD,
+ TypeHandle typeHnd = ClassLoader::LoadTypeDefThrowing(pAsm->GetManifestModule(), mdTD,
ClassLoader::ThrowIfNotFound,
ClassLoader::PermitUninstDefOrRef);
types.Append(typeHnd);
@@ -801,7 +803,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetExportedTypes(QCall::AssemblyHandle
IsTdPublic(dwFlags))
{
NameHandle typeName(pszNameSpace, pszClassName);
- typeName.SetTypeToken(pAsm->GetModule(), mdCT);
+ typeName.SetTypeToken(pAsm->GetManifestModule(), mdCT);
TypeHandle typeHnd = pAsm->GetLoader()->LoadTypeHandleThrowIfFailed(&typeName);
types.Append(typeHnd);
@@ -845,7 +847,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetForwardedTypes(QCall::AssemblyHandle
Assembly * pAsm = pAssembly->GetAssembly();
- IMDInternalImport *pImport = pAsm->GetMDImport();
+ IMDInternalImport *pImport = pAsm->GetManifestImport();
// enumerate the ExportedTypes table
{
@@ -871,7 +873,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetForwardedTypes(QCall::AssemblyHandle
if ((TypeFromToken(mdImpl) == mdtAssemblyRef) && (mdImpl != mdAssemblyRefNil))
{
NameHandle typeName(pszNameSpace, pszClassName);
- typeName.SetTypeToken(pAsm->GetModule(), mdCT);
+ typeName.SetTypeToken(pAsm->GetManifestModule(), mdCT);
TypeHandle typeHnd = pAsm->GetLoader()->LoadTypeHandleThrowIfFailed(&typeName);
types.Append(typeHnd);
@@ -977,7 +979,7 @@ FCIMPL1(Object*, AssemblyNative::GetReferencedAssemblies, AssemblyBaseObject * p
HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
- IMDInternalImport *pImport = pAssembly->GetAssembly()->GetMDImport();
+ IMDInternalImport *pImport = pAssembly->GetAssembly()->GetManifestImport();
MethodTable* pAsmNameClass = CoreLibBinder::GetClass(CLASS__ASSEMBLY_NAME);
@@ -1104,7 +1106,7 @@ FCIMPL1(ReflectModuleBaseObject *, AssemblyNative::GetInMemoryAssemblyModule, As
DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
- FC_RETURN_MODULE_OBJECT(pAssembly->GetModule(), refAssembly);
+ FC_RETURN_MODULE_OBJECT(pAssembly->GetCurrentModule(), refAssembly);
}
FCIMPLEND
@@ -1356,7 +1358,7 @@ extern "C" void QCALLTYPE AssemblyNative_ApplyUpdate(
{
COMPlusThrow(kNotSupportedException, W("NotSupported_DebuggerAttached"));
}
- Module* pModule = assembly->GetModule();
+ Module* pModule = assembly->GetDomainAssembly()->GetModule();
if (!pModule->IsEditAndContinueEnabled())
{
COMPlusThrow(kInvalidOperationException, W("InvalidOperation_AssemblyNotEditable"));
diff --git a/src/coreclr/vm/assemblyspec.cpp b/src/coreclr/vm/assemblyspec.cpp
index cce0b240105d3..dfbee7152df19 100644
--- a/src/coreclr/vm/assemblyspec.cpp
+++ b/src/coreclr/vm/assemblyspec.cpp
@@ -250,7 +250,8 @@ void AssemblySpec::InitializeSpec(PEAssembly * pFile)
// This uses thread storage to allocate space. Please use Checkpoint and release it.
-void AssemblySpec::InitializeSpec(StackingAllocator* alloc, ASSEMBLYNAMEREF* pName)
+HRESULT AssemblySpec::InitializeSpec(StackingAllocator* alloc, ASSEMBLYNAMEREF* pName,
+ BOOL fParse /*=TRUE*/)
{
CONTRACTL
{
@@ -289,86 +290,107 @@ void AssemblySpec::InitializeSpec(StackingAllocator* alloc, ASSEMBLYNAMEREF* pNa
SetName(lpName);
}
- AssemblyMetaDataInternal asmInfo;
- // Flags
- DWORD dwFlags = (*pName)->GetFlags();
-
- // Version
- VERSIONREF version = (VERSIONREF) (*pName)->GetVersion();
- if(version == NULL) {
- asmInfo.usMajorVersion = (USHORT)-1;
- asmInfo.usMinorVersion = (USHORT)-1;
- asmInfo.usBuildNumber = (USHORT)-1;
- asmInfo.usRevisionNumber = (USHORT)-1;
+ if (fParse) {
+ HRESULT hr = ParseName();
+ // Sometimes Fusion flags invalid characters in the name, sometimes it doesn't
+ // depending on where the invalid characters are
+ // We want to Raise the assembly resolve event on all invalid characters
+ // but calling ParseName before checking for invalid characters gives Fusion a chance to
+ // parse the rest of the name (to get a public key token, etc.)
+ if ((hr == FUSION_E_INVALID_NAME) || (!IsValidAssemblyName())) {
+ // This is the only case where we do not throw on an error
+ // We don't want to throw so as to give the caller a chance to call RaiseAssemblyResolveEvent
+ // The only caller that cares is System.Reflection.Assembly.InternalLoad which calls us through
+ // AssemblyNameNative::Init
+ return FUSION_E_INVALID_NAME;
+ }
+ else
+ IfFailThrow(hr);
}
else {
- asmInfo.usMajorVersion = (USHORT)version->GetMajor();
- asmInfo.usMinorVersion = (USHORT)version->GetMinor();
- asmInfo.usBuildNumber = (USHORT)version->GetBuild();
- asmInfo.usRevisionNumber = (USHORT)version->GetRevision();
- }
-
- asmInfo.szLocale = 0;
-
- if ((*pName)->GetCultureInfo() != NULL)
- {
- struct _gc {
- OBJECTREF cultureinfo;
- STRINGREF pString;
- } gc;
-
- gc.cultureinfo = (*pName)->GetCultureInfo();
- gc.pString = NULL;
-
- GCPROTECT_BEGIN(gc);
+ AssemblyMetaDataInternal asmInfo;
+ // Flags
+ DWORD dwFlags = (*pName)->GetFlags();
+
+ // Version
+ VERSIONREF version = (VERSIONREF) (*pName)->GetVersion();
+ if(version == NULL) {
+ asmInfo.usMajorVersion = (USHORT)-1;
+ asmInfo.usMinorVersion = (USHORT)-1;
+ asmInfo.usBuildNumber = (USHORT)-1;
+ asmInfo.usRevisionNumber = (USHORT)-1;
+ }
+ else {
+ asmInfo.usMajorVersion = (USHORT)version->GetMajor();
+ asmInfo.usMinorVersion = (USHORT)version->GetMinor();
+ asmInfo.usBuildNumber = (USHORT)version->GetBuild();
+ asmInfo.usRevisionNumber = (USHORT)version->GetRevision();
+ }
- MethodDescCallSite getName(METHOD__CULTURE_INFO__GET_NAME, &gc.cultureinfo);
+ asmInfo.szLocale = 0;
- ARG_SLOT args[] = {
- ObjToArgSlot(gc.cultureinfo)
- };
- gc.pString = getName.Call_RetSTRINGREF(args);
- if (gc.pString != NULL) {
- WCHAR* pString;
- int iString;
- gc.pString->RefInterpretGetStringValuesDangerousForGC(&pString, &iString);
- DWORD lgth = WszWideCharToMultiByte(CP_UTF8, 0, pString, iString, NULL, 0, NULL, NULL);
- S_UINT32 lengthWillNull = S_UINT32(lgth) + S_UINT32(1);
- LPSTR lpLocale = (LPSTR) alloc->Alloc(lengthWillNull);
- if (lengthWillNull.IsOverflow())
- {
- COMPlusThrowHR(COR_E_OVERFLOW);
+ if ((*pName)->GetCultureInfo() != NULL)
+ {
+ struct _gc {
+ OBJECTREF cultureinfo;
+ STRINGREF pString;
+ } gc;
+
+ gc.cultureinfo = (*pName)->GetCultureInfo();
+ gc.pString = NULL;
+
+ GCPROTECT_BEGIN(gc);
+
+ MethodDescCallSite getName(METHOD__CULTURE_INFO__GET_NAME, &gc.cultureinfo);
+
+ ARG_SLOT args[] = {
+ ObjToArgSlot(gc.cultureinfo)
+ };
+ gc.pString = getName.Call_RetSTRINGREF(args);
+ if (gc.pString != NULL) {
+ WCHAR* pString;
+ int iString;
+ gc.pString->RefInterpretGetStringValuesDangerousForGC(&pString, &iString);
+ DWORD lgth = WszWideCharToMultiByte(CP_UTF8, 0, pString, iString, NULL, 0, NULL, NULL);
+ S_UINT32 lengthWillNull = S_UINT32(lgth) + S_UINT32(1);
+ LPSTR lpLocale = (LPSTR) alloc->Alloc(lengthWillNull);
+ if (lengthWillNull.IsOverflow())
+ {
+ COMPlusThrowHR(COR_E_OVERFLOW);
+ }
+ WszWideCharToMultiByte(CP_UTF8, 0, pString, iString,
+ lpLocale, lengthWillNull.Value(), NULL, NULL);
+ lpLocale[lgth] = '\0';
+ asmInfo.szLocale = lpLocale;
}
- WszWideCharToMultiByte(CP_UTF8, 0, pString, iString,
- lpLocale, lengthWillNull.Value(), NULL, NULL);
- lpLocale[lgth] = '\0';
- asmInfo.szLocale = lpLocale;
+ GCPROTECT_END();
}
- GCPROTECT_END();
- }
-
- // Strong name
- DWORD cbPublicKeyOrToken=0;
- BYTE* pbPublicKeyOrToken=NULL;
- // Note that we prefer to take a public key token if present,
- // even if flags indicate a full public key
- if ((*pName)->GetPublicKeyToken() != NULL) {
- dwFlags &= ~afPublicKey;
- PBYTE pArray = NULL;
- pArray = (*pName)->GetPublicKeyToken()->GetDirectPointerToNonObjectElements();
- cbPublicKeyOrToken = (*pName)->GetPublicKeyToken()->GetNumComponents();
- pbPublicKeyOrToken = pArray;
- }
- else if ((*pName)->GetPublicKey() != NULL) {
- dwFlags |= afPublicKey;
- PBYTE pArray = NULL;
- pArray = (*pName)->GetPublicKey()->GetDirectPointerToNonObjectElements();
- cbPublicKeyOrToken = (*pName)->GetPublicKey()->GetNumComponents();
- pbPublicKeyOrToken = pArray;
- }
- BaseAssemblySpec::Init(GetName(),&asmInfo,pbPublicKeyOrToken,cbPublicKeyOrToken,dwFlags);
+
+ // Strong name
+ DWORD cbPublicKeyOrToken=0;
+ BYTE* pbPublicKeyOrToken=NULL;
+ // Note that we prefer to take a public key token if present,
+ // even if flags indicate a full public key
+ if ((*pName)->GetPublicKeyToken() != NULL) {
+ dwFlags &= ~afPublicKey;
+ PBYTE pArray = NULL;
+ pArray = (*pName)->GetPublicKeyToken()->GetDirectPointerToNonObjectElements();
+ cbPublicKeyOrToken = (*pName)->GetPublicKeyToken()->GetNumComponents();
+ pbPublicKeyOrToken = pArray;
+ }
+ else if ((*pName)->GetPublicKey() != NULL) {
+ dwFlags |= afPublicKey;
+ PBYTE pArray = NULL;
+ pArray = (*pName)->GetPublicKey()->GetDirectPointerToNonObjectElements();
+ cbPublicKeyOrToken = (*pName)->GetPublicKey()->GetNumComponents();
+ pbPublicKeyOrToken = pArray;
+ }
+ BaseAssemblySpec::Init(GetName(),&asmInfo,pbPublicKeyOrToken,cbPublicKeyOrToken,dwFlags);
+ }
CloneFieldsToStackingAllocator(alloc);
+
+ return S_OK;
}
void AssemblySpec::AssemblyNameInit(ASSEMBLYNAMEREF* pAsmName, PEImage* pImageInfo)
@@ -734,7 +756,7 @@ DomainAssembly *AssemblySpec::LoadDomainAssembly(FileLoadLevel targetLevel,
BinderTracing::AssemblyBindOperation bindOperation(this);
bindOperation.SetResult(pAssembly->GetPEAssembly(), true /*cached*/);
- pDomain->LoadDomainAssembly(pAssembly, targetLevel);
+ pDomain->LoadDomainFile(pAssembly, targetLevel);
RETURN pAssembly;
}
diff --git a/src/coreclr/vm/assemblyspec.hpp b/src/coreclr/vm/assemblyspec.hpp
index 8d2bd8045593d..5d09b5b75a664 100644
--- a/src/coreclr/vm/assemblyspec.hpp
+++ b/src/coreclr/vm/assemblyspec.hpp
@@ -16,7 +16,7 @@
#define _ASSEMBLYSPEC_H
#include "hash.h"
#include "assemblyspecbase.h"
-#include "domainassembly.h"
+#include "domainfile.h"
#include "holder.h"
class AppDomain;
@@ -103,7 +103,9 @@ class AssemblySpec : public BaseAssemblySpec
void InitializeSpec(PEAssembly* pPEAssembly);
- void InitializeSpec(StackingAllocator* alloc, ASSEMBLYNAMEREF* pName);
+ HRESULT InitializeSpec(StackingAllocator* alloc,
+ ASSEMBLYNAMEREF* pName,
+ BOOL fParse = TRUE);
void AssemblyNameInit(ASSEMBLYNAMEREF* pName, PEImage* pImageInfo); //[in,out], [in]
diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp
index c25b7aa19cc9d..72a2e1152210b 100644
--- a/src/coreclr/vm/ceeload.cpp
+++ b/src/coreclr/vm/ceeload.cpp
@@ -443,6 +443,7 @@ void Module::SetNativeMetadataAssemblyRefInCache(DWORD rid, PTR_Assembly pAssemb
//
// szName is only used by dynamic modules, see ReflectionModule::Initialize
//
+//
void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName)
{
CONTRACTL
@@ -463,6 +464,14 @@ void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName)
m_DictionaryCrst.Init(CrstDomainLocalBlock);
AllocateMaps();
+
+ if (IsSystem() ||
+ (strcmp(m_pSimpleName, "System") == 0) ||
+ (strcmp(m_pSimpleName, "System.Core") == 0))
+ {
+ FastInterlockOr(&m_dwPersistedFlags, LOW_LEVEL_SYSTEM_ASSEMBLY_BY_NAME);
+ }
+
m_dwTransientFlags &= ~((DWORD)CLASSES_FREED); // Set flag indicating LookupMaps are now in a consistent and destructable state
#ifdef FEATURE_COLLECTIBLE_TYPES
@@ -1032,7 +1041,7 @@ BOOL Module::IsEditAndContinueCapable(Assembly *pAssembly, PEAssembly *pPEAssemb
BOOL Module::IsManifest()
{
WRAPPER_NO_CONTRACT;
- return dac_cast(GetAssembly()->GetModule()) ==
+ return dac_cast(GetAssembly()->GetManifestModule()) ==
dac_cast(this);
}
@@ -1040,7 +1049,14 @@ DomainAssembly* Module::GetDomainAssembly()
{
LIMITED_METHOD_DAC_CONTRACT;
- return dac_cast(m_ModuleID->GetDomainAssembly());
+ return dac_cast(m_ModuleID->GetDomainFile());
+}
+
+DomainFile *Module::GetDomainFile()
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ return dac_cast(m_ModuleID->GetDomainFile());
}
#ifndef DACCESS_COMPILE
@@ -1613,7 +1629,9 @@ BOOL Module::IsNoStringInterning()
HRESULT hr;
- IMDInternalImport *mdImport = GetAssembly()->GetMDImport();
+ // This flag applies to assembly, but it is stored on module so it can be cached in ngen image
+ // Thus, we should ever need it for manifest module only.
+ IMDInternalImport *mdImport = GetAssembly()->GetManifestImport();
_ASSERTE(mdImport);
mdToken token;
@@ -1718,7 +1736,9 @@ BOOL Module::IsRuntimeWrapExceptions()
HRESULT hr;
BOOL fRuntimeWrapExceptions = FALSE;
- IMDInternalImport *mdImport = GetAssembly()->GetMDImport();
+ // This flag applies to assembly, but it is stored on module so it can be cached in ngen image
+ // Thus, we should ever need it for manifest module only.
+ IMDInternalImport *mdImport = GetAssembly()->GetManifestImport();
mdToken token;
IfFailGo(mdImport->GetAssemblyFromScope(&token));
@@ -1755,42 +1775,6 @@ BOOL Module::IsRuntimeWrapExceptions()
return !!(m_dwPersistedFlags & WRAP_EXCEPTIONS);
}
-BOOL Module::IsRuntimeMarshallingEnabled()
-{
- CONTRACTL
- {
- THROWS;
- if (IsRuntimeMarshallingEnabledCached()) GC_NOTRIGGER; else GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END
-
- if (IsRuntimeMarshallingEnabledCached())
- {
- return !!(m_dwPersistedFlags & RUNTIME_MARSHALLING_ENABLED);
- }
-
- HRESULT hr;
-
- IMDInternalImport *mdImport = GetAssembly()->GetMDImport();
-
- mdToken token;
- if (SUCCEEDED(hr = mdImport->GetAssemblyFromScope(&token)))
- {
- const BYTE *pVal;
- ULONG cbVal;
-
- hr = mdImport->GetCustomAttributeByName(token,
- g_DisableRuntimeMarshallingAttribute,
- (const void**)&pVal, &cbVal);
- }
-
- FastInterlockOr(&m_dwPersistedFlags, RUNTIME_MARSHALLING_ENABLED_IS_CACHED |
- (hr == S_OK ? 0 : RUNTIME_MARSHALLING_ENABLED));
-
- return hr != S_OK;
-}
-
BOOL Module::IsPreV4Assembly()
{
CONTRACTL
@@ -1802,7 +1786,7 @@ BOOL Module::IsPreV4Assembly()
if (!(m_dwPersistedFlags & COMPUTED_IS_PRE_V4_ASSEMBLY))
{
- IMDInternalImport *pImport = GetAssembly()->GetMDImport();
+ IMDInternalImport *pImport = GetAssembly()->GetManifestImport();
_ASSERTE(pImport);
BOOL fIsPreV4Assembly = FALSE;
@@ -1984,13 +1968,13 @@ void Module::AllocateStatics(AllocMemTracker *pamTracker)
BuildStaticsOffsets(pamTracker);
}
-void Module::SetDomainAssembly(DomainAssembly *pDomainAssembly)
+void Module::SetDomainFile(DomainFile *pDomainFile)
{
CONTRACTL
{
INSTANCE_CHECK;
- PRECONDITION(CheckPointer(pDomainAssembly));
- PRECONDITION(IsManifest());
+ PRECONDITION(CheckPointer(pDomainFile));
+ PRECONDITION(IsManifest() == pDomainFile->IsAssembly());
THROWS;
GC_TRIGGERS;
MODE_ANY;
@@ -2010,7 +1994,7 @@ void Module::SetDomainAssembly(DomainAssembly *pDomainAssembly)
}
else
{
- pLoaderAllocator = pDomainAssembly->GetAppDomain()->GetLoaderAllocator();
+ pLoaderAllocator = pDomainFile->GetAppDomain()->GetLoaderAllocator();
}
SIZE_T size = GetDomainLocalModuleSize();
@@ -2050,7 +2034,7 @@ void Module::SetDomainAssembly(DomainAssembly *pDomainAssembly)
m_ModuleID = pModuleData;
}
- m_ModuleID->SetDomainAssembly(pDomainAssembly);
+ m_ModuleID->SetDomainFile(pDomainFile);
// Allocate static handles now.
// NOTE: Bootstrapping issue with CoreLib - we will manually allocate later
@@ -2058,7 +2042,7 @@ void Module::SetDomainAssembly(DomainAssembly *pDomainAssembly)
// as it is currently initialized through the DomainLocalModule::PopulateClass in MethodTable::CheckRunClassInitThrowing
// (If we don't do this, it would allocate here unused regular static handles that will be overridden later)
if (g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT] != NULL && !GetAssembly()->IsCollectible())
- AllocateRegularStaticHandles(pDomainAssembly->GetAppDomain());
+ AllocateRegularStaticHandles(pDomainFile->GetAppDomain());
}
OBJECTREF Module::GetExposedObject()
@@ -2073,7 +2057,7 @@ OBJECTREF Module::GetExposedObject()
}
CONTRACT_END;
- RETURN GetDomainAssembly()->GetExposedModuleObject();
+ RETURN GetDomainFile()->GetExposedModuleObject();
}
//
@@ -3300,7 +3284,7 @@ Module::GetAssemblyIfLoaded(
}
if (pDomainAssembly && pDomainAssembly->IsLoaded())
- pAssembly = pDomainAssembly->GetAssembly();
+ pAssembly = pDomainAssembly->GetCurrentAssembly(); // Do not use GetAssembly - that may force the completion of a load
// Only store in the rid map if working with the current AppDomain.
if (fCanUseRidMap && pAssembly)
@@ -3384,7 +3368,7 @@ DomainAssembly * Module::LoadAssembly(mdAssemblyRef kAssemblyRef)
if (pAssembly != NULL)
{
pDomainAssembly = pAssembly->GetDomainAssembly();
- ::GetAppDomain()->LoadDomainAssembly(pDomainAssembly, FILE_LOADED);
+ ::GetAppDomain()->LoadDomainFile(pDomainAssembly, FILE_LOADED);
RETURN pDomainAssembly;
}
@@ -3411,9 +3395,9 @@ DomainAssembly * Module::LoadAssembly(mdAssemblyRef kAssemblyRef)
!pDomainAssembly->IsLoaded() || // GetAssemblyIfLoaded will not find not-yet-loaded assemblies
GetAssemblyIfLoaded(kAssemblyRef, NULL, FALSE, pDomainAssembly->GetPEAssembly()->GetHostAssembly()->GetBinder()) != NULL); // GetAssemblyIfLoaded should find all remaining cases
- if (pDomainAssembly->GetAssembly() != NULL)
+ if (pDomainAssembly->GetCurrentAssembly() != NULL)
{
- StoreAssemblyRef(kAssemblyRef, pDomainAssembly->GetAssembly());
+ StoreAssemblyRef(kAssemblyRef, pDomainAssembly->GetCurrentAssembly());
}
}
@@ -3454,7 +3438,7 @@ Module *Module::GetModuleIfLoaded(mdFile kFile)
if (kFile == mdTokenNil)
RETURN NULL;
- RETURN GetAssembly()->GetModule()->GetModuleIfLoaded(kFile);
+ RETURN GetAssembly()->GetManifestModule()->GetModuleIfLoaded(kFile);
}
Module *pModule = LookupFile(kFile);
@@ -3463,7 +3447,7 @@ Module *Module::GetModuleIfLoaded(mdFile kFile)
if (IsManifest())
{
if (kFile == mdFileNil)
- pModule = GetAssembly()->GetModule();
+ pModule = GetAssembly()->GetManifestModule();
}
else
{
@@ -3477,7 +3461,7 @@ Module *Module::GetModuleIfLoaded(mdFile kFile)
{
if (kMatch == mdFileNil)
{
- pModule = pAssembly->GetModule();
+ pModule = pAssembly->GetManifestModule();
}
else
{
@@ -3485,7 +3469,7 @@ Module *Module::GetModuleIfLoaded(mdFile kFile)
}
}
else
- pModule = pAssembly->GetModule()->LookupFile(kMatch);
+ pModule = pAssembly->GetManifestModule()->LookupFile(kMatch);
}
#ifndef DACCESS_COMPILE
@@ -3501,9 +3485,9 @@ Module *Module::GetModuleIfLoaded(mdFile kFile)
#ifndef DACCESS_COMPILE
-DomainAssembly *Module::LoadModule(AppDomain *pDomain, mdFile kFile)
+DomainFile *Module::LoadModule(AppDomain *pDomain, mdFile kFile)
{
- CONTRACT(DomainAssembly *)
+ CONTRACT(DomainFile *)
{
INSTANCE_CHECK;
THROWS;
@@ -3523,7 +3507,7 @@ DomainAssembly *Module::LoadModule(AppDomain *pDomain, mdFile kFile)
else
{
// This is mdtFile
- IfFailThrow(GetAssembly()->GetMDImport()->GetFileProps(kFile,
+ IfFailThrow(GetAssembly()->GetManifestImport()->GetFileProps(kFile,
&psModuleName,
NULL,
NULL,
@@ -3562,7 +3546,7 @@ PTR_Module Module::LookupModule(mdToken kFile)
if (kFileLocal == mdTokenNil)
COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- RETURN GetAssembly()->GetModule()->LookupModule(kFileLocal);
+ RETURN GetAssembly()->GetManifestModule()->LookupModule(kFileLocal);
}
PTR_Module pModule = LookupFile(kFile);
@@ -3573,12 +3557,12 @@ PTR_Module Module::LookupModule(mdToken kFile)
mdFile kMatch = pAssembly->GetManifestFileToken(GetMDImport(), kFile);
if (IsNilToken(kMatch)) {
if (kMatch == mdFileNil)
- pModule = pAssembly->GetModule();
+ pModule = pAssembly->GetManifestModule();
else
COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
}
else
- pModule = pAssembly->GetModule()->LookupFile(kMatch);
+ pModule = pAssembly->GetManifestModule()->LookupFile(kMatch);
}
RETURN pModule;
}
@@ -4047,7 +4031,7 @@ void Module::UpdateDynamicMetadataIfNeeded()
#endif // DEBUGGING_SUPPORTED
-BOOL Module::NotifyDebuggerLoad(AppDomain *pDomain, DomainAssembly * pDomainAssembly, int flags, BOOL attaching)
+BOOL Module::NotifyDebuggerLoad(AppDomain *pDomain, DomainFile * pDomainFile, int flags, BOOL attaching)
{
WRAPPER_NO_CONTRACT;
@@ -4058,7 +4042,7 @@ BOOL Module::NotifyDebuggerLoad(AppDomain *pDomain, DomainAssembly * pDomainAsse
// Always capture metadata, even if no debugger is attached. If a debugger later attaches, it will use
// this data.
{
- Module * pModule = pDomainAssembly->GetModule();
+ Module * pModule = pDomainFile->GetModule();
pModule->UpdateDynamicMetadataIfNeeded();
}
@@ -4079,7 +4063,7 @@ BOOL Module::NotifyDebuggerLoad(AppDomain *pDomain, DomainAssembly * pDomainAsse
m_pPEAssembly->GetPath().GetCount(),
GetAssembly(),
pDomain,
- pDomainAssembly,
+ pDomainFile,
attaching);
result = TRUE;
@@ -4575,7 +4559,7 @@ Module *Module::GetModuleFromIndex(DWORD ix)
Assembly *pAssembly = this->LookupAssemblyRef(mdAssemblyRefToken);
if (pAssembly)
{
- RETURN pAssembly->GetModule();
+ RETURN pAssembly->GetManifestModule();
}
else
{
@@ -6458,7 +6442,11 @@ void Module::WriteAllModuleProfileData(bool cleanup)
while (assemblyIterator.Next(pDomainAssembly.This()))
{
- pDomainAssembly->GetModule()->WriteMethodProfileDataLogFile(cleanup);
+ DomainModuleIterator i = pDomainAssembly->IterateModules(kModIterIncludeLoaded);
+ while (i.Next())
+ {
+ /*hr=*/i.GetModule()->WriteMethodProfileDataLogFile(cleanup);
+ }
}
}
}
@@ -7449,7 +7437,7 @@ VOID Module::EnsureActive()
MODE_ANY;
}
CONTRACTL_END;
- GetDomainAssembly()->EnsureActive();
+ GetDomainFile()->EnsureActive();
}
#endif // DACCESS_COMPILE
@@ -7468,13 +7456,13 @@ VOID Module::EnsureAllocated()
}
CONTRACTL_END;
- GetDomainAssembly()->EnsureAllocated();
+ GetDomainFile()->EnsureAllocated();
}
VOID Module::EnsureLibraryLoaded()
{
STANDARD_VM_CONTRACT;
- GetDomainAssembly()->EnsureLibraryLoaded();
+ GetDomainFile()->EnsureLibraryLoaded();
}
#endif // !DACCESS_COMPILE
@@ -7489,10 +7477,10 @@ CHECK Module::CheckActivated()
CONTRACTL_END;
#ifndef DACCESS_COMPILE
- DomainAssembly *pDomainAssembly = GetDomainAssembly();
- CHECK(pDomainAssembly != NULL);
- PREFIX_ASSUME(pDomainAssembly != NULL);
- CHECK(pDomainAssembly->CheckActivated());
+ DomainFile *pDomainFile = GetDomainFile();
+ CHECK(pDomainFile != NULL);
+ PREFIX_ASSUME(pDomainFile != NULL);
+ CHECK(pDomainFile->CheckActivated());
#endif
CHECK_OK;
}
diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h
index d9cd6742cb6c0..e7dd5629a2c84 100644
--- a/src/coreclr/vm/ceeload.h
+++ b/src/coreclr/vm/ceeload.h
@@ -832,12 +832,8 @@ class Module
//If m_MethodDefToPropertyInfoMap has been generated
COMPUTED_METHODDEF_TO_PROPERTYINFO_MAP = 0x00002000,
- // unused = 0x00004000,
-
- //If setting has been cached
- RUNTIME_MARSHALLING_ENABLED_IS_CACHED = 0x00008000,
- //If runtime marshalling is enabled for this assembly
- RUNTIME_MARSHALLING_ENABLED = 0x00010000,
+ // Low level system assembly. Used by preferred zap module computation.
+ LOW_LEVEL_SYSTEM_ASSEMBLY_BY_NAME = 0x00004000,
};
Volatile m_dwTransientFlags;
@@ -1131,9 +1127,13 @@ class Module
MethodTable *GetGlobalMethodTable();
bool NeedsGlobalMethodTable();
+ // This works for manifest modules too
+ DomainFile *GetDomainFile();
+
+ // Operates on assembly of module
DomainAssembly *GetDomainAssembly();
- void SetDomainAssembly(DomainAssembly *pDomainAssembly);
+ void SetDomainFile(DomainFile *pDomainFile);
OBJECTREF GetExposedObject();
@@ -1190,6 +1190,14 @@ class Module
LIMITED_METHOD_CONTRACT;
FastInterlockOr(&m_dwTransientFlags, MODULE_IS_TENURED);
}
+
+ // CAUTION: This should only be used as backout code if an assembly is unsuccessfully
+ // added to the shared domain assembly map.
+ VOID UnsetIsTenured()
+ {
+ LIMITED_METHOD_CONTRACT;
+ FastInterlockAnd(&m_dwTransientFlags, ~MODULE_IS_TENURED);
+ }
#endif // !DACCESS_COMPILE
@@ -1210,6 +1218,13 @@ class Module
}
#endif
+ BOOL IsLowLevelSystemAssemblyByName()
+ {
+ LIMITED_METHOD_CONTRACT;
+ // The flag is set during initialization, so we can skip the memory barrier
+ return m_dwPersistedFlags.LoadWithoutBarrier() & LOW_LEVEL_SYSTEM_ASSEMBLY_BY_NAME;
+ }
+
#ifndef DACCESS_COMPILE
VOID EnsureActive();
VOID EnsureAllocated();
@@ -1416,7 +1431,7 @@ class Module
DomainAssembly * LoadAssembly(mdAssemblyRef kAssemblyRef);
Module *GetModuleIfLoaded(mdFile kFile);
- DomainAssembly *LoadModule(AppDomain *pDomain, mdFile kFile);
+ DomainFile *LoadModule(AppDomain *pDomain, mdFile kFile);
PTR_Module LookupModule(mdToken kFile); //wrapper over GetModuleIfLoaded, takes modulerefs as well
DWORD GetAssemblyRefFlags(mdAssemblyRef tkAssemblyRef);
@@ -1699,7 +1714,7 @@ class Module
public:
// Debugger stuff
- BOOL NotifyDebuggerLoad(AppDomain *pDomain, DomainAssembly * pDomainAssembly, int level, BOOL attaching);
+ BOOL NotifyDebuggerLoad(AppDomain *pDomain, DomainFile * pDomainFile, int level, BOOL attaching);
void NotifyDebuggerUnload(AppDomain *pDomain);
void SetDebuggerInfoBits(DebuggerAssemblyControlFlags newBits);
@@ -1970,6 +1985,18 @@ class Module
return dac_cast(m_ModuleID);
}
+ SIZE_T * GetAddrModuleID()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return (SIZE_T*) &m_ModuleID;
+ }
+
+ static SIZE_T GetOffsetOfModuleID()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return offsetof(Module, m_ModuleID);
+ }
+
PTR_DomainLocalModule GetDomainLocalModule();
// LoaderHeap for storing IJW thunks
@@ -2044,18 +2071,6 @@ class Module
//-----------------------------------------------------------------------------------------
BOOL IsRuntimeWrapExceptions();
- //-----------------------------------------------------------------------------------------
- // If true, the built-in runtime-generated marshalling subsystem will be used for
- // P/Invokes, function pointer invocations, and delegates defined in this module
- //-----------------------------------------------------------------------------------------
- BOOL IsRuntimeMarshallingEnabled();
-
- BOOL IsRuntimeMarshallingEnabledCached()
- {
- LIMITED_METHOD_CONTRACT;
- return (m_dwPersistedFlags & RUNTIME_MARSHALLING_ENABLED_IS_CACHED);
- }
-
BOOL HasDefaultDllImportSearchPathsAttribute();
BOOL IsDefaultDllImportSearchPathsAttributeCached()
diff --git a/src/coreclr/vm/ceeload.inl b/src/coreclr/vm/ceeload.inl
index fee8a8f4fcc33..ca770297a4bc9 100644
--- a/src/coreclr/vm/ceeload.inl
+++ b/src/coreclr/vm/ceeload.inl
@@ -297,25 +297,25 @@ inline Assembly *Module::LookupAssemblyRef(mdAssemblyRef token)
inline void Module::ForceStoreAssemblyRef(mdAssemblyRef token, Assembly *value)
{
WRAPPER_NO_CONTRACT; // THROWS/GC_NOTRIGGER/INJECT_FAULT()/MODE_ANY
- _ASSERTE(value->GetModule());
+ _ASSERTE(value->GetManifestModule());
_ASSERTE(TypeFromToken(token) == mdtAssemblyRef);
- m_ManifestModuleReferencesMap.AddElement(this, RidFromToken(token), value->GetModule());
+ m_ManifestModuleReferencesMap.AddElement(this, RidFromToken(token), value->GetManifestModule());
}
inline void Module::StoreAssemblyRef(mdAssemblyRef token, Assembly *value)
{
WRAPPER_NO_CONTRACT;
- _ASSERTE(value->GetModule());
+ _ASSERTE(value->GetManifestModule());
_ASSERTE(TypeFromToken(token) == mdtAssemblyRef);
- m_ManifestModuleReferencesMap.TrySetElement(RidFromToken(token), value->GetModule());
+ m_ManifestModuleReferencesMap.TrySetElement(RidFromToken(token), value->GetManifestModule());
}
inline mdAssemblyRef Module::FindAssemblyRef(Assembly *targetAssembly)
{
WRAPPER_NO_CONTRACT;
- return m_ManifestModuleReferencesMap.Find(targetAssembly->GetModule()) | mdtAssemblyRef;
+ return m_ManifestModuleReferencesMap.Find(targetAssembly->GetManifestModule()) | mdtAssemblyRef;
}
#endif //DACCESS_COMPILE
diff --git a/src/coreclr/vm/class.h b/src/coreclr/vm/class.h
index 9aa6c6994e726..0ccacd36a9f91 100644
--- a/src/coreclr/vm/class.h
+++ b/src/coreclr/vm/class.h
@@ -363,21 +363,19 @@ class EEClassLayoutInfo
private:
enum {
// TRUE if the GC layout of the class is bit-for-bit identical
- // to its unmanaged counterpart with the runtime marshalling system
- // (i.e. no internal reference fields, no ansi-unicode char conversions required, etc.)
- // Used to optimize marshaling.
- e_BLITTABLE = 0x01,
- // Is this type also sequential in managed memory?
- e_MANAGED_SEQUENTIAL = 0x02,
+ // to its unmanaged counterpart (i.e. no internal reference fields,
+ // no ansi-unicode char conversions required, etc.) Used to
+ // optimize marshaling.
+ e_BLITTABLE = 0x01,
+ // Post V1.0 addition: Is this type also sequential in managed memory?
+ e_MANAGED_SEQUENTIAL = 0x02,
// When a sequential/explicit type has no fields, it is conceptually
// zero-sized, but actually is 1 byte in length. This holds onto this
// fact and allows us to revert the 1 byte of padding when another
// explicit type inherits from this type.
- e_ZERO_SIZED = 0x04,
+ e_ZERO_SIZED = 0x04,
// The size of the struct is explicitly specified in the meta-data.
- e_HAS_EXPLICIT_SIZE = 0x08,
- // The type recursively has a field that is LayoutKind.Auto and not an enum.
- e_HAS_AUTO_LAYOUT_FIELD_IN_LAYOUT = 0x10
+ e_HAS_EXPLICIT_SIZE = 0x08
};
BYTE m_bFlags;
@@ -421,12 +419,6 @@ class EEClassLayoutInfo
return (m_bFlags & e_HAS_EXPLICIT_SIZE) == e_HAS_EXPLICIT_SIZE;
}
- BOOL HasAutoLayoutField() const
- {
- LIMITED_METHOD_CONTRACT;
- return (m_bFlags & e_HAS_AUTO_LAYOUT_FIELD_IN_LAYOUT) == e_HAS_AUTO_LAYOUT_FIELD_IN_LAYOUT;
- }
-
BYTE GetPackingSize() const
{
LIMITED_METHOD_CONTRACT;
@@ -461,13 +453,6 @@ class EEClassLayoutInfo
m_bFlags = hasExplicitSize ? (m_bFlags | e_HAS_EXPLICIT_SIZE)
: (m_bFlags & ~e_HAS_EXPLICIT_SIZE);
}
-
- void SetHasAutoLayoutField(BOOL hasAutoLayoutField)
- {
- LIMITED_METHOD_CONTRACT;
- m_bFlags = hasAutoLayoutField ? (m_bFlags | e_HAS_AUTO_LAYOUT_FIELD_IN_LAYOUT)
- : (m_bFlags & ~e_HAS_AUTO_LAYOUT_FIELD_IN_LAYOUT);
- }
};
//
@@ -1410,8 +1395,6 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW!
BOOL HasExplicitSize();
- BOOL IsAutoLayoutOrHasAutoLayoutField();
-
static void GetBestFitMapping(MethodTable * pMT, BOOL *pfBestFitMapping, BOOL *pfThrowOnUnmappableChar);
/*
@@ -2099,13 +2082,6 @@ inline BOOL EEClass::HasExplicitSize()
return HasLayout() && GetLayoutInfo()->HasExplicitSize();
}
-inline BOOL EEClass::IsAutoLayoutOrHasAutoLayoutField()
-{
- LIMITED_METHOD_CONTRACT;
- // If this type is not auto
- return !HasLayout() || GetLayoutInfo()->HasAutoLayoutField();
-}
-
//==========================================================================
// These routines manage the prestub (a bootstrapping stub that all
// FunctionDesc's are initialized with.)
diff --git a/src/coreclr/vm/classhash.cpp b/src/coreclr/vm/classhash.cpp
index 7320f7bae72a7..28c636f7c9aad 100644
--- a/src/coreclr/vm/classhash.cpp
+++ b/src/coreclr/vm/classhash.cpp
@@ -267,7 +267,7 @@ VOID EEClassHashTable::ConstructKeyFromData(PTR_EEClassHashEntry pEntry, // IN
mdToken mdtUncompressed = UncompressModuleAndClassDef(Data);
if (TypeFromToken(mdtUncompressed) == mdtExportedType)
{
- IfFailThrow(GetModule()->GetClassLoader()->GetAssembly()->GetMDImport()->GetExportedTypeProps(
+ IfFailThrow(GetModule()->GetClassLoader()->GetAssembly()->GetManifestImport()->GetExportedTypeProps(
mdtUncompressed,
(LPCSTR *)&pszNameSpace,
(LPCSTR *)&pszName,
diff --git a/src/coreclr/vm/classlayoutinfo.cpp b/src/coreclr/vm/classlayoutinfo.cpp
index b95c6d4108ed4..90315764cfbc5 100644
--- a/src/coreclr/vm/classlayoutinfo.cpp
+++ b/src/coreclr/vm/classlayoutinfo.cpp
@@ -226,18 +226,23 @@ namespace
*pLargestAlignmentRequirementOut = LargestAlignmentRequirement;
}
- RawFieldPlacementInfo GetFieldPlacementInfo(CorElementType corElemType, TypeHandle pNestedType)
+ //=======================================================================
+ // This function returns TRUE if the provided corElemType disqualifies
+ // the structure from being a managed-sequential structure.
+ // The fsig parameter is used when the corElemType doesn't contain enough information
+ // to successfully determine if this field disqualifies the type from being
+ // managed-sequential.
+ // This function also fills in the pManagedPlacementInfo structure for this field.
+ //=======================================================================
+ BOOL CheckIfDisqualifiedFromManagedSequential(CorElementType corElemType, MetaSig& fsig, RawFieldPlacementInfo* pManagedPlacementInfo)
{
- RawFieldPlacementInfo placementInfo;
- // Initialize offset to a dummy value as we set it to the correct value later.
- placementInfo.m_offset = (UINT32)-1;
- placementInfo.m_size = TARGET_POINTER_SIZE;
- placementInfo.m_alignment = TARGET_POINTER_SIZE;
+ pManagedPlacementInfo->m_alignment = TARGET_POINTER_SIZE;
+ pManagedPlacementInfo->m_size = TARGET_POINTER_SIZE;
// This type may qualify for ManagedSequential. Collect managed size and alignment info.
if (CorTypeInfo::IsPrimitiveType(corElemType))
{
// Safe cast - no primitive type is larger than 4gb!
- placementInfo.m_size = ((UINT32)CorTypeInfo::Size(corElemType));
+ pManagedPlacementInfo->m_size = ((UINT32)CorTypeInfo::Size(corElemType));
#if defined(TARGET_X86) && defined(UNIX_X86_ABI)
switch (corElemType)
{
@@ -246,87 +251,67 @@ namespace
case ELEMENT_TYPE_U8:
case ELEMENT_TYPE_R8:
{
- placementInfo.m_alignment = 4;
+ pManagedPlacementInfo->m_alignment = 4;
break;
}
default:
{
- placementInfo.m_alignment = placementInfo.m_size;
+ pManagedPlacementInfo->m_alignment = pManagedPlacementInfo->m_size;
break;
}
}
#else // TARGET_X86 && UNIX_X86_ABI
- placementInfo.m_alignment = placementInfo.m_size;
+ pManagedPlacementInfo->m_alignment = pManagedPlacementInfo->m_size;
#endif
+ return FALSE;
}
else if (corElemType == ELEMENT_TYPE_PTR || corElemType == ELEMENT_TYPE_FNPTR)
{
- placementInfo.m_size = TARGET_POINTER_SIZE;
- placementInfo.m_alignment = TARGET_POINTER_SIZE;
+ pManagedPlacementInfo->m_size = TARGET_POINTER_SIZE;
+ pManagedPlacementInfo->m_alignment = TARGET_POINTER_SIZE;
+
+ return FALSE;
}
else if (corElemType == ELEMENT_TYPE_VALUETYPE)
{
- _ASSERTE(!pNestedType.IsNull());
+ TypeHandle pNestedType = fsig.GetLastTypeHandleThrowing(ClassLoader::LoadTypes,
+ CLASS_LOAD_APPROXPARENTS,
+ TRUE);
- placementInfo.m_size = (pNestedType.GetMethodTable()->GetNumInstanceFieldBytes());
+ pManagedPlacementInfo->m_size = (pNestedType.GetMethodTable()->GetNumInstanceFieldBytes());
#if !defined(TARGET_64BIT) && (DATA_ALIGNMENT > 4)
- if (placementInfo.m_size >= DATA_ALIGNMENT)
+ if (pManagedPlacementInfo->m_size >= DATA_ALIGNMENT)
{
- placementInfo.m_alignment = DATA_ALIGNMENT;
+ pManagedPlacementInfo->m_alignment = DATA_ALIGNMENT;
}
else
#elif defined(FEATURE_64BIT_ALIGNMENT)
if (pNestedType.RequiresAlign8())
{
- placementInfo.m_alignment = 8;
+ pManagedPlacementInfo->m_alignment = 8;
}
else
#endif // FEATURE_64BIT_ALIGNMENT
if (pNestedType.GetMethodTable()->ContainsPointers())
{
// this field type has GC pointers in it, which need to be pointer-size aligned
- placementInfo.m_alignment = TARGET_POINTER_SIZE;
+ // so do this if it has not been done already
+ pManagedPlacementInfo->m_alignment = TARGET_POINTER_SIZE;
}
else
{
- placementInfo.m_alignment = pNestedType.GetMethodTable()->GetFieldAlignmentRequirement();
+ pManagedPlacementInfo->m_alignment = pNestedType.GetMethodTable()->GetFieldAlignmentRequirement();
}
+ // Types that have GC Pointer fields (objects or byrefs) are disqualified from ManagedSequential layout.
+ return pNestedType.GetMethodTable()->ContainsPointers() != FALSE;
}
// No other type permitted for ManagedSequential.
- return placementInfo;
- }
-
- BOOL TypeHasGCPointers(CorElementType corElemType, TypeHandle pNestedType)
- {
- if (CorTypeInfo::IsPrimitiveType(corElemType) || corElemType == ELEMENT_TYPE_PTR || corElemType == ELEMENT_TYPE_FNPTR)
- {
- return FALSE;
- }
- if (corElemType == ELEMENT_TYPE_VALUETYPE)
- {
- _ASSERTE(!pNestedType.IsNull());
- return pNestedType.GetMethodTable()->ContainsPointers() != FALSE;
- }
return TRUE;
}
- BOOL TypeHasAutoLayoutField(CorElementType corElemType, TypeHandle pNestedType)
- {
- if (CorTypeInfo::IsPrimitiveType(corElemType) || corElemType == ELEMENT_TYPE_PTR || corElemType == ELEMENT_TYPE_FNPTR)
- {
- return FALSE;
- }
- if (corElemType == ELEMENT_TYPE_VALUETYPE)
- {
- _ASSERTE(!pNestedType.IsNull());
- return pNestedType.IsEnum() || pNestedType.GetMethodTable()->IsAutoLayoutOrHasAutoLayoutField();
- }
- return FALSE;
- }
-
#ifdef UNIX_AMD64_ABI
void SystemVAmd64CheckForPassNativeStructInRegister(MethodTable* pMT, EEClassNativeLayoutInfo* pNativeLayoutInfo)
{
@@ -452,7 +437,6 @@ namespace
ParseNativeTypeFlags nativeTypeFlags,
const SigTypeContext* pTypeContext,
BOOL* fDisqualifyFromManagedSequential,
- BOOL* fHasAutoLayoutField,
LayoutRawFieldInfo* pFieldInfoArrayOut,
BOOL* pIsBlittableOut,
ULONG* cInstanceFields
@@ -521,16 +505,7 @@ namespace
#endif
MetaSig fsig(pCOMSignature, cbCOMSignature, pModule, pTypeContext, MetaSig::sigField);
CorElementType corElemType = fsig.NextArgNormalized();
- TypeHandle typeHandleMaybe;
- if (corElemType == ELEMENT_TYPE_VALUETYPE) // Only look up the next element in the signature if it is a value type to avoid causing recursive type loads in valid scenarios.
- {
- typeHandleMaybe = fsig.GetLastTypeHandleThrowing(ClassLoader::LoadTypes,
- CLASS_LOAD_APPROXPARENTS,
- TRUE);
- }
- pFieldInfoArrayOut->m_placement = GetFieldPlacementInfo(corElemType, typeHandleMaybe);
- *fDisqualifyFromManagedSequential |= TypeHasGCPointers(corElemType, typeHandleMaybe);
- *fHasAutoLayoutField |= TypeHasAutoLayoutField(corElemType, typeHandleMaybe);
+ *fDisqualifyFromManagedSequential |= CheckIfDisqualifiedFromManagedSequential(corElemType, fsig, &pFieldInfoArrayOut->m_placement);
if (!IsFieldBlittable(pModule, fd, fsig.GetArgProps(), pTypeContext, nativeTypeFlags))
*pIsBlittableOut = FALSE;
@@ -623,7 +598,6 @@ VOID EEClassLayoutInfo::CollectLayoutFieldMetadataThrowing(
// Running tote - if anything in this type disqualifies it from being ManagedSequential, somebody will set this to TRUE by the the time
// function exits.
BOOL fDisqualifyFromManagedSequential;
- BOOL hasAutoLayoutField = FALSE;
// Check if this type might be ManagedSequential. Only valuetypes marked Sequential can be
// ManagedSequential. Other issues checked below might also disqualify the type.
@@ -638,11 +612,6 @@ VOID EEClassLayoutInfo::CollectLayoutFieldMetadataThrowing(
fDisqualifyFromManagedSequential = TRUE;
}
- if (pParentMT && !pParentMT->IsValueTypeClass() && pParentMT->IsAutoLayoutOrHasAutoLayoutField())
- {
- hasAutoLayoutField = TRUE;
- }
-
BOOL fHasNonTrivialParent = pParentMT &&
!pParentMT->IsObjectClass() &&
@@ -690,7 +659,6 @@ VOID EEClassLayoutInfo::CollectLayoutFieldMetadataThrowing(
nativeTypeFlags,
pTypeContext,
&fDisqualifyFromManagedSequential,
- &hasAutoLayoutField,
pInfoArrayOut,
&isBlittable,
&cInstanceFields
@@ -703,8 +671,6 @@ VOID EEClassLayoutInfo::CollectLayoutFieldMetadataThrowing(
isBlittable = isBlittable && (fHasNonTrivialParent ? pParentMT->IsBlittable() : TRUE);
pEEClassLayoutInfoOut->SetIsBlittable(isBlittable);
- pEEClassLayoutInfoOut->SetHasAutoLayoutField(hasAutoLayoutField);
-
S_UINT32 cbSortArraySize = S_UINT32(cTotalFields) * S_UINT32(sizeof(LayoutRawFieldInfo*));
if (cbSortArraySize.IsOverflow())
{
diff --git a/src/coreclr/vm/classnames.h b/src/coreclr/vm/classnames.h
index 7d71ce2c7d891..94e9b1025c7a4 100644
--- a/src/coreclr/vm/classnames.h
+++ b/src/coreclr/vm/classnames.h
@@ -113,6 +113,4 @@
#define g_CriticalFinalizerObjectName "CriticalFinalizerObject"
-#define g_DisableRuntimeMarshallingAttribute "System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute"
-
#endif //!__CLASSNAMES_H__
diff --git a/src/coreclr/vm/clsload.cpp b/src/coreclr/vm/clsload.cpp
index c1a5ffb86ecd9..a2b0129e2dd71 100644
--- a/src/coreclr/vm/clsload.cpp
+++ b/src/coreclr/vm/clsload.cpp
@@ -563,7 +563,7 @@ BOOL ClassLoader::IsNested(Module *pModule, mdToken token, mdToken *mdEncloser)
(*mdEncloser != mdTypeRefNil));
case mdtExportedType:
- IfFailThrow(pModule->GetAssembly()->GetMDImport()->GetExportedTypeProps(
+ IfFailThrow(pModule->GetAssembly()->GetManifestImport()->GetExportedTypeProps(
token,
NULL, // namespace
NULL, // name
@@ -643,11 +643,17 @@ void ClassLoader::GetClassValue(NameHandleTable nhTable,
#endif
PTR_Assembly assembly = GetAssembly();
- Module * pCurrentClsModule = assembly->GetModule();
- _ASSERTE(pCurrentClsModule != NULL);
+ PREFIX_ASSUME(assembly != NULL);
+ ModuleIterator i = assembly->IterateModules();
- if (!pLookInThisModuleOnly || (pCurrentClsModule == pLookInThisModuleOnly))
+ while (i.Next())
{
+ Module * pCurrentClsModule = i.GetModule();
+ PREFIX_ASSUME(pCurrentClsModule != NULL);
+
+ if (pLookInThisModuleOnly && (pCurrentClsModule != pLookInThisModuleOnly))
+ continue;
+
#ifdef FEATURE_READYTORUN
if (nhTable == nhCaseSensitive && pCurrentClsModule->IsReadyToRun() && pCurrentClsModule->GetReadyToRunInfo()->HasHashtableOfTypes() &&
pCurrentClsModule->GetAvailableClassHash() == NULL)
@@ -738,7 +744,7 @@ void ClassLoader::GetClassValue(NameHandleTable nhTable,
(pBucket = pTable->FindNextNestedClass(pName, pData, &sContext)) != NULL);
break;
case mdtExportedType:
- while ((!CompareNestedEntryWithExportedType(pNameModule->GetAssembly()->GetMDImport(),
+ while ((!CompareNestedEntryWithExportedType(pNameModule->GetAssembly()->GetManifestImport(),
mdEncloser,
pCurrentClsModule->GetAvailableClassHash(),
pBucket->GetEncloser())) &&
@@ -832,11 +838,16 @@ void ClassLoader::LazyPopulateCaseSensitiveHashTables()
_ASSERT(m_cUnhashedModules > 0);
AllocMemTracker amTracker;
+ ModuleIterator i = GetAssembly()->IterateModules();
- // Create a case-sensitive hashtable for the module, and fill it with the module's typedef entries
- Module *pModule = GetAssembly()->GetModule();
- if (pModule->GetAvailableClassHash() == NULL)
+ // Create a case-sensitive hashtable for each module, and fill it with the module's typedef entries
+ while (i.Next())
{
+ Module *pModule = i.GetModule();
+ PREFIX_ASSUME(pModule != NULL);
+ if (pModule->GetAvailableClassHash() != NULL)
+ continue;
+
// Lazy construction of the case-sensitive hashtable of types is *only* a scenario for ReadyToRun images
// (either images compiled with an old version of crossgen, or for case-insensitive type lookups in R2R modules)
_ASSERT(pModule->IsReadyToRun());
@@ -847,14 +858,14 @@ void ClassLoader::LazyPopulateCaseSensitiveHashTables()
PopulateAvailableClassHashTable(pModule, &amTracker);
}
- // Add exported types to the hashtable
- IMDInternalImport * pManifestImport = GetAssembly()->GetMDImport();
+ // Add exported types of the manifest module to the hashtable
+ IMDInternalImport * pManifestImport = GetAssembly()->GetManifestImport();
HENUMInternalHolder phEnum(pManifestImport);
phEnum.EnumInit(mdtExportedType, mdTokenNil);
mdToken mdExportedType;
while (pManifestImport->EnumNext(&phEnum, &mdExportedType))
- AddExportedTypeHaveLock(GetAssembly()->GetModule(), mdExportedType, &amTracker);
+ AddExportedTypeHaveLock(GetAssembly()->GetManifestModule(), mdExportedType, &amTracker);
amTracker.SuppressRelease();
}
@@ -871,7 +882,7 @@ void ClassLoader::LazyPopulateCaseInsensitiveHashTables()
}
CONTRACTL_END;
- if (GetAssembly()->GetModule()->GetAvailableClassHash() == NULL)
+ if (GetAssembly()->GetManifestModule()->GetAvailableClassHash() == NULL)
{
// This is a R2R assembly, and a case insensitive type lookup was triggered.
// Construct the case-sensitive table first, since the case-insensitive table
@@ -882,23 +893,28 @@ void ClassLoader::LazyPopulateCaseInsensitiveHashTables()
// Add any unhashed modules into our hash tables, and try again.
AllocMemTracker amTracker;
- Module *pModule = GetAssembly()->GetModule();
- if (pModule->GetAvailableClassCaseInsHash() == NULL)
+ ModuleIterator i = GetAssembly()->IterateModules();
+
+ while (i.Next())
{
- EEClassHashTable *pNewClassCaseInsHash = pModule->GetAvailableClassHash()->MakeCaseInsensitiveTable(pModule, &amTracker);
+ Module *pModule = i.GetModule();
+ if (pModule->GetAvailableClassCaseInsHash() == NULL)
+ {
+ EEClassHashTable *pNewClassCaseInsHash = pModule->GetAvailableClassHash()->MakeCaseInsensitiveTable(pModule, &amTracker);
- LOG((LF_CLASSLOADER, LL_INFO10, "%s's classes being added to case insensitive hash table\n",
- pModule->GetSimpleName()));
+ LOG((LF_CLASSLOADER, LL_INFO10, "%s's classes being added to case insensitive hash table\n",
+ pModule->GetSimpleName()));
- {
- CANNOTTHROWCOMPLUSEXCEPTION();
- FAULT_FORBID();
+ {
+ CANNOTTHROWCOMPLUSEXCEPTION();
+ FAULT_FORBID();
- amTracker.SuppressRelease();
- pModule->SetAvailableClassCaseInsHash(pNewClassCaseInsHash);
- FastInterlockDecrement((LONG*)&m_cUnhashedModules);
+ amTracker.SuppressRelease();
+ pModule->SetAvailableClassCaseInsHash(pNewClassCaseInsHash);
+ FastInterlockDecrement((LONG*)&m_cUnhashedModules);
- _ASSERT(m_cUnhashedModules >= 0);
+ _ASSERT(m_cUnhashedModules >= 0);
+ }
}
}
}
@@ -1482,7 +1498,7 @@ ClassLoader::LoadTypeHandleThrowing(
if (typeHnd.IsNull() || !CompareNameHandleWithTypeHandleNoThrow(pName, typeHnd))
{
if (SUCCEEDED(pClsLdr->FindTypeDefByExportedType(
- pClsLdr->GetAssembly()->GetMDImport(),
+ pClsLdr->GetAssembly()->GetManifestImport(),
FoundExportedType,
pFoundModule->GetMDImport(),
&FoundCl)))
@@ -1844,8 +1860,16 @@ void ClassLoader::FreeModules()
CONTRACTL_END;
Module *pManifest = NULL;
- if (GetAssembly() && (NULL != (pManifest = GetAssembly()->GetModule())))
- {
+ if (GetAssembly() && (NULL != (pManifest = GetAssembly()->GetManifestModule()))) {
+ // Unload the manifest last, since it contains the module list in its rid map
+ ModuleIterator i = GetAssembly()->IterateModules();
+ while (i.Next()) {
+ // Have the module free its various tables and some of the EEClass links
+ if (i.GetModule() != pManifest)
+ i.GetModule()->Destruct();
+ }
+
+ // Now do the manifest module.
pManifest->Destruct();
}
@@ -3243,6 +3267,15 @@ TypeHandle ClassLoader::LoadTypeHandleForTypeKey(TypeKey *pTypeKey,
UINT32 typeLoad = ETW::TypeSystemLog::TypeLoadBegin();
#endif
+ // When using domain neutral assemblies (and not eagerly propagating dependency loads),
+ // it's possible to get here without having injected the module into the current app domain.
+ // GetDomainFile will accomplish that.
+
+ if (!pTypeKey->IsConstructed())
+ {
+ pTypeKey->GetModule()->GetDomainFile();
+ }
+
ClassLoadLevel currentLevel = typeHnd.IsNull() ? CLASS_LOAD_BEGIN : typeHnd.GetLoadLevel();
ClassLoadLevel targetLevelUnderLock = targetLevel < CLASS_DEPENDENCIES_LOADED ? targetLevel : (ClassLoadLevel) (CLASS_DEPENDENCIES_LOADED-1);
if (currentLevel < targetLevelUnderLock)
@@ -5126,7 +5159,12 @@ ClassLoader::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
if (m_pAssembly.IsValid())
{
- m_pAssembly->GetModule()->EnumMemoryRegions(flags, true);
+ ModuleIterator modIter = GetAssembly()->IterateModules();
+
+ while (modIter.Next())
+ {
+ modIter.GetModule()->EnumMemoryRegions(flags, true);
+ }
}
}
diff --git a/src/coreclr/vm/codeversion.cpp b/src/coreclr/vm/codeversion.cpp
index d59e13d45d45d..8fa82da46db6e 100644
--- a/src/coreclr/vm/codeversion.cpp
+++ b/src/coreclr/vm/codeversion.cpp
@@ -2036,15 +2036,18 @@ HRESULT CodeVersionManager::EnumerateDomainClosedMethodDescs(
// these are the default flags which won't actually be used in shared mode other than
// asserting they were specified with their default values
AssemblyIterationFlags assemFlags = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution);
+ ModuleIterationOption moduleFlags = (ModuleIterationOption)kModIterIncludeLoaded;
if (pAppDomainToSearch != NULL)
{
assemFlags = (AssemblyIterationFlags)(kIncludeAvailableToProfilers | kIncludeExecution);
+ moduleFlags = (ModuleIterationOption)kModIterIncludeAvailableToProfilers;
}
LoadedMethodDescIterator it(
pAppDomainToSearch,
pModuleContainingMethodDef,
methodDef,
- assemFlags);
+ assemFlags,
+ moduleFlags);
CollectibleAssemblyHolder pDomainAssembly;
while (it.Next(pDomainAssembly.This()))
{
diff --git a/src/coreclr/vm/comdynamic.cpp b/src/coreclr/vm/comdynamic.cpp
index 99a6c788b1e4f..4996b53e2e48c 100644
--- a/src/coreclr/vm/comdynamic.cpp
+++ b/src/coreclr/vm/comdynamic.cpp
@@ -900,8 +900,12 @@ void UpdateRuntimeStateForAssemblyCustomAttribute(Module* pModule, mdToken tkCus
actualFlags = ((DWORD)pAssembly->GetDebuggerInfoBits() & mask) | flags;
pAssembly->SetDebuggerInfoBits((DebuggerAssemblyControlFlags)actualFlags);
- actualFlags = ((DWORD)(pAssembly->GetModule()->GetDebuggerInfoBits()) & mask) | flags;
- pAssembly->GetModule()->SetDebuggerInfoBits((DebuggerAssemblyControlFlags)actualFlags);
+ ModuleIterator i = pAssembly->IterateModules();
+ while (i.Next())
+ {
+ actualFlags = ((DWORD)(i.GetModule()->GetDebuggerInfoBits()) & mask) | flags;
+ i.GetModule()->SetDebuggerInfoBits((DebuggerAssemblyControlFlags)actualFlags);
+ }
}
// InternalsVisibleTo and IgnoresAccessChecksTo attribute processing
diff --git a/src/coreclr/vm/commodule.cpp b/src/coreclr/vm/commodule.cpp
index cd2b5ab843456..f19482c2a59f3 100644
--- a/src/coreclr/vm/commodule.cpp
+++ b/src/coreclr/vm/commodule.cpp
@@ -256,13 +256,13 @@ extern "C" INT32 QCALLTYPE ModuleBuilder_GetMemberRef(QCall::ModuleHandle pModul
}
SafeComHolderPreemp pAssemblyEmit;
- IfFailThrow( pRefingAssembly->GetModule()->GetEmitter()->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pAssemblyEmit) );
+ IfFailThrow( pRefingAssembly->GetManifestModule()->GetEmitter()->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pAssemblyEmit) );
CQuickBytes qbNewSig;
ULONG cbNewSig;
IfFailThrow( pRefedModule->GetMDImport()->TranslateSigWithScope(
- pRefedAssembly->GetMDImport(),
+ pRefedAssembly->GetManifestImport(),
NULL, 0, // hash value
pvComSig,
cbComSig,
@@ -335,7 +335,7 @@ extern "C" INT32 QCALLTYPE ModuleBuilder_GetMemberRefOfMethodInfo(QCall::ModuleH
Assembly * pRefingAssembly = pModule->GetAssembly();
SafeComHolderPreemp pAssemblyEmit;
- IfFailThrow( pRefingAssembly->GetModule()->GetEmitter()->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pAssemblyEmit) );
+ IfFailThrow( pRefingAssembly->GetManifestModule()->GetEmitter()->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pAssemblyEmit) );
CQuickBytes qbNewSig;
ULONG cbNewSig;
@@ -349,7 +349,7 @@ extern "C" INT32 QCALLTYPE ModuleBuilder_GetMemberRefOfMethodInfo(QCall::ModuleH
}
IfFailThrow( pMeth->GetMDImport()->TranslateSigWithScope(
- pRefedAssembly->GetMDImport(),
+ pRefedAssembly->GetManifestImport(),
NULL, 0, // hash blob value
pvComSig,
cbComSig,
@@ -421,14 +421,14 @@ extern "C" mdMemberRef QCALLTYPE ModuleBuilder_GetMemberRefOfFieldInfo(QCall::Mo
COMPlusThrow(kNotSupportedException, W("NotSupported_CollectibleBoundNonCollectible"));
}
SafeComHolderPreemp pAssemblyEmit;
- IfFailThrow( pRefingAssembly->GetModule()->GetEmitter()->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pAssemblyEmit) );
+ IfFailThrow( pRefingAssembly->GetManifestModule()->GetEmitter()->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pAssemblyEmit) );
// Translate the field signature this scope
CQuickBytes qbNewSig;
ULONG cbNewSig;
IfFailThrow( pRefedMDImport->TranslateSigWithScope(
- pRefedAssembly->GetMDImport(),
+ pRefedAssembly->GetManifestImport(),
NULL, 0, // hash value
pvComSig,
cbComSig,
@@ -499,20 +499,14 @@ extern "C" void QCALLTYPE ModuleBuilder_SetFieldRVAContent(QCall::ModuleHandle p
if (pReflectionModule->m_sdataSection == 0)
IfFailThrow( pGen->GetSectionCreate (".sdata", sdReadWrite, &pReflectionModule->m_sdataSection) );
- // Define the alignment that the rva will be set to. Since the CoreCLR runtime only has hard alignment requirements
- // up to 8 bytes, the highest alignment we may need is 8 byte alignment. This hard alignment requirement is only needed
- // by Runtime.Helpers.CreateSpan. Since the previous alignment was 4 bytes before CreateSpan was implemented, if the
- // data isn't itself of size divisible by 8, just align to 4 to the memory cost of excess alignment.
- DWORD alignment = (length % 8 == 0) ? 8 : 4;
-
// Get the size of current .sdata section. This will be the RVA for this field within the section
DWORD dwRVA = 0;
IfFailThrow( pGen->GetSectionDataLen(pReflectionModule->m_sdataSection, &dwRVA) );
- dwRVA = (dwRVA + alignment-1) & ~(alignment-1);
+ dwRVA = (dwRVA + sizeof(DWORD)-1) & ~(sizeof(DWORD)-1);
// allocate the space in .sdata section
void * pvBlob;
- IfFailThrow( pGen->GetSectionBlock(pReflectionModule->m_sdataSection, length, alignment, (void**) &pvBlob) );
+ IfFailThrow( pGen->GetSectionBlock(pReflectionModule->m_sdataSection, length, sizeof(DWORD), (void**) &pvBlob) );
// copy over the initialized data if specified
if (pContent != NULL)
diff --git a/src/coreclr/vm/common.h b/src/coreclr/vm/common.h
index c2fff3f9c9a96..bcd9af84555c6 100644
--- a/src/coreclr/vm/common.h
+++ b/src/coreclr/vm/common.h
@@ -120,6 +120,8 @@ typedef DPTR(class ComPlusCallMethodDesc) PTR_ComPlusCallMethodDesc;
typedef VPTR(class DebugInterface) PTR_DebugInterface;
typedef DPTR(class Dictionary) PTR_Dictionary;
typedef VPTR(class DomainAssembly) PTR_DomainAssembly;
+typedef VPTR(class DomainFile) PTR_DomainFile;
+typedef VPTR(class DomainModule) PTR_DomainModule;
typedef DPTR(struct FailedAssembly) PTR_FailedAssembly;
typedef VPTR(class EditAndContinueModule) PTR_EditAndContinueModule;
typedef DPTR(class EEClass) PTR_EEClass;
@@ -427,6 +429,7 @@ extern DummyGlobalContract ___contract;
#include "typehandle.inl"
#include "object.inl"
#include "clsload.inl"
+#include "domainfile.inl"
#include "method.inl"
#include "syncblk.inl"
#include "threads.inl"
diff --git a/src/coreclr/vm/coreassemblyspec.cpp b/src/coreclr/vm/coreassemblyspec.cpp
index 2da6e14750d71..eaaddafdbe9c6 100644
--- a/src/coreclr/vm/coreassemblyspec.cpp
+++ b/src/coreclr/vm/coreassemblyspec.cpp
@@ -15,7 +15,7 @@
#include "appdomain.inl"
#include
#include "peimagelayout.inl"
-#include "domainassembly.h"
+#include "domainfile.h"
#include "holder.h"
#include "bundle.h"
#include "strongnameinternal.h"
diff --git a/src/coreclr/vm/corelib.cpp b/src/coreclr/vm/corelib.cpp
index 54bb5177cae53..707cd24274148 100644
--- a/src/coreclr/vm/corelib.cpp
+++ b/src/coreclr/vm/corelib.cpp
@@ -32,6 +32,7 @@
#include "comdatetime.h"
#include "compatibilityswitch.h"
#include "debugdebugger.h"
+#include "assemblyname.hpp"
#include "assemblynative.hpp"
#include "comthreadpool.h"
#include "comwaithandle.h"
diff --git a/src/coreclr/vm/dacenumerablehash.inl b/src/coreclr/vm/dacenumerablehash.inl
index 049329bbfbc67..e4e5de3b11f3f 100644
--- a/src/coreclr/vm/dacenumerablehash.inl
+++ b/src/coreclr/vm/dacenumerablehash.inl
@@ -400,8 +400,8 @@ namespace HashTableDetail
{
// Use the C++ detection idiom (https://isocpp.org/blog/2017/09/detection-idiom-a-stopgap-for-concepts-simon-brand) to call the
// derived table's EnumMemoryRegionsForEntry method if it defines one.
- template struct make_void { using type = void; };
- template using void_t = typename make_void::type;
+ template
+ using void_t = void;
template
struct negation : std::integral_constant { };
diff --git a/src/coreclr/vm/dbginterface.h b/src/coreclr/vm/dbginterface.h
index c9bc65c33fd28..51b2c3bf36358 100644
--- a/src/coreclr/vm/dbginterface.h
+++ b/src/coreclr/vm/dbginterface.h
@@ -68,7 +68,7 @@ class DebugInterface
DWORD dwModuleName, // number of characters in file name excludign null
Assembly * pAssembly, // the assembly the module belongs to
AppDomain * pAppDomain, // the AppDomain the module is being loaded into
- DomainAssembly * pDomainAssembly,
+ DomainFile * pDomainFile,
BOOL fAttaching) = 0; // true if this notification is due to a debugger
// being attached to the process
@@ -242,7 +242,7 @@ class DebugInterface
// send a custom notification from the target to the RS. This will become an ICorDebugThread and
// ICorDebugAppDomain on the RS.
- virtual void SendCustomDebuggerNotification(Thread * pThread, DomainAssembly * pDomainAssembly, mdTypeDef classToken) = 0;
+ virtual void SendCustomDebuggerNotification(Thread * pThread, DomainFile * pDomainFile, mdTypeDef classToken) = 0;
// Send an MDA notification. This ultimately translates to an ICorDebugMDA object on the Right-Side.
virtual void SendMDANotification(
diff --git a/src/coreclr/vm/debugdebugger.cpp b/src/coreclr/vm/debugdebugger.cpp
index 566bb74d6d3eb..2ade537044abb 100644
--- a/src/coreclr/vm/debugdebugger.cpp
+++ b/src/coreclr/vm/debugdebugger.cpp
@@ -827,11 +827,11 @@ FCIMPL1(void, DebugDebugger::CustomNotification, Object * dataUNSAFE)
StrongHandleHolder objHandle = pAppDomain->CreateStrongHandle(pData);
MethodTable * pMT = pData->GetGCSafeMethodTable();
Module * pModule = pMT->GetModule();
- DomainAssembly * pDomainAssembly = pModule->GetDomainAssembly();
+ DomainFile * pDomainFile = pModule->GetDomainFile();
mdTypeDef classToken = pMT->GetCl();
pThread->SetThreadCurrNotification(objHandle);
- g_pDebugInterface->SendCustomDebuggerNotification(pThread, pDomainAssembly, classToken);
+ g_pDebugInterface->SendCustomDebuggerNotification(pThread, pDomainFile, classToken);
pThread->ClearThreadCurrNotification();
if (pThread->IsAbortRequested())
diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp
index 3a35a8e108fa4..6c4ce7608660e 100644
--- a/src/coreclr/vm/dllimport.cpp
+++ b/src/coreclr/vm/dllimport.cpp
@@ -107,7 +107,6 @@ StubSigDesc::StubSigDesc(MethodDesc *pMD)
m_tkMethodDef = pMD->GetMemberDef();
SigTypeContext::InitTypeContext(pMD, &m_typeContext);
- m_pMetadataModule = pMD->GetModule();
m_pLoaderModule = pMD->GetLoaderModule(); // Used for ILStubCache selection and MethodTable creation.
INDEBUG(InitDebugNames());
@@ -134,13 +133,11 @@ StubSigDesc::StubSigDesc(MethodDesc* pMD, const Signature& sig, Module* pModule)
{
m_tkMethodDef = pMD->GetMemberDef();
SigTypeContext::InitTypeContext(pMD, &m_typeContext);
- m_pMetadataModule = pMD->GetModule();
m_pLoaderModule = pMD->GetLoaderModule(); // Used for ILStubCache selection and MethodTable creation.
}
else
{
m_tkMethodDef = mdMethodDefNil;
- m_pMetadataModule = m_pModule;
m_pLoaderModule = m_pModule;
}
@@ -169,8 +166,7 @@ StubSigDesc::StubSigDesc(MethodTable* pMT, const Signature& sig, Module* pModule
if (pMT != NULL)
{
SigTypeContext::InitTypeContext(pMT, &m_typeContext);
- m_pMetadataModule = pMT->GetModule();
- m_pLoaderModule = pMT->GetLoaderModule();
+ m_pLoaderModule = pMT->GetLoaderModule(); // Used for ILStubCache selection and MethodTable creation.
}
else
{
@@ -197,7 +193,6 @@ StubSigDesc::StubSigDesc(const Signature& sig, Module* pModule)
m_sig = sig;
m_pModule = pModule;
m_tkMethodDef = mdMethodDefNil;
- m_pMetadataModule = m_pModule;
m_pLoaderModule = m_pModule;
INDEBUG(InitDebugNames());
@@ -964,7 +959,7 @@ class ILStubState : public StubState
if (pTargetMD)
{
pTargetMD->GetMethodInfoWithNewSig(strNamespaceOrClassName, strMethodName, strMethodSignature);
- uModuleId = (UINT64)(TADDR)pTargetMD->GetModule_NoLogging();
+ uModuleId = (UINT64)pTargetMD->GetModule()->GetAddrModuleID();
}
//
@@ -3292,15 +3287,6 @@ BOOL NDirect::MarshalingRequired(
}
CollateParamTokens(pMDImport, methodToken, numArgs - 1, pParamTokenArray);
- // We enable the runtime marshalling system whenever it is enabled on the module as a whole
- // or when the call is a COM interop call. COM interop calls are already using a significant portion of the runtime
- // marshalling system just to function at all, so we aren't going to disable the parameter marshalling;
- // we'd rather have developers use the feature flag to diable the whole COM interop subsystem at once.
- bool runtimeMarshallingEnabled = pModule->IsRuntimeMarshallingEnabled();
-#ifdef FEATURE_COMINTEROP
- runtimeMarshallingEnabled |= pMD && pMD->IsComPlusCall();
-#endif
-
for (ULONG i = 0; i < numArgs; i++)
{
SigPointer arg = ptr;
@@ -3314,7 +3300,7 @@ BOOL NDirect::MarshalingRequired(
IfFailThrow(arg.GetElemType(NULL)); // skip ELEMENT_TYPE_PTR
IfFailThrow(arg.PeekElemType(&type));
- if (runtimeMarshallingEnabled && type == ELEMENT_TYPE_VALUETYPE)
+ if (type == ELEMENT_TYPE_VALUETYPE)
{
if ((arg.HasCustomModifier(pModule,
"Microsoft.VisualC.NeedsCopyConstructorModifier",
@@ -3345,21 +3331,11 @@ BOOL NDirect::MarshalingRequired(
{
TypeHandle hndArgType = arg.GetTypeHandleThrowing(pModule, &emptyTypeContext);
- // When the runtime runtime marshalling system is disabled, we don't support
- // any types that contain gc pointers, but all "unmanaged" types are treated as blittable
- // as long as they aren't auto-layout and don't have any auto-layout fields.
- if (!runtimeMarshallingEnabled &&
- (hndArgType.GetMethodTable()->ContainsPointers()
- || hndArgType.GetMethodTable()->IsAutoLayoutOrHasAutoLayoutField()))
+ // JIT can handle internal blittable value types
+ if (!hndArgType.IsBlittable() && !hndArgType.IsEnum())
{
return TRUE;
}
- else if (runtimeMarshallingEnabled && !hndArgType.IsBlittable() && !hndArgType.IsEnum())
- {
- // When the runtime runtime marshalling system is enabled, we do special handling
- // for any types that aren't blittable or enums.
- return TRUE;
- }
if (i > 0)
{
@@ -3372,15 +3348,10 @@ BOOL NDirect::MarshalingRequired(
case ELEMENT_TYPE_BOOLEAN:
case ELEMENT_TYPE_CHAR:
{
- // When runtime marshalling is enabled:
// Bool requires marshaling
// Char may require marshaling (MARSHAL_TYPE_ANSICHAR)
- if (runtimeMarshallingEnabled)
- {
- return TRUE;
- }
+ return TRUE;
}
- FALLTHROUGH;
default:
{
@@ -3405,10 +3376,7 @@ BOOL NDirect::MarshalingRequired(
// check for explicit MarshalAs
NativeTypeParamInfo paramInfo;
- // We only check the MarshalAs info when the runtime marshalling system is enabled.
- // We ignore MarshalAs when the system is disabled, so no reason to disqualify from inlining
- // when it is present.
- if (runtimeMarshallingEnabled && pParamTokenArray[i] != mdParamDefNil)
+ if (pParamTokenArray[i] != mdParamDefNil)
{
if (!ParseNativeTypeInfo(pParamTokenArray[i], pMDImport, ¶mInfo) ||
paramInfo.m_NativeType != NATIVE_TYPE_DEFAULT)
@@ -3626,7 +3594,6 @@ static void CreateNDirectStubWorker(StubState* pss,
CONSISTENCY_CHECK_MSGF(false, ("BreakOnInteropStubSetup: '%s' ", pSigDesc->m_pDebugName));
#endif // _DEBUG
- bool runtimeMarshallingEnabled = SF_IsCOMStub(dwStubFlags) || pSigDesc->m_pMetadataModule->IsRuntimeMarshallingEnabled();
if (SF_IsCOMStub(dwStubFlags))
{
_ASSERTE(0 == nlType);
@@ -3648,48 +3615,26 @@ static void CreateNDirectStubWorker(StubState* pss,
&pSigDesc->m_typeContext);
if (SF_IsVarArgStub(dwStubFlags))
- {
- if (!runtimeMarshallingEnabled)
- {
- COMPlusThrow(kMarshalDirectiveException, IDS_EE_NDIRECT_DISABLEDMARSHAL_VARARGS);
- }
msig.SetTreatAsVarArg();
- }
bool fThisCall = (unmgdCallConv == CorInfoCallConvExtension::Thiscall);
- if (nlFlags & nlfLastError)
- {
- if (!runtimeMarshallingEnabled)
- {
- COMPlusThrow(kMarshalDirectiveException, IDS_EE_NDIRECT_DISABLEDMARSHAL_SETLASTERROR);
- }
- pss->SetLastError(TRUE);
- }
+ pss->SetLastError(nlFlags & nlfLastError);
// This has been in the product since forward P/Invoke via delegates was
// introduced. It's wrong, but please keep it for backward compatibility.
- if (runtimeMarshallingEnabled && SF_IsDelegateStub(dwStubFlags))
+ if (SF_IsDelegateStub(dwStubFlags))
pss->SetLastError(TRUE);
pss->BeginEmit(dwStubFlags);
if (-1 != iLCIDArg)
{
- if (!runtimeMarshallingEnabled)
- {
- COMPlusThrow(kMarshalDirectiveException, IDS_EE_NDIRECT_DISABLEDMARSHAL_LCID);
- }
- // The code to handle the LCID will call MarshalLCID before calling MarshalArgument
+ // The code to handle the LCID will call MarshalLCID before calling MarshalArgument
// on the argument the LCID should go after. So we just bump up the index here.
iLCIDArg++;
}
- if (!runtimeMarshallingEnabled && SF_IsHRESULTSwapping(dwStubFlags))
- {
- COMPlusThrow(kMarshalDirectiveException, IDS_EE_NDIRECT_DISABLEDMARSHAL_PRESERVESIG);
- }
-
int numArgs = msig.NumFixedArgs();
// thiscall must have at least one parameter (the "this")
diff --git a/src/coreclr/vm/dllimport.h b/src/coreclr/vm/dllimport.h
index 8b472e3a0aafb..f731823ff4a0b 100644
--- a/src/coreclr/vm/dllimport.h
+++ b/src/coreclr/vm/dllimport.h
@@ -23,15 +23,7 @@ struct StubSigDesc
MethodDesc *m_pMD;
MethodTable *m_pMT;
Signature m_sig;
- // Module to use for signature reading.
Module *m_pModule;
- // Module that owns any metadata that influences interop behavior.
- // This is usually the same as m_pModule, but can differ with vararg
- // P/Invokes, where the calling assembly's module is assigned to m_pModule
- // since the specific caller signature is defined in that assembly, not the
- // assembly that defined the P/Invoke.
- Module *m_pMetadataModule;
- // Used for ILStubCache selection and MethodTable creation.
Module *m_pLoaderModule;
mdMethodDef m_tkMethodDef;
SigTypeContext m_typeContext;
diff --git a/src/coreclr/vm/dllimportcallback.cpp b/src/coreclr/vm/dllimportcallback.cpp
index 65d2afd7d0512..455d33813eec0 100644
--- a/src/coreclr/vm/dllimportcallback.cpp
+++ b/src/coreclr/vm/dllimportcallback.cpp
@@ -195,6 +195,37 @@ extern "C" VOID STDCALL ReversePInvokeBadTransition()
);
}
+// Disable from a place that is calling into managed code via a UMEntryThunk.
+extern "C" VOID STDCALL UMThunkStubRareDisableWorker(Thread *pThread, UMEntryThunk *pUMEntryThunk)
+{
+ STATIC_CONTRACT_THROWS;
+ STATIC_CONTRACT_GC_TRIGGERS;
+
+ // Do not add a CONTRACT here. We haven't set up SEH.
+
+ // WARNING!!!!
+ // when we start executing here, we are actually in cooperative mode. But we
+ // haven't synchronized with the barrier to reentry yet. So we are in a highly
+ // dangerous mode. If we call managed code, we will potentially be active in
+ // the GC heap, even as GC's are occuring!
+
+ // We must do the following in this order, because otherwise we would be constructing
+ // the exception for the abort without synchronizing with the GC. Also, we have no
+ // CLR SEH set up, despite the fact that we may throw a ThreadAbortException.
+ pThread->RareDisablePreemptiveGC();
+ pThread->HandleThreadAbort();
+
+#ifdef DEBUGGING_SUPPORTED
+ // If the debugger is attached, we use this opportunity to see if
+ // we're disabling preemptive GC on the way into the runtime from
+ // unmanaged code. We end up here because
+ // Increment/DecrementTraceCallCount() will bump
+ // g_TrapReturningThreads for us.
+ if (CORDebuggerTraceCall())
+ g_pDebugInterface->TraceCall((const BYTE *)pUMEntryThunk->GetManagedTarget());
+#endif // DEBUGGING_SUPPORTED
+}
+
PCODE TheUMEntryPrestubWorker(UMEntryThunk * pUMEntryThunk)
{
STATIC_CONTRACT_THROWS;
@@ -203,13 +234,39 @@ PCODE TheUMEntryPrestubWorker(UMEntryThunk * pUMEntryThunk)
Thread * pThread = GetThreadNULLOk();
if (pThread == NULL)
+ pThread = CreateThreadBlockThrow();
+
+ GCX_COOP_THREAD_EXISTS(pThread);
+
+ if (pThread->IsAbortRequested())
+ pThread->HandleThreadAbort();
+
+ UMEntryThunk::DoRunTimeInit(pUMEntryThunk);
+
+ return (PCODE)pUMEntryThunk->GetCode();
+}
+
+void RunTimeInit_Wrapper(LPVOID /* UMThunkMarshInfo * */ ptr)
+{
+ WRAPPER_NO_CONTRACT;
+
+ UMEntryThunk::DoRunTimeInit((UMEntryThunk*)ptr);
+}
+
+
+// asm entrypoint
+void STDCALL UMEntryThunk::DoRunTimeInit(UMEntryThunk* pUMEntryThunk)
+{
+
+ CONTRACTL
{
- CREATETHREAD_IF_NULL_FAILFAST(pThread, W("Failed to setup new thread during reverse P/Invoke"));
+ THROWS;
+ GC_TRIGGERS;
+ MODE_COOPERATIVE;
+ ENTRY_POINT;
+ PRECONDITION(CheckPointer(pUMEntryThunk));
}
-
- // Verify the current thread isn't in COOP mode.
- if (pThread->PreemptiveGCDisabled())
- ReversePInvokeBadTransition();
+ CONTRACTL_END;
INSTALL_MANAGED_EXCEPTION_DISPATCHER;
// this method is called by stubs which are called by managed code,
@@ -217,13 +274,15 @@ PCODE TheUMEntryPrestubWorker(UMEntryThunk * pUMEntryThunk)
// exceptions don't leak out into managed code.
INSTALL_UNWIND_AND_CONTINUE_HANDLER;
- ExecutableWriterHolder uMEntryThunkWriterHolder(pUMEntryThunk, sizeof(UMEntryThunk));
- uMEntryThunkWriterHolder.GetRW()->RunTimeInit(pUMEntryThunk);
+ {
+ GCX_PREEMP();
+
+ ExecutableWriterHolder uMEntryThunkWriterHolder(pUMEntryThunk, sizeof(UMEntryThunk));
+ uMEntryThunkWriterHolder.GetRW()->RunTimeInit(pUMEntryThunk);
+ }
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;
-
- return (PCODE)pUMEntryThunk->GetCode();
}
UMEntryThunk* UMEntryThunk::CreateUMEntryThunk()
diff --git a/src/coreclr/vm/dllimportcallback.h b/src/coreclr/vm/dllimportcallback.h
index fb2214a8c18d5..14b7db5704824 100644
--- a/src/coreclr/vm/dllimportcallback.h
+++ b/src/coreclr/vm/dllimportcallback.h
@@ -16,12 +16,6 @@
#include "class.h"
#include "dllimport.h"
-class UMThunkMarshInfo;
-typedef DPTR(class UMThunkMarshInfo) PTR_UMThunkMarshInfo;
-
-class UMEntryThunk;
-typedef DPTR(class UMEntryThunk) PTR_UMEntryThunk;
-
//----------------------------------------------------------------------
// This structure collects all information needed to marshal an
// unmanaged->managed thunk. The only information missing is the
@@ -195,6 +189,9 @@ class UMEntryThunk
#endif // _DEBUG
}
+ // asm entrypoint
+ static VOID STDCALL DoRunTimeInit(UMEntryThunk* pThis);
+
PCODE GetManagedTarget() const
{
CONTRACT (PCODE)
@@ -399,7 +396,14 @@ class UMEntryThunkCache
};
#if defined(TARGET_X86) && !defined(FEATURE_STUBS_AS_IL)
+//-------------------------------------------------------------------------
+// One-time creation of special prestub to initialize UMEntryThunks.
+//-------------------------------------------------------------------------
+Stub *GenerateUMThunkPrestub();
+
EXCEPTION_HANDLER_DECL(FastNExportExceptHandler);
+EXCEPTION_HANDLER_DECL(UMThunkPrestubHandler);
+
#endif // TARGET_X86 && !FEATURE_STUBS_AS_IL
extern "C" void TheUMEntryPrestub(void);
diff --git a/src/coreclr/vm/domainassembly.cpp b/src/coreclr/vm/domainfile.cpp
similarity index 80%
rename from src/coreclr/vm/domainassembly.cpp
rename to src/coreclr/vm/domainfile.cpp
index 458f988280b02..22796801543b3 100644
--- a/src/coreclr/vm/domainassembly.cpp
+++ b/src/coreclr/vm/domainfile.cpp
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// --------------------------------------------------------------------------------
-// DomainAssembly.cpp
+// DomainFile.cpp
//
// --------------------------------------------------------------------------------
@@ -30,42 +30,33 @@
#endif // FEATURE_PERFMAP
#ifndef DACCESS_COMPILE
-DomainAssembly::DomainAssembly(AppDomain* pDomain, PEAssembly* pPEAssembly, LoaderAllocator* pLoaderAllocator) :
- m_pAssembly(NULL),
- m_pDomain(pDomain),
+DomainFile::DomainFile(AppDomain *pDomain, PEAssembly *pPEAssembly)
+ : m_pDomain(pDomain),
m_pPEAssembly(pPEAssembly),
m_pModule(NULL),
- m_fCollectible(pLoaderAllocator->IsCollectible()),
- m_NextDomainAssemblyInSameALC(NULL),
- m_pLoaderAllocator(pLoaderAllocator),
m_level(FILE_LOAD_CREATE),
- m_loading(TRUE),
- m_hExposedModuleObject(NULL),
- m_hExposedAssemblyObject(NULL),
m_pError(NULL),
- m_bDisableActivationCheck(FALSE),
- m_fHostAssemblyPublished(FALSE),
- m_pDynamicMethodTable(NULL),
- m_debuggerFlags(DACF_NONE),
m_notifyflags(NOT_NOTIFIED),
- m_fDebuggerUnloadStarted(FALSE)
+ m_loading(TRUE),
+ m_pDynamicMethodTable(NULL),
+ m_pUMThunkHash(NULL),
+ m_bDisableActivationCheck(FALSE)
{
CONTRACTL
{
CONSTRUCTOR_CHECK;
- THROWS; // ValidateForExecution
- GC_TRIGGERS; // ValidateForExecution
+ THROWS; // From CreateHandle
+ GC_NOTRIGGER;
MODE_ANY;
+ FORBID_FAULT;
}
CONTRACTL_END;
+ m_hExposedModuleObject = NULL;
pPEAssembly->AddRef();
- pPEAssembly->ValidateForExecution();
-
- SetupDebuggingConfig();
}
-DomainAssembly::~DomainAssembly()
+DomainFile::~DomainFile()
{
CONTRACTL
{
@@ -79,24 +70,36 @@ DomainAssembly::~DomainAssembly()
m_pPEAssembly->Release();
if (m_pDynamicMethodTable)
m_pDynamicMethodTable->Destroy();
-
delete m_pError;
+}
- if (m_fHostAssemblyPublished)
+#endif //!DACCESS_COMPILE
+
+LoaderAllocator * DomainFile::GetLoaderAllocator()
+{
+ CONTRACTL
{
- // Remove association first.
- UnregisterFromHostAssembly();
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
}
-
- if (m_pAssembly != NULL)
+ CONTRACTL_END;
+ Assembly *pAssembly = GetDomainAssembly()->GetAssembly();
+ if ((pAssembly != NULL) && (pAssembly->IsCollectible()))
{
- delete m_pAssembly;
+ return pAssembly->GetLoaderAllocator();
+ }
+ else
+ {
+ return this->GetAppDomain()->GetLoaderAllocator();
}
}
+#ifndef DACCESS_COMPILE
+
// Optimization intended for EnsureLoadLevel only
#include
-void DomainAssembly::EnsureLoadLevel(FileLoadLevel targetLevel)
+void DomainFile::EnsureLoadLevel(FileLoadLevel targetLevel)
{
CONTRACT_VOID
{
@@ -109,7 +112,7 @@ void DomainAssembly::EnsureLoadLevel(FileLoadLevel targetLevel)
TRIGGERSGC ();
if (IsLoading())
{
- this->GetAppDomain()->LoadDomainAssembly(this, targetLevel);
+ this->GetAppDomain()->LoadDomainFile(this, targetLevel);
// Enforce the loading requirement. Note that we may have a deadlock in which case we
// may be off by one which is OK. (At this point if we are short of targetLevel we know
@@ -124,7 +127,26 @@ void DomainAssembly::EnsureLoadLevel(FileLoadLevel targetLevel)
}
#include
-CHECK DomainAssembly::CheckLoadLevel(FileLoadLevel requiredLevel, BOOL deadlockOK)
+void DomainFile::AttemptLoadLevel(FileLoadLevel targetLevel)
+{
+ CONTRACT_VOID
+ {
+ INSTANCE_CHECK;
+ THROWS;
+ GC_TRIGGERS;
+ }
+ CONTRACT_END;
+
+ if (IsLoading())
+ this->GetAppDomain()->LoadDomainFile(this, targetLevel);
+ else
+ ThrowIfError(targetLevel);
+
+ RETURN;
+}
+
+
+CHECK DomainFile::CheckLoadLevel(FileLoadLevel requiredLevel, BOOL deadlockOK)
{
CONTRACTL
{
@@ -154,7 +176,7 @@ CHECK DomainAssembly::CheckLoadLevel(FileLoadLevel requiredLevel, BOOL deadlockO
-void DomainAssembly::RequireLoadLevel(FileLoadLevel targetLevel)
+void DomainFile::RequireLoadLevel(FileLoadLevel targetLevel)
{
CONTRACT_VOID
{
@@ -174,7 +196,7 @@ void DomainAssembly::RequireLoadLevel(FileLoadLevel targetLevel)
}
-void DomainAssembly::SetError(Exception *ex)
+void DomainFile::SetError(Exception *ex)
{
CONTRACT_VOID
{
@@ -189,26 +211,26 @@ void DomainAssembly::SetError(Exception *ex)
m_pError = new ExInfo(ex->DomainBoundClone());
- if (m_pModule)
- {
- m_pModule->NotifyEtwLoadFinished(ex->GetHR());
+ GetCurrentModule()->NotifyEtwLoadFinished(ex->GetHR());
- if (!IsProfilerNotified())
- {
- SetProfilerNotified();
+ if (!IsProfilerNotified())
+ {
+ SetProfilerNotified();
#ifdef PROFILING_SUPPORTED
+ if (GetCurrentModule() != NULL)
+ {
// Only send errors for non-shared assemblies; other assemblies might be successfully completed
// in another app domain later.
- m_pModule->NotifyProfilerLoadFinished(ex->GetHR());
-#endif
+ GetCurrentModule()->NotifyProfilerLoadFinished(ex->GetHR());
}
+#endif
}
RETURN;
}
-void DomainAssembly::ThrowIfError(FileLoadLevel targetLevel)
+void DomainFile::ThrowIfError(FileLoadLevel targetLevel)
{
CONTRACT_VOID
{
@@ -228,7 +250,7 @@ void DomainAssembly::ThrowIfError(FileLoadLevel targetLevel)
RETURN;
}
-CHECK DomainAssembly::CheckNoError(FileLoadLevel targetLevel)
+CHECK DomainFile::CheckNoError(FileLoadLevel targetLevel)
{
LIMITED_METHOD_CONTRACT;
CHECK(m_level >= targetLevel
@@ -237,7 +259,7 @@ CHECK DomainAssembly::CheckNoError(FileLoadLevel targetLevel)
CHECK_OK;
}
-CHECK DomainAssembly::CheckLoaded()
+CHECK DomainFile::CheckLoaded()
{
CONTRACTL
{
@@ -248,7 +270,7 @@ CHECK DomainAssembly::CheckLoaded()
}
CONTRACTL_END;
- CHECK_MSG(CheckNoError(FILE_LOADED), "DomainAssembly load resulted in an error");
+ CHECK_MSG(CheckNoError(FILE_LOADED), "DomainFile load resulted in an error");
if (IsLoaded())
CHECK_OK;
@@ -265,7 +287,7 @@ CHECK DomainAssembly::CheckLoaded()
CHECK_OK;
}
-CHECK DomainAssembly::CheckActivated()
+CHECK DomainFile::CheckActivated()
{
CONTRACTL
{
@@ -276,7 +298,7 @@ CHECK DomainAssembly::CheckActivated()
}
CONTRACTL_END;
- CHECK_MSG(CheckNoError(FILE_ACTIVE), "DomainAssembly load resulted in an error");
+ CHECK_MSG(CheckNoError(FILE_ACTIVE), "DomainFile load resulted in an error");
if (IsActive())
CHECK_OK;
@@ -289,7 +311,7 @@ CHECK DomainAssembly::CheckActivated()
CHECK_OK;
CHECK_MSG(GetPEAssembly()->IsLoaded(), "PEAssembly has not been loaded");
- CHECK_MSG(IsLoaded(), "DomainAssembly has not been fully loaded");
+ CHECK_MSG(IsLoaded(), "DomainFile has not been fully loaded");
CHECK_MSG(m_bDisableActivationCheck || CheckLoadLevel(FILE_ACTIVE), "File has not had execution verified");
CHECK_OK;
@@ -297,6 +319,20 @@ CHECK DomainAssembly::CheckActivated()
#endif //!DACCESS_COMPILE
+DomainAssembly *DomainFile::GetDomainAssembly()
+{
+ CONTRACTL
+ {
+ SUPPORTS_DAC;
+ NOTHROW;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ _ASSERTE(IsAssembly());
+ return (DomainAssembly *) this;
+}
+
// Return true iff the debugger should get notifications about this assembly.
//
// Notes:
@@ -322,7 +358,7 @@ BOOL DomainAssembly::IsVisibleToDebugger()
// Returns managed representation of the module (Module or ModuleBuilder).
// Returns NULL if the managed scout was already collected (see code:LoaderAllocator#AssemblyPhases).
//
-OBJECTREF DomainAssembly::GetExposedModuleObject()
+OBJECTREF DomainFile::GetExposedModuleObject()
{
CONTRACTL
{
@@ -387,9 +423,9 @@ OBJECTREF DomainAssembly::GetExposedModuleObject()
}
return pLoaderAllocator->GetHandleValue(m_hExposedModuleObject);
-}
+} // DomainFile::GetExposedModuleObject
-BOOL DomainAssembly::DoIncrementalLoad(FileLoadLevel level)
+BOOL DomainFile::DoIncrementalLoad(FileLoadLevel level)
{
STANDARD_VM_CONTRACT;
@@ -455,7 +491,7 @@ BOOL DomainAssembly::DoIncrementalLoad(FileLoadLevel level)
#ifdef FEATURE_MULTICOREJIT
{
- Module * pModule = m_pModule;
+ Module * pModule = GetModule();
if (pModule != NULL) // Should not triggle assert when module is NULL
{
@@ -467,7 +503,7 @@ BOOL DomainAssembly::DoIncrementalLoad(FileLoadLevel level)
return TRUE;
}
-void DomainAssembly::PreLoadLibrary()
+void DomainFile::PreLoadLibrary()
{
CONTRACTL
{
@@ -476,9 +512,11 @@ void DomainAssembly::PreLoadLibrary()
}
CONTRACTL_END;
-} // DomainAssembly::PreLoadLibrary
+} // DomainFile::PreLoadLibrary
-void DomainAssembly::LoadLibrary()
+// Note that this is the sole loading function which must be called OUTSIDE THE LOCK, since
+// it will potentially involve the OS loader lock.
+void DomainFile::LoadLibrary()
{
CONTRACTL
{
@@ -489,7 +527,7 @@ void DomainAssembly::LoadLibrary()
}
-void DomainAssembly::PostLoadLibrary()
+void DomainFile::PostLoadLibrary()
{
CONTRACTL
{
@@ -519,46 +557,46 @@ void DomainAssembly::PostLoadLibrary()
if (!IsProfilerNotified())
{
SetProfilerNotified();
- GetModule()->NotifyProfilerLoadFinished(S_OK);
+ GetCurrentModule()->NotifyProfilerLoadFinished(S_OK);
}
#endif
}
-void DomainAssembly::AddDependencies()
+void DomainFile::AddDependencies()
{
STANDARD_VM_CONTRACT;
}
-void DomainAssembly::EagerFixups()
+void DomainFile::EagerFixups()
{
WRAPPER_NO_CONTRACT;
#ifdef FEATURE_READYTORUN
- if (GetModule()->IsReadyToRun())
+ if (GetCurrentModule()->IsReadyToRun())
{
- GetModule()->RunEagerFixups();
+ GetCurrentModule()->RunEagerFixups();
- PEImageLayout * pLayout = GetModule()->GetReadyToRunInfo()->GetImage();
+ PEImageLayout * pLayout = GetCurrentModule()->GetReadyToRunInfo()->GetImage();
TADDR base = dac_cast(pLayout->GetBase());
ExecutionManager::AddCodeRange(base, base + (TADDR)pLayout->GetVirtualSize(),
ExecutionManager::GetReadyToRunJitManager(),
RangeSection::RANGE_SECTION_READYTORUN,
- GetModule() /* (void *)pLayout */);
+ GetCurrentModule() /* (void *)pLayout */);
}
#endif // FEATURE_READYTORUN
}
-void DomainAssembly::VtableFixups()
+void DomainFile::VtableFixups()
{
WRAPPER_NO_CONTRACT;
- GetModule()->FixupVTables();
+ GetCurrentModule()->FixupVTables();
}
-void DomainAssembly::FinishLoad()
+void DomainFile::FinishLoad()
{
CONTRACTL
{
@@ -583,7 +621,7 @@ void DomainAssembly::FinishLoad()
#endif
}
-void DomainAssembly::Activate()
+void DomainFile::Activate()
{
CONTRACT_VOID
{
@@ -593,11 +631,24 @@ void DomainAssembly::Activate()
}
CONTRACT_END;
- // We cannot execute any code in this assembly until we know what exception plan it is on.
- // At the point of an exception's stack-crawl it is too late because we cannot tolerate a GC.
- // See PossiblyUnwrapThrowable and its callers.
- _ASSERTE(GetModule() == GetAssembly()->GetModule());
- GetModule()->IsRuntimeWrapExceptions();
+ // If we are a module, ensure we've activated the assembly first.
+
+ if (!IsAssembly())
+ {
+ GetDomainAssembly()->EnsureActive();
+ }
+ else
+ {
+ // We cannot execute any code in this assembly until we know what exception plan it is on.
+ // At the point of an exception's stack-crawl it is too late because we cannot tolerate a GC.
+ // See PossiblyUnwrapThrowable and its callers.
+ _ASSERTE(GetLoadedModule() == GetDomainAssembly()->GetLoadedAssembly()->GetManifestModule());
+ GetLoadedModule()->IsRuntimeWrapExceptions();
+ }
+
+ // Now activate any dependencies.
+ // This will typically cause reentrancy of course.
+
//
// Now call the module constructor. Note that this might cause reentrancy;
@@ -618,18 +669,84 @@ void DomainAssembly::Activate()
}
#endif //_DEBUG
+
RETURN;
}
+//--------------------------------------------------------------------------------
+// DomainAssembly
+//--------------------------------------------------------------------------------
+
+DomainAssembly::DomainAssembly(AppDomain *pDomain, PEAssembly *pPEAssembly, LoaderAllocator *pLoaderAllocator)
+ : DomainFile(pDomain, pPEAssembly),
+ m_pAssembly(NULL),
+ m_debuggerFlags(DACF_NONE),
+ m_fDebuggerUnloadStarted(FALSE),
+ m_fCollectible(pLoaderAllocator->IsCollectible()),
+ m_fHostAssemblyPublished(false),
+ m_pLoaderAllocator(pLoaderAllocator),
+ m_NextDomainAssemblyInSameALC(NULL)
+{
+ CONTRACTL
+ {
+ CONSTRUCTOR_CHECK;
+ STANDARD_VM_CHECK;
+ INJECT_FAULT(COMPlusThrowOM(););
+ }
+ CONTRACTL_END;
+
+ pPEAssembly->ValidateForExecution();
+
+ // !!! backout
+
+ m_hExposedAssemblyObject = NULL;
+
+ SetupDebuggingConfig();
+
+ // Add a Module iterator entry for this assembly.
+ IfFailThrow(m_Modules.Append(this));
+}
+
+DomainAssembly::~DomainAssembly()
+{
+ CONTRACTL
+ {
+ DESTRUCTOR_CHECK;
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_ANY;
+ INJECT_FAULT(COMPlusThrowOM(););
+ }
+ CONTRACTL_END;
+
+ if (m_fHostAssemblyPublished)
+ {
+ // Remove association first.
+ UnregisterFromHostAssembly();
+ }
+
+ ModuleIterator i = IterateModules(kModIterIncludeLoading);
+ while (i.Next())
+ {
+ if (i.GetDomainFile() != this)
+ delete i.GetDomainFile();
+ }
+
+ if (m_pAssembly != NULL)
+ {
+ delete m_pAssembly;
+ }
+}
+
void DomainAssembly::SetAssembly(Assembly* pAssembly)
{
STANDARD_VM_CONTRACT;
- _ASSERTE(pAssembly->GetModule()->GetPEAssembly()==m_pPEAssembly);
+ _ASSERTE(pAssembly->GetManifestModule()->GetPEAssembly()==m_pPEAssembly);
_ASSERTE(m_pAssembly == NULL);
m_pAssembly = pAssembly;
- m_pModule = pAssembly->GetModule();
+ m_pModule = pAssembly->GetManifestModule();
pAssembly->SetDomainAssembly(this);
}
@@ -724,7 +841,7 @@ OBJECTREF DomainAssembly::GetExposedAssemblyObject()
}
return pLoaderAllocator->GetHandleValue(m_hExposedAssemblyObject);
-}
+} // DomainAssembly::GetExposedAssemblyObject
void DomainAssembly::Begin()
{
@@ -800,7 +917,8 @@ void DomainAssembly::Allocate()
}
SetAssembly(pAssembly);
-}
+
+} // DomainAssembly::Allocate
void DomainAssembly::DeliverAsyncEvents()
{
@@ -815,8 +933,10 @@ void DomainAssembly::DeliverAsyncEvents()
OVERRIDE_LOAD_LEVEL_LIMIT(FILE_ACTIVE);
m_pDomain->RaiseLoadingAssemblyEvent(this);
+
}
+
void DomainAssembly::DeliverSyncEvents()
{
CONTRACTL
@@ -826,8 +946,17 @@ void DomainAssembly::DeliverSyncEvents()
}
CONTRACTL_END;
- GetModule()->NotifyEtwLoadFinished(S_OK);
+ GetCurrentModule()->NotifyEtwLoadFinished(S_OK);
+ // We may be notified from inside the loader lock if we are delivering IJW events, so keep track.
+#ifdef PROFILING_SUPPORTED
+ if (!IsProfilerNotified())
+ {
+ SetProfilerNotified();
+ GetCurrentModule()->NotifyProfilerLoadFinished(S_OK);
+ }
+
+#endif
#ifdef DEBUGGING_SUPPORTED
GCX_COOP();
if (!IsDebuggerNotified())
@@ -839,7 +968,7 @@ void DomainAssembly::DeliverSyncEvents()
}
#endif // DEBUGGING_SUPPORTED
-}
+} // DomainAssembly::DeliverSyncEvents
/*
// The enum for dwLocation from managed code:
@@ -1023,6 +1152,7 @@ BOOL DomainAssembly::NotifyDebuggerLoad(int flags, BOOL attaching)
}
// There is still work we need to do even when no debugger is attached.
+
if (flags & ATTACH_ASSEMBLY_LOAD)
{
if (ShouldNotifyDebugger())
@@ -1032,18 +1162,24 @@ BOOL DomainAssembly::NotifyDebuggerLoad(int flags, BOOL attaching)
result = TRUE;
}
- if(this->ShouldNotifyDebugger())
+ DomainModuleIterator i = IterateModules(kModIterIncludeLoading);
+ while (i.Next())
{
- result = result ||
- this->GetModule()->NotifyDebuggerLoad(this->GetAppDomain(), this, flags, attaching);
+ DomainFile * pDomainFile = i.GetDomainFile();
+ if(pDomainFile->ShouldNotifyDebugger())
+ {
+ result = result ||
+ pDomainFile->GetModule()->NotifyDebuggerLoad(this->GetAppDomain(), pDomainFile, flags, attaching);
+ }
}
-
if( ShouldNotifyDebugger())
{
result|=m_pModule->NotifyDebuggerLoad(m_pDomain, this, ATTACH_MODULE_LOAD, attaching);
SetDebuggerNotified();
}
+
+
return result;
}
@@ -1059,22 +1195,29 @@ void DomainAssembly::NotifyDebuggerUnload()
m_fDebuggerUnloadStarted = TRUE;
- // Dispatch module unload for the module. Debugger is resilient in case we haven't dispatched
+ // Dispatch module unloads for all modules. Debugger is resilient in case we haven't dispatched
// a previous load event (such as if debugger attached after the modules was loaded).
- this->GetModule()->NotifyDebuggerUnload(this->GetAppDomain());
+ DomainModuleIterator i = IterateModules(kModIterIncludeLoading);
+ while (i.Next())
+ {
+ i.GetDomainFile()->GetModule()->NotifyDebuggerUnload(this->GetAppDomain());
+ }
g_pDebugInterface->UnloadAssembly(this);
+
}
#endif // #ifndef DACCESS_COMPILE
#ifdef DACCESS_COMPILE
-void DomainAssembly::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
+void
+DomainFile::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
{
SUPPORTS_DAC;
- DAC_ENUM_DTHIS();
+ //sizeof(DomainFile) == 0x60
+ DAC_ENUM_VTHIS();
// Modules are needed for all minidumps, but they are enumerated elsewhere
// so we don't need to duplicate effort; thus we do noting with m_pModule.
@@ -1090,6 +1233,19 @@ void DomainAssembly::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
{
m_pDomain->EnumMemoryRegions(flags, true);
}
+}
+
+void
+DomainAssembly::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
+{
+ SUPPORTS_DAC;
+
+ //sizeof(DomainAssembly) == 0xe0
+ DAC_ENUM_VTHIS();
+ DomainFile::EnumMemoryRegions(flags);
+
+ // For minidumps without full memory, we need to always be able to iterate over m_Modules.
+ m_Modules.EnumMemoryRegions(flags);
if (flags != CLRDATA_ENUM_MEM_MINI && flags != CLRDATA_ENUM_MEM_TRIAGE)
{
diff --git a/src/coreclr/vm/domainassembly.h b/src/coreclr/vm/domainfile.h
similarity index 59%
rename from src/coreclr/vm/domainassembly.h
rename to src/coreclr/vm/domainfile.h
index 268c49654253c..917af193ceade 100644
--- a/src/coreclr/vm/domainassembly.h
+++ b/src/coreclr/vm/domainfile.h
@@ -1,14 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// --------------------------------------------------------------------------------
-// DomainAssembly.h
+// DomainFile.h
//
// --------------------------------------------------------------------------------
-#ifndef _DOMAINASSEMBLY_H_
-#define _DOMAINASSEMBLY_H_
+#ifndef _DOMAINFILE_H_
+#define _DOMAINFILE_H_
// --------------------------------------------------------------------------------
// Required headers
@@ -59,23 +59,27 @@ enum NotificationStatus
};
// --------------------------------------------------------------------------------
-// DomainAssembly represents an assembly loaded (or being loaded) into an app domain. It
+// DomainFile represents a file loaded (or being loaded) into an app domain. It
// is guranteed to be unique per file per app domain.
// --------------------------------------------------------------------------------
-class DomainAssembly final
+class DomainFile
{
-public:
+ VPTR_BASE_VTABLE_CLASS(DomainFile);
+
+ public:
// ------------------------------------------------------------
// Public API
// ------------------------------------------------------------
#ifndef DACCESS_COMPILE
- ~DomainAssembly();
- DomainAssembly() {LIMITED_METHOD_CONTRACT;};
+ virtual ~DomainFile();
+ DomainFile() {LIMITED_METHOD_CONTRACT;};
#endif
+ virtual LoaderAllocator *GetLoaderAllocator();
+
PTR_AppDomain GetAppDomain()
{
LIMITED_METHOD_CONTRACT;
@@ -89,41 +93,12 @@ class DomainAssembly final
return PTR_PEAssembly(m_pPEAssembly);
}
- Assembly* GetAssembly()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- CONSISTENCY_CHECK(CheckLoaded());
-
- return m_pAssembly;
- }
-
- Module* GetModule()
- {
- LIMITED_METHOD_CONTRACT;
- CONSISTENCY_CHECK(CheckLoaded());
-
- return m_pModule;
- }
-
IMDInternalImport *GetMDImport()
{
WRAPPER_NO_CONTRACT;
return m_pPEAssembly->GetMDImport();
}
- OBJECTREF GetExposedAssemblyObjectIfExists()
- {
- LIMITED_METHOD_CONTRACT;
-
- OBJECTREF objRet = NULL;
- GET_LOADERHANDLE_VALUE_FAST(GetLoaderAllocator(), m_hExposedAssemblyObject, &objRet);
- return objRet;
- }
-
- // Returns managed representation of the assembly (Assembly or AssemblyBuilder).
- // Returns NULL if the managed scout was already collected (see code:LoaderAllocator#AssemblyPhases).
- OBJECTREF GetExposedAssemblyObject();
-
OBJECTREF GetExposedModuleObjectIfExists()
{
LIMITED_METHOD_CONTRACT;
@@ -155,17 +130,9 @@ class DomainAssembly final
}
#endif
- BOOL IsCollectible()
- {
- LIMITED_METHOD_CONTRACT;
- return m_fCollectible;
- }
+ virtual BOOL IsAssembly() = 0;
- ULONG HashIdentity()
- {
- WRAPPER_NO_CONTRACT;
- return GetPEAssembly()->HashIdentity();
- }
+ DomainAssembly *GetDomainAssembly();
// ------------------------------------------------------------
// Loading state checks
@@ -235,6 +202,7 @@ class DomainAssembly final
return EnsureLoadLevel(FILE_LOAD_ALLOCATE);
}
+
void EnsureLibraryLoaded()
{
WRAPPER_NO_CONTRACT;
@@ -246,6 +214,10 @@ class DomainAssembly final
// is required for an operation. Note that deadlocks are tolerated so the level may be one
void EnsureLoadLevel(FileLoadLevel targetLevel) DAC_EMPTY();
+ // AttemptLoadLevel is a generic routine used to try to further load the file to a given level.
+ // No guarantee is made about the load level resulting however.
+ void AttemptLoadLevel(FileLoadLevel targetLevel) DAC_EMPTY();
+
// CheckLoadLevel is an assert predicate used to verify the load level of an assembly.
// deadlockOK indicates that the level is allowed to be one short if we are restricted
// by loader reentrancy.
@@ -273,12 +245,16 @@ class DomainAssembly final
// ------------------------------------------------------------
#ifndef DACCESS_COMPILE
- BOOL Equals(DomainAssembly *pAssembly) { WRAPPER_NO_CONTRACT; return GetPEAssembly()->Equals(pAssembly->GetPEAssembly()); }
+ BOOL Equals(DomainFile *pFile) { WRAPPER_NO_CONTRACT; return GetPEAssembly()->Equals(pFile->GetPEAssembly()); }
BOOL Equals(PEAssembly *pPEAssembly) { WRAPPER_NO_CONTRACT; return GetPEAssembly()->Equals(pPEAssembly); }
#endif // DACCESS_COMPILE
+ Module* GetCurrentModule();
+ Module* GetLoadedModule();
+ Module* GetModule();
+
#ifdef DACCESS_COMPILE
- void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
+ virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
#endif
#ifndef DACCESS_COMPILE
@@ -286,33 +262,7 @@ class DomainAssembly final
DynamicMethodTable* GetDynamicMethodTable();
#endif
- DomainAssembly* GetNextDomainAssemblyInSameALC()
- {
- return m_NextDomainAssemblyInSameALC;
- }
-
- void SetNextDomainAssemblyInSameALC(DomainAssembly* domainAssembly)
- {
- _ASSERTE(m_NextDomainAssemblyInSameALC == NULL);
- m_NextDomainAssemblyInSameALC = domainAssembly;
- }
-
- LoaderAllocator* GetLoaderAllocator()
- {
- LIMITED_METHOD_CONTRACT;
- return m_pLoaderAllocator;
- }
-
-// ------------------------------------------------------------
-// Resource access
-// ------------------------------------------------------------
-
- BOOL GetResource(LPCSTR szName, DWORD* cbResource,
- PBYTE* pbInMemoryResource, DomainAssembly** pAssemblyRef,
- LPCSTR* szFileName, DWORD* dwLocation,
- BOOL fSkipRaiseResolveEvent);
-
- private:
+ protected:
// ------------------------------------------------------------
// Loader API
// ------------------------------------------------------------
@@ -322,53 +272,59 @@ class DomainAssembly final
friend class Module;
friend class FileLoadLock;
- DomainAssembly(AppDomain* pDomain, PEAssembly* pPEAssembly, LoaderAllocator* pLoaderAllocator);
+ DomainFile(AppDomain *pDomain, PEAssembly *pPEAssembly);
BOOL DoIncrementalLoad(FileLoadLevel targetLevel);
void ClearLoading() { LIMITED_METHOD_CONTRACT; m_loading = FALSE; }
void SetLoadLevel(FileLoadLevel level) { LIMITED_METHOD_CONTRACT; m_level = level; }
#ifndef DACCESS_COMPILE
- void Begin();
- void Allocate();
+ virtual void Begin() = 0;
+ virtual void Allocate() = 0;
void AddDependencies();
void PreLoadLibrary();
void LoadLibrary();
- void PostLoadLibrary();
+ void PostLoadLibrary();
void EagerFixups();
void VtableFixups();
- void DeliverSyncEvents();
- void DeliverAsyncEvents();
+ virtual void DeliverSyncEvents() = 0;
+ virtual void DeliverAsyncEvents() = 0;
void FinishLoad();
void Activate();
-
- void RegisterWithHostAssembly();
- void UnregisterFromHostAssembly();
#endif
// This should be used to permanently set the load to fail. Do not use with transient conditions
void SetError(Exception *ex);
- void SetAssembly(Assembly* pAssembly);
void SetProfilerNotified() { LIMITED_METHOD_CONTRACT; m_notifyflags|= PROFILER_NOTIFIED; }
void SetDebuggerNotified() { LIMITED_METHOD_CONTRACT; m_notifyflags|=DEBUGGER_NOTIFIED; }
void SetShouldNotifyDebugger() { LIMITED_METHOD_CONTRACT; m_notifyflags|=DEBUGGER_NEEDNOTIFICATION; }
+ // ------------------------------------------------------------
+ // Instance data
+ // ------------------------------------------------------------
+
+ PTR_AppDomain m_pDomain;
+ PTR_PEAssembly m_pPEAssembly;
+ PTR_Module m_pModule;
+ FileLoadLevel m_level;
+ LOADERHANDLE m_hExposedModuleObject;
+
class ExInfo
{
enum
{
- ExType_ClrEx,
- ExType_HR
+ ExType_ClrEx,
+ ExType_HR
}
m_type;
union
{
- Exception* m_pEx;
- HRESULT m_hr;
+ Exception *m_pEx;
+ HRESULT m_hr;
};
- public:
+ public:
void Throw()
{
CONTRACTL
@@ -378,35 +334,209 @@ class DomainAssembly final
MODE_ANY;
}
CONTRACTL_END;
- if (m_type == ExType_ClrEx)
+ if (m_type==ExType_ClrEx)
{
- PAL_CPP_THROW(Exception*, m_pEx->DomainBoundClone());
+ PAL_CPP_THROW(Exception *, m_pEx->DomainBoundClone());
}
- if (m_type == ExType_HR)
+ if (m_type==ExType_HR)
ThrowHR(m_hr);
_ASSERTE(!"Bad exception type");
ThrowHR(E_UNEXPECTED);
};
-
ExInfo(Exception* pEx)
{
LIMITED_METHOD_CONTRACT;
- m_type = ExType_ClrEx;
- m_pEx = pEx;
+ m_type=ExType_ClrEx;
+ m_pEx=pEx;
};
+ void ConvertToHResult()
+ {
+ LIMITED_METHOD_CONTRACT;
+ if(m_type==ExType_HR)
+ return;
+ _ASSERTE(m_type==ExType_ClrEx);
+ HRESULT hr=m_pEx->GetHR();
+ delete m_pEx;
+ m_hr=hr;
+ m_type=ExType_HR;
+ };
~ExInfo()
{
LIMITED_METHOD_CONTRACT;
- if (m_type == ExType_ClrEx)
+ if (m_type==ExType_ClrEx)
delete m_pEx;
}
+ }* m_pError;
+
+ void ReleaseManagedData()
+ {
+ if (m_pError)
+ m_pError->ConvertToHResult();
};
+ DWORD m_notifyflags;
+ BOOL m_loading;
+ // m_pDynamicMethodTable is used by the light code generation to allow method
+ // generation on the fly. They are lazily created when/if a dynamic method is requested
+ // for this specific module
+ DynamicMethodTable *m_pDynamicMethodTable;
+ class UMThunkHash *m_pUMThunkHash;
+ BOOL m_bDisableActivationCheck;
+};
+
+//---------------------------------------------------------------------------------------
+// One of these values is specified when requesting a module iterator to customize which
+// modules should appear in the enumeration
+enum ModuleIterationOption
+{
+ // include only modules that are already loaded (m_level >= FILE_LOAD_DELIVER_EVENTS)
+ kModIterIncludeLoaded = 1,
+
+ // include all modules, even those that are still in the process of loading (all m_level values)
+ kModIterIncludeLoading = 2,
+
+ // include only modules loaded just enough that profilers are notified of them.
+ // (m_level >= FILE_LOAD_LOADLIBRARY). See comment at code:DomainFile::IsAvailableToProfilers
+ kModIterIncludeAvailableToProfilers = 3,
+};
+
+// --------------------------------------------------------------------------------
+// DomainAssembly is a subclass of DomainFile which specifically represents a assembly.
+// --------------------------------------------------------------------------------
+
+class DomainAssembly : public DomainFile
+{
+ VPTR_VTABLE_CLASS(DomainAssembly, DomainFile);
+
public:
-// ------------------------------------------------------------
-// Debugger control API
-// ------------------------------------------------------------
+ // ------------------------------------------------------------
+ // Public API
+ // ------------------------------------------------------------
+
+ LoaderAllocator *GetLoaderAllocator()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_pLoaderAllocator;
+ }
+
+ void SetAssembly(Assembly* pAssembly);
+
+ BOOL IsAssembly()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return TRUE;
+ }
+
+ OBJECTREF GetExposedAssemblyObjectIfExists()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ OBJECTREF objRet = NULL;
+ GET_LOADERHANDLE_VALUE_FAST(GetLoaderAllocator(), m_hExposedAssemblyObject, &objRet);
+ return objRet;
+ }
+
+ // Returns managed representation of the assembly (Assembly or AssemblyBuilder).
+ // Returns NULL if the managed scout was already collected (see code:LoaderAllocator#AssemblyPhases).
+ OBJECTREF GetExposedAssemblyObject();
+
+ Assembly* GetCurrentAssembly();
+ Assembly* GetLoadedAssembly();
+ Assembly* GetAssembly();
+
+#ifdef DACCESS_COMPILE
+ virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
+#endif
+
+ // ------------------------------------------------------------
+ // Modules
+ // ------------------------------------------------------------
+ class ModuleIterator
+ {
+ ArrayList::Iterator m_i;
+ ModuleIterationOption m_moduleIterationOption;
+
+ public:
+ BOOL Next()
+ {
+ WRAPPER_NO_CONTRACT;
+ while (m_i.Next())
+ {
+ if (m_i.GetElement() == NULL)
+ {
+ continue;
+ }
+ if (GetDomainFile()->IsError())
+ {
+ continue;
+ }
+ if (m_moduleIterationOption == kModIterIncludeLoading)
+ return TRUE;
+ if ((m_moduleIterationOption == kModIterIncludeLoaded) &&
+ GetDomainFile()->IsLoaded())
+ return TRUE;
+ if ((m_moduleIterationOption == kModIterIncludeAvailableToProfilers) &&
+ GetDomainFile()->IsAvailableToProfilers())
+ return TRUE;
+ }
+ return FALSE;
+ }
+ Module *GetModule()
+ {
+ WRAPPER_NO_CONTRACT;
+ return GetDomainFile()->GetModule();
+ }
+ Module *GetLoadedModule()
+ {
+ WRAPPER_NO_CONTRACT;
+ return GetDomainFile()->GetLoadedModule();
+ }
+ DomainFile *GetDomainFile()
+ {
+ WRAPPER_NO_CONTRACT;
+ return dac_cast(m_i.GetElement());
+ }
+ SIZE_T GetIndex()
+ {
+ WRAPPER_NO_CONTRACT;
+ return m_i.GetIndex();
+ }
+
+ private:
+ friend class DomainAssembly;
+ // Cannot have constructor so this iterator can be used inside a union
+ static ModuleIterator Create(DomainAssembly * pDomainAssembly, ModuleIterationOption moduleIterationOption)
+ {
+ WRAPPER_NO_CONTRACT;
+ ModuleIterator i;
+
+ i.m_i = pDomainAssembly->m_Modules.Iterate();
+ i.m_moduleIterationOption = moduleIterationOption;
+
+ return i;
+ }
+ };
+ friend class ModuleIterator;
+
+ ModuleIterator IterateModules(ModuleIterationOption moduleIterationOption)
+ {
+ WRAPPER_NO_CONTRACT;
+ return ModuleIterator::Create(this, moduleIterationOption);
+ }
+
+ // ------------------------------------------------------------
+ // Resource access
+ // ------------------------------------------------------------
+
+ BOOL GetResource(LPCSTR szName, DWORD *cbResource,
+ PBYTE *pbInMemoryResource, DomainAssembly** pAssemblyRef,
+ LPCSTR *szFileName, DWORD *dwLocation,
+ BOOL fSkipRaiseResolveEvent);
+
+ // ------------------------------------------------------------
+ // Debugger control API
+ // ------------------------------------------------------------
DebuggerAssemblyControlFlags GetDebuggerInfoBits(void)
{
@@ -423,46 +553,75 @@ class DomainAssembly final
void SetupDebuggingConfig(void);
DWORD ComputeDebuggingConfig(void);
- HRESULT GetDebuggingCustomAttributes(DWORD* pdwFlags);
+ HRESULT GetDebuggingCustomAttributes(DWORD *pdwFlags);
BOOL IsVisibleToDebugger();
BOOL NotifyDebuggerLoad(int flags, BOOL attaching);
void NotifyDebuggerUnload();
-private:
- // ------------------------------------------------------------
- // Instance data
- // ------------------------------------------------------------
+ inline BOOL IsCollectible();
- PTR_Assembly m_pAssembly;
- PTR_AppDomain m_pDomain;
- PTR_PEAssembly m_pPEAssembly;
- PTR_Module m_pModule;
- BOOL m_fCollectible;
- DomainAssembly* m_NextDomainAssemblyInSameALC;
- PTR_LoaderAllocator m_pLoaderAllocator;
+ private:
- FileLoadLevel m_level;
- BOOL m_loading;
+ // ------------------------------------------------------------
+ // Loader API
+ // ------------------------------------------------------------
- LOADERHANDLE m_hExposedModuleObject;
- LOADERHANDLE m_hExposedAssemblyObject;
+ friend class AppDomain;
+ friend class Assembly;
- ExInfo* m_pError;
+#ifndef DACCESS_COMPILE
+public:
+ ~DomainAssembly();
+private:
+ DomainAssembly(AppDomain *pDomain, PEAssembly *pPEAssembly, LoaderAllocator *pLoaderAllocator);
+#endif
- BOOL m_bDisableActivationCheck;
- BOOL m_fHostAssemblyPublished;
+ // ------------------------------------------------------------
+ // Internal routines
+ // ------------------------------------------------------------
- // m_pDynamicMethodTable is used by the light code generation to allow method
- // generation on the fly. They are lazily created when/if a dynamic method is requested
- // for this specific module
- DynamicMethodTable* m_pDynamicMethodTable;
+#ifndef DACCESS_COMPILE
+ void Begin();
+ void Allocate();
+ void DeliverSyncEvents();
+ void DeliverAsyncEvents();
+ void RegisterWithHostAssembly();
+ void UnregisterFromHostAssembly();
+#endif
+
+ public:
+ ULONG HashIdentity();
+ // ------------------------------------------------------------
+ // Instance data
+ // ------------------------------------------------------------
- DebuggerAssemblyControlFlags m_debuggerFlags;
- DWORD m_notifyflags;
- BOOL m_fDebuggerUnloadStarted;
+ private:
+ LOADERHANDLE m_hExposedAssemblyObject;
+ PTR_Assembly m_pAssembly;
+ DebuggerAssemblyControlFlags m_debuggerFlags;
+ ArrayList m_Modules;
+ BOOL m_fDebuggerUnloadStarted;
+ BOOL m_fCollectible;
+ Volatile m_fHostAssemblyPublished;
+ PTR_LoaderAllocator m_pLoaderAllocator;
+ DomainAssembly* m_NextDomainAssemblyInSameALC;
+
+ public:
+ DomainAssembly* GetNextDomainAssemblyInSameALC()
+ {
+ return m_NextDomainAssemblyInSameALC;
+ }
+
+ void SetNextDomainAssemblyInSameALC(DomainAssembly* domainAssembly)
+ {
+ _ASSERTE(m_NextDomainAssemblyInSameALC == NULL);
+ m_NextDomainAssemblyInSameALC = domainAssembly;
+ }
};
-#endif // _DOMAINASSEMBLY_H_
+typedef DomainAssembly::ModuleIterator DomainModuleIterator;
+
+#endif // _DOMAINFILE_H_
diff --git a/src/coreclr/vm/domainfile.inl b/src/coreclr/vm/domainfile.inl
new file mode 100644
index 0000000000000..a87d9aaef1309
--- /dev/null
+++ b/src/coreclr/vm/domainfile.inl
@@ -0,0 +1,72 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+//
+
+inline Module* DomainFile::GetCurrentModule()
+{
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ return m_pModule;
+}
+
+inline Module* DomainFile::GetLoadedModule()
+{
+ LIMITED_METHOD_CONTRACT;
+ CONSISTENCY_CHECK(CheckLoaded());
+
+ return m_pModule;
+}
+
+inline Module* DomainFile::GetModule()
+{
+ LIMITED_METHOD_CONTRACT;
+ SUPPORTS_DAC;
+
+ {
+ // While executing the consistency check, we will take a lock.
+ // But since this is debug-only, we'll allow the lock violation so that
+ // CANNOT_TAKE_LOCK callers aren't penalized
+ CONTRACT_VIOLATION(TakesLockViolation);
+ CONSISTENCY_CHECK(CheckLoadLevel(FILE_LOAD_ALLOCATE));
+ }
+
+ return m_pModule;
+}
+
+inline Assembly* DomainAssembly::GetCurrentAssembly()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return m_pAssembly;
+}
+
+inline Assembly* DomainAssembly::GetLoadedAssembly()
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+ CONSISTENCY_CHECK(CheckLoaded());
+
+ return m_pAssembly;
+}
+
+inline Assembly* DomainAssembly::GetAssembly()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ CONSISTENCY_CHECK(CheckLoadLevel(FILE_LOAD_ALLOCATE));
+ return m_pAssembly;
+}
+
+inline ULONG DomainAssembly::HashIdentity()
+{
+ WRAPPER_NO_CONTRACT;
+ return GetPEAssembly()->HashIdentity();
+}
+
+inline BOOL DomainAssembly::IsCollectible()
+{
+ LIMITED_METHOD_CONTRACT;
+ return m_fCollectible;
+}
+
diff --git a/src/coreclr/vm/dwbucketmanager.hpp b/src/coreclr/vm/dwbucketmanager.hpp
index 6eb0e9438b5f3..2524f706c7ef3 100644
--- a/src/coreclr/vm/dwbucketmanager.hpp
+++ b/src/coreclr/vm/dwbucketmanager.hpp
@@ -650,7 +650,7 @@ void BaseBucketParamsManager::GetModuleVersion(_Out_writes_(maxLength) WCHAR* ta
// if we failed to get a version and this isn't the manifest module then try that
if (!gotFileVersion && !pModule->IsManifest())
{
- pModule = pModule->GetAssembly()->GetModule();
+ pModule = pModule->GetAssembly()->GetManifestModule();
if (pModule)
gotFileVersion = GetFileVersionInfoForModule(pModule, major, minor, build, revision);
}
@@ -701,7 +701,7 @@ void BaseBucketParamsManager::GetModuleTimeStamp(_Out_writes_(maxLength) WCHAR*
{
// We only store the IL timestamp in the native image for the
// manifest module. We should consider fixing this for Orcas.
- PTR_PEAssembly pFile = pModule->GetAssembly()->GetModule()->GetPEAssembly();
+ PTR_PEAssembly pFile = pModule->GetAssembly()->GetManifestModule()->GetPEAssembly();
// for dynamic modules use 0 as the time stamp
ULONG ulTimeStamp = 0;
diff --git a/src/coreclr/vm/dwreport.cpp b/src/coreclr/vm/dwreport.cpp
index 47defdeedb5d0..1032725eb854b 100644
--- a/src/coreclr/vm/dwreport.cpp
+++ b/src/coreclr/vm/dwreport.cpp
@@ -17,7 +17,6 @@
#include "field.h"
#include
#include
-#include
#include "dbginterface.h"
#include
#include "dlwrap.h"
@@ -58,6 +57,14 @@ class SimpleModuleHolder
operator HMODULE() { return hModule; }
};
+#ifndef FEATURE_CORESYSTEM
+#define WER_MODULE_NAME_W WINDOWS_KERNEL32_DLLNAME_W
+typedef SimpleModuleHolder WerModuleHolder;
+#else
+#define WER_MODULE_NAME_W W("api-ms-win-core-windowserrorreporting-l1-1-0.dll")
+typedef SimpleModuleHolder WerModuleHolder;
+#endif
+
//------------------------------------------------------------------------------
// Description
// Indicate if Watson is enabled
@@ -100,17 +107,47 @@ BOOL RegisterOutOfProcessWatsonCallbacks()
CONTRACTL_END;
WCHAR wszDACName[] = MAIN_DAC_MODULE_NAME_W W(".dll");
+ WerModuleHolder hWerModule(WER_MODULE_NAME_W);
+
+#ifdef FEATURE_CORESYSTEM
+ if ((hWerModule == NULL) && !RunningOnWin8())
+ {
+ // If we are built for CoreSystemServer, but are running on Windows 7, we need to look elsewhere
+ hWerModule = WerModuleHolder(W("Kernel32.dll"));
+ }
+#endif
+
+ if (hWerModule == NULL)
+ {
+ _ASSERTE(!"failed to get WER module handle");
+ return FALSE;
+ }
+
+ typedef HRESULT (WINAPI * WerRegisterRuntimeExceptionModuleFnPtr)(PCWSTR, PDWORD);
+ WerRegisterRuntimeExceptionModuleFnPtr pFnWerRegisterRuntimeExceptionModule;
+
+ pFnWerRegisterRuntimeExceptionModule = (WerRegisterRuntimeExceptionModuleFnPtr)
+ GetProcAddress(hWerModule, "WerRegisterRuntimeExceptionModule");
+
+ _ASSERTE(pFnWerRegisterRuntimeExceptionModule != NULL);
+ if (pFnWerRegisterRuntimeExceptionModule == NULL)
+ {
+ return FALSE;
+ }
HRESULT hr = S_OK;
EX_TRY
{
PathString wszDACPath;
- hr = ::GetClrModuleDirectory(wszDACPath);
- if (SUCCEEDED(hr))
+ if (SUCCEEDED(::GetClrModuleDirectory(wszDACPath)))
{
wszDACPath.Append(wszDACName);
- hr = WerRegisterRuntimeExceptionModule(wszDACPath, (PDWORD)GetClrModuleBase());
+ hr = (*pFnWerRegisterRuntimeExceptionModule)(wszDACPath, (PDWORD)GetClrModuleBase());
+ }
+ else {
+ hr = E_FAIL;
}
+
}
EX_CATCH_HRESULT(hr);
@@ -119,7 +156,16 @@ BOOL RegisterOutOfProcessWatsonCallbacks()
STRESS_LOG0(LF_STARTUP,
LL_ERROR,
"WATSON support: failed to register DAC dll with WerRegisterRuntimeExceptionModule");
+
+#ifdef FEATURE_CORESYSTEM
+ // For CoreSys we *could* be running on a platform that doesn't have Watson proper
+ // (the APIs might exist but they just fail).
+ // WerRegisterRuntimeExceptionModule may return E_NOIMPL.
return TRUE;
+#else // FEATURE_CORESYSTEM
+ _ASSERTE(! "WATSON support: failed to register DAC dll with WerRegisterRuntimeExceptionModule");
+ return FALSE;
+#endif // FEATURE_CORESYSTEM
}
STRESS_LOG0(LF_STARTUP,
diff --git a/src/coreclr/vm/dynamicmethod.cpp b/src/coreclr/vm/dynamicmethod.cpp
index a5a9ee44ba8eb..35137855229e5 100644
--- a/src/coreclr/vm/dynamicmethod.cpp
+++ b/src/coreclr/vm/dynamicmethod.cpp
@@ -20,7 +20,7 @@
#ifndef DACCESS_COMPILE
// get the method table for dynamic methods
-DynamicMethodTable* DomainAssembly::GetDynamicMethodTable()
+DynamicMethodTable* DomainFile::GetDynamicMethodTable()
{
CONTRACT (DynamicMethodTable*)
{
diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h
index 08ab8e71c868a..be7a6826854f0 100644
--- a/src/coreclr/vm/ecalllist.h
+++ b/src/coreclr/vm/ecalllist.h
@@ -291,6 +291,12 @@ FCFuncStart(gAssemblyLoadContextFuncs)
FCFuncElement("IsTracingEnabled", AssemblyNative::IsTracingEnabled)
FCFuncEnd()
+FCFuncStart(gAssemblyNameFuncs)
+ FCFuncElement("nInit", AssemblyNameNative::Init)
+ FCFuncElement("ComputePublicKeyToken", AssemblyNameNative::GetPublicKeyToken)
+ FCFuncElement("nGetFileInformation", AssemblyNameNative::GetFileInformation)
+FCFuncEnd()
+
FCFuncStart(gAssemblyBuilderFuncs)
FCFuncElement("GetInMemoryAssemblyModule", AssemblyNative::GetInMemoryAssemblyModule)
FCFuncEnd()
@@ -316,6 +322,8 @@ FCFuncStart(gDelegateFuncs)
FCFuncEnd()
FCFuncStart(gMathFuncs)
+ FCFuncElementSig("Abs", &gsig_SM_Dbl_RetDbl, COMDouble::Abs)
+ FCFuncElementSig("Abs", &gsig_SM_Flt_RetFlt, COMSingle::Abs)
FCFuncElement("Acos", COMDouble::Acos)
FCFuncElement("Acosh", COMDouble::Acosh)
FCFuncElement("Asin", COMDouble::Asin)
@@ -764,6 +772,7 @@ FCClassElement("ArgIterator", "System", gVarArgFuncs)
FCClassElement("Array", "System", gArrayFuncs)
FCClassElement("AssemblyBuilder", "System.Reflection.Emit", gAssemblyBuilderFuncs)
FCClassElement("AssemblyLoadContext", "System.Runtime.Loader", gAssemblyLoadContextFuncs)
+FCClassElement("AssemblyName", "System.Reflection", gAssemblyNameFuncs)
FCClassElement("Buffer", "System", gBufferFuncs)
FCClassElement("CastHelpers", "System.Runtime.CompilerServices", gCastHelpers)
FCClassElement("CompatibilitySwitch", "System.Runtime.Versioning", gCompatibilitySwitchFuncs)
diff --git a/src/coreclr/vm/eventtrace.cpp b/src/coreclr/vm/eventtrace.cpp
index 3c5d8ded8c574..e5473b1104177 100644
--- a/src/coreclr/vm/eventtrace.cpp
+++ b/src/coreclr/vm/eventtrace.cpp
@@ -1380,7 +1380,7 @@ void BulkComLogger::AddCcwHandle(Object **handle)
-#include "domainassembly.h"
+#include "domainfile.h"
BulkStaticsLogger::BulkStaticsLogger(BulkTypeEventLogger *typeLogger)
: m_buffer(0), m_used(0), m_count(0), m_domain(0), m_typeLogger(typeLogger)
@@ -1524,64 +1524,69 @@ void BulkStaticsLogger::LogAllStatics()
continue;
CollectibleAssemblyHolder pAssembly = pDomainAssembly->GetAssembly();
- // Get the domain module from the module/appdomain pair.
- Module *module = pDomainAssembly->GetModule();
- if (module == NULL)
- continue;
-
- DomainAssembly *domainAssembly = module->GetDomainAssembly();
- if (domainAssembly == NULL)
- continue;
-
- // Ensure the module has fully loaded.
- if (!domainAssembly->IsActive())
- continue;
-
- DomainLocalModule *domainModule = module->GetDomainLocalModule();
- if (domainModule == NULL)
- continue;
+ DomainModuleIterator modIter = pDomainAssembly->IterateModules(kModIterIncludeLoaded);
- // Now iterate all types with
- LookupMap::Iterator mtIter = module->EnumerateTypeDefs();
- while (mtIter.Next())
+ while (modIter.Next())
{
- // I don't think mt can be null here, but the dac does a null check...
- // IsFullyLoaded should be equivalent to 'GetLoadLevel() == CLASS_LOADED'
- MethodTable *mt = mtIter.GetElement();
- if (mt == NULL || !mt->IsFullyLoaded())
+ // Get the domain module from the module/appdomain pair.
+ Module *module = modIter.GetModule();
+ if (module == NULL)
+ continue;
+
+ DomainFile *domainFile = module->GetDomainFile();
+ if (domainFile == NULL)
continue;
- EEClass *cls = mt->GetClass();
- _ASSERTE(cls != NULL);
+ // Ensure the module has fully loaded.
+ if (!domainFile->IsActive())
+ continue;
- if (cls->GetNumStaticFields() <= 0)
+ DomainLocalModule *domainModule = module->GetDomainLocalModule();
+ if (domainModule == NULL)
continue;
- ApproxFieldDescIterator fieldIter(mt, ApproxFieldDescIterator::STATIC_FIELDS);
- for (FieldDesc *field = fieldIter.Next(); field != NULL; field = fieldIter.Next())
+ // Now iterate all types with
+ LookupMap::Iterator mtIter = module->EnumerateTypeDefs();
+ while (mtIter.Next())
{
- // Don't want thread local
- _ASSERTE(field->IsStatic());
- if (field->IsSpecialStatic() || field->IsEnCNew())
+ // I don't think mt can be null here, but the dac does a null check...
+ // IsFullyLoaded should be equivalent to 'GetLoadLevel() == CLASS_LOADED'
+ MethodTable *mt = mtIter.GetElement();
+ if (mt == NULL || !mt->IsFullyLoaded())
continue;
- // Static valuetype values are boxed.
- CorElementType fieldType = field->GetFieldType();
- if (fieldType != ELEMENT_TYPE_CLASS && fieldType != ELEMENT_TYPE_VALUETYPE)
- continue;
+ EEClass *cls = mt->GetClass();
+ _ASSERTE(cls != NULL);
- BYTE *base = field->GetBaseInDomainLocalModule(domainModule);
- if (base == NULL)
+ if (cls->GetNumStaticFields() <= 0)
continue;
- Object **address = (Object**)field->GetStaticAddressHandle(base);
- Object *obj = NULL;
- if (address == NULL || ((obj = *address) == NULL))
- continue;
-
- WriteEntry(domain, address, *address, field);
- } // foreach static field
- }
+ ApproxFieldDescIterator fieldIter(mt, ApproxFieldDescIterator::STATIC_FIELDS);
+ for (FieldDesc *field = fieldIter.Next(); field != NULL; field = fieldIter.Next())
+ {
+ // Don't want thread local
+ _ASSERTE(field->IsStatic());
+ if (field->IsSpecialStatic() || field->IsEnCNew())
+ continue;
+
+ // Static valuetype values are boxed.
+ CorElementType fieldType = field->GetFieldType();
+ if (fieldType != ELEMENT_TYPE_CLASS && fieldType != ELEMENT_TYPE_VALUETYPE)
+ continue;
+
+ BYTE *base = field->GetBaseInDomainLocalModule(domainModule);
+ if (base == NULL)
+ continue;
+
+ Object **address = (Object**)field->GetStaticAddressHandle(base);
+ Object *obj = NULL;
+ if (address == NULL || ((obj = *address) == NULL))
+ continue;
+
+ WriteEntry(domain, address, *address, field);
+ } // foreach static field
+ }
+ } // foreach domain module
} // foreach domain assembly
} // foreach AppDomain
} // BulkStaticsLogger::LogAllStatics
@@ -6042,7 +6047,7 @@ VOID ETW::LoaderLog::SendAssemblyEvent(Assembly *pAssembly, DWORD dwEventOptions
PCWSTR szDtraceOutput1=W("");
BOOL bIsDynamicAssembly = pAssembly->IsDynamic();
BOOL bIsCollectibleAssembly = pAssembly->IsCollectible();
- BOOL bIsReadyToRun = pAssembly->GetPEAssembly()->IsReadyToRun();
+ BOOL bIsReadyToRun = pAssembly->GetManifestFile()->IsReadyToRun();
ULONGLONG ullAssemblyId = (ULONGLONG)pAssembly;
ULONGLONG ullDomainId = (ULONGLONG)pAssembly->GetDomain();
@@ -6333,7 +6338,7 @@ VOID ETW::LoaderLog::SendModuleEvent(Module *pModule, DWORD dwEventOptions, BOOL
if(!bIsDynamicAssembly)
{
- ModuleILPath = (PWCHAR)pModule->GetAssembly()->GetPEAssembly()->GetPEImage()->GetPath().GetUnicode();
+ ModuleILPath = (PWCHAR)pModule->GetAssembly()->GetManifestFile()->GetPEImage()->GetPath().GetUnicode();
ModuleNativePath = (PWCHAR)pEmptyString;
}
@@ -7241,14 +7246,18 @@ VOID ETW::EnumerationLog::IterateDomain(BaseDomain *pDomain, DWORD enumerationOp
CollectibleAssemblyHolder pDomainAssembly;
while (assemblyIterator.Next(pDomainAssembly.This()))
{
- CollectibleAssemblyHolder pAssembly = pDomainAssembly->GetAssembly();
+ CollectibleAssemblyHolder pAssembly = pDomainAssembly->GetLoadedAssembly();
if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCStart)
{
ETW::EnumerationLog::IterateAssembly(pAssembly, enumerationOptions);
}
- Module * pModule = pDomainAssembly->GetModule();
- ETW::EnumerationLog::IterateModule(pModule, enumerationOptions);
+ DomainModuleIterator domainModuleIterator = pDomainAssembly->IterateModules(kModIterIncludeLoaded);
+ while (domainModuleIterator.Next())
+ {
+ Module * pModule = domainModuleIterator.GetModule();
+ ETW::EnumerationLog::IterateModule(pModule, enumerationOptions);
+ }
if((enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleDCEnd) ||
(enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload))
@@ -7304,8 +7313,12 @@ VOID ETW::EnumerationLog::IterateCollectibleLoaderAllocator(AssemblyLoaderAlloca
{
Assembly *pAssembly = domainAssemblyIt->GetAssembly(); // TODO: handle iterator
- Module* pModule = domainAssemblyIt->GetModule();
- ETW::EnumerationLog::IterateModule(pModule, enumerationOptions);
+ DomainModuleIterator domainModuleIterator = domainAssemblyIt->IterateModules(kModIterIncludeLoaded);
+ while (domainModuleIterator.Next())
+ {
+ Module *pModule = domainModuleIterator.GetModule();
+ ETW::EnumerationLog::IterateModule(pModule, enumerationOptions);
+ }
if (enumerationOptions & ETW::EnumerationLog::EnumerationStructs::DomainAssemblyModuleUnload)
{
@@ -7349,8 +7362,11 @@ VOID ETW::EnumerationLog::IterateAssembly(Assembly *pAssembly, DWORD enumeration
{
if(pAssembly->GetDomain()->IsAppDomain())
{
- Module* pModule = pAssembly->GetDomainAssembly()->GetModule();
- ETW::LoaderLog::SendModuleEvent(pModule, enumerationOptions, TRUE);
+ DomainModuleIterator dmIterator = pAssembly->GetDomainAssembly()->IterateModules(kModIterIncludeLoaded);
+ while (dmIterator.Next())
+ {
+ ETW::LoaderLog::SendModuleEvent(dmIterator.GetModule(), enumerationOptions, TRUE);
+ }
}
}
diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp
index dd80bf37ec679..fa2b8ffc7dfe3 100644
--- a/src/coreclr/vm/excep.cpp
+++ b/src/coreclr/vm/excep.cpp
@@ -500,7 +500,7 @@ OBJECTREF PossiblyUnwrapThrowable(OBJECTREF throwable, Assembly *pAssembly)
// Check if we are required to compute the RuntimeWrapExceptions status.
BOOL fIsRuntimeWrappedException = ((throwable != NULL) && (throwable->GetMethodTable() == pMT_RuntimeWrappedException));
BOOL fRequiresComputingRuntimeWrapExceptionsStatus = (fIsRuntimeWrappedException &&
- (!(pAssembly->GetModule()->IsRuntimeWrapExceptionsStatusComputed())));
+ (!(pAssembly->GetManifestModule()->IsRuntimeWrapExceptionsStatusComputed())));
CONTRACTL
{
@@ -513,7 +513,7 @@ OBJECTREF PossiblyUnwrapThrowable(OBJECTREF throwable, Assembly *pAssembly)
}
CONTRACTL_END;
- if (fIsRuntimeWrappedException && (!pAssembly->GetModule()->IsRuntimeWrapExceptions()))
+ if (fIsRuntimeWrappedException && (!pAssembly->GetManifestModule()->IsRuntimeWrapExceptions()))
{
// We already created the instance, fetched the field. We know it is
// not marshal by ref, or any of the other cases that might trigger GC.
@@ -12136,8 +12136,8 @@ VOID CheckAndThrowSameTypeAndAssemblyInvalidCastException(TypeHandle thCastFrom,
_ASSERTE(pAssemblyTypeFrom != NULL);
_ASSERTE(pAssemblyTypeTo != NULL);
- PEAssembly *pPEAssemblyTypeFrom = pAssemblyTypeFrom->GetPEAssembly();
- PEAssembly *pPEAssemblyTypeTo = pAssemblyTypeTo->GetPEAssembly();
+ PEAssembly *pPEAssemblyTypeFrom = pAssemblyTypeFrom->GetManifestFile();
+ PEAssembly *pPEAssemblyTypeTo = pAssemblyTypeTo->GetManifestFile();
_ASSERTE(pPEAssemblyTypeFrom != NULL);
_ASSERTE(pPEAssemblyTypeTo != NULL);
diff --git a/src/coreclr/vm/field.cpp b/src/coreclr/vm/field.cpp
index 31d858814d020..a0e1260976dee 100644
--- a/src/coreclr/vm/field.cpp
+++ b/src/coreclr/vm/field.cpp
@@ -61,8 +61,6 @@ VOID FieldDesc::Init(mdFieldDef mb, CorElementType FieldType, DWORD dwMemberAttr
FieldType == ELEMENT_TYPE_R8 ||
FieldType == ELEMENT_TYPE_CLASS ||
FieldType == ELEMENT_TYPE_VALUETYPE ||
- FieldType == ELEMENT_TYPE_BYREF ||
- FieldType == ELEMENT_TYPE_TYPEDBYREF ||
FieldType == ELEMENT_TYPE_PTR ||
FieldType == ELEMENT_TYPE_FNPTR
);
@@ -72,8 +70,7 @@ VOID FieldDesc::Init(mdFieldDef mb, CorElementType FieldType, DWORD dwMemberAttr
m_requiresFullMbValue = 0;
SetMemberDef(mb);
- // A TypedByRef should be treated like a regular value type.
- m_type = FieldType != ELEMENT_TYPE_TYPEDBYREF ? FieldType : ELEMENT_TYPE_VALUETYPE;
+ m_type = FieldType;
m_prot = fdFieldAccessMask & dwMemberAttrs;
m_isStatic = fIsStatic != 0;
m_isRVA = fIsRVA != 0;
@@ -84,7 +81,7 @@ VOID FieldDesc::Init(mdFieldDef mb, CorElementType FieldType, DWORD dwMemberAttr
#endif
_ASSERTE(GetMemberDef() == mb); // no truncation
- _ASSERTE(GetFieldType() == FieldType || (FieldType == ELEMENT_TYPE_TYPEDBYREF && m_type == ELEMENT_TYPE_VALUETYPE));
+ _ASSERTE(GetFieldType() == FieldType);
_ASSERTE(GetFieldProtection() == (fdFieldAccessMask & dwMemberAttrs));
_ASSERTE((BOOL) IsStatic() == (fIsStatic != 0));
}
@@ -97,14 +94,6 @@ BOOL FieldDesc::IsObjRef()
return CorTypeInfo::IsObjRef_NoThrow(GetFieldType());
}
-// Return whether the field is a GC ref type
-BOOL FieldDesc::IsByRef()
-{
- WRAPPER_NO_CONTRACT;
- SUPPORTS_DAC;
- return CorTypeInfo::IsByRef_NoThrow(GetFieldType());
-}
-
BOOL FieldDesc::MightHaveName(ULONG nameHashValue)
{
LIMITED_METHOD_CONTRACT;
@@ -163,7 +152,6 @@ TypeHandle FieldDesc::LookupFieldTypeHandle(ClassLoadLevel level, BOOL dropGener
_ASSERTE(type == ELEMENT_TYPE_CLASS ||
type == ELEMENT_TYPE_VALUETYPE ||
type == ELEMENT_TYPE_STRING ||
- type == ELEMENT_TYPE_TYPEDBYREF ||
type == ELEMENT_TYPE_SZARRAY ||
type == ELEMENT_TYPE_VAR
);
diff --git a/src/coreclr/vm/field.h b/src/coreclr/vm/field.h
index 72378df259060..25e9e19fb7306 100644
--- a/src/coreclr/vm/field.h
+++ b/src/coreclr/vm/field.h
@@ -353,8 +353,6 @@ class FieldDesc
BOOL IsObjRef();
- BOOL IsByRef();
-
UINT LoadSize();
// Return -1 if the type isn't loaded yet (i.e. if LookupFieldTypeHandle() would return null)
diff --git a/src/coreclr/vm/frames.cpp b/src/coreclr/vm/frames.cpp
index 9377b4ec028b7..2f7a4d91c9ec4 100644
--- a/src/coreclr/vm/frames.cpp
+++ b/src/coreclr/vm/frames.cpp
@@ -63,12 +63,21 @@ void Frame::Log() {
MethodDesc* method = GetFunction();
+#ifdef TARGET_X86
+ if (GetVTablePtr() == UMThkCallFrame::GetMethodFrameVPtr())
+ method = ((UMThkCallFrame*) this)->GetUMEntryThunk()->GetMethod();
+#endif
+
STRESS_LOG3(LF_STUBS, LL_INFO1000000, "STUBS: In Stub with Frame %p assoc Method %pM FrameType = %pV\n", this, method, *((void**) this));
char buff[64];
const char* frameType;
if (GetVTablePtr() == PrestubMethodFrame::GetMethodFrameVPtr())
frameType = "PreStub";
+#ifdef TARGET_X86
+ else if (GetVTablePtr() == UMThkCallFrame::GetMethodFrameVPtr())
+ frameType = "UMThkCallFrame";
+#endif
else if (GetVTablePtr() == PInvokeCalliFrame::GetMethodFrameVPtr())
{
sprintf_s(buff, ARRAY_SIZE(buff), "PInvoke CALLI target" FMT_ADDR,
@@ -1594,6 +1603,32 @@ void ComMethodFrame::DoSecondPassHandlerCleanup(Frame * pCurFrame)
#endif // FEATURE_COMINTEROP
+
+#ifdef TARGET_X86
+
+PTR_UMEntryThunk UMThkCallFrame::GetUMEntryThunk()
+{
+ LIMITED_METHOD_DAC_CONTRACT;
+ return dac_cast(GetDatum());
+}
+
+#ifdef DACCESS_COMPILE
+void UMThkCallFrame::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
+{
+ WRAPPER_NO_CONTRACT;
+ UnmanagedToManagedFrame::EnumMemoryRegions(flags);
+
+ // Pieces of the UMEntryThunk need to be saved.
+ UMEntryThunk *pThunk = GetUMEntryThunk();
+ DacEnumMemoryRegion(dac_cast(pThunk), sizeof(UMEntryThunk));
+
+ UMThunkMarshInfo *pMarshInfo = pThunk->GetUMThunkMarshInfo();
+ DacEnumMemoryRegion(dac_cast(pMarshInfo), sizeof(UMThunkMarshInfo));
+}
+#endif
+
+#endif // TARGET_X86
+
#ifndef DACCESS_COMPILE
#if defined(_MSC_VER) && defined(TARGET_X86)
@@ -1917,18 +1952,16 @@ VOID InlinedCallFrame::Init()
}
-#ifdef FEATURE_COMINTEROP
+
void UnmanagedToManagedFrame::ExceptionUnwind()
{
WRAPPER_NO_CONTRACT;
AppDomain::ExceptionUnwind(this);
}
-#endif // FEATURE_COMINTEROP
#endif // !DACCESS_COMPILE
-#ifdef FEATURE_COMINTEROP
PCODE UnmanagedToManagedFrame::GetReturnAddress()
{
WRAPPER_NO_CONTRACT;
@@ -1947,7 +1980,6 @@ PCODE UnmanagedToManagedFrame::GetReturnAddress()
return pRetAddr;
}
}
-#endif // FEATURE_COMINTEROP
#ifndef DACCESS_COMPILE
//=================================================================================
diff --git a/src/coreclr/vm/frames.h b/src/coreclr/vm/frames.h
index 82e57cbbb0401..c2946ced0b2f6 100644
--- a/src/coreclr/vm/frames.h
+++ b/src/coreclr/vm/frames.h
@@ -90,18 +90,23 @@
// | |
// | +-TPMethodFrame - for calls on transparent proxy
// |
-#ifdef FEATURE_COMINTEROP
// +-UnmanagedToManagedFrame - this frame represents a transition from
// | | unmanaged code back to managed code. It's
// | | main functions are to stop COM+ exception
// | | propagation and to expose unmanaged parameters.
// | |
+#ifdef FEATURE_COMINTEROP
+// | |
// | +-ComMethodFrame - this frame represents a transition from
// | | com to com+
// | |
// | +-ComPrestubMethodFrame - prestub frame for calls from COM to CLR
// |
#endif //FEATURE_COMINTEROP
+#ifdef TARGET_X86
+// | +-UMThkCallFrame - this frame represents an unmanaged->managed
+// | transition through N/Direct
+#endif
#if defined(TARGET_X86) && !defined(UNIX_X86_ABI)
// +-TailCallFrame - padding for tailcalls
// |
@@ -167,9 +172,16 @@ Delegate over a native function pointer:
Reverse P/Invoke (used for C++ exports & fixups as well as delegates
obtained from function pointers):
Normal stub:
- The stub exists statically as UMThunkStub and calls to IL stub.
+ x86: The stub is generated by UMEntryThunk::CompileUMThunkWorker
+ (in DllImportCallback.cpp) and it is frameless. It calls directly
+ the managed target or to IL stub if marshaling is required.
+ non-x86: The stub exists statically as UMThunkStub and calls to IL stub.
Prestub:
- The prestub exists statically as TheUMEntryPrestub.
+ The prestub is generated by GenerateUMThunkPrestub (x86) or exists statically
+ as TheUMEntryPrestub (64-bit), and it erects an UMThkCallFrame frame.
+
+Reverse P/Invoke AppDomain selector stub:
+ The asm helper is IJWNOADThunkJumpTarget (in asmhelpers.asm) and it is frameless.
//------------------------------------------------------------------------
#endif // 0
@@ -200,8 +212,8 @@ FRAME_TYPE_NAME(HelperMethodFrame_3OBJ)
FRAME_TYPE_NAME(HelperMethodFrame_PROTECTOBJ)
FRAME_ABSTRACT_TYPE_NAME(FramedMethodFrame)
FRAME_TYPE_NAME(MulticastFrame)
-#ifdef FEATURE_COMINTEROP
FRAME_ABSTRACT_TYPE_NAME(UnmanagedToManagedFrame)
+#ifdef FEATURE_COMINTEROP
FRAME_TYPE_NAME(ComMethodFrame)
FRAME_TYPE_NAME(ComPlusMethodFrame)
FRAME_TYPE_NAME(ComPrestubMethodFrame)
@@ -226,6 +238,9 @@ FRAME_TYPE_NAME(DebuggerClassInitMarkFrame)
FRAME_TYPE_NAME(DebuggerSecurityCodeMarkFrame)
FRAME_TYPE_NAME(DebuggerExitFrame)
FRAME_TYPE_NAME(DebuggerU2MCatchHandlerFrame)
+#ifdef TARGET_X86
+FRAME_TYPE_NAME(UMThkCallFrame)
+#endif
FRAME_TYPE_NAME(InlinedCallFrame)
#if defined(TARGET_X86) && !defined(UNIX_X86_ABI)
FRAME_TYPE_NAME(TailCallFrame)
@@ -266,6 +281,9 @@ class Frame;
class FramedMethodFrame;
typedef VPTR(class FramedMethodFrame) PTR_FramedMethodFrame;
struct HijackArgs;
+class UMEntryThunk;
+class UMThunkMarshInfo;
+class Marshaler;
struct ResolveCacheElem;
#if defined(DACCESS_COMPILE)
class DacDbiInterfaceImpl;
@@ -1796,8 +1814,6 @@ class MulticastFrame : public TransitionFrame
};
-#ifdef FEATURE_COMINTEROP
-
//-----------------------------------------------------------------------
// Transition frame from unmanaged to managed
//-----------------------------------------------------------------------
@@ -1906,6 +1922,8 @@ class UnmanagedToManagedFrame : public Frame
#endif
};
+#ifdef FEATURE_COMINTEROP
+
//------------------------------------------------------------------------
// This frame represents a transition from COM to COM+
//------------------------------------------------------------------------
@@ -2756,6 +2774,43 @@ class DebuggerU2MCatchHandlerFrame : public Frame
DEFINE_VTABLE_GETTER_AND_DTOR(DebuggerU2MCatchHandlerFrame)
};
+
+class UMThunkMarshInfo;
+typedef DPTR(class UMThunkMarshInfo) PTR_UMThunkMarshInfo;
+
+class UMEntryThunk;
+typedef DPTR(class UMEntryThunk) PTR_UMEntryThunk;
+
+#if defined(TARGET_X86)
+//------------------------------------------------------------------------
+// This frame guards an unmanaged->managed transition thru a UMThk
+//------------------------------------------------------------------------
+
+class UMThkCallFrame : public UnmanagedToManagedFrame
+{
+ VPTR_VTABLE_CLASS(UMThkCallFrame, UnmanagedToManagedFrame)
+
+public:
+
+#ifdef DACCESS_COMPILE
+ virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
+#endif
+
+ PTR_UMEntryThunk GetUMEntryThunk();
+
+ static int GetOffsetOfUMEntryThunk()
+ {
+ WRAPPER_NO_CONTRACT;
+ return GetOffsetOfDatum();
+ }
+
+protected:
+
+ // Keep as last entry in class
+ DEFINE_VTABLE_GETTER_AND_CTOR_AND_DTOR(UMThkCallFrame)
+};
+#endif // TARGET_X86 && !TARGET_UNIX
+
// Frame for the Reverse PInvoke (i.e. UnmanagedCallersOnlyAttribute).
struct ReversePInvokeFrame
{
@@ -2766,6 +2821,29 @@ struct ReversePInvokeFrame
#endif
};
+#if defined(TARGET_X86) && defined(FEATURE_COMINTEROP)
+//-------------------------------------------------------------------------
+// Exception handler for COM to managed frame
+// and the layout of the exception registration record structure in the stack
+// the layout is similar to the NT's EXCEPTIONREGISTRATION record
+// followed by the UnmanagedToManagedFrame specific info
+
+struct ComToManagedExRecord
+{
+ EXCEPTION_REGISTRATION_RECORD m_ExReg;
+ ArgumentRegisters m_argRegs;
+ GSCookie m_gsCookie;
+ UMThkCallFrame m_frame;
+
+ UnmanagedToManagedFrame * GetCurrFrame()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return &m_frame;
+ }
+};
+#endif // TARGET_X86 && FEATURE_COMINTEROP
+
+
//------------------------------------------------------------------------
// This frame is pushed by any JIT'ted method that contains one or more
// inlined N/Direct calls. Note that the JIT'ted method keeps it pushed
diff --git a/src/coreclr/vm/i386/asmhelpers.asm b/src/coreclr/vm/i386/asmhelpers.asm
index 896c249822c55..d3eb78da47256 100644
--- a/src/coreclr/vm/i386/asmhelpers.asm
+++ b/src/coreclr/vm/i386/asmhelpers.asm
@@ -43,6 +43,7 @@ EXTERN _COMPlusFrameHandlerRevCom:PROC
endif ; FEATURE_COMINTEROP
EXTERN __alloca_probe:PROC
EXTERN _NDirectImportWorker@4:PROC
+EXTERN _UMThunkStubRareDisableWorker@8:PROC
EXTERN _VarargPInvokeStubWorker@12:PROC
EXTERN _GenericPInvokeCalliStubWorker@12:PROC
@@ -52,7 +53,6 @@ EXTERN _CopyCtorCallStubWorker@4:PROC
endif
EXTERN _PreStubWorker@8:PROC
-EXTERN _TheUMEntryPrestubWorker@4:PROC
ifdef FEATURE_COMINTEROP
EXTERN _CLRToCOMWorker@8:PROC
@@ -255,6 +255,9 @@ COMPlusNestedExceptionHandler proto c
FastNExportExceptHandler proto c
.safeseh FastNExportExceptHandler
+UMThunkPrestubHandler proto c
+.safeseh UMThunkPrestubHandler
+
ifdef FEATURE_COMINTEROP
COMPlusFrameHandlerRevCom proto c
.safeseh COMPlusFrameHandlerRevCom
@@ -869,6 +872,23 @@ getFPReturn4:
retn 8
_getFPReturn@8 endp
+; VOID __cdecl UMThunkStubRareDisable()
+;
+; @todo: this is very similar to StubRareDisable
+;
+_UMThunkStubRareDisable proc public
+ push eax
+ push ecx
+
+ push eax ; Push the UMEntryThunk
+ push ecx ; Push thread
+ call _UMThunkStubRareDisableWorker@8
+
+ pop ecx
+ pop eax
+ retn
+_UMThunkStubRareDisable endp
+
; void __stdcall JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
_JIT_ProfilerEnterLeaveTailcallStub@4 proc public
@@ -1412,22 +1432,6 @@ public _ThePreStubPatchLabel@0
ret
_ThePreStubPatch@0 endp
-_TheUMEntryPrestub@0 proc public
- ; push argument registers
- push ecx
- push edx
-
- push eax ; UMEntryThunk*
- call _TheUMEntryPrestubWorker@4
-
- ; pop argument registers
- pop edx
- pop ecx
-
- ; eax = PCODE
- jmp eax ; Tail Jmp
-_TheUMEntryPrestub@0 endp
-
ifdef FEATURE_COMINTEROP
;==========================================================================
; CLR -> COM generic or late-bound call
diff --git a/src/coreclr/vm/i386/cgenx86.cpp b/src/coreclr/vm/i386/cgenx86.cpp
index d2d5d1676e95c..f0a81d6daeea1 100644
--- a/src/coreclr/vm/i386/cgenx86.cpp
+++ b/src/coreclr/vm/i386/cgenx86.cpp
@@ -931,6 +931,58 @@ WORD GetUnpatchedCodeData(LPCBYTE pAddr)
#ifndef DACCESS_COMPILE
+#if defined(TARGET_X86) && !defined(FEATURE_STUBS_AS_IL)
+//-------------------------------------------------------------------------
+// One-time creation of special prestub to initialize UMEntryThunks.
+//-------------------------------------------------------------------------
+Stub *GenerateUMThunkPrestub()
+{
+ CONTRACT(Stub*)
+ {
+ STANDARD_VM_CHECK;
+ POSTCONDITION(CheckPointer(RETVAL));
+ }
+ CONTRACT_END;
+
+ CPUSTUBLINKER sl;
+ CPUSTUBLINKER *psl = &sl;
+
+ CodeLabel* rgRareLabels[] = { psl->NewCodeLabel(),
+ psl->NewCodeLabel(),
+ psl->NewCodeLabel()
+ };
+
+
+ CodeLabel* rgRejoinLabels[] = { psl->NewCodeLabel(),
+ psl->NewCodeLabel(),
+ psl->NewCodeLabel()
+ };
+
+ // emit the initial prolog
+ psl->EmitComMethodStubProlog(UMThkCallFrame::GetMethodFrameVPtr(), rgRareLabels, rgRejoinLabels, FALSE /*Don't profile*/);
+
+ // mov ecx, [esi+UMThkCallFrame.pUMEntryThunk]
+ psl->X86EmitIndexRegLoad(kECX, kESI, UMThkCallFrame::GetOffsetOfUMEntryThunk());
+
+ // The call conv is a __stdcall
+ psl->X86EmitPushReg(kECX);
+
+ // call UMEntryThunk::DoRunTimeInit
+ psl->X86EmitCall(psl->NewExternalCodeLabel((LPVOID)UMEntryThunk::DoRunTimeInit), 4);
+
+ // mov ecx, [esi+UMThkCallFrame.pUMEntryThunk]
+ psl->X86EmitIndexRegLoad(kEAX, kESI, UMThkCallFrame::GetOffsetOfUMEntryThunk());
+
+ // lea eax, [eax + UMEntryThunk.m_code] // point to fixedup UMEntryThunk
+ psl->X86EmitOp(0x8d, kEAX, kEAX,
+ UMEntryThunk::GetCodeOffset() + UMEntryThunkCode::GetEntryPointOffset());
+
+ psl->EmitComMethodStubEpilog(UMThkCallFrame::GetMethodFrameVPtr(), rgRareLabels, rgRejoinLabels, FALSE /*Don't profile*/);
+
+ RETURN psl->Link(SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap());
+}
+#endif // TARGET_X86 && !FEATURE_STUBS_AS_IL
+
Stub *GenerateInitPInvokeFrameHelper()
{
CONTRACT(Stub*)
diff --git a/src/coreclr/vm/i386/excepx86.cpp b/src/coreclr/vm/i386/excepx86.cpp
index 15dd0667dd6c4..3d2e0e4dddeca 100644
--- a/src/coreclr/vm/i386/excepx86.cpp
+++ b/src/coreclr/vm/i386/excepx86.cpp
@@ -113,6 +113,17 @@ static void RtlUnwindCallback()
_ASSERTE(!"Should never get here");
}
+BOOL NExportSEH(EXCEPTION_REGISTRATION_RECORD* pEHR)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ if ((LPVOID)pEHR->Handler == (LPVOID)UMThunkPrestubHandler)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
BOOL FastNExportSEH(EXCEPTION_REGISTRATION_RECORD* pEHR)
{
LIMITED_METHOD_CONTRACT;
@@ -145,8 +156,9 @@ BOOL IsUnmanagedToManagedSEHHandler(EXCEPTION_REGISTRATION_RECORD *pEstablisherF
//
// ComPlusFrameSEH() is for COMPlusFrameHandler & COMPlusNestedExceptionHandler.
// FastNExportSEH() is for FastNExportExceptHandler.
+ // NExportSEH() is for UMThunkPrestubHandler.
//
- return (ComPlusFrameSEH(pEstablisherFrame) || FastNExportSEH(pEstablisherFrame) || ReverseCOMSEH(pEstablisherFrame));
+ return (ComPlusFrameSEH(pEstablisherFrame) || FastNExportSEH(pEstablisherFrame) || NExportSEH(pEstablisherFrame) || ReverseCOMSEH(pEstablisherFrame));
}
Frame *GetCurrFrame(EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame)
@@ -154,7 +166,10 @@ Frame *GetCurrFrame(EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame)
Frame *pFrame;
WRAPPER_NO_CONTRACT;
_ASSERTE(IsUnmanagedToManagedSEHHandler(pEstablisherFrame));
- pFrame = ((FrameHandlerExRecord *)pEstablisherFrame)->GetCurrFrame();
+ if (NExportSEH(pEstablisherFrame))
+ pFrame = ((ComToManagedExRecord *)pEstablisherFrame)->GetCurrFrame();
+ else
+ pFrame = ((FrameHandlerExRecord *)pEstablisherFrame)->GetCurrFrame();
// Assert that the exception frame is on the thread or that the exception frame is the top frame.
_ASSERTE(GetThreadNULLOk() == NULL || GetThread()->GetFrame() == (Frame*)-1 || GetThread()->GetFrame() <= pFrame);
@@ -3369,6 +3384,52 @@ EXCEPTION_HANDLER_IMPL(FastNExportExceptHandler)
return retval;
}
+
+// Just like a regular NExport handler -- except it pops an extra frame on unwind. A handler
+// like this is needed by the COMMethodStubProlog code. It first pushes a frame -- and then
+// pushes a handler. When we unwind, we need to pop the extra frame to avoid corrupting the
+// frame chain in the event of an unmanaged catcher.
+//
+EXCEPTION_HANDLER_IMPL(UMThunkPrestubHandler)
+{
+ // @todo: we'd like to have a dynamic contract here, but there's a problem. (Bug 129180) Enter on the CRST used
+ // in HandleManagedFault leaves the no-trigger count incremented. The destructor of this contract will restore
+ // it to zero, then when we leave the CRST in LinkFrameAndThrow, we assert because we're trying to decrement the
+ // gc-trigger count down past zero. The solution is to fix what we're doing with this CRST.
+ STATIC_CONTRACT_THROWS; // COMPlusFrameHandler throws
+ STATIC_CONTRACT_GC_TRIGGERS;
+ STATIC_CONTRACT_MODE_ANY;
+
+ EXCEPTION_DISPOSITION retval = ExceptionContinueSearch;
+
+ // We must forward to the COMPlusFrameHandler. This will unwind the Frame Chain up to here, and also leave the
+ // preemptive GC mode set correctly.
+ retval = EXCEPTION_HANDLER_FWD(COMPlusFrameHandler);
+
+#ifdef _DEBUG
+ // If the exception is escaping the last CLR personality routine on the stack,
+ // then state a flag on the thread to indicate so.
+ if (retval == ExceptionContinueSearch)
+ {
+ SetReversePInvokeEscapingUnhandledExceptionStatus(IS_UNWINDING(pExceptionRecord->ExceptionFlags), pEstablisherFrame);
+ }
+#endif // _DEBUG
+
+ if (IS_UNWINDING(pExceptionRecord->ExceptionFlags))
+ {
+ // Pops an extra frame on unwind.
+
+ GCX_COOP(); // Must be cooperative to modify frame chain.
+
+ Thread *pThread = GetThread();
+ Frame *pFrame = pThread->GetFrame();
+ pFrame->ExceptionUnwind();
+ pFrame->Pop(pThread);
+ }
+
+ return retval;
+}
+
#ifdef FEATURE_COMINTEROP
// The reverse COM interop path needs to be sure to pop the ComMethodFrame that is pushed, but we do not want
// to have an additional FS:0 handler between the COM callsite and the call into managed. So we push this
diff --git a/src/coreclr/vm/i386/stublinkerx86.cpp b/src/coreclr/vm/i386/stublinkerx86.cpp
index 74d55fd4544db..3f4a7ed531273 100644
--- a/src/coreclr/vm/i386/stublinkerx86.cpp
+++ b/src/coreclr/vm/i386/stublinkerx86.cpp
@@ -2445,21 +2445,44 @@ VOID StubLinkerCPU::X86EmitCurrentThreadFetch(X86Reg dstreg, unsigned preservedR
#endif // TARGET_UNIX
}
-#if defined(FEATURE_COMINTEROP) && defined(TARGET_X86)
+#if defined(TARGET_X86)
-#if defined(PROFILING_SUPPORTED)
+#if defined(PROFILING_SUPPORTED) && !defined(FEATURE_STUBS_AS_IL)
VOID StubLinkerCPU::EmitProfilerComCallProlog(TADDR pFrameVptr, X86Reg regFrame)
{
STANDARD_VM_CONTRACT;
- // Load the methoddesc into ECX (Frame->m_pvDatum->m_pMD)
- X86EmitIndexRegLoad(kECX, regFrame, ComMethodFrame::GetOffsetOfDatum());
- X86EmitIndexRegLoad(kECX, kECX, ComCallMethodDesc::GetOffsetOfMethodDesc());
+ if (pFrameVptr == UMThkCallFrame::GetMethodFrameVPtr())
+ {
+ // Load the methoddesc into ECX (UMThkCallFrame->m_pvDatum->m_pMD)
+ X86EmitIndexRegLoad(kECX, regFrame, UMThkCallFrame::GetOffsetOfDatum());
+ X86EmitIndexRegLoad(kECX, kECX, UMEntryThunk::GetOffsetOfMethodDesc());
+
+ // Push arguments and notify profiler
+ X86EmitPushImm32(COR_PRF_TRANSITION_CALL); // Reason
+ X86EmitPushReg(kECX); // MethodDesc*
+ X86EmitCall(NewExternalCodeLabel((LPVOID) ProfilerUnmanagedToManagedTransitionMD), 2*sizeof(void*));
+ }
+
+#ifdef FEATURE_COMINTEROP
+ else if (pFrameVptr == ComMethodFrame::GetMethodFrameVPtr())
+ {
+ // Load the methoddesc into ECX (Frame->m_pvDatum->m_pMD)
+ X86EmitIndexRegLoad(kECX, regFrame, ComMethodFrame::GetOffsetOfDatum());
+ X86EmitIndexRegLoad(kECX, kECX, ComCallMethodDesc::GetOffsetOfMethodDesc());
+
+ // Push arguments and notify profiler
+ X86EmitPushImm32(COR_PRF_TRANSITION_CALL); // Reason
+ X86EmitPushReg(kECX); // MethodDesc*
+ X86EmitCall(NewExternalCodeLabel((LPVOID) ProfilerUnmanagedToManagedTransitionMD), 2*sizeof(void*));
+ }
+#endif // FEATURE_COMINTEROP
- // Push arguments and notify profiler
- X86EmitPushImm32(COR_PRF_TRANSITION_CALL); // Reason
- X86EmitPushReg(kECX); // MethodDesc*
- X86EmitCall(NewExternalCodeLabel((LPVOID) ProfilerUnmanagedToManagedTransitionMD), 2*sizeof(void*));
+ // Unrecognized frame vtbl
+ else
+ {
+ _ASSERTE(!"Unrecognized vtble passed to EmitComMethodStubProlog with profiling turned on.");
+ }
}
@@ -2468,21 +2491,50 @@ VOID StubLinkerCPU::EmitProfilerComCallEpilog(TADDR pFrameVptr, X86Reg regFrame)
CONTRACTL
{
STANDARD_VM_CHECK;
- PRECONDITION(pFrameVptr == ComMethodFrame::GetMethodFrameVPtr());
+#ifdef FEATURE_COMINTEROP
+ PRECONDITION(pFrameVptr == UMThkCallFrame::GetMethodFrameVPtr() || pFrameVptr == ComMethodFrame::GetMethodFrameVPtr());
+#else
+ PRECONDITION(pFrameVptr == UMThkCallFrame::GetMethodFrameVPtr());
+#endif // FEATURE_COMINTEROP
}
CONTRACTL_END;
- // Load the methoddesc into ECX (Frame->m_pvDatum->m_pMD)
- X86EmitIndexRegLoad(kECX, regFrame, ComMethodFrame::GetOffsetOfDatum());
- X86EmitIndexRegLoad(kECX, kECX, ComCallMethodDesc::GetOffsetOfMethodDesc());
+ if (pFrameVptr == UMThkCallFrame::GetMethodFrameVPtr())
+ {
+ // Load the methoddesc into ECX (UMThkCallFrame->m_pvDatum->m_pMD)
+ X86EmitIndexRegLoad(kECX, regFrame, UMThkCallFrame::GetOffsetOfDatum());
+ X86EmitIndexRegLoad(kECX, kECX, UMEntryThunk::GetOffsetOfMethodDesc());
+
+ // Push arguments and notify profiler
+ X86EmitPushImm32(COR_PRF_TRANSITION_RETURN); // Reason
+ X86EmitPushReg(kECX); // MethodDesc*
+ X86EmitCall(NewExternalCodeLabel((LPVOID) ProfilerManagedToUnmanagedTransitionMD), 2*sizeof(void*));
+ }
+
+#ifdef FEATURE_COMINTEROP
+ else if (pFrameVptr == ComMethodFrame::GetMethodFrameVPtr())
+ {
+ // Load the methoddesc into ECX (Frame->m_pvDatum->m_pMD)
+ X86EmitIndexRegLoad(kECX, regFrame, ComMethodFrame::GetOffsetOfDatum());
+ X86EmitIndexRegLoad(kECX, kECX, ComCallMethodDesc::GetOffsetOfMethodDesc());
+
+ // Push arguments and notify profiler
+ X86EmitPushImm32(COR_PRF_TRANSITION_RETURN); // Reason
+ X86EmitPushReg(kECX); // MethodDesc*
+ X86EmitCall(NewExternalCodeLabel((LPVOID) ProfilerManagedToUnmanagedTransitionMD), 2*sizeof(void*));
+ }
+#endif // FEATURE_COMINTEROP
- // Push arguments and notify profiler
- X86EmitPushImm32(COR_PRF_TRANSITION_RETURN); // Reason
- X86EmitPushReg(kECX); // MethodDesc*
- X86EmitCall(NewExternalCodeLabel((LPVOID) ProfilerManagedToUnmanagedTransitionMD), 2*sizeof(void*));
+ // Unrecognized frame vtbl
+ else
+ {
+ _ASSERTE(!"Unrecognized vtble passed to EmitComMethodStubEpilog with profiling turned on.");
+ }
}
-#endif // PROFILING_SUPPORTED
+#endif // PROFILING_SUPPORTED && !FEATURE_STUBS_AS_IL
+
+#ifndef FEATURE_STUBS_AS_IL
//========================================================================
// Prolog for entering managed code from COM
// pushes the appropriate frame ptr
@@ -2532,6 +2584,13 @@ void StubLinkerCPU::EmitComMethodStubProlog(TADDR pFrameVptr,
// lea esi, [esp+4] ;; set ESI -> new frame
X86EmitEspOffset(0x8d, kESI, 4); // lea ESI, [ESP+4]
+ if (pFrameVptr == UMThkCallFrame::GetMethodFrameVPtr())
+ {
+ // Preserve argument registers for thiscall/fastcall
+ X86EmitPushReg(kECX);
+ X86EmitPushReg(kEDX);
+ }
+
// Emit Setup thread
EmitSetup(rgRareLabels[0]); // rareLabel for rare setup
EmitLabel(rgRejoinLabels[0]); // rejoin label for rare setup
@@ -2580,6 +2639,23 @@ void StubLinkerCPU::EmitComMethodStubProlog(TADDR pFrameVptr,
// mov [ebx + Thread.GetFrame()], esi
X86EmitIndexRegStore(kEBX, Thread::GetOffsetOfCurrentFrame(), kESI);
+ if (pFrameVptr == UMThkCallFrame::GetMethodFrameVPtr())
+ {
+ // push UnmanagedToManagedExceptHandler
+ X86EmitPushImmPtr((LPVOID)UMThunkPrestubHandler);
+
+ // mov eax, fs:[0]
+ static const BYTE codeSEH1[] = { 0x64, 0xA1, 0x0, 0x0, 0x0, 0x0};
+ EmitBytes(codeSEH1, sizeof(codeSEH1));
+
+ // push eax
+ X86EmitPushReg(kEAX);
+
+ // mov dword ptr fs:[0], esp
+ static const BYTE codeSEH2[] = { 0x64, 0x89, 0x25, 0x0, 0x0, 0x0, 0x0};
+ EmitBytes(codeSEH2, sizeof(codeSEH2));
+ }
+
#if _DEBUG
if (Frame::ShouldLogTransitions())
{
@@ -2616,6 +2692,19 @@ void StubLinkerCPU::EmitComMethodStubEpilog(TADDR pFrameVptr,
EmitCheckGSCookie(kESI, UnmanagedToManagedFrame::GetOffsetOfGSCookie());
+ if (pFrameVptr == UMThkCallFrame::GetMethodFrameVPtr())
+ {
+ // if we are using exceptions, unlink the SEH
+ // mov ecx,[esp] ;;pointer to the next exception record
+ X86EmitEspOffset(0x8b, kECX, 0);
+
+ // mov dword ptr fs:[0], ecx
+ static const BYTE codeSEH[] = { 0x64, 0x89, 0x0D, 0x0, 0x0, 0x0, 0x0 };
+ EmitBytes(codeSEH, sizeof(codeSEH));
+
+ X86EmitAddEsp(sizeof(EXCEPTION_REGISTRATION_RECORD));
+ }
+
// mov [ebx + Thread.GetFrame()], edi ;; restore previous frame
X86EmitIndexRegStore(kEBX, Thread::GetOffsetOfCurrentFrame(), kEDI);
@@ -2625,6 +2714,13 @@ void StubLinkerCPU::EmitComMethodStubEpilog(TADDR pFrameVptr,
EmitEnable(rgRareLabels[2]); // rare gc
EmitLabel(rgRejoinLabels[2]); // rejoin for rare gc
+ if (pFrameVptr == UMThkCallFrame::GetMethodFrameVPtr())
+ {
+ // Restore argument registers for thiscall/fastcall
+ X86EmitPopReg(kEDX);
+ X86EmitPopReg(kECX);
+ }
+
// add esp, popstack
X86EmitAddEsp(sizeof(GSCookie) + UnmanagedToManagedFrame::GetOffsetOfCalleeSavedRegisters());
@@ -2665,6 +2761,7 @@ void StubLinkerCPU::EmitComMethodStubEpilog(TADDR pFrameVptr,
EmitLabel(rgRareLabels[0]); // label for rare setup thread
EmitRareSetup(rgRejoinLabels[0], /*fThrow*/ TRUE); // emit rare setup thread
}
+#endif // !FEATURE_STUBS_AS_IL
//---------------------------------------------------------------
// Emit code to store the setup current Thread structure in eax.
@@ -2695,12 +2792,16 @@ VOID StubLinkerCPU::EmitRareSetup(CodeLabel *pRejoinPoint, BOOL fThrow)
{
STANDARD_VM_CONTRACT;
+#ifndef FEATURE_COMINTEROP
+ _ASSERTE(fThrow);
+#else // !FEATURE_COMINTEROP
if (!fThrow)
{
X86EmitPushReg(kESI);
X86EmitCall(NewExternalCodeLabel((LPVOID) CreateThreadBlockReturnHr), sizeof(void*));
}
else
+#endif // !FEATURE_COMINTEROP
{
X86EmitCall(NewExternalCodeLabel((LPVOID) CreateThreadBlockThrow), 0);
}
@@ -2710,6 +2811,10 @@ VOID StubLinkerCPU::EmitRareSetup(CodeLabel *pRejoinPoint, BOOL fThrow)
X86EmitNearJump(pRejoinPoint);
}
+//========================================================================
+#endif // TARGET_X86
+//========================================================================
+#if defined(FEATURE_COMINTEROP) && defined(TARGET_X86)
//========================================================================
// Epilog for stubs that enter managed code from COM
//
@@ -2815,9 +2920,9 @@ void StubLinkerCPU::EmitSharedComMethodStubEpilog(TADDR pFrameVptr,
EmitRareSetup(rgRejoinLabels[0],/*fThrow*/ FALSE); // emit rare setup thread
}
+//========================================================================
#endif // defined(FEATURE_COMINTEROP) && defined(TARGET_X86)
-
#if !defined(FEATURE_STUBS_AS_IL) && defined(TARGET_X86)
/*==============================================================================
Pushes a TransitionFrame on the stack
@@ -3332,7 +3437,7 @@ VOID StubLinkerCPU::EmitUnwindInfoCheckSubfunction()
#endif // defined(_DEBUG) && defined(STUBLINKER_GENERATES_UNWIND_INFO)
-#if defined(FEATURE_COMINTEROP) && defined(TARGET_X86)
+#ifdef TARGET_X86
//-----------------------------------------------------------------------
// Generates the inline portion of the code to enable preemptive GC. Hopefully,
@@ -3474,6 +3579,7 @@ VOID StubLinkerCPU::EmitRareDisable(CodeLabel *pRejoinPoint)
X86EmitNearJump(pRejoinPoint);
}
+#ifdef FEATURE_COMINTEROP
//-----------------------------------------------------------------------
// Generates the out-of-line portion of the code to disable preemptive GC.
// After the work is done, the code normally jumps back to the "pRejoinPoint"
@@ -3505,8 +3611,10 @@ VOID StubLinkerCPU::EmitRareDisableHRESULT(CodeLabel *pRejoinPoint, CodeLabel *p
X86EmitNearJump(pExitPoint);
}
+#endif // FEATURE_COMINTEROP
+
+#endif // TARGET_X86
-#endif // defined(FEATURE_COMINTEROP) && defined(TARGET_X86)
VOID StubLinkerCPU::EmitShuffleThunk(ShuffleEntry *pShuffleEntryArray)
diff --git a/src/coreclr/vm/i386/stublinkerx86.h b/src/coreclr/vm/i386/stublinkerx86.h
index c719057e97ea3..02ab6e9d253ea 100644
--- a/src/coreclr/vm/i386/stublinkerx86.h
+++ b/src/coreclr/vm/i386/stublinkerx86.h
@@ -250,6 +250,17 @@ class StubLinkerCPU : public StubLinker
);
VOID X86EmitPushEBPframe();
+#if defined(TARGET_X86)
+#if defined(PROFILING_SUPPORTED) && !defined(FEATURE_STUBS_AS_IL)
+ // These are used to emit calls to notify the profiler of transitions in and out of
+ // managed code through COM->COM+ interop or N/Direct
+ VOID EmitProfilerComCallProlog(TADDR pFrameVptr, X86Reg regFrame);
+ VOID EmitProfilerComCallEpilog(TADDR pFrameVptr, X86Reg regFrame);
+#endif // PROFILING_SUPPORTED && !FEATURE_STUBS_AS_IL
+#endif // TARGET_X86
+
+
+
// Emits the most efficient form of the operation:
//
// opcode altreg, [basereg + scaledreg*scale + ofs]
@@ -329,7 +340,6 @@ class StubLinkerCPU : public StubLinker
#endif
}
-#if defined(FEATURE_COMINTEROP) && defined(TARGET_X86)
VOID EmitEnable(CodeLabel *pForwardRef);
VOID EmitRareEnable(CodeLabel *pRejoinPoint);
@@ -339,13 +349,20 @@ class StubLinkerCPU : public StubLinker
VOID EmitSetup(CodeLabel *pForwardRef);
VOID EmitRareSetup(CodeLabel* pRejoinPoint, BOOL fThrow);
-#endif // FEATURE_COMINTEROP && TARGET_X86
#ifndef FEATURE_STUBS_AS_IL
VOID EmitMethodStubProlog(TADDR pFrameVptr, int transitionBlockOffset);
VOID EmitMethodStubEpilog(WORD numArgBytes, int transitionBlockOffset);
VOID EmitCheckGSCookie(X86Reg frameReg, int gsCookieOffset);
+
+#ifdef TARGET_X86
+ void EmitComMethodStubProlog(TADDR pFrameVptr, CodeLabel** rgRareLabels,
+ CodeLabel** rgRejoinLabels, BOOL bShouldProfile);
+
+ void EmitComMethodStubEpilog(TADDR pFrameVptr, CodeLabel** rgRareLabels,
+ CodeLabel** rgRejoinLabels, BOOL bShouldProfile);
+#endif // TARGET_X86
#endif // !FEATURE_STUBS_AS_IL
#ifdef TARGET_X86
@@ -362,20 +379,6 @@ class StubLinkerCPU : public StubLinker
VOID EmitComputedInstantiatingMethodStub(MethodDesc* pSharedMD, struct ShuffleEntry *pShuffleEntryArray, void* extraArg);
#if defined(FEATURE_COMINTEROP) && defined(TARGET_X86)
-
-#if defined(PROFILING_SUPPORTED)
- // These are used to emit calls to notify the profiler of transitions in and out of
- // managed code through COM->COM+ interop or N/Direct
- VOID EmitProfilerComCallProlog(TADDR pFrameVptr, X86Reg regFrame);
- VOID EmitProfilerComCallEpilog(TADDR pFrameVptr, X86Reg regFrame);
-#endif // PROFILING_SUPPORTED
-
- void EmitComMethodStubProlog(TADDR pFrameVptr, CodeLabel** rgRareLabels,
- CodeLabel** rgRejoinLabels, BOOL bShouldProfile);
-
- void EmitComMethodStubEpilog(TADDR pFrameVptr, CodeLabel** rgRareLabels,
- CodeLabel** rgRejoinLabels, BOOL bShouldProfile);
-
//========================================================================
// shared Epilog for stubs that enter managed code from COM
// uses a return thunk within the method desc
diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp
index b509a5c221ed1..3bf1abcfcfbee 100644
--- a/src/coreclr/vm/interoputil.cpp
+++ b/src/coreclr/vm/interoputil.cpp
@@ -1063,7 +1063,7 @@ CorClassIfaceAttr ReadClassInterfaceTypeCustomAttribute(TypeHandle type)
{
// Check the class interface attribute at the assembly level.
Assembly *pAssembly = type.GetAssembly();
- hr = TryParseClassInterfaceAttribute(pAssembly->GetModule(), pAssembly->GetManifestToken(), &attrValueMaybe);
+ hr = TryParseClassInterfaceAttribute(pAssembly->GetManifestModule(), pAssembly->GetManifestToken(), &attrValueMaybe);
if (FAILED(hr))
ThrowHR(hr, BFA_BAD_CLASS_INT_CA_FORMAT);
}
@@ -2501,8 +2501,8 @@ HRESULT GetTypeLibGuidForAssembly(Assembly *pAssembly, GUID *pGuid)
CQuickArray rName; // String for guid.
ULONG cbData; // Size of the string in bytes.
- // Get GUID from Assembly, else Generate from name.
- hr = pAssembly->GetMDImport()->GetItemGuid(TokenFromRid(1, mdtAssembly), pGuid);
+ // Get GUID from Assembly, else from Manifest Module, else Generate from name.
+ hr = pAssembly->GetManifestImport()->GetItemGuid(TokenFromRid(1, mdtAssembly), pGuid);
if (*pGuid == GUID_NULL)
{
@@ -2548,7 +2548,7 @@ HRESULT GetTypeLibVersionForAssembly(
ULONG cbData = 0;
// Check to see if the TypeLibVersionAttribute is set.
- IfFailRet(pAssembly->GetMDImport()->GetCustomAttributeByName(TokenFromRid(1, mdtAssembly), INTEROP_TYPELIBVERSION_TYPE, (const void**)&pbData, &cbData));
+ IfFailRet(pAssembly->GetManifestImport()->GetCustomAttributeByName(TokenFromRid(1, mdtAssembly), INTEROP_TYPELIBVERSION_TYPE, (const void**)&pbData, &cbData));
// For attribute contents, see https://docs.microsoft.com/dotnet/api/system.runtime.interopservices.typelibversionattribute
if (cbData >= (2 + 2 * sizeof(UINT32)))
diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp
index 27d2452491e2a..109f98ceecfe1 100644
--- a/src/coreclr/vm/jithelpers.cpp
+++ b/src/coreclr/vm/jithelpers.cpp
@@ -529,8 +529,16 @@ ftype BankersRound(ftype value)
if ((value -(integerPart +0.5)) == 0.0)
{
// round to even
+#if defined(TARGET_ARM) && defined(FEATURE_CORESYSTEM)
+ // @ARMTODO: On ARM when building on CoreSystem (where we link against the system CRT) an attempt to
+ // use fmod(float, float) fails to link (apparently this is converted to a reference to fmodf, which
+ // is not included in the system CRT). Use the double version instead.
+ if (fmod(double(integerPart), double(2.0)) == 0.0)
+ return integerPart;
+#else
if (fmod(ftype(integerPart), ftype(2.0)) == 0.0)
return integerPart;
+#endif
// Else return the nearest even integer
return (ftype)_copysign(ceil(fabs(value+0.5)),
@@ -1434,7 +1442,7 @@ HCIMPL2(void*, JIT_GetSharedNonGCStaticBaseDynamicClass_Helper, DomainLocalModul
HELPER_METHOD_FRAME_BEGIN_RET_0();
- MethodTable *pMT = pLocalModule->GetDomainAssembly()->GetModule()->GetDynamicClassMT(dwDynamicClassDomainID);
+ MethodTable *pMT = pLocalModule->GetDomainFile()->GetModule()->GetDynamicClassMT(dwDynamicClassDomainID);
_ASSERTE(pMT);
pMT->CheckRunClassInitThrowing();
@@ -1456,7 +1464,7 @@ HCIMPL2(void*, JIT_GetSharedNonGCStaticBaseDynamicClass, DomainLocalModule *pLoc
if (pLocalInfo != NULL)
{
PTR_BYTE retval;
- GET_DYNAMICENTRY_NONGCSTATICS_BASEPOINTER(pLocalModule->GetDomainAssembly()->GetModule()->GetLoaderAllocator(),
+ GET_DYNAMICENTRY_NONGCSTATICS_BASEPOINTER(pLocalModule->GetDomainFile()->GetModule()->GetLoaderAllocator(),
pLocalInfo,
&retval);
@@ -1478,7 +1486,7 @@ HCIMPL2(void, JIT_ClassInitDynamicClass_Helper, DomainLocalModule *pLocalModule,
HELPER_METHOD_FRAME_BEGIN_0();
- MethodTable *pMT = pLocalModule->GetDomainAssembly()->GetModule()->GetDynamicClassMT(dwDynamicClassDomainID);
+ MethodTable *pMT = pLocalModule->GetDomainFile()->GetModule()->GetDynamicClassMT(dwDynamicClassDomainID);
_ASSERTE(pMT);
pMT->CheckRunClassInitThrowing();
@@ -1517,7 +1525,7 @@ HCIMPL2(void*, JIT_GetSharedGCStaticBaseDynamicClass_Helper, DomainLocalModule *
HELPER_METHOD_FRAME_BEGIN_RET_0();
- MethodTable *pMT = pLocalModule->GetDomainAssembly()->GetModule()->GetDynamicClassMT(dwDynamicClassDomainID);
+ MethodTable *pMT = pLocalModule->GetDomainFile()->GetModule()->GetDynamicClassMT(dwDynamicClassDomainID);
_ASSERTE(pMT);
pMT->CheckRunClassInitThrowing();
@@ -1539,7 +1547,7 @@ HCIMPL2(void*, JIT_GetSharedGCStaticBaseDynamicClass, DomainLocalModule *pLocalM
if (pLocalInfo != NULL)
{
PTR_BYTE retval;
- GET_DYNAMICENTRY_GCSTATICS_BASEPOINTER(pLocalModule->GetDomainAssembly()->GetModule()->GetLoaderAllocator(),
+ GET_DYNAMICENTRY_GCSTATICS_BASEPOINTER(pLocalModule->GetDomainFile()->GetModule()->GetLoaderAllocator(),
pLocalInfo,
&retval);
@@ -1853,7 +1861,7 @@ HCIMPL2(void*, JIT_GetSharedNonGCThreadStaticBaseDynamicClass, DomainLocalModule
if (pLocalInfo != NULL)
{
PTR_BYTE retval;
- GET_DYNAMICENTRY_NONGCTHREADSTATICS_BASEPOINTER(pDomainLocalModule->GetDomainAssembly()->GetModule()->GetLoaderAllocator(),
+ GET_DYNAMICENTRY_NONGCTHREADSTATICS_BASEPOINTER(pDomainLocalModule->GetDomainFile()->GetModule()->GetLoaderAllocator(),
pLocalInfo,
&retval);
return retval;
@@ -1864,7 +1872,7 @@ HCIMPL2(void*, JIT_GetSharedNonGCThreadStaticBaseDynamicClass, DomainLocalModule
// then we have to go through the slow path
// Obtain the Module
- Module * pModule = pDomainLocalModule->GetDomainAssembly()->GetModule();
+ Module * pModule = pDomainLocalModule->GetDomainFile()->GetModule();
// Obtain the MethodTable
MethodTable * pMT = pModule->GetDynamicClassMT(dwDynamicClassDomainID);
@@ -1901,7 +1909,7 @@ HCIMPL2(void*, JIT_GetSharedGCThreadStaticBaseDynamicClass, DomainLocalModule *p
if (pLocalInfo != NULL)
{
PTR_BYTE retval;
- GET_DYNAMICENTRY_GCTHREADSTATICS_BASEPOINTER(pDomainLocalModule->GetDomainAssembly()->GetModule()->GetLoaderAllocator(),
+ GET_DYNAMICENTRY_GCTHREADSTATICS_BASEPOINTER(pDomainLocalModule->GetDomainFile()->GetModule()->GetLoaderAllocator(),
pLocalInfo,
&retval);
@@ -1913,7 +1921,7 @@ HCIMPL2(void*, JIT_GetSharedGCThreadStaticBaseDynamicClass, DomainLocalModule *p
// then we have to go through the slow path
// Obtain the Module
- Module * pModule = pDomainLocalModule->GetDomainAssembly()->GetModule();
+ Module * pModule = pDomainLocalModule->GetDomainFile()->GetModule();
// Obtain the MethodTable
MethodTable * pMT = pModule->GetDynamicClassMT(dwDynamicClassDomainID);
diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp
index 7c298b847400e..e28434acabe56 100644
--- a/src/coreclr/vm/jitinterface.cpp
+++ b/src/coreclr/vm/jitinterface.cpp
@@ -953,7 +953,7 @@ void CEEInfo::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken
ThrowBadTokenException(pResolvedToken);
{
- DomainAssembly *pTargetModule = pModule->LoadModule(GetAppDomain(), metaTOK);
+ DomainFile *pTargetModule = pModule->LoadModule(GetAppDomain(), metaTOK);
if (pTargetModule == NULL)
COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
th = TypeHandle(pTargetModule->GetModule()->GetGlobalMethodTable());
@@ -2029,53 +2029,53 @@ bool CEEInfo::checkMethodModifier(CORINFO_METHOD_HANDLE hMethod,
return result;
}
-static unsigned MarkGCField(BYTE* gcPtrs, CorInfoGCType type)
-{
- STANDARD_VM_CONTRACT;
-
- // Ensure that if we have multiple fields with the same offset,
- // that we don't double count the data in the gc layout.
- if (*gcPtrs == TYPE_GC_NONE)
- {
- *gcPtrs = type;
- return 1;
- }
- else if (*gcPtrs != type)
- {
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
- return 0;
-}
-
/*********************************************************************/
static unsigned ComputeGCLayout(MethodTable * pMT, BYTE* gcPtrs)
{
STANDARD_VM_CONTRACT;
+ unsigned result = 0;
+
_ASSERTE(pMT->IsValueType());
if (pMT->HasSameTypeDefAs(g_pByReferenceClass))
- return MarkGCField(gcPtrs, TYPE_GC_BYREF);
+ {
+ if (gcPtrs[0] == TYPE_GC_NONE)
+ {
+ gcPtrs[0] = TYPE_GC_BYREF;
+ result++;
+ }
+ else if (gcPtrs[0] != TYPE_GC_BYREF)
+ {
+ COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
+ }
+ return result;
+ }
- unsigned result = 0;
ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS);
for (FieldDesc *pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next())
{
int fieldStartIndex = pFD->GetOffset() / TARGET_POINTER_SIZE;
- if (pFD->GetFieldType() == ELEMENT_TYPE_VALUETYPE)
- {
- MethodTable * pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable();
- result += ComputeGCLayout(pFieldMT, gcPtrs + fieldStartIndex);
- }
- else if (pFD->IsObjRef())
+ if (pFD->GetFieldType() != ELEMENT_TYPE_VALUETYPE)
{
- result += MarkGCField(gcPtrs + fieldStartIndex, TYPE_GC_REF);
+ if (pFD->IsObjRef())
+ {
+ if (gcPtrs[fieldStartIndex] == TYPE_GC_NONE)
+ {
+ gcPtrs[fieldStartIndex] = TYPE_GC_REF;
+ result++;
+ }
+ else if (gcPtrs[fieldStartIndex] != TYPE_GC_REF)
+ {
+ COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
+ }
+ }
}
- else if (pFD->IsByRef())
+ else
{
- result += MarkGCField(gcPtrs + fieldStartIndex, TYPE_GC_BYREF);
+ MethodTable * pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable();
+ result += ComputeGCLayout(pFieldMT, gcPtrs + fieldStartIndex);
}
}
return result;
@@ -9002,6 +9002,9 @@ CorInfoType CEEInfo::getFieldTypeInternal (CORINFO_FIELD_HANDLE fieldHnd,
FieldDesc* field = (FieldDesc*) fieldHnd;
CorElementType type = field->GetFieldType();
+ // TODO should not burn the time to do this for anything but Value Classes
+ _ASSERTE(type != ELEMENT_TYPE_BYREF);
+
if (type == ELEMENT_TYPE_I)
{
PTR_MethodTable enclosingMethodTable = field->GetApproxEnclosingMethodTable();
@@ -12733,7 +12736,7 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config,
LARGE_INTEGER methodJitTimeStop;
QueryPerformanceCounter(&methodJitTimeStop);
SString codeBase;
- ftn->GetModule()->GetDomainAssembly()->GetPEAssembly()->GetPathOrCodeBase(codeBase);
+ ftn->GetModule()->GetDomainFile()->GetPEAssembly()->GetPathOrCodeBase(codeBase);
codeBase.AppendPrintf(W(",0x%x,%d,%d\n"),
//(const WCHAR *)codeBase, //module name
ftn->GetMemberDef(), //method token
@@ -12815,11 +12818,13 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config,
"Jitted Entry at" FMT_ADDR "method %s::%s %s\n", DBG_ADDR(nativeEntry),
ftn->m_pszDebugClassName, ftn->m_pszDebugMethodName, ftn->m_pszDebugMethodSignature));
+#if defined(FEATURE_CORESYSTEM)
+
#ifdef _DEBUG
LPCUTF8 pszDebugClassName = ftn->m_pszDebugClassName;
LPCUTF8 pszDebugMethodName = ftn->m_pszDebugMethodName;
LPCUTF8 pszDebugMethodSignature = ftn->m_pszDebugMethodSignature;
-#elif 0
+#else
LPCUTF8 pszNamespace;
LPCUTF8 pszDebugClassName = ftn->GetMethodTable()->GetFullyQualifiedNameInfo(&pszNamespace);
LPCUTF8 pszDebugMethodName = ftn->GetName();
@@ -12828,6 +12833,7 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config,
//DbgPrintf("Jitted Entry at" FMT_ADDR "method %s::%s %s size %08x\n", DBG_ADDR(nativeEntry),
// pszDebugClassName, pszDebugMethodName, pszDebugMethodSignature, sizeOfCode);
+#endif
ClrFlushInstructionCache(nativeEntry, sizeOfCode);
ret = (PCODE)nativeEntry;
diff --git a/src/coreclr/vm/loaderallocator.cpp b/src/coreclr/vm/loaderallocator.cpp
index 657ff7b2b40ce..5b5c9d142c89d 100644
--- a/src/coreclr/vm/loaderallocator.cpp
+++ b/src/coreclr/vm/loaderallocator.cpp
@@ -360,7 +360,7 @@ LoaderAllocator * LoaderAllocator::GCLoaderAllocators_RemoveAssemblies(AppDomain
while (iData.Next_Unlocked(pDomainAssembly.This()))
{
// The assembly could be collected (ref-count = 0), do not use holder which calls add-ref
- Assembly * pAssembly = pDomainAssembly->GetAssembly();
+ Assembly * pAssembly = pDomainAssembly->GetLoadedAssembly();
if (pAssembly != NULL)
{
@@ -393,7 +393,7 @@ LoaderAllocator * LoaderAllocator::GCLoaderAllocators_RemoveAssemblies(AppDomain
while (i.Next_Unlocked(pDomainAssembly.This()))
{
// The assembly could be collected (ref-count = 0), do not use holder which calls add-ref
- Assembly * pAssembly = pDomainAssembly->GetAssembly();
+ Assembly * pAssembly = pDomainAssembly->GetLoadedAssembly();
if (pAssembly != NULL)
{
@@ -420,7 +420,7 @@ LoaderAllocator * LoaderAllocator::GCLoaderAllocators_RemoveAssemblies(AppDomain
while (i.Next_Unlocked(pDomainAssembly.This()))
{
// The assembly could be collected (ref-count = 0), do not use holder which calls add-ref
- Assembly * pAssembly = pDomainAssembly->GetAssembly();
+ Assembly * pAssembly = pDomainAssembly->GetLoadedAssembly();
if (pAssembly != NULL)
{
@@ -672,7 +672,7 @@ BOOL LoaderAllocator::Destroy(QCall::LoaderAllocatorHandle pLoaderAllocator)
DomainAssembly* pDomainAssembly = (DomainAssembly*)(pID->GetDomainAssemblyIterator());
if (pDomainAssembly != NULL)
{
- Assembly *pAssembly = pDomainAssembly->GetAssembly();
+ Assembly *pAssembly = pDomainAssembly->GetCurrentAssembly();
pLoaderAllocator->m_pFirstDomainAssemblyFromSameALCToDelete = pAssembly->GetDomainAssembly();
}
diff --git a/src/coreclr/vm/memberload.cpp b/src/coreclr/vm/memberload.cpp
index 4c8e7dc7e2a92..78fdb518a1618 100644
--- a/src/coreclr/vm/memberload.cpp
+++ b/src/coreclr/vm/memberload.cpp
@@ -277,7 +277,7 @@ void MemberLoader::GetDescFromMemberRef(Module * pModule,
{
case mdtModuleRef:
{
- DomainAssembly *pTargetModule = pModule->LoadModule(GetAppDomain(), parent);
+ DomainFile *pTargetModule = pModule->LoadModule(GetAppDomain(), parent);
if (pTargetModule == NULL)
COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
typeHnd = TypeHandle(pTargetModule->GetModule()->GetGlobalMethodTable());
diff --git a/src/coreclr/vm/methoditer.cpp b/src/coreclr/vm/methoditer.cpp
index da24a53d064a1..841b3214d2e2d 100644
--- a/src/coreclr/vm/methoditer.cpp
+++ b/src/coreclr/vm/methoditer.cpp
@@ -77,7 +77,11 @@ BOOL LoadedMethodDescIterator::Next(
dbg_m_pDomainAssembly = *pDomainAssemblyHolder;
#endif //_DEBUG
- m_currentModule = (*pDomainAssemblyHolder)->GetModule();
+ m_moduleIterator = (*pDomainAssemblyHolder)->IterateModules(m_moduleIterationFlags);
+
+ADVANCE_MODULE:
+ if (!m_moduleIterator.Next())
+ goto ADVANCE_ASSEMBLY;
if (m_mainMD->HasClassInstantiation())
{
@@ -92,7 +96,7 @@ BOOL LoadedMethodDescIterator::Next(
if (m_mainMD->HasClassInstantiation())
{
if (!GetCurrentModule()->GetAvailableParamTypes()->FindNext(&m_typeIterator, &m_typeIteratorEntry))
- goto ADVANCE_ASSEMBLY;
+ goto ADVANCE_MODULE;
if (CORCOMPILE_IS_POINTER_TAGGED(m_typeIteratorEntry->GetTypeHandle().AsTAddr()))
goto ADVANCE_TYPE;
@@ -126,7 +130,7 @@ BOOL LoadedMethodDescIterator::Next(
}
else if (m_startedNonGenericType)
{
- goto ADVANCE_ASSEMBLY;
+ goto ADVANCE_MODULE;
}
else
{
@@ -184,7 +188,7 @@ Module * LoadedMethodDescIterator::GetCurrentModule()
}
CONTRACTL_END
- return m_currentModule;
+ return m_moduleIterator.GetLoadedModule();
}
MethodDesc *LoadedMethodDescIterator::Current()
@@ -224,7 +228,8 @@ LoadedMethodDescIterator::Start(
AppDomain * pAppDomain,
Module *pModule,
mdMethodDef md,
- AssemblyIterationFlags assemblyIterationFlags)
+ AssemblyIterationFlags assemblyIterationFlags,
+ ModuleIterationOption moduleIterationFlags)
{
CONTRACTL
{
@@ -236,6 +241,7 @@ LoadedMethodDescIterator::Start(
CONTRACTL_END;
m_assemIterationFlags = assemblyIterationFlags;
+ m_moduleIterationFlags = moduleIterationFlags;
m_mainMD = NULL;
m_module = pModule;
m_md = md;
diff --git a/src/coreclr/vm/methoditer.h b/src/coreclr/vm/methoditer.h
index fdc49e2ce5971..71192be2e0c01 100644
--- a/src/coreclr/vm/methoditer.h
+++ b/src/coreclr/vm/methoditer.h
@@ -9,7 +9,7 @@
#include "instmethhash.h"
#include "method.hpp"
#include "appdomain.hpp"
-#include "domainassembly.h"
+#include "domainfile.h"
#include "typehash.h"
@@ -44,8 +44,9 @@ class LoadedMethodDescIterator
// These are used when iterating over an AppDomain
AppDomain::AssemblyIterator m_assemIterator;
- Module* m_currentModule;
+ DomainModuleIterator m_moduleIterator;
AssemblyIterationFlags m_assemIterationFlags;
+ ModuleIterationOption m_moduleIterationFlags;
EETypeHashTable::Iterator m_typeIterator;
EETypeHashEntry * m_typeIteratorEntry;
@@ -68,17 +69,19 @@ class LoadedMethodDescIterator
void Start(AppDomain * pAppDomain,
Module *pModule,
mdMethodDef md,
- AssemblyIterationFlags assemIterationFlags = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution));
+ AssemblyIterationFlags assemIterationFlags = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution),
+ ModuleIterationOption moduleIterationFlags = kModIterIncludeLoaded);
void Start(AppDomain * pAppDomain, Module *pModule, mdMethodDef md, MethodDesc *pDesc);
LoadedMethodDescIterator(
AppDomain * pAppDomain,
Module *pModule,
mdMethodDef md,
- AssemblyIterationFlags assemblyIterationFlags = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution))
+ AssemblyIterationFlags assemblyIterationFlags = (AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution),
+ ModuleIterationOption moduleIterationFlags = kModIterIncludeLoaded)
{
LIMITED_METHOD_CONTRACT;
- Start(pAppDomain, pModule, md, assemblyIterationFlags);
+ Start(pAppDomain, pModule, md, assemblyIterationFlags, moduleIterationFlags);
}
LoadedMethodDescIterator(void);
diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h
index 76c552a304284..86a033a0593a2 100644
--- a/src/coreclr/vm/methodtable.h
+++ b/src/coreclr/vm/methodtable.h
@@ -1517,8 +1517,6 @@ class MethodTable
inline BOOL HasExplicitSize();
- inline BOOL IsAutoLayoutOrHasAutoLayoutField();
-
UINT32 GetNativeSize();
DWORD GetBaseSize()
diff --git a/src/coreclr/vm/methodtable.inl b/src/coreclr/vm/methodtable.inl
index 72b628dae9545..d14a73532b6e1 100644
--- a/src/coreclr/vm/methodtable.inl
+++ b/src/coreclr/vm/methodtable.inl
@@ -947,13 +947,6 @@ inline BOOL MethodTable::HasExplicitSize()
return GetClass()->HasExplicitSize();
}
-//==========================================================================================
-inline BOOL MethodTable::IsAutoLayoutOrHasAutoLayoutField()
-{
- LIMITED_METHOD_CONTRACT;
- return GetClass()->IsAutoLayoutOrHasAutoLayoutField();
-}
-
//==========================================================================================
inline DWORD MethodTable::GetPerInstInfoSize()
{
diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp
index 82499f314e4f3..694e03cca35f2 100644
--- a/src/coreclr/vm/methodtablebuilder.cpp
+++ b/src/coreclr/vm/methodtablebuilder.cpp
@@ -3935,27 +3935,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
break;
}
- case ELEMENT_TYPE_BYREF:
- {
- dwLog2FieldSize = LOG2_PTRSIZE;
- if (fIsStatic)
- {
- // Byref-like types cannot be used for static fields
- BuildMethodTableThrowException(IDS_CLASSLOAD_BYREFLIKE_STATICFIELD);
- }
- if (!bmtFP->fIsByRefLikeType)
- {
- // Non-byref-like types cannot contain byref-like instance fields
- BuildMethodTableThrowException(IDS_CLASSLOAD_BYREFLIKE_INSTANCEFIELD);
- }
- break;
- }
-
- case ELEMENT_TYPE_TYPEDBYREF:
- {
- goto IS_VALUETYPE;
- }
-
// Class type variable (method type variables aren't allowed in fields)
// These only occur in open types used for verification/reflection.
case ELEMENT_TYPE_VAR:
@@ -3991,6 +3970,7 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
{
Module * pTokenModule;
dwByValueClassToken = fsig.GetArgProps().PeekValueTypeTokenClosed(GetModule(), &bmtGenerics->typeContext, &pTokenModule);
+ fIsByValue = TRUE;
// By-value class
BAD_FORMAT_NOTHROW_ASSERT(dwByValueClassToken != 0);
@@ -4062,11 +4042,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
pByValueClass = (MethodTable *)-1;
}
} // If 'this' is a value class
- }
- // TypedReference shares the rest of the code here
-IS_VALUETYPE:
- {
- fIsByValue = TRUE;
// It's not self-referential so try to load it
if (pByValueClass == NULL)
@@ -8673,14 +8648,6 @@ MethodTableBuilder::HandleExplicitLayout(
BuildMethodTableThrowException(IDS_CLASSLOAD_GENERAL);
}
}
-
- if (!numInstanceFieldBytes.IsOverflow() && numInstanceFieldBytes.Value() == 0)
- {
- // If we calculate a 0-byte size here, we should have also calculated a 0-byte size
- // in the initial layout algorithm.
- _ASSERTE(GetLayoutInfo()->IsZeroSized());
- numInstanceFieldBytes = S_UINT32(1);
- }
}
// The GC requires that all valuetypes containing orefs be sized to a multiple of TARGET_POINTER_SIZE.
diff --git a/src/coreclr/vm/mlinfo.cpp b/src/coreclr/vm/mlinfo.cpp
index 5a071c2b9f8f9..c573184012284 100644
--- a/src/coreclr/vm/mlinfo.cpp
+++ b/src/coreclr/vm/mlinfo.cpp
@@ -1056,78 +1056,6 @@ OleColorMarshalingInfo *EEMarshalingData::GetOleColorMarshalingInfo()
}
#endif // FEATURE_COMINTEROP
-namespace
-{
- MarshalInfo::MarshalType GetDisabledMarshallerType(
- Module* pModule,
- SigPointer sig,
- const SigTypeContext * pTypeContext,
- MethodTable** pMTOut,
- UINT* errorResIDOut)
- {
- switch (sig.PeekElemTypeNormalized(pModule, pTypeContext))
- {
- case ELEMENT_TYPE_BOOLEAN:
- case ELEMENT_TYPE_U1:
- return MarshalInfo::MARSHAL_TYPE_GENERIC_U1;
- case ELEMENT_TYPE_I1:
- return MarshalInfo::MARSHAL_TYPE_GENERIC_1;
- case ELEMENT_TYPE_CHAR:
- case ELEMENT_TYPE_U2:
- return MarshalInfo::MARSHAL_TYPE_GENERIC_U2;
- case ELEMENT_TYPE_I2:
- return MarshalInfo::MARSHAL_TYPE_GENERIC_2;
- case ELEMENT_TYPE_U4:
- return MarshalInfo::MARSHAL_TYPE_GENERIC_U4;
- case ELEMENT_TYPE_I4:
- return MarshalInfo::MARSHAL_TYPE_GENERIC_4;
- case ELEMENT_TYPE_U8:
- case ELEMENT_TYPE_I8:
- return MarshalInfo::MARSHAL_TYPE_GENERIC_8;
-#ifdef TARGET_64BIT
- case ELEMENT_TYPE_U:
- case ELEMENT_TYPE_PTR:
- case ELEMENT_TYPE_FNPTR:
- case ELEMENT_TYPE_I:
- return MarshalInfo::MARSHAL_TYPE_GENERIC_8;
-#else
- case ELEMENT_TYPE_U:
- return MarshalInfo::MARSHAL_TYPE_GENERIC_U4;
- case ELEMENT_TYPE_PTR:
- case ELEMENT_TYPE_FNPTR:
- case ELEMENT_TYPE_I:
- return MarshalInfo::MARSHAL_TYPE_GENERIC_4;
-#endif
- case ELEMENT_TYPE_R4:
- return MarshalInfo::MARSHAL_TYPE_FLOAT;
- case ELEMENT_TYPE_R8:
- return MarshalInfo::MARSHAL_TYPE_DOUBLE;
- case ELEMENT_TYPE_VAR:
- case ELEMENT_TYPE_VALUETYPE:
- {
- TypeHandle sigTH = sig.GetTypeHandleThrowing(pModule, pTypeContext);
- MethodTable* pMT = sigTH.GetMethodTable();
-
- if (!pMT->IsValueType() || pMT->ContainsPointers())
- {
- *errorResIDOut = IDS_EE_BADMARSHAL_MARSHAL_DISABLED;
- return MarshalInfo::MARSHAL_TYPE_UNKNOWN;
- }
- if (pMT->IsAutoLayoutOrHasAutoLayoutField())
- {
- *errorResIDOut = IDS_EE_BADMARSHAL_AUTOLAYOUT;
- return MarshalInfo::MARSHAL_TYPE_UNKNOWN;
- }
- *pMTOut = pMT;
- return MarshalInfo::MARSHAL_TYPE_BLITTABLEVALUECLASS;
- }
- default:
- *errorResIDOut = IDS_EE_BADMARSHAL_MARSHAL_DISABLED;
- return MarshalInfo::MARSHAL_TYPE_UNKNOWN;
- }
- }
-}
-
//==========================================================================
// Constructs MarshalInfo.
//==========================================================================
@@ -1235,30 +1163,7 @@ MarshalInfo::MarshalInfo(Module* pModule,
m_byref = TRUE;
#endif
- // For COM IL-stub scenarios, we do not support disabling the runtime marshalling support.
- // The runtime-integrated COM support uses a significant portion of the marshalling infrastructure as well as
- // quite a bit of its own custom marshalling infrastructure to function in basically any aspect.
- // As a result, disabling marshalling in COM scenarios isn't useful. Instead, we recommend that people set the
- // feature switch to false to disable the runtime COM support if they want it disabled.
- // For field marshalling scenarios, we also don't disable runtime marshalling. If we're already in a field
- // marshalling scenario, we've already decided that the context for the owning type is using runtime marshalling,
- // so the fields of the struct should also use runtime marshalling.
- const bool useRuntimeMarshalling = ms != MARSHAL_SCENARIO_NDIRECT || pModule->IsRuntimeMarshallingEnabled();
- if (!useRuntimeMarshalling)
- {
- m_in = TRUE;
- m_out = FALSE;
- m_byref = FALSE;
- m_type = GetDisabledMarshallerType(
- pModule,
- sig,
- pTypeContext,
- &m_pMT,
- &m_resID);
- m_args.m_pMT = m_pMT;
- return;
- }
// Retrieve the native type for the current parameter.
if (!ParseNativeTypeInfo(token, pModule->GetMDImport(), &ParamInfo))
@@ -1417,7 +1322,6 @@ MarshalInfo::MarshalInfo(Module* pModule,
switch (mtype)
{
case ELEMENT_TYPE_BOOLEAN:
-
switch (nativeType)
{
case NATIVE_TYPE_BOOLEAN:
@@ -1578,6 +1482,10 @@ MarshalInfo::MarshalInfo(Module* pModule,
break;
case ELEMENT_TYPE_I:
+ // Technically the "native int" and "native uint" types aren't supported in the WinRT scenario,
+ // but we need to not block ourselves from using them to enable accurate managed->native marshalling of
+ // projected types such as NotifyCollectionChangedEventArgs and NotifyPropertyChangedEventArgs.
+
if (!(nativeType == NATIVE_TYPE_INT || nativeType == NATIVE_TYPE_UINT || nativeType == NATIVE_TYPE_DEFAULT))
{
m_resID = IDS_EE_BADMARSHAL_I;
@@ -1591,6 +1499,7 @@ MarshalInfo::MarshalInfo(Module* pModule,
break;
case ELEMENT_TYPE_U:
+
if (!(nativeType == NATIVE_TYPE_UINT || nativeType == NATIVE_TYPE_INT || nativeType == NATIVE_TYPE_DEFAULT))
{
m_resID = IDS_EE_BADMARSHAL_I;
@@ -1655,21 +1564,6 @@ MarshalInfo::MarshalInfo(Module* pModule,
{
TypeHandle sigTH = sig.GetTypeHandleThrowing(pModule, pTypeContext);
- if (sigTH.GetMethodTable()->IsValueType())
- {
- // For value types, we need to handle the "value type marshalled as a COM interface"
- // case here for back-compat.
- // Otherwise, we can go to the value-type case.
-#ifdef FEATURE_COMINTEROP
- if (nativeType != NATIVE_TYPE_INTF)
- {
- goto lValueClass;
- }
-#else
- goto lValueClass;
-#endif
- }
-
// Disallow marshaling generic types.
if (sigTH.HasInstantiation())
{
@@ -2074,13 +1968,14 @@ MarshalInfo::MarshalInfo(Module* pModule,
}
}
+
else if (m_pMT->IsArray())
{
_ASSERTE(!"This invalid signature should never be hit!");
IfFailGoto(E_FAIL, lFail);
}
#endif // FEATURE_COMINTEROP
- else
+ else if (!m_pMT->IsValueType())
{
if (!(nativeType == NATIVE_TYPE_INTF || nativeType == NATIVE_TYPE_DEFAULT))
{
@@ -2095,6 +1990,12 @@ MarshalInfo::MarshalInfo(Module* pModule,
IfFailGoto(E_FAIL, lFail);
#endif // FEATURE_COMINTEROP
}
+
+ else
+ {
+ _ASSERTE(m_pMT->IsValueType());
+ goto lValueClass;
+ }
}
break;
}
@@ -2265,7 +2166,8 @@ MarshalInfo::MarshalInfo(Module* pModule,
|| m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR64T))
|| m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR128T))
|| m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTOR256T))
- || m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTORT))
+ // Crossgen scenarios block Vector from even being loaded
+ || m_pMT->HasSameTypeDefAs(CoreLibBinder::GetClass(CLASS__VECTORT))
)))
{
m_resID = IDS_EE_BADMARSHAL_GENERICS_RESTRICTION;
@@ -3000,15 +2902,6 @@ UINT16 MarshalInfo::GetNativeSize(MarshalType mtype)
if (nativeSize == VARIABLESIZE)
{
_ASSERTE(IsValueClass(mtype));
- // For blittable types, use the GetNumInstanceFieldBytes method.
- // When we generate IL stubs when marshalling is disabled,
- // we reuse the blittable value class marshalling mechanism.
- // In that scenario, only GetNumInstanceFieldBytes will return the correct value.
- // GetNativeSize will return the size for when runtime marshalling is enabled.
- if (mtype == MARSHAL_TYPE_BLITTABLEVALUECLASS)
- {
- return (UINT16) m_pMT->GetNumInstanceFieldBytes();
- }
return (UINT16) m_pMT->GetNativeSize();
}
diff --git a/src/coreclr/vm/multicorejit.cpp b/src/coreclr/vm/multicorejit.cpp
index 18a0a141a8228..b747608a18478 100644
--- a/src/coreclr/vm/multicorejit.cpp
+++ b/src/coreclr/vm/multicorejit.cpp
@@ -234,11 +234,11 @@ FileLoadLevel MulticoreJitManager::GetModuleFileLoadLevel(Module * pModule)
if (pModule != NULL)
{
- DomainAssembly * pDomainAssembly = pModule->GetDomainAssembly();
+ DomainFile * pDomainFile = pModule->GetDomainFile();
- if (pDomainAssembly != NULL)
+ if (pDomainFile != NULL)
{
- level = pDomainAssembly->GetLoadLevel();
+ level = pDomainFile->GetLoadLevel();
}
}
@@ -310,7 +310,7 @@ bool RecorderModuleInfo::SetModule(Module * pMod)
SString sAssemblyName;
StackScratchBuffer scratch;
- pMod->GetAssembly()->GetPEAssembly()->GetDisplayName(sAssemblyName);
+ pMod->GetAssembly()->GetManifestFile()->GetDisplayName(sAssemblyName);
LPCUTF8 pAssemblyName = sAssemblyName.GetUTF8(scratch);
unsigned lenAssemblyName = sAssemblyName.GetCount();
@@ -770,8 +770,21 @@ HRESULT MulticoreJitModuleEnumerator::HandleAssembly(DomainAssembly * pAssembly)
{
STANDARD_VM_CONTRACT;
- Module * pModule = pAssembly->GetModule();
- return OnModule(pModule);
+ DomainAssembly::ModuleIterator modIt = pAssembly->IterateModules(kModIterIncludeLoaded);
+
+ HRESULT hr = S_OK;
+
+ while (modIt.Next() && SUCCEEDED(hr))
+ {
+ Module * pModule = modIt.GetModule();
+
+ if (pModule != NULL)
+ {
+ hr = OnModule(pModule);
+ }
+ }
+
+ return hr;
}
diff --git a/src/coreclr/vm/nativeimage.cpp b/src/coreclr/vm/nativeimage.cpp
index 2664a44ad2d18..3bb47cff1acb3 100644
--- a/src/coreclr/vm/nativeimage.cpp
+++ b/src/coreclr/vm/nativeimage.cpp
@@ -289,7 +289,7 @@ void NativeImage::CheckAssemblyMvid(Assembly *assembly) const
}
GUID assemblyMvid;
- assembly->GetMDImport()->GetScopeProps(NULL, &assemblyMvid);
+ assembly->GetManifestImport()->GetScopeProps(NULL, &assemblyMvid);
const byte *pImageBase = (const BYTE *)m_pImageLayout->GetBase();
const GUID *componentMvid = (const GUID *)&pImageBase[m_pComponentAssemblyMvids->VirtualAddress] + assemblyNameIndex->Index;
diff --git a/src/coreclr/vm/nativelibrary.cpp b/src/coreclr/vm/nativelibrary.cpp
index e050e0b1719ff..d5a91b4863c2f 100644
--- a/src/coreclr/vm/nativelibrary.cpp
+++ b/src/coreclr/vm/nativelibrary.cpp
@@ -318,7 +318,7 @@ namespace
#endif // !TARGET_UNIX
NATIVE_LIBRARY_HANDLE hmod = NULL;
- PEAssembly *pManifestFile = pAssembly->GetPEAssembly();
+ PEAssembly *pManifestFile = pAssembly->GetManifestFile();
PTR_AssemblyBinder pBinder = pManifestFile->GetAssemblyBinder();
//Step 0: Check if the assembly was bound using TPA.
@@ -363,7 +363,7 @@ namespace
{
STANDARD_VM_CONTRACT;
- PTR_AssemblyBinder pBinder = pAssembly->GetPEAssembly()->GetAssemblyBinder();
+ PTR_AssemblyBinder pBinder = pAssembly->GetManifestFile()->GetAssemblyBinder();
return pBinder->GetManagedAssemblyLoadContext();
}
@@ -461,7 +461,7 @@ namespace
NATIVE_LIBRARY_HANDLE hmod = NULL;
- SString path = pAssembly->GetPEAssembly()->GetPath();
+ SString path = pAssembly->GetManifestFile()->GetPath();
SString::Iterator lastPathSeparatorIter = path.End();
if (PEAssembly::FindLastPathSeparator(path, lastPathSeparatorIter))
@@ -610,7 +610,7 @@ namespace
NATIVE_LIBRARY_HANDLE hmod = NULL;
-#if !defined(TARGET_UNIX)
+#if defined(FEATURE_CORESYSTEM) && !defined(TARGET_UNIX)
// Try to go straight to System32 for Windows API sets. This is replicating quick check from
// the OS implementation of api sets.
if (IsWindowsAPISet(wszLibName))
@@ -621,7 +621,7 @@ namespace
return hmod;
}
}
-#endif // !TARGET_UNIX
+#endif // FEATURE_CORESYSTEM && !TARGET_UNIX
if (g_hostpolicy_embedded)
{
@@ -771,7 +771,7 @@ NATIVE_LIBRARY_HANDLE NativeLibrary::LoadLibraryByName(LPCWSTR libraryName, Asse
}
else
{
- GetDllImportSearchPathFlags(callingAssembly->GetModule(),
+ GetDllImportSearchPathFlags(callingAssembly->GetManifestModule(),
&dllImportSearchPathFlags, &searchAssemblyDirectory);
}
diff --git a/src/coreclr/vm/object.inl b/src/coreclr/vm/object.inl
index 46b8db4d0d841..e61f2eb443bab 100644
--- a/src/coreclr/vm/object.inl
+++ b/src/coreclr/vm/object.inl
@@ -272,4 +272,38 @@ inline TypeHandle Object::GetGCSafeTypeHandle() const
return TypeHandle(pMT);
}
+template
+inline void FindByRefPointerOffsetsInByRefLikeObject(PTR_MethodTable pMT, SIZE_T baseOffset, const F processPointerOffset)
+{
+ WRAPPER_NO_CONTRACT;
+ _ASSERTE(pMT != nullptr);
+ _ASSERTE(pMT->IsByRefLike());
+
+ if (pMT->HasSameTypeDefAs(g_pByReferenceClass))
+ {
+ processPointerOffset(baseOffset);
+ return;
+ }
+
+ ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS);
+ for (FieldDesc *pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next())
+ {
+ if (pFD->GetFieldType() != ELEMENT_TYPE_VALUETYPE)
+ {
+ continue;
+ }
+
+ // TODO: GetApproxFieldTypeHandleThrowing may throw. This is a potential stress problem for fragile NGen of non-CoreLib
+ // assemblies. It won't ever throw for CoreCLR with R2R. Figure out if anything needs to be done to deal with the
+ // exception.
+ PTR_MethodTable pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable();
+ if (!pFieldMT->IsByRefLike())
+ {
+ continue;
+ }
+
+ FindByRefPointerOffsetsInByRefLikeObject(pFieldMT, baseOffset + pFD->GetOffset(), processPointerOffset);
+ }
+}
+
#endif // _OBJECT_INL_
diff --git a/src/coreclr/vm/peassembly.cpp b/src/coreclr/vm/peassembly.cpp
index 7926fa8b85bf8..9f228fdb5af82 100644
--- a/src/coreclr/vm/peassembly.cpp
+++ b/src/coreclr/vm/peassembly.cpp
@@ -552,7 +552,7 @@ BOOL PEAssembly::GetResource(LPCSTR szName, DWORD *cbResource,
pDomainAssembly = pAssembly->GetDomainAssembly();
pPEAssembly = pDomainAssembly->GetPEAssembly();
- if (FAILED(pAssembly->GetMDImport()->FindManifestResourceByName(
+ if (FAILED(pAssembly->GetManifestImport()->FindManifestResourceByName(
szName,
&mdResource)))
{
@@ -1080,7 +1080,7 @@ void PEAssembly::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;
- DAC_ENUM_DTHIS();
+ DAC_ENUM_VTHIS();
EMEM_OUT(("MEM: %p PEAssembly\n", dac_cast(this)));
#ifdef _DEBUG
diff --git a/src/coreclr/vm/peassembly.h b/src/coreclr/vm/peassembly.h
index 8cb12f986c8bb..3342e835f265a 100644
--- a/src/coreclr/vm/peassembly.h
+++ b/src/coreclr/vm/peassembly.h
@@ -83,6 +83,11 @@ typedef VPTR(PEAssembly) PTR_PEAssembly;
class PEAssembly final
{
+ // ------------------------------------------------------------
+ // SOS support
+ // ------------------------------------------------------------
+ VPTR_BASE_CONCRETE_VTABLE_CLASS(PEAssembly)
+
public:
// ------------------------------------------------------------
@@ -93,7 +98,7 @@ class PEAssembly final
STDMETHOD_(ULONG, Release)();
#ifdef DACCESS_COMPILE
- void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
+ virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
#endif
#if CHECK_INVARIANTS
@@ -376,7 +381,7 @@ class PEAssembly final
#ifdef DACCESS_COMPILE
// just to make the DAC and GCC happy.
- ~PEAssembly() {};
+ virtual ~PEAssembly() {};
PEAssembly() = default;
#else
PEAssembly(
@@ -388,7 +393,7 @@ class PEAssembly final
BINDER_SPACE::Assembly* pHostAssembly = NULL
);
- ~PEAssembly();
+ virtual ~PEAssembly();
#endif
void OpenMDImport();
diff --git a/src/coreclr/vm/peimage.cpp b/src/coreclr/vm/peimage.cpp
index 946943cc3cd61..1b72b89106df6 100644
--- a/src/coreclr/vm/peimage.cpp
+++ b/src/coreclr/vm/peimage.cpp
@@ -456,6 +456,34 @@ void PEImage::GetMVID(GUID *pMvid)
#endif // _DEBUG
}
+void PEImage::VerifyIsAssembly()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ // buch of legacy stuff here wrt the error codes...
+
+ if (!HasNTHeaders())
+ ThrowFormat(COR_E_BADIMAGEFORMAT);
+
+ if(!HasCorHeader())
+ ThrowFormat(COR_E_ASSEMBLYEXPECTED);
+
+ CHECK checkGoodFormat;
+ checkGoodFormat = CheckILFormat();
+ if (!checkGoodFormat)
+ ThrowFormat(COR_E_BADIMAGEFORMAT);
+
+ mdAssembly a;
+ if (FAILED(GetMDImport()->GetAssemblyFromScope(&a)))
+ ThrowFormat(COR_E_ASSEMBLYEXPECTED);
+}
+
void DECLSPEC_NORETURN PEImage::ThrowFormat(HRESULT hrError)
{
CONTRACTL
diff --git a/src/coreclr/vm/peimage.h b/src/coreclr/vm/peimage.h
index f353cebe978d1..6451283d007ce 100644
--- a/src/coreclr/vm/peimage.h
+++ b/src/coreclr/vm/peimage.h
@@ -182,6 +182,8 @@ class PEImage final
CHECK CheckILFormat();
CHECK CheckUniqueInstance();
+ void VerifyIsAssembly();
+
void SetModuleFileNameHintForDAC();
#ifdef DACCESS_COMPILE
void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
diff --git a/src/coreclr/vm/perfmap.cpp b/src/coreclr/vm/perfmap.cpp
index 5e004f6ed0c1f..30708584c3f72 100644
--- a/src/coreclr/vm/perfmap.cpp
+++ b/src/coreclr/vm/perfmap.cpp
@@ -393,7 +393,7 @@ NativeImagePerfMap::NativeImagePerfMap(Assembly * pAssembly, BSTR pDestPath)
// Get the native image signature (GUID).
// Used to ensure that we match symbols to the correct NGEN image.
WCHAR wszSignature[39];
- GetNativeImageSignature(pAssembly->GetPEAssembly(), wszSignature, ARRAY_SIZE(wszSignature));
+ GetNativeImageSignature(pAssembly->GetManifestFile(), wszSignature, ARRAY_SIZE(wszSignature));
// Build the path to the perfmap file, which consists of .ni..map.
// Example: /tmp/System.Private.CoreLib.ni.{GUID}.map
diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp
index 681301621f72f..d8488e7e583b8 100644
--- a/src/coreclr/vm/prestub.cpp
+++ b/src/coreclr/vm/prestub.cpp
@@ -520,7 +520,7 @@ PCODE MethodDesc::GetPrecompiledR2RCode(PrepareCodeConfig* pConfig)
// Lookup in the entry point assembly for a R2R entrypoint (generics with large version bubble enabled)
if (pCode == NULL && HasClassOrMethodInstantiation() && SystemDomain::System()->DefaultDomain()->GetRootAssembly() != NULL)
{
- pModule = SystemDomain::System()->DefaultDomain()->GetRootAssembly()->GetModule();
+ pModule = SystemDomain::System()->DefaultDomain()->GetRootAssembly()->GetManifestModule();
_ASSERT(pModule != NULL);
if (pModule->IsReadyToRun() && pModule->IsInSameVersionBubble(GetModule()))
@@ -2262,6 +2262,10 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo
// use the prestub.
//==========================================================================
+#if defined(TARGET_X86) && !defined(FEATURE_STUBS_AS_IL)
+static PCODE g_UMThunkPreStub;
+#endif // TARGET_X86 && !FEATURE_STUBS_AS_IL
+
#ifndef DACCESS_COMPILE
void ThePreStubManager::Init(void)
@@ -2282,6 +2286,10 @@ void InitPreStubManager(void)
{
STANDARD_VM_CONTRACT;
+#if defined(TARGET_X86) && !defined(FEATURE_STUBS_AS_IL)
+ g_UMThunkPreStub = GenerateUMThunkPrestub()->GetEntryPoint();
+#endif // TARGET_X86 && !FEATURE_STUBS_AS_IL
+
ThePreStubManager::Init();
}
@@ -2289,7 +2297,11 @@ PCODE TheUMThunkPreStub()
{
LIMITED_METHOD_CONTRACT;
+#if defined(TARGET_X86) && !defined(FEATURE_STUBS_AS_IL)
+ return g_UMThunkPreStub;
+#else // TARGET_X86 && !FEATURE_STUBS_AS_IL
return GetEEFuncEntryPoint(TheUMEntryPrestub);
+#endif // TARGET_X86 && !FEATURE_STUBS_AS_IL
}
PCODE TheVarargNDirectStub(BOOL hasRetBuffArg)
diff --git a/src/coreclr/vm/profilingenumerators.cpp b/src/coreclr/vm/profilingenumerators.cpp
index 7d537924df891..609b57cf4ee3a 100644
--- a/src/coreclr/vm/profilingenumerators.cpp
+++ b/src/coreclr/vm/profilingenumerators.cpp
@@ -250,7 +250,7 @@ HRESULT IterateUnsharedModules(AppDomain * pAppDomain,
// enumerable.
//
// Note: To determine what happens in a given load stage of a module or assembly,
- // look at the switch statement in code:DomainAssembly::DoIncrementalLoad, and keep in
+ // look at the switch statement in code:DomainFile::DoIncrementalLoad, and keep in
// mind that it takes cases on the *next* load stage; in other words, the actions
// that appear in a case for a given load stage are actually executed as we attempt
// to transition TO that load stage, and thus they actually execute while the module
@@ -282,14 +282,21 @@ HRESULT IterateUnsharedModules(AppDomain * pAppDomain,
// < Module NOT available from catch-up enumeration
// < ModuleUnloadStarted issued
//
+ // The IterateModules parameter below ensures only modules at level >=
+ // code:FILE_LOAD_LOADLIBRARY will be included in the iteration.
+ //
// Details for module callbacks are the same as those for assemblies, so see
// code:#ProfilerEnumAssemblies for info on how the timing works.
-
- // Call user-supplied callback, and cancel iteration if requested
- HRESULT hr = (callbackObj->*callbackMethod)(pDomainAssembly->GetModule());
- if (hr != S_OK)
+ DomainModuleIterator domainModuleIterator =
+ pDomainAssembly->IterateModules(kModIterIncludeAvailableToProfilers);
+ while (domainModuleIterator.Next())
{
- return hr;
+ // Call user-supplied callback, and cancel iteration if requested
+ HRESULT hr = (callbackObj->*callbackMethod)(domainModuleIterator.GetModule());
+ if (hr != S_OK)
+ {
+ return hr;
+ }
}
}
@@ -395,9 +402,9 @@ HRESULT ProfilerModuleEnum::Init()
HRESULT hr = S_OK;
- // When an assembly is loaded into an AppDomain, a DomainAssembly is
- // created (one per pairing of the AppDomain with the assembly). This means
- // that we'll create multiple DomainAssemblys for the same module if it is loaded
+ // When an assembly or module is loaded into an AppDomain, a separate DomainFile is
+ // created (one per pairing of the AppDomain with the module or assembly). This means
+ // that we'll create multiple DomainFiles for the same module if it is loaded
// domain-neutral (i.e., "shared"). The profiling API callbacks shield the profiler
// from this, and only report a given module the first time it's loaded. So a
// profiler sees only one ModuleLoadFinished for a module loaded domain-neutral, even
@@ -450,8 +457,8 @@ HRESULT IterateAppDomainContainingModule::AddAppDomainContainingModule(AppDomain
}
CONTRACTL_END;
- DomainAssembly * pDomainAssembly = m_pModule->GetDomainAssembly();
- if ((pDomainAssembly != NULL) && (pDomainAssembly->IsAvailableToProfilers()))
+ DomainFile * pDomainFile = m_pModule->GetDomainFile();
+ if ((pDomainFile != NULL) && (pDomainFile->IsAvailableToProfilers()))
{
if (m_index < m_cAppDomainIds)
{
diff --git a/src/coreclr/vm/proftoeeinterfaceimpl.cpp b/src/coreclr/vm/proftoeeinterfaceimpl.cpp
index 5162ac38a3bb4..749fa73126b08 100644
--- a/src/coreclr/vm/proftoeeinterfaceimpl.cpp
+++ b/src/coreclr/vm/proftoeeinterfaceimpl.cpp
@@ -1274,7 +1274,7 @@ bool AllocByClassHelper(Object * pBO, void * pv)
_ASSERTE(pv != NULL);
{
- BEGIN_PROFILER_CALLBACK(CORProfilerTrackGC());
+ BEGIN_PROFILER_CALLBACK(CORProfilerTrackAllocations());
// Pass along the call
g_profControlBlock.AllocByClass(
(ObjectID) pBO,
@@ -5710,7 +5710,7 @@ HRESULT ProfToEEInterfaceImpl::GetAssemblyInfo(AssemblyID assemblyId,
// Find the module the manifest lives in.
if (pModuleId)
{
- *pModuleId = (ModuleID) pAssembly->GetModule();
+ *pModuleId = (ModuleID) pAssembly->GetManifestModule();
// This is the case where the profiler has called GetAssemblyInfo
// on an assembly that has been completely created yet.
diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp
index 2d5d1cfc92b37..96971b8180195 100644
--- a/src/coreclr/vm/qcallentrypoints.cpp
+++ b/src/coreclr/vm/qcallentrypoints.cpp
@@ -27,6 +27,7 @@
#include "comdatetime.h"
#include "compatibilityswitch.h"
#include "debugdebugger.h"
+#include "assemblyname.hpp"
#include "assemblynative.hpp"
#include "comthreadpool.h"
#include "comwaithandle.h"
diff --git a/src/coreclr/vm/reflectioninvocation.cpp b/src/coreclr/vm/reflectioninvocation.cpp
index e49ad881f5fe5..495e10e4f4a36 100644
--- a/src/coreclr/vm/reflectioninvocation.cpp
+++ b/src/coreclr/vm/reflectioninvocation.cpp
@@ -1579,17 +1579,19 @@ extern "C" void QCALLTYPE ReflectionInvocation_RunClassConstructor(QCall::TypeHa
END_QCALL;
}
-// This method triggers the module constructor for a given module
+// This method triggers the module constructor for a give module
extern "C" void QCALLTYPE ReflectionInvocation_RunModuleConstructor(QCall::ModuleHandle pModule)
{
QCALL_CONTRACT;
- DomainAssembly *pDomainAssembly = pModule->GetDomainAssembly();
- if (pDomainAssembly != NULL && pDomainAssembly->IsActive())
+ DomainFile *pDomainFile = pModule->GetDomainFile();
+ if (pDomainFile != NULL && pDomainFile->IsActive())
return;
BEGIN_QCALL;
- pDomainAssembly->EnsureActive();
+ if(pDomainFile == NULL)
+ pDomainFile = pModule->GetDomainFile();
+ pDomainFile->EnsureActive();
END_QCALL;
}
diff --git a/src/coreclr/vm/rejit.cpp b/src/coreclr/vm/rejit.cpp
index 80f05489ad3b2..aaf335390764c 100644
--- a/src/coreclr/vm/rejit.cpp
+++ b/src/coreclr/vm/rejit.cpp
@@ -811,31 +811,35 @@ HRESULT ReJitManager::UpdateNativeInlinerActiveILVersions(
_ASSERTE(pDomainAssembly != NULL);
_ASSERTE(pDomainAssembly->GetAssembly() != NULL);
- Module * pModule = pDomainAssembly->GetModule();
- if (pModule->HasReadyToRunInlineTrackingMap())
+ DomainModuleIterator domainModuleIterator = pDomainAssembly->IterateModules(kModIterIncludeLoaded);
+ while (domainModuleIterator.Next())
{
- inlinerIter.Reset(pModule, pInlinee);
-
- MethodDesc *pInliner = NULL;
- while (inlinerIter.Next())
+ Module * pCurModule = domainModuleIterator.GetModule();
+ if (pCurModule->HasReadyToRunInlineTrackingMap())
{
- pInliner = inlinerIter.GetMethodDesc();
+ inlinerIter.Reset(pCurModule, pInlinee);
+
+ MethodDesc *pInliner = NULL;
+ while (inlinerIter.Next())
{
- CodeVersionManager *pCodeVersionManager = pModule->GetCodeVersionManager();
- CodeVersionManager::LockHolder codeVersioningLockHolder;
- ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(pInliner);
- if (!ilVersion.HasDefaultIL())
+ pInliner = inlinerIter.GetMethodDesc();
{
- // This method has already been ReJITted, no need to request another ReJIT at this point.
- // The ReJITted method will be in the JIT inliner check below.
- continue;
+ CodeVersionManager *pCodeVersionManager = pCurModule->GetCodeVersionManager();
+ CodeVersionManager::LockHolder codeVersioningLockHolder;
+ ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(pInliner);
+ if (!ilVersion.HasDefaultIL())
+ {
+ // This method has already been ReJITted, no need to request another ReJIT at this point.
+ // The ReJITted method will be in the JIT inliner check below.
+ continue;
+ }
}
- }
- hr = UpdateActiveILVersion(pMgrToCodeActivationBatch, pInliner->GetModule(), pInliner->GetMemberDef(), fIsRevert, flags);
- if (FAILED(hr))
- {
- ReportReJITError(pInliner->GetModule(), pInliner->GetMemberDef(), NULL, hr);
+ hr = UpdateActiveILVersion(pMgrToCodeActivationBatch, pInliner->GetModule(), pInliner->GetMemberDef(), fIsRevert, flags);
+ if (FAILED(hr))
+ {
+ ReportReJITError(pInliner->GetModule(), pInliner->GetMemberDef(), NULL, hr);
+ }
}
}
}
diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp
index 362ea14986498..41057e01620d3 100644
--- a/src/coreclr/vm/runtimehandles.cpp
+++ b/src/coreclr/vm/runtimehandles.cpp
@@ -186,9 +186,9 @@ NOINLINE ReflectModuleBaseObject* GetRuntimeModuleHelper(LPVOID __me, Module *pM
if (pModule == NULL)
return NULL;
- DomainAssembly * pDomainAssembly = pModule->GetDomainAssembly();
+ DomainFile * pDomainFile = pModule->GetDomainFile();
- OBJECTREF refModule = (pDomainAssembly != NULL) ? pDomainAssembly->GetExposedModuleObjectIfExists() : NULL;
+ OBJECTREF refModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
if(refModule != NULL)
return (ReflectModuleBaseObject*)OBJECTREFToObject(refModule);
@@ -354,7 +354,7 @@ FCIMPL1(AssemblyBaseObject*, RuntimeTypeHandle::GetAssembly, ReflectClassBaseObj
if (refType == NULL)
FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
- Module *pModule = refType->GetType().GetAssembly()->GetModule();
+ Module *pModule = refType->GetType().GetAssembly()->GetManifestModule();
DomainAssembly *pDomainAssembly = pModule->GetDomainAssembly();
FC_RETURN_ASSEMBLY_OBJECT(pDomainAssembly, refType);
@@ -2667,20 +2667,20 @@ FCIMPL1(ReflectModuleBaseObject*, AssemblyHandle::GetManifestModule, AssemblyBas
FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
- Assembly* currentAssembly = pAssembly->GetAssembly();
+ Assembly* currentAssembly = pAssembly->GetCurrentAssembly();
- Module *pModule = currentAssembly->GetModule();
- DomainAssembly * pDomainAssembly = pModule->GetDomainAssembly();
+ Module *pModule = currentAssembly->GetManifestModule();
+ DomainFile * pDomainFile = pModule->GetDomainFile();
#ifdef _DEBUG
OBJECTREF orModule;
HELPER_METHOD_FRAME_BEGIN_RET_1(refAssembly);
- orModule = (pDomainAssembly != NULL) ? pDomainAssembly->GetExposedModuleObjectIfExists() : NULL;
+ orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
if (orModule == NULL)
orModule = pModule->GetExposedObject();
#else
- OBJECTREF orModule = (pDomainAssembly != NULL) ? pDomainAssembly->GetExposedModuleObjectIfExists() : NULL;
+ OBJECTREF orModule = (pDomainFile != NULL) ? pDomainFile->GetExposedModuleObjectIfExists() : NULL;
if (orModule != NULL)
return (ReflectModuleBaseObject*)OBJECTREFToObject(orModule);
@@ -2705,7 +2705,7 @@ FCIMPL1(INT32, AssemblyHandle::GetToken, AssemblyBaseObject* pAssemblyUNSAFE) {
DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
mdAssembly token = mdAssemblyNil;
- IMDInternalImport *mdImport = pAssembly->GetAssembly()->GetMDImport();
+ IMDInternalImport *mdImport = pAssembly->GetCurrentAssembly()->GetManifestImport();
if (mdImport != 0)
{
@@ -2905,7 +2905,7 @@ FCIMPL5(ReflectMethodObject*, ModuleHandle::GetDynamicMethod, ReflectMethodObjec
HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
- DomainAssembly *pDomainModule = pModule->GetDomainAssembly();
+ DomainFile *pDomainModule = pModule->GetDomainFile();
U1ARRAYREF dataArray = (U1ARRAYREF)sig;
DWORD sigSize = dataArray->GetNumComponents();
diff --git a/src/coreclr/vm/siginfo.cpp b/src/coreclr/vm/siginfo.cpp
index 5a277914d8cee..a197fbc87cabd 100644
--- a/src/coreclr/vm/siginfo.cpp
+++ b/src/coreclr/vm/siginfo.cpp
@@ -4903,67 +4903,20 @@ void PromoteCarefully(promote_func fn,
(*fn) (ppObj, sc, flags);
}
-class ByRefPointerOffsetsReporter
-{
- promote_func* _fn;
- ScanContext* _sc;
- PTR_VOID _src;
-
- void Report(SIZE_T pointerOffset)
- {
- WRAPPER_NO_CONTRACT;
- PTR_PTR_Object fieldRef = dac_cast(PTR_BYTE(_src) + pointerOffset);
- (*_fn)(fieldRef, _sc, GC_CALL_INTERIOR);
- }
-
-public:
- ByRefPointerOffsetsReporter(promote_func* fn, ScanContext* sc, PTR_VOID pSrc)
- : _fn{fn}
- , _sc{sc}
- , _src{pSrc}
- {
- WRAPPER_NO_CONTRACT;
- }
-
- void Find(PTR_MethodTable pMT, SIZE_T baseOffset)
- {
- WRAPPER_NO_CONTRACT;
- _ASSERTE(pMT != nullptr);
- _ASSERTE(pMT->IsByRefLike());
-
- if (pMT->HasSameTypeDefAs(g_pByReferenceClass))
- {
- Report(baseOffset);
- return;
- }
-
- ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS);
- for (FieldDesc* pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next())
- {
- if (pFD->GetFieldType() == ELEMENT_TYPE_VALUETYPE)
- {
- PTR_MethodTable pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable();
- if (pFieldMT->IsByRefLike())
- {
- Find(pFieldMT, baseOffset + pFD->GetOffset());
- }
- }
- else if (pFD->IsByRef())
- {
- Report(baseOffset + pFD->GetOffset());
- }
- }
- }
-};
-
void ReportPointersFromValueType(promote_func *fn, ScanContext *sc, PTR_MethodTable pMT, PTR_VOID pSrc)
{
WRAPPER_NO_CONTRACT;
if (pMT->IsByRefLike())
{
- ByRefPointerOffsetsReporter reporter{fn, sc, pSrc};
- reporter.Find(pMT, 0 /* baseOffset */);
+ FindByRefPointerOffsetsInByRefLikeObject(
+ pMT,
+ 0 /* baseOffset */,
+ [&](SIZE_T pointerOffset)
+ {
+ PTR_PTR_Object fieldRef = dac_cast(PTR_BYTE(pSrc) + pointerOffset);
+ (*fn)(fieldRef, sc, GC_CALL_INTERIOR);
+ });
}
if (!pMT->ContainsPointers())
diff --git a/src/coreclr/vm/stubgen.cpp b/src/coreclr/vm/stubgen.cpp
index 2249756c3358a..f829212a8ef6e 100644
--- a/src/coreclr/vm/stubgen.cpp
+++ b/src/coreclr/vm/stubgen.cpp
@@ -2669,7 +2669,7 @@ void ILStubLinker::TransformArgForJIT(LocalDesc *pLoc)
// JIT will handle structures
if (pLoc->InternalToken.IsValueType())
{
- _ASSERTE(pLoc->InternalToken.IsNativeValueType() || !pLoc->InternalToken.GetMethodTable()->ContainsPointers());
+ _ASSERTE(pLoc->InternalToken.IsBlittable());
break;
}
FALLTHROUGH;
diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp
index 20bdfcc6fcc6e..200d36586ef52 100644
--- a/src/coreclr/vm/threads.cpp
+++ b/src/coreclr/vm/threads.cpp
@@ -1124,12 +1124,8 @@ extern "C" void *JIT_WriteBarrier_Loc;
#ifdef TARGET_ARM64
extern "C" void (*JIT_WriteBarrier_Table)();
-
-extern "C" void *JIT_WriteBarrier_Loc;
-void *JIT_WriteBarrier_Loc = 0;
-
-extern "C" void *JIT_WriteBarrier_Table_Loc;
-void *JIT_WriteBarrier_Table_Loc = 0;
+extern "C" void *JIT_WriteBarrier_Loc = 0;
+extern "C" void *JIT_WriteBarrier_Table_Loc = 0;
#endif // TARGET_ARM64
#ifdef TARGET_ARM
@@ -8530,8 +8526,8 @@ Thread::EnumMemoryRegionsWorker(CLRDataEnumMemoryFlags flags)
DacEnumCodeForStackwalk(callEnd);
// To stackwalk through funceval frames, we need to be sure to preserve the
- // DebuggerModule's m_pRuntimeDomainAssembly. This is the only case that doesn't use the current
- // vmDomainAssembly in code:DacDbiInterfaceImpl::EnumerateInternalFrames. The following
+ // DebuggerModule's m_pRuntimeDomainFile. This is the only case that doesn't use the current
+ // vmDomainFile in code:DacDbiInterfaceImpl::EnumerateInternalFrames. The following
// code mimics that function.
// Allow failure, since we want to continue attempting to walk the stack regardless of the outcome.
EX_TRY
diff --git a/src/coreclr/vm/threads.h b/src/coreclr/vm/threads.h
index f51f75445b399..1bfccb85e10d6 100644
--- a/src/coreclr/vm/threads.h
+++ b/src/coreclr/vm/threads.h
@@ -132,7 +132,7 @@ class Frame;
class ThreadBaseObject;
class AppDomainStack;
class LoadLevelLimiter;
-class DomainAssembly;
+class DomainFile;
class DeadlockAwareLock;
struct HelperMethodFrameCallerList;
class ThreadLocalIBCInfo;
diff --git a/src/coreclr/vm/typeparse.cpp b/src/coreclr/vm/typeparse.cpp
index dab28d4703f17..524a9e595bc24 100644
--- a/src/coreclr/vm/typeparse.cpp
+++ b/src/coreclr/vm/typeparse.cpp
@@ -1273,7 +1273,7 @@ TypeName::GetTypeHaveAssemblyHelper(
TypeHandle th = TypeHandle();
SArray & names = GetNames();
- Module * pManifestModule = pAssembly->GetModule();
+ Module * pManifestModule = pAssembly->GetManifestModule();
Module * pLookOnlyInModule = NULL;
ClassLoader * pClassLoader = pAssembly->GetLoader();
@@ -1427,7 +1427,7 @@ DomainAssembly * LoadDomainAssembly(
{
// If the requesting assembly has Fallback LoadContext binder available,
// then set it up in the AssemblySpec.
- PEAssembly *pRequestingAssemblyManifestFile = pRequestingAssembly->GetPEAssembly();
+ PEAssembly *pRequestingAssemblyManifestFile = pRequestingAssembly->GetManifestFile();
spec.SetFallbackBinderForRequestingAssembly(pRequestingAssemblyManifestFile->GetFallbackBinder());
}
diff --git a/src/coreclr/vm/util.cpp b/src/coreclr/vm/util.cpp
index 12a4ed3225739..026ba5da743a5 100644
--- a/src/coreclr/vm/util.cpp
+++ b/src/coreclr/vm/util.cpp
@@ -329,6 +329,22 @@ void NPrintToHandleA(HANDLE Handle, const char *pszString, size_t BytesToWrite)
while (BytesToWrite > 0) {
DWORD dwChunkToWrite = (DWORD) min(BytesToWrite, maxWriteFileSize);
+ // No CharNextExA on CoreSystem, we just assume no multi-byte characters (this code path shouldn't be
+ // used in the production codepath for currently supported CoreSystem based products anyway).
+#ifndef FEATURE_CORESYSTEM
+ if (dwChunkToWrite < BytesToWrite) {
+ break;
+ // must go by char to find biggest string that will fit, taking DBCS chars into account
+ //dwChunkToWrite = 0;
+ //const char *charNext = pszString;
+ //while (dwChunkToWrite < maxWriteFileSize-2 && charNext) {
+ // charNext = CharNextExA(0, pszString+dwChunkToWrite, 0);
+ // dwChunkToWrite = (DWORD)(charNext - pszString);
+ //}
+ //if (dwChunkToWrite == 0)
+ // break;
+ }
+#endif // !FEATURE_CORESYSTEM
// Try to write to handle. If this is not a CUI app, then this is probably
// not going to work unless the dev took special pains to set their own console
diff --git a/src/coreclr/vm/win32threadpool.cpp b/src/coreclr/vm/win32threadpool.cpp
index 3e16f18a2d83b..7ffbc34948a47 100644
--- a/src/coreclr/vm/win32threadpool.cpp
+++ b/src/coreclr/vm/win32threadpool.cpp
@@ -494,7 +494,11 @@ void ThreadpoolMgr::InitPlatformVariables()
_ASSERTE(hNtDll);
if (!UsePortableThreadPool())
{
+#ifdef FEATURE_CORESYSTEM
hCoreSynch = CLRLoadLibrary(W("api-ms-win-core-synch-l1-1-0.dll"));
+#else
+ hCoreSynch = CLRLoadLibrary(W("kernel32.dll"));
+#endif
_ASSERTE(hCoreSynch);
}
}
@@ -3995,7 +3999,7 @@ DWORD WINAPI ThreadpoolMgr::GateThreadStart(LPVOID lpArgs)
* 2. GCCpuGroups=1, CLR creates GC threads for all processors in all CPU groups
* thus, the threadpool thread would use a whole CPU group (if Thread_UseAllCpuGroups is not set).
* ==> use g_SystemInfo.dwNumberOfProcessors.
- * 3. !defined(TARGET_UNIX), GetCurrentProcessCpuCount()
+ * 3. !defined(TARGET_UNIX) but defined(FEATURE_CORESYSTEM), GetCurrentProcessCpuCount()
* returns g_SystemInfo.dwNumberOfProcessors ==> use g_SystemInfo.dwNumberOfProcessors;
* Other cases:
* 1. Normal case: the mask is all or a subset of all processors in a CPU group;
diff --git a/src/coreclr/vm/zapsig.cpp b/src/coreclr/vm/zapsig.cpp
index b66c7b1057138..dbdff7a98c8f5 100644
--- a/src/coreclr/vm/zapsig.cpp
+++ b/src/coreclr/vm/zapsig.cpp
@@ -620,7 +620,7 @@ Module *ZapSig::DecodeModuleFromIndex(Module *fromModule,
}
}
- return pAssembly->GetModule();
+ return pAssembly->GetManifestModule();
}
Module *ZapSig::DecodeModuleFromIndexIfLoaded(Module *fromModule,
@@ -686,7 +686,7 @@ Module *ZapSig::DecodeModuleFromIndexIfLoaded(Module *fromModule,
if (pAssembly == NULL)
return NULL;
- return pAssembly->GetModule();
+ return pAssembly->GetManifestModule();
}
diff --git a/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs b/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs
index e1e81da93ff4d..f17bbbe6378cc 100644
--- a/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs
+++ b/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs
@@ -94,7 +94,7 @@ void UpdateResources()
try
{
// Open the source host file.
- appHostSourceStream = new FileStream(appHostSourceFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1);
+ appHostSourceStream = new FileStream(appHostSourceFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
memoryMappedFile = MemoryMappedFile.CreateFromFile(appHostSourceStream, null, 0, MemoryMappedFileAccess.Read, HandleInheritability.None, true);
memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.CopyOnWrite);
diff --git a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Directory.Build.props b/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Directory.Build.props
deleted file mode 100644
index 1f343d09fe105..0000000000000
--- a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Directory.Build.props
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- $(MSBuildThisFileDirectory)ILCompilerRIDs.props
-
-
-
-
-
diff --git a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/ILCompilerRIDs.props b/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/ILCompilerRIDs.props
deleted file mode 100644
index 70e13f311b74a..0000000000000
--- a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/ILCompilerRIDs.props
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Microsoft.DotNet.ILCompiler.pkgproj b/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Microsoft.DotNet.ILCompiler.pkgproj
deleted file mode 100644
index 65fd54d7bf3fb..0000000000000
--- a/src/installer/pkg/projects/Microsoft.DotNet.ILCompiler/Microsoft.DotNet.ILCompiler.pkgproj
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
- true
- true
- Provides a native AOT compiler and runtime for .NET
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/installer/pkg/projects/nativeaot-packages.proj b/src/installer/pkg/projects/nativeaot-packages.proj
deleted file mode 100644
index 10ab1d60c56fa..0000000000000
--- a/src/installer/pkg/projects/nativeaot-packages.proj
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/installer/pkg/projects/netcoreappRIDs.props b/src/installer/pkg/projects/netcoreappRIDs.props
index 6282d87b88a92..37fa250ded667 100644
--- a/src/installer/pkg/projects/netcoreappRIDs.props
+++ b/src/installer/pkg/projects/netcoreappRIDs.props
@@ -26,9 +26,6 @@
arm
-
- armv6
-
arm64
diff --git a/src/libraries/Common/src/Internal/Cryptography/AsymmetricAlgorithmHelpers.Der.cs b/src/libraries/Common/src/Internal/Cryptography/AsymmetricAlgorithmHelpers.Der.cs
index d3c442760423c..b750a2de5e9d8 100644
--- a/src/libraries/Common/src/Internal/Cryptography/AsymmetricAlgorithmHelpers.Der.cs
+++ b/src/libraries/Common/src/Internal/Cryptography/AsymmetricAlgorithmHelpers.Der.cs
@@ -143,6 +143,7 @@ static int GetDerLengthLength(int payloadLength)
}
}
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
///
/// Converts IeeeP1363 format to the specified signature format
///
@@ -181,6 +182,7 @@ internal static byte[] ConvertSignatureToIeeeP1363(
currentFormat.ToString());
}
}
+#endif
public static int BitsToBytes(int bitLength)
{
@@ -212,6 +214,7 @@ private static void CopySignatureField(ReadOnlySpan signatureField, Span signatureField, Span source, Span destination
hashAlgorithm == HashAlgorithmName.MD5 ? MD5.TryHashData(source, destination, out bytesWritten) :
throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithm.Name);
}
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 is used when the user asks for it.")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "MD5 is used when the user asks for it.")]
+ private static HashAlgorithm GetHashAlgorithm(HashAlgorithmName hashAlgorithmName) =>
+ hashAlgorithmName == HashAlgorithmName.SHA256 ? SHA256.Create() :
+ hashAlgorithmName == HashAlgorithmName.SHA1 ? SHA1.Create() :
+ hashAlgorithmName == HashAlgorithmName.SHA512 ? SHA512.Create() :
+ hashAlgorithmName == HashAlgorithmName.SHA384 ? SHA384.Create() :
+ hashAlgorithmName == HashAlgorithmName.MD5 ? MD5.Create() :
+ throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName.Name);
}
}
diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Hmac.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Hmac.cs
index 993d6d42ae751..6cf3766ad8ed5 100644
--- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Hmac.cs
+++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Hmac.cs
@@ -16,15 +16,7 @@ internal static partial class AppleCrypto
internal static partial SafeHmacHandle HmacCreate(PAL_HashAlgorithm algorithm, ref int cbDigest);
[GeneratedDllImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_HmacInit")]
- private static unsafe partial int HmacInit(SafeHmacHandle ctx, byte* pbKey, int cbKey);
-
- internal static unsafe int HmacInit(SafeHmacHandle ctx, ReadOnlySpan key)
- {
- fixed (byte* pKey = &MemoryMarshal.GetReference(key))
- {
- return HmacInit(ctx, pKey, key.Length);
- }
- }
+ internal static partial int HmacInit(SafeHmacHandle ctx, byte[] pbKey, int cbKey);
internal static int HmacUpdate(SafeHmacHandle ctx, ReadOnlySpan data) =>
HmacUpdate(ctx, ref MemoryMarshal.GetReference(data), data.Length);
diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.IPAddress.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.IPAddress.cs
index 4bbd79987510b..567f97df901ce 100644
--- a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.IPAddress.cs
+++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.IPAddress.cs
@@ -2,8 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics;
using System.Runtime.InteropServices;
+using System.Text;
internal static partial class Interop
{
@@ -32,19 +33,6 @@ public bool IsIPv6
private uint _isIPv6; // Non-zero if this is an IPv6 address; zero for IPv4.
internal uint ScopeId; // Scope ID (IPv6 only)
- public override unsafe int GetHashCode()
- {
- HashCode h = default;
- fixed (byte* ptr = Address)
- {
- h.AddBytes(new ReadOnlySpan(ptr, IsIPv6 ? IPv6AddressBytes : IPv4AddressBytes));
- }
- return h.ToHashCode();
- }
-
- public override bool Equals([NotNullWhen(true)] object? obj) =>
- obj is IPAddress other && Equals(other);
-
public bool Equals(IPAddress other)
{
int addressByteCount;
diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.LChflags.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.LChflags.cs
index cbc05ad5a85b6..2b1b67784e87d 100644
--- a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.LChflags.cs
+++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.LChflags.cs
@@ -25,11 +25,5 @@ internal enum UserFlags : uint
[GeneratedDllImport(Libraries.SystemNative, EntryPoint = "SystemNative_LChflagsCanSetHiddenFlag")]
[SuppressGCTransition]
private static partial int LChflagsCanSetHiddenFlag();
-
- internal static readonly bool SupportsHiddenFlag = (CanGetHiddenFlag() != 0);
-
- [GeneratedDllImport(Libraries.SystemNative, EntryPoint = "SystemNative_CanGetHiddenFlag")]
- [SuppressGCTransition]
- private static partial int CanGetHiddenFlag();
}
}
diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs
index 95e9ab89fc505..593c6f4e593f6 100644
--- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs
+++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs
@@ -105,28 +105,18 @@ internal static unsafe SafeEvpPKeyHandle DecodePkcs8PrivateKey(
}
[GeneratedDllImport(Libraries.CryptoNative)]
- private static partial int CryptoNative_GetPkcs8PrivateKeySize(IntPtr pkey, out int p8size);
+ private static partial int CryptoNative_GetPkcs8PrivateKeySize(IntPtr pkey);
private static int GetPkcs8PrivateKeySize(IntPtr pkey)
{
- const int Success = 1;
- const int Error = -1;
- const int MissingPrivateKey = -2;
+ int ret = CryptoNative_GetPkcs8PrivateKeySize(pkey);
- int ret = CryptoNative_GetPkcs8PrivateKeySize(pkey, out int p8size);
-
- switch (ret)
+ if (ret < 0)
{
- case Success:
- return p8size;
- case Error:
- throw CreateOpenSslCryptographicException();
- case MissingPrivateKey:
- throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
- default:
- Debug.Fail($"Unexpected return '{ret}' value from {nameof(CryptoNative_GetPkcs8PrivateKeySize)}.");
- throw new CryptographicException();
+ throw CreateOpenSslCryptographicException();
}
+
+ return ret;
}
[GeneratedDllImport(Libraries.CryptoNative)]
diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs
index 12b75443f7472..d403daac342ad 100644
--- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs
+++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs
@@ -327,9 +327,12 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia
Crypto.ErrClearError();
}
- // Set client cert callback, this will interrupt the handshake with SecurityStatusPalErrorCode.CredentialsNeeded
- // if server actually requests a certificate.
- Ssl.SslSetClientCertCallback(sslHandle, 1);
+ if (sslAuthenticationOptions.CertSelectionDelegate != null && sslAuthenticationOptions.CertificateContext == null)
+ {
+ // We don't have certificate but we have callback. We should wait for remote certificate and
+ // possible trusted issuer list.
+ Interop.Ssl.SslSetClientCertCallback(sslHandle, 1);
+ }
}
if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired)
diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs
index 379ab7586ed38..c01b829cd189d 100644
--- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs
+++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs
@@ -6,7 +6,6 @@
using System.Diagnostics;
using System.Net.Security;
using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Win32.SafeHandles;
@@ -48,7 +47,7 @@ internal static partial class Ssl
internal static partial void SslSetAcceptState(SafeSslHandle ssl);
[GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslSetAlpnProtos")]
- internal static unsafe partial int SslSetAlpnProtos(SafeSslHandle ssl, byte* protos, int len);
+ internal static partial int SslSetAlpnProtos(SafeSslHandle ssl, IntPtr protos, int len);
[GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslGetVersion")]
internal static partial IntPtr SslGetVersion(SafeSslHandle ssl);
@@ -169,7 +168,16 @@ internal static class Capabilities
internal static readonly bool Tls13Supported = Tls13SupportedImpl() != 0;
}
- internal static int GetAlpnProtocolListSerializedLength(List applicationProtocols)
+ internal static unsafe int SslSetAlpnProtos(SafeSslHandle ssl, List protocols)
+ {
+ byte[] buffer = ConvertAlpnProtocolListToByteArray(protocols);
+ fixed (byte* b = buffer)
+ {
+ return SslSetAlpnProtos(ssl, (IntPtr)b, buffer.Length);
+ }
+ }
+
+ internal static byte[] ConvertAlpnProtocolListToByteArray(List applicationProtocols)
{
int protocolSize = 0;
foreach (SslApplicationProtocol protocol in applicationProtocols)
@@ -182,37 +190,16 @@ internal static int GetAlpnProtocolListSerializedLength(List applicationProtocols, Span buffer)
- {
- Debug.Assert(GetAlpnProtocolListSerializedLength(applicationProtocols) == buffer.Length,
- "GetAlpnProtocolListSerializedSize(applicationProtocols) == buffer.Length");
-
- int offset = 0;
+ byte[] buffer = new byte[protocolSize];
+ var offset = 0;
foreach (SslApplicationProtocol protocol in applicationProtocols)
{
- buffer[offset++] = (byte)protocol.Protocol.Length;
- protocol.Protocol.Span.CopyTo(buffer.Slice(offset));
+ buffer[offset++] = (byte)(protocol.Protocol.Length);
+ protocol.Protocol.Span.CopyTo(buffer.AsSpan(offset));
offset += protocol.Protocol.Length;
}
- }
-
- internal static unsafe int SslSetAlpnProtos(SafeSslHandle ssl, List applicationProtocols)
- {
- int length = GetAlpnProtocolListSerializedLength(applicationProtocols);
- Span buffer = length <= 256 ? stackalloc byte[256].Slice(0, length) : new byte[length];
- SerializeAlpnProtocolList(applicationProtocols, buffer);
- return SslSetAlpnProtos(ssl, buffer);
- }
- internal static unsafe int SslSetAlpnProtos(SafeSslHandle ssl, Span serializedProtocols)
- {
- fixed (byte* pBuffer = &MemoryMarshal.GetReference(serializedProtocols))
- {
- return SslSetAlpnProtos(ssl, pBuffer, serializedProtocols.Length);
- }
+ return buffer;
}
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslAddExtraChainCert")]
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptCreateHash.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptCreateHash.cs
index b57a4b0f61927..0a60ee7918ac3 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptCreateHash.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptCreateHash.cs
@@ -19,7 +19,7 @@ internal enum CryptCreateHashFlags : int
internal static partial bool CryptCreateHash(
SafeProvHandle hProv,
int Algid,
- SafeCapiKeyHandle hKey,
+ SafeKeyHandle hKey,
CryptCreateHashFlags dwFlags,
out SafeHashHandle phHash);
}
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDecrypt.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDecrypt.cs
index 3f05d5c223e7c..7865c1180ff8f 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDecrypt.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDecrypt.cs
@@ -16,7 +16,7 @@ internal enum CryptDecryptFlags : int
[GeneratedDllImport(Libraries.Advapi32, SetLastError = true)]
public static partial bool CryptDecrypt(
- SafeCapiKeyHandle hKey,
+ SafeKeyHandle hKey,
SafeHashHandle hHash,
bool Final,
int dwFlags,
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDeriveKey.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDeriveKey.cs
index 51b77aef3d0ac..2bc7d4ed8d8ba 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDeriveKey.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptDeriveKey.cs
@@ -14,6 +14,6 @@ internal static partial bool CryptDeriveKey(
int Algid,
SafeHashHandle hBaseData,
int dwFlags,
- out SafeCapiKeyHandle phKey);
+ out SafeKeyHandle phKey);
}
}
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptEncrypt.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptEncrypt.cs
index 17e50c1e59d0f..fa883e5eef421 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptEncrypt.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptEncrypt.cs
@@ -10,7 +10,7 @@ internal static partial class Advapi32
{
[GeneratedDllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, SetLastError = true)]
public static partial bool CryptEncrypt(
- SafeCapiKeyHandle hKey,
+ SafeKeyHandle hKey,
SafeHashHandle hHash,
bool Final,
int dwFlags,
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptExportKey.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptExportKey.cs
index 633997f99880e..9eb16f4019035 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptExportKey.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptExportKey.cs
@@ -10,8 +10,8 @@ internal static partial class Advapi32
{
[GeneratedDllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, SetLastError = true)]
public static partial bool CryptExportKey(
- SafeCapiKeyHandle hKey,
- SafeCapiKeyHandle hExpKey,
+ SafeKeyHandle hKey,
+ SafeKeyHandle hExpKey,
int dwBlobType,
int dwFlags,
byte[]? pbData,
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGenKey.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGenKey.cs
index cf6aaf36b1c15..d19c090d84d60 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGenKey.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGenKey.cs
@@ -9,6 +9,6 @@ internal static partial class Interop
internal static partial class Advapi32
{
[GeneratedDllImport(Libraries.Advapi32, CharSet = CharSet.Unicode, SetLastError = true)]
- internal static partial bool CryptGenKey(SafeProvHandle hProv, int Algid, int dwFlags, out SafeCapiKeyHandle phKey);
+ internal static partial bool CryptGenKey(SafeProvHandle hProv, int Algid, int dwFlags, out SafeKeyHandle phKey);
}
}
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetKeyParam.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetKeyParam.cs
index 63f33ffa39227..9737c2b066388 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetKeyParam.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetKeyParam.cs
@@ -19,7 +19,7 @@ internal enum CryptGetKeyParamFlags : int
[GeneratedDllImport(Libraries.Advapi32, SetLastError = true)]
public static partial bool CryptGetKeyParam(
- SafeCapiKeyHandle hKey,
+ SafeKeyHandle hKey,
CryptGetKeyParamFlags dwParam,
byte[]? pbData,
ref int pdwDataLen,
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetUserKey.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetUserKey.cs
index 88b5d00e56389..c5080a0078470 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetUserKey.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptGetUserKey.cs
@@ -9,6 +9,6 @@ internal static partial class Interop
internal static partial class Advapi32
{
[GeneratedDllImport(Libraries.Advapi32, SetLastError = true)]
- internal static partial bool CryptGetUserKey(SafeProvHandle hProv, int dwKeySpec, out SafeCapiKeyHandle phUserKey);
+ internal static partial bool CryptGetUserKey(SafeProvHandle hProv, int dwKeySpec, out SafeKeyHandle phUserKey);
}
}
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptImportKey.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptImportKey.cs
index 3c8cb90d99f5c..f5e73879d99ca 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptImportKey.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptImportKey.cs
@@ -13,8 +13,8 @@ internal static unsafe partial bool CryptImportKey(
SafeProvHandle hProv,
byte* pbData,
int dwDataLen,
- SafeCapiKeyHandle hPubKey,
+ SafeKeyHandle hPubKey,
int dwFlags,
- out SafeCapiKeyHandle phKey);
+ out SafeKeyHandle phKey);
}
}
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSetKeyParam.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSetKeyParam.cs
index 07d510705e2f7..5fb1c83ff37e5 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSetKeyParam.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSetKeyParam.cs
@@ -9,9 +9,9 @@ internal static partial class Interop
internal static partial class Advapi32
{
[GeneratedDllImport(Libraries.Advapi32, SetLastError = true)]
- public static partial bool CryptSetKeyParam(SafeCapiKeyHandle hKey, int dwParam, byte[] pbData, int dwFlags);
+ public static partial bool CryptSetKeyParam(SafeKeyHandle hKey, int dwParam, byte[] pbData, int dwFlags);
[GeneratedDllImport(Libraries.Advapi32, SetLastError = true)]
- public static partial bool CryptSetKeyParam(SafeCapiKeyHandle safeKeyHandle, int dwParam, ref int pdw, int dwFlags);
+ public static partial bool CryptSetKeyParam(SafeKeyHandle safeKeyHandle, int dwParam, ref int pdw, int dwFlags);
}
}
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSignHash.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSignHash.cs
index dd7a12c30b397..0d9f3a1703141 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSignHash.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptSignHash.cs
@@ -38,7 +38,7 @@ public static partial bool CryptVerifySignature(
SafeHashHandle hHash,
byte[] pbSignature,
int dwSigLen,
- SafeCapiKeyHandle hPubKey,
+ SafeKeyHandle hPubKey,
string? szDescription,
CryptSignAndVerifyHashFlags dwFlags);
}
diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/SafeKeyHandle.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/SafeKeyHandle.cs
index b8a0e5c944b20..5f12dd16db064 100644
--- a/src/libraries/Common/src/Interop/Windows/Advapi32/SafeKeyHandle.cs
+++ b/src/libraries/Common/src/Interop/Windows/Advapi32/SafeKeyHandle.cs
@@ -16,13 +16,13 @@ namespace System.Security.Cryptography
/// of the key handle and provider handle. This also applies to hash handles, which point to a
/// CRYPT_HASH_CTX. Those structures are defined in COMCryptography.h
///
- internal sealed class SafeCapiKeyHandle : SafeHandleZeroOrMinusOneIsInvalid
+ internal sealed class SafeKeyHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private int _keySpec;
private bool _fPublicOnly;
private SafeProvHandle? _parent;
- public SafeCapiKeyHandle() : base(true)
+ public SafeKeyHandle() : base(true)
{
SetHandle(IntPtr.Zero);
_keySpec = 0;
@@ -70,14 +70,14 @@ internal void SetParent(SafeProvHandle parent)
_parent.DangerousAddRef(ref ignored);
}
- internal static SafeCapiKeyHandle InvalidHandle
+ internal static SafeKeyHandle InvalidHandle
{
- get { return SafeHandleCache.GetInvalidHandle(() => new SafeCapiKeyHandle()); }
+ get { return SafeHandleCache.GetInvalidHandle(() => new SafeKeyHandle()); }
}
protected override void Dispose(bool disposing)
{
- if (!SafeHandleCache.IsCachedInvalidHandle(this))
+ if (!SafeHandleCache.IsCachedInvalidHandle(this))
{
base.Dispose(disposing);
}
diff --git a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptImportKey.cs b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptImportKey.cs
index 913261e58915c..13d709643a184 100644
--- a/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptImportKey.cs
+++ b/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptImportKey.cs
@@ -37,7 +37,7 @@ internal static unsafe SafeKeyHandle BCryptImportKey(SafeAlgorithmHandle hAlg, R
}
[StructLayout(LayoutKind.Sequential)]
- internal struct BCRYPT_KEY_DATA_BLOB_HEADER
+ private struct BCRYPT_KEY_DATA_BLOB_HEADER
{
public uint dwMagic;
public uint dwVersion;
diff --git a/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Keys.cs b/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Keys.cs
index 5d9fbe7595ed0..406e0177f8ecf 100644
--- a/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Keys.cs
+++ b/src/libraries/Common/src/Interop/Windows/NCrypt/Interop.Keys.cs
@@ -11,11 +11,8 @@ internal static partial class Interop
{
internal static partial class NCrypt
{
- internal const string NCRYPT_CIPHER_KEY_BLOB = "CipherKeyBlob";
internal const string NCRYPT_PKCS8_PRIVATE_KEY_BLOB = "PKCS8_PRIVATEKEY";
- internal const int NCRYPT_CIPHER_KEY_BLOB_MAGIC = 0x52485043; //'CPHR'
-
[GeneratedDllImport(Interop.Libraries.NCrypt, CharSet = CharSet.Unicode)]
internal static partial ErrorCode NCryptOpenKey(SafeNCryptProviderHandle hProvider, out SafeNCryptKeyHandle phKey, string pszKeyName, int dwLegacyKeySpec, CngKeyOpenOptions dwFlags);
diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.Constants.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.Constants.cs
index e1a9bc4cce2ac..7a1574155a7d9 100644
--- a/src/libraries/Common/src/Interop/Windows/User32/Interop.Constants.cs
+++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.Constants.cs
@@ -198,7 +198,6 @@ internal static partial class User32
public const int WAIT_TIMEOUT = 0x00000102;
- public const int WM_DESTROY = 0x0002;
public const int WM_CLOSE = 0x0010;
public const int WM_QUERYENDSESSION = 0x0011;
public const int WM_QUIT = 0x0012;
diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.GetMessage.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.PeekMessage.cs
similarity index 77%
rename from src/libraries/Common/src/Interop/Windows/User32/Interop.GetMessage.cs
rename to src/libraries/Common/src/Interop/Windows/User32/Interop.PeekMessage.cs
index 5f9af4ffc2aa7..6bcfa1488d684 100644
--- a/src/libraries/Common/src/Interop/Windows/User32/Interop.GetMessage.cs
+++ b/src/libraries/Common/src/Interop/Windows/User32/Interop.PeekMessage.cs
@@ -9,6 +9,6 @@ internal static partial class Interop
internal static partial class User32
{
[GeneratedDllImport(Libraries.User32, CharSet = CharSet.Unicode, ExactSpelling = true)]
- public static partial int GetMessageW(ref MSG msg, IntPtr hwnd, int msgMin, int msgMax);
+ public static partial bool PeekMessageW(ref MSG msg, IntPtr hwnd, int msgMin, int msgMax, int remove);
}
}
diff --git a/src/libraries/Common/src/Interop/Windows/User32/Interop.PostQuitMessage.cs b/src/libraries/Common/src/Interop/Windows/User32/Interop.PostQuitMessage.cs
deleted file mode 100644
index 511e68c0f883b..0000000000000
--- a/src/libraries/Common/src/Interop/Windows/User32/Interop.PostQuitMessage.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Runtime.InteropServices;
-
-internal static partial class Interop
-{
- internal static partial class User32
- {
- [GeneratedDllImport(Libraries.User32, CharSet = CharSet.Unicode, ExactSpelling = true)]
- public static partial void PostQuitMessage(int exitCode);
- }
-}
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SafeEvpPKeyHandle.OpenSsl.cs b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeEvpPKeyHandle.Unix.cs
similarity index 77%
rename from src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SafeEvpPKeyHandle.OpenSsl.cs
rename to src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeEvpPKeyHandle.Unix.cs
index 47b6ba4812e54..9e67a1a9df2d6 100644
--- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SafeEvpPKeyHandle.OpenSsl.cs
+++ b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeEvpPKeyHandle.Unix.cs
@@ -3,29 +3,23 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
namespace System.Security.Cryptography
{
- public sealed class SafeEvpPKeyHandle : SafeHandle
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ internal
+#else
+ public
+#endif
+ sealed class SafeEvpPKeyHandle : SafeHandle
{
internal static readonly SafeEvpPKeyHandle InvalidHandle = new SafeEvpPKeyHandle();
- [UnsupportedOSPlatform("android")]
- [UnsupportedOSPlatform("browser")]
- [UnsupportedOSPlatform("ios")]
- [UnsupportedOSPlatform("tvos")]
- [UnsupportedOSPlatform("windows")]
public SafeEvpPKeyHandle() :
base(IntPtr.Zero, ownsHandle: true)
{
}
- [UnsupportedOSPlatform("android")]
- [UnsupportedOSPlatform("browser")]
- [UnsupportedOSPlatform("ios")]
- [UnsupportedOSPlatform("tvos")]
- [UnsupportedOSPlatform("windows")]
public SafeEvpPKeyHandle(IntPtr handle, bool ownsHandle)
: base(handle, ownsHandle)
{
@@ -71,6 +65,7 @@ public SafeEvpPKeyHandle DuplicateHandle()
return safeHandle;
}
+#if !INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
///
/// The runtime version number for the loaded version of OpenSSL.
///
@@ -78,11 +73,7 @@ public SafeEvpPKeyHandle DuplicateHandle()
/// For OpenSSL 1.1+ this is the result of OpenSSL_version_num()
,
/// for OpenSSL 1.0.x this is the result of SSLeay()
.
///
- [UnsupportedOSPlatform("android")]
- [UnsupportedOSPlatform("browser")]
- [UnsupportedOSPlatform("ios")]
- [UnsupportedOSPlatform("tvos")]
- [UnsupportedOSPlatform("windows")]
public static long OpenSslVersion { get; } = Interop.OpenSsl.OpenSslVersionNumber();
+#endif
}
}
diff --git a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs
index 54d6284d601c9..20f987f6cc053 100644
--- a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs
+++ b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.Security.Cryptography.X509Certificates;
+using Internal.Cryptography.Pal;
namespace Microsoft.Win32.SafeHandles
{
diff --git a/src/libraries/Common/src/System/Net/CookieComparer.cs b/src/libraries/Common/src/System/Net/CookieComparer.cs
index 529ec06a51a1f..7d511ace0a9ac 100644
--- a/src/libraries/Common/src/System/Net/CookieComparer.cs
+++ b/src/libraries/Common/src/System/Net/CookieComparer.cs
@@ -5,29 +5,23 @@ namespace System.Net
{
internal static class CookieComparer
{
- internal static bool Equals(Cookie left, Cookie right)
+ internal static int Compare(Cookie left, Cookie right)
{
- if (!string.Equals(left.Name, right.Name, StringComparison.OrdinalIgnoreCase))
+ int result;
+
+ if ((result = string.Compare(left.Name, right.Name, StringComparison.OrdinalIgnoreCase)) != 0)
{
- return false;
+ return result;
}
- if (!EqualDomains(left.Domain, right.Domain))
+ if ((result = string.Compare(left.Domain, right.Domain, StringComparison.OrdinalIgnoreCase)) != 0)
{
- return false;
+ return result;
}
// NB: Only the path is case sensitive as per spec. However, many Windows applications assume
// case-insensitivity.
- return string.Equals(left.Path, right.Path, StringComparison.Ordinal);
- }
-
- internal static bool EqualDomains(ReadOnlySpan left, ReadOnlySpan right)
- {
- if (left.Length != 0 && left[0] == '.') left = left.Slice(1);
- if (right.Length != 0 && right[0] == '.') right = right.Slice(1);
-
- return left.Equals(right, StringComparison.OrdinalIgnoreCase);
+ return string.Compare(left.Path, right.Path, StringComparison.Ordinal);
}
}
}
diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs
index e254c3a1ef0bc..6e109d6f8c547 100644
--- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs
+++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http3/QPack/H3StaticTable.Http3.cs
@@ -48,7 +48,7 @@ public static bool TryGetStatusIndex(int status, out int index)
// TODO: just use Dictionary directly to avoid interface dispatch.
public static IReadOnlyDictionary MethodIndex => s_methodIndex;
- public static ref readonly HeaderField Get(int index) => ref s_staticTable[index];
+ public static ref HeaderField Get(int index) => ref s_staticTable[index];
private static readonly HeaderField[] s_staticTable = new HeaderField[]
{
diff --git a/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs b/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs
index c2fcca169d21d..579e69a153f04 100644
--- a/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs
+++ b/src/libraries/Common/src/System/Net/NetworkInformation/UnixCommandLinePing.cs
@@ -90,8 +90,7 @@ public static string ConstructCommandLine(int packetSize, int timeout, string ad
// OSX: ping requires -W flag which accepts timeout in MILLISECONDS; ping6 doesn't support timeout
if (OperatingSystem.IsFreeBSD())
{
- // Syntax changed in FreeBSD 13.0 and options are not common for both address families
- if (ipv4 || Environment.OSVersion.Version.Major > 12)
+ if (ipv4)
{
sb.Append(" -W ");
}
@@ -136,8 +135,7 @@ public static string ConstructCommandLine(int packetSize, int timeout, string ad
if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsMacOS())
{
// OSX and FreeBSD use -h to set hop limit for IPv6 and -m ttl for IPv4
- // Syntax changed in FreeBSD 13.0 and options are not common for both address families
- if (ipv4 || (OperatingSystem.IsFreeBSD() && Environment.OSVersion.Version.Major > 12))
+ if (ipv4)
{
sb.Append(" -m ");
}
diff --git a/src/libraries/Common/src/System/Net/SocketProtocolSupportPal.Unix.cs b/src/libraries/Common/src/System/Net/SocketProtocolSupportPal.Unix.cs
index c755c16517c77..8de1e2a0f4ce3 100644
--- a/src/libraries/Common/src/System/Net/SocketProtocolSupportPal.Unix.cs
+++ b/src/libraries/Common/src/System/Net/SocketProtocolSupportPal.Unix.cs
@@ -15,9 +15,7 @@ private static unsafe bool IsSupported(AddressFamily af)
IntPtr socket = invalid;
try
{
- Interop.Error result = Interop.Sys.Socket(af, SocketType.Dgram, 0, &socket);
- // we get EAFNOSUPPORT when family is not supported by Kernel, EPROTONOSUPPORT may come from policy enforcement like FreeBSD jail()
- return result != Interop.Error.EAFNOSUPPORT && result != Interop.Error.EPROTONOSUPPORT;
+ return Interop.Sys.Socket(af, SocketType.Dgram, 0, &socket) != Interop.Error.EAFNOSUPPORT;
}
finally
{
diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs
index 67e9d869a68db..a16f66c40c89e 100644
--- a/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs
+++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1Reader/AsnValueReader.cs
@@ -34,18 +34,6 @@ internal Asn1Tag PeekTag()
return Asn1Tag.Decode(_span, out _);
}
- internal ReadOnlySpan PeekContentBytes()
- {
- AsnDecoder.ReadEncodedValue(
- _span,
- _ruleSet,
- out int contentOffset,
- out int contentLength,
- out _);
-
- return _span.Slice(contentOffset, contentLength);
- }
-
internal ReadOnlySpan PeekEncodedValue()
{
AsnDecoder.ReadEncodedValue(_span, _ruleSet, out _, out _, out int consumed);
diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs b/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs
index f9ec1cb44be8e..b5e8c50c42b51 100644
--- a/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs
+++ b/src/libraries/Common/src/System/Security/Cryptography/DSACng.ImportExport.cs
@@ -11,425 +11,432 @@
namespace System.Security.Cryptography
{
- public sealed partial class DSACng : DSA
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ internal static partial class DSAImplementation
{
- // For keysizes up to and including 1024 bits, CNG's blob format is BCRYPT_DSA_KEY_BLOB.
- // For keysizes exceeding 1024 bits, CNG's blob format is BCRYPT_DSA_KEY_BLOB_V2.
- private const int MaxV1KeySize = 1024;
-
- private const int Sha1HashOutputSize = 20;
- private const int Sha256HashOutputSize = 32;
- private const int Sha512HashOutputSize = 64;
-
- public override void ImportParameters(DSAParameters parameters)
+#endif
+ public sealed partial class DSACng : DSA
{
- if (parameters.P == null || parameters.Q == null || parameters.G == null || parameters.Y == null)
- throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MissingFields);
-
- // J is not required and is not even used on CNG blobs. It should however be less than P (J == (P-1) / Q). This validation check
- // is just to maintain parity with DSACryptoServiceProvider, which also performs this check.
- if (parameters.J != null && parameters.J.Length >= parameters.P.Length)
- throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPJ);
-
- bool hasPrivateKey = parameters.X != null;
+ // For keysizes up to and including 1024 bits, CNG's blob format is BCRYPT_DSA_KEY_BLOB.
+ // For keysizes exceeding 1024 bits, CNG's blob format is BCRYPT_DSA_KEY_BLOB_V2.
+ private const int MaxV1KeySize = 1024;
- int keySizeInBytes = parameters.P.Length;
- int keySizeInBits = keySizeInBytes * 8;
+ private const int Sha1HashOutputSize = 20;
+ private const int Sha256HashOutputSize = 32;
+ private const int Sha512HashOutputSize = 64;
- if (parameters.G.Length != keySizeInBytes || parameters.Y.Length != keySizeInBytes)
- throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPGY);
+ public override void ImportParameters(DSAParameters parameters)
+ {
+ if (parameters.P == null || parameters.Q == null || parameters.G == null || parameters.Y == null)
+ throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MissingFields);
- if (hasPrivateKey && parameters.X!.Length != parameters.Q.Length)
- throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedQX);
+ // J is not required and is not even used on CNG blobs. It should however be less than P (J == (P-1) / Q). This validation check
+ // is just to maintain parity with DSACryptoServiceProvider, which also performs this check.
+ if (parameters.J != null && parameters.J.Length >= parameters.P.Length)
+ throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPJ);
- byte[] blob;
- if (keySizeInBits <= MaxV1KeySize)
- {
- GenerateV1DsaBlob(out blob, parameters, keySizeInBytes, hasPrivateKey);
- }
- else
- {
- GenerateV2DsaBlob(out blob, parameters, keySizeInBytes, hasPrivateKey);
- }
+ bool hasPrivateKey = parameters.X != null;
- ImportKeyBlob(blob, hasPrivateKey);
- }
+ int keySizeInBytes = parameters.P.Length;
+ int keySizeInBits = keySizeInBytes * 8;
- public override void ImportEncryptedPkcs8PrivateKey(
- ReadOnlySpan passwordBytes,
- ReadOnlySpan source,
- out int bytesRead)
- {
- ThrowIfDisposed();
- base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
- }
+ if (parameters.G.Length != keySizeInBytes || parameters.Y.Length != keySizeInBytes)
+ throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPGY);
- public override void ImportEncryptedPkcs8PrivateKey(
- ReadOnlySpan password,
- ReadOnlySpan source,
- out int bytesRead)
- {
- ThrowIfDisposed();
- base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
- }
+ if (hasPrivateKey && parameters.X!.Length != parameters.Q.Length)
+ throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedQX);
- public override byte[] ExportEncryptedPkcs8PrivateKey(
- ReadOnlySpan passwordBytes,
- PbeParameters pbeParameters)
- {
- if (pbeParameters == null)
- throw new ArgumentNullException(nameof(pbeParameters));
+ byte[] blob;
+ if (keySizeInBits <= MaxV1KeySize)
+ {
+ GenerateV1DsaBlob(out blob, parameters, keySizeInBytes, hasPrivateKey);
+ }
+ else
+ {
+ GenerateV2DsaBlob(out blob, parameters, keySizeInBytes, hasPrivateKey);
+ }
- return CngPkcs8.ExportEncryptedPkcs8PrivateKey(
- this,
- passwordBytes,
- pbeParameters);
- }
+ ImportKeyBlob(blob, hasPrivateKey);
+ }
- public override byte[] ExportEncryptedPkcs8PrivateKey(
- ReadOnlySpan password,
- PbeParameters pbeParameters)
- {
- if (pbeParameters == null)
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan passwordBytes,
+ ReadOnlySpan source,
+ out int bytesRead)
{
- throw new ArgumentNullException(nameof(pbeParameters));
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
}
- PasswordBasedEncryption.ValidatePbeParameters(
- pbeParameters,
- password,
- ReadOnlySpan.Empty);
-
- if (CngPkcs8.IsPlatformScheme(pbeParameters))
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan password,
+ ReadOnlySpan source,
+ out int bytesRead)
{
- return ExportEncryptedPkcs8(password, pbeParameters.IterationCount);
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
}
- return CngPkcs8.ExportEncryptedPkcs8PrivateKey(
- this,
- password,
- pbeParameters);
- }
+ public override byte[] ExportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan passwordBytes,
+ PbeParameters pbeParameters)
+ {
+ if (pbeParameters == null)
+ throw new ArgumentNullException(nameof(pbeParameters));
- public override bool TryExportEncryptedPkcs8PrivateKey(
- ReadOnlySpan passwordBytes,
- PbeParameters pbeParameters,
- Span destination,
- out int bytesWritten)
- {
- if (pbeParameters == null)
- throw new ArgumentNullException(nameof(pbeParameters));
-
- PasswordBasedEncryption.ValidatePbeParameters(
- pbeParameters,
- ReadOnlySpan.Empty,
- passwordBytes);
-
- return CngPkcs8.TryExportEncryptedPkcs8PrivateKey(
- this,
- passwordBytes,
- pbeParameters,
- destination,
- out bytesWritten);
- }
+ return CngPkcs8.ExportEncryptedPkcs8PrivateKey(
+ this,
+ passwordBytes,
+ pbeParameters);
+ }
- public override bool TryExportEncryptedPkcs8PrivateKey(
- ReadOnlySpan password,
- PbeParameters pbeParameters,
- Span destination,
- out int bytesWritten)
- {
- if (pbeParameters == null)
- throw new ArgumentNullException(nameof(pbeParameters));
+ public override byte[] ExportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan password,
+ PbeParameters pbeParameters)
+ {
+ if (pbeParameters == null)
+ {
+ throw new ArgumentNullException(nameof(pbeParameters));
+ }
- PasswordBasedEncryption.ValidatePbeParameters(
- pbeParameters,
- password,
- ReadOnlySpan.Empty);
+ PasswordBasedEncryption.ValidatePbeParameters(
+ pbeParameters,
+ password,
+ ReadOnlySpan.Empty);
- if (CngPkcs8.IsPlatformScheme(pbeParameters))
- {
- return TryExportEncryptedPkcs8(
+ if (CngPkcs8.IsPlatformScheme(pbeParameters))
+ {
+ return ExportEncryptedPkcs8(password, pbeParameters.IterationCount);
+ }
+
+ return CngPkcs8.ExportEncryptedPkcs8PrivateKey(
+ this,
password,
- pbeParameters.IterationCount,
- destination,
- out bytesWritten);
+ pbeParameters);
}
- return CngPkcs8.TryExportEncryptedPkcs8PrivateKey(
- this,
- password,
- pbeParameters,
- destination,
- out bytesWritten);
- }
-
- private static unsafe void GenerateV1DsaBlob(out byte[] blob, DSAParameters parameters, int cbKey, bool includePrivate)
- {
- // We need to build a key blob structured as follows:
- //
- // BCRYPT_DSA_KEY_BLOB header
- // byte[cbKey] P
- // byte[cbKey] G
- // byte[cbKey] Y
- // -- Private only --
- // byte[Sha1HashOutputSize] X
-
- int blobSize =
- sizeof(BCRYPT_DSA_KEY_BLOB) +
- cbKey +
- cbKey +
- cbKey;
-
- if (includePrivate)
+ public override bool TryExportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan passwordBytes,
+ PbeParameters pbeParameters,
+ Span destination,
+ out int bytesWritten)
{
- blobSize += Sha1HashOutputSize;
+ if (pbeParameters == null)
+ throw new ArgumentNullException(nameof(pbeParameters));
+
+ PasswordBasedEncryption.ValidatePbeParameters(
+ pbeParameters,
+ ReadOnlySpan.Empty,
+ passwordBytes);
+
+ return CngPkcs8.TryExportEncryptedPkcs8PrivateKey(
+ this,
+ passwordBytes,
+ pbeParameters,
+ destination,
+ out bytesWritten);
}
- blob = new byte[blobSize];
- fixed (byte* pDsaBlob = &blob[0])
+ public override bool TryExportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan password,
+ PbeParameters pbeParameters,
+ Span destination,
+ out int bytesWritten)
{
- // Build the header
- BCRYPT_DSA_KEY_BLOB* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB*)pDsaBlob;
-
- pBcryptBlob->Magic = includePrivate ? KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC : KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC;
- pBcryptBlob->cbKey = cbKey;
+ if (pbeParameters == null)
+ throw new ArgumentNullException(nameof(pbeParameters));
- int offset = sizeof(KeyBlobMagicNumber) + sizeof(int); // skip Magic and cbKey
-
- if (parameters.Seed != null)
- {
- // The Seed length is hardcoded into BCRYPT_DSA_KEY_BLOB, so check it now we can give a nicer error message.
- if (parameters.Seed.Length != Sha1HashOutputSize)
- throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_SeedRestriction_ShortKey);
+ PasswordBasedEncryption.ValidatePbeParameters(
+ pbeParameters,
+ password,
+ ReadOnlySpan.Empty);
- Interop.BCrypt.EmitBigEndian(blob, ref offset, parameters.Counter);
- Interop.BCrypt.Emit(blob, ref offset, parameters.Seed);
- }
- else
+ if (CngPkcs8.IsPlatformScheme(pbeParameters))
{
- // If Seed is not present, back fill both counter and seed with 0xff. Do not use parameters.Counter as CNG is more strict than CAPI and will reject
- // anything other than 0xffffffff. That could complicate efforts to switch usage of DSACryptoServiceProvider to DSACng.
- Interop.BCrypt.EmitByte(blob, ref offset, 0xff, Sha1HashOutputSize + sizeof(int));
+ return TryExportEncryptedPkcs8(
+ password,
+ pbeParameters.IterationCount,
+ destination,
+ out bytesWritten);
}
- // The Q length is hardcoded into BCRYPT_DSA_KEY_BLOB, so check it now we can give a nicer error message.
- if (parameters.Q!.Length != Sha1HashOutputSize)
- throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_QRestriction_ShortKey);
-
- Interop.BCrypt.Emit(blob, ref offset, parameters.Q);
+ return CngPkcs8.TryExportEncryptedPkcs8PrivateKey(
+ this,
+ password,
+ pbeParameters,
+ destination,
+ out bytesWritten);
+ }
- Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB)}");
+ private static unsafe void GenerateV1DsaBlob(out byte[] blob, DSAParameters parameters, int cbKey, bool includePrivate)
+ {
+ // We need to build a key blob structured as follows:
+ //
+ // BCRYPT_DSA_KEY_BLOB header
+ // byte[cbKey] P
+ // byte[cbKey] G
+ // byte[cbKey] Y
+ // -- Private only --
+ // byte[Sha1HashOutputSize] X
+
+ int blobSize =
+ sizeof(BCRYPT_DSA_KEY_BLOB) +
+ cbKey +
+ cbKey +
+ cbKey;
- Interop.BCrypt.Emit(blob, ref offset, parameters.P!);
- Interop.BCrypt.Emit(blob, ref offset, parameters.G!);
- Interop.BCrypt.Emit(blob, ref offset, parameters.Y!);
if (includePrivate)
{
- Interop.BCrypt.Emit(blob, ref offset, parameters.X!);
+ blobSize += Sha1HashOutputSize;
}
- Debug.Assert(offset == blobSize, $"Expected offset = blobSize, got {offset} != {blobSize}");
- }
- }
-
- private static unsafe void GenerateV2DsaBlob(out byte[] blob, DSAParameters parameters, int cbKey, bool includePrivateParameters)
- {
- // We need to build a key blob structured as follows:
- // BCRYPT_DSA_KEY_BLOB_V2 header
- // byte[cbSeedLength] Seed
- // byte[cbGroupSize] Q
- // byte[cbKey] P
- // byte[cbKey] G
- // byte[cbKey] Y
- // -- Private only --
- // byte[cbGroupSize] X
-
- int blobSize =
- sizeof(BCRYPT_DSA_KEY_BLOB_V2) +
- (parameters.Seed == null ? parameters.Q!.Length : parameters.Seed.Length) + // Use Q size if Seed is not present
- parameters.Q!.Length +
- parameters.P!.Length +
- parameters.G!.Length +
- parameters.Y!.Length +
- (includePrivateParameters ? parameters.X!.Length : 0);
-
- blob = new byte[blobSize];
- fixed (byte* pDsaBlob = &blob[0])
- {
- // Build the header
- BCRYPT_DSA_KEY_BLOB_V2* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pDsaBlob;
-
- pBcryptBlob->Magic = includePrivateParameters ? KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2 : KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2;
- pBcryptBlob->cbKey = cbKey;
-
- // For some reason, Windows bakes the hash algorithm into the key itself. Furthermore, it demands that the Q length match the
- // length of the named hash algorithm's output - otherwise, the Import fails. So we have to give it the hash algorithm that matches
- // the Q length - and if there is no matching hash algorithm, we throw up our hands and throw a PlatformNotSupported.
- //
- // Note that this has no bearing on the hash algorithm you pass to SignData(). The class library (not Windows) hashes that according
- // to the hash algorithm passed to SignData() and presents the hash result to NCryptSignHash(), truncating the hash to the Q length
- // if necessary (and as demanded by the NIST spec.) Windows will be no wiser and we'll get the result we want.
- pBcryptBlob->hashAlgorithm = parameters.Q.Length switch
+ blob = new byte[blobSize];
+ fixed (byte* pDsaBlob = &blob[0])
{
- Sha1HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA1,
- Sha256HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA256,
- Sha512HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA512,
- _ => throw new PlatformNotSupportedException(SR.Cryptography_InvalidDsaParameters_QRestriction_LargeKey),
- };
- pBcryptBlob->standardVersion = DSAFIPSVERSION_ENUM.DSA_FIPS186_3;
+ // Build the header
+ BCRYPT_DSA_KEY_BLOB* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB*)pDsaBlob;
- int offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2) - 4; //skip to Count[4]
+ pBcryptBlob->Magic = includePrivate ? KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC : KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC;
+ pBcryptBlob->cbKey = cbKey;
- if (parameters.Seed != null)
- {
- Interop.BCrypt.EmitBigEndian(blob, ref offset, parameters.Counter);
- Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}");
- pBcryptBlob->cbSeedLength = parameters.Seed.Length;
- pBcryptBlob->cbGroupSize = parameters.Q.Length;
- Interop.BCrypt.Emit(blob, ref offset, parameters.Seed);
- }
- else
- {
- // If Seed is not present, back fill both counter and seed with 0xff. Do not use parameters.Counter as CNG is more strict than CAPI and will reject
- // anything other than 0xffffffff. That could complicate efforts to switch usage of DSACryptoServiceProvider to DSACng.
- Interop.BCrypt.EmitByte(blob, ref offset, 0xff, sizeof(int));
- Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}");
- int defaultSeedLength = parameters.Q.Length;
- pBcryptBlob->cbSeedLength = defaultSeedLength;
- pBcryptBlob->cbGroupSize = parameters.Q.Length;
- Interop.BCrypt.EmitByte(blob, ref offset, 0xff, defaultSeedLength);
- }
+ int offset = sizeof(KeyBlobMagicNumber) + sizeof(int); // skip Magic and cbKey
- Interop.BCrypt.Emit(blob, ref offset, parameters.Q);
- Interop.BCrypt.Emit(blob, ref offset, parameters.P);
- Interop.BCrypt.Emit(blob, ref offset, parameters.G);
- Interop.BCrypt.Emit(blob, ref offset, parameters.Y);
+ if (parameters.Seed != null)
+ {
+ // The Seed length is hardcoded into BCRYPT_DSA_KEY_BLOB, so check it now we can give a nicer error message.
+ if (parameters.Seed.Length != Sha1HashOutputSize)
+ throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_SeedRestriction_ShortKey);
- if (includePrivateParameters)
- {
- Interop.BCrypt.Emit(blob, ref offset, parameters.X!);
- }
+ Interop.BCrypt.EmitBigEndian(blob, ref offset, parameters.Counter);
+ Interop.BCrypt.Emit(blob, ref offset, parameters.Seed);
+ }
+ else
+ {
+ // If Seed is not present, back fill both counter and seed with 0xff. Do not use parameters.Counter as CNG is more strict than CAPI and will reject
+ // anything other than 0xffffffff. That could complicate efforts to switch usage of DSACryptoServiceProvider to DSACng.
+ Interop.BCrypt.EmitByte(blob, ref offset, 0xff, Sha1HashOutputSize + sizeof(int));
+ }
- Debug.Assert(offset == blobSize, $"Expected offset = blobSize, got {offset} != {blobSize}");
- }
- }
+ // The Q length is hardcoded into BCRYPT_DSA_KEY_BLOB, so check it now we can give a nicer error message.
+ if (parameters.Q!.Length != Sha1HashOutputSize)
+ throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_QRestriction_ShortKey);
- public override DSAParameters ExportParameters(bool includePrivateParameters)
- {
- byte[] dsaBlob = ExportKeyBlob(includePrivateParameters);
+ Interop.BCrypt.Emit(blob, ref offset, parameters.Q);
- KeyBlobMagicNumber magic = (KeyBlobMagicNumber)BitConverter.ToInt32(dsaBlob, 0);
+ Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB)}");
- // Check the magic value in the key blob header. If the blob does not have the required magic,
- // then throw a CryptographicException.
- CheckMagicValueOfKey(magic, includePrivateParameters);
+ Interop.BCrypt.Emit(blob, ref offset, parameters.P!);
+ Interop.BCrypt.Emit(blob, ref offset, parameters.G!);
+ Interop.BCrypt.Emit(blob, ref offset, parameters.Y!);
+ if (includePrivate)
+ {
+ Interop.BCrypt.Emit(blob, ref offset, parameters.X!);
+ }
- unsafe
- {
- DSAParameters dsaParams = default;
+ Debug.Assert(offset == blobSize, $"Expected offset = blobSize, got {offset} != {blobSize}");
+ }
+ }
- fixed (byte* pDsaBlob = dsaBlob)
+ private static unsafe void GenerateV2DsaBlob(out byte[] blob, DSAParameters parameters, int cbKey, bool includePrivateParameters)
+ {
+ // We need to build a key blob structured as follows:
+ // BCRYPT_DSA_KEY_BLOB_V2 header
+ // byte[cbSeedLength] Seed
+ // byte[cbGroupSize] Q
+ // byte[cbKey] P
+ // byte[cbKey] G
+ // byte[cbKey] Y
+ // -- Private only --
+ // byte[cbGroupSize] X
+
+ int blobSize =
+ sizeof(BCRYPT_DSA_KEY_BLOB_V2) +
+ (parameters.Seed == null ? parameters.Q!.Length : parameters.Seed.Length) + // Use Q size if Seed is not present
+ parameters.Q!.Length +
+ parameters.P!.Length +
+ parameters.G!.Length +
+ parameters.Y!.Length +
+ (includePrivateParameters ? parameters.X!.Length : 0);
+
+ blob = new byte[blobSize];
+ fixed (byte* pDsaBlob = &blob[0])
{
- int offset;
- if (magic == KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC || magic == KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC)
+ // Build the header
+ BCRYPT_DSA_KEY_BLOB_V2* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pDsaBlob;
+
+ pBcryptBlob->Magic = includePrivateParameters ? KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2 : KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2;
+ pBcryptBlob->cbKey = cbKey;
+
+ // For some reason, Windows bakes the hash algorithm into the key itself. Furthermore, it demands that the Q length match the
+ // length of the named hash algorithm's output - otherwise, the Import fails. So we have to give it the hash algorithm that matches
+ // the Q length - and if there is no matching hash algorithm, we throw up our hands and throw a PlatformNotSupported.
+ //
+ // Note that this has no bearing on the hash algorithm you pass to SignData(). The class library (not Windows) hashes that according
+ // to the hash algorithm passed to SignData() and presents the hash result to NCryptSignHash(), truncating the hash to the Q length
+ // if necessary (and as demanded by the NIST spec.) Windows will be no wiser and we'll get the result we want.
+ pBcryptBlob->hashAlgorithm = parameters.Q.Length switch
{
- if (dsaBlob.Length < sizeof(BCRYPT_DSA_KEY_BLOB))
- throw ErrorCode.E_FAIL.ToCryptographicException();
-
- BCRYPT_DSA_KEY_BLOB* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB*)pDsaBlob;
- // We now have a buffer laid out as follows:
- // BCRYPT_DSA_KEY_BLOB header
- // byte[cbKey] P
- // byte[cbKey] G
- // byte[cbKey] Y
- // -- Private only --
- // byte[Sha1HashOutputSize] X
-
- offset = sizeof(KeyBlobMagicNumber) + sizeof(int); // skip Magic and cbKey
-
- // Read out a (V1) BCRYPT_DSA_KEY_BLOB structure.
- dsaParams.Counter = BinaryPrimitives.ReadInt32BigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4));
- dsaParams.Seed = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize);
- dsaParams.Q = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize);
-
- Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB)}");
- dsaParams.P = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
- dsaParams.G = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
- dsaParams.Y = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
- if (includePrivateParameters)
- {
- dsaParams.X = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize);
- }
+ Sha1HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA1,
+ Sha256HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA256,
+ Sha512HashOutputSize => HASHALGORITHM_ENUM.DSA_HASH_ALGORITHM_SHA512,
+ _ => throw new PlatformNotSupportedException(SR.Cryptography_InvalidDsaParameters_QRestriction_LargeKey),
+ };
+ pBcryptBlob->standardVersion = DSAFIPSVERSION_ENUM.DSA_FIPS186_3;
+
+ int offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2) - 4; //skip to Count[4]
+
+ if (parameters.Seed != null)
+ {
+ Interop.BCrypt.EmitBigEndian(blob, ref offset, parameters.Counter);
+ Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}");
+ pBcryptBlob->cbSeedLength = parameters.Seed.Length;
+ pBcryptBlob->cbGroupSize = parameters.Q.Length;
+ Interop.BCrypt.Emit(blob, ref offset, parameters.Seed);
}
else
{
- Debug.Assert(magic == KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2 || magic == KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2);
+ // If Seed is not present, back fill both counter and seed with 0xff. Do not use parameters.Counter as CNG is more strict than CAPI and will reject
+ // anything other than 0xffffffff. That could complicate efforts to switch usage of DSACryptoServiceProvider to DSACng.
+ Interop.BCrypt.EmitByte(blob, ref offset, 0xff, sizeof(int));
+ Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}");
+ int defaultSeedLength = parameters.Q.Length;
+ pBcryptBlob->cbSeedLength = defaultSeedLength;
+ pBcryptBlob->cbGroupSize = parameters.Q.Length;
+ Interop.BCrypt.EmitByte(blob, ref offset, 0xff, defaultSeedLength);
+ }
+
+ Interop.BCrypt.Emit(blob, ref offset, parameters.Q);
+ Interop.BCrypt.Emit(blob, ref offset, parameters.P);
+ Interop.BCrypt.Emit(blob, ref offset, parameters.G);
+ Interop.BCrypt.Emit(blob, ref offset, parameters.Y);
- if (dsaBlob.Length < sizeof(BCRYPT_DSA_KEY_BLOB_V2))
- throw ErrorCode.E_FAIL.ToCryptographicException();
+ if (includePrivateParameters)
+ {
+ Interop.BCrypt.Emit(blob, ref offset, parameters.X!);
+ }
- BCRYPT_DSA_KEY_BLOB_V2* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pDsaBlob;
- // We now have a buffer laid out as follows:
- // BCRYPT_DSA_KEY_BLOB_V2 header
- // byte[cbSeedLength] Seed
- // byte[cbGroupSize] Q
- // byte[cbKey] P
- // byte[cbKey] G
- // byte[cbKey] Y
- // -- Private only --
- // byte[cbGroupSize] X
+ Debug.Assert(offset == blobSize, $"Expected offset = blobSize, got {offset} != {blobSize}");
+ }
+ }
- offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2) - 4; //skip to Count[4]
+ public override DSAParameters ExportParameters(bool includePrivateParameters)
+ {
+ byte[] dsaBlob = ExportKeyBlob(includePrivateParameters);
- // Read out a BCRYPT_DSA_KEY_BLOB_V2 structure.
- dsaParams.Counter = BinaryPrimitives.ReadInt32BigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4));
+ KeyBlobMagicNumber magic = (KeyBlobMagicNumber)BitConverter.ToInt32(dsaBlob, 0);
- Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}");
+ // Check the magic value in the key blob header. If the blob does not have the required magic,
+ // then throw a CryptographicException.
+ CheckMagicValueOfKey(magic, includePrivateParameters);
- dsaParams.Seed = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbSeedLength);
- dsaParams.Q = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbGroupSize);
- dsaParams.P = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
- dsaParams.G = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
- dsaParams.Y = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
- if (includePrivateParameters)
+ unsafe
+ {
+ DSAParameters dsaParams = default;
+
+ fixed (byte* pDsaBlob = dsaBlob)
+ {
+ int offset;
+ if (magic == KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC || magic == KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC)
{
- dsaParams.X = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbGroupSize);
+ if (dsaBlob.Length < sizeof(BCRYPT_DSA_KEY_BLOB))
+ throw ErrorCode.E_FAIL.ToCryptographicException();
+
+ BCRYPT_DSA_KEY_BLOB* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB*)pDsaBlob;
+ // We now have a buffer laid out as follows:
+ // BCRYPT_DSA_KEY_BLOB header
+ // byte[cbKey] P
+ // byte[cbKey] G
+ // byte[cbKey] Y
+ // -- Private only --
+ // byte[Sha1HashOutputSize] X
+
+ offset = sizeof(KeyBlobMagicNumber) + sizeof(int); // skip Magic and cbKey
+
+ // Read out a (V1) BCRYPT_DSA_KEY_BLOB structure.
+ dsaParams.Counter = BinaryPrimitives.ReadInt32BigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4));
+ dsaParams.Seed = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize);
+ dsaParams.Q = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize);
+
+ Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB)}");
+ dsaParams.P = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
+ dsaParams.G = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
+ dsaParams.Y = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
+ if (includePrivateParameters)
+ {
+ dsaParams.X = Interop.BCrypt.Consume(dsaBlob, ref offset, Sha1HashOutputSize);
+ }
+ }
+ else
+ {
+ Debug.Assert(magic == KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2 || magic == KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2);
+
+ if (dsaBlob.Length < sizeof(BCRYPT_DSA_KEY_BLOB_V2))
+ throw ErrorCode.E_FAIL.ToCryptographicException();
+
+ BCRYPT_DSA_KEY_BLOB_V2* pBcryptBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pDsaBlob;
+ // We now have a buffer laid out as follows:
+ // BCRYPT_DSA_KEY_BLOB_V2 header
+ // byte[cbSeedLength] Seed
+ // byte[cbGroupSize] Q
+ // byte[cbKey] P
+ // byte[cbKey] G
+ // byte[cbKey] Y
+ // -- Private only --
+ // byte[cbGroupSize] X
+
+ offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2) - 4; //skip to Count[4]
+
+ // Read out a BCRYPT_DSA_KEY_BLOB_V2 structure.
+ dsaParams.Counter = BinaryPrimitives.ReadInt32BigEndian(Interop.BCrypt.Consume(dsaBlob, ref offset, 4));
+
+ Debug.Assert(offset == sizeof(BCRYPT_DSA_KEY_BLOB_V2), $"Expected offset = sizeof(BCRYPT_DSA_KEY_BLOB_V2), got {offset} != {sizeof(BCRYPT_DSA_KEY_BLOB_V2)}");
+
+ dsaParams.Seed = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbSeedLength);
+ dsaParams.Q = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbGroupSize);
+ dsaParams.P = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
+ dsaParams.G = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
+ dsaParams.Y = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbKey);
+ if (includePrivateParameters)
+ {
+ dsaParams.X = Interop.BCrypt.Consume(dsaBlob, ref offset, pBcryptBlob->cbGroupSize);
+ }
}
- }
- // If no counter/seed information is present, normalize Counter and Seed to 0/null to maintain parity with the CAPI version of DSA.
- if (dsaParams.Counter == -1)
- {
- dsaParams.Counter = 0;
- dsaParams.Seed = null;
- }
+ // If no counter/seed information is present, normalize Counter and Seed to 0/null to maintain parity with the CAPI version of DSA.
+ if (dsaParams.Counter == -1)
+ {
+ dsaParams.Counter = 0;
+ dsaParams.Seed = null;
+ }
- Debug.Assert(offset == dsaBlob.Length, $"Expected offset = dsaBlob.Length, got {offset} != {dsaBlob.Length}");
+ Debug.Assert(offset == dsaBlob.Length, $"Expected offset = dsaBlob.Length, got {offset} != {dsaBlob.Length}");
- return dsaParams;
+ return dsaParams;
+ }
}
}
- }
- ///
- /// This function checks the magic value in the key blob header
- ///
- /// The expected magic number.
- /// Private blob if true else public key blob
- private static void CheckMagicValueOfKey(KeyBlobMagicNumber magic, bool includePrivateParameters)
- {
- if (includePrivateParameters)
- {
- if (magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC && magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2)
- throw new CryptographicException(SR.Cryptography_NotValidPrivateKey);
- }
- else
+ ///
+ /// This function checks the magic value in the key blob header
+ ///
+ /// The expected magic number.
+ /// Private blob if true else public key blob
+ private static void CheckMagicValueOfKey(KeyBlobMagicNumber magic, bool includePrivateParameters)
{
- if (magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC && magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2)
- throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey);
+ if (includePrivateParameters)
+ {
+ if (magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC && magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2)
+ throw new CryptographicException(SR.Cryptography_NotValidPrivateKey);
+ }
+ else
+ {
+ if (magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC && magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2)
+ throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey);
+ }
}
- }
+ }
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
}
+#endif
}
diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSACng.SignVerify.cs b/src/libraries/Common/src/System/Security/Cryptography/DSACng.SignVerify.cs
index 9393dc735880f..7971a35a2adf9 100644
--- a/src/libraries/Common/src/System/Security/Cryptography/DSACng.SignVerify.cs
+++ b/src/libraries/Common/src/System/Security/Cryptography/DSACng.SignVerify.cs
@@ -9,174 +9,199 @@
namespace System.Security.Cryptography
{
- public sealed partial class DSACng : DSA
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ internal static partial class DSAImplementation
{
- // As of FIPS 186-4 the maximum Q size is 32 bytes.
- //
- // See also: cbGroupSize at
- // https://docs.microsoft.com/en-us/windows/desktop/api/bcrypt/ns-bcrypt-_bcrypt_dsa_key_blob_v2
- private const int WindowsMaxQSize = 32;
-
- public override byte[] CreateSignature(byte[] rgbHash)
+#endif
+ public sealed partial class DSACng : DSA
{
- if (rgbHash == null)
- {
- throw new ArgumentNullException(nameof(rgbHash));
- }
-
- Span stackBuf = stackalloc byte[WindowsMaxQSize];
- ReadOnlySpan source = AdjustHashSizeIfNecessary(rgbHash, stackBuf);
+ // As of FIPS 186-4 the maximum Q size is 32 bytes.
+ //
+ // See also: cbGroupSize at
+ // https://docs.microsoft.com/en-us/windows/desktop/api/bcrypt/ns-bcrypt-_bcrypt_dsa_key_blob_v2
+ private const int WindowsMaxQSize = 32;
- using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
+ public override byte[] CreateSignature(byte[] rgbHash)
{
- unsafe
+ if (rgbHash == null)
{
- return CngCommon.SignHash(keyHandle, source, AsymmetricPaddingMode.None, null, source.Length * 2);
+ throw new ArgumentNullException(nameof(rgbHash));
}
- }
- }
- protected override unsafe bool TryCreateSignatureCore(
- ReadOnlySpan hash,
- Span destination,
- DSASignatureFormat signatureFormat,
- out int bytesWritten)
- {
- Span stackBuf = stackalloc byte[WindowsMaxQSize];
- ReadOnlySpan source = AdjustHashSizeIfNecessary(hash, stackBuf);
+ Span stackBuf = stackalloc byte[WindowsMaxQSize];
+ ReadOnlySpan source = AdjustHashSizeIfNecessary(rgbHash, stackBuf);
- using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
- {
- if (!CngCommon.TrySignHash(keyHandle, source, destination, AsymmetricPaddingMode.None, null, out bytesWritten))
+ using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
{
- bytesWritten = 0;
- return false;
+ unsafe
+ {
+ return CngCommon.SignHash(keyHandle, source, AsymmetricPaddingMode.None, null, source.Length * 2);
+ }
}
}
- if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation)
- {
- return true;
- }
-
- if (signatureFormat != DSASignatureFormat.Rfc3279DerSequence)
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ protected override unsafe bool TryCreateSignatureCore(
+ ReadOnlySpan hash,
+ Span destination,
+ DSASignatureFormat signatureFormat,
+ out int bytesWritten)
+#else
+ public override unsafe bool TryCreateSignature(ReadOnlySpan hash, Span destination, out int bytesWritten)
+#endif
{
- Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}");
- throw new CryptographicException(
- SR.Cryptography_UnknownSignatureFormat,
- signatureFormat.ToString());
- }
+ Span stackBuf = stackalloc byte[WindowsMaxQSize];
+ ReadOnlySpan source = AdjustHashSizeIfNecessary(hash, stackBuf);
- return AsymmetricAlgorithmHelpers.TryConvertIeee1363ToDer(
- destination.Slice(0, bytesWritten),
- destination,
- out bytesWritten);
- }
+ using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
+ {
+ if (!CngCommon.TrySignHash(keyHandle, source, destination, AsymmetricPaddingMode.None, null, out bytesWritten))
+ {
+ bytesWritten = 0;
+ return false;
+ }
+ }
- public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature)
- {
- if (rgbHash == null)
- {
- throw new ArgumentNullException(nameof(rgbHash));
- }
- if (rgbSignature == null)
- {
- throw new ArgumentNullException(nameof(rgbSignature));
- }
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation)
+ {
+ return true;
+ }
- return VerifySignatureCore(rgbHash, rgbSignature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation);
- }
+ if (signatureFormat != DSASignatureFormat.Rfc3279DerSequence)
+ {
+ Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}");
+ throw new CryptographicException(
+ SR.Cryptography_UnknownSignatureFormat,
+ signatureFormat.ToString());
+ }
- protected override bool VerifySignatureCore(
- ReadOnlySpan hash,
- ReadOnlySpan signature,
- DSASignatureFormat signatureFormat)
- {
- Span stackBuf = stackalloc byte[WindowsMaxQSize];
- ReadOnlySpan source = AdjustHashSizeIfNecessary(hash, stackBuf);
+ return AsymmetricAlgorithmHelpers.TryConvertIeee1363ToDer(
+ destination.Slice(0, bytesWritten),
+ destination,
+ out bytesWritten);
+#else
+ return true;
+#endif
+ }
- if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence)
+ public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature)
{
- // source.Length is the field size, in bytes, so just convert to bits.
- int fieldSizeBits = source.Length * 8;
- signature = this.ConvertSignatureToIeeeP1363(signatureFormat, signature, fieldSizeBits);
+ if (rgbHash == null)
+ {
+ throw new ArgumentNullException(nameof(rgbHash));
+ }
+ if (rgbSignature == null)
+ {
+ throw new ArgumentNullException(nameof(rgbSignature));
+ }
+
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ return VerifySignatureCore(rgbHash, rgbSignature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation);
+#else
+ return VerifySignature((ReadOnlySpan)rgbHash, (ReadOnlySpan)rgbSignature);
+#endif
}
- else if (signatureFormat != DSASignatureFormat.IeeeP1363FixedFieldConcatenation)
+
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ protected override bool VerifySignatureCore(
+ ReadOnlySpan hash,
+ ReadOnlySpan signature,
+ DSASignatureFormat signatureFormat)
{
- Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}");
- throw new CryptographicException(
- SR.Cryptography_UnknownSignatureFormat,
- signatureFormat.ToString());
- }
+ Span stackBuf = stackalloc byte[WindowsMaxQSize];
+ ReadOnlySpan source = AdjustHashSizeIfNecessary(hash, stackBuf);
- using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
+ if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence)
+ {
+ // source.Length is the field size, in bytes, so just convert to bits.
+ int fieldSizeBits = source.Length * 8;
+ signature = this.ConvertSignatureToIeeeP1363(signatureFormat, signature, fieldSizeBits);
+ }
+ else if (signatureFormat != DSASignatureFormat.IeeeP1363FixedFieldConcatenation)
+ {
+ Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}");
+ throw new CryptographicException(
+ SR.Cryptography_UnknownSignatureFormat,
+ signatureFormat.ToString());
+ }
+#else
+ public override bool VerifySignature(ReadOnlySpan hash, ReadOnlySpan signature)
{
- unsafe
+ Span stackBuf = stackalloc byte[WindowsMaxQSize];
+ ReadOnlySpan source = AdjustHashSizeIfNecessary(hash, stackBuf);
+#endif
+ using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
{
- return CngCommon.VerifyHash(keyHandle, source, signature, AsymmetricPaddingMode.None, null);
+ unsafe
+ {
+ return CngCommon.VerifyHash(keyHandle, source, signature, AsymmetricPaddingMode.None, null);
+ }
}
}
- }
-
- private ReadOnlySpan AdjustHashSizeIfNecessary(ReadOnlySpan hash, Span stackBuf)
- {
- Debug.Assert(stackBuf.Length == WindowsMaxQSize);
- // Windows CNG requires that the hash output and q match sizes, but we can better
- // interoperate with other FIPS 186-3 implementations if we perform truncation
- // here, before sending it to CNG. Since this is a scenario presented in the
- // CAVP reference test suite, we can confirm our implementation.
- //
- // If, on the other hand, Q is too big, we need to left-pad the hash with zeroes
- // (since it gets treated as a big-endian number). Since this is also a scenario
- // presented in the CAVP reference test suite, we can confirm our implementation.
+ private ReadOnlySpan AdjustHashSizeIfNecessary(ReadOnlySpan hash, Span stackBuf)
+ {
+ Debug.Assert(stackBuf.Length == WindowsMaxQSize);
- int qLength = ComputeQLength();
- Debug.Assert(qLength <= WindowsMaxQSize);
+ // Windows CNG requires that the hash output and q match sizes, but we can better
+ // interoperate with other FIPS 186-3 implementations if we perform truncation
+ // here, before sending it to CNG. Since this is a scenario presented in the
+ // CAVP reference test suite, we can confirm our implementation.
+ //
+ // If, on the other hand, Q is too big, we need to left-pad the hash with zeroes
+ // (since it gets treated as a big-endian number). Since this is also a scenario
+ // presented in the CAVP reference test suite, we can confirm our implementation.
- if (qLength == hash.Length)
- {
- return hash;
- }
+ int qLength = ComputeQLength();
+ Debug.Assert(qLength <= WindowsMaxQSize);
- if (qLength < hash.Length)
- {
- return hash.Slice(0, qLength);
- }
+ if (qLength == hash.Length)
+ {
+ return hash;
+ }
- int zeroByteCount = qLength - hash.Length;
- stackBuf.Slice(0, zeroByteCount).Clear();
- hash.CopyTo(stackBuf.Slice(zeroByteCount));
- return stackBuf.Slice(0, qLength);
- }
+ if (qLength < hash.Length)
+ {
+ return hash.Slice(0, qLength);
+ }
- private int ComputeQLength()
- {
- byte[] blob;
- using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
- {
- blob = this.ExportKeyBlob(false);
+ int zeroByteCount = qLength - hash.Length;
+ stackBuf.Slice(0, zeroByteCount).Clear();
+ hash.CopyTo(stackBuf.Slice(zeroByteCount));
+ return stackBuf.Slice(0, qLength);
}
- unsafe
+ private int ComputeQLength()
{
- if (blob.Length < sizeof(BCRYPT_DSA_KEY_BLOB_V2))
+ byte[] blob;
+ using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle())
{
- return Sha1HashOutputSize;
+ blob = this.ExportKeyBlob(false);
}
- fixed (byte* pBlobBytes = blob)
+ unsafe
{
- BCRYPT_DSA_KEY_BLOB_V2* pBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pBlobBytes;
- if (pBlob->Magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2 && pBlob->Magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2)
+ if (blob.Length < sizeof(BCRYPT_DSA_KEY_BLOB_V2))
{
- // This is a V1 BCRYPT_DSA_KEY_BLOB, which hardcodes the Q length to 20 bytes.
return Sha1HashOutputSize;
}
- return pBlob->cbGroupSize;
+ fixed (byte* pBlobBytes = blob)
+ {
+ BCRYPT_DSA_KEY_BLOB_V2* pBlob = (BCRYPT_DSA_KEY_BLOB_V2*)pBlobBytes;
+ if (pBlob->Magic != KeyBlobMagicNumber.BCRYPT_DSA_PUBLIC_MAGIC_V2 && pBlob->Magic != KeyBlobMagicNumber.BCRYPT_DSA_PRIVATE_MAGIC_V2)
+ {
+ // This is a V1 BCRYPT_DSA_KEY_BLOB, which hardcodes the Q length to 20 bytes.
+ return Sha1HashOutputSize;
+ }
+
+ return pBlob->cbGroupSize;
+ }
}
}
}
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
}
+#endif
}
diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSACng.cs b/src/libraries/Common/src/System/Security/Cryptography/DSACng.cs
index d9f8ed5cafa68..a89f2706a23d4 100644
--- a/src/libraries/Common/src/System/Security/Cryptography/DSACng.cs
+++ b/src/libraries/Common/src/System/Security/Cryptography/DSACng.cs
@@ -5,80 +5,84 @@
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
namespace System.Security.Cryptography
{
- public sealed partial class DSACng : DSA
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ internal static partial class DSAImplementation
{
- ///
- /// Create a DSACng algorithm with a random 2048 bit key pair.
- ///
- [SupportedOSPlatform("windows")]
- public DSACng()
- : this(keySize: s_defaultKeySize)
+#endif
+ public sealed partial class DSACng : DSA
{
- }
+ ///
+ /// Create a DSACng algorithm with a random 2048 bit key pair.
+ ///
+ public DSACng()
+ : this(keySize: s_defaultKeySize)
+ {
+ }
- ///
- /// Creates a new DSACng object that will use a randomly generated key of the specified size.
- /// Valid key sizes range from 512 to 3072 bits, in increments of 64. It's suggested that a
- /// minimum size of 2048 bits be used for all keys.
- ///
- /// Size of the key to generate, in bits.
- /// if is not valid
- [SupportedOSPlatform("windows")]
- public DSACng(int keySize)
- {
- LegalKeySizesValue = s_legalKeySizes;
- KeySize = keySize;
- }
+ ///
+ /// Creates a new DSACng object that will use a randomly generated key of the specified size.
+ /// Valid key sizes range from 512 to 3072 bits, in increments of 64. It's suggested that a
+ /// minimum size of 2048 bits be used for all keys.
+ ///
+ /// Size of the key to generate, in bits.
+ /// if is not valid
+ public DSACng(int keySize)
+ {
+ LegalKeySizesValue = s_legalKeySizes;
+ KeySize = keySize;
+ }
- public override KeySizes[] LegalKeySizes
- {
- get
+ public override KeySizes[] LegalKeySizes
{
- return base.LegalKeySizes;
+ get
+ {
+ return base.LegalKeySizes;
+ }
}
- }
- public override string SignatureAlgorithm => "DSA";
- public override string? KeyExchangeAlgorithm => null;
+ public override string SignatureAlgorithm => "DSA";
+ public override string? KeyExchangeAlgorithm => null;
- // Need to override since base methods throw a "override me" exception: makes SignData/VerifyData function.
- protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) =>
- CngCommon.HashData(data, offset, count, hashAlgorithm);
+ // Need to override since base methods throw a "override me" exception: makes SignData/VerifyData function.
+ protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) =>
+ CngCommon.HashData(data, offset, count, hashAlgorithm);
- protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) =>
- CngCommon.HashData(data, hashAlgorithm);
+ protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) =>
+ CngCommon.HashData(data, hashAlgorithm);
- protected override bool TryHashData(ReadOnlySpan source, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) =>
- CngCommon.TryHashData(source, destination, hashAlgorithm, out bytesWritten);
+ protected override bool TryHashData(ReadOnlySpan source, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) =>
+ CngCommon.TryHashData(source, destination, hashAlgorithm, out bytesWritten);
- private void ForceSetKeySize(int newKeySize)
- {
- // Our LegalKeySizes value stores the values that we encoded as being the correct
- // legal key size limitations for this algorithm, as documented on MSDN.
- //
- // But on a new OS version we might not question if our limit is accurate, or MSDN
- // could have been inaccurate to start with.
- //
- // Since the key is already loaded, we know that Windows thought it to be valid;
- // therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance
- // check.
- //
- KeySizeValue = newKeySize;
- }
+ private void ForceSetKeySize(int newKeySize)
+ {
+ // Our LegalKeySizes value stores the values that we encoded as being the correct
+ // legal key size limitations for this algorithm, as documented on MSDN.
+ //
+ // But on a new OS version we might not question if our limit is accurate, or MSDN
+ // could have been inaccurate to start with.
+ //
+ // Since the key is already loaded, we know that Windows thought it to be valid;
+ // therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance
+ // check.
+ //
+ KeySizeValue = newKeySize;
+ }
- private static bool Supports2048KeySize()
- {
- Debug.Assert(OperatingSystem.IsWindows());
- Version version = Environment.OSVersion.Version;
- bool isAtLeastWindows8 = version.Major > 6 || (version.Major == 6 && version.Minor >= 2);
- return isAtLeastWindows8;
- }
+ private static bool Supports2048KeySize()
+ {
+ Debug.Assert(OperatingSystem.IsWindows());
+ Version version = Environment.OSVersion.Version;
+ bool isAtLeastWindows8 = version.Major > 6 || (version.Major == 6 && version.Minor >= 2);
+ return isAtLeastWindows8;
+ }
- private static readonly KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(minSize: 512, maxSize: 3072, skipSize: 64) };
- private static readonly int s_defaultKeySize = Supports2048KeySize() ? 2048 : 1024;
+ private static readonly KeySizes[] s_legalKeySizes = new KeySizes[] { new KeySizes(minSize: 512, maxSize: 3072, skipSize: 64) };
+ private static readonly int s_defaultKeySize = Supports2048KeySize() ? 2048 : 1024;
+ }
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
}
+#endif
}
diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSAOpenSsl.cs b/src/libraries/Common/src/System/Security/Cryptography/DSAOpenSsl.cs
index 8a8445fe17f5b..d51e1a3a8e5d3 100644
--- a/src/libraries/Common/src/System/Security/Cryptography/DSAOpenSsl.cs
+++ b/src/libraries/Common/src/System/Security/Cryptography/DSAOpenSsl.cs
@@ -3,400 +3,425 @@
using System.Diagnostics;
using System.IO;
-using System.Runtime.Versioning;
using Internal.Cryptography;
using Microsoft.Win32.SafeHandles;
namespace System.Security.Cryptography
{
- public sealed partial class DSAOpenSsl : DSA
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ public partial class DSA : AsymmetricAlgorithm
{
- // The biggest key allowed by FIPS 186-4 has N=256 (bit), which
- // maximally produces a 72-byte DER signature.
- // If a future version of the standard continues to enhance DSA,
- // we may want to bump this limit to allow the max-1 (expected size)
- // TryCreateSignature to pass.
- // Future updates seem unlikely, though, as FIPS 186-5 October 2019 draft has
- // DSA as a no longer supported/updated algorithm.
- private const int SignatureStackBufSize = 72;
- private const int BitsPerByte = 8;
-
- private Lazy _key = null!;
-
- [UnsupportedOSPlatform("android")]
- [UnsupportedOSPlatform("browser")]
- [UnsupportedOSPlatform("ios")]
- [UnsupportedOSPlatform("tvos")]
- [UnsupportedOSPlatform("windows")]
- public DSAOpenSsl()
- : this(2048)
+ private static DSA CreateCore()
{
+ return new DSAImplementation.DSAOpenSsl();
}
+ }
- [UnsupportedOSPlatform("android")]
- [UnsupportedOSPlatform("browser")]
- [UnsupportedOSPlatform("ios")]
- [UnsupportedOSPlatform("tvos")]
- [UnsupportedOSPlatform("windows")]
- public DSAOpenSsl(int keySize)
+ internal static partial class DSAImplementation
+ {
+#endif
+ public sealed partial class DSAOpenSsl : DSA
{
- ThrowIfNotSupported();
- LegalKeySizesValue = s_legalKeySizes;
- base.KeySize = keySize;
- _key = new Lazy(GenerateKey);
- }
+ // The biggest key allowed by FIPS 186-4 has N=256 (bit), which
+ // maximally produces a 72-byte DER signature.
+ // If a future version of the standard continues to enhance DSA,
+ // we may want to bump this limit to allow the max-1 (expected size)
+ // TryCreateSignature to pass.
+ // Future updates seem unlikely, though, as FIPS 186-5 October 2019 draft has
+ // DSA as a no longer supported/updated algorithm.
+ private const int SignatureStackBufSize = 72;
+ private const int BitsPerByte = 8;
+
+ private Lazy _key = null!;
+
+ public DSAOpenSsl()
+ : this(2048)
+ {
+ }
- public override int KeySize
- {
- set
+ public DSAOpenSsl(int keySize)
+ {
+ ThrowIfNotSupported();
+ LegalKeySizesValue = s_legalKeySizes;
+ base.KeySize = keySize;
+ _key = new Lazy(GenerateKey);
+ }
+
+ public override int KeySize
{
- if (KeySize == value)
+ set
{
- return;
- }
+ if (KeySize == value)
+ {
+ return;
+ }
- // Set the KeySize before FreeKey so that an invalid value doesn't throw away the key
- base.KeySize = value;
+ // Set the KeySize before FreeKey so that an invalid value doesn't throw away the key
+ base.KeySize = value;
- ThrowIfDisposed();
- FreeKey();
- _key = new Lazy(GenerateKey);
+ ThrowIfDisposed();
+ FreeKey();
+ _key = new Lazy(GenerateKey);
+ }
}
- }
-
- private void ForceSetKeySize(int newKeySize)
- {
- // In the event that a key was loaded via ImportParameters or an IntPtr/SafeHandle
- // it could be outside of the bounds that we currently represent as "legal key sizes".
- // Since that is our view into the underlying component it can be detached from the
- // component's understanding. If it said it has opened a key, and this is the size, trust it.
- KeySizeValue = newKeySize;
- }
- public override KeySizes[] LegalKeySizes
- {
- get
+ private void ForceSetKeySize(int newKeySize)
{
- return base.LegalKeySizes;
+ // In the event that a key was loaded via ImportParameters or an IntPtr/SafeHandle
+ // it could be outside of the bounds that we currently represent as "legal key sizes".
+ // Since that is our view into the underlying component it can be detached from the
+ // component's understanding. If it said it has opened a key, and this is the size, trust it.
+ KeySizeValue = newKeySize;
}
- }
- public override DSAParameters ExportParameters(bool includePrivateParameters)
- {
- // It's entirely possible that this line will cause the key to be generated in the first place.
- SafeDsaHandle key = GetKey();
-
- DSAParameters dsaParameters = Interop.Crypto.ExportDsaParameters(key, includePrivateParameters);
- bool hasPrivateKey = dsaParameters.X != null;
+ public override KeySizes[] LegalKeySizes
+ {
+ get
+ {
+ return base.LegalKeySizes;
+ }
+ }
- if (hasPrivateKey != includePrivateParameters)
- throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
+ public override DSAParameters ExportParameters(bool includePrivateParameters)
+ {
+ // It's entirely possible that this line will cause the key to be generated in the first place.
+ SafeDsaHandle key = GetKey();
- return dsaParameters;
- }
+ DSAParameters dsaParameters = Interop.Crypto.ExportDsaParameters(key, includePrivateParameters);
+ bool hasPrivateKey = dsaParameters.X != null;
- public override void ImportParameters(DSAParameters parameters)
- {
- if (parameters.P == null || parameters.Q == null || parameters.G == null || parameters.Y == null)
- throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MissingFields);
+ if (hasPrivateKey != includePrivateParameters)
+ throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
- // J is not required and is not even used on CNG blobs. It should however be less than P (J == (P-1) / Q). This validation check
- // is just to maintain parity with DSACNG and DSACryptoServiceProvider, which also perform this check.
- if (parameters.J != null && parameters.J.Length >= parameters.P.Length)
- throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPJ);
+ return dsaParameters;
+ }
- bool hasPrivateKey = parameters.X != null;
+ public override void ImportParameters(DSAParameters parameters)
+ {
+ if (parameters.P == null || parameters.Q == null || parameters.G == null || parameters.Y == null)
+ throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MissingFields);
- int keySize = parameters.P.Length;
- if (parameters.G.Length != keySize || parameters.Y.Length != keySize)
- throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPGY);
+ // J is not required and is not even used on CNG blobs. It should however be less than P (J == (P-1) / Q). This validation check
+ // is just to maintain parity with DSACNG and DSACryptoServiceProvider, which also perform this check.
+ if (parameters.J != null && parameters.J.Length >= parameters.P.Length)
+ throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPJ);
- if (hasPrivateKey && parameters.X!.Length != parameters.Q.Length)
- throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedQX);
+ bool hasPrivateKey = parameters.X != null;
- ThrowIfDisposed();
+ int keySize = parameters.P.Length;
+ if (parameters.G.Length != keySize || parameters.Y.Length != keySize)
+ throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedPGY);
- SafeDsaHandle key;
- if (!Interop.Crypto.DsaKeyCreateByExplicitParameters(
- out key,
- parameters.P, parameters.P.Length,
- parameters.Q, parameters.Q.Length,
- parameters.G, parameters.G.Length,
- parameters.Y, parameters.Y.Length,
- parameters.X, parameters.X != null ? parameters.X.Length : 0))
- {
- throw Interop.Crypto.CreateOpenSslCryptographicException();
- }
+ if (hasPrivateKey && parameters.X!.Length != parameters.Q.Length)
+ throw new ArgumentException(SR.Cryptography_InvalidDsaParameters_MismatchedQX);
- SetKey(key);
- }
+ ThrowIfDisposed();
- public override void ImportEncryptedPkcs8PrivateKey(
- ReadOnlySpan passwordBytes,
- ReadOnlySpan source,
- out int bytesRead)
- {
- ThrowIfDisposed();
- base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
- }
+ SafeDsaHandle key;
+ if (!Interop.Crypto.DsaKeyCreateByExplicitParameters(
+ out key,
+ parameters.P, parameters.P.Length,
+ parameters.Q, parameters.Q.Length,
+ parameters.G, parameters.G.Length,
+ parameters.Y, parameters.Y.Length,
+ parameters.X, parameters.X != null ? parameters.X.Length : 0))
+ {
+ throw Interop.Crypto.CreateOpenSslCryptographicException();
+ }
- public override void ImportEncryptedPkcs8PrivateKey(
- ReadOnlySpan password,
- ReadOnlySpan source,
- out int bytesRead)
- {
- ThrowIfDisposed();
- base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
- }
+ SetKey(key);
+ }
- protected override void Dispose(bool disposing)
- {
- if (disposing)
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan passwordBytes,
+ ReadOnlySpan source,
+ out int bytesRead)
{
- FreeKey();
- _key = null!;
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(passwordBytes, source, out bytesRead);
}
- base.Dispose(disposing);
- }
-
- private void FreeKey()
- {
- if (_key != null && _key.IsValueCreated)
+ public override void ImportEncryptedPkcs8PrivateKey(
+ ReadOnlySpan password,
+ ReadOnlySpan source,
+ out int bytesRead)
{
- SafeDsaHandle handle = _key.Value;
+ ThrowIfDisposed();
+ base.ImportEncryptedPkcs8PrivateKey(password, source, out bytesRead);
+ }
- if (handle != null)
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
{
- handle.Dispose();
+ FreeKey();
+ _key = null!;
}
+
+ base.Dispose(disposing);
}
- }
- private static void CheckInvalidKey(SafeDsaHandle key)
- {
- if (key == null || key.IsInvalid)
+ private void FreeKey()
{
- throw new CryptographicException(SR.Cryptography_OpenInvalidHandle);
- }
- }
+ if (_key != null && _key.IsValueCreated)
+ {
+ SafeDsaHandle handle = _key.Value;
- private SafeDsaHandle GenerateKey()
- {
- SafeDsaHandle key;
+ if (handle != null)
+ {
+ handle.Dispose();
+ }
+ }
+ }
- if (!Interop.Crypto.DsaGenerateKey(out key, KeySize))
+ private static void CheckInvalidKey(SafeDsaHandle key)
{
- throw Interop.Crypto.CreateOpenSslCryptographicException();
+ if (key == null || key.IsInvalid)
+ {
+ throw new CryptographicException(SR.Cryptography_OpenInvalidHandle);
+ }
}
- return key;
- }
+ private SafeDsaHandle GenerateKey()
+ {
+ SafeDsaHandle key;
- protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
- {
- // we're sealed and the base should have checked this already
- Debug.Assert(data != null);
- Debug.Assert(offset >= 0 && offset <= data.Length);
- Debug.Assert(count >= 0 && count <= data.Length);
- Debug.Assert(!string.IsNullOrEmpty(hashAlgorithm.Name));
+ if (!Interop.Crypto.DsaGenerateKey(out key, KeySize))
+ {
+ throw Interop.Crypto.CreateOpenSslCryptographicException();
+ }
- return AsymmetricAlgorithmHelpers.HashData(data, offset, count, hashAlgorithm);
- }
+ return key;
+ }
- protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) =>
- AsymmetricAlgorithmHelpers.HashData(data, hashAlgorithm);
+ protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm)
+ {
+ // we're sealed and the base should have checked this already
+ Debug.Assert(data != null);
+ Debug.Assert(offset >= 0 && offset <= data.Length);
+ Debug.Assert(count >= 0 && count <= data.Length);
+ Debug.Assert(!string.IsNullOrEmpty(hashAlgorithm.Name));
- protected override bool TryHashData(ReadOnlySpan data, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) =>
- AsymmetricAlgorithmHelpers.TryHashData(data, destination, hashAlgorithm, out bytesWritten);
+ return AsymmetricAlgorithmHelpers.HashData(data, offset, count, hashAlgorithm);
+ }
- public override byte[] CreateSignature(byte[] rgbHash)
- {
- if (rgbHash == null)
- throw new ArgumentNullException(nameof(rgbHash));
+ protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) =>
+ AsymmetricAlgorithmHelpers.HashData(data, hashAlgorithm);
- SafeDsaHandle key = GetKey();
- int signatureSize = Interop.Crypto.DsaEncodedSignatureSize(key);
- int signatureFieldSize = Interop.Crypto.DsaSignatureFieldSize(key) * BitsPerByte;
- Span signDestination = stackalloc byte[SignatureStackBufSize];
+ protected override bool TryHashData(ReadOnlySpan data, Span destination, HashAlgorithmName hashAlgorithm, out int bytesWritten) =>
+ AsymmetricAlgorithmHelpers.TryHashData(data, destination, hashAlgorithm, out bytesWritten);
- ReadOnlySpan derSignature = SignHash(rgbHash, signDestination, signatureSize, key);
- return AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, signatureFieldSize);
- }
+ public override byte[] CreateSignature(byte[] rgbHash)
+ {
+ if (rgbHash == null)
+ throw new ArgumentNullException(nameof(rgbHash));
- public override bool TryCreateSignature(
- ReadOnlySpan hash,
- Span destination,
- out int bytesWritten)
- {
- return TryCreateSignatureCore(
- hash,
- destination,
- DSASignatureFormat.IeeeP1363FixedFieldConcatenation,
- out bytesWritten);
- }
+ SafeDsaHandle key = GetKey();
+ int signatureSize = Interop.Crypto.DsaEncodedSignatureSize(key);
+ int signatureFieldSize = Interop.Crypto.DsaSignatureFieldSize(key) * BitsPerByte;
+ Span signDestination = stackalloc byte[SignatureStackBufSize];
- protected override bool TryCreateSignatureCore(
- ReadOnlySpan hash,
- Span destination,
- DSASignatureFormat signatureFormat,
- out int bytesWritten)
- {
- SafeDsaHandle key = GetKey();
- int maxSignatureSize = Interop.Crypto.DsaEncodedSignatureSize(key);
- Span signDestination = stackalloc byte[SignatureStackBufSize];
+ ReadOnlySpan derSignature = SignHash(rgbHash, signDestination, signatureSize, key);
+ return AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, signatureFieldSize);
+ }
+
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ public override bool TryCreateSignature(
+ ReadOnlySpan hash,
+ Span destination,
+ out int bytesWritten)
+ {
+ return TryCreateSignatureCore(
+ hash,
+ destination,
+ DSASignatureFormat.IeeeP1363FixedFieldConcatenation,
+ out bytesWritten);
+ }
- if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation)
+ protected override bool TryCreateSignatureCore(
+ ReadOnlySpan hash,
+ Span destination,
+ DSASignatureFormat signatureFormat,
+ out int bytesWritten)
+#else
+ public override bool TryCreateSignature(ReadOnlySpan hash, Span destination, out int bytesWritten)
+#endif
{
- int fieldSizeBytes = Interop.Crypto.DsaSignatureFieldSize(key);
- int p1363SignatureSize = 2 * fieldSizeBytes;
+ SafeDsaHandle key = GetKey();
+ int maxSignatureSize = Interop.Crypto.DsaEncodedSignatureSize(key);
+ Span signDestination = stackalloc byte[SignatureStackBufSize];
- if (destination.Length < p1363SignatureSize)
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation)
+#endif
{
- bytesWritten = 0;
- return false;
- }
+ int fieldSizeBytes = Interop.Crypto.DsaSignatureFieldSize(key);
+ int p1363SignatureSize = 2 * fieldSizeBytes;
- int fieldSizeBits = fieldSizeBytes * 8;
+ if (destination.Length < p1363SignatureSize)
+ {
+ bytesWritten = 0;
+ return false;
+ }
- ReadOnlySpan derSignature = SignHash(hash, signDestination, maxSignatureSize, key);
- bytesWritten = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, fieldSizeBits, destination);
- Debug.Assert(bytesWritten == p1363SignatureSize);
- return true;
- }
- else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence)
- {
- if (destination.Length >= maxSignatureSize)
+ int fieldSizeBits = fieldSizeBytes * 8;
+
+ ReadOnlySpan derSignature = SignHash(hash, signDestination, maxSignatureSize, key);
+ bytesWritten = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, fieldSizeBits, destination);
+ Debug.Assert(bytesWritten == p1363SignatureSize);
+ return true;
+ }
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence)
{
- signDestination = destination;
+ if (destination.Length >= maxSignatureSize)
+ {
+ signDestination = destination;
+ }
+ else if (maxSignatureSize > signDestination.Length)
+ {
+ Debug.Fail($"Stack-based signDestination is insufficient ({maxSignatureSize} needed)");
+ bytesWritten = 0;
+ return false;
+ }
+
+ ReadOnlySpan derSignature = SignHash(hash, signDestination, maxSignatureSize, key);
+
+ if (destination == signDestination)
+ {
+ bytesWritten = derSignature.Length;
+ return true;
+ }
+
+ return Helpers.TryCopyToDestination(derSignature, destination, out bytesWritten);
}
- else if (maxSignatureSize > signDestination.Length)
+ else
{
- Debug.Fail($"Stack-based signDestination is insufficient ({maxSignatureSize} needed)");
- bytesWritten = 0;
- return false;
+ Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}");
+ throw new CryptographicException(
+ SR.Cryptography_UnknownSignatureFormat,
+ signatureFormat.ToString());
}
+#endif
+ }
- ReadOnlySpan derSignature = SignHash(hash, signDestination, maxSignatureSize, key);
+ private static ReadOnlySpan SignHash(
+ ReadOnlySpan hash,
+ Span destination,
+ int signatureLength,
+ SafeDsaHandle key)
+ {
+ if (signatureLength > destination.Length)
+ {
+ Debug.Fail($"Stack-based signDestination is insufficient ({signatureLength} needed)");
+ destination = new byte[signatureLength];
+ }
- if (destination == signDestination)
+ if (!Interop.Crypto.DsaSign(key, hash, destination, out int actualLength))
{
- bytesWritten = derSignature.Length;
- return true;
+ throw Interop.Crypto.CreateOpenSslCryptographicException();
}
- return Helpers.TryCopyToDestination(derSignature, destination, out bytesWritten);
- }
- else
- {
- Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}");
- throw new CryptographicException(
- SR.Cryptography_UnknownSignatureFormat,
- signatureFormat.ToString());
- }
- }
+ Debug.Assert(
+ actualLength <= signatureLength,
+ "DSA_sign reported an unexpected signature size",
+ "DSA_sign reported signatureSize was {0}, when <= {1} was expected",
+ actualLength,
+ signatureLength);
- private static ReadOnlySpan SignHash(
- ReadOnlySpan hash,
- Span destination,
- int signatureLength,
- SafeDsaHandle key)
- {
- if (signatureLength > destination.Length)
- {
- Debug.Fail($"Stack-based signDestination is insufficient ({signatureLength} needed)");
- destination = new byte[signatureLength];
+ return destination.Slice(0, actualLength);
}
- if (!Interop.Crypto.DsaSign(key, hash, destination, out int actualLength))
+ public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature)
{
- throw Interop.Crypto.CreateOpenSslCryptographicException();
- }
-
- Debug.Assert(
- actualLength <= signatureLength,
- "DSA_sign reported an unexpected signature size",
- "DSA_sign reported signatureSize was {0}, when <= {1} was expected",
- actualLength,
- signatureLength);
-
- return destination.Slice(0, actualLength);
- }
+ if (rgbHash == null)
+ throw new ArgumentNullException(nameof(rgbHash));
+ if (rgbSignature == null)
+ throw new ArgumentNullException(nameof(rgbSignature));
- public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature)
- {
- if (rgbHash == null)
- throw new ArgumentNullException(nameof(rgbHash));
- if (rgbSignature == null)
- throw new ArgumentNullException(nameof(rgbSignature));
+ return VerifySignature((ReadOnlySpan)rgbHash, (ReadOnlySpan)rgbSignature);
+ }
- return VerifySignature((ReadOnlySpan)rgbHash, (ReadOnlySpan)rgbSignature);
- }
+#if INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
+ public override bool VerifySignature(ReadOnlySpan hash, ReadOnlySpan signature) =>
+ VerifySignatureCore(hash, signature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation);
- public override bool VerifySignature(ReadOnlySpan hash, ReadOnlySpan signature) =>
- VerifySignatureCore(hash, signature, DSASignatureFormat.IeeeP1363FixedFieldConcatenation);
+ protected override bool VerifySignatureCore(
+ ReadOnlySpan hash,
+ ReadOnlySpan signature,
+ DSASignatureFormat signatureFormat)
+#else
+ public override bool VerifySignature(ReadOnlySpan hash, ReadOnlySpan signature)
+#endif
+ {
+ SafeDsaHandle key = GetKey();
- protected override bool VerifySignatureCore(
- ReadOnlySpan